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

Last change on this file since 13621 was 13621, checked in by molsson, 3 months ago

#5850 Recommitting InstLibNodes changes from r13614.

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