source: trunk/Compiler/ModelicaFrontEnd/src/jastadd/instance/InstanceTree.jrag @ 12962

Last change on this file since 12962 was 12962, checked in by molsson, 6 months ago

InstNode.isPrimitive returns true for classes extending primitives (except ExternalObject).

File size: 128.4 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    eq InstExpandableConnectorDecl.getInstComponentDecl(int i).myEnvironment(String name)          = 
671        useTemplate(i) ? template(i).myEnvironment(name) : myEnvironment_def(name);
672    eq InstArrayExpandableConnector.getInstComponentDecl(int i).myEnvironment(String name)         = 
673        useTemplate(i) ? template(i).myEnvironment(name) : myEnvironment_def(name);
674    eq InstReplacingExpandableConnectorDecl.getInstComponentDecl(int i).myEnvironment(String name) = 
675        useTemplate(i) ? template(i).myEnvironment(name) : myEnvironment_def(name);
676
677    syn lazy Environment InstNode.myEnvironment_def(String name) = 
678        getMergedEnvironment().filter(name, retrieveReplacingComponent(name), retrieveReplacingClass(name));
679    syn lazy Environment InstRecordConstructor.myEnvironment_def(String name) = 
680        declarationInstComponent(name).filteredEnvironment().mergeOuterClone(getMergedEnvironment().filter(name));
681
682    eq InstReplacingShortClassDecl.getOriginalInstClass().myEnvironment()            = filteredEnvironment();
683    eq InstReplacingShortClassDecl.getOriginalInstClass().myEnvironment(String name) = filteredEnvironment().filter(name);
684
685    inh Environment InstComponentRedeclare.myEnvironment(String name);
686    inh Environment InstClassRedeclare.myEnvironment(String name);
687    inh Environment InstConstraining.myEnvironment(String name);
688
689    // Get environment and add any modifications from constraining
690    eq InstComponentRedeclare.getInstComponentDecl().myEnvironment(String name) =
691        myEnvironment(name).mergeInnerClone(instModificationsFromConstrainingType());
692    eq InstClassRedeclare.getInstClassDecl().myEnvironment(String name)         =
693        myEnvironment(name).mergeInnerClone(instModificationsFromConstrainingType());
694
695    eq InstConstraining.getInstNode().myEnvironment(String name) {
696        Environment env = myEnvironment(name);
697        if (hasInstClassModification())
698            env = env.clone().mergeInner(getInstClassModification());
699        return env;
700    }
701
702    eq Program.getInstProgramRoot().myEnvironment() = new Environment();
703    eq Program.getInstProgramRoot().myEnvironment(String name) = new Environment();
704
705    syn lazy List<InstArrayModification> InstValueModification.getInstArrayModificationList() {
706        List<InstArrayModification> res = new List<InstArrayModification>();
707        if (getFExp().isArray()) {
708            for (int i = 1, n = getFExp().size().get(0) + 1; i < n; i++) {
709                FExp exp = getFExp().splitArrayExp(i);
710                res.add(new InstArrayModification(getSrcModification(), exp));
711            }
712        }
713        return res;
714    }
715
716    /**
717     * Get the InstValueModification corresponding to the specified cell (1-based index) of the array.
718     */
719    syn InstValueModification InstValueModification.arrayInstModification(int i) {
720        int n = getNumInstArrayModification();
721        if (n <= 0) {
722            return this;
723        } else {
724            // Make sure we always return something
725            int j = (i > 0 && i <= n) ? i - 1 : 0;
726            return getInstArrayModification(j);
727        }
728    }
729
730    syn InstModification InstModification.matchInstModification(String name) = null;
731    eq InstCompleteModification.matchInstModification(String name) {
732        for (InstModification im : getInstClassModification().getInstArguments()) {
733            InstModification match = im.matchInstModification(name);
734            if (match != null)
735                return match;
736        }
737        return null;
738    }
739
740    eq InstComponentModification.matchInstModification(String name) {
741        if (name().equals(name))
742            return hasInstModification() ? getInstModification() : null;
743        return null;
744    }
745   
746    // Only add modifiers in constraining clauses
747    eq InstComponentRedeclare.matchInstModification(String name) {
748        if (name().equals(name) && hasConstrainingModification())
749            return getInstComponentDecl().getInstConstrainingComponent().getInstClassModification();
750        return null;
751    }
752
753    // Only add modifiers in constraining clauses
754    eq InstClassRedeclare.matchInstModification(String name) {
755        if (name().equals(name) && hasConstrainingModification())
756            return getInstClassDecl().getInstConstrainingClass().getInstClassModification();
757        return null;
758    }
759   
760   
761    /**
762     * Find the InstModification containing this expression, if any.
763     */
764    inh InstModification FExp.surroundingInstModification();
765    eq InstModification.getChild().surroundingInstModification() = this;
766    eq InstNode.getChild().surroundingInstModification()         = null;
767    eq Root.getChild().surroundingInstModification()             = null;
768   
769   
770    syn InstComponentRedeclare InstModification.matchInstComponentRedeclare(String name) = null;
771    eq InstComponentRedeclare.matchInstComponentRedeclare(String name) {
772        if (getName().name().equals(name))
773            return this;
774        else
775            return null;
776    }
777
778    syn InstClassRedeclare InstModification.matchInstClassRedeclare(String name) = null;
779    eq InstClassRedeclare.matchInstClassRedeclare(String name) {
780        if (getName().name().equals(name))
781            return this;
782        else
783            return null;
784    }
785
786    syn InstComponentRedeclare InstNode.retrieveReplacingComponent(String name) {
787        for (InstModification im : getMergedEnvironment()) {
788            InstComponentRedeclare icr = im.matchInstComponentRedeclare(name);
789            if (icr != null) 
790                return icr;
791        }
792        return null;
793    }
794
795    syn InstComponentRedeclare InstNode.retrieveConstrainingComponent(String name) {
796        for (InstModification im : getMergedEnvironment()) {
797            InstComponentRedeclare icr = im.matchInstComponentRedeclare(name);
798            if (icr != null && icr.getComponentRedeclareDecl().hasSrcConstrainingClause()) 
799                return icr;
800        }
801        return null;
802    }
803
804    // TODO: make sure components are created using the right class now
805    syn InstRedeclareClassNode InstNode.retrieveReplacingClass(String name) {
806        for (InstModification im : getMergedEnvironment()) {
807            InstClassRedeclare icr = im.matchInstClassRedeclare(name);
808            if (icr != null) 
809                return icr;
810        }
811        return null;
812    }
813
814    syn InstRedeclareClassNode InstNode.retrieveConstrainingClass(String name) {
815        for (InstModification im : getMergedEnvironment()) {
816            InstRedeclareClassNode icr = im.matchInstClassRedeclare(name);
817            if (icr != null && icr.redeclaringClassDecl().hasSrcConstrainingClause()) 
818                return icr;
819        }
820        return null;
821    }
822
823    eq InstExtends.retrieveReplacingClass(String name) {
824        InstRedeclareClassNode res = super.retrieveReplacingClass(name);
825        return (res == null) ? lookupReplacingClass(name) : res;
826    }
827   
828    inh InstRedeclareClassNode InstExtends.lookupReplacingClass(String name);
829    eq InstNode.getInstExtends().lookupReplacingClass(String name) {
830        for (InstClassDecl icd : getRedeclaredInstClassDecls())
831                if (icd.name().equals(name))
832                        return icd;
833        return retrieveReplacingClass(name);
834    }
835    eq InstExtends.getChild().lookupReplacingClass(String name) {
836        InstRedeclareClassNode res = lookupReplacingClass(name);
837        if (res != null)
838                return res;
839        for (InstClassDecl icd : getRedeclaredInstClassDecls())
840                if (icd.name().equals(name))
841                        return icd;
842        return super.retrieveReplacingClass(name);
843    }
844    eq InstRoot.getChild().lookupReplacingClass(String name) = null;
845    eq Root.getChild().lookupReplacingClass(String name)     = null;
846
847    inh InstNode InstModification.myInstNode();
848    inh InstNode InstNode.myInstNode();
849    inh InstNode FAbstractEquation.myInstNode();
850    eq Root.getChild().myInstNode()                       = null;
851    eq InstNode.getChild().myInstNode()                   = this;
852    eq InstComponentDecl.getChild().myInstNode()          = 
853        isExpandableConnectorMember() ? myExpandableConnectorTemplate() : this;
854    eq InstNode.getElementInstModification().myInstNode() = myInstNode();
855    eq InstExpandableConnectorDecl.getInstComponentDecl(int i).myInstNode()          = 
856        template(i).myInstNode();
857    eq InstReplacingExpandableConnectorDecl.getInstComponentDecl(int i).myInstNode() = 
858        template(i).myInstNode();
859    eq InstArrayExpandableConnector.getInstComponentDecl(int i).myInstNode()         = 
860        template(i).myInstNode();
861
862    inh InstNode InstModification.myParentInstNode();
863    inh InstNode InstNode.myParentInstNode();
864    eq Root.getChild().myParentInstNode()     = null;
865    eq InstNode.getChild().myParentInstNode() = this;
866
867    //The lexical scope of modifiers for short classes are "outside" of the short declaration
868    eq InstExtendsShortClass.getChild().myInstNode() = getLookupNode();
869
870        /**
871         * InstPrimitive:s may have children of type InstExtends, if the InstPrimitive is instantiated
872         * either from a short class declaration that references a primitive type or from a 'type' class
873         * declaration that inherits a primitive type. In both cases, the result is one or a chain of InstExtends/
874         * InstExtendsShortClass children. The final node in such a chain holds the total merged environment of
875         * the InstPrimitive. InstRecords can of course have InstExtends.
876         */
877        syn lazy Environment InstNode.totalMergedEnvironment() {
878                if (getNumInstExtends()==0)
879                        return getMergedEnvironment();
880                else
881                        return getInstExtends(0).totalMergedEnvironment();
882        }
883    eq InstSimpleShortClassDecl.totalMergedEnvironment() = actualInstClass().getMergedEnvironment();
884    eq InstLibNode.totalMergedEnvironment()              = actualInstClass().getMergedEnvironment();
885
886}
887
888aspect InstanceTreeConstruction {
889
890    syn lazy List Program.getAnonymousClassList() = new List();
891
892    private Map<String,SrcClassDecl> Program.anonymousClassMap = null;
893
894    syn SrcClassDecl Program.anonymousClass(String code, SrcRestriction restriction, String targetName) {
895        if (anonymousClassMap == null)
896            anonymousClassMap = new HashMap<String,SrcClassDecl>();
897        SrcClassDecl res = anonymousClassMap.get(code);
898        if (res == null) {
899            try {
900                addAnonymousClass(root().getUtilInterface().getParserHandler().parseAnonymousClassString(code, restriction, targetName));
901                res = getAnonymousClass(getNumAnonymousClass() - 1);
902                anonymousClassMap.put(code, res);
903            } catch (IOException e) {
904                // Can't normally happen when reading from a string, but just in case
905                throw new RuntimeException("Reading from string failed", e);
906            } catch (beaver.Parser.Exception e) {
907                // Parser crashed - just handle this higher up
908                throw new RuntimeException("Parser crashed", e);
909            } catch (ParserException e) {
910                CompilerException ce = new CompilerException();
911                ce.addProblem(e.getProblem());
912                throw ce;
913            }
914        }
915        return res;
916    }
917
918    syn lazy List InstProgramRoot.getInstAnonymousClassList() = new List();
919
920    syn lazy InstClassDecl InstProgramRoot.instantiateModel(String className) {
921        int p = className.indexOf('(');
922        if (p >= 0) {
923            String targetName = className.substring(0, p);
924            InstLookupResult<InstClassDecl> icd = lookupInstClassQualified(targetName);
925            if (icd.successful()) {
926                SrcRestriction restriction = ((SrcBaseClassDecl) icd.target().actualInstClass().getSrcClassDecl()).getSrcRestriction();
927                SrcClassDecl cl = sourceRoot().getProgram().anonymousClass(className, restriction, targetName);
928                if (cl != null) {
929                    addInstAnonymousClass(createInstClassDecl(cl));
930                    return getInstAnonymousClass(getNumInstAnonymousClass() - 1);
931                }
932            }
933            return unknownInstClassDecl();
934        } else {
935            InstLookupResult<InstClassDecl> icd = lookupInstClassQualified(className);
936            return icd.successful() ? icd.target() : unknownInstClassDecl();
937        }
938    }
939
940    syn nta Opt InstNode.getDynamicFExpOpt()                       = new DynamicOpt();
941    syn nta Opt InstExternal.getDynamicFExpOpt()                   = new DynamicOpt();
942    syn nta Opt FExp.getDynamicFExpOpt()                           = new DynamicOpt();
943        syn nta Opt FAbstractEquation.getDynamicFAbstractEquationOpt() = new DynamicOpt();     
944        syn nta Opt FVariable.getDynamicFVariableOpt()                 = new DynamicOpt();
945       
946        /**
947         * Dynamically places an FExp in the tree under this InstNode.
948         *
949         * @return  the final version of the dynamically placed node.
950         */
951        public FExp InstNode.dynamicFExp(FExp exp) {
952                getDynamicFExpOpt().setChild(exp, 0);
953                return (FExp) getDynamicFExpOpt().getChild(0);
954        }
955
956    public void InstNode.clearDynamicFExp() {
957       getDynamicFExpOpt().setChild(null, 0);
958    }
959
960    /**
961     * Dynamically places an FExp in the tree under this InstExternal.
962     *
963     * @return  the final version of the dynamically placed node.
964     */
965    public FExp InstExternal.dynamicFExp(FExp exp) {
966        getDynamicFExpOpt().setChild(exp, 0);
967        return (FExp) getDynamicFExpOpt().getChild(0);
968    }
969       
970       
971        /**
972         * Dynamically places an FExp in the tree under this FExp.
973         *
974         * If <code>exp</code> is already in tree of if <code>exp == this</code>,
975         * then <code>exp</code> is returned.
976         *
977         * @return  the final version of the dynamically placed node.
978         */
979        public FExp FExp.dynamicFExp(FExp exp) {
980                if (exp == this || exp == null)
981                        return exp;
982                if (exp.parent != null) {
983                        int i = exp.parent.getIndexOfChild(exp);
984                        if (i >= 0)
985                                return (FExp) exp.parent.getChild(i);
986                }
987                getDynamicFExpOpt().setChild(exp, 0);
988                return (FExp) getDynamicFExpOpt().getChild(0);
989        }
990   
991    public FVariable FVariable.dynamicFVariable(FVariable fv) {
992        if (fv == this)
993            return fv;
994        if (fv.parent != null) {
995            int i = fv.parent.getIndexOfChild(fv);
996            if (i >= 0)
997                return (FVariable) fv.parent.getChild(i);
998        }
999        getDynamicFVariableOpt().setChild(fv, 0);
1000        return (FVariable) getDynamicFVariableOpt().getChild(0);
1001    }
1002   
1003    /**
1004     * Dynamically places an FAbstractEquation in the tree under this FAbstractEquation.
1005     *
1006     * @return  the final version of the dynamically placed node.
1007     */
1008    public FAbstractEquation FAbstractEquation.dynamicFAbstractEquation(FAbstractEquation eqn) {
1009        if (eqn == this)
1010            return eqn;
1011        getDynamicFAbstractEquationOpt().setChild(eqn, 0);
1012        return (FAbstractEquation) getDynamicFAbstractEquationOpt().getChild(0);
1013    }
1014
1015
1016    public interface InstLookupRedirectNode {
1017        InstLookupResult<InstClassDecl> lookupInstClassRedirect(String name);
1018    }
1019
1020        InstNode implements InstLookupRedirectNode;
1021        InstModification implements InstLookupRedirectNode;
1022
1023    syn lazy List InstNode.getInstComponentDeclList() {
1024        List<InstComponentDecl> l = new List<InstComponentDecl>();
1025        for (SrcComponentDecl cd : components()) {
1026            if (!cd.hasRedeclare()) {
1027                l.add(createInstComponentDecl(cd));
1028            }
1029        }
1030        return l;
1031       
1032    }
1033
1034    eq InstComponentDecl.getInstComponentDeclList() {
1035        //System.out.println( " : " + getClass().getName() + " : "+ myFSubscripts().size());
1036        if (isArray()) { // Take care of array declarations separately
1037            // Loop over indices and create new InstArrayComponentDecls
1038            List l = new List();
1039            // Only one FSubscript is used to create the one layer of InstArrayComponentDecls.
1040            // For a zero length or unknown length, create a dummy node with index 0.
1041            int n = childDimensionLength();
1042            for (int i = (n < 1) ? 0 : 1; i <= n || i == 0; i++)
1043                l.add(createInstArrayComponentDecl(i));
1044            return l;
1045        } else { // If not array, then proceed as usual
1046            return super.getInstComponentDeclList();
1047        }
1048    }
1049
1050    public InstComponentDecl InstComponentDecl.createInstArrayComponentDecl(int i) {
1051        return new InstArrayComponentDecl(name(), new InstClassAccess("ArrayDecl"), new Opt(), 
1052                getSrcComponentDecl(), new Opt(), new Opt(), new Opt(), i);
1053    }
1054
1055    syn lazy List InstNode.getInstClassDeclList() {
1056        List l = new List();
1057       
1058        for (SrcClassDecl cd : classes()) {
1059            if (!cd.hasRedeclare()) {
1060                InstClassDecl icd = createInstClassDecl(cd);
1061                if (icd != null)
1062                    l.add(icd);
1063            }
1064        }
1065       
1066        return l;
1067    }
1068
1069    syn lazy List InstNode.getRedeclaredInstClassDeclList() {
1070        List l = new List();
1071       
1072        for (SrcClassDecl cd : classes()) {
1073            if (cd.hasRedeclare()) {
1074                InstNode icd = cd.newInstClassDecl();
1075                if (icd != null)
1076                    l.add(icd);
1077            }
1078        }
1079       
1080        return l;
1081    }
1082
1083    syn boolean SrcClassDecl.getRedeclare() = false;
1084
1085    syn boolean SrcClassDecl.hasRedeclare() = getRedeclare();
1086    eq SrcExtendClassDecl.hasRedeclare()    = true;
1087
1088    syn lazy List InstNode.getInstExtendsList() {
1089        List l = new List();
1090        if (shouldHaveInstExtendsList()) {
1091            InstNode lookup = instLookupNodeForShortClassExtends();
1092            for (SrcExtendsClause e : superClasses()) { 
1093                l.add(createInstExtends(e, lookup));
1094            }
1095        }
1096        return l;
1097    }
1098
1099    syn boolean InstNode.shouldHaveInstExtendsList()      = true;
1100    eq InstComponentDecl.shouldHaveInstExtendsList()      = !isArrayDecl();
1101    eq InstArrayComponentDecl.shouldHaveInstExtendsList() = childDimensionLength() == Size.UNKNOWN;
1102
1103    /**
1104     * Find the instance tree node an extends below this node, from a short class declaration,
1105     * should look up right hand side names in its modification from.
1106     */
1107    syn InstNode InstNode.instLookupNodeForShortClassExtends()          = myInstClass().instLookupNodeForShortClassExtends();
1108    eq InstClassDecl.instLookupNodeForShortClassExtends()               = null;
1109    eq InstShortClassDecl.instLookupNodeForShortClassExtends()          = this;
1110    eq InstReplacingShortClassDecl.instLookupNodeForShortClassExtends() = getInstClassRedeclare().instLookupNodeForShortClassExtends();
1111    eq InstLibNode.instLookupNodeForShortClassExtends()                 = resolveLib().instLookupNodeForShortClassExtends();
1112
1113    syn InstNode InstClassRedeclare.instLookupNodeForShortClassExtends() = myInstNode();
1114
1115    eq InstPrimitive.getInstComponentDeclList() = new List();
1116    eq InstPrimitive.getInstClassDeclList() = new List();
1117
1118    syn lazy List<InstComponentDecl> InstRecordConstructor.getInstComponentDeclList() {
1119        InstClassDecl rec = getRecord().myInstClassDecl().actualInstClass();
1120        List<InstComponentDecl> l = new List<InstComponentDecl>();
1121        for (SrcComponentDecl cd : rec.components()) 
1122            l.add(rec.createInstComponentDecl(cd));
1123        return l;
1124    }
1125
1126    syn lazy List<InstExtends> InstRecordConstructor.getInstExtendsList() {
1127        InstClassDecl rec = getRecord().myInstClassDecl().actualInstClass();
1128        List l = new List();
1129        InstNode lookup = myInstClassDecl().instLookupNodeForShortClassExtends();
1130        for (SrcExtendsClause e : rec.superClasses()) 
1131            l.add(rec.createInstExtends(e, lookup));
1132        return l;
1133    }
1134
1135    syn lazy List<InstModification> InstRecordConstructor.getInstModificationList() {
1136        List<InstModification> res = new List<InstModification>();
1137        for (InstFunctionArgument ifa : getArgs()) {
1138            ifa.populateInstModifications(res);
1139        }
1140        return res;
1141    }
1142
1143    public void InstFunctionArgument.populateInstModifications(List<InstModification> res) {}
1144
1145    public void InstPositionalArgument.populateInstModifications(List<InstModification> res) {
1146        res.add(newInstModification());
1147    }
1148
1149    public void InstNamedArgument.populateInstModifications(List<InstModification> res) {
1150        res.add(newInstModification());
1151    }
1152
1153    syn InstModification InstFunctionArgument.newInstModification() = 
1154            new InstComponentModification(getSrcModification(), false, false,
1155                    boundInput.createInstAccess(),
1156                    new Opt<InstModification>(getSrcModification().newInstModification()));
1157
1158    syn InstValueModification SrcDummyModification.newInstModification() = new InstValueModification(this);
1159
1160    syn nta SrcModification InstFunctionArgument.getSrcModification() {
1161        SrcDummyModification res = new SrcDummyModification();
1162        copyLocationTo(res);
1163        return res;
1164    }
1165
1166
1167    syn lazy List<InstModification> InstNode.getElementInstModificationList() {
1168        List<InstModification> l = new List<InstModification>();
1169        for (SrcModificationOrRedeclareElement m : elementModifications()) 
1170            l.add(m.newInstModification());
1171        return l;
1172    }
1173
1174
1175    public InstComponentDecl InstNode.createInstComponentDecl(SrcComponentDecl cd) {
1176        // Check if the component is redeclared.
1177        // -> Yes: Create an InstReplacingComponent component
1178        // -> No: Create an InstComponent
1179        InstComponentRedeclare irc = retrieveReplacingComponent(cd.name());
1180        InstComponentRedeclare cicr = retrieveConstrainingComponent(cd.name());
1181        if (irc!=null) {
1182            SrcComponentDecl replacingComp = irc.getComponentRedeclareDecl();
1183            return new InstCreateReplacingComponentDecl(replacingComp, irc, cd, irc, cicr);
1184            // TODO: handle expandable connectors in this case
1185        } else { 
1186            return new InstCreateComponentDecl(cd, null);
1187        }
1188     }
1189
1190     rewrite InstCreateReplacingComponentDecl {
1191         to InstComponentDecl getClassName().myInstClassDecl().newInstReplacingComponent(
1192                 getSrcComponentDecl(), getOriginalDecl(), 
1193                 getInstComponentRedeclare(), getInstConstrainingRedeclare());
1194     }
1195     
1196     rewrite InstCreateComponentDecl {
1197         to InstComponentDecl getClassName().myInstClassDecl().newInstComponentDecl(getSrcComponentDecl());
1198     }
1199     
1200     rewrite InstCreateForIndexPrimitive {
1201         to InstPrimitive (InstPrimitive) getClassName().myInstClassDecl().newInstComponentDecl(getSrcComponentDecl());
1202     }
1203
1204     public InstClassDecl InstNode.createInstClassDecl(SrcClassDecl bcd) {
1205         // Check if the class is redeclared.
1206         // -> Yes: Create an InstReplacingClass component
1207         // -> No: Create an InstClassDecl
1208         InstRedeclareClassNode icr = retrieveReplacingClass(bcd.name());
1209         InstRedeclareClassNode cicr = retrieveConstrainingClass(bcd.name());
1210         if (icr != null) {
1211             SrcClassDecl replacingClass = icr.redeclaringClassDecl();
1212             return bcd.newInstReplacingClass(replacingClass, icr, cicr);
1213         } else {
1214             return bcd.newInstClassDecl();
1215         }
1216     }
1217
1218     public interface InstRedeclareClassNode {
1219         public InstLookupResult<InstComponentDecl> lookupInstComponent(String name);
1220         public InstLookupResult<InstClassDecl> lookupInstClass(String name);
1221         public InstLookupResult<InstClassDecl> lookupInstClassQualified(String name);
1222         public SrcClassDecl redeclaringClassDecl();
1223         public InstClassDecl redeclaringInstClassDecl();
1224         public InstNode instLookupNodeForShortClassExtends();
1225     }
1226    InstClassDecl implements InstRedeclareClassNode;
1227    InstClassRedeclare implements InstRedeclareClassNode;
1228
1229    syn SrcClassDecl InstClassDecl.redeclaringClassDecl()      = getSrcClassDecl();
1230    syn SrcClassDecl InstClassRedeclare.redeclaringClassDecl() = getSrcClassRedeclare().getSrcBaseClassDecl();
1231
1232    syn InstClassDecl InstClassDecl.redeclaringInstClassDecl()      = this;
1233    syn InstClassDecl InstClassRedeclare.redeclaringInstClassDecl() = getInstClassDecl();
1234
1235    public InstNode InstNode.createInstExtends(SrcExtendsClause ec, InstNode lookup) {
1236        // This cannot be redeclared. Just create and return.
1237        return ec.newInstExtends(lookup);
1238    }
1239
1240    public InstNode InstReplacingShortClassDecl.createInstExtends(SrcExtendsClause ec, InstNode lookup) {
1241        return createInstExtendsCheckReplacing(ec, lookup);
1242    }
1243
1244    public InstNode InstReplacingSimpleShortClassDecl.createInstExtends(SrcExtendsClause ec, InstNode lookup) {
1245        return createInstExtendsCheckReplacing(ec, lookup);
1246    }
1247
1248    public InstNode InstExtendsShortClass.createInstExtends(SrcExtendsClause ec, InstNode lookup) {
1249        return createInstExtendsCheckReplacing(ec, lookup);
1250    }
1251
1252    public InstNode InstReplacingExtendsShortClass.createInstExtends(SrcExtendsClause ec, InstNode lookup) {
1253        return createInstExtendsCheckReplacing(ec, lookup);
1254    }
1255
1256    public InstNode InstNode.createInstExtendsCheckReplacing(SrcExtendsClause ec, InstNode lookup) {
1257        if (!isInInstModification() && ec.needsReplacingExtends()) {
1258            Environment e = myEnvironment();
1259            InstModification im = findMatching(e, name());
1260            if (im != null)
1261                return im.createInstReplacingExtends(ec, lookup);
1262        }
1263        return ec.newInstExtends(lookup);
1264    }
1265
1266    public InstExtends InstModification.createInstReplacingExtends(SrcExtendsClause ec, InstNode lookup) {
1267        return ec.newInstExtends(lookup);
1268    }
1269
1270    public InstExtends InstClassRedeclare.createInstReplacingExtends(SrcExtendsClause ec, InstNode lookup) {
1271        for (InstExtends ie : getInstClassDecl().actualInstClass().getInstExtendss())
1272            return ie.createInstReplacingExtends(ec, lookup);
1273        return ec.newInstExtends(lookup);
1274    }
1275
1276    public InstExtends InstShortClassDecl.createInstReplacingExtends(SrcExtendsClause ec, InstNode lookup) {
1277        for (InstExtends ie : getInstExtendss())
1278            return ie.createInstReplacingExtends(ec, lookup);
1279        return ec.newInstExtends(lookup);
1280    }
1281
1282    public InstExtends InstSimpleShortClassDecl.createInstReplacingExtends(SrcExtendsClause ec, InstNode lookup) {
1283        return actualInstClass().createInstReplacingExtends(ec, lookup);
1284    }
1285
1286    public InstExtends InstLibNode.createInstReplacingExtends(SrcExtendsClause ec, InstNode lookup) {
1287        return actualInstClass().createInstReplacingExtends(ec, lookup);
1288    }
1289
1290    public InstExtends InstNode.createInstReplacingExtends(SrcExtendsClause ec, InstNode lookup) {
1291        return ec.newInstExtends(lookup);
1292    }
1293
1294    public InstExtends InstExtendsShortClass.createInstReplacingExtends(SrcExtendsClause ec, InstNode lookup) {
1295        return ec.newInstReplacingExtends(this);
1296    }
1297
1298    eq InstNamedModification.matches(String str) = name().equals(str);
1299
1300    inh boolean InstNode.isInInstModification();
1301    eq InstModification.getChild().isInInstModification() = true;
1302    eq InstRoot.getChild().isInInstModification()         = false;
1303    eq Root.getChild().isInInstModification()             = false;
1304
1305    syn boolean SrcExtendsClause.needsReplacingExtends()  = false;
1306    eq SrcExtendsClauseShortClass.needsReplacingExtends() = true;
1307
1308
1309    public InstComponentDecl InstClassDecl.newInstComponentDecl(SrcComponentDecl cd) {
1310        return newInstComponentDecl(cd, cd.getClassName());
1311    }
1312
1313    public InstComponentDecl InstClassDecl.newInstComponentDecl(SrcComponentDecl cd, SrcAccess className) {
1314        InstComponentDecl icd = newInstComponentDeclGeneric(cd.name(), cd, className);
1315        if (cd.hasSrcArraySubscripts()) {
1316            icd.setLocalFArraySubscripts(cd.instantiateArraySubscripts());
1317        }
1318        if (cd.hasSrcConditionalAttribute())
1319            icd.setConditionalAttribute(cd.getSrcConditionalAttribute().getSrcExp().instantiate());
1320        return icd;
1321    }
1322
1323    public InstComponentDecl InstClassDecl.newInstComponentDeclCopy(
1324            String name, FArraySubscripts subscripts, SrcComponentDecl cd, SrcAccess className) {
1325        InstComponentDecl icd = newInstComponentDeclGeneric(name, cd, className);
1326        if (subscripts != null) {
1327            icd.setLocalFArraySubscripts(subscripts);
1328        }
1329        return icd;
1330    }
1331
1332    public abstract InstComponentDecl InstClassDecl.newInstComponentDeclGeneric(String name, SrcComponentDecl cd, SrcAccess className);
1333
1334    public InstComponentDecl InstBaseClassDecl.newInstComponentDeclGeneric(String name, SrcComponentDecl cd, SrcAccess className) {
1335        InstComponentDecl icd = emptyInstComponentDecl(name, cd, className.newInstAccess());
1336        if (cd.hasSrcModification()) {
1337            icd.setInstModification(cd.getSrcModification().newInstModification());
1338        }
1339        icd.setInstConstrainingComponentOpt(cd.newInstConstrainingComponentOpt(null));
1340        icd.setLocation(cd.myComponentClause());
1341        return icd;
1342    }
1343
1344    public InstComponentDecl InstSimpleShortClassDecl.newInstComponentDeclGeneric(String name, SrcComponentDecl cd, SrcAccess className) {
1345        return actualInstClass().newInstComponentDeclGeneric(name, cd, className);
1346    }
1347
1348    public InstComponentDecl InstLibNode.newInstComponentDeclGeneric(String name, SrcComponentDecl cd, SrcAccess className) {
1349        return actualInstClass().newInstComponentDeclGeneric(name, cd, className);
1350    }
1351
1352    public InstComponentDecl BadInstClassDecl.newInstComponentDeclGeneric(String name, SrcComponentDecl cd, SrcAccess className) {
1353        throw new UnsupportedOperationException();
1354    }
1355
1356    public InstComponentDecl InstBaseClassDecl.emptyInstComponentDecl(String name, SrcComponentDecl cd, InstAccess className) {
1357        if (isRecord()) 
1358            return new InstRecord(name, className, new Opt(), cd, new Opt(), new Opt(), new Opt());
1359        else if (extendsEnum()) 
1360            return new InstEnum(name, className, new Opt(), cd, new Opt(), new Opt(), new Opt());
1361        else if (isExternalObject())
1362            return new InstExternalObject(name, className, new Opt(), cd, new Opt(), new Opt(), new Opt());
1363        else if (extendsPrimitive()) 
1364            return new InstPrimitive(name, className, new Opt(), cd, new Opt(), new Opt(), new Opt());
1365        else if (isExpandableConnector())
1366            return new InstExpandableConnectorDecl(name, className, new Opt(), cd, new Opt(), new Opt(), new Opt());
1367        else if (isPartialFunction())
1368            return new InstPartialFunction(name, className, new Opt(), cd, new Opt(), new Opt(), new Opt());
1369        else
1370            return new InstComposite(name, className, new Opt(), cd, new Opt(), new Opt(), new Opt());
1371    }
1372
1373    public InstComponentDecl InstPrimitiveClassDecl.emptyInstComponentDecl(String name, SrcComponentDecl cd, InstAccess className) {
1374        return new InstPrimitive(name, className, new Opt(), cd, new Opt(), new Opt(), new Opt());
1375    }
1376
1377    public InstComponentDecl InstEnumClassDecl.emptyInstComponentDecl(String name, SrcComponentDecl cd, InstAccess className) {
1378        return new InstEnum(name, className, new Opt(), cd, new Opt(), new Opt(), new Opt());
1379    }
1380
1381    public InstComponentDecl InstBuiltInClassDecl.newInstComponentDeclGeneric(String name, SrcComponentDecl cd, SrcAccess className) {
1382        if (cd.isEnumLiteral()) 
1383            return new InstEnumLiteral(name, className.newInstAccess(), new Opt(), cd, new Opt(), new Opt(), new Opt());   
1384        else 
1385            return new InstBuiltIn(name, className.newInstAccess(), new Opt(), cd, new Opt(), new Opt(), new Opt());
1386    }
1387
1388    public InstComponentDecl InstClassDecl.newInstConstrainingComponentDecl(SrcComponentDecl cd, SrcAccess className) {
1389        InstComponentDecl icd = newInstComponentDecl(cd, className);
1390        icd.setInstConstrainingComponentOpt(new Opt());
1391        return icd;
1392    }
1393
1394    public abstract InstComponentDecl InstClassDecl.newInstReplacingComponent(
1395            SrcComponentDecl replacingDecl, SrcComponentDecl originalDecl, 
1396            InstComponentRedeclare icr, InstComponentRedeclare cicr);
1397
1398    // TODO: Should probably represent different var & type subscripts in instance tree as well
1399    public FArraySubscripts SrcComponentDecl.instantiateArraySubscripts() {
1400        FArrayExpSubscripts fas = null;
1401        if (hasVarArraySubscripts()) {
1402            fas = getVarArraySubscripts().instantiate();
1403        }
1404        if (hasTypeArraySubscripts()) {
1405            FArrayExpSubscripts fas2 = getTypeArraySubscripts().instantiate();
1406            if (fas == null) {
1407                fas = fas2;
1408            } else {
1409                for (FSubscript s : fas2.getFSubscripts()) {
1410                    fas.addFSubscript(s);
1411                }
1412            }
1413        }
1414        return fas;
1415    }
1416
1417    public InstComponentDecl InstBaseClassDecl.newInstReplacingComponent(
1418            SrcComponentDecl replacingDecl, SrcComponentDecl originalDecl, 
1419            InstComponentRedeclare icr, InstComponentRedeclare cicr) {
1420        Opt fas_opt = new Opt();
1421        if (replacingDecl.hasSrcArraySubscripts()) {
1422            fas_opt.setChild(replacingDecl.instantiateArraySubscripts(), 0);
1423        }
1424        Opt cond_attr_opt = new Opt();
1425        if (originalDecl.hasSrcConditionalAttribute()) {
1426            cond_attr_opt.setChild(originalDecl.getSrcConditionalAttribute().getSrcExp().instantiate(), 0);
1427        }
1428        String name = replacingDecl.name();
1429        InstAccess className = replacingDecl.newInstClassAccess();
1430       
1431        InstComponentDecl icd;
1432        if (isPrimitive()) {
1433            icd = new InstReplacingPrimitive(name, className, fas_opt, 
1434                    replacingDecl, new Opt(), new Opt(), cond_attr_opt, originalDecl, icr);
1435        } else if (isRecord()) {
1436            icd = new InstReplacingRecord(name, className, fas_opt, 
1437                    replacingDecl, new Opt(), new Opt(), cond_attr_opt, originalDecl, icr);
1438        } else {
1439            if (isExpandableConnector()) {
1440                icd = new InstReplacingExpandableConnectorDecl(name, className, fas_opt, 
1441                        replacingDecl, new Opt(), new Opt(), cond_attr_opt, originalDecl, icr);
1442            } else {
1443                icd = new InstReplacingComposite(name, className, fas_opt, 
1444                        replacingDecl, new Opt(), new Opt(), cond_attr_opt, originalDecl, icr);
1445            }
1446        }
1447       
1448        SrcComponentDecl constrainingDecl = (cicr == null) ? originalDecl : cicr.getComponentRedeclareDecl();
1449        icd.setInstConstrainingComponentOpt(constrainingDecl.newInstConstrainingComponentOpt(cicr));
1450        icd.setLocation(originalDecl);
1451        return icd;
1452    }
1453
1454    public InstComponentDecl InstLibNode.newInstReplacingComponent(
1455            SrcComponentDecl replacingDecl, SrcComponentDecl originalDecl, 
1456            InstComponentRedeclare icr, InstComponentRedeclare cicr) {
1457        return resolveLib().newInstReplacingComponent(replacingDecl, originalDecl, icr, cicr);
1458    }
1459
1460    // This cannot be done.
1461    public InstComponentDecl InstBuiltInClassDecl.newInstReplacingComponent(
1462            SrcComponentDecl replacingDecl, SrcComponentDecl originalDecl, 
1463            InstComponentRedeclare icr, InstComponentRedeclare cicr) {
1464        throw new UnsupportedOperationException();
1465    }
1466
1467    public InstComponentDecl BadInstClassDecl.newInstReplacingComponent(
1468            SrcComponentDecl replacingDecl, SrcComponentDecl originalDecl, 
1469            InstComponentRedeclare icr, InstComponentRedeclare cicr) {
1470        throw new UnsupportedOperationException();
1471    }
1472
1473    public InstClassDecl SrcClassDecl.newInstClassDecl() {
1474        return new UnknownInstClassDecl();
1475    }
1476   
1477    public Opt<InstExternal> SrcFullClassDecl.newInstExternalOpt() {
1478        return hasSrcExternalClause() ? new Opt(getSrcExternalClause().instantiate()) : new Opt();
1479    }
1480
1481    public InstFullClassDecl SrcFullClassDecl.newInstClassDecl() {
1482        InstFullClassDecl fcd = new InstFullClassDecl(this, new Opt(), newInstRestriction(), newInstExternalOpt());
1483        fcd.setInstConstrainingClassOpt(newInstConstrainingClassOpt(null));
1484        fcd.setLocation(this);
1485        return fcd;
1486    }
1487
1488    public InstExtendClassDecl SrcExtendClassDecl.newInstClassDecl() {
1489        // TODO: Shouldn't extending class decl be able to have an external clause?
1490        InstExtendClassDecl ecd = new InstExtendClassDecl(this, new Opt(), newInstRestriction(), new Opt());
1491        ecd.setInstConstrainingClassOpt(newInstConstrainingClassOpt(null));
1492        ecd.setLocation(this);
1493        return ecd;
1494    }
1495
1496    public InstShortClassDecl SrcShortClassDecl.newInstClassDecl() {
1497        Opt fas_opt = new Opt();
1498        if (getSrcExtendsClauseShortClass().hasSrcArraySubscripts()) {
1499            fas_opt.setChild(getSrcExtendsClauseShortClass().getSrcArraySubscripts().instantiate(),0);
1500        }
1501        InstShortClassDecl scd =  new InstShortClassDecl(this, new Opt(), 
1502                newInstRestriction(),fas_opt);
1503        scd.setInstConstrainingClassOpt(newInstConstrainingClassOpt(null));     
1504        scd.setLocation(this);
1505        return scd;
1506    }
1507
1508    public InstPrimitiveClassDecl SrcPrimitiveClassDecl.newInstClassDecl() {
1509        return new InstPrimitiveClassDecl(this, new Opt(), newInstRestriction(), newInstExternalOpt());
1510    }
1511
1512    public InstBuiltInClassDecl SrcBuiltInClassDecl.newInstClassDecl() {
1513        return new InstBuiltInClassDecl(this);
1514    }
1515
1516    public InstLibNode SrcLibNode.newInstClassDecl() {
1517        return new InstLibNode(this);
1518    }
1519
1520    public InstEnumClassDecl SrcEnumClassDecl.newInstClassDecl() {
1521        InstEnumClassDecl ecd = new InstEnumClassDecl(this, new Opt(), newInstRestriction(), newInstExternalOpt());
1522        ecd.setLocation(this);
1523        return ecd;
1524    }
1525
1526    public BadInstClassDecl SrcBadClassDecl.newInstClassDecl() {
1527        return new BadInstClassDecl(this);
1528    }
1529
1530    public InstClassDecl SrcClassDecl.newInstReplacingClass(
1531            SrcClassDecl replacingClass, InstRedeclareClassNode icr, InstRedeclareClassNode cicr) {
1532        return replacingClass.createInstReplacingClass(this, icr, cicr);
1533    }
1534
1535    public InstClassDecl SrcClassDecl.createInstReplacingClass(
1536            SrcClassDecl replacedClass, InstRedeclareClassNode icr, InstRedeclareClassNode cicr) {
1537        return null;
1538    }
1539
1540    public InstClassDecl SrcFullClassDecl.createInstReplacingClass(
1541            SrcClassDecl replacedClass, InstRedeclareClassNode icr, InstRedeclareClassNode cicr) {
1542        InstRestriction ir = newInstRestriction();
1543        Opt<InstExternal> exto = newInstExternalOpt();
1544        SrcClassDecl constrainingDecl = (cicr == null) ? replacedClass : cicr.redeclaringClassDecl();
1545        InstReplacingFullClassDecl fcd = new InstReplacingFullClassDecl(this, new Opt(), ir, exto, replacedClass, icr);
1546        fcd.setInstConstrainingClassOpt(constrainingDecl.newInstConstrainingClassOpt(cicr));
1547        //TODO: Should be constr clause of original or redeclared?
1548        // - Should be from redeclared if it has one.
1549        fcd.setLocation(this);
1550        return fcd;
1551    }
1552
1553    public InstClassDecl SrcShortClassDecl.createInstReplacingClass(
1554            SrcClassDecl replacedClass, InstRedeclareClassNode icr, InstRedeclareClassNode cicr) {
1555        Opt fas_opt = new Opt();
1556        if (getSrcExtendsClauseShortClass().hasSrcArraySubscripts()) {
1557            fas_opt.setChild(getSrcExtendsClauseShortClass().getSrcArraySubscripts().instantiate(), 0);
1558        }
1559        SrcClassDecl constrainingDecl = (cicr == null) ? replacedClass : cicr.redeclaringClassDecl();
1560        InstRestriction ir = newInstRestriction();
1561        InstReplacingShortClassDecl scd =  new InstReplacingShortClassDecl(this, new Opt(), ir, fas_opt, replacedClass, icr);
1562        scd.setInstConstrainingClassOpt(constrainingDecl.newInstConstrainingClassOpt(cicr));
1563        scd.setLocation(this);
1564        return scd;
1565     }
1566
1567    // Create InstRestriction
1568    public InstRestriction SrcBaseClassDecl.newInstRestriction() {
1569        return getSrcRestriction().newInstRestriction();
1570    }
1571   
1572    public abstract InstRestriction SrcRestriction.newInstRestriction();
1573    public InstModel               SrcModel.newInstRestriction()               { return new InstModel(); }
1574    public InstBlock               SrcBlock.newInstRestriction()               { return new InstBlock(); }
1575    public InstMClass              SrcClass.newInstRestriction()              { return new InstMClass(); }
1576    public InstConnector           SrcConnector.newInstRestriction()           { return new InstConnector(); }
1577    public InstExpandableConnector SrcExpandableConnector.newInstRestriction() { return new InstExpandableConnector(); }
1578    public InstMType               SrcType.newInstRestriction()               { return new InstMType(); }
1579    public InstMPackage            SrcPackage.newInstRestriction()            { return new InstMPackage(); }
1580    public InstFunction            SrcFunction.newInstRestriction()            { return new InstFunction(); }
1581    public InstMRecord             SrcRecord.newInstRestriction()              { return new InstMRecord(); }
1582    public InstOperator            SrcOperator.newInstRestriction()            { return new InstOperator(); }
1583    public InstOperatorFunction    SrcOperatorFunction.newInstRestriction()    { return new InstOperatorFunction(); }
1584    public InstOperatorRecord      SrcOperatorRecord.newInstRestriction()      { return new InstOperatorRecord(); }
1585
1586    /**
1587     * A connector class inheriting a record class is both connector and record,
1588     * this method finds any inherited restriction that should be kept.
1589     */
1590    syn InstRestriction InstRestriction.inheritedRestriction()       = null;
1591    eq InstMRecord.inheritedRestriction()                            = this;
1592    eq InstOperatorRecord.inheritedRestriction()                     = this;
1593    inh lazy InstRestriction InstConnector.inheritedRestriction();
1594    eq InstBaseClassDecl.getInstRestriction().inheritedRestriction() = inheritedRestriction(false);
1595   
1596    /**
1597     * A connector class inheriting a record class is both connector and record,
1598     * this method finds any inherited restriction that should be kept.
1599     */
1600    syn InstRestriction InstClassDecl.inheritedRestriction(boolean checkMine) = null;
1601    eq InstSimpleShortClassDecl.inheritedRestriction(boolean checkMine)       = 
1602        actualInstClass().inheritedRestriction(true);
1603    eq InstLibNode.inheritedRestriction(boolean checkMine)                    = 
1604        actualInstClass().inheritedRestriction(true);
1605    eq InstBaseClassDecl.inheritedRestriction(boolean checkMine) {
1606        if (checkMine)
1607            return getInstRestriction().inheritedRestriction();
1608        for (InstExtends ie : getInstExtendss()) {
1609            InstRestriction ir = ie.myInstClass().inheritedRestriction(true);
1610            if (ir != null)
1611                return ir;
1612        }
1613        return null;
1614    }
1615
1616    // Build an InstExtends
1617    public InstExtends SrcExtendsClause.newInstExtends(InstNode lookup) {
1618        InstNormalExtends ie = newEmptyInstExtends(lookup);
1619        ie.setClassName(getSuper().newInstAccess());
1620        ie.setSrcExtendsClause(this);
1621        if (hasSrcClassModification())
1622            ie.setInstClassModification(getSrcClassModification().newInstModification());
1623        ie.setLocation(this);
1624        return ie;
1625    }
1626
1627    public InstExtends SrcExtendsClause.newInstReplacingExtends(InstExtendsShortClass iesc) {
1628        InstReplacingExtendsShortClass ie = new InstReplacingExtendsShortClass();
1629        ie.setClassName(getSuper().newInstAccess());
1630        ie.setSrcExtendsClause(this);
1631        ie.setInstExtendsShortClass(iesc);
1632        ie.setLocation(this);
1633        return ie;
1634    }
1635
1636    public InstNormalExtends SrcExtendsClause.newEmptyInstExtends(InstNode lookup) {
1637        return new InstNormalExtends();
1638    }
1639
1640    public InstNormalExtends SrcExtendsClauseShortClass.newEmptyInstExtends(InstNode lookup) {
1641        InstExtendsShortClass res = new InstExtendsShortClass();
1642        res.setLookupNode(lookup);
1643        return res;
1644    }
1645
1646    public InstNormalExtends SrcInlineExtendsClause.newEmptyInstExtends(InstNode lookup) {
1647        return new InstInlineExtends();
1648    }
1649
1650    public InstAccess SrcComponentDecl.newInstClassAccess() {
1651        return getClassName().newInstAccess();
1652    }
1653
1654    public abstract InstAccess SrcAccess.newInstAccess();
1655
1656    public InstAccess SrcArrayAccess.newInstAccess() {
1657        InstAccess ia = new InstParseArrayAccess(getID(), getSrcArraySubscripts().instantiate());
1658        ia.setLocation(this);
1659        return ia;
1660    }
1661
1662    public InstAccess SrcNamedAccess.newInstAccess() {
1663        InstAccess ia = new InstParseAccess(getID());
1664        ia.setLocation(this);
1665        return ia;
1666    }
1667
1668    public InstAccess SrcDot.newInstAccess() {
1669        List<InstAccess> l = new List<InstAccess>();
1670        for (SrcAccess a : getSrcAccesss())
1671            l.add(a.newInstAccess());
1672        InstDot ia = new InstDot(l);
1673        ia.setLocation(this);
1674        return ia;
1675    }
1676
1677    public InstAccess SrcGlobalAccess.newInstAccess() {
1678        InstAccess ia = new InstGlobalAccess(getSrcAccess().newInstAccess());
1679        ia.setLocation(this);
1680        return ia;
1681    }
1682
1683    syn boolean InstExtends.hasInstClassModification()           = false;
1684    eq InstReplacingExtendsShortClass.hasInstClassModification() = getInstExtendsShortClass().hasInstClassModification();
1685
1686    syn InstClassModification InstExtends.getInstClassModification() = null;
1687    eq InstReplacingExtendsShortClass.getInstClassModification()     = getInstExtendsShortClass().getInstClassModification();
1688
1689    syn lazy InstProgramRoot Program.getInstProgramRoot() {
1690        return new InstProgramRoot(this, new Opt(), new Opt(), new Opt());
1691    }
1692
1693    syn lazy InstClassDecl InstClassRedeclare.getInstClassDecl() {
1694        return getSrcClassRedeclare().getSrcBaseClassDecl().newInstClassDecl();
1695    }
1696
1697    syn lazy InstComponentDecl InstComponentRedeclare.getInstComponentDecl() =
1698        new InstCreateComponentDecl(getComponentRedeclareDecl(), null);
1699
1700    syn lazy InstComponentDecl InstReplacingRecord.getOriginalInstComponent() =
1701        new InstCreateComponentDecl(getOriginalDecl(), null);
1702
1703    syn lazy InstComponentDecl InstReplacingComposite.getOriginalInstComponent() =
1704        new InstCreateComponentDecl(getOriginalDecl(), null);
1705
1706    syn lazy InstComponentDecl InstReplacingPrimitive.getOriginalInstComponent() =
1707        new InstCreateComponentDecl(getOriginalDecl(), null);
1708
1709
1710    syn lazy InstClassDecl InstReplacingShortClassDecl.getOriginalInstClass() =
1711        getOriginalClassDecl().newInstClassDecl();
1712
1713    syn lazy InstClassDecl InstReplacingSimpleShortClassDecl.getOriginalInstClass() =
1714        getOriginalClassDecl().newInstClassDecl();
1715
1716    syn lazy InstClassDecl InstReplacingFullClassDecl.getOriginalInstClass() =
1717        getOriginalClassDecl().newInstClassDecl();
1718
1719    /**
1720     * Returns the FExp associated with this argument, if any.
1721     */
1722    public FExp InstFunctionArgument.getFExp() { return null; }
1723
1724    /**
1725     * Returns the FExp associated with this argument, if any, without triggering rewrites.
1726     */
1727    public FExp InstFunctionArgument.getFExpNoTransform() { return null; }
1728   
1729    public FExp InstFunctionArgument.getOriginalFExp() { return null; }
1730    public FExp InstGivenArgument.getOriginalFExp()    { return getFExpNoTransform(); }
1731
1732    syn lazy FFunctionCallStmt InstExternalObject.getDestructorCall() {
1733        InstAccess name = getClassName().copyAndAppend("destructor");
1734        List<InstFunctionArgument> args = new List<InstFunctionArgument>();
1735        args.add(new InstPositionalArgument(createAccessExp(), 0));
1736        InstFunctionCall ifc = new InstFunctionCall(name, args);
1737        ifc.generated = true;
1738        FFunctionCallStmt stmt = new FFunctionCallStmt(new List(), ifc);
1739        return stmt;
1740    }
1741
1742
1743    private boolean InstShortClassDecl.simpleRewriteDone = false;
1744
1745    rewrite InstShortClassDecl {
1746        when (!simpleRewriteDone) to InstAbstractShortClassDecl {
1747                simpleRewriteDone = true;
1748                if (shouldBeExpanded())
1749                        return this;
1750                InstSimpleShortClassDecl res = createInstSimpleShortClassDecl();
1751                res.setLocation(this);
1752                return res;
1753        }
1754    }
1755
1756    public InstSimpleShortClassDecl InstShortClassDecl.createInstSimpleShortClassDecl() {
1757        return new InstSimpleShortClassDecl(getSrcClassDecl(), getInstConstrainingClassOpt(), getInstRestriction());
1758    }
1759
1760    public InstReplacingSimpleShortClassDecl InstReplacingShortClassDecl.createInstSimpleShortClassDecl() {
1761        return new InstReplacingSimpleShortClassDecl(getSrcClassDecl(), getInstConstrainingClassOpt(), 
1762               getInstRestriction(), getOriginalClassDecl(), getInstClassRedeclare());
1763    }
1764
1765    syn boolean InstShortClassDecl.shouldBeExpanded() = 
1766        hasFArraySubscripts() || 
1767        hasInstClassModification() || 
1768        getSrcClassDecl().hasSrcTypePrefix() || 
1769        !filteredEnvironment().isEmpty();
1770    eq InstReplacingShortClassDecl.shouldBeExpanded() =
1771        super.shouldBeExpanded() || 
1772        (hasInstConstrainingClass() && getInstConstrainingClass().hasInstClassModification()) || 
1773        (isFunction() && !instModificationsFromConstrainingType().isEmpty());
1774
1775    syn boolean SrcClassDecl.hasSrcTypePrefix() = false;
1776    eq SrcShortClassDecl.hasSrcTypePrefix()     = getSrcExtendsClauseShortClass().hasSrcTypePrefix();
1777
1778    syn boolean SrcExtendsClauseShortClass.hasSrcTypePrefix() = 
1779        hasSrcTypePrefixFlow() || hasSrcTypePrefixVariability() || hasSrcTypePrefixInputOutput();
1780
1781    syn lazy InstAccess InstSimpleShortClassDecl.getTarget() = 
1782        getSrcBaseClassDecl().superClasses().iterator().next().getSuper().newInstAccess();
1783
1784    /**
1785     * If this is a short class declaration we return the RHS class, else this.
1786     */
1787    syn InstClassDecl InstClassDecl.myTargetInstClassDecl();
1788    eq  InstClassDecl              .myTargetInstClassDecl() = this;
1789    eq  InstSimpleShortClassDecl   .myTargetInstClassDecl() = getTarget().myInstClassDecl();
1790    eq  InstShortClassDecl         .myTargetInstClassDecl() = getInstExtends(0).myInstClass();
1791
1792    syn boolean InstRestriction.equals(Object o) = getClass().equals(o.getClass());
1793
1794    syn lazy InstClassDecl InstLibNode.getActualInstClass() {
1795        SrcLibNode ln = (SrcLibNode) getSrcClassDecl();
1796        SrcClassDecl cl = ln.myClass();
1797        if (ln.nameCaseChanged()) {
1798            flushCache();
1799        }
1800        return createInstClassDecl(cl);
1801    }
1802
1803    public List<InstComponentDecl> InstSimpleShortClassDecl.getInstComponentDeclList() {
1804        throw new UnsupportedOperationException();
1805    }
1806    public List<InstComponentDecl> InstLibNode.getInstComponentDeclList() {
1807        throw new UnsupportedOperationException();
1808    }
1809
1810    public List<InstClassDecl> InstSimpleShortClassDecl.getInstClassDeclList() {
1811        throw new UnsupportedOperationException();
1812    }
1813    public List<InstClassDecl> InstLibNode.getInstClassDeclList() {
1814        throw new UnsupportedOperationException();
1815    }
1816
1817    public List<InstExtends> InstSimpleShortClassDecl.getInstExtendsList() {
1818        throw new UnsupportedOperationException();
1819    }
1820    public List<InstExtends> InstLibNode.getInstExtendsList() {
1821        throw new UnsupportedOperationException();
1822    }
1823
1824    public List<InstImport> InstSimpleShortClassDecl.getInstImportList() {
1825        throw new UnsupportedOperationException();
1826    }
1827    public List<InstImport> InstLibNode.getInstImportList() {
1828        throw new UnsupportedOperationException();
1829    }
1830
1831    public List<InstClassDecl> InstSimpleShortClassDecl.getRedeclaredInstClassDeclList() {
1832        throw new UnsupportedOperationException();
1833    }
1834    public List<InstClassDecl> InstLibNode.getRedeclaredInstClassDeclList() {
1835        throw new UnsupportedOperationException();
1836    }
1837
1838}
1839
1840aspect ExpandableConnectorMembers {
1841   
1842    private List<InstComponentDecl> InstExpandableConnectorDecl.expandedMembers          = null;
1843    private List<InstComponentDecl> InstReplacingExpandableConnectorDecl.expandedMembers = null;
1844    private List<InstComponentDecl> InstArrayExpandableConnector.expandedMembers         = null;
1845
1846    private InstComponentDecl[] InstExpandableConnectorDecl.templates          = null;
1847    private InstComponentDecl[] InstReplacingExpandableConnectorDecl.templates = null;
1848    private InstComponentDecl[] InstArrayExpandableConnector.templates         = null;
1849
1850    syn boolean InstExpandableConnectorDecl.useTemplate(int i)          = 
1851        templates != null && getInstComponentDecl(i) != templates[i];
1852    syn boolean InstReplacingExpandableConnectorDecl.useTemplate(int i) = 
1853        templates != null && getInstComponentDecl(i) != templates[i];
1854    syn boolean InstArrayExpandableConnector.useTemplate(int i)         = 
1855        templates != null && getInstComponentDecl(i) != templates[i];
1856
1857    syn InstComponentDecl InstExpandableConnectorDecl.template(int i)          = 
1858        templates[i].arrayTopInstComponentDecl();
1859    syn InstComponentDecl InstReplacingExpandableConnectorDecl.template(int i) = 
1860        templates[i].arrayTopInstComponentDecl();
1861    syn InstComponentDecl InstArrayExpandableConnector.template(int i)         = 
1862        templates[i].arrayTopInstComponentDecl();
1863
1864    eq InstExpandableConnectorDecl.getInstComponentDeclList()          = 
1865        (expandedMembers != null) ? expandedMembers : super.getInstComponentDeclList();
1866    eq InstReplacingExpandableConnectorDecl.getInstComponentDeclList() = 
1867        (expandedMembers != null) ? expandedMembers : super.getInstComponentDeclList();
1868    eq InstArrayExpandableConnector.getInstComponentDeclList()         = 
1869        (expandedMembers != null) ? expandedMembers : super.getInstComponentDeclList();
1870   
1871    eq InstExpandableConnectorDecl.getInstExtendsList()          = 
1872        (expandedMembers != null) ? new List<InstExtends>() : super.getInstExtendsList();
1873    eq InstReplacingExpandableConnectorDecl.getInstExtendsList() = 
1874        (expandedMembers != null) ? new List<InstExtends>() : super.getInstExtendsList();
1875    eq InstArrayExpandableConnector.getInstExtendsList()         = 
1876        (expandedMembers != null) ? new List<InstExtends>() : super.getInstExtendsList();
1877   
1878    public InstComponentDecl InstExpandableConnectorDecl.createInstArrayComponentDecl(int i) {
1879        return new InstArrayExpandableConnector(name(), new InstClassAccess("ArrayDecl"), new Opt(), 
1880                getSrcComponentDecl(), new Opt(), new Opt(), new Opt(), i);
1881    }
1882    public InstComponentDecl InstReplacingExpandableConnectorDecl.createInstArrayComponentDecl(int i) {
1883        return new InstArrayExpandableConnector(name(), new InstClassAccess("ArrayDecl"), new Opt(), 
1884                getSrcComponentDecl(), new Opt(), new Opt(), new Opt(), i);
1885    }
1886    public InstComponentDecl InstArrayExpandableConnector.createInstArrayComponentDecl(int i) {
1887        return new InstArrayExpandableConnector(name(), new InstClassAccess("ArrayDecl"), new Opt(), 
1888                getSrcComponentDecl(), new Opt(), new Opt(), new Opt(), i);
1889    }
1890
1891    inh boolean InstComponentDecl.isExpandableConnectorMember();
1892    eq InstExpandableConnectorDecl.getInstComponentDecl().isExpandableConnectorMember()          = true;
1893    eq InstReplacingExpandableConnectorDecl.getInstComponentDecl().isExpandableConnectorMember() = true;
1894    eq InstArrayExpandableConnector.getInstComponentDecl().isExpandableConnectorMember()         = true;
1895    eq BaseNode.getChild().isExpandableConnectorMember()                                         = false;
1896
1897    inh boolean InstComponentDecl.inExpandableConnector();
1898    eq InstExpandableConnectorDecl.getInstComponentDecl().inExpandableConnector()          = true;
1899    eq InstReplacingExpandableConnectorDecl.getInstComponentDecl().inExpandableConnector() = true;
1900    eq InstArrayExpandableConnector.getInstComponentDecl().inExpandableConnector()         = true;
1901    eq InstClassDecl.getChild().inExpandableConnector()                                    = false;
1902    eq Root.getChild().inExpandableConnector()                                             = false;
1903
1904    inh InstComponentDecl InstComponentDecl.myExpandableConnectorTemplate();
1905    eq InstExpandableConnectorDecl.getInstComponentDecl(int i).myExpandableConnectorTemplate()          = template(i);
1906    eq InstReplacingExpandableConnectorDecl.getInstComponentDecl(int i).myExpandableConnectorTemplate() = template(i);
1907    eq InstArrayExpandableConnector.getInstComponentDecl(int i).myExpandableConnectorTemplate()         = template(i);
1908    eq BaseNode.getChild().myExpandableConnectorTemplate() = null;
1909
1910}
1911
1912aspect InstaceConstrainingClauses {
1913
1914    public Opt SrcComponentDecl.newInstConstrainingComponentOpt(InstComponentRedeclare cicr) {
1915        if (hasSrcConstrainingClause()) {
1916            SrcConstrainingClause cc = getSrcConstrainingClause();
1917            Opt opt = cc.hasSrcClassModification() ? new Opt(cc.getSrcClassModification().newInstModification()) : new Opt();
1918            return new Opt(new InstConstrainingComponent(cc.getSrcAccess().newInstAccess(), opt, this, cicr));
1919        } else {
1920            return new Opt();
1921        }
1922    }
1923
1924    public Opt SrcClassDecl.newInstConstrainingClassOpt(InstRedeclareClassNode cicr) {
1925        return new Opt();
1926    }
1927
1928    public Opt SrcBaseClassDecl.newInstConstrainingClassOpt(InstRedeclareClassNode cicr) {
1929        if (hasSrcConstrainingClause()) {
1930            SrcConstrainingClause cc = getSrcConstrainingClause();
1931            Opt opt = cc.hasSrcClassModification() ? new Opt(cc.getSrcClassModification().newInstModification()) : new Opt();
1932            return new Opt(new InstConstrainingClass(cc.getSrcAccess().newInstAccess(), opt, this, cicr));
1933        } else {
1934            return new Opt();
1935        }
1936    }
1937
1938    syn lazy SrcConstrainingClause InstConstraining.getSrcConstrainingClause();
1939    eq InstConstrainingComponent.getSrcConstrainingClause() = getSrcComponentDecl().getSrcConstrainingClause();
1940    eq InstConstrainingClass.getSrcConstrainingClause() = getSrcBaseClassDecl().getSrcConstrainingClause();
1941
1942    syn lazy InstBaseNode InstConstraining.getInstNode();
1943    eq InstConstrainingComponent.getInstNode() =
1944        getClassName().myInstClassDecl().newInstConstrainingComponentDecl(getSrcComponentDecl(), getSrcConstrainingClause().getSrcAccess());
1945    eq InstConstrainingClass.getInstNode() {
1946        SrcClassDecl classToExpand = getClassName().myInstClassDecl().getSrcClassDecl();
1947        return classToExpand.newInstClassDecl();
1948    }
1949   
1950    syn lazy FExp InstValueModification.getFExp() = getSrcValueModification().instantiateExp();
1951    eq InstArrayModification.getFExp()            = getCell();
1952   
1953    syn FExp SrcValueModification.instantiateExp() = getSrcExp().instantiate();
1954    eq SrcDummyModification.instantiateExp()       = myFExp().treeCopy();
1955
1956    public List InstNode.buildFAbstractEquationList() { 
1957    List l = new List();
1958            for (SrcAbstractEquation e : equations()) {
1959                l.add(e.instantiate());
1960            }
1961            for (SrcAlgorithm a : algorithms()) {
1962                l.add(a.instantiate());
1963            }
1964            for (FAlgorithm a : fAlgorithms()) {
1965                l.add(a.fullCopy());
1966            }
1967            return l;
1968        }
1969
1970    public List InstArrayComponentDecl.buildFAbstractEquationList() {
1971        return instComponentDecl().buildFAbstractEquationList();
1972    }
1973
1974    syn lazy List InstNode.getFAbstractEquationList() = 
1975        buildFAbstractEquationList();
1976    eq InstComponentDecl.getFAbstractEquationList() = 
1977        isArrayParent() ? new List() : buildFAbstractEquationList();
1978
1979    // TODO: Change behaviour of isArrayDecl to this instead?
1980    syn boolean InstComponentDecl.isArrayParent() = 
1981        getNumInstComponentDecl() > 0 && getInstComponentDecl(0).isArrayChild();
1982
1983    syn boolean InstComponentDecl.isArrayChild() = false;
1984    eq InstArrayComponentDecl.isArrayChild()     = true;
1985}
1986
1987aspect InstImportClauses {
1988
1989
1990    syn List InstNode.getInstImportList() {
1991        List l = new List();
1992        for (SrcImportClause ic : imports()) {
1993                InstImport iic = ic.newInstImport();
1994                iic.setLocation(ic);
1995                l.add(iic);
1996        }
1997        return l;
1998    }
1999
2000
2001        public abstract InstImport SrcImportClause.newInstImport(); 
2002        public InstImport SrcImportClauseQualified.newInstImport() {
2003                return new InstImportQualified(getPackageName().newInstAccess(),this);
2004        }
2005        public InstImport SrcImportClauseUnqualified.newInstImport() {
2006                return new InstImportUnqualified(getPackageName().newInstAccess(),this);
2007        }
2008        public InstImport SrcImportClauseRename.newInstImport() {
2009                return new InstImportRename(getPackageName().newInstAccess(),this);
2010        }
2011       
2012
2013} 
2014
2015aspect InstanceAST_API {
2016        syn boolean InstNode.nameScope() = false;
2017        eq InstComponentDecl.nameScope() = true;
2018        eq InstArrayComponentDecl.nameScope() = false;
2019    eq InstBaseClassDecl.nameScope() = true;
2020
2021    syn String InstNode.name()           = "";
2022    eq InstComponentDecl.name()          = getName();
2023    eq InstClassDecl.name()              = getSrcClassDecl().name();
2024    eq InstExtends.name()                = getClassName().name();
2025   
2026    syn String InstGeneratedInner.name() = getCopiedOuter().name();
2027   
2028   /**
2029   * Retrieve fully indexed names for array elements
2030   *
2031   */
2032   
2033    syn String InstNode.getElementName() = name();
2034    eq InstArrayComponentDecl.getElementName() {
2035        if (ndims() != 0 )  {
2036            return getFAccess().scalarName(false, true) + myIndex().partIndex(0, myDimension() + 1).toString();
2037        }
2038        return getFAccess().scalarName(false, true);
2039    }
2040   
2041    syn SrcBaseClassDecl InstBaseClassDecl.getSrcBaseClassDecl() = (SrcBaseClassDecl)getSrcClassDecl();
2042    syn SrcShortClassDecl InstAbstractShortClassDecl.getSrcShortClassDecl() = (SrcShortClassDecl)getSrcClassDecl();
2043    syn SrcFullClassDecl InstFullClassDecl.getSrcFullClassDecl() = (SrcFullClassDecl)getSrcClassDecl();
2044    syn SrcBuiltInClassDecl InstBuiltInClassDecl.getSrcBuiltInClassDecl() = (SrcBuiltInClassDecl)getSrcClassDecl();
2045
2046    syn String InstNode.qualifiedName();
2047    syn lazy String InstClassDecl.qualifiedName();
2048    eq InstComponentDecl.qualifiedName()     = getFAccess().name();
2049    eq InstExtends.qualifiedName()           = myInstClass().qualifiedName();
2050    eq InstInlineExtends.qualifiedName()     = 
2051        surroundingInstClass().myInheritedOrigin().qualifiedName();
2052    eq InstBaseClassDecl.qualifiedName()     = getInstRestriction().qualifiedClassName();
2053    eq InstLibNode.qualifiedName()           = resolveLib().qualifiedName();
2054    eq BadInstClassDecl.qualifiedName()      = buildQualifiedName();
2055    eq InstBuiltInClassDecl.qualifiedName()  = name();
2056    eq InstProgramRoot.qualifiedName()       = "";
2057   
2058    eq InstArrayComponentDecl.qualifiedName(){
2059        if (ndims() != 0 ){
2060            return super.qualifiedName() + 
2061                myIndex().partIndex(0, myDimension() + 1).toString();
2062        }
2063        return super.qualifiedName();
2064    } 
2065
2066    syn String InstRestriction.qualifiedClassName() = myInstClassDecl().buildQualifiedName();
2067    eq InstOperator.qualifiedClassName()            = myInstClassDecl().buildQualifiedOperatorName();
2068    eq InstOperatorFunction.qualifiedClassName()    = myInstClassDecl().buildQualifiedOperatorName();
2069
2070    syn String InstNode.buildQualifiedName() = combineName(instClassNamePrefix(false), name());
2071
2072    syn String InstClassDecl.buildQualifiedOperatorName() = combineName(instClassNamePrefix(true), name());
2073
2074    inh String InstNode.instClassNamePrefix(boolean sup);
2075    eq InstExtends.getChild().instClassNamePrefix(boolean sup)       = sup ? qualifiedName() : instClassNamePrefix(sup);
2076    eq InstBaseClassDecl.getChild().instClassNamePrefix(boolean sup) = qualifiedName();
2077    eq InstLibNode.getChild().instClassNamePrefix(boolean sup)       = instClassNamePrefix(sup);
2078    eq InstComponentDecl.getChild().instClassNamePrefix(boolean sup) = buildQualifiedName();
2079    eq Root.getChild().instClassNamePrefix(boolean sup)              = "";
2080    eq InstRoot.getChild().instClassNamePrefix(boolean sup)          = "";
2081
2082    /**
2083     * Get the qualified class name of the oldest ancestor in the inheritance structure.
2084     *
2085     * For classes inheriting multiple classes, only the first one is considered.
2086     * This is useful mostly for classes that only allows inheriting from one other class.
2087     */
2088    syn String InstNode.baseClassName()                  = 
2089        (getNumInstExtends() > 0) ? getInstExtends(0).baseClassName() : qualifiedName();
2090    eq InstComponentDecl.baseClassName()                 = myInstClass().baseClassName();
2091    eq InstSimpleShortClassDecl.baseClassName()          = actualInstClass().baseClassName();
2092    eq InstLibNode.baseClassName()                       = actualInstClass().baseClassName();
2093
2094
2095        syn Iterable<SrcAbstractEquation> InstNode.equations() = Collections.<SrcAbstractEquation>emptyList();
2096        eq InstComponentDecl.equations()                    = myInstClass().equations();
2097        eq InstExtends.equations()                          = myInstClass().equations();
2098        eq InstFullClassDecl.equations()                    = getSrcBaseClassDecl().equations();       
2099       
2100        syn Iterable<SrcAlgorithm> InstNode.algorithms() = Collections.<SrcAlgorithm>emptyList();
2101        eq InstComponentDecl.algorithms()             = myInstClass().algorithms();
2102        eq InstExtends.algorithms()                   = myInstClass().algorithms();
2103        eq InstFullClassDecl.algorithms()             = getSrcBaseClassDecl().algorithms();     
2104       
2105    syn Iterable<FAlgorithm> InstNode.fAlgorithms() = Collections.<FAlgorithm>emptyList();
2106    eq InstComponentDecl.fAlgorithms()              = myInstClass().fAlgorithms();
2107    eq InstExtends.fAlgorithms()                    = myInstClass().fAlgorithms();
2108    eq InstFullClassDecl.fAlgorithms() {
2109        InstExternal ie = getInstExternal();
2110        if (ie != null) {
2111            ArrayList<FAlgorithm> l = new ArrayList<FAlgorithm>();
2112            l.add(ie.getFAlgorithm());
2113            return l;
2114        } else {
2115            return super.fAlgorithms();
2116        }
2117    }
2118
2119    syn Iterable<SrcComponentDecl> InstNode.components() = Collections.<SrcComponentDecl>emptyList();
2120    eq InstComponentDecl.components()                 = myInstClass().components();
2121    eq InstArrayComponentDecl.components()            = instComponentDecl().components();
2122    eq InstExtends.components()                       = 
2123        extendsPrimitive() ? Collections.<SrcComponentDecl>emptyList() : myInstClass().components();
2124    eq InstBaseClassDecl.components()                 = getSrcBaseClassDecl().components();
2125    eq InstLibNode.components()                       = resolveLib().components();
2126
2127    syn Iterable<SrcExtendsClause> InstNode.superClasses() = Collections.<SrcExtendsClause>emptyList();
2128    eq InstComponentDecl.superClasses()                 = myInstClass().superClasses();
2129    eq InstArrayComponentDecl.superClasses()            = instComponentDecl().superClasses();
2130    eq InstExtends.superClasses()                       = myInstClass().superClasses();
2131    eq InstBaseClassDecl.superClasses()                 = getSrcBaseClassDecl().superClasses();
2132    eq InstLibNode.superClasses()                       = resolveLib().superClasses();
2133
2134    syn Iterable<SrcClassDecl> InstNode.classes() = Collections.<SrcClassDecl>emptyList();
2135    eq InstProgramRoot.classes()               = getProgram().classes();
2136    eq InstComponentDecl.classes()             = myInstClass().classes();
2137    eq InstArrayComponentDecl.classes()        = instComponentDecl().classes();
2138    eq InstBaseClassDecl.classes()             = getSrcBaseClassDecl().classes();
2139    eq InstExtends.classes()                   = myInstClass().classes();
2140    eq InstLibNode.classes()                   = resolveLib().classes();
2141
2142    syn Iterable<SrcImportClause> InstNode.imports() = Collections.<SrcImportClause>emptyList();
2143    eq InstComponentDecl.imports()                = myInstClass().imports();
2144    eq InstBaseClassDecl.imports()                = getSrcBaseClassDecl().imports();
2145    eq InstExtends.imports()                      = myInstClass().imports();
2146    eq InstLibNode.imports()                      = resolveLib().imports();
2147
2148    syn Iterable<SrcModificationOrRedeclareElement> InstNode.elementModifications() = 
2149        Collections.<SrcModificationOrRedeclareElement>emptyList();
2150    eq InstComponentDecl.elementModifications() = myInstClass().elementModifications();
2151    eq InstExtends.elementModifications()       = myInstClass().elementModifications();
2152    eq InstBaseClassDecl.elementModifications() = getSrcClassDecl().elementModifications();
2153    eq InstLibNode.elementModifications()       = getSrcClassDecl().elementModifications();
2154
2155    inh InstEnumClassDecl InstEnumLiteral.myInstEnumClassDecl();
2156    eq InstEnumClassDecl.getInstComponentDecl().myInstEnumClassDecl() = this;
2157    eq InstNode.getChild().myInstEnumClassDecl()                      = null;
2158    eq FlatRoot.getChild().myInstEnumClassDecl()                      = null;
2159
2160    inh int InstEnumLiteral.myIndex();
2161    eq InstEnumClassDecl.getInstComponentDecl(int i).myIndex() = 
2162        enumLiterals().indexOf(getInstComponentDecl(i)) + 1;
2163    eq InstNode.getChild().myIndex()                           = 0;
2164    eq FlatRoot.getChild().myIndex()                           = 0;
2165
2166    syn ArrayList<InstEnumLiteral> InstClassDecl.enumLiterals() =
2167        extendsEnum() ? getInstExtends(0).myInstClass().enumLiterals() : new ArrayList<InstEnumLiteral>();
2168    eq InstSimpleShortClassDecl.enumLiterals()                  = actualInstClass().enumLiterals();
2169    eq InstLibNode.enumLiterals()                               = actualInstClass().enumLiterals();
2170    syn lazy ArrayList<InstEnumLiteral> InstEnumClassDecl.enumLiterals() {
2171        ArrayList<InstEnumLiteral> l = new ArrayList<InstEnumLiteral>();
2172        for (InstComponentDecl icd : getInstComponentDecls()) {
2173            if (icd.isEnumLiteral()) {
2174                l.add((InstEnumLiteral)icd);
2175            }
2176        }
2177        return l;
2178    }
2179
2180
2181    // Overridden in SrcBaseClassDecl by generated API for optional child
2182    syn boolean SrcClassDecl.hasSrcConstrainingClause() = false;
2183    syn SrcConstrainingClause SrcClassDecl.getSrcConstrainingClause() = null;
2184
2185    // Overridden in InstBaseClassDecl by generated API for optional child
2186    syn boolean InstClassDecl.hasInstConstrainingClass() = false;
2187    syn InstConstrainingClass InstClassDecl.getInstConstrainingClass() = null;
2188
2189    syn boolean InstNode.hasInstConstraining() = false;
2190    eq InstBaseClassDecl.hasInstConstraining() = hasInstConstrainingClass();
2191    eq InstComponentDecl.hasInstConstraining() = hasInstConstrainingComponent();
2192
2193    syn InstConstraining InstNode.getInstConstraining() = null;
2194    eq InstBaseClassDecl.getInstConstraining()          = getInstConstrainingClass();
2195    eq InstComponentDecl.getInstConstraining()          = getInstConstrainingComponent();
2196
2197    /**
2198     * Does this constraining clause come from a redeclare?
2199     */
2200    syn boolean InstConstraining.hasInstRedeclare();
2201    eq InstConstrainingComponent.hasInstRedeclare() = getInstRedeclare() != null;
2202    eq InstConstrainingClass.hasInstRedeclare()     = getInstRedeclare() != null;
2203
2204    /**
2205     * get the InstNode for the redeclare that this constraining clause comes from.
2206     *
2207     * Only valid if hasInstRedeclare() returns true.
2208     */
2209    syn InstNode InstConstraining.getRedeclareInstNode();
2210    eq InstConstrainingComponent.getRedeclareInstNode() = getInstRedeclare().getInstComponentDecl();
2211    eq InstConstrainingClass.getRedeclareInstNode()     = getInstRedeclare().redeclaringInstClassDecl();
2212
2213    /**
2214     * Is this declaration redeclared?
2215     */
2216    syn boolean InstNode.isRedeclared()                 = false;
2217    eq InstReplacingFullClassDecl.isRedeclared()        = true;
2218    eq InstReplacingShortClassDecl.isRedeclared()       = true;
2219    eq InstReplacingSimpleShortClassDecl.isRedeclared() = true;
2220    eq InstReplacingComposite.isRedeclared()            = true;
2221    eq InstReplacingRecord.isRedeclared()               = true;
2222    eq InstReplacingPrimitive.isRedeclared()            = true;
2223
2224    /**
2225     * Is this declaration replaceable?
2226     */
2227    syn boolean InstNode.isReplaceable() = false;
2228    eq InstClassDecl.isReplaceable()     = getSrcClassDecl().getReplaceable();
2229    eq InstComponentDecl.isReplaceable() = getSrcComponentDecl().hasReplaceable();
2230
2231    /**
2232     * Is this declaration affected by a constraining type?
2233     */
2234    syn boolean InstNode.isConstrained() = isReplaceable() || isRedeclared();
2235
2236    // Overridden in SrcBaseClassDecl by generated API for optional child
2237    syn boolean SrcClassDecl.getReplaceable() = false;
2238
2239    syn boolean InstNode.extendsPrimitive()        = false;
2240    eq InstShortClassDecl.extendsPrimitive()       = getNumInstExtends() == 1 && getInstExtends(0).extendsPrimitive();
2241    eq InstFullClassDecl.extendsPrimitive()        = getNumInstExtends() == 1 && getInstExtends(0).extendsPrimitive();
2242    eq InstSimpleShortClassDecl.extendsPrimitive() = actualInstClass().isPrimitive();
2243    eq InstLibNode.extendsPrimitive()              = actualInstClass().extendsPrimitive();
2244    eq InstExtends.extendsPrimitive() {
2245        InstClassDecl icd = myInstClass();
2246        return !isRecursive() && icd.isPrimitive();
2247    }
2248
2249    /**
2250     * Check if this node is a class declaration or an extends in one.
2251     */
2252    syn boolean InstNode.isClassDecl() = false;
2253    eq InstClassDecl.isClassDecl()     = true;
2254    eq InstExtends.isClassDecl()       = isInClassDecl();
2255   
2256    /**
2257     * Check if this node is an extends.
2258     */
2259    syn boolean InstNode.isExtends() = false;
2260    eq InstExtends.isExtends()     = true;
2261
2262    /**
2263     * Check if this extends is part of a class declaration.
2264     */
2265    inh boolean InstExtends.isInClassDecl();
2266    eq InstClassDecl.getChild().isInClassDecl() = true;
2267    eq InstBaseNode.getChild().isInClassDecl()  = false;
2268    eq Root.getChild().isInClassDecl()          = false;
2269   
2270    /**
2271     * Check if this node is a component declaration or an extends in one.
2272     */
2273    syn boolean InstNode.isComponentDecl() = false;
2274    eq InstComponentDecl.isComponentDecl() = true;
2275    eq InstExtends.isComponentDecl()       = isInComponentDecl();
2276   
2277    /**
2278     * Check if this extends is part of a component declaration.
2279     */
2280    inh boolean InstExtends.isInComponentDecl();
2281    eq InstComponentDecl.getChild().isInComponentDecl() = true;
2282    eq InstBaseNode.getChild().isInComponentDecl()      = false;
2283    eq Root.getChild().isInComponentDecl()              = false;
2284
2285    /**
2286     * Check if this class is or extends an enumeration.
2287     */
2288    syn boolean InstNode.extendsEnum()        = false;
2289    eq InstClassDecl.extendsEnum()            = getNumInstExtends() == 1 && getInstExtends(0).extendsEnum();
2290    eq InstSimpleShortClassDecl.extendsEnum() = actualInstClass().extendsEnum();
2291    eq InstLibNode.extendsEnum()              = actualInstClass().extendsEnum();
2292    eq InstEnumClassDecl.extendsEnum()        = true;
2293    eq InstExtends.extendsEnum()              = !isRecursive() && myInstClass().extendsEnum();
2294
2295        syn InstClassDecl InstClassDecl.getBaseInstClass() = 
2296                (getNumInstExtends() > 0) ? getInstExtends(0).getBaseInstClass() : this;
2297        syn InstClassDecl InstExtends.getBaseInstClass()   = 
2298                myInstClass().getBaseInstClass();
2299       
2300        inh boolean InstNode.enclosedBy(InstNode node);
2301        eq InstNode.getChild().enclosedBy(InstNode node) = (node == this) || enclosedBy(node);
2302        eq InstRoot.getChild().enclosedBy(InstNode node) = (node == this);
2303    eq Root.getChild().enclosedBy(InstNode node)     = false;
2304   
2305    syn InstNode InstNode.commonAncestor(InstNode node) {
2306        HashSet<InstNode> theirs = new HashSet<InstNode>(node.instAncestors());
2307        for (InstNode mine : instAncestors())
2308            if (theirs.contains(mine))
2309                return mine;
2310        return null;
2311    }
2312   
2313    syn java.util.List<InstNode> InstNode.instAncestors() {
2314        ArrayList<InstNode> list = new ArrayList<InstNode>();
2315        InstNode cur = this;
2316        while (cur != null) {
2317            list.add(cur);
2318            cur = cur.instNodeParent();
2319        }
2320        return list;
2321    }
2322
2323    inh InstNode InstNode.instNodeParent();
2324    eq InstNode.getChild().instNodeParent() = this;
2325    eq Root.getChild().instNodeParent()     = null;
2326   
2327    syn InstNode InstNode.matchingAncestor(InstNode node) {
2328        if (node.isClassDecl()) {
2329            int dims = node.nTypeDims();
2330            for (InstNode mine : instAncestors()) {
2331                if (mine.isThisClass(node)) {
2332                    if (dims == 0 || mine.isClassDecl()) {
2333                        return mine;
2334                    }
2335                    dims = dims - 1;
2336                }
2337            }
2338            return null;
2339        } else {
2340            return commonAncestor(node);
2341        }
2342    }
2343   
2344    syn int InstNode.nTypeDims()      = 0;
2345    eq InstShortClassDecl.nTypeDims() = (hasFArraySubscripts() ? getFArraySubscripts().ndims() : 0) 
2346            + getInstExtends(0).nTypeDims();
2347    eq InstExtends.nTypeDims()        = myInstClass().nTypeDims();
2348   
2349    syn boolean InstNode.isThisClass(InstNode node)                 = this == node;
2350    eq InstComponentDecl.isThisClass(InstNode node)                 = myInstClass().isThisClass(node);
2351    eq InstReplacingShortClassDecl.isThisClass(InstNode node)       = getInstClassRedeclare().isThisClass(node);
2352    eq InstReplacingSimpleShortClassDecl.isThisClass(InstNode node) = actualInstClass().isThisClass(node);
2353   
2354    public interface InstRedeclareClassNode {
2355        public boolean isThisClass(InstNode node);
2356    }
2357   
2358    syn boolean InstClassRedeclare.isThisClass(InstNode node)       = getInstClassDecl().isThisClass(node);
2359   
2360        /**
2361         * Find the component that this access should be evaluated in.
2362         */
2363        inh InstComponentDecl InstAccess.containingInstComponent();
2364        inh InstComponentDecl InstNode.containingInstComponent();
2365        eq InstComponentDecl.getLocalFArraySubscripts().containingInstComponent() = 
2366                containingInstComponent();
2367        eq InstComponentDecl.getFArraySubscripts().containingInstComponent()      = 
2368                containingInstComponent();
2369        eq InstComponentDecl.getChild().containingInstComponent() = this;
2370        eq InstClassDecl.getChild().containingInstComponent()     = null;
2371        eq InstRoot.getChild().containingInstComponent()          = null;
2372        eq Root.getChild().containingInstComponent()              = null;
2373
2374
2375    /**
2376     * Iterate over all components in this node and all InstExtends (recursively).
2377     * Filters out any duplicate components.
2378     *
2379     * @return  an Iterable over the components
2380     */
2381    public Iterable<InstComponentDecl> InstNode.allInstComponentDecls() {
2382        return new FilteredIterable(allInstComponentDeclsWithDuplicates(), NO_DUPLICATE);
2383    }
2384
2385    /**
2386     * Iterate over all components in this node and all InstExtends (recursively).
2387     *
2388     * @return  an Iterable over the components
2389     */
2390    public Iterable<InstComponentDecl> InstRecordConstructor.allInstComponentDecls() {
2391        return new AllInstComponentIterable(this);
2392    }
2393
2394
2395    public static final Criteria<InstComponentDecl> InstNode.NO_DUPLICATE = new Criteria<InstComponentDecl>() {
2396        public boolean test(InstComponentDecl elem) {
2397            return !elem.isDuplicate();
2398        }
2399    };
2400
2401    /**
2402     * Iterate over all components in this node and all InstExtends (recursively).
2403     * Includes any duplicate components.
2404     *
2405     * @return  an Iterable over the components
2406     */
2407    public Iterable<InstComponentDecl> InstNode.allInstComponentDeclsWithDuplicates() {
2408        return new AllInstComponentIterable(this);
2409    }
2410    public Iterable<InstComponentDecl> InstClassDecl.allInstComponentDeclsWithDuplicates() {
2411        return new AllInstComponentIterable(actualInstClass());
2412    }
2413
2414    /**
2415     * Iterate over all classes in this node and all InstExtends (recursively).
2416     *
2417     * @return  an Iterable over the classes
2418     */
2419    public Iterable<InstClassDecl> InstNode.allInstClassDecls() {
2420        return new AllInstClassIterable(this);
2421    }
2422    public Iterable<InstClassDecl> InstClassDecl.allInstClassDecls() {
2423        return new AllInstClassIterable(actualInstClass());
2424    }
2425
2426    protected Iterator<InstComponentDecl> InstNode.allInstComponentDeclsIterator() {
2427        return new AllInstComponentIterator(this);
2428    }
2429    protected Iterator<InstComponentDecl> InstClassDecl.allInstComponentDeclsIterator() {
2430        return new AllInstComponentIterator(actualInstClass());
2431    }
2432
2433    protected Iterator<InstClassDecl> InstNode.allInstClassDeclsIterator() {
2434        return new AllInstClassIterator(this);
2435    }
2436
2437    interface AllInstComponentSource {
2438        public List<InstComponentDecl> getInstComponentDecls();
2439        public List<InstExtends> getInstExtendss();
2440    }
2441    InstNode implements AllInstComponentSource;
2442    InstRecordConstructor implements AllInstComponentSource;
2443
2444    interface AllInstClassSource {
2445        public List<InstClassDecl> getInstClassDecls();
2446        public List<InstExtends> getInstExtendss();
2447    }
2448    InstNode implements AllInstClassSource;
2449
2450    public class ASTNode {
2451
2452        protected static class AllInstComponentIterable implements Iterable<InstComponentDecl> {
2453
2454            private AllInstComponentSource src;
2455
2456            public AllInstComponentIterable(AllInstComponentSource src) {
2457                this.src = src;
2458            }
2459
2460            public Iterator<InstComponentDecl> iterator() {
2461                return new AllInstComponentIterator(src);
2462            }
2463
2464        }
2465
2466        protected static class AllInstClassIterable implements Iterable<InstClassDecl> {
2467
2468            private AllInstClassSource src;
2469
2470            public AllInstClassIterable(AllInstClassSource src) {
2471                this.src = src;
2472            }
2473
2474            public Iterator<InstClassDecl> iterator() {
2475                return new AllInstClassIterator(src);
2476            }
2477
2478        }
2479
2480        protected static class AllInstComponentIterator extends AllInstNodeIterator<InstComponentDecl> {
2481
2482            public AllInstComponentIterator(AllInstComponentSource src) {
2483                super(src.getInstExtendss(), src.getInstComponentDecls());
2484            }
2485
2486            protected Iterator<InstComponentDecl> subIterator(InstExtends ie) {
2487                return ie.allInstComponentDeclsIterator();
2488            }
2489
2490        }
2491
2492        protected static class AllInstClassIterator extends AllInstNodeIterator<InstClassDecl> {
2493
2494            public AllInstClassIterator(AllInstClassSource src) {
2495                super(src.getInstExtendss(), src.getInstClassDecls());
2496            }
2497
2498            protected Iterator<InstClassDecl> subIterator(InstExtends ie) {
2499                return ie.allInstClassDeclsIterator();
2500            }
2501
2502        }
2503
2504        private static abstract class AllInstNodeIterator<T extends InstNode> implements Iterator<T> {
2505
2506            private Iterator<T> current;
2507            private Iterator<InstExtends> exts;
2508            private Iterator<T> last;
2509
2510            public AllInstNodeIterator(List<InstExtends> extList, List<T> lastList) {
2511                exts = extList.iterator();
2512                last = lastList.iterator();
2513                if (exts.hasNext()) {
2514                    current = subIterator(exts.next());
2515                } else {
2516                    current = last;
2517                }
2518                update();
2519            }
2520
2521            protected abstract Iterator<T> subIterator(InstExtends ie);
2522
2523            public boolean hasNext() {
2524                return current.hasNext();
2525            }
2526
2527            public T next() {
2528                T res = current.next();
2529                update();
2530                return res;
2531            }
2532
2533            public void remove() {
2534                throw new UnsupportedOperationException();
2535            }
2536
2537            private void update() {
2538                while (!current.hasNext() && exts.hasNext()) {
2539                    current = subIterator(exts.next());
2540                }
2541                if (!current.hasNext()) {
2542                    current = last;
2543                }
2544            }
2545
2546        }
2547
2548    }
2549
2550    inh InstNode InstNode.containingInstNode();
2551    inh InstNode FExp.containingInstNode();
2552    eq InstNode.getChild().containingInstNode() = this;
2553    eq InstRoot.getChild().containingInstNode() = null;
2554    eq Root.getChild().containingInstNode()     = null;
2555   
2556    inh InstNode FExternalStmt.containingInstClassDecl();
2557    eq Root.getChild().containingInstClassDecl()          = null;
2558    eq InstClassDecl.getChild().containingInstClassDecl() = this;
2559
2560}
2561
2562aspect SourceAST_API {
2563
2564    private static final byte SrcLibNode.UPDATED_NAME_CASE_NOT_DONE  = 0;
2565    private static final byte SrcLibNode.UPDATED_NAME_CASE_CHANGE    = 1;
2566    private static final byte SrcLibNode.UPDATED_NAME_CASE_NO_CHANGE = 2;
2567    private byte SrcLibNode.updatedNameCase = UPDATED_NAME_CASE_NOT_DONE;
2568
2569    syn SrcClassDecl SrcLibNode.myClass() {
2570        SrcClassDecl cl = getSrcStoredDefinition().getSrcClassDecl(0);
2571        if (updatedNameCase == UPDATED_NAME_CASE_NOT_DONE) {
2572            if (!cl.name().equals(name()) && cl.name().equalsIgnoreCase(name())) {
2573                setName(cl.getName().treeCopy());
2574                updatedNameCase = UPDATED_NAME_CASE_CHANGE;
2575            } else {
2576                updatedNameCase = UPDATED_NAME_CASE_NO_CHANGE;
2577            }
2578        }
2579        return cl;
2580    }
2581
2582    syn boolean SrcLibNode.nameCaseChanged() = updatedNameCase == UPDATED_NAME_CASE_CHANGE;
2583
2584    public class ASTNode {
2585        protected static final Criteria<ASTNode> NOT_ERROR_NODE_CRITERIA = new Criteria<ASTNode>() {
2586            public boolean test(ASTNode elem) {
2587                return !elem.isError();
2588            }
2589        };
2590   
2591        public static <N extends ASTNode> Iterable<N> filterErrorNodes(final Iterable<N> parent) {
2592            return new Iterable<N>() {
2593                public Iterator<N> iterator() {
2594                    return new FilteredIterator<N>(parent.iterator(), NOT_ERROR_NODE_CRITERIA);
2595                }
2596            };
2597        }
2598    }
2599
2600}
2601
2602aspect InstArrays {
2603
2604    /**
2605     * Find the number of the dimension corresponding to this InstArrayComponentDecl.
2606     */
2607    inh int InstArrayComponentDecl.myDimension();
2608    eq InstNode.getChild().myDimension()               = 0;
2609    eq InstRecordConstructor.getChild().myDimension()  = 0;
2610    eq InstArrayComponentDecl.getChild().myDimension() = myDimension() + 1;
2611
2612    /**
2613     * Check if this InstArrayComponentDecl is in the bottom dimension of the array.
2614     */
2615    syn boolean InstArrayComponentDecl.isBottomDimension() = isBottomDimHelper(1);
2616
2617    inh boolean InstArrayComponentDecl.isBottomDimHelper(int i);
2618    eq InstNode.getChild().isBottomDimHelper(int i)               = i == ndims();
2619    eq InstRecordConstructor.getChild().isBottomDimHelper(int i)  = i == ndims();
2620    eq InstArrayComponentDecl.getChild().isBottomDimHelper(int i) = isBottomDimHelper(i + 1);
2621
2622    /**
2623     * Efficiently check if this InstArrayComponentDecl is in the top dimension of the array.
2624     */
2625    inh boolean InstArrayComponentDecl.isTopDimension();
2626    eq InstNode.getChild().isTopDimension()               = true;
2627    eq InstRecordConstructor.getChild().isTopDimension()  = true;
2628    eq InstArrayComponentDecl.getChild().isTopDimension() = false;
2629
2630        /**
2631         * Find the length of the dimension corresponding to this InstArrayComponentDecl.
2632         */
2633        syn int InstComponentDecl.myDimensionLength() = size().get(0);
2634        eq InstArrayComponentDecl.myDimensionLength() = dimensionLength(0);
2635
2636    /**
2637     * Find the length of the dimension corresponding to the next level of InstArrayComponentDecls in an array.
2638     *
2639     * For a primitive, the length of the first dimension is returned.
2640     */
2641    syn int InstComponentDecl.childDimensionLength() = size().get(0);
2642    eq InstArrayComponentDecl.childDimensionLength() = dimensionLength(1);
2643
2644        /**
2645         * Find the length of the dimension corresponding to the InstArrayComponentDecl(s)
2646         *        <code>i</code> levels under this one.
2647         */
2648        inh int InstArrayComponentDecl.dimensionLength(int i);
2649        eq InstArrayComponentDecl.getInstComponentDecl().dimensionLength(int i) = dimensionLength(i + 1);
2650        eq InstComponentDecl.getInstComponentDecl().dimensionLength(int i)      = size().get(i);
2651        eq InstRoot.getChild().dimensionLength(int i)                           = Size.UNKNOWN;
2652        eq FlatRoot.getChild().dimensionLength(int i)                           = Size.UNKNOWN;
2653
2654    /**
2655     * Get an Index to my cell.
2656     *
2657     * Only valid for bottom level in array.
2658     */
2659    syn Index InstArrayComponentDecl.myIndex() {
2660        Index i = parentIndex();
2661        i.set(myDimension(), getIndex());
2662        return i;
2663    }
2664
2665    /**
2666     * Calculate Index of parent.
2667     *
2668     * For internal use only - returns an incomplete Index. See {@link #myIndex()}.
2669     */
2670    inh Index InstArrayComponentDecl.parentIndex();
2671    eq InstNode.getChild().parentIndex()               = null;
2672    eq InstRecordConstructor.getChild().parentIndex()  = null;
2673    eq InstComponentDecl.getChild().parentIndex()      = new Index(new int[ndims()]);
2674    eq InstArrayComponentDecl.getChild().parentIndex() = myIndex();
2675   
2676    /**
2677     * Get an Index to my cell for the concatenation of all surrounding array indices.
2678     */
2679    syn Index InstArrayComponentDecl.myTotalIndex() = parentTotalIndex().expand(myIndex());
2680   
2681    /**
2682     * For internal use only - returns an incomplete Index. See {@link #myTotalIndex()}.
2683     */
2684    inh Index InstComponentDecl.parentTotalIndex();
2685    eq InstProgramRoot.getChild().parentTotalIndex()        = Index.NULL;
2686    eq InstComponentDecl.getChild().parentTotalIndex()      = parentTotalIndex();
2687    eq InstArrayComponentDecl.getChild().parentTotalIndex() = isBottomDimension() ? myTotalIndex() : myTotalIndex();
2688
2689    /**
2690     * The top level component for the array.
2691     */
2692    inh InstComponentDecl InstArrayComponentDecl.instComponentDecl();
2693    eq InstArrayComponentDecl.getChild().instComponentDecl() = instComponentDecl();
2694    eq InstComponentDecl.getChild().instComponentDecl()      = this;
2695    eq Root.getChild().instComponentDecl()                   = null;
2696
2697    /**
2698     * If this is an array, get the top level component for the array.
2699     */
2700    syn InstComponentDecl InstComponentDecl.arrayTopInstComponentDecl() = this;
2701    eq InstArrayComponentDecl.arrayTopInstComponentDecl()               = instComponentDecl();
2702
2703        syn boolean InstComponentDecl.isArrayDecl() = hasFArraySubscripts() && 
2704                getFArraySubscripts().ndims()>0;
2705       
2706    syn java.util.List<? extends Subscript> InstNode.myFSubscripts() = Collections.emptyList();
2707    eq InstSimpleShortClassDecl.myFSubscripts()             = actualInstClass().myFSubscripts();
2708    eq InstLibNode.myFSubscripts()                          = actualInstClass().myFSubscripts();
2709    eq InstFullClassDecl.myFSubscripts()                    = 
2710        (getNumInstExtends() == 1) ? getInstExtends(0).myFSubscripts() : super.myFSubscripts();
2711    eq InstExtends.myFSubscripts()                          = 
2712        isRecursive() ? Collections.<FSubscript>emptyList() : myInstClass().myFSubscripts();
2713    syn lazy java.util.List<Subscript> InstShortClassDecl.myFSubscripts() {
2714                java.util.List<Subscript> l = new ArrayList<>();
2715        if (hasFArraySubscripts()) {
2716            for (Subscript s : getFArraySubscripts().subscripts()) {
2717                l.add(s);
2718            }
2719        }
2720        if (getNumInstExtends() == 1) {
2721                        l.addAll(getInstExtends(0).myFSubscripts());
2722        }
2723                return l;
2724        }
2725        syn lazy java.util.List<Subscript> InstComponentDecl.myFSubscripts() {
2726                java.util.List<Subscript> l = new ArrayList<>();
2727                addLocalFArraySubscriptsTo(l);
2728                l.addAll(myInstClass().myFSubscripts());
2729                return l;
2730        }
2731       
2732        public void InstComponentDecl.addLocalFArraySubscriptsTo(java.util.List<Subscript> l) {
2733        if (hasLocalFArraySubscripts()) {
2734            for (Subscript s : getLocalFArraySubscripts().subscripts()) {
2735                l.add(s);
2736            }
2737        } else {
2738            addFSubscriptsFromOriginalDeclTo(l);
2739        }
2740        }
2741       
2742    public void InstComponentDecl.addFSubscriptsFromOriginalDeclTo(java.util.List<Subscript> l) {}
2743    public void InstReplacingComposite.addFSubscriptsFromOriginalDeclTo(java.util.List<Subscript> l) {
2744        getOriginalInstComponent().addLocalFArraySubscriptsTo(l);
2745    }
2746    public void InstReplacingRecord.addFSubscriptsFromOriginalDeclTo(java.util.List<Subscript> l) {
2747        getOriginalInstComponent().addLocalFArraySubscriptsTo(l);
2748    }
2749    public void InstReplacingPrimitive.addFSubscriptsFromOriginalDeclTo(java.util.List<Subscript> l) {
2750        getOriginalInstComponent().addLocalFArraySubscriptsTo(l);
2751    }
2752
2753        /**
2754         * This is the definition of an NTA that collects both the local
2755         * array subscripts given a component declaration and array subscripts
2756         * given on the declaration's class (in the case of short
2757         * class declarations).
2758         */
2759        syn lazy FArraySubscripts InstComponentDecl.getFArraySubscripts() {
2760            if (myFSubscripts().isEmpty())
2761                return null;
2762        List<FSubscript> list = new List<FSubscript>();
2763        for (Subscript s : myFSubscripts()) { 
2764            list.add(s.deferredCopy());
2765        }
2766        return new FArrayExpSubscripts(list);
2767        }
2768       
2769        syn boolean InstComponentDecl.hasFArraySubscripts() = getFArraySubscripts()!=null;
2770       
2771}
2772
2773aspect DeferredSubscripts {
2774
2775    public FSubscript FSubscript.deferredCopy() {
2776        return treeCopy();
2777    }
2778
2779    public FSubscript FExpSubscript.deferredCopy() {
2780        return copyLocationTo(new FDeferExpSubscript(getFExp().treeCopy(), this));
2781    }
2782
2783    public FSubscript IntegerSubscript.deferredCopy() {
2784        return new FIntegerSubscript(value);
2785    }
2786
2787    inh InstLookupResult<InstComponentDecl> FExpSubscript.lookupInstComponent(String name);
2788    eq FDeferExpSubscript.getFExp().lookupInstComponent(String name) = getDefer().lookupInstComponent(name);
2789
2790}
2791
2792aspect InstanceAnnotations {
2793   
2794    syn lazy Opt<InstClassModification> InstClassDecl.getClassAnnotationOpt() = new Opt<InstClassModification>();
2795    syn lazy Opt<InstClassModification> InstComponentDecl.getClassAnnotationOpt() = new Opt<InstClassModification>();
2796    syn lazy Opt<InstClassModification> InstExtends.getClassAnnotationOpt() = new Opt<InstClassModification>();
2797    syn lazy Opt<InstClassModification> InstExtends.getClassAnnotationExtendsOpt() = new Opt<InstClassModification>();
2798   
2799    syn lazy Opt<InstClassModification> InstComponentDecl.getAnnotationOpt() = new Opt<InstClassModification>();
2800   
2801    syn lazy Opt<InstClassModification> InstElementModification.getAnnotationOpt() = new Opt<InstClassModification>();
2802}
2803
2804aspect InstanceToString {
2805
2806
2807    public String InstClassDecl.toString() {
2808        return getSrcClassDecl().toString();
2809    }
2810   
2811    public String InstExternal.toString() {
2812        return getSrcExternalClause().toString();
2813    }
2814   
2815    public String InstComponentDecl.toString() {
2816        return getSrcComponentDecl().myComponentClause().toString();
2817    }
2818
2819    public String InstEnumLiteral.toString() {
2820        return prettyPrint("");
2821    }
2822   
2823    public String InstExtends.toString() {
2824        return getSrcExtendsClause().toString();
2825    }
2826
2827    public String InstModification.toString() {
2828        return getSrcModification().toString();
2829    }
2830
2831}
2832
2833
2834aspect InheritedFrom {
2835
2836    /**
2837     * If this class was inherited into this scope, return the corresponding class
2838     * from the inherited class.
2839     *
2840     * The inhetitance can be either direct or through a surronding class that was
2841     * inherited in. This method only follows a single extends.
2842     *
2843     * If no surrounding extends exists or any lookup fails, <code>this</code> is returned.
2844     */
2845    syn InstClassDecl InstClassDecl.myInheritedOrigin() {
2846        InstClassDecl res = inheritedOriginHelper(name());
2847        return res.isUnknown() ? this : res;
2848    }
2849
2850    inh InstClassDecl InstClassDecl.inheritedOriginHelper(String name);
2851    eq InstExtends  .getInstClassDecl().inheritedOriginHelper(String name) = 
2852        myInstClass().memberInstClass(name).target(INST_UNKNOWN_CLASS, this);
2853    eq InstClassDecl.getInstClassDecl().inheritedOriginHelper(String name) = 
2854        inheritedOriginHelper(name()).memberInstClass(name).target(INST_UNKNOWN_CLASS, this);
2855    eq InstNode     .getChild()        .inheritedOriginHelper(String name) = 
2856        unknownInstClassDecl();
2857}
2858
2859
2860/* TODO: If we are doing this, we should do it properly
2861aspect InstancePrettyPrint {
2862
2863        public String InstNode.prettyPrint(String indent) {
2864                String str = getClass().getName();
2865                str = indent + str.substring(str.lastIndexOf('.')+1);
2866                return str;
2867
2868        }
2869
2870        public String InstBaseClassDecl.prettyPrint(String indent) {
2871                String str = getClass().getName();
2872                str = indent+str.substring(str.lastIndexOf('.')+1);
2873                str+= ": " + name();
2874                return str;
2875
2876        }
2877
2878        public String InstShortClassDecl.prettyPrint(String indent) {
2879                String str = getClass().getName();
2880                str = indent+str.substring(str.lastIndexOf('.')+1);
2881                str+= ": " + getInstExtends(0).getClassName().name() + " "+ name();
2882                return str;
2883        }
2884
2885        public String InstExtendsShortClass.prettyPrint(String indent) {
2886                String str = getClass().getName();
2887                str = indent+str.substring(str.lastIndexOf('.')+1);
2888                str+= ": " + getClassName().name();
2889                return str;
2890               
2891        }
2892
2893        public String InstExtends.prettyPrint(String indent) {
2894                String str = getClass().getName();
2895                str = indent+str.substring(str.lastIndexOf('.')+1);
2896                str+= ": " + getClassName().name();
2897                return str;
2898               
2899        }
2900
2901        public String InstComponentDecl.prettyPrint(String indent) {
2902                String str = getClass().getName();
2903                str = indent+str.substring(str.lastIndexOf('.')+1);
2904                str+= ": " + getClassName().name() + " "+
2905                                      name();
2906                return str;
2907
2908        }
2909
2910        public String InstArrayComponentDecl.prettyPrint(String indent) {
2911                String str = getClass().getName();
2912                str = indent+str.substring(str.lastIndexOf('.')+1);
2913                str+= ": " + getIndex();
2914                return str;
2915
2916        }
2917       
2918        public String InstImport.prettyPrint(String indent) {
2919                String str = getClass().getName();
2920                str = indent+str.substring(str.lastIndexOf('.')+1);
2921                str += ": " + getPackageName().name();
2922                return str;
2923        }
2924
2925        public String InstAccess.prettyPrint(String indent) {
2926                String str = getClass().getName();
2927                str = indent+str.substring(str.lastIndexOf('.')+1);
2928                str += ": " + name();
2929                return str;
2930        }
2931
2932       
2933}
2934*/
Note: See TracBrowser for help on using the repository browser.