source: branches/dev-mj-1626/Compiler/ModelicaFrontEnd/src/jastadd/instance/InstanceTree.jrag @ 13095

Last change on this file since 13095 was 13095, checked in by tgutzmann, 5 months ago

Merge from trunk

File size: 128.5 KB
Line 
1/*
2    Copyright (C) 2009-2017 Modelon AB
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, version 3 of the License.
7
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12
13    You should have received a copy of the GNU General Public License
14    along with this program.  If not, see <http://www.gnu.org/licenses/>.
15*/
16
17import java.util.ArrayList;
18import java.util.Collection;
19import java.util.HashSet;
20import java.util.Iterator;
21import java.util.Collections;
22import org.jmodelica.util.Criteria;
23import org.jmodelica.util.collections.FilteredIterable;
24
25aspect Environment {
26
27    /**
28     * TODO: Is it a good idea to inherit? Should env be a component?
29     */
30    public class Environment extends ArrayList<InstModification> {
31       
32        public Environment() {
33        }
34       
35        public Environment(Iterable<InstModification>... sets) {
36            for (Iterable<InstModification> set : sets) {
37                for (InstModification mod : set) {
38                    addAll(mod.expand());
39                }
40            }
41        }
42
43        /**
44         * Merge an outer modification into the environment: add it at the beginning.
45         *
46         * @return <code>this</code>, for convenience
47         */
48        public Environment mergeOuter(InstModification outerMod) {
49            addAll(0, outerMod.expand());
50            return this;
51        }
52
53        /**
54         * Merge an inner modification into the environment: add it last.
55         *
56         * @return <code>this</code>, for convenience
57         */
58        public Environment mergeInner(InstModification innerMod) {
59            addAll(innerMod.expand());
60            return this;
61        }
62
63        /**
64         * Merge outer sets of modifications: add them at the beginning.
65         *
66         * @return if there are no modifications to merge, <code>this</code>;
67         *         otherwise a clone with the modifications merged
68         */
69        public Environment mergeOuterClone(Iterable<InstModification>... sets) {
70            ArrayList<InstModification> mods = new ArrayList<InstModification>();
71            for (Iterable<InstModification> set : sets)
72                for (InstModification mod : set)
73                    mods.addAll(mod.expand());
74            Environment env = this;
75            if (!mods.isEmpty()) {
76                env = clone();
77                env.addAll(0, mods);
78            }
79            return env;
80        }
81
82        /**
83         * Merge inner sets of modifications: add them last.
84         *
85         * @return if there are no modifications to merge, <code>this</code>;
86         *         otherwise a clone with the modifications merged
87         */
88        public Environment mergeInnerClone(Iterable<InstModification>... sets) {
89            ArrayList<InstModification> mods = new ArrayList<InstModification>();
90            for (Iterable<InstModification> set : sets)
91                for (InstModification mod : set)
92                    mods.addAll(mod.expand());
93            Environment env = this;
94            if (!mods.isEmpty()) {
95                env = clone();
96                env.addAll(mods);
97            }
98            return env;
99        }
100
101        /**
102         * Find the first modification matching the given name, or null if none are found.
103         */
104        public InstModification find(String name) {
105            for (InstModification im : this) {
106                InstModification match = im.matchInstModification(name);
107                if (match != null) {
108                    return match;
109                }
110            }
111            return null;
112        }
113
114        /**
115         * Creates a new environment that is a copy of this one, filtered for a named class or component.
116         *
117         * When filtering the environment, the result consists only of modifications with a matching prefix.
118         * In effect, this results in a "peeling" operation, where the first name in a qualified name is removed,
119         * and the rest of the modification is added to the new Environment.
120         *
121         * Redeclares are not taken into account.
122         */
123        public Environment filter(String name) {
124            return filter(name, null, null);
125        }
126
127        /**
128         * Creates a new environment that is a copy of this one, filtered for a named class or component.
129         *
130         * When filtering the environment, the result consists only of modifications with a matching prefix.
131         * In effect, this results in a "peeling" operation, where the first name in a qualified name is removed,
132         * and the rest of the modification is added to the new Environment.
133         *
134         * Any given redeclares are taken into account.
135         */
136        public Environment filter(String name, InstComponentRedeclare icr, InstRedeclareClassNode ircn) {
137            Environment env = new Environment();
138            boolean componentRedeclareFound = false;
139            boolean classRedeclareFound = false;
140            for (InstModification im : this) {
141                // If a first component redeclare modification is found, add modifiers
142                if (!componentRedeclareFound && im == icr) {
143                    if (icr.getInstComponentDecl().hasInstModification()) 
144                        env.mergeInner(icr.getInstComponentDecl().getInstModification());
145                    componentRedeclareFound = true;
146                }
147                // If a first class redeclare modification is found, add modifiers
148                if (!classRedeclareFound && im == ircn) {
149                    InstClassRedeclare iclr = (InstClassRedeclare) im;
150                    if (iclr.hasInstClassModification()) 
151                        env.mergeInner(iclr.getInstClassDecl().getInstClassModification());
152                    classRedeclareFound = true;
153                }
154               
155                InstModification match = im.matchInstModification(name);
156                if (match != null) {
157                    env.mergeInner(match);
158                }
159            }
160            return env;
161        }
162
163        public Environment clone() {
164            Environment env = new Environment();
165            env.addAll(this);
166            return env;
167        }
168
169        public ModificationNode merged(Criteria<InstModification> filter) {
170            ModificationNode modifications = ModificationNode.newRootNode();
171            Iterable<InstModification> iterable = new FilteredIterable(new ReverseListIterable(this), filter);
172            for (InstModification element : iterable) {
173                element.collectModifications(modifications);
174            }
175            return modifications;
176        }
177
178        /**
179         * TODO: implement!
180         */
181        public Environment peel(String name) {
182            return new Environment();
183        }
184
185        public String toString() {
186            StringBuilder str = new StringBuilder();
187            str.append("{");
188            for (InstModification im : this) {
189                str.append("  " + im.getSrcModification() + ",");
190                str.append(im.myInstNode().toString());
191                str.append("\n");
192            }
193            str.append("}\n");
194            return str.toString();
195        }
196
197        public String toString(String indent) {
198            StringBuilder str = new StringBuilder();
199            str.append(indent + "{");
200            for (int i = 0; i < size(); i++) {
201                InstModification im = get(i);
202                if (i==0) {
203                    str.append(im.getSrcModification());
204                } else {
205                    str.append(indent + " " + im.getSrcModification());
206                }
207                str.append(": ");
208                str.append(im.myInstNode().name());
209               
210                if (i != size() - 1) {
211                    str.append(",\n");
212                }
213            }
214            str.append("}\n");
215            return str.toString();
216        }
217
218    }
219
220}
221
222aspect InstModifications{
223
224    public ArrayList<InstModification> InstModification.expand() {
225        ArrayList<InstModification> l = new ArrayList<InstModification>();
226        l.add(this);
227        return l;
228    }
229
230    public ArrayList<InstModification> InstCompleteModification.expand() {
231        ArrayList<InstModification> l = new ArrayList<InstModification>();
232        for (InstModification im : getInstClassModification().getInstArguments())
233            l.add(im);
234        if (hasInstValueModification())
235            l.add(getInstValueModification());
236        return l;       
237   
238    }
239
240    public ArrayList<InstModification> InstClassModification.expand() {
241        ArrayList<InstModification> l = new ArrayList<InstModification>();
242        for (InstModification im : getInstArguments())
243                l.add(im);
244        return l;       
245    }
246
247    public abstract InstModification SrcModification.newInstModification();
248    public InstCompleteModification SrcCompleteModification.newInstModification() {
249        InstCompleteModification icm = new InstCompleteModification(this,getSrcClassModification().newInstModification(),new Opt());
250        if (hasSrcValueModification())
251            icm.setInstValueModification(getSrcValueModification().newInstModification());
252        return icm;
253    }
254    public InstValueModification SrcValueModification.newInstModification() {
255        return new InstValueModification(this);
256    }
257    public InstClassModification SrcClassModification.newInstModification () {
258        List l = new List();
259        for (SrcArgument a : getSrcArguments()) {
260            l.add(a.newInstModification());
261        }
262        return new InstClassModification(this,l);
263    }
264
265    public InstComponentModification SrcComponentModification.newInstModification() {
266        InstComponentModification top = null, last = null;
267        // TODO: handle dotted names in modifications instead of splitting?
268        for (SrcAccess part : getName().nameParts()) {
269            InstComponentModification icm = new InstComponentModification(
270                    this, getEach(), getFinal(), part.newInstAccess(), new Opt());
271            icm.setLocation(this);
272            if (last == null) {
273                top = last = icm;
274            } else {
275                InstClassModification icm2 = new InstClassModification(this, new List(icm));
276                icm2.setLocation(this);
277                InstCompleteModification icm3 = new InstCompleteModification(this, icm2, new Opt());
278                icm3.setLocation(this);
279                last.setInstModification(icm3);
280                last = icm;
281            }
282        }
283        if (hasSrcModification()) {
284            last.setInstModification(getSrcModification().newInstModification());
285        }
286        return top;
287    }
288
289    public InstComponentRedeclare SrcComponentRedeclare.newInstModification() {
290        InstComponentRedeclare icr = new InstComponentRedeclare(this, getEach(), getFinal(), getName().newInstAccess());
291        icr.setLocation(this);
292        return icr;
293    }
294    public InstComponentRedeclare SrcComponentDecl.newInstModification() {
295        if (!hasRedeclare()) {
296            throw new UnsupportedOperationException();
297        }
298        InstAccess name;
299        if (hasVarArraySubscripts()) {
300            name = new InstParseArrayAccess(getName().getID(), getVarArraySubscripts().instantiate());
301        } else {
302            name = new InstParseAccess(getName().getID());
303        }
304        name.setLocation(getName());
305        InstComponentRedeclare icr = new InstComponentRedeclare(this, false, false, name);
306        icr.setLocation(myComponentClause());
307        return icr;
308    }
309
310    public InstClassRedeclare SrcClassRedeclare.newInstModification() {
311        InstClassRedeclare icr = new InstClassRedeclare(this, getEach(), getFinal(), getName().newInstAccess());
312        icr.setLocation(this);
313        return icr;
314    }
315
316
317    syn SrcCompleteModification InstCompleteModification.getSrcCompleteModification()    = (SrcCompleteModification)  getSrcModification();
318    syn SrcClassModification InstClassModification.getSrcClassModification()             = (SrcClassModification)     getSrcModification();
319    syn SrcValueModification InstValueModification.getSrcValueModification()             = (SrcValueModification)     getSrcModification();
320    syn SrcComponentModification InstComponentModification.getSrcComponentModification() = (SrcComponentModification) getSrcModification();
321    syn SrcClassRedeclare InstClassRedeclare.getSrcClassRedeclare()                      = (SrcClassRedeclare)        getSrcModification();
322
323    syn SrcComponentDecl InstComponentRedeclare.getComponentRedeclareDecl() = 
324        getSrcModification().componentRedeclareDecl();
325
326    public interface SrcModificationOrRedeclareElement {
327        public SrcComponentDecl componentRedeclareDecl();
328    }
329
330    syn SrcComponentDecl SrcModification.componentRedeclareDecl() {
331        throw new UnsupportedOperationException();
332    }
333    eq SrcComponentRedeclare.componentRedeclareDecl() = getSrcComponentDecl();
334    syn SrcComponentDecl SrcComponentDecl.componentRedeclareDecl()  = this;
335}
336
337aspect MergedEnvironment {
338    public abstract class ModificationNode {
339        protected String name;
340        protected Map<String, ModificationNode> subNodes = new LinkedHashMap<>();
341       
342        protected ModificationNode(String name) {
343            this.name = name;
344        }
345       
346        public void setModification(InstValueModification modification) {
347        }
348       
349        public boolean isEmpty() {
350            return name.isEmpty() && subNodes.isEmpty();
351        }
352       
353        public ModificationNode subNode(String name) {
354            if (!subNodes.containsKey(name)) {
355                subNodes.put(name, new ValueModificationNode(name));
356            }
357            return subNodes.get(name);
358        }
359       
360        public ModificationNode redeclareSubNode(String name, InstElementRedeclare redeclare) {
361            subNodes.put(name, new RedeclareModificationNode(name, redeclare));
362            return subNodes.get(name);
363        }
364       
365        public static ModificationNode newRootNode() {
366            return new ValueModificationNode("");
367        }
368    }
369   
370    public class ValueModificationNode extends ModificationNode {
371        private InstValueModification modification;
372
373        public ValueModificationNode(String name) {
374            super(name);
375        }
376       
377        @Override
378        public void setModification(InstValueModification modification) {
379            this.modification = modification;
380        }
381    }
382   
383    public class RedeclareModificationNode extends ModificationNode {
384        private InstElementRedeclare redeclare;
385       
386        public RedeclareModificationNode(String name, InstElementRedeclare redeclare) {
387            super(name);
388            this.redeclare = redeclare;
389        }
390    }
391
392    public abstract void InstModification.collectModifications(ModificationNode results);
393    public void  InstCompleteModification.collectModifications(ModificationNode results) {
394        getInstClassModification().collectModifications(results);
395        if (hasInstValueModification()) {
396            getInstValueModification().collectModifications(results);
397        }
398    }
399    public void InstValueModification.collectModifications(ModificationNode results) {
400        results.setModification(this);
401    }
402    public void InstClassModification.collectModifications(ModificationNode results) {
403        for (InstArgument argument : getInstArguments()) {
404            argument.collectModifications(results);
405        }
406    }
407    public void InstComponentModification.collectModifications(ModificationNode results) {
408        if (hasInstModification()) {
409            getInstModification().collectModifications(results.subNode(name()));
410        }
411    }
412    public void InstElementRedeclare.collectModifications(ModificationNode results) {
413        results.redeclareSubNode(name(), this);
414    }
415}
416
417aspect Environments {
418
419    syn lazy Collection<InstModification> InstNode.localInstModifications() {
420        Collection<InstModification> nc = localInstModificationsNoClass();
421        Collection<InstModification> c = localInstModificationsClass();
422        if (nc.isEmpty()) {
423            return c;
424        } else if (c.isEmpty()) {
425            return nc;
426        } else {
427            ArrayList<InstModification> l = new ArrayList<InstModification>();
428            l.addAll(nc);
429            l.addAll(c);
430            return l;
431        }
432    }
433    /**
434     * All local modifications except those from any target class.
435     *
436     * Used for extends within components.
437     */
438    syn Collection<InstModification> InstNode.localInstModificationsNoClass() = Collections.<InstModification>emptyList();
439    /**
440     * Local modifications only from any target class.
441     *
442     * Used for extends within components.
443     */
444    syn Collection<InstModification> InstNode.localInstModificationsClass()   = Collections.<InstModification>emptyList();
445
446    eq InstComponentDecl.localInstModificationsNoClass() {
447        ArrayList<InstModification> l = new ArrayList<InstModification>();
448        if (hasInstModification() && !isGeneratedInner()) {
449            l.add(getInstModification());
450        }
451        l.addAll(instModificationsFromConstrainingType());
452        if (myInstClass().isRedeclared()) {
453            l.addAll(myInstClass().instModificationsFromConstrainingType());
454        }
455        return l;
456    }
457
458    eq InstComponentDecl.localInstModificationsClass() = myInstClass().classInstModifications();
459
460    eq InstExtends.localInstModificationsNoClass() {
461        ArrayList<InstModification> l = new ArrayList<InstModification>();
462        if (hasInstClassModification()) {
463            l.add(getInstClassModification());
464        }
465        return l;
466    }
467
468    eq InstExtends.localInstModificationsClass() = myInstClass().classInstModifications();
469
470    eq InstClassDecl.localInstModificationsNoClass() {
471        ArrayList<InstModification> l = new ArrayList<InstModification>();
472        if (hasInstClassModification()) {
473            l.add(getInstClassModification());
474        }
475        l.addAll(instModificationsFromConstrainingType());
476        return l;
477    }
478
479    eq InstClassDecl.localInstModificationsClass() = targetClassInstModifications();
480
481    syn java.util.List<InstModification> InstClassDecl.targetClassInstModifications() = Collections.<InstModification>emptyList();
482    eq InstShortClassDecl.targetClassInstModifications()       = 
483        getInstExtends(0).isRecursive() ? Collections.<InstModification>emptyList() : myTargetInstClassDecl().classInstModifications();
484    eq InstSimpleShortClassDecl.targetClassInstModifications() = 
485        isRecursive() ? Collections.<InstModification>emptyList() : myTargetInstClassDecl().classInstModifications();
486
487    syn java.util.List<InstModification> InstComponentDecl.instModificationsForConstraining() {
488        if (!isGeneratedInner()) {
489            if (hasInstConstrainingComponent()) {
490                if (getInstConstrainingComponent().hasInstClassModification())
491                    return Collections.singletonList((InstModification) getInstConstrainingComponent().getInstClassModification());
492            } else if (hasInstModification()) {
493                return Collections.singletonList(getInstModification());
494            }
495        }
496        return Collections.<InstModification>emptyList();
497    }
498
499    syn java.util.List<InstModification> InstClassDecl.instModificationsForConstraining() {
500        if (hasInstConstrainingClass()) {
501            if (getInstConstrainingClass().hasInstClassModification())
502                return Collections.singletonList((InstModification) getInstConstrainingClass().getInstClassModification());
503        } else {
504            if (hasInstClassModification())
505                return Collections.singletonList((InstModification) getInstClassModification());
506        }
507        return Collections.<InstModification>emptyList();
508    }
509
510    syn java.util.List<InstModification> InstNode.instModificationsFromConstrainingType() = Collections.<InstModification>emptyList();
511
512    eq InstComponentDecl.instModificationsFromConstrainingType()      = instModificationsForConstraining();
513    eq InstReplacingComposite.instModificationsFromConstrainingType() = getOriginalInstComponent().instModificationsForConstraining();
514    eq InstReplacingRecord.instModificationsFromConstrainingType()    = getOriginalInstComponent().instModificationsForConstraining();
515    eq InstReplacingPrimitive.instModificationsFromConstrainingType() = getOriginalInstComponent().instModificationsForConstraining();
516
517    eq InstClassDecl.instModificationsFromConstrainingType()                     = instModificationsForConstraining();
518    eq InstReplacingFullClassDecl.instModificationsFromConstrainingType()        = getOriginalInstClass().instModificationsForConstraining();
519    eq InstReplacingShortClassDecl.instModificationsFromConstrainingType()       = getOriginalInstClass().instModificationsForConstraining();
520    eq InstReplacingSimpleShortClassDecl.instModificationsFromConstrainingType() = getOriginalInstClass().instModificationsForConstraining();
521
522    syn java.util.List<InstModification> InstComponentRedeclare.instModificationsFromConstrainingType() {
523        InstLookupResult<InstComponentDecl> repl = lookupInstComponentInInstElement(name());
524        if (repl.successful()) 
525            return repl.target().instModificationsFromConstrainingType();
526        else
527            return Collections.<InstModification>emptyList();
528    }
529
530    syn java.util.List<InstModification> InstClassRedeclare.instModificationsFromConstrainingType() {
531        InstLookupResult<InstClassDecl> repl = lookupInstClassInInstElement(name());
532        if (repl.successful()) 
533            return repl.target().instModificationsFromConstrainingType();
534        else
535            return Collections.<InstModification>emptyList();
536    }
537
538    /**
539     * Return OriginalInstClass for nodes that have it, null otherwise.
540     */
541    syn InstClassDecl InstClassDecl.originalInstClass()      = null;
542    eq InstReplacingShortClassDecl.originalInstClass()       = getOriginalInstClass();
543    eq InstReplacingSimpleShortClassDecl.originalInstClass() = getOriginalInstClass();
544    eq InstReplacingFullClassDecl.originalInstClass()        = getOriginalInstClass();
545
546    syn boolean InstClassDecl.hasInstClassModification() = false;
547    // Check in source tree instead of on InstExtends NTA to avoid expanding tree while calculating shouldBeExpanded()
548    eq InstShortClassDecl.hasInstClassModification()     = getSrcClassDecl().hasSrcClassModification();
549    syn InstClassModification InstClassDecl.getInstClassModification() = null;
550    eq InstShortClassDecl.getInstClassModification()                   = getInstExtends(0).getInstClassModification();
551
552    // Check in source tree instead of on InstClassDecl NTA to avoid expanding tree while calculating shouldBeExpanded()
553    syn boolean InstClassRedeclare.hasInstClassModification()     = getSrcClassRedeclare().getSrcBaseClassDecl().hasSrcClassModification();
554
555    /**
556     * Check if there is a constraining clause with modifications.
557     */
558    syn boolean InstElementRedeclare.hasConstrainingModification();
559    // Check in source tree instead of on InstClassDecl NTA to avoid expanding tree while calculating shouldBeExpanded()
560    eq InstClassRedeclare.hasConstrainingModification()     = getSrcClassRedeclare().getSrcBaseClassDecl().hasConstrainingModification();
561    eq InstComponentRedeclare.hasConstrainingModification() = getComponentRedeclareDecl().hasConstrainingModification();
562
563    /**
564     * Check if there is a constraining clause with modifications.
565     */
566    syn boolean SrcElement.hasConstrainingModification()       = false;
567    eq SrcBaseClassDecl.hasConstrainingModification()          = 
568        hasSrcConstrainingClause() && getSrcConstrainingClause().hasSrcClassModification();
569    eq SrcComponentClause.hasConstrainingModification()        = 
570        hasSrcConstrainingClause() && getSrcConstrainingClause().hasSrcClassModification();
571    syn boolean SrcComponentDecl.hasConstrainingModification() = 
572        myComponentClause().hasConstrainingModification();
573
574    syn boolean SrcClassDecl.hasSrcClassModification() = false;
575    eq SrcShortClassDecl.hasSrcClassModification()     = getSrcExtendsClauseShortClass().hasSrcClassModification();
576
577    syn lazy ArrayList<InstModification> InstClassDecl.classInstModifications() = getMergedEnvironment().clone();
578
579    /* getMergedEnvironment gives the environment applicable
580       to the children of the InstNode. It consists of the outer modifications
581       in the environment (with the name of the InstNode itself, if any,
582       removed) merged with potential local modifications.
583    */
584    syn lazy Environment InstNode.getMergedEnvironment() = 
585        filteredEnvironment().mergeInnerClone(getElementInstModifications(), localInstModifications());
586    eq InstForIndexPrimitive.getMergedEnvironment() = new Environment();
587    eq InstExtendsShortClass.getMergedEnvironment() {
588        if (inInstComponent()) {
589            return myEnvironmentNoClass().mergeInnerClone(
590                    getElementInstModifications(), localInstModifications(), myEnvironmentClass());
591        } else {
592            return super.getMergedEnvironment();
593        }
594    }
595   
596    syn lazy Environment InstRecordConstructor.getMergedEnvironment() = 
597        myInstClassDecl().getMergedEnvironment().mergeOuterClone(getInstModifications());
598
599    /**
600     *  Gives the environment filtered on this InstNode. The result includes only include modifications on/for this
601     *  InstNode.
602     */
603    syn Environment InstNode.filteredEnvironment() = nameScope() ? myEnvironment(name()) : myEnvironment();
604
605    eq InstArrayComponentDecl.getMergedEnvironment() {
606        Environment env = super.getMergedEnvironment();
607        for (int i = 0; i < env.size(); i++) {
608            if (env.get(i) instanceof InstValueModification) {
609                InstValueModification ivm = (InstValueModification) env.get(i);
610                FExp exp = ivm.getFExp();
611                if (ivm.getFExp().isArray()) {
612                    env.set(i, ivm.arrayInstModification(getIndex()));
613                }
614            }
615        }
616        return env;
617    }
618
619    /**
620     * Helper method for calculating the environment.
621     */
622    inh Environment InstExtends.myEnvironmentNoClass();
623    inh Environment InstExtends.myEnvironmentClass();
624    eq Root.getChild().myEnvironmentNoClass()              = null;
625    eq Root.getChild().myEnvironmentClass()                = null;
626    eq InstNode.getChild().myEnvironmentNoClass()          = getMergedEnvironment().clone();
627    eq InstNode.getChild().myEnvironmentClass()            = new Environment();
628    eq InstExtends.getChild().myEnvironmentNoClass()       = 
629        myEnvironmentNoClass().mergeInnerClone(getElementInstModifications(), localInstModificationsNoClass());
630    eq InstExtends.getChild().myEnvironmentClass()         = 
631        myEnvironmentClass().mergeInnerClone(localInstModificationsClass());
632    eq InstComponentDecl.getChild().myEnvironmentNoClass() = 
633        filteredEnvironment().mergeInnerClone(getElementInstModifications(), localInstModificationsNoClass());
634    eq InstComponentDecl.getChild().myEnvironmentClass()   = new Environment(localInstModificationsClass());
635
636
637    /**
638     * myEnvironment represents the environment of the InstNode itself. It is defined
639     * as an inherited attribute and is computed from the outer environment located at
640     * ancestor InstNodes.
641     */ 
642    inh Environment InstNode.myEnvironment();
643    inh Environment InstNode.myEnvironment(String name);
644    eq Root.getChild().myEnvironment()            = null;
645    eq Root.getChild().myEnvironment(String name) = null;
646
647    /**
648     * When no arguments are supplied to myEnvironment, the MergedEnvironment of the ancestor
649     * InstNode is simply duplicated. This is typically the case for extends clauses.
650     */
651    eq InstNode.getChild().myEnvironment()                          = getMergedEnvironment().clone();
652    eq InstRecordConstructor.getInstComponentDecl().myEnvironment() = getMergedEnvironment().clone();
653    eq InstRecordConstructor.getInstExtends().myEnvironment()       = getMergedEnvironment().clone();
654    eq InstExpandableConnectorDecl.getInstComponentDecl(int i).myEnvironment()          = 
655        useTemplate(i) ? template(i).myEnvironment() : getMergedEnvironment().clone();
656    eq InstArrayExpandableConnector.getInstComponentDecl(int i).myEnvironment()         = 
657        useTemplate(i) ? template(i).myEnvironment() : getMergedEnvironment().clone();
658    eq InstReplacingExpandableConnectorDecl.getInstComponentDecl(int i).myEnvironment() = 
659        useTemplate(i) ? template(i).myEnvironment() : getMergedEnvironment().clone();
660
661    /**
662     * When a string argument representing a component name is given as argument to myEnvironment,
663     * the environment is filtered on that name.
664     */
665    eq InstNode.getChild().myEnvironment(String name) = myEnvironment_def(name); // This is just to get caching at the right place.
666    eq InstRecordConstructor.getInstComponentDecl().myEnvironment(String name)     = myEnvironment_def(name);
667    eq InstRecordConstructor.getInstExtends().myEnvironment(String name)           = myEnvironment_def(name);
668    eq InstComponentDecl.getInstConstrainingComponent().myEnvironment(String name) = getMergedEnvironment().clone();
669    eq InstBaseClassDecl.getInstConstrainingClass().myEnvironment(String name)     = getMergedEnvironment().clone();
670    // TODO: This seems like the wriong name - shouldn't we filter on template's name?
671    eq InstExpandableConnectorDecl.getInstComponentDecl(int i).myEnvironment(String name)          = 
672        useTemplate(i) ? template(i).myEnvironment(name) : myEnvironment_def(name);
673    eq InstArrayExpandableConnector.getInstComponentDecl(int i).myEnvironment(String name)         = 
674        useTemplate(i) ? template(i).myEnvironment(name) : myEnvironment_def(name);
675    eq InstReplacingExpandableConnectorDecl.getInstComponentDecl(int i).myEnvironment(String name) = 
676        useTemplate(i) ? template(i).myEnvironment(name) : myEnvironment_def(name);
677
678    syn lazy Environment InstNode.myEnvironment_def(String name) = 
679        getMergedEnvironment().filter(name, retrieveReplacingComponent(name), retrieveReplacingClass(name));
680    syn lazy Environment InstRecordConstructor.myEnvironment_def(String name) = 
681        declarationInstComponent(name).filteredEnvironment().mergeOuterClone(getMergedEnvironment().filter(name));
682
683    eq InstReplacingShortClassDecl.getOriginalInstClass().myEnvironment()            = filteredEnvironment();
684    eq InstReplacingShortClassDecl.getOriginalInstClass().myEnvironment(String name) = filteredEnvironment().filter(name);
685
686    inh Environment InstComponentRedeclare.myEnvironment(String name);
687    inh Environment InstClassRedeclare.myEnvironment(String name);
688    inh Environment InstConstraining.myEnvironment(String name);
689
690    // Get environment and add any modifications from constraining
691    eq InstComponentRedeclare.getInstComponentDecl().myEnvironment(String name) =
692        myEnvironment(name).mergeInnerClone(instModificationsFromConstrainingType());
693    eq InstClassRedeclare.getInstClassDecl().myEnvironment(String name)         =
694        myEnvironment(name).mergeInnerClone(instModificationsFromConstrainingType());
695
696    eq InstConstraining.getInstNode().myEnvironment(String name) {
697        Environment env = myEnvironment(name);
698        if (hasInstClassModification())
699            env = env.clone().mergeInner(getInstClassModification());
700        return env;
701    }
702
703    eq Program.getInstProgramRoot().myEnvironment() = new Environment();
704    eq Program.getInstProgramRoot().myEnvironment(String name) = new Environment();
705
706    syn lazy List<InstArrayModification> InstValueModification.getInstArrayModificationList() {
707        List<InstArrayModification> res = new List<InstArrayModification>();
708        if (getFExp().isArray()) {
709            for (int i = 1, n = getFExp().size().get(0) + 1; i < n; i++) {
710                FExp exp = getFExp().splitArrayExp(i);
711                res.add(new InstArrayModification(getSrcModification(), exp));
712            }
713        }
714        return res;
715    }
716
717    /**
718     * Get the InstValueModification corresponding to the specified cell (1-based index) of the array.
719     */
720    syn InstValueModification InstValueModification.arrayInstModification(int i) {
721        int n = getNumInstArrayModification();
722        if (n <= 0) {
723            return this;
724        } else {
725            // Make sure we always return something
726            int j = (i > 0 && i <= n) ? i - 1 : 0;
727            return getInstArrayModification(j);
728        }
729    }
730
731    syn InstModification InstModification.matchInstModification(String name) = null;
732    eq InstCompleteModification.matchInstModification(String name) {
733        for (InstModification im : getInstClassModification().getInstArguments()) {
734            InstModification match = im.matchInstModification(name);
735            if (match != null)
736                return match;
737        }
738        return null;
739    }
740
741    eq InstComponentModification.matchInstModification(String name) {
742        if (name().equals(name))
743            return hasInstModification() ? getInstModification() : null;
744        return null;
745    }
746   
747    // Only add modifiers in constraining clauses
748    eq InstComponentRedeclare.matchInstModification(String name) {
749        if (name().equals(name) && hasConstrainingModification())
750            return getInstComponentDecl().getInstConstrainingComponent().getInstClassModification();
751        return null;
752    }
753
754    // Only add modifiers in constraining clauses
755    eq InstClassRedeclare.matchInstModification(String name) {
756        if (name().equals(name) && hasConstrainingModification())
757            return getInstClassDecl().getInstConstrainingClass().getInstClassModification();
758        return null;
759    }
760   
761   
762    /**
763     * Find the InstModification containing this expression, if any.
764     */
765    inh InstModification FExp.surroundingInstModification();
766    eq InstModification.getChild().surroundingInstModification() = this;
767    eq InstNode.getChild().surroundingInstModification()         = null;
768    eq Root.getChild().surroundingInstModification()             = null;
769   
770   
771    syn InstComponentRedeclare InstModification.matchInstComponentRedeclare(String name) = null;
772    eq InstComponentRedeclare.matchInstComponentRedeclare(String name) {
773        if (getName().name().equals(name))
774            return this;
775        else
776            return null;
777    }
778
779    syn InstClassRedeclare InstModification.matchInstClassRedeclare(String name) = null;
780    eq InstClassRedeclare.matchInstClassRedeclare(String name) {
781        if (getName().name().equals(name))
782            return this;
783        else
784            return null;
785    }
786
787    syn InstComponentRedeclare InstNode.retrieveReplacingComponent(String name) {
788        for (InstModification im : getMergedEnvironment()) {
789            InstComponentRedeclare icr = im.matchInstComponentRedeclare(name);
790            if (icr != null) 
791                return icr;
792        }
793        return null;
794    }
795
796    syn InstComponentRedeclare InstNode.retrieveConstrainingComponent(String name) {
797        for (InstModification im : getMergedEnvironment()) {
798            InstComponentRedeclare icr = im.matchInstComponentRedeclare(name);
799            if (icr != null && icr.getComponentRedeclareDecl().hasSrcConstrainingClause()) 
800                return icr;
801        }
802        return null;
803    }
804
805    // TODO: make sure components are created using the right class now
806    syn InstRedeclareClassNode InstNode.retrieveReplacingClass(String name) {
807        for (InstModification im : getMergedEnvironment()) {
808            InstClassRedeclare icr = im.matchInstClassRedeclare(name);
809            if (icr != null) 
810                return icr;
811        }
812        return null;
813    }
814
815    syn InstRedeclareClassNode InstNode.retrieveConstrainingClass(String name) {
816        for (InstModification im : getMergedEnvironment()) {
817            InstRedeclareClassNode icr = im.matchInstClassRedeclare(name);
818            if (icr != null && icr.redeclaringClassDecl().hasSrcConstrainingClause()) 
819                return icr;
820        }
821        return null;
822    }
823
824    eq InstExtends.retrieveReplacingClass(String name) {
825        InstRedeclareClassNode res = super.retrieveReplacingClass(name);
826        return (res == null) ? lookupReplacingClass(name) : res;
827    }
828   
829    inh InstRedeclareClassNode InstExtends.lookupReplacingClass(String name);
830    eq InstNode.getInstExtends().lookupReplacingClass(String name) {
831        for (InstClassDecl icd : getRedeclaredInstClassDecls())
832                if (icd.name().equals(name))
833                        return icd;
834        return retrieveReplacingClass(name);
835    }
836    eq InstExtends.getChild().lookupReplacingClass(String name) {
837        InstRedeclareClassNode res = lookupReplacingClass(name);
838        if (res != null)
839                return res;
840        for (InstClassDecl icd : getRedeclaredInstClassDecls())
841                if (icd.name().equals(name))
842                        return icd;
843        return super.retrieveReplacingClass(name);
844    }
845    eq InstRoot.getChild().lookupReplacingClass(String name) = null;
846    eq Root.getChild().lookupReplacingClass(String name)     = null;
847
848    inh InstNode InstModification.myInstNode();
849    inh InstNode InstNode.myInstNode();
850    inh InstNode FAbstractEquation.myInstNode();
851    eq Root.getChild().myInstNode()                       = null;
852    eq InstNode.getChild().myInstNode()                   = this;
853    eq InstComponentDecl.getChild().myInstNode()          = 
854        isExpandableConnectorMember() ? myExpandableConnectorTemplate() : this;
855    eq InstNode.getElementInstModification().myInstNode() = myInstNode();
856    eq InstExpandableConnectorDecl.getInstComponentDecl(int i).myInstNode()          = 
857        template(i).myInstNode();
858    eq InstReplacingExpandableConnectorDecl.getInstComponentDecl(int i).myInstNode() = 
859        template(i).myInstNode();
860    eq InstArrayExpandableConnector.getInstComponentDecl(int i).myInstNode()         = 
861        template(i).myInstNode();
862
863    inh InstNode InstModification.myParentInstNode();
864    inh InstNode InstNode.myParentInstNode();
865    eq Root.getChild().myParentInstNode()     = null;
866    eq InstNode.getChild().myParentInstNode() = this;
867
868    //The lexical scope of modifiers for short classes are "outside" of the short declaration
869    eq InstExtendsShortClass.getChild().myInstNode() = getLookupNode();
870
871        /**
872         * InstPrimitive:s may have children of type InstExtends, if the InstPrimitive is instantiated
873         * either from a short class declaration that references a primitive type or from a 'type' class
874         * declaration that inherits a primitive type. In both cases, the result is one or a chain of InstExtends/
875         * InstExtendsShortClass children. The final node in such a chain holds the total merged environment of
876         * the InstPrimitive. InstRecords can of course have InstExtends.
877         */
878        syn lazy Environment InstNode.totalMergedEnvironment() {
879                if (getNumInstExtends()==0)
880                        return getMergedEnvironment();
881                else
882                        return getInstExtends(0).totalMergedEnvironment();
883        }
884    eq InstSimpleShortClassDecl.totalMergedEnvironment() = actualInstClass().getMergedEnvironment();
885    eq InstLibNode.totalMergedEnvironment()              = actualInstClass().getMergedEnvironment();
886
887}
888
889aspect InstanceTreeConstruction {
890
891    syn lazy List Program.getAnonymousClassList() = new List();
892
893    private Map<String,SrcClassDecl> Program.anonymousClassMap = null;
894
895    syn SrcClassDecl Program.anonymousClass(String code, SrcRestriction restriction, String targetName) {
896        if (anonymousClassMap == null)
897            anonymousClassMap = new HashMap<String,SrcClassDecl>();
898        SrcClassDecl res = anonymousClassMap.get(code);
899        if (res == null) {
900            try {
901                addAnonymousClass(root().getUtilInterface().getParserHandler().parseAnonymousClassString(code, restriction, targetName));
902                res = getAnonymousClass(getNumAnonymousClass() - 1);
903                anonymousClassMap.put(code, res);
904            } catch (IOException e) {
905                // Can't normally happen when reading from a string, but just in case
906                throw new RuntimeException("Reading from string failed", e);
907            } catch (beaver.Parser.Exception e) {
908                // Parser crashed - just handle this higher up
909                throw new RuntimeException("Parser crashed", e);
910            } catch (ParserException e) {
911                CompilerException ce = new CompilerException();
912                ce.addProblem(e.getProblem());
913                throw ce;
914            }
915        }
916        return res;
917    }
918
919    syn lazy List InstProgramRoot.getInstAnonymousClassList() = new List();
920
921    syn lazy InstClassDecl InstProgramRoot.instantiateModel(String className) {
922        int p = className.indexOf('(');
923        if (p >= 0) {
924            String targetName = className.substring(0, p);
925            InstLookupResult<InstClassDecl> icd = lookupInstClassQualified(targetName);
926            if (icd.successful()) {
927                SrcRestriction restriction = ((SrcBaseClassDecl) icd.target().actualInstClass().getSrcClassDecl()).getSrcRestriction();
928                SrcClassDecl cl = sourceRoot().getProgram().anonymousClass(className, restriction, targetName);
929                if (cl != null) {
930                    addInstAnonymousClass(createInstClassDecl(cl));
931                    return getInstAnonymousClass(getNumInstAnonymousClass() - 1);
932                }
933            }
934            return unknownInstClassDecl();
935        } else {
936            InstLookupResult<InstClassDecl> icd = lookupInstClassQualified(className);
937            return icd.successful() ? icd.target() : unknownInstClassDecl();
938        }
939    }
940
941    syn nta Opt InstNode.getDynamicFExpOpt()                       = new DynamicOpt();
942    syn nta Opt InstExternal.getDynamicFExpOpt()                   = new DynamicOpt();
943    syn nta Opt FExp.getDynamicFExpOpt()                           = new DynamicOpt();
944        syn nta Opt FAbstractEquation.getDynamicFAbstractEquationOpt() = new DynamicOpt();     
945        syn nta Opt FVariable.getDynamicFVariableOpt()                 = new DynamicOpt();
946       
947        /**
948         * Dynamically places an FExp in the tree under this InstNode.
949         *
950         * @return  the final version of the dynamically placed node.
951         */
952        public FExp InstNode.dynamicFExp(FExp exp) {
953                getDynamicFExpOpt().setChild(exp, 0);
954                return (FExp) getDynamicFExpOpt().getChild(0);
955        }
956
957    public void InstNode.clearDynamicFExp() {
958       getDynamicFExpOpt().setChild(null, 0);
959    }
960
961    /**
962     * Dynamically places an FExp in the tree under this InstExternal.
963     *
964     * @return  the final version of the dynamically placed node.
965     */
966    public FExp InstExternal.dynamicFExp(FExp exp) {
967        getDynamicFExpOpt().setChild(exp, 0);
968        return (FExp) getDynamicFExpOpt().getChild(0);
969    }
970       
971       
972        /**
973         * Dynamically places an FExp in the tree under this FExp.
974         *
975         * If <code>exp</code> is already in tree of if <code>exp == this</code>,
976         * then <code>exp</code> is returned.
977         *
978         * @return  the final version of the dynamically placed node.
979         */
980        public FExp FExp.dynamicFExp(FExp exp) {
981                if (exp == this || exp == null)
982                        return exp;
983                if (exp.parent != null) {
984                        int i = exp.parent.getIndexOfChild(exp);
985                        if (i >= 0)
986                                return (FExp) exp.parent.getChild(i);
987                }
988                getDynamicFExpOpt().setChild(exp, 0);
989                return (FExp) getDynamicFExpOpt().getChild(0);
990        }
991   
992    public FVariable FVariable.dynamicFVariable(FVariable fv) {
993        if (fv == this)
994            return fv;
995        if (fv.parent != null) {
996            int i = fv.parent.getIndexOfChild(fv);
997            if (i >= 0)
998                return (FVariable) fv.parent.getChild(i);
999        }
1000        getDynamicFVariableOpt().setChild(fv, 0);
1001        return (FVariable) getDynamicFVariableOpt().getChild(0);
1002    }
1003   
1004    /**
1005     * Dynamically places an FAbstractEquation in the tree under this FAbstractEquation.
1006     *
1007     * @return  the final version of the dynamically placed node.
1008     */
1009    public FAbstractEquation FAbstractEquation.dynamicFAbstractEquation(FAbstractEquation eqn) {
1010        if (eqn == this)
1011            return eqn;
1012        getDynamicFAbstractEquationOpt().setChild(eqn, 0);
1013        return (FAbstractEquation) getDynamicFAbstractEquationOpt().getChild(0);
1014    }
1015
1016
1017    public interface InstLookupRedirectNode {
1018        InstLookupResult<InstClassDecl> lookupInstClassRedirect(String name);
1019    }
1020
1021        InstNode implements InstLookupRedirectNode;
1022        InstModification implements InstLookupRedirectNode;
1023
1024    syn lazy List InstNode.getInstComponentDeclList() {
1025        List<InstComponentDecl> l = new List<InstComponentDecl>();
1026        for (SrcComponentDecl cd : components()) {
1027            if (!cd.hasRedeclare()) {
1028                l.add(createInstComponentDecl(cd));
1029            }
1030        }
1031        return l;
1032       
1033    }
1034
1035    eq InstComponentDecl.getInstComponentDeclList() {
1036        //System.out.println( " : " + getClass().getName() + " : "+ myFSubscripts().size());
1037        if (isArray()) { // Take care of array declarations separately
1038            // Loop over indices and create new InstArrayComponentDecls
1039            List l = new List();
1040            // Only one FSubscript is used to create the one layer of InstArrayComponentDecls.
1041            // For a zero length or unknown length, create a dummy node with index 0.
1042            int n = childDimensionLength();
1043            for (int i = (n < 1) ? 0 : 1; i <= n || i == 0; i++)
1044                l.add(createInstArrayComponentDecl(i));
1045            return l;
1046        } else { // If not array, then proceed as usual
1047            return super.getInstComponentDeclList();
1048        }
1049    }
1050
1051    public InstComponentDecl InstComponentDecl.createInstArrayComponentDecl(int i) {
1052        return new InstArrayComponentDecl(name(), new InstClassAccess("ArrayDecl"), new Opt(), 
1053                getSrcComponentDecl(), new Opt(), new Opt(), new Opt(), i);
1054    }
1055
1056    syn lazy List InstNode.getInstClassDeclList() {
1057        List l = new List();
1058       
1059        for (SrcClassDecl cd : classes()) {
1060            if (!cd.hasRedeclare()) {
1061                InstClassDecl icd = createInstClassDecl(cd);
1062                if (icd != null)
1063                    l.add(icd);
1064            }
1065        }
1066       
1067        return l;
1068    }
1069
1070    syn lazy List InstNode.getRedeclaredInstClassDeclList() {
1071        List l = new List();
1072       
1073        for (SrcClassDecl cd : classes()) {
1074            if (cd.hasRedeclare()) {
1075                InstNode icd = cd.newInstClassDecl();
1076                if (icd != null)
1077                    l.add(icd);
1078            }
1079        }
1080       
1081        return l;
1082    }
1083
1084    syn boolean SrcClassDecl.getRedeclare() = false;
1085
1086    syn boolean SrcClassDecl.hasRedeclare() = getRedeclare();
1087    eq SrcExtendClassDecl.hasRedeclare()    = true;
1088
1089    syn lazy List InstNode.getInstExtendsList() {
1090        List l = new List();
1091        if (shouldHaveInstExtendsList()) {
1092            InstNode lookup = instLookupNodeForShortClassExtends();
1093            for (SrcExtendsClause e : superClasses()) { 
1094                l.add(createInstExtends(e, lookup));
1095            }
1096        }
1097        return l;
1098    }
1099
1100    syn boolean InstNode.shouldHaveInstExtendsList()      = true;
1101    eq InstComponentDecl.shouldHaveInstExtendsList()      = !isArrayDecl();
1102    eq InstArrayComponentDecl.shouldHaveInstExtendsList() = childDimensionLength() == Size.UNKNOWN;
1103
1104    /**
1105     * Find the instance tree node an extends below this node, from a short class declaration,
1106     * should look up right hand side names in its modification from.
1107     */
1108    syn InstNode InstNode.instLookupNodeForShortClassExtends()          = myInstClass().instLookupNodeForShortClassExtends();
1109    eq InstClassDecl.instLookupNodeForShortClassExtends()               = null;
1110    eq InstShortClassDecl.instLookupNodeForShortClassExtends()          = this;
1111    eq InstReplacingShortClassDecl.instLookupNodeForShortClassExtends() = getInstClassRedeclare().instLookupNodeForShortClassExtends();
1112    eq InstLibNode.instLookupNodeForShortClassExtends()                 = resolveLib().instLookupNodeForShortClassExtends();
1113
1114    syn InstNode InstClassRedeclare.instLookupNodeForShortClassExtends() = myInstNode();
1115
1116    eq InstPrimitive.getInstComponentDeclList() = new List();
1117    eq InstPrimitive.getInstClassDeclList() = new List();
1118
1119    syn lazy List<InstComponentDecl> InstRecordConstructor.getInstComponentDeclList() {
1120        InstClassDecl rec = getRecord().myInstClassDecl().actualInstClass();
1121        List<InstComponentDecl> l = new List<InstComponentDecl>();
1122        for (SrcComponentDecl cd : rec.components()) 
1123            l.add(rec.createInstComponentDecl(cd));
1124        return l;
1125    }
1126
1127    syn lazy List<InstExtends> InstRecordConstructor.getInstExtendsList() {
1128        InstClassDecl rec = getRecord().myInstClassDecl().actualInstClass();
1129        List l = new List();
1130        InstNode lookup = myInstClassDecl().instLookupNodeForShortClassExtends();
1131        for (SrcExtendsClause e : rec.superClasses()) 
1132            l.add(rec.createInstExtends(e, lookup));
1133        return l;
1134    }
1135
1136    syn lazy List<InstModification> InstRecordConstructor.getInstModificationList() {
1137        List<InstModification> res = new List<InstModification>();
1138        for (InstFunctionArgument ifa : getArgs()) {
1139            ifa.populateInstModifications(res);
1140        }
1141        return res;
1142    }
1143
1144    public void InstFunctionArgument.populateInstModifications(List<InstModification> res) {}
1145
1146    public void InstPositionalArgument.populateInstModifications(List<InstModification> res) {
1147        res.add(newInstModification());
1148    }
1149
1150    public void InstNamedArgument.populateInstModifications(List<InstModification> res) {
1151        res.add(newInstModification());
1152    }
1153
1154    syn InstModification InstFunctionArgument.newInstModification() = 
1155            new InstComponentModification(getSrcModification(), false, false,
1156                    boundInput.createInstAccess(),
1157                    new Opt<InstModification>(getSrcModification().newInstModification()));
1158
1159    syn InstValueModification SrcDummyModification.newInstModification() = new InstValueModification(this);
1160
1161    syn nta SrcModification InstFunctionArgument.getSrcModification() {
1162        SrcDummyModification res = new SrcDummyModification();
1163        copyLocationTo(res);
1164        return res;
1165    }
1166
1167
1168    syn lazy List<InstModification> InstNode.getElementInstModificationList() {
1169        List<InstModification> l = new List<InstModification>();
1170        for (SrcModificationOrRedeclareElement m : elementModifications()) 
1171            l.add(m.newInstModification());
1172        return l;
1173    }
1174
1175
1176    public InstComponentDecl InstNode.createInstComponentDecl(SrcComponentDecl cd) {
1177        // Check if the component is redeclared.
1178        // -> Yes: Create an InstReplacingComponent component
1179        // -> No: Create an InstComponent
1180        InstComponentRedeclare irc = retrieveReplacingComponent(cd.name());
1181        InstComponentRedeclare cicr = retrieveConstrainingComponent(cd.name());
1182        if (irc!=null) {
1183            SrcComponentDecl replacingComp = irc.getComponentRedeclareDecl();
1184            return new InstCreateReplacingComponentDecl(replacingComp, irc, cd, irc, cicr);
1185            // TODO: handle expandable connectors in this case
1186        } else { 
1187            return new InstCreateComponentDecl(cd, null);
1188        }
1189     }
1190
1191     rewrite InstCreateReplacingComponentDecl {
1192         to InstComponentDecl getClassName().myInstClassDecl().newInstReplacingComponent(
1193                 getSrcComponentDecl(), getOriginalDecl(), 
1194                 getInstComponentRedeclare(), getInstConstrainingRedeclare());
1195     }
1196     
1197     rewrite InstCreateComponentDecl {
1198         to InstComponentDecl getClassName().myInstClassDecl().newInstComponentDecl(getSrcComponentDecl());
1199     }
1200     
1201     rewrite InstCreateForIndexPrimitive {
1202         to InstPrimitive (InstPrimitive) getClassName().myInstClassDecl().newInstComponentDecl(getSrcComponentDecl());
1203     }
1204
1205     public InstClassDecl InstNode.createInstClassDecl(SrcClassDecl bcd) {
1206         // Check if the class is redeclared.
1207         // -> Yes: Create an InstReplacingClass component
1208         // -> No: Create an InstClassDecl
1209         InstRedeclareClassNode icr = retrieveReplacingClass(bcd.name());
1210         InstRedeclareClassNode cicr = retrieveConstrainingClass(bcd.name());
1211         if (icr != null) {
1212             SrcClassDecl replacingClass = icr.redeclaringClassDecl();
1213             return bcd.newInstReplacingClass(replacingClass, icr, cicr);
1214         } else {
1215             return bcd.newInstClassDecl();
1216         }
1217     }
1218
1219     public interface InstRedeclareClassNode {
1220         public InstLookupResult<InstComponentDecl> lookupInstComponent(String name);
1221         public InstLookupResult<InstClassDecl> lookupInstClass(String name);
1222         public InstLookupResult<InstClassDecl> lookupInstClassQualified(String name);
1223         public SrcClassDecl redeclaringClassDecl();
1224         public InstClassDecl redeclaringInstClassDecl();
1225         public InstNode instLookupNodeForShortClassExtends();
1226     }
1227    InstClassDecl implements InstRedeclareClassNode;
1228    InstClassRedeclare implements InstRedeclareClassNode;
1229
1230    syn SrcClassDecl InstClassDecl.redeclaringClassDecl()      = getSrcClassDecl();
1231    syn SrcClassDecl InstClassRedeclare.redeclaringClassDecl() = getSrcClassRedeclare().getSrcBaseClassDecl();
1232
1233    syn InstClassDecl InstClassDecl.redeclaringInstClassDecl()      = this;
1234    syn InstClassDecl InstClassRedeclare.redeclaringInstClassDecl() = getInstClassDecl();
1235
1236    public InstNode InstNode.createInstExtends(SrcExtendsClause ec, InstNode lookup) {
1237        // This cannot be redeclared. Just create and return.
1238        return ec.newInstExtends(lookup);
1239    }
1240
1241    public InstNode InstReplacingShortClassDecl.createInstExtends(SrcExtendsClause ec, InstNode lookup) {
1242        return createInstExtendsCheckReplacing(ec, lookup);
1243    }
1244
1245    public InstNode InstReplacingSimpleShortClassDecl.createInstExtends(SrcExtendsClause ec, InstNode lookup) {
1246        return createInstExtendsCheckReplacing(ec, lookup);
1247    }
1248
1249    public InstNode InstExtendsShortClass.createInstExtends(SrcExtendsClause ec, InstNode lookup) {
1250        return createInstExtendsCheckReplacing(ec, lookup);
1251    }
1252
1253    public InstNode InstReplacingExtendsShortClass.createInstExtends(SrcExtendsClause ec, InstNode lookup) {
1254        return createInstExtendsCheckReplacing(ec, lookup);
1255    }
1256
1257    public InstNode InstNode.createInstExtendsCheckReplacing(SrcExtendsClause ec, InstNode lookup) {
1258        if (!isInInstModification() && ec.needsReplacingExtends()) {
1259            Environment e = myEnvironment();
1260            InstModification im = findMatching(e, name());
1261            if (im != null)
1262                return im.createInstReplacingExtends(ec, lookup);
1263        }
1264        return ec.newInstExtends(lookup);
1265    }
1266
1267    public InstExtends InstModification.createInstReplacingExtends(SrcExtendsClause ec, InstNode lookup) {
1268        return ec.newInstExtends(lookup);
1269    }
1270
1271    public InstExtends InstClassRedeclare.createInstReplacingExtends(SrcExtendsClause ec, InstNode lookup) {
1272        for (InstExtends ie : getInstClassDecl().actualInstClass().getInstExtendss())
1273            return ie.createInstReplacingExtends(ec, lookup);
1274        return ec.newInstExtends(lookup);
1275    }
1276
1277    public InstExtends InstShortClassDecl.createInstReplacingExtends(SrcExtendsClause ec, InstNode lookup) {
1278        for (InstExtends ie : getInstExtendss())
1279            return ie.createInstReplacingExtends(ec, lookup);
1280        return ec.newInstExtends(lookup);
1281    }
1282
1283    public InstExtends InstSimpleShortClassDecl.createInstReplacingExtends(SrcExtendsClause ec, InstNode lookup) {
1284        return actualInstClass().createInstReplacingExtends(ec, lookup);
1285    }
1286
1287    public InstExtends InstLibNode.createInstReplacingExtends(SrcExtendsClause ec, InstNode lookup) {
1288        return actualInstClass().createInstReplacingExtends(ec, lookup);
1289    }
1290
1291    public InstExtends InstNode.createInstReplacingExtends(SrcExtendsClause ec, InstNode lookup) {
1292        return ec.newInstExtends(lookup);
1293    }
1294
1295    public InstExtends InstExtendsShortClass.createInstReplacingExtends(SrcExtendsClause ec, InstNode lookup) {
1296        return ec.newInstReplacingExtends(this);
1297    }
1298
1299    eq InstNamedModification.matches(String str) = name().equals(str);
1300
1301    inh boolean InstNode.isInInstModification();
1302    eq InstModification.getChild().isInInstModification() = true;
1303    eq InstRoot.getChild().isInInstModification()         = false;
1304    eq Root.getChild().isInInstModification()             = false;
1305
1306    syn boolean SrcExtendsClause.needsReplacingExtends()  = false;
1307    eq SrcExtendsClauseShortClass.needsReplacingExtends() = true;
1308
1309
1310    public InstComponentDecl InstClassDecl.newInstComponentDecl(SrcComponentDecl cd) {
1311        return newInstComponentDecl(cd, cd.getClassName());
1312    }
1313
1314    public InstComponentDecl InstClassDecl.newInstComponentDecl(SrcComponentDecl cd, SrcAccess className) {
1315        InstComponentDecl icd = newInstComponentDeclGeneric(cd.name(), cd, className);
1316        if (cd.hasSrcArraySubscripts()) {
1317            icd.setLocalFArraySubscripts(cd.instantiateArraySubscripts());
1318        }
1319        if (cd.hasSrcConditionalAttribute())
1320            icd.setConditionalAttribute(cd.getSrcConditionalAttribute().getSrcExp().instantiate());
1321        return icd;
1322    }
1323
1324    public InstComponentDecl InstClassDecl.newInstComponentDeclCopy(
1325            String name, FArraySubscripts subscripts, SrcComponentDecl cd, SrcAccess className) {
1326        InstComponentDecl icd = newInstComponentDeclGeneric(name, cd, className);
1327        if (subscripts != null) {
1328            icd.setLocalFArraySubscripts(subscripts);
1329        }
1330        return icd;
1331    }
1332
1333    public abstract InstComponentDecl InstClassDecl.newInstComponentDeclGeneric(String name, SrcComponentDecl cd, SrcAccess className);
1334
1335    public InstComponentDecl InstBaseClassDecl.newInstComponentDeclGeneric(String name, SrcComponentDecl cd, SrcAccess className) {
1336        InstComponentDecl icd = emptyInstComponentDecl(name, cd, className.newInstAccess());
1337        if (cd.hasSrcModification()) {
1338            icd.setInstModification(cd.getSrcModification().newInstModification());
1339        }
1340        icd.setInstConstrainingComponentOpt(cd.newInstConstrainingComponentOpt(null));
1341        icd.setLocation(cd.myComponentClause());
1342        return icd;
1343    }
1344
1345    public InstComponentDecl InstSimpleShortClassDecl.newInstComponentDeclGeneric(String name, SrcComponentDecl cd, SrcAccess className) {
1346        return actualInstClass().newInstComponentDeclGeneric(name, cd, className);
1347    }
1348
1349    public InstComponentDecl InstLibNode.newInstComponentDeclGeneric(String name, SrcComponentDecl cd, SrcAccess className) {
1350        return actualInstClass().newInstComponentDeclGeneric(name, cd, className);
1351    }
1352
1353    public InstComponentDecl BadInstClassDecl.newInstComponentDeclGeneric(String name, SrcComponentDecl cd, SrcAccess className) {
1354        throw new UnsupportedOperationException();
1355    }
1356
1357    public InstComponentDecl InstBaseClassDecl.emptyInstComponentDecl(String name, SrcComponentDecl cd, InstAccess className) {
1358        if (isRecord()) 
1359            return new InstRecord(name, className, new Opt(), cd, new Opt(), new Opt(), new Opt());
1360        else if (extendsEnum()) 
1361            return new InstEnum(name, className, new Opt(), cd, new Opt(), new Opt(), new Opt());
1362        else if (isExternalObject())
1363            return new InstExternalObject(name, className, new Opt(), cd, new Opt(), new Opt(), new Opt());
1364        else if (extendsPrimitive()) 
1365            return new InstPrimitive(name, className, new Opt(), cd, new Opt(), new Opt(), new Opt());
1366        else if (isExpandableConnector())
1367            return new InstExpandableConnectorDecl(name, className, new Opt(), cd, new Opt(), new Opt(), new Opt());
1368        else if (isPartialFunction())
1369            return new InstPartialFunction(name, className, new Opt(), cd, new Opt(), new Opt(), new Opt());
1370        else
1371            return new InstComposite(name, className, new Opt(), cd, new Opt(), new Opt(), new Opt());
1372    }
1373
1374    public InstComponentDecl InstPrimitiveClassDecl.emptyInstComponentDecl(String name, SrcComponentDecl cd, InstAccess className) {
1375        return new InstPrimitive(name, className, new Opt(), cd, new Opt(), new Opt(), new Opt());
1376    }
1377
1378    public InstComponentDecl InstEnumClassDecl.emptyInstComponentDecl(String name, SrcComponentDecl cd, InstAccess className) {
1379        return new InstEnum(name, className, new Opt(), cd, new Opt(), new Opt(), new Opt());
1380    }
1381
1382    public InstComponentDecl InstBuiltInClassDecl.newInstComponentDeclGeneric(String name, SrcComponentDecl cd, SrcAccess className) {
1383        if (cd.isEnumLiteral()) 
1384            return new InstEnumLiteral(name, className.newInstAccess(), new Opt(), cd, new Opt(), new Opt(), new Opt());   
1385        else 
1386            return new InstBuiltIn(name, className.newInstAccess(), new Opt(), cd, new Opt(), new Opt(), new Opt());
1387    }
1388
1389    public InstComponentDecl InstClassDecl.newInstConstrainingComponentDecl(SrcComponentDecl cd, SrcAccess className) {
1390        InstComponentDecl icd = newInstComponentDecl(cd, className);
1391        icd.setInstConstrainingComponentOpt(new Opt());
1392        return icd;
1393    }
1394
1395    public abstract InstComponentDecl InstClassDecl.newInstReplacingComponent(
1396            SrcComponentDecl replacingDecl, SrcComponentDecl originalDecl, 
1397            InstComponentRedeclare icr, InstComponentRedeclare cicr);
1398
1399    // TODO: Should probably represent different var & type subscripts in instance tree as well
1400    public FArraySubscripts SrcComponentDecl.instantiateArraySubscripts() {
1401        FArrayExpSubscripts fas = null;
1402        if (hasVarArraySubscripts()) {
1403            fas = getVarArraySubscripts().instantiate();
1404        }
1405        if (hasTypeArraySubscripts()) {
1406            FArrayExpSubscripts fas2 = getTypeArraySubscripts().instantiate();
1407            if (fas == null) {
1408                fas = fas2;
1409            } else {
1410                for (FSubscript s : fas2.getFSubscripts()) {
1411                    fas.addFSubscript(s);
1412                }
1413            }
1414        }
1415        return fas;
1416    }
1417
1418    public InstComponentDecl InstBaseClassDecl.newInstReplacingComponent(
1419            SrcComponentDecl replacingDecl, SrcComponentDecl originalDecl, 
1420            InstComponentRedeclare icr, InstComponentRedeclare cicr) {
1421        Opt fas_opt = new Opt();
1422        if (replacingDecl.hasSrcArraySubscripts()) {
1423            fas_opt.setChild(replacingDecl.instantiateArraySubscripts(), 0);
1424        }
1425        Opt cond_attr_opt = new Opt();
1426        if (originalDecl.hasSrcConditionalAttribute()) {
1427            cond_attr_opt.setChild(originalDecl.getSrcConditionalAttribute().getSrcExp().instantiate(), 0);
1428        }
1429        String name = replacingDecl.name();
1430        InstAccess className = replacingDecl.newInstClassAccess();
1431       
1432        InstComponentDecl icd;
1433        if (isPrimitive()) {
1434            icd = new InstReplacingPrimitive(name, className, fas_opt, 
1435                    replacingDecl, new Opt(), new Opt(), cond_attr_opt, originalDecl, icr);
1436        } else if (isRecord()) {
1437            icd = new InstReplacingRecord(name, className, fas_opt, 
1438                    replacingDecl, new Opt(), new Opt(), cond_attr_opt, originalDecl, icr);
1439        } else {
1440            if (isExpandableConnector()) {
1441                icd = new InstReplacingExpandableConnectorDecl(name, className, fas_opt, 
1442                        replacingDecl, new Opt(), new Opt(), cond_attr_opt, originalDecl, icr);
1443            } else {
1444                icd = new InstReplacingComposite(name, className, fas_opt, 
1445                        replacingDecl, new Opt(), new Opt(), cond_attr_opt, originalDecl, icr);
1446            }
1447        }
1448       
1449        SrcComponentDecl constrainingDecl = (cicr == null) ? originalDecl : cicr.getComponentRedeclareDecl();
1450        icd.setInstConstrainingComponentOpt(constrainingDecl.newInstConstrainingComponentOpt(cicr));
1451        icd.setLocation(originalDecl);
1452        return icd;
1453    }
1454
1455    public InstComponentDecl InstLibNode.newInstReplacingComponent(
1456            SrcComponentDecl replacingDecl, SrcComponentDecl originalDecl, 
1457            InstComponentRedeclare icr, InstComponentRedeclare cicr) {
1458        return resolveLib().newInstReplacingComponent(replacingDecl, originalDecl, icr, cicr);
1459    }
1460
1461    // This cannot be done.
1462    public InstComponentDecl InstBuiltInClassDecl.newInstReplacingComponent(
1463            SrcComponentDecl replacingDecl, SrcComponentDecl originalDecl, 
1464            InstComponentRedeclare icr, InstComponentRedeclare cicr) {
1465        throw new UnsupportedOperationException();
1466    }
1467
1468    public InstComponentDecl BadInstClassDecl.newInstReplacingComponent(
1469            SrcComponentDecl replacingDecl, SrcComponentDecl originalDecl, 
1470            InstComponentRedeclare icr, InstComponentRedeclare cicr) {
1471        throw new UnsupportedOperationException();
1472    }
1473
1474    public InstClassDecl SrcClassDecl.newInstClassDecl() {
1475        return new UnknownInstClassDecl();
1476    }
1477   
1478    public Opt<InstExternal> SrcFullClassDecl.newInstExternalOpt() {
1479        return hasSrcExternalClause() ? new Opt(getSrcExternalClause().instantiate()) : new Opt();
1480    }
1481
1482    public InstFullClassDecl SrcFullClassDecl.newInstClassDecl() {
1483        InstFullClassDecl fcd = new InstFullClassDecl(this, new Opt(), newInstRestriction(), newInstExternalOpt());
1484        fcd.setInstConstrainingClassOpt(newInstConstrainingClassOpt(null));
1485        fcd.setLocation(this);
1486        return fcd;
1487    }
1488
1489    public InstExtendClassDecl SrcExtendClassDecl.newInstClassDecl() {
1490        // TODO: Shouldn't extending class decl be able to have an external clause?
1491        InstExtendClassDecl ecd = new InstExtendClassDecl(this, new Opt(), newInstRestriction(), new Opt());
1492        ecd.setInstConstrainingClassOpt(newInstConstrainingClassOpt(null));
1493        ecd.setLocation(this);
1494        return ecd;
1495    }
1496
1497    public InstShortClassDecl SrcShortClassDecl.newInstClassDecl() {
1498        Opt fas_opt = new Opt();
1499        if (getSrcExtendsClauseShortClass().hasSrcArraySubscripts()) {
1500            fas_opt.setChild(getSrcExtendsClauseShortClass().getSrcArraySubscripts().instantiate(),0);
1501        }
1502        InstShortClassDecl scd =  new InstShortClassDecl(this, new Opt(), 
1503                newInstRestriction(),fas_opt);
1504        scd.setInstConstrainingClassOpt(newInstConstrainingClassOpt(null));     
1505        scd.setLocation(this);
1506        return scd;
1507    }
1508
1509    public InstPrimitiveClassDecl SrcPrimitiveClassDecl.newInstClassDecl() {
1510        return new InstPrimitiveClassDecl(this, new Opt(), newInstRestriction(), newInstExternalOpt());
1511    }
1512
1513    public InstBuiltInClassDecl SrcBuiltInClassDecl.newInstClassDecl() {
1514        return new InstBuiltInClassDecl(this);
1515    }
1516
1517    public InstLibNode SrcLibNode.newInstClassDecl() {
1518        return new InstLibNode(this);
1519    }
1520
1521    public InstEnumClassDecl SrcEnumClassDecl.newInstClassDecl() {
1522        InstEnumClassDecl ecd = new InstEnumClassDecl(this, new Opt(), newInstRestriction(), newInstExternalOpt());
1523        ecd.setLocation(this);
1524        return ecd;
1525    }
1526
1527    public BadInstClassDecl SrcBadClassDecl.newInstClassDecl() {
1528        return new BadInstClassDecl(this);
1529    }
1530
1531    public InstClassDecl SrcClassDecl.newInstReplacingClass(
1532            SrcClassDecl replacingClass, InstRedeclareClassNode icr, InstRedeclareClassNode cicr) {
1533        return replacingClass.createInstReplacingClass(this, icr, cicr);
1534    }
1535
1536    public InstClassDecl SrcClassDecl.createInstReplacingClass(
1537            SrcClassDecl replacedClass, InstRedeclareClassNode icr, InstRedeclareClassNode cicr) {
1538        return null;
1539    }
1540
1541    public InstClassDecl SrcFullClassDecl.createInstReplacingClass(
1542            SrcClassDecl replacedClass, InstRedeclareClassNode icr, InstRedeclareClassNode cicr) {
1543        InstRestriction ir = newInstRestriction();
1544        Opt<InstExternal> exto = newInstExternalOpt();
1545        SrcClassDecl constrainingDecl = (cicr == null) ? replacedClass : cicr.redeclaringClassDecl();
1546        InstReplacingFullClassDecl fcd = new InstReplacingFullClassDecl(this, new Opt(), ir, exto, replacedClass, icr);
1547        fcd.setInstConstrainingClassOpt(constrainingDecl.newInstConstrainingClassOpt(cicr));
1548        //TODO: Should be constr clause of original or redeclared?
1549        // - Should be from redeclared if it has one.
1550        fcd.setLocation(this);
1551        return fcd;
1552    }
1553
1554    public InstClassDecl SrcShortClassDecl.createInstReplacingClass(
1555            SrcClassDecl replacedClass, InstRedeclareClassNode icr, InstRedeclareClassNode cicr) {
1556        Opt fas_opt = new Opt();
1557        if (getSrcExtendsClauseShortClass().hasSrcArraySubscripts()) {
1558            fas_opt.setChild(getSrcExtendsClauseShortClass().getSrcArraySubscripts().instantiate(), 0);
1559        }
1560        SrcClassDecl constrainingDecl = (cicr == null) ? replacedClass : cicr.redeclaringClassDecl();
1561        InstRestriction ir = newInstRestriction();
1562        InstReplacingShortClassDecl scd =  new InstReplacingShortClassDecl(this, new Opt(), ir, fas_opt, replacedClass, icr);
1563        scd.setInstConstrainingClassOpt(constrainingDecl.newInstConstrainingClassOpt(cicr));
1564        scd.setLocation(this);
1565        return scd;
1566     }
1567
1568    // Create InstRestriction
1569    public InstRestriction SrcBaseClassDecl.newInstRestriction() {
1570        return getSrcRestriction().newInstRestriction();
1571    }
1572   
1573    public abstract InstRestriction SrcRestriction.newInstRestriction();
1574    public InstModel               SrcModel.newInstRestriction()               { return new InstModel(); }
1575    public InstBlock               SrcBlock.newInstRestriction()               { return new InstBlock(); }
1576    public InstMClass              SrcClass.newInstRestriction()              { return new InstMClass(); }
1577    public InstConnector           SrcConnector.newInstRestriction()           { return new InstConnector(); }
1578    public InstExpandableConnector SrcExpandableConnector.newInstRestriction() { return new InstExpandableConnector(); }
1579    public InstMType               SrcType.newInstRestriction()               { return new InstMType(); }
1580    public InstMPackage            SrcPackage.newInstRestriction()            { return new InstMPackage(); }
1581    public InstFunction            SrcFunction.newInstRestriction()            { return new InstFunction(); }
1582    public InstMRecord             SrcRecord.newInstRestriction()              { return new InstMRecord(); }
1583    public InstOperator            SrcOperator.newInstRestriction()            { return new InstOperator(); }
1584    public InstOperatorFunction    SrcOperatorFunction.newInstRestriction()    { return new InstOperatorFunction(); }
1585    public InstOperatorRecord      SrcOperatorRecord.newInstRestriction()      { return new InstOperatorRecord(); }
1586
1587    /**
1588     * A connector class inheriting a record class is both connector and record,
1589     * this method finds any inherited restriction that should be kept.
1590     */
1591    syn InstRestriction InstRestriction.inheritedRestriction()       = null;
1592    eq InstMRecord.inheritedRestriction()                            = this;
1593    eq InstOperatorRecord.inheritedRestriction()                     = this;
1594    inh lazy InstRestriction InstConnector.inheritedRestriction();
1595    eq InstBaseClassDecl.getInstRestriction().inheritedRestriction() = inheritedRestriction(false);
1596   
1597    /**
1598     * A connector class inheriting a record class is both connector and record,
1599     * this method finds any inherited restriction that should be kept.
1600     */
1601    syn InstRestriction InstClassDecl.inheritedRestriction(boolean checkMine) = null;
1602    eq InstSimpleShortClassDecl.inheritedRestriction(boolean checkMine)       = 
1603        actualInstClass().inheritedRestriction(true);
1604    eq InstLibNode.inheritedRestriction(boolean checkMine)                    = 
1605        actualInstClass().inheritedRestriction(true);
1606    eq InstBaseClassDecl.inheritedRestriction(boolean checkMine) {
1607        if (checkMine)
1608            return getInstRestriction().inheritedRestriction();
1609        for (InstExtends ie : getInstExtendss()) {
1610            InstRestriction ir = ie.myInstClass().inheritedRestriction(true);
1611            if (ir != null)
1612                return ir;
1613        }
1614        return null;
1615    }
1616
1617    // Build an InstExtends
1618    public InstExtends SrcExtendsClause.newInstExtends(InstNode lookup) {
1619        InstNormalExtends ie = newEmptyInstExtends(lookup);
1620        ie.setClassName(getSuper().newInstAccess());
1621        ie.setSrcExtendsClause(this);
1622        if (hasSrcClassModification())
1623            ie.setInstClassModification(getSrcClassModification().newInstModification());
1624        ie.setLocation(this);
1625        return ie;
1626    }
1627
1628    public InstExtends SrcExtendsClause.newInstReplacingExtends(InstExtendsShortClass iesc) {
1629        InstReplacingExtendsShortClass ie = new InstReplacingExtendsShortClass();
1630        ie.setClassName(getSuper().newInstAccess());
1631        ie.setSrcExtendsClause(this);
1632        ie.setInstExtendsShortClass(iesc);
1633        ie.setLocation(this);
1634        return ie;
1635    }
1636
1637    public InstNormalExtends SrcExtendsClause.newEmptyInstExtends(InstNode lookup) {
1638        return new InstNormalExtends();
1639    }
1640
1641    public InstNormalExtends SrcExtendsClauseShortClass.newEmptyInstExtends(InstNode lookup) {
1642        InstExtendsShortClass res = new InstExtendsShortClass();
1643        res.setLookupNode(lookup);
1644        return res;
1645    }
1646
1647    public InstNormalExtends SrcInlineExtendsClause.newEmptyInstExtends(InstNode lookup) {
1648        return new InstInlineExtends();
1649    }
1650
1651    public InstAccess SrcComponentDecl.newInstClassAccess() {
1652        return getClassName().newInstAccess();
1653    }
1654
1655    public abstract InstAccess SrcAccess.newInstAccess();
1656
1657    public InstAccess SrcArrayAccess.newInstAccess() {
1658        InstAccess ia = new InstParseArrayAccess(getID(), getSrcArraySubscripts().instantiate());
1659        ia.setLocation(this);
1660        return ia;
1661    }
1662
1663    public InstAccess SrcNamedAccess.newInstAccess() {
1664        InstAccess ia = new InstParseAccess(getID());
1665        ia.setLocation(this);
1666        return ia;
1667    }
1668
1669    public InstAccess SrcDot.newInstAccess() {
1670        List<InstAccess> l = new List<InstAccess>();
1671        for (SrcNamedAccess a : getSrcNamedAccesss())
1672            l.add(a.newInstAccess());
1673        InstDot ia = new InstDot(l);
1674        ia.setLocation(this);
1675        return ia;
1676    }
1677
1678    public InstAccess SrcGlobalAccess.newInstAccess() {
1679        InstAccess ia = new InstGlobalAccess(getSrcAccess().newInstAccess());
1680        ia.setLocation(this);
1681        return ia;
1682    }
1683
1684    syn boolean InstExtends.hasInstClassModification()           = false;
1685    eq InstReplacingExtendsShortClass.hasInstClassModification() = getInstExtendsShortClass().hasInstClassModification();
1686
1687    syn InstClassModification InstExtends.getInstClassModification() = null;
1688    eq InstReplacingExtendsShortClass.getInstClassModification()     = getInstExtendsShortClass().getInstClassModification();
1689
1690    syn lazy InstProgramRoot Program.getInstProgramRoot() {
1691        return new InstProgramRoot(this, new Opt(), new Opt(), new Opt());
1692    }
1693
1694    syn lazy InstClassDecl InstClassRedeclare.getInstClassDecl() {
1695        return getSrcClassRedeclare().getSrcBaseClassDecl().newInstClassDecl();
1696    }
1697
1698    syn lazy InstComponentDecl InstComponentRedeclare.getInstComponentDecl() =
1699        new InstCreateComponentDecl(getComponentRedeclareDecl(), null);
1700
1701    syn lazy InstComponentDecl InstReplacingRecord.getOriginalInstComponent() =
1702        new InstCreateComponentDecl(getOriginalDecl(), null);
1703
1704    syn lazy InstComponentDecl InstReplacingComposite.getOriginalInstComponent() =
1705        new InstCreateComponentDecl(getOriginalDecl(), null);
1706
1707    syn lazy InstComponentDecl InstReplacingPrimitive.getOriginalInstComponent() =
1708        new InstCreateComponentDecl(getOriginalDecl(), null);
1709
1710
1711    syn lazy InstClassDecl InstReplacingShortClassDecl.getOriginalInstClass() =
1712        getOriginalClassDecl().newInstClassDecl();
1713
1714    syn lazy InstClassDecl InstReplacingSimpleShortClassDecl.getOriginalInstClass() =
1715        getOriginalClassDecl().newInstClassDecl();
1716
1717    syn lazy InstClassDecl InstReplacingFullClassDecl.getOriginalInstClass() =
1718        getOriginalClassDecl().newInstClassDecl();
1719
1720    /**
1721     * Returns the FExp associated with this argument, if any.
1722     */
1723    public FExp InstFunctionArgument.getFExp() { return null; }
1724
1725    /**
1726     * Returns the FExp associated with this argument, if any, without triggering rewrites.
1727     */
1728    public FExp InstFunctionArgument.getFExpNoTransform() { return null; }
1729   
1730    public FExp InstFunctionArgument.getOriginalFExp() { return null; }
1731    public FExp InstGivenArgument.getOriginalFExp()    { return getFExpNoTransform(); }
1732
1733    syn lazy FFunctionCallStmt InstExternalObject.getDestructorCall() {
1734        InstAccess name = getClassName().copyAndAppend("destructor");
1735        List<InstFunctionArgument> args = new List<InstFunctionArgument>();
1736        args.add(new InstPositionalArgument(createAccessExp(), 0));
1737        InstFunctionCall ifc = new InstFunctionCall(name, args);
1738        ifc.generated = true;
1739        FFunctionCallStmt stmt = new FFunctionCallStmt(new List(), ifc);
1740        return stmt;
1741    }
1742
1743
1744    private boolean InstShortClassDecl.simpleRewriteDone = false;
1745
1746    rewrite InstShortClassDecl {
1747        when (!simpleRewriteDone) to InstAbstractShortClassDecl {
1748                simpleRewriteDone = true;
1749                if (shouldBeExpanded())
1750                        return this;
1751                InstSimpleShortClassDecl res = createInstSimpleShortClassDecl();
1752                res.setLocation(this);
1753                return res;
1754        }
1755    }
1756
1757    public InstSimpleShortClassDecl InstShortClassDecl.createInstSimpleShortClassDecl() {
1758        return new InstSimpleShortClassDecl(getSrcClassDecl(), getInstConstrainingClassOpt(), getInstRestriction());
1759    }
1760
1761    public InstReplacingSimpleShortClassDecl InstReplacingShortClassDecl.createInstSimpleShortClassDecl() {
1762        return new InstReplacingSimpleShortClassDecl(getSrcClassDecl(), getInstConstrainingClassOpt(), 
1763               getInstRestriction(), getOriginalClassDecl(), getInstClassRedeclare());
1764    }
1765
1766    syn boolean InstShortClassDecl.shouldBeExpanded() = 
1767        hasFArraySubscripts() || 
1768        hasInstClassModification() || 
1769        getSrcClassDecl().hasSrcTypePrefix() || 
1770        !filteredEnvironment().isEmpty();
1771    eq InstReplacingShortClassDecl.shouldBeExpanded() =
1772        super.shouldBeExpanded() || 
1773        (hasInstConstrainingClass() && getInstConstrainingClass().hasInstClassModification()) || 
1774        (isFunction() && !instModificationsFromConstrainingType().isEmpty());
1775
1776    syn boolean SrcClassDecl.hasSrcTypePrefix() = false;
1777    eq SrcShortClassDecl.hasSrcTypePrefix()     = getSrcExtendsClauseShortClass().hasSrcTypePrefix();
1778
1779    syn boolean SrcExtendsClauseShortClass.hasSrcTypePrefix() = 
1780        hasSrcTypePrefixFlow() || hasSrcTypePrefixVariability() || hasSrcTypePrefixInputOutput();
1781
1782    syn lazy InstAccess InstSimpleShortClassDecl.getTarget() = 
1783        getSrcBaseClassDecl().superClasses().iterator().next().getSuper().newInstAccess();
1784
1785    /**
1786     * If this is a short class declaration we return the RHS class, else this.
1787     */
1788    syn InstClassDecl InstClassDecl.myTargetInstClassDecl();
1789    eq  InstClassDecl              .myTargetInstClassDecl() = this;
1790    eq  InstSimpleShortClassDecl   .myTargetInstClassDecl() = getTarget().myInstClassDecl();
1791    eq  InstShortClassDecl         .myTargetInstClassDecl() = getInstExtends(0).myInstClass();
1792
1793    syn boolean InstRestriction.equals(Object o) = getClass().equals(o.getClass());
1794
1795    syn lazy InstClassDecl InstLibNode.getActualInstClass() {
1796        SrcLibNode ln = (SrcLibNode) getSrcClassDecl();
1797        SrcClassDecl cl = ln.myClass();
1798        if (ln.nameCaseChanged()) {
1799            flushCache();
1800        }
1801        return createInstClassDecl(cl);
1802    }
1803
1804    public List<InstComponentDecl> InstSimpleShortClassDecl.getInstComponentDeclList() {
1805        throw new UnsupportedOperationException();
1806    }
1807    public List<InstComponentDecl> InstLibNode.getInstComponentDeclList() {
1808        throw new UnsupportedOperationException();
1809    }
1810
1811    public List<InstClassDecl> InstSimpleShortClassDecl.getInstClassDeclList() {
1812        throw new UnsupportedOperationException();
1813    }
1814    public List<InstClassDecl> InstLibNode.getInstClassDeclList() {
1815        throw new UnsupportedOperationException();
1816    }
1817
1818    public List<InstExtends> InstSimpleShortClassDecl.getInstExtendsList() {
1819        throw new UnsupportedOperationException();
1820    }
1821    public List<InstExtends> InstLibNode.getInstExtendsList() {
1822        throw new UnsupportedOperationException();
1823    }
1824
1825    public List<InstImport> InstSimpleShortClassDecl.getInstImportList() {
1826        throw new UnsupportedOperationException();
1827    }
1828    public List<InstImport> InstLibNode.getInstImportList() {
1829        throw new UnsupportedOperationException();
1830    }
1831
1832    public List<InstClassDecl> InstSimpleShortClassDecl.getRedeclaredInstClassDeclList() {
1833        throw new UnsupportedOperationException();
1834    }
1835    public List<InstClassDecl> InstLibNode.getRedeclaredInstClassDeclList() {
1836        throw new UnsupportedOperationException();
1837    }
1838
1839}
1840
1841aspect ExpandableConnectorMembers {
1842   
1843    private List<InstComponentDecl> InstExpandableConnectorDecl.expandedMembers          = null;
1844    private List<InstComponentDecl> InstReplacingExpandableConnectorDecl.expandedMembers = null;
1845    private List<InstComponentDecl> InstArrayExpandableConnector.expandedMembers         = null;
1846
1847    private InstComponentDecl[] InstExpandableConnectorDecl.templates          = null;
1848    private InstComponentDecl[] InstReplacingExpandableConnectorDecl.templates = null;
1849    private InstComponentDecl[] InstArrayExpandableConnector.templates         = null;
1850
1851    syn boolean InstExpandableConnectorDecl.useTemplate(int i)          = 
1852        templates != null && getInstComponentDecl(i) != templates[i];
1853    syn boolean InstReplacingExpandableConnectorDecl.useTemplate(int i) = 
1854        templates != null && getInstComponentDecl(i) != templates[i];
1855    syn boolean InstArrayExpandableConnector.useTemplate(int i)         = 
1856        templates != null && getInstComponentDecl(i) != templates[i];
1857
1858    syn InstComponentDecl InstExpandableConnectorDecl.template(int i)          = 
1859        templates[i].arrayTopInstComponentDecl();
1860    syn InstComponentDecl InstReplacingExpandableConnectorDecl.template(int i) = 
1861        templates[i].arrayTopInstComponentDecl();
1862    syn InstComponentDecl InstArrayExpandableConnector.template(int i)         = 
1863        templates[i].arrayTopInstComponentDecl();
1864
1865    eq InstExpandableConnectorDecl.getInstComponentDeclList()          = 
1866        (expandedMembers != null) ? expandedMembers : super.getInstComponentDeclList();
1867    eq InstReplacingExpandableConnectorDecl.getInstComponentDeclList() = 
1868        (expandedMembers != null) ? expandedMembers : super.getInstComponentDeclList();
1869    eq InstArrayExpandableConnector.getInstComponentDeclList()         = 
1870        (expandedMembers != null) ? expandedMembers : super.getInstComponentDeclList();
1871   
1872    eq InstExpandableConnectorDecl.getInstExtendsList()          = 
1873        (expandedMembers != null) ? new List<InstExtends>() : super.getInstExtendsList();
1874    eq InstReplacingExpandableConnectorDecl.getInstExtendsList() = 
1875        (expandedMembers != null) ? new List<InstExtends>() : super.getInstExtendsList();
1876    eq InstArrayExpandableConnector.getInstExtendsList()         = 
1877        (expandedMembers != null) ? new List<InstExtends>() : super.getInstExtendsList();
1878   
1879    public InstComponentDecl InstExpandableConnectorDecl.createInstArrayComponentDecl(int i) {
1880        return new InstArrayExpandableConnector(name(), new InstClassAccess("ArrayDecl"), new Opt(), 
1881                getSrcComponentDecl(), new Opt(), new Opt(), new Opt(), i);
1882    }
1883    public InstComponentDecl InstReplacingExpandableConnectorDecl.createInstArrayComponentDecl(int i) {
1884        return new InstArrayExpandableConnector(name(), new InstClassAccess("ArrayDecl"), new Opt(), 
1885                getSrcComponentDecl(), new Opt(), new Opt(), new Opt(), i);
1886    }
1887    public InstComponentDecl InstArrayExpandableConnector.createInstArrayComponentDecl(int i) {
1888        return new InstArrayExpandableConnector(name(), new InstClassAccess("ArrayDecl"), new Opt(), 
1889                getSrcComponentDecl(), new Opt(), new Opt(), new Opt(), i);
1890    }
1891
1892    inh boolean InstComponentDecl.isExpandableConnectorMember();
1893    eq InstExpandableConnectorDecl.getInstComponentDecl().isExpandableConnectorMember()          = true;
1894    eq InstReplacingExpandableConnectorDecl.getInstComponentDecl().isExpandableConnectorMember() = true;
1895    eq InstArrayExpandableConnector.getInstComponentDecl().isExpandableConnectorMember()         = true;
1896    eq BaseNode.getChild().isExpandableConnectorMember()                                         = false;
1897
1898    inh boolean InstComponentDecl.inExpandableConnector();
1899    eq InstExpandableConnectorDecl.getInstComponentDecl().inExpandableConnector()          = true;
1900    eq InstReplacingExpandableConnectorDecl.getInstComponentDecl().inExpandableConnector() = true;
1901    eq InstArrayExpandableConnector.getInstComponentDecl().inExpandableConnector()         = true;
1902    eq InstClassDecl.getChild().inExpandableConnector()                                    = false;
1903    eq Root.getChild().inExpandableConnector()                                             = false;
1904
1905    inh InstComponentDecl InstComponentDecl.myExpandableConnectorTemplate();
1906    eq InstExpandableConnectorDecl.getInstComponentDecl(int i).myExpandableConnectorTemplate()          = template(i);
1907    eq InstReplacingExpandableConnectorDecl.getInstComponentDecl(int i).myExpandableConnectorTemplate() = template(i);
1908    eq InstArrayExpandableConnector.getInstComponentDecl(int i).myExpandableConnectorTemplate()         = template(i);
1909    eq BaseNode.getChild().myExpandableConnectorTemplate() = null;
1910
1911}
1912
1913aspect InstaceConstrainingClauses {
1914
1915    public Opt SrcComponentDecl.newInstConstrainingComponentOpt(InstComponentRedeclare cicr) {
1916        if (hasSrcConstrainingClause()) {
1917            SrcConstrainingClause cc = getSrcConstrainingClause();
1918            Opt opt = cc.hasSrcClassModification() ? new Opt(cc.getSrcClassModification().newInstModification()) : new Opt();
1919            return new Opt(new InstConstrainingComponent(cc.getSrcAccess().newInstAccess(), opt, this, cicr));
1920        } else {
1921            return new Opt();
1922        }
1923    }
1924
1925    public Opt SrcClassDecl.newInstConstrainingClassOpt(InstRedeclareClassNode cicr) {
1926        return new Opt();
1927    }
1928
1929    public Opt SrcBaseClassDecl.newInstConstrainingClassOpt(InstRedeclareClassNode cicr) {
1930        if (hasSrcConstrainingClause()) {
1931            SrcConstrainingClause cc = getSrcConstrainingClause();
1932            Opt opt = cc.hasSrcClassModification() ? new Opt(cc.getSrcClassModification().newInstModification()) : new Opt();
1933            return new Opt(new InstConstrainingClass(cc.getSrcAccess().newInstAccess(), opt, this, cicr));
1934        } else {
1935            return new Opt();
1936        }
1937    }
1938
1939    syn lazy SrcConstrainingClause InstConstraining.getSrcConstrainingClause();
1940    eq InstConstrainingComponent.getSrcConstrainingClause() = getSrcComponentDecl().getSrcConstrainingClause();
1941    eq InstConstrainingClass.getSrcConstrainingClause() = getSrcBaseClassDecl().getSrcConstrainingClause();
1942
1943    syn lazy InstBaseNode InstConstraining.getInstNode();
1944    eq InstConstrainingComponent.getInstNode() =
1945        getClassName().myInstClassDecl().newInstConstrainingComponentDecl(getSrcComponentDecl(), getSrcConstrainingClause().getSrcAccess());
1946    eq InstConstrainingClass.getInstNode() {
1947        SrcClassDecl classToExpand = getClassName().myInstClassDecl().getSrcClassDecl();
1948        return classToExpand.newInstClassDecl();
1949    }
1950   
1951    syn lazy FExp InstValueModification.getFExp() = getSrcValueModification().instantiateExp();
1952    eq InstArrayModification.getFExp()            = getCell();
1953   
1954    syn FExp SrcValueModification.instantiateExp() = getSrcExp().instantiate();
1955    eq SrcDummyModification.instantiateExp()       = myFExp().treeCopy();
1956
1957    public List InstNode.buildFAbstractEquationList() { 
1958    List l = new List();
1959            for (SrcAbstractEquation e : equations()) {
1960                l.add(e.instantiate());
1961            }
1962            for (SrcAlgorithm a : algorithms()) {
1963                l.add(a.instantiate());
1964            }
1965            for (FAlgorithm a : fAlgorithms()) {
1966                l.add(a.fullCopy());
1967            }
1968            return l;
1969        }
1970
1971    public List InstArrayComponentDecl.buildFAbstractEquationList() {
1972        return instComponentDecl().buildFAbstractEquationList();
1973    }
1974
1975    syn lazy List InstNode.getFAbstractEquationList() = 
1976        buildFAbstractEquationList();
1977    eq InstComponentDecl.getFAbstractEquationList() = 
1978        isArrayParent() ? new List() : buildFAbstractEquationList();
1979
1980    // TODO: Change behaviour of isArrayDecl to this instead?
1981    syn boolean InstComponentDecl.isArrayParent() = 
1982        getNumInstComponentDecl() > 0 && getInstComponentDecl(0).isArrayChild();
1983
1984    syn boolean InstComponentDecl.isArrayChild() = false;
1985    eq InstArrayComponentDecl.isArrayChild()     = true;
1986}
1987
1988aspect InstImportClauses {
1989
1990
1991    syn List InstNode.getInstImportList() {
1992        List l = new List();
1993        for (SrcImportClause ic : imports()) {
1994                InstImport iic = ic.newInstImport();
1995                iic.setLocation(ic);
1996                l.add(iic);
1997        }
1998        return l;
1999    }
2000
2001
2002        public abstract InstImport SrcImportClause.newInstImport(); 
2003        public InstImport SrcImportClauseQualified.newInstImport() {
2004                return new InstImportQualified(getPackageName().newInstAccess(),this);
2005        }
2006        public InstImport SrcImportClauseUnqualified.newInstImport() {
2007                return new InstImportUnqualified(getPackageName().newInstAccess(),this);
2008        }
2009        public InstImport SrcImportClauseRename.newInstImport() {
2010                return new InstImportRename(getPackageName().newInstAccess(),this);
2011        }
2012       
2013
2014} 
2015
2016aspect InstanceAST_API {
2017        syn boolean InstNode.nameScope() = false;
2018        eq InstComponentDecl.nameScope() = true;
2019        eq InstArrayComponentDecl.nameScope() = false;
2020    eq InstBaseClassDecl.nameScope() = true;
2021
2022    syn String InstNode.name()           = "";
2023    eq InstComponentDecl.name()          = getName();
2024    eq InstClassDecl.name()              = getSrcClassDecl().name();
2025    eq InstExtends.name()                = getClassName().name();
2026   
2027    syn String InstGeneratedInner.name() = getCopiedOuter().name();
2028   
2029   /**
2030   * Retrieve fully indexed names for array elements
2031   *
2032   */
2033   
2034    syn String InstNode.getElementName() = name();
2035    eq InstArrayComponentDecl.getElementName() {
2036        if (ndims() != 0 )  {
2037            return getFAccess().scalarName(false, true) + myIndex().partIndex(0, myDimension() + 1).toString();
2038        }
2039        return getFAccess().scalarName(false, true);
2040    }
2041   
2042    syn SrcBaseClassDecl InstBaseClassDecl.getSrcBaseClassDecl() = (SrcBaseClassDecl)getSrcClassDecl();
2043    syn SrcShortClassDecl InstAbstractShortClassDecl.getSrcShortClassDecl() = (SrcShortClassDecl)getSrcClassDecl();
2044    syn SrcFullClassDecl InstFullClassDecl.getSrcFullClassDecl() = (SrcFullClassDecl)getSrcClassDecl();
2045    syn SrcBuiltInClassDecl InstBuiltInClassDecl.getSrcBuiltInClassDecl() = (SrcBuiltInClassDecl)getSrcClassDecl();
2046
2047    syn String InstNode.qualifiedName();
2048    syn lazy String InstClassDecl.qualifiedName();
2049    eq InstComponentDecl.qualifiedName()     = getFAccess().name();
2050    eq InstExtends.qualifiedName()           = myInstClass().qualifiedName();
2051    eq InstInlineExtends.qualifiedName()     = 
2052        surroundingInstClass().myInheritedOrigin().qualifiedName();
2053    eq InstBaseClassDecl.qualifiedName()     = getInstRestriction().qualifiedClassName();
2054    eq InstLibNode.qualifiedName()           = resolveLib().qualifiedName();
2055    eq BadInstClassDecl.qualifiedName()      = buildQualifiedName();
2056    eq InstBuiltInClassDecl.qualifiedName()  = name();
2057    eq InstProgramRoot.qualifiedName()       = "";
2058   
2059    eq InstArrayComponentDecl.qualifiedName(){
2060        if (ndims() != 0 ){
2061            return super.qualifiedName() + 
2062                myIndex().partIndex(0, myDimension() + 1).toString();
2063        }
2064        return super.qualifiedName();
2065    } 
2066
2067    syn String InstRestriction.qualifiedClassName() = myInstClassDecl().buildQualifiedName();
2068    eq InstOperator.qualifiedClassName()            = myInstClassDecl().buildQualifiedOperatorName();
2069    eq InstOperatorFunction.qualifiedClassName()    = myInstClassDecl().buildQualifiedOperatorName();
2070
2071    syn String InstNode.buildQualifiedName() = combineName(instClassNamePrefix(false), name());
2072
2073    syn String InstClassDecl.buildQualifiedOperatorName() = combineName(instClassNamePrefix(true), name());
2074
2075    inh String InstNode.instClassNamePrefix(boolean sup);
2076    eq InstExtends.getChild().instClassNamePrefix(boolean sup)       = sup ? qualifiedName() : instClassNamePrefix(sup);
2077    eq InstBaseClassDecl.getChild().instClassNamePrefix(boolean sup) = qualifiedName();
2078    eq InstLibNode.getChild().instClassNamePrefix(boolean sup)       = instClassNamePrefix(sup);
2079    eq InstComponentDecl.getChild().instClassNamePrefix(boolean sup) = buildQualifiedName();
2080    eq Root.getChild().instClassNamePrefix(boolean sup)              = "";
2081    eq InstRoot.getChild().instClassNamePrefix(boolean sup)          = "";
2082
2083    /**
2084     * Get the qualified class name of the oldest ancestor in the inheritance structure.
2085     *
2086     * For classes inheriting multiple classes, only the first one is considered.
2087     * This is useful mostly for classes that only allows inheriting from one other class.
2088     */
2089    syn String InstNode.baseClassName()                  = 
2090        (getNumInstExtends() > 0) ? getInstExtends(0).baseClassName() : qualifiedName();
2091    eq InstComponentDecl.baseClassName()                 = myInstClass().baseClassName();
2092    eq InstSimpleShortClassDecl.baseClassName()          = actualInstClass().baseClassName();
2093    eq InstLibNode.baseClassName()                       = actualInstClass().baseClassName();
2094
2095
2096        syn Iterable<SrcAbstractEquation> InstNode.equations() = Collections.<SrcAbstractEquation>emptyList();
2097        eq InstComponentDecl.equations()                    = myInstClass().equations();
2098        eq InstExtends.equations()                          = myInstClass().equations();
2099        eq InstFullClassDecl.equations()                    = getSrcBaseClassDecl().equations();       
2100       
2101        syn Iterable<SrcAlgorithm> InstNode.algorithms() = Collections.<SrcAlgorithm>emptyList();
2102        eq InstComponentDecl.algorithms()             = myInstClass().algorithms();
2103        eq InstExtends.algorithms()                   = myInstClass().algorithms();
2104        eq InstFullClassDecl.algorithms()             = getSrcBaseClassDecl().algorithms();     
2105       
2106    syn Iterable<FAlgorithm> InstNode.fAlgorithms() = Collections.<FAlgorithm>emptyList();
2107    eq InstComponentDecl.fAlgorithms()              = myInstClass().fAlgorithms();
2108    eq InstExtends.fAlgorithms()                    = myInstClass().fAlgorithms();
2109    eq InstFullClassDecl.fAlgorithms() {
2110        InstExternal ie = getInstExternal();
2111        if (ie != null) {
2112            ArrayList<FAlgorithm> l = new ArrayList<FAlgorithm>();
2113            l.add(ie.getFAlgorithm());
2114            return l;
2115        } else {
2116            return super.fAlgorithms();
2117        }
2118    }
2119
2120    syn Iterable<SrcComponentDecl> InstNode.components() = Collections.<SrcComponentDecl>emptyList();
2121    eq InstComponentDecl.components()                 = myInstClass().components();
2122    eq InstArrayComponentDecl.components()            = instComponentDecl().components();
2123    eq InstExtends.components()                       = 
2124        extendsPrimitive() ? Collections.<SrcComponentDecl>emptyList() : myInstClass().components();
2125    eq InstBaseClassDecl.components()                 = getSrcBaseClassDecl().components();
2126    eq InstLibNode.components()                       = resolveLib().components();
2127
2128    syn Iterable<SrcExtendsClause> InstNode.superClasses() = Collections.<SrcExtendsClause>emptyList();
2129    eq InstComponentDecl.superClasses()                 = myInstClass().superClasses();
2130    eq InstArrayComponentDecl.superClasses()            = instComponentDecl().superClasses();
2131    eq InstExtends.superClasses()                       = myInstClass().superClasses();
2132    eq InstBaseClassDecl.superClasses()                 = getSrcBaseClassDecl().superClasses();
2133    eq InstLibNode.superClasses()                       = resolveLib().superClasses();
2134
2135    syn Iterable<SrcClassDecl> InstNode.classes() = Collections.<SrcClassDecl>emptyList();
2136    eq InstProgramRoot.classes()               = getProgram().classes();
2137    eq InstComponentDecl.classes()             = myInstClass().classes();
2138    eq InstArrayComponentDecl.classes()        = instComponentDecl().classes();
2139    eq InstBaseClassDecl.classes()             = getSrcBaseClassDecl().classes();
2140    eq InstExtends.classes()                   = myInstClass().classes();
2141    eq InstLibNode.classes()                   = resolveLib().classes();
2142
2143    syn Iterable<SrcImportClause> InstNode.imports() = Collections.<SrcImportClause>emptyList();
2144    eq InstComponentDecl.imports()                = myInstClass().imports();
2145    eq InstBaseClassDecl.imports()                = getSrcBaseClassDecl().imports();
2146    eq InstExtends.imports()                      = myInstClass().imports();
2147    eq InstLibNode.imports()                      = resolveLib().imports();
2148
2149    syn Iterable<SrcModificationOrRedeclareElement> InstNode.elementModifications() = 
2150        Collections.<SrcModificationOrRedeclareElement>emptyList();
2151    eq InstComponentDecl.elementModifications() = myInstClass().elementModifications();
2152    eq InstExtends.elementModifications()       = myInstClass().elementModifications();
2153    eq InstBaseClassDecl.elementModifications() = getSrcClassDecl().elementModifications();
2154    eq InstLibNode.elementModifications()       = getSrcClassDecl().elementModifications();
2155
2156    inh InstEnumClassDecl InstEnumLiteral.myInstEnumClassDecl();
2157    eq InstEnumClassDecl.getInstComponentDecl().myInstEnumClassDecl() = this;
2158    eq InstNode.getChild().myInstEnumClassDecl()                      = null;
2159    eq FlatRoot.getChild().myInstEnumClassDecl()                      = null;
2160
2161    inh int InstEnumLiteral.myIndex();
2162    eq InstEnumClassDecl.getInstComponentDecl(int i).myIndex() = 
2163        enumLiterals().indexOf(getInstComponentDecl(i)) + 1;
2164    eq InstNode.getChild().myIndex()                           = 0;
2165    eq FlatRoot.getChild().myIndex()                           = 0;
2166
2167    syn ArrayList<InstEnumLiteral> InstClassDecl.enumLiterals() =
2168        extendsEnum() ? getInstExtends(0).myInstClass().enumLiterals() : new ArrayList<InstEnumLiteral>();
2169    eq InstSimpleShortClassDecl.enumLiterals()                  = actualInstClass().enumLiterals();
2170    eq InstLibNode.enumLiterals()                               = actualInstClass().enumLiterals();
2171    syn lazy ArrayList<InstEnumLiteral> InstEnumClassDecl.enumLiterals() {
2172        ArrayList<InstEnumLiteral> l = new ArrayList<InstEnumLiteral>();
2173        for (InstComponentDecl icd : getInstComponentDecls()) {
2174            if (icd.isEnumLiteral()) {
2175                l.add((InstEnumLiteral)icd);
2176            }
2177        }
2178        return l;
2179    }
2180
2181
2182    // Overridden in SrcBaseClassDecl by generated API for optional child
2183    syn boolean SrcClassDecl.hasSrcConstrainingClause() = false;
2184    syn SrcConstrainingClause SrcClassDecl.getSrcConstrainingClause() = null;
2185
2186    // Overridden in InstBaseClassDecl by generated API for optional child
2187    syn boolean InstClassDecl.hasInstConstrainingClass() = false;
2188    syn InstConstrainingClass InstClassDecl.getInstConstrainingClass() = null;
2189
2190    syn boolean InstNode.hasInstConstraining() = false;
2191    eq InstBaseClassDecl.hasInstConstraining() = hasInstConstrainingClass();
2192    eq InstComponentDecl.hasInstConstraining() = hasInstConstrainingComponent();
2193
2194    syn InstConstraining InstNode.getInstConstraining() = null;
2195    eq InstBaseClassDecl.getInstConstraining()          = getInstConstrainingClass();
2196    eq InstComponentDecl.getInstConstraining()          = getInstConstrainingComponent();
2197
2198    /**
2199     * Does this constraining clause come from a redeclare?
2200     */
2201    syn boolean InstConstraining.hasInstRedeclare();
2202    eq InstConstrainingComponent.hasInstRedeclare() = getInstRedeclare() != null;
2203    eq InstConstrainingClass.hasInstRedeclare()     = getInstRedeclare() != null;
2204
2205    /**
2206     * get the InstNode for the redeclare that this constraining clause comes from.
2207     *
2208     * Only valid if hasInstRedeclare() returns true.
2209     */
2210    syn InstNode InstConstraining.getRedeclareInstNode();
2211    eq InstConstrainingComponent.getRedeclareInstNode() = getInstRedeclare().getInstComponentDecl();
2212    eq InstConstrainingClass.getRedeclareInstNode()     = getInstRedeclare().redeclaringInstClassDecl();
2213
2214    /**
2215     * Is this declaration redeclared?
2216     */
2217    syn boolean InstNode.isRedeclared()                 = false;
2218    eq InstReplacingFullClassDecl.isRedeclared()        = true;
2219    eq InstReplacingShortClassDecl.isRedeclared()       = true;
2220    eq InstReplacingSimpleShortClassDecl.isRedeclared() = true;
2221    eq InstReplacingComposite.isRedeclared()            = true;
2222    eq InstReplacingRecord.isRedeclared()               = true;
2223    eq InstReplacingPrimitive.isRedeclared()            = true;
2224
2225    /**
2226     * Is this declaration replaceable?
2227     */
2228    syn boolean InstNode.isReplaceable() = false;
2229    eq InstClassDecl.isReplaceable()     = getSrcClassDecl().getReplaceable();
2230    eq InstComponentDecl.isReplaceable() = getSrcComponentDecl().hasReplaceable();
2231
2232    /**
2233     * Is this declaration affected by a constraining type?
2234     */
2235    syn boolean InstNode.isConstrained() = isReplaceable() || isRedeclared();
2236
2237    // Overridden in SrcBaseClassDecl by generated API for optional child
2238    syn boolean SrcClassDecl.getReplaceable() = false;
2239
2240    syn boolean InstNode.extendsPrimitive()        = false;
2241    eq InstShortClassDecl.extendsPrimitive()       = getNumInstExtends() == 1 && getInstExtends(0).extendsPrimitive();
2242    eq InstFullClassDecl.extendsPrimitive()        = getNumInstExtends() == 1 && getInstExtends(0).extendsPrimitive();
2243    eq InstSimpleShortClassDecl.extendsPrimitive() = actualInstClass().isPrimitive();
2244    eq InstLibNode.extendsPrimitive()              = actualInstClass().extendsPrimitive();
2245    eq InstExtends.extendsPrimitive() {
2246        InstClassDecl icd = myInstClass();
2247        return !isRecursive() && icd.isPrimitive();
2248    }
2249
2250    /**
2251     * Check if this node is a class declaration or an extends in one.
2252     */
2253    syn boolean InstNode.isClassDecl() = false;
2254    eq InstClassDecl.isClassDecl()     = true;
2255    eq InstExtends.isClassDecl()       = isInClassDecl();
2256   
2257    /**
2258     * Check if this node is an extends.
2259     */
2260    syn boolean InstNode.isExtends() = false;
2261    eq InstExtends.isExtends()     = true;
2262
2263    /**
2264     * Check if this extends is part of a class declaration.
2265     */
2266    inh boolean InstExtends.isInClassDecl();
2267    eq InstClassDecl.getChild().isInClassDecl() = true;
2268    eq InstBaseNode.getChild().isInClassDecl()  = false;
2269    eq Root.getChild().isInClassDecl()          = false;
2270   
2271    /**
2272     * Check if this node is a component declaration or an extends in one.
2273     */
2274    syn boolean InstNode.isComponentDecl() = false;
2275    eq InstComponentDecl.isComponentDecl() = true;
2276    eq InstExtends.isComponentDecl()       = isInComponentDecl();
2277   
2278    /**
2279     * Check if this extends is part of a component declaration.
2280     */
2281    inh boolean InstExtends.isInComponentDecl();
2282    eq InstComponentDecl.getChild().isInComponentDecl() = true;
2283    eq InstBaseNode.getChild().isInComponentDecl()      = false;
2284    eq Root.getChild().isInComponentDecl()              = false;
2285
2286    /**
2287     * Check if this class is or extends an enumeration.
2288     */
2289    syn boolean InstNode.extendsEnum()        = false;
2290    eq InstClassDecl.extendsEnum()            = getNumInstExtends() == 1 && getInstExtends(0).extendsEnum();
2291    eq InstSimpleShortClassDecl.extendsEnum() = actualInstClass().extendsEnum();
2292    eq InstLibNode.extendsEnum()              = actualInstClass().extendsEnum();
2293    eq InstEnumClassDecl.extendsEnum()        = true;
2294    eq InstExtends.extendsEnum()              = !isRecursive() && myInstClass().extendsEnum();
2295
2296        syn InstClassDecl InstClassDecl.getBaseInstClass() = 
2297                (getNumInstExtends() > 0) ? getInstExtends(0).getBaseInstClass() : this;
2298        syn InstClassDecl InstExtends.getBaseInstClass()   = 
2299                myInstClass().getBaseInstClass();
2300       
2301        inh boolean InstNode.enclosedBy(InstNode node);
2302        eq InstNode.getChild().enclosedBy(InstNode node) = (node == this) || enclosedBy(node);
2303        eq InstRoot.getChild().enclosedBy(InstNode node) = (node == this);
2304    eq Root.getChild().enclosedBy(InstNode node)     = false;
2305   
2306    syn InstNode InstNode.commonAncestor(InstNode node) {
2307        HashSet<InstNode> theirs = new HashSet<InstNode>(node.instAncestors());
2308        for (InstNode mine : instAncestors())
2309            if (theirs.contains(mine))
2310                return mine;
2311        return null;
2312    }
2313   
2314    syn java.util.List<InstNode> InstNode.instAncestors() {
2315        ArrayList<InstNode> list = new ArrayList<InstNode>();
2316        InstNode cur = this;
2317        while (cur != null) {
2318            list.add(cur);
2319            cur = cur.instNodeParent();
2320        }
2321        return list;
2322    }
2323
2324    inh InstNode InstNode.instNodeParent();
2325    eq InstNode.getChild().instNodeParent() = this;
2326    eq Root.getChild().instNodeParent()     = null;
2327   
2328    syn InstNode InstNode.matchingAncestor(InstNode node) {
2329        if (node.isClassDecl()) {
2330            int dims = node.nTypeDims();
2331            for (InstNode mine : instAncestors()) {
2332                if (mine.isThisClass(node)) {
2333                    if (dims == 0 || mine.isClassDecl()) {
2334                        return mine;
2335                    }
2336                    dims = dims - 1;
2337                }
2338            }
2339            return null;
2340        } else {
2341            return commonAncestor(node);
2342        }
2343    }
2344   
2345    syn int InstNode.nTypeDims()      = 0;
2346    eq InstShortClassDecl.nTypeDims() = (hasFArraySubscripts() ? getFArraySubscripts().ndims() : 0) 
2347            + getInstExtends(0).nTypeDims();
2348    eq InstExtends.nTypeDims()        = myInstClass().nTypeDims();
2349   
2350    syn boolean InstNode.isThisClass(InstNode node)                 = this == node;
2351    eq InstComponentDecl.isThisClass(InstNode node)                 = myInstClass().isThisClass(node);
2352    eq InstReplacingShortClassDecl.isThisClass(InstNode node)       = getInstClassRedeclare().isThisClass(node);
2353    eq InstReplacingSimpleShortClassDecl.isThisClass(InstNode node) = actualInstClass().isThisClass(node);
2354   
2355    public interface InstRedeclareClassNode {
2356        public boolean isThisClass(InstNode node);
2357    }
2358   
2359    syn boolean InstClassRedeclare.isThisClass(InstNode node)       = getInstClassDecl().isThisClass(node);
2360   
2361        /**
2362         * Find the component that this access should be evaluated in.
2363         */
2364        inh InstComponentDecl InstAccess.containingInstComponent();
2365        inh InstComponentDecl InstNode.containingInstComponent();
2366        eq InstComponentDecl.getLocalFArraySubscripts().containingInstComponent() = 
2367                containingInstComponent();
2368        eq InstComponentDecl.getFArraySubscripts().containingInstComponent()      = 
2369                containingInstComponent();
2370        eq InstComponentDecl.getChild().containingInstComponent() = this;
2371        eq InstClassDecl.getChild().containingInstComponent()     = null;
2372        eq InstRoot.getChild().containingInstComponent()          = null;
2373        eq Root.getChild().containingInstComponent()              = null;
2374
2375
2376    /**
2377     * Iterate over all components in this node and all InstExtends (recursively).
2378     * Filters out any duplicate components.
2379     *
2380     * @return  an Iterable over the components
2381     */
2382    public Iterable<InstComponentDecl> InstNode.allInstComponentDecls() {
2383        return new FilteredIterable(allInstComponentDeclsWithDuplicates(), NO_DUPLICATE);
2384    }
2385
2386    /**
2387     * Iterate over all components in this node and all InstExtends (recursively).
2388     *
2389     * @return  an Iterable over the components
2390     */
2391    public Iterable<InstComponentDecl> InstRecordConstructor.allInstComponentDecls() {
2392        return new AllInstComponentIterable(this);
2393    }
2394
2395
2396    public static final Criteria<InstComponentDecl> InstNode.NO_DUPLICATE = new Criteria<InstComponentDecl>() {
2397        public boolean test(InstComponentDecl elem) {
2398            return !elem.isDuplicate();
2399        }
2400    };
2401
2402    /**
2403     * Iterate over all components in this node and all InstExtends (recursively).
2404     * Includes any duplicate components.
2405     *
2406     * @return  an Iterable over the components
2407     */
2408    public Iterable<InstComponentDecl> InstNode.allInstComponentDeclsWithDuplicates() {
2409        return new AllInstComponentIterable(this);
2410    }
2411    public Iterable<InstComponentDecl> InstClassDecl.allInstComponentDeclsWithDuplicates() {
2412        return new AllInstComponentIterable(actualInstClass());
2413    }
2414
2415    /**
2416     * Iterate over all classes in this node and all InstExtends (recursively).
2417     *
2418     * @return  an Iterable over the classes
2419     */
2420    public Iterable<InstClassDecl> InstNode.allInstClassDecls() {
2421        return new AllInstClassIterable(this);
2422    }
2423    public Iterable<InstClassDecl> InstClassDecl.allInstClassDecls() {
2424        return new AllInstClassIterable(actualInstClass());
2425    }
2426
2427    protected Iterator<InstComponentDecl> InstNode.allInstComponentDeclsIterator() {
2428        return new AllInstComponentIterator(this);
2429    }
2430    protected Iterator<InstComponentDecl> InstClassDecl.allInstComponentDeclsIterator() {
2431        return new AllInstComponentIterator(actualInstClass());
2432    }
2433
2434    protected Iterator<InstClassDecl> InstNode.allInstClassDeclsIterator() {
2435        return new AllInstClassIterator(this);
2436    }
2437
2438    interface AllInstComponentSource {
2439        public List<InstComponentDecl> getInstComponentDecls();
2440        public List<InstExtends> getInstExtendss();
2441    }
2442    InstNode implements AllInstComponentSource;
2443    InstRecordConstructor implements AllInstComponentSource;
2444
2445    interface AllInstClassSource {
2446        public List<InstClassDecl> getInstClassDecls();
2447        public List<InstExtends> getInstExtendss();
2448    }
2449    InstNode implements AllInstClassSource;
2450
2451    public class ASTNode {
2452
2453        protected static class AllInstComponentIterable implements Iterable<InstComponentDecl> {
2454
2455            private AllInstComponentSource src;
2456
2457            public AllInstComponentIterable(AllInstComponentSource src) {
2458                this.src = src;
2459            }
2460
2461            public Iterator<InstComponentDecl> iterator() {
2462                return new AllInstComponentIterator(src);
2463            }
2464
2465        }
2466
2467        protected static class AllInstClassIterable implements Iterable<InstClassDecl> {
2468
2469            private AllInstClassSource src;
2470
2471            public AllInstClassIterable(AllInstClassSource src) {
2472                this.src = src;
2473            }
2474
2475            public Iterator<InstClassDecl> iterator() {
2476                return new AllInstClassIterator(src);
2477            }
2478
2479        }
2480
2481        protected static class AllInstComponentIterator extends AllInstNodeIterator<InstComponentDecl> {
2482
2483            public AllInstComponentIterator(AllInstComponentSource src) {
2484                super(src.getInstExtendss(), src.getInstComponentDecls());
2485            }
2486
2487            protected Iterator<InstComponentDecl> subIterator(InstExtends ie) {
2488                return ie.allInstComponentDeclsIterator();
2489            }
2490
2491        }
2492
2493        protected static class AllInstClassIterator extends AllInstNodeIterator<InstClassDecl> {
2494
2495            public AllInstClassIterator(AllInstClassSource src) {
2496                super(src.getInstExtendss(), src.getInstClassDecls());
2497            }
2498
2499            protected Iterator<InstClassDecl> subIterator(InstExtends ie) {
2500                return ie.allInstClassDeclsIterator();
2501            }
2502
2503        }
2504
2505        private static abstract class AllInstNodeIterator<T extends InstNode> implements Iterator<T> {
2506
2507            private Iterator<T> current;
2508            private Iterator<InstExtends> exts;
2509            private Iterator<T> last;
2510
2511            public AllInstNodeIterator(List<InstExtends> extList, List<T> lastList) {
2512                exts = extList.iterator();
2513                last = lastList.iterator();
2514                if (exts.hasNext()) {
2515                    current = subIterator(exts.next());
2516                } else {
2517                    current = last;
2518                }
2519                update();
2520            }
2521
2522            protected abstract Iterator<T> subIterator(InstExtends ie);
2523
2524            public boolean hasNext() {
2525                return current.hasNext();
2526            }
2527
2528            public T next() {
2529                T res = current.next();
2530                update();
2531                return res;
2532            }
2533
2534            public void remove() {
2535                throw new UnsupportedOperationException();
2536            }
2537
2538            private void update() {
2539                while (!current.hasNext() && exts.hasNext()) {
2540                    current = subIterator(exts.next());
2541                }
2542                if (!current.hasNext()) {
2543                    current = last;
2544                }
2545            }
2546
2547        }
2548
2549    }
2550
2551    inh InstNode InstNode.containingInstNode();
2552    inh InstNode FExp.containingInstNode();
2553    eq InstNode.getChild().containingInstNode() = this;
2554    eq InstRoot.getChild().containingInstNode() = null;
2555    eq Root.getChild().containingInstNode()     = null;
2556   
2557    inh InstNode FExternalStmt.containingInstClassDecl();
2558    eq Root.getChild().containingInstClassDecl()          = null;
2559    eq InstClassDecl.getChild().containingInstClassDecl() = this;
2560
2561}
2562
2563aspect SourceAST_API {
2564
2565    private static final byte SrcLibNode.UPDATED_NAME_CASE_NOT_DONE  = 0;
2566    private static final byte SrcLibNode.UPDATED_NAME_CASE_CHANGE    = 1;
2567    private static final byte SrcLibNode.UPDATED_NAME_CASE_NO_CHANGE = 2;
2568    private byte SrcLibNode.updatedNameCase = UPDATED_NAME_CASE_NOT_DONE;
2569
2570    syn SrcClassDecl SrcLibNode.myClass() {
2571        SrcClassDecl cl = getSrcStoredDefinition().getSrcClassDecl(0);
2572        if (updatedNameCase == UPDATED_NAME_CASE_NOT_DONE) {
2573            if (!cl.name().equals(name()) && cl.name().equalsIgnoreCase(name())) {
2574                setName(cl.getName().treeCopy());
2575                updatedNameCase = UPDATED_NAME_CASE_CHANGE;
2576            } else {
2577                updatedNameCase = UPDATED_NAME_CASE_NO_CHANGE;
2578            }
2579        }
2580        return cl;
2581    }
2582
2583    syn boolean SrcLibNode.nameCaseChanged() = updatedNameCase == UPDATED_NAME_CASE_CHANGE;
2584
2585    public class ASTNode {
2586        protected static final Criteria<ASTNode> NOT_ERROR_NODE_CRITERIA = new Criteria<ASTNode>() {
2587            public boolean test(ASTNode elem) {
2588                return !elem.isError();
2589            }
2590        };
2591   
2592        public static <N extends ASTNode> Iterable<N> filterErrorNodes(final Iterable<N> parent) {
2593            return new Iterable<N>() {
2594                public Iterator<N> iterator() {
2595                    return new FilteredIterator<N>(parent.iterator(), NOT_ERROR_NODE_CRITERIA);
2596                }
2597            };
2598        }
2599    }
2600
2601}
2602
2603aspect InstArrays {
2604
2605    /**
2606     * Find the number of the dimension corresponding to this InstArrayComponentDecl.
2607     */
2608    inh int InstArrayComponentDecl.myDimension();
2609    eq InstNode.getChild().myDimension()               = 0;
2610    eq InstRecordConstructor.getChild().myDimension()  = 0;
2611    eq InstArrayComponentDecl.getChild().myDimension() = myDimension() + 1;
2612
2613    /**
2614     * Check if this InstArrayComponentDecl is in the bottom dimension of the array.
2615     */
2616    syn boolean InstArrayComponentDecl.isBottomDimension() = isBottomDimHelper(1);
2617
2618    inh boolean InstArrayComponentDecl.isBottomDimHelper(int i);
2619    eq InstNode.getChild().isBottomDimHelper(int i)               = i == ndims();
2620    eq InstRecordConstructor.getChild().isBottomDimHelper(int i)  = i == ndims();
2621    eq InstArrayComponentDecl.getChild().isBottomDimHelper(int i) = isBottomDimHelper(i + 1);
2622
2623    /**
2624     * Efficiently check if this InstArrayComponentDecl is in the top dimension of the array.
2625     */
2626    inh boolean InstArrayComponentDecl.isTopDimension();
2627    eq InstNode.getChild().isTopDimension()               = true;
2628    eq InstRecordConstructor.getChild().isTopDimension()  = true;
2629    eq InstArrayComponentDecl.getChild().isTopDimension() = false;
2630
2631        /**
2632         * Find the length of the dimension corresponding to this InstArrayComponentDecl.
2633         */
2634        syn int InstComponentDecl.myDimensionLength() = size().get(0);
2635        eq InstArrayComponentDecl.myDimensionLength() = dimensionLength(0);
2636
2637    /**
2638     * Find the length of the dimension corresponding to the next level of InstArrayComponentDecls in an array.
2639     *
2640     * For a primitive, the length of the first dimension is returned.
2641     */
2642    syn int InstComponentDecl.childDimensionLength() = size().get(0);
2643    eq InstArrayComponentDecl.childDimensionLength() = dimensionLength(1);
2644
2645        /**
2646         * Find the length of the dimension corresponding to the InstArrayComponentDecl(s)
2647         *        <code>i</code> levels under this one.
2648         */
2649        inh int InstArrayComponentDecl.dimensionLength(int i);
2650        eq InstArrayComponentDecl.getInstComponentDecl().dimensionLength(int i) = dimensionLength(i + 1);
2651        eq InstComponentDecl.getInstComponentDecl().dimensionLength(int i)      = size().get(i);
2652        eq InstRoot.getChild().dimensionLength(int i)                           = Size.UNKNOWN;
2653        eq FlatRoot.getChild().dimensionLength(int i)                           = Size.UNKNOWN;
2654
2655    /**
2656     * Get an Index to my cell.
2657     *
2658     * Only valid for bottom level in array.
2659     */
2660    syn Index InstArrayComponentDecl.myIndex() {
2661        Index i = parentIndex();
2662        i.set(myDimension(), getIndex());
2663        return i;
2664    }
2665
2666    /**
2667     * Calculate Index of parent.
2668     *
2669     * For internal use only - returns an incomplete Index. See {@link #myIndex()}.
2670     */
2671    inh Index InstArrayComponentDecl.parentIndex();
2672    eq InstNode.getChild().parentIndex()               = null;
2673    eq InstRecordConstructor.getChild().parentIndex()  = null;
2674    eq InstComponentDecl.getChild().parentIndex()      = new Index(new int[ndims()]);
2675    eq InstArrayComponentDecl.getChild().parentIndex() = myIndex();
2676   
2677    /**
2678     * Get an Index to my cell for the concatenation of all surrounding array indices.
2679     */
2680    syn Index InstArrayComponentDecl.myTotalIndex() = parentTotalIndex().expand(myIndex());
2681   
2682    /**
2683     * For internal use only - returns an incomplete Index. See {@link #myTotalIndex()}.
2684     */
2685    inh Index InstComponentDecl.parentTotalIndex();
2686    eq InstProgramRoot.getChild().parentTotalIndex()        = Index.NULL;
2687    eq InstComponentDecl.getChild().parentTotalIndex()      = parentTotalIndex();
2688    eq InstArrayComponentDecl.getChild().parentTotalIndex() = isBottomDimension() ? myTotalIndex() : myTotalIndex();
2689
2690    /**
2691     * The top level component for the array.
2692     */
2693    inh InstComponentDecl InstArrayComponentDecl.instComponentDecl();
2694    eq InstArrayComponentDecl.getChild().instComponentDecl() = instComponentDecl();
2695    eq InstComponentDecl.getChild().instComponentDecl()      = this;
2696    eq Root.getChild().instComponentDecl()                   = null;
2697
2698    /**
2699     * If this is an array, get the top level component for the array.
2700     */
2701    syn InstComponentDecl InstComponentDecl.arrayTopInstComponentDecl() = this;
2702    eq InstArrayComponentDecl.arrayTopInstComponentDecl()               = instComponentDecl();
2703
2704        syn boolean InstComponentDecl.isArrayDecl() = hasFArraySubscripts() && 
2705                getFArraySubscripts().ndims()>0;
2706       
2707    syn java.util.List<? extends Subscript> InstNode.myFSubscripts() = Collections.emptyList();
2708    eq InstSimpleShortClassDecl.myFSubscripts()             = actualInstClass().myFSubscripts();
2709    eq InstLibNode.myFSubscripts()                          = actualInstClass().myFSubscripts();
2710    eq InstFullClassDecl.myFSubscripts()                    = 
2711        (getNumInstExtends() == 1) ? getInstExtends(0).myFSubscripts() : super.myFSubscripts();
2712    eq InstExtends.myFSubscripts()                          = 
2713        isRecursive() ? Collections.<FSubscript>emptyList() : myInstClass().myFSubscripts();
2714    syn lazy java.util.List<Subscript> InstShortClassDecl.myFSubscripts() {
2715                java.util.List<Subscript> l = new ArrayList<>();
2716        if (hasFArraySubscripts()) {
2717            for (Subscript s : getFArraySubscripts().subscripts()) {
2718                l.add(s);
2719            }
2720        }
2721        if (getNumInstExtends() == 1) {
2722                        l.addAll(getInstExtends(0).myFSubscripts());
2723        }
2724                return l;
2725        }
2726        syn lazy java.util.List<Subscript> InstComponentDecl.myFSubscripts() {
2727                java.util.List<Subscript> l = new ArrayList<>();
2728                addLocalFArraySubscriptsTo(l);
2729                l.addAll(myInstClass().myFSubscripts());
2730                return l;
2731        }
2732       
2733        public void InstComponentDecl.addLocalFArraySubscriptsTo(java.util.List<Subscript> l) {
2734        if (hasLocalFArraySubscripts()) {
2735            for (Subscript s : getLocalFArraySubscripts().subscripts()) {
2736                l.add(s);
2737            }
2738        } else {
2739            addFSubscriptsFromOriginalDeclTo(l);
2740        }
2741        }
2742       
2743    public void InstComponentDecl.addFSubscriptsFromOriginalDeclTo(java.util.List<Subscript> l) {}
2744    public void InstReplacingComposite.addFSubscriptsFromOriginalDeclTo(java.util.List<Subscript> l) {
2745        getOriginalInstComponent().addLocalFArraySubscriptsTo(l);
2746    }
2747    public void InstReplacingRecord.addFSubscriptsFromOriginalDeclTo(java.util.List<Subscript> l) {
2748        getOriginalInstComponent().addLocalFArraySubscriptsTo(l);
2749    }
2750    public void InstReplacingPrimitive.addFSubscriptsFromOriginalDeclTo(java.util.List<Subscript> l) {
2751        getOriginalInstComponent().addLocalFArraySubscriptsTo(l);
2752    }
2753
2754        /**
2755         * This is the definition of an NTA that collects both the local
2756         * array subscripts given a component declaration and array subscripts
2757         * given on the declaration's class (in the case of short
2758         * class declarations).
2759         */
2760        syn lazy FArraySubscripts InstComponentDecl.getFArraySubscripts() {
2761            if (myFSubscripts().isEmpty())
2762                return null;
2763        List<FSubscript> list = new List<FSubscript>();
2764        for (Subscript s : myFSubscripts()) { 
2765            list.add(s.deferredCopy());
2766        }
2767        return new FArrayExpSubscripts(list);
2768        }
2769       
2770        syn boolean InstComponentDecl.hasFArraySubscripts() = getFArraySubscripts()!=null;
2771       
2772}
2773
2774aspect DeferredSubscripts {
2775
2776    public FSubscript FSubscript.deferredCopy() {
2777        return treeCopy();
2778    }
2779
2780    public FSubscript FExpSubscript.deferredCopy() {
2781        return copyLocationTo(new FDeferExpSubscript(getFExp().treeCopy(), this));
2782    }
2783
2784    public FSubscript IntegerSubscript.deferredCopy() {
2785        return new FIntegerSubscript(value);
2786    }
2787
2788    inh InstLookupResult<InstComponentDecl> FExpSubscript.lookupInstComponent(String name);
2789    eq FDeferExpSubscript.getFExp().lookupInstComponent(String name) = getDefer().lookupInstComponent(name);
2790
2791}
2792
2793aspect InstanceAnnotations {
2794   
2795    syn lazy Opt<InstClassModification> InstClassDecl.getClassAnnotationOpt() = new Opt<InstClassModification>();
2796    syn lazy Opt<InstClassModification> InstComponentDecl.getClassAnnotationOpt() = new Opt<InstClassModification>();
2797    syn lazy Opt<InstClassModification> InstExtends.getClassAnnotationOpt() = new Opt<InstClassModification>();
2798    syn lazy Opt<InstClassModification> InstExtends.getClassAnnotationExtendsOpt() = new Opt<InstClassModification>();
2799   
2800    syn lazy Opt<InstClassModification> InstComponentDecl.getAnnotationOpt() = new Opt<InstClassModification>();
2801   
2802    syn lazy Opt<InstClassModification> InstElementModification.getAnnotationOpt() = new Opt<InstClassModification>();
2803}
2804
2805aspect InstanceToString {
2806
2807
2808    public String InstClassDecl.toString() {
2809        return getSrcClassDecl().toString();
2810    }
2811   
2812    public String InstExternal.toString() {
2813        return getSrcExternalClause().toString();
2814    }
2815   
2816    public String InstComponentDecl.toString() {
2817        return getSrcComponentDecl().myComponentClause().toString();
2818    }
2819
2820    public String InstEnumLiteral.toString() {
2821        return prettyPrint("");
2822    }
2823   
2824    public String InstExtends.toString() {
2825        return getSrcExtendsClause().toString();
2826    }
2827
2828    public String InstModification.toString() {
2829        return getSrcModification().toString();
2830    }
2831
2832}
2833
2834
2835aspect InheritedFrom {
2836
2837    /**
2838     * If this class was inherited into this scope, return the corresponding class
2839     * from the inherited class.
2840     *
2841     * The inhetitance can be either direct or through a surronding class that was
2842     * inherited in. This method only follows a single extends.
2843     *
2844     * If no surrounding extends exists or any lookup fails, <code>this</code> is returned.
2845     */
2846    syn InstClassDecl InstClassDecl.myInheritedOrigin() {
2847        InstClassDecl res = inheritedOriginHelper(name());
2848        return res.isUnknown() ? this : res;
2849    }
2850
2851    inh InstClassDecl InstClassDecl.inheritedOriginHelper(String name);
2852    eq InstExtends  .getInstClassDecl().inheritedOriginHelper(String name) = 
2853        myInstClass().memberInstClass(name).target(INST_UNKNOWN_CLASS, this);
2854    eq InstClassDecl.getInstClassDecl().inheritedOriginHelper(String name) = 
2855        inheritedOriginHelper(name()).memberInstClass(name).target(INST_UNKNOWN_CLASS, this);
2856    eq InstNode     .getChild()        .inheritedOriginHelper(String name) = 
2857        unknownInstClassDecl();
2858}
2859
2860
2861/* TODO: If we are doing this, we should do it properly
2862aspect InstancePrettyPrint {
2863
2864        public String InstNode.prettyPrint(String indent) {
2865                String str = getClass().getName();
2866                str = indent + str.substring(str.lastIndexOf('.')+1);
2867                return str;
2868
2869        }
2870
2871        public String InstBaseClassDecl.prettyPrint(String indent) {
2872                String str = getClass().getName();
2873                str = indent+str.substring(str.lastIndexOf('.')+1);
2874                str+= ": " + name();
2875                return str;
2876
2877        }
2878
2879        public String InstShortClassDecl.prettyPrint(String indent) {
2880                String str = getClass().getName();
2881                str = indent+str.substring(str.lastIndexOf('.')+1);
2882                str+= ": " + getInstExtends(0).getClassName().name() + " "+ name();
2883                return str;
2884        }
2885
2886        public String InstExtendsShortClass.prettyPrint(String indent) {
2887                String str = getClass().getName();
2888                str = indent+str.substring(str.lastIndexOf('.')+1);
2889                str+= ": " + getClassName().name();
2890                return str;
2891               
2892        }
2893
2894        public String InstExtends.prettyPrint(String indent) {
2895                String str = getClass().getName();
2896                str = indent+str.substring(str.lastIndexOf('.')+1);
2897                str+= ": " + getClassName().name();
2898                return str;
2899               
2900        }
2901
2902        public String InstComponentDecl.prettyPrint(String indent) {
2903                String str = getClass().getName();
2904                str = indent+str.substring(str.lastIndexOf('.')+1);
2905                str+= ": " + getClassName().name() + " "+
2906                                      name();
2907                return str;
2908
2909        }
2910
2911        public String InstArrayComponentDecl.prettyPrint(String indent) {
2912                String str = getClass().getName();
2913                str = indent+str.substring(str.lastIndexOf('.')+1);
2914                str+= ": " + getIndex();
2915                return str;
2916
2917        }
2918       
2919        public String InstImport.prettyPrint(String indent) {
2920                String str = getClass().getName();
2921                str = indent+str.substring(str.lastIndexOf('.')+1);
2922                str += ": " + getPackageName().name();
2923                return str;
2924        }
2925
2926        public String InstAccess.prettyPrint(String indent) {
2927                String str = getClass().getName();
2928                str = indent+str.substring(str.lastIndexOf('.')+1);
2929                str += ": " + name();
2930                return str;
2931        }
2932
2933       
2934}
2935*/
Note: See TracBrowser for help on using the repository browser.