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

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

Merge from trunk

File size: 40.7 KB
Line 
1/*
2    Copyright (C) 2009 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 org.jmodelica.util.collections.IntIterator;
18
19aspect InstLookupComponents {
20   
21    class InstComponentDecl implements InstLookupResult.Item {}
22    class InstClassDecl     implements InstLookupResult.Item {}
23    interface InstCallable  extends    InstLookupResult.Item {}
24
25    /**
26     * Result class for lookups in the instance tree.
27     *
28     * Use the static fields and methods to generate results.
29     */
30    public abstract class InstLookupResult<T extends InstLookupResult.Item> {
31
32        public interface Item {
33            public InstLookupResult<InstComponentDecl> memberInstComponent(String name);
34            public InstCallable asCallable();
35        }
36       
37        /**
38         * Indicates that the target was not found.
39         */
40        public static <T extends Item> InstLookupResult<T> notFound() {
41            return (InstLookupResult<T>) NOT_FOUND;
42        }
43
44        /**
45         * Indicates that the target was found.
46         *
47         * Includes the found class or component.
48         */
49        public static <T extends Item> InstLookupResult<T> found(T target) {
50            return new Found(target);
51        }
52
53        /**
54         * Indicates that the target was found, but not accessible due to a constrainedby clause.
55         *
56         * Includes the declaration with the limiting constrainedby clause.
57         */
58        public static <T extends Item> InstLookupResult<T> constrained(T target, InstNode constr) {
59            return new Constrained(target, constr);
60        }
61
62        /**
63         * Indicates that the target was found, but not accessible due to a constrainedby clause.
64         *
65         * Includes the declaration with the limiting constrainedby clause.
66         */
67        public static <T extends Item> InstLookupResult<T> constrained(InstLookupResult<T> res, InstNode constr) {
68            return new Constrained(res.target(), constr);
69        }
70       
71        /**
72         * Indicates that the target was found as an outer, target() returns the corresponding inner.
73         */
74        public static InstLookupResult<InstComponentDecl> outer(InstComponentDecl outer) {
75            return new Outer(outer);
76        }
77
78        /**
79         * Did the lookup succeed?
80         */
81        public boolean successful() {
82            return false;
83        }
84
85        /**
86         * Is this a "not found" result?
87         */
88        public boolean isNotFound() {
89            return false;
90        }
91
92        /**
93         * Is this a result that should generate an error?
94         */
95        public boolean isError() { return false; }
96       
97        /**
98         * Is this a result that should generate an error or warning?
99         */
100        public boolean isProblem() { return false; }
101
102        /**
103         * Get the found class or component, if any.
104         *
105         * Returns <code>null</code> if lookup was not successful.
106         */
107        public T targetOrNull() {
108            return null;
109        }
110       
111        /**
112         * Returns the outer for outer lookup results, this for rest.
113         */
114        public InstLookupResult<T> unresolved() {
115            return this;
116        }
117       
118        /**
119         * @param target The new target
120         * @return a copy of this InstLookupResult with a new target.
121         */
122        public abstract <NT extends Item> InstLookupResult<NT> create(NT target);
123       
124        /**
125         * @param name Name of target subcomponent
126         * @return <code>this</code> if <code>this</code> is an error, else lookup
127         *         result of member <code>name</code> in <code>target()</code>
128         */
129        public abstract InstLookupResult<InstComponentDecl> memberInstComponent(String name);
130       
131        /**
132         * Get the found class or component, if any.
133         *
134         * @throws UnsupportedOperationException  if lookup was not successful.
135         */
136        public T target() {
137            throw new UnsupportedOperationException("Trying to use result of failed name lookup");
138        }
139
140        /**
141         * Get the found class or component, or a default value.
142         *
143         * Returns <code>gen.generate(src)</code> if lookup was not successful.
144         */
145        public T target(DefaultGenerator<T> gen, ASTNode src) {
146            return successful() ? target() : gen.generate(src);
147        }
148
149        /**
150         * Generate warnings and errors for unsuccessful lookup result.
151         *
152         * @param src   node to generate problem on
153         * @param kind  how to describe the declaration being sought, e.g. "component"
154         * @param name  the name being sought
155         */
156        public boolean problem(ASTNode src, String kind, String name) {
157            return false;
158        }
159
160        /**
161         * Generates a default value for {@link #target(DefaultGenerator, ASTNode)}.
162         */
163        public static interface DefaultGenerator<T extends Item> {
164            public T generate(ASTNode src);
165        }
166
167        private final static InstLookupResult NOT_FOUND = new NotFound(); 
168
169        private static class NotFound<T extends Item> extends InstLookupResult<T> {
170           
171            public <NT extends Item> InstLookupResult<NT> create(NT target) {
172                return notFound();
173            }
174           
175            public boolean isNotFound() {
176                return true;
177            }
178           
179            @Override
180            public boolean isError() { return true; }
181           
182            @Override
183            public boolean isProblem() { return true; }
184           
185            @Override
186            public boolean problem(ASTNode src, String kind, String name) {
187                src.error("Cannot find %s declaration for %s", kind, name);
188                return true;
189            }
190           
191            public InstLookupResult<InstComponentDecl> memberInstComponent(String name) {
192                return (InstLookupResult<InstComponentDecl>) this;
193            }
194        }
195
196        private static class Found<T extends Item> extends InstLookupResult<T> {
197            private T target;
198
199            public <NT extends Item> InstLookupResult<NT> create(NT target) {
200                return new Found(target);
201            }
202           
203            public Found(T target) {
204                this.target = target;
205            }
206
207            public boolean successful() {
208                return true;
209            }
210
211            public T target() {
212                return target;
213            }
214
215            public T targetOrNull() {
216                return target;
217            }
218           
219            public InstLookupResult<InstComponentDecl> memberInstComponent(String name) {
220                return target().memberInstComponent(name);
221            }
222        }
223
224        private static class Constrained<T extends Item> extends Found<T> {
225            private InstNode constr;
226
227            public <NT extends Item> InstLookupResult<NT> create(NT target) {
228                return new Constrained(target, constr);
229            }
230           
231            public Constrained(T target, InstNode constr) {
232                super(target);
233                this.constr = constr;
234            }
235           
236            @Override
237            public boolean isError() { return true; }
238           
239            @Override
240            public boolean isProblem() { return true; }
241           
242            @Override
243            public boolean problem(ASTNode src, String kind, String name) {
244                ASTNode.NOT_IN_CONSTRAINING_TYPE.invoke(src, kind, name, constr);
245                return false;
246            }
247           
248        }
249       
250        private static class Outer extends Found<InstComponentDecl> {
251           
252            private InstLookupResult<InstComponentDecl> outer;
253           
254            public InstLookupResult<InstComponentDecl> create(InstComponentDecl target) {
255                return new Outer(target);
256            }
257           
258            public Outer(InstComponentDecl target) {
259                super(target);
260                this.outer = InstLookupResult.found(target);
261            }
262           
263            public InstComponentDecl target() {
264                InstComponentDecl inner = outer.target().myInnerInstComponentDecl();
265                if (inner == null) {
266                    return outer.target().unknownInstComponentDecl();
267                }
268                return inner;
269            }
270
271            public InstComponentDecl targetOrNull() {
272                return target();
273            }
274           
275            public InstLookupResult<InstComponentDecl> unresolved() {
276                return outer;
277            }
278           
279            public InstLookupResult<InstComponentDecl> memberInstComponent(String name) {
280                InstLookupResult<InstComponentDecl> res = super.memberInstComponent(name);
281                if (!res.isError() && !outer.target().memberInstComponent(name).successful())
282                    return new OuterError(res.target());
283                return res;
284            }
285           
286            private class OuterError extends Found<InstComponentDecl> {
287               
288                public InstLookupResult<InstComponentDecl> create(InstComponentDecl target) {
289                    return new OuterError(target);
290                }
291               
292                public OuterError(InstComponentDecl target) {
293                    super(target);
294                }
295               
296                @Override
297                public boolean isError() { return true; }
298               
299                @Override
300                public boolean isProblem() { return true; }
301               
302                @Override
303                public boolean problem(ASTNode src, String kind, String name) {
304                    src.error("Cannot use %s %s in inner '%s', because it is not present in outer '%s'", kind, name, Outer.this.target(), outer.target());
305                    return true;
306                }
307            }
308        }
309    }
310
311    protected static final InstLookupResult.DefaultGenerator<InstComponentDecl> ASTNode.INST_UNKNOWN_COMPONENT = 
312            new InstLookupResult.DefaultGenerator<InstComponentDecl>() {
313        public InstComponentDecl generate(ASTNode src) {
314            return src.unknownInstComponentDecl();
315        }
316    };
317
318    inh InstLookupResult<InstComponentDecl> InstAccess.lookupInstComponent(String name);
319    inh InstLookupResult<InstComponentDecl> InstConstraining.lookupInstComponent(String name);
320    inh lazy InstLookupResult<InstComponentDecl> InstNode.lookupInstComponent(String name);
321    inh lazy InstLookupResult<InstComponentDecl> InstModification.lookupInstComponent(String name);
322    eq InstNode.getChild().lookupInstComponent(String name)   = genericLookupInstComponent(name);
323    eq InstRoot.getChild().lookupInstComponent(String name)   = InstLookupResult.notFound();
324    eq InstImport.getChild().lookupInstComponent(String name) = InstLookupResult.notFound();
325
326    eq InstComponentDecl.getInstModification().lookupInstComponent(String name)          = lookupInstComponent(name);
327    eq InstComponentDecl.getInstConstrainingComponent().lookupInstComponent(String name) = lookupInstComponent(name);
328    eq InstComponentDecl.getConditionalAttribute().lookupInstComponent(String name)      = lookupInstComponent(name);
329    eq InstComponentDecl.getFArraySubscripts().lookupInstComponent(String name)          = lookupInstComponent(name);
330    eq InstComponentDecl.getLocalFArraySubscripts().lookupInstComponent(String name)     = lookupInstComponent(name);
331
332    eq InstExpandableConnectorDecl.getInstComponentDecl(int i).lookupInstComponent(String name)          = 
333        useTemplate(i) ? template(i).lookupInstComponent(name) : genericLookupInstComponent(name);
334    eq InstArrayExpandableConnector.getInstComponentDecl(int i).lookupInstComponent(String name)         = 
335        useTemplate(i) ? template(i).lookupInstComponent(name) : genericLookupInstComponent(name);
336    eq InstReplacingExpandableConnectorDecl.getInstComponentDecl(int i).lookupInstComponent(String name) = 
337        useTemplate(i) ? template(i).lookupInstComponent(name) : genericLookupInstComponent(name);
338
339    eq InstReplacingRecord.getOriginalInstComponent().lookupInstComponent(String name)    = lookupInstComponent(name);
340    eq InstReplacingComposite.getOriginalInstComponent().lookupInstComponent(String name) = lookupInstComponent(name);
341    eq InstReplacingPrimitive.getOriginalInstComponent().lookupInstComponent(String name) = lookupInstComponent(name);
342    eq InstNormalExtends.getInstClassModification().lookupInstComponent(String name)      = lookupInstComponent(name);
343    eq InstExtendsShortClass.getInstClassModification().lookupInstComponent(String name)  = getLookupNode().lookupInstComponent(name);
344    eq InstShortClassDecl.getChild().lookupInstComponent(String name)                     = lookupInstComponent(name);
345    eq InstSimpleShortClassDecl.getChild().lookupInstComponent(String name)               = lookupInstComponent(name);
346    eq InstLibNode.getChild().lookupInstComponent(String name)                            = lookupInstComponent(name);
347    eq InstExternalObject.getDestructorCall().lookupInstComponent(String name)            = lookupInstComponent(name);
348    eq InstConstrainingComponent.getChild().lookupInstComponent(String name)              = 
349        (getInstRedeclare() != null) ? getInstRedeclare().lookupInstComponent(name) : lookupInstComponent(name);
350    eq InstConstrainingClass.getChild().lookupInstComponent(String name)                  = 
351        (getInstRedeclare() != null) ? getInstRedeclare().lookupInstComponent(name) : lookupInstComponent(name);
352
353    eq InstDot.getInstAccess(int i).lookupInstComponent(String name)             = 
354        (i == 0) ? lookupInstComponent(name) : getInstAccessNoListTrans(i - 1).qualifiedLookupInstComponent(name);
355    eq InstScalarAccess.getExpandedSubscripts().lookupInstComponent(String name) = getTopInstAccess().lookupInstComponent(name);
356    eq InstArrayAccess.getFArraySubscripts().lookupInstComponent(String name)    = getTopInstAccess().lookupInstComponent(name);
357    eq InstGlobalAccess.getInstAccess().lookupInstComponent(String name)         = InstLookupResult.notFound();
358   
359   
360    syn InstLookupResult<InstComponentDecl> InstAccess.qualifiedLookupInstComponent(String name) {
361        InstLookupResult<InstComponentDecl> res = qualifiedLookupInstComponentUnconstrained(name);
362        if (res.successful()) { // TODO: limit to only replaceable and replaced components and their children?
363            InstNode constr = lookupConstrainingInstNode();
364            if (constr != null && !constr.memberInstComponent(name).successful())
365                return InstLookupResult.<InstComponentDecl>constrained(res, closestConstrainingDecl());
366        }
367        return res;
368    }
369
370    syn InstLookupResult<InstComponentDecl> InstAccess.qualifiedLookupInstComponentUnconstrained(String name) = 
371        InstLookupResult.notFound();
372    eq InstClassAccess.qualifiedLookupInstComponentUnconstrained(String name)                                 = 
373        myInstClassDecl().memberInstComponent(name);
374    eq InstComponentAccess.qualifiedLookupInstComponentUnconstrained(String name)                             = 
375        lookupArrayElement(myInstLookup()).memberInstComponent(name);
376    eq InstComponentArrayAccess.qualifiedLookupInstComponentUnconstrained(String name)                        = 
377        lookupArrayElement(myInstLookup()).memberInstComponent(name);
378
379    syn InstNode InstAccess.lookupConstrainingInstNode()     = null;
380    eq InstComponentAccess.lookupConstrainingInstNode()      = 
381        lookupArrayElement(inQualified() ? lookupConstrainingInstComponent(name()) : lookupConstrainingInstComponentHelper(null, name()));
382    eq InstComponentArrayAccess.lookupConstrainingInstNode() = 
383        lookupArrayElement(inQualified() ? lookupConstrainingInstComponent(name()) : lookupConstrainingInstComponentHelper(null, name()));
384
385    inh InstComponentDecl InstAccess.lookupConstrainingInstComponent(String name);
386    eq BaseNode.getChild().lookupConstrainingInstComponent(String name)          = null;
387    eq InstDot.getInstAccess(int i).lookupConstrainingInstComponent(String name) =
388        lookupConstrainingInstComponentHelper((i == 0) ? null : getInstAccessNoListTrans(i - 1), name);
389
390    syn InstComponentDecl InstAccess.lookupConstrainingInstComponentHelper(InstAccess part, String name) {
391        InstLookupResult<InstComponentDecl> res;
392        if (part == null) {
393            res = lookupInstComponent(name);
394        } else {
395            InstNode parent = part.lookupConstrainingInstNode();
396            res = (parent != null) ? parent.memberInstComponent(name) : InstLookupResult.<InstComponentDecl>notFound();
397        }
398        if (!res.successful())
399            return null;
400        InstComponentDecl icd = res.target();
401        if (!icd.isReplaceable())
402            return icd;
403        return icd.constrainingInstComponentDecl();
404    }
405
406    syn InstNode InstAccess.closestConstrainingDecl()     = null;
407    eq InstClassAccess.closestConstrainingDecl()          = 
408        myInstClassDecl().isConstrained() ? myInstClassDecl().myConstrainingDecl() : findClosestConstrainingInstNode();
409    eq InstComponentAccess.closestConstrainingDecl()      = 
410        myInstComponentDecl().isConstrained() ? myInstComponentDecl().myConstrainingDecl() : findClosestConstrainingInstNode();
411    eq InstComponentArrayAccess.closestConstrainingDecl() = 
412        myInstComponentDecl().isConstrained() ? myInstComponentDecl().myConstrainingDecl() : findClosestConstrainingInstNode();
413
414    inh InstNode InstAccess.findClosestConstrainingInstNode();
415    eq InstDot.getInstAccess(int i).findClosestConstrainingInstNode() = 
416        (i == 0) ? null : getInstAccessNoListTrans(i - 1).closestConstrainingDecl();
417    eq BaseNode.getChild().findClosestConstrainingInstNode()          = null;
418
419    syn InstNode InstNode.myConstrainingDecl() {
420        if (hasInstConstraining() && getInstConstraining().hasInstRedeclare()) {
421            return getInstConstraining().getRedeclareInstNode();
422        } else {
423            return myDefaultConstrainingDecl();
424        }
425    }
426    eq InstLibNode.myConstrainingDecl() = resolveLib().myConstrainingDecl();
427
428    syn InstNode InstNode.myDefaultConstrainingDecl()                = this;
429    eq InstReplacingFullClassDecl.myDefaultConstrainingDecl()        = getOriginalInstClass();
430    eq InstReplacingShortClassDecl.myDefaultConstrainingDecl()       = getOriginalInstClass();
431    eq InstReplacingSimpleShortClassDecl.myDefaultConstrainingDecl() = getOriginalInstClass();
432    eq InstReplacingComposite.myDefaultConstrainingDecl()            = getOriginalInstComponent();
433    eq InstReplacingRecord.myDefaultConstrainingDecl()               = getOriginalInstComponent();
434    eq InstReplacingPrimitive.myDefaultConstrainingDecl()            = getOriginalInstComponent();
435
436
437    inh InstLookupResult<InstComponentDecl> InstAccess.localLookupInstComponent(String name);
438    eq InstRoot.getChild().localLookupInstComponent(String name)          = InstLookupResult.notFound();
439    eq FlatRoot.getChild().localLookupInstComponent(String name)          = InstLookupResult.notFound();
440    eq InstClassDecl.getChild().localLookupInstComponent(String name)     = memberInstComponent(name);
441    eq InstComponentDecl.getChild().localLookupInstComponent(String name) = memberInstComponent(name);
442
443    syn InstLookupResult<InstComponentDecl> InstValueModification.lookupInstComponentForBindingExp(String name) = lookupInstComponent(name);
444   
445    /**
446     * Get a specific child access, triggering transformations on that child, but *not* on the entire list.
447     */
448    syn InstAccess InstDot.getInstAccessNoListTrans(int i) = getInstAccessListNoTransform().getChild(i);
449
450    /**
451     * Lookup the specific array component corresponding to this access, using current ceval()
452     * value for indices. If no specific component can be found or this access is not to a specific
453     * element, the component for the array is returned.
454     *
455     * @param array  the component node for the array
456     */
457    public InstComponentDecl InstAccess.lookupArrayElement(InstComponentDecl array) {
458        return array;
459    }
460
461    public InstComponentDecl InstArrayAccess.lookupArrayElement(InstComponentDecl array) {
462        if (!isArray() && array != null) {
463            // If we can, try to get the correct InstArrayComponentDecl to do lookup from
464            try {
465                Index i = getFArraySubscripts().createIndex();
466                InstComponentDecl icd = array;
467                for (int dim = 0; dim < i.ndims(); dim++) {
468                    int j = i.get(dim) - 1;
469                    if (j < 0 || j >= icd.getNumInstComponentDecl()) {
470                        return array;
471                    } else {
472                        icd = icd.getInstComponentDecl(j);
473                        if (!(icd instanceof InstArrayComponentDecl))
474                            return array;
475                    }
476                }
477                return icd;
478            } catch (ConstantEvaluationException e) {
479            }
480        }
481        return array;
482    }
483   
484    public InstLookupResult<InstComponentDecl> InstAccess.lookupArrayElement(InstLookupResult<InstComponentDecl> array) {
485        if (array.isError()) {
486            return array;
487        }
488       
489        InstComponentDecl icd = lookupArrayElement(array.target());
490        if (icd == array.target()) {
491            return array;
492        }
493        return array.create(icd);
494    }
495
496    /**
497     * Lookup component, selecting array indices based on i, where i covers this access.
498     */
499    syn InstComponentDecl InstAccess.lookupWithIndex(Index i) = lookupWithIndexImpl(i, null);
500
501    /**
502     * Lookup component, selecting array indices based on i, where i covers an InstDot that
503     * this access is part of.
504     */
505    inh InstComponentDecl InstAccess.lookupAsPartWithIndex(Index i);
506    eq InstDot .getInstAccess(int j).lookupAsPartWithIndex(Index i) = 
507        lookupWithIndexImpl(i, (j < getNumInstAccess() - 1) ? getInstAccess(j + 1) : null);
508    eq BaseNode.getChild()          .lookupAsPartWithIndex(Index i) = 
509        unknownInstComponentDecl();
510
511    protected InstComponentDecl InstAccess.lookupWithIndexImpl(Index i, InstAccess stopAt) {
512        InstAccess first = getFirstInstAccess();
513        InstAccess cur = first;
514        InstComponentDecl icd = cur.myInstComponentDecl();
515        IntIterator index = i.iterator();
516       
517        while (cur != stopAt && icd != null && !icd.isUnknown()) {
518            if (cur == first) {
519                icd = icd.arrayCell(index);
520            } else {
521                icd = icd.memberArrayCell(cur.name(), index);
522            }
523            cur = cur.getNextInstAccess();
524        }
525       
526        return (icd == null) ? unknownInstComponentDecl() : icd;
527    }
528
529    syn InstComponentDecl InstComponentDecl.memberArrayCell(String name, IntIterator index) {
530        InstComponentDecl res = memberInstComponent(name).targetOrNull();
531        if (res != null) {
532            res = res.arrayCell(index);
533        }
534        return res;
535    }
536
537    syn InstComponentDecl InstComponentDecl.arrayCell(Index index) = arrayCell(index.iterator());
538
539    syn InstComponentDecl InstComponentDecl.arrayCell(IntIterator index) {
540        if (index.hasNext() && isArray() && !isPrimitive()) {
541            return getInstComponentDecl(index.next() - 1).arrayCell(index);
542        } else {
543            return this;
544        }
545    }
546
547    /**
548     * Lookup component, re-evaluating any array indexes except in last component.
549     */
550    public InstComponentDecl InstAccess.lookupEvaluatingIndices() {
551        InstAccess cur = getFirstInstAccess();
552        InstComponentDecl icd = cur.myInstComponentDecl();
553       
554        InstAccess next = cur.getNextInstAccess();
555        while (next != null && icd != null && !icd.isUnknown()) {
556            icd = cur.lookupArrayElement(icd);
557            icd = icd.memberInstComponent(next.name()).targetOrNull();
558            cur = next;
559            next = next.getNextInstAccess();
560        }
561        icd = cur.lookupArrayElement(icd);
562       
563        return (icd == null) ? unknownInstComponentDecl() : icd;
564    }
565
566    inh InstLookupResult<InstComponentDecl> FIterExp.lookupInstComponent(String name);
567    inh InstLookupResult<InstComponentDecl> InstForClauseE.lookupInstComponent(String name);
568    inh InstLookupResult<InstComponentDecl> InstForStmt.lookupInstComponent(String name);
569    inh InstLookupResult<InstComponentDecl> InstForIndex.lookupInstComponent(String name);
570
571    /*
572     * Ensures that lookup of for-indices is only performed from right to left in order
573     * to avoid lookup loops within them.
574     */
575    eq InstForClauseE.getChild().lookupInstComponent(String name) =
576            getInstForIndex(getNumInstForIndex() - 1).localLookupInstComponent(name);
577    eq InstForClauseE.getInstForIndex(int index).lookupInstComponent(String name) =
578            index == 0 ? lookupInstComponent(name) : getInstForIndex(index - 1).localLookupInstComponent(name);
579    eq InstForStmt.getChild().lookupInstComponent(String name) =
580            getInstForIndex(getNumInstForIndex() - 1).localLookupInstComponent(name);
581    eq InstForStmt.getInstForIndex(int index).lookupInstComponent(String name) =
582            index == 0 ? lookupInstComponent(name) : getInstForIndex(index - 1).localLookupInstComponent(name);
583    eq FIterExp.getChild().lookupInstComponent(String name) =
584            getForIndex(getNumForIndex() - 1).localLookupInstComponent(name);
585    eq FIterExp.getForIndex(int index).lookupInstComponent(String name) =
586            index == 0 ? lookupInstComponent(name) : getForIndex(index - 1).localLookupInstComponent(name);
587
588    syn InstLookupResult<InstComponentDecl> CommonForIndex.localLookupInstComponent(String name) = null;
589    syn InstLookupResult<InstComponentDecl> InstForIndex.localLookupInstComponent(String name) {
590        InstPrimitive var = getInstPrimitive();
591        if (var.name().equals(name)) {
592            return InstLookupResult.<InstComponentDecl> found(var);
593        }
594        return lookupInstComponent(name);
595    }
596
597    eq SourceRoot.getChild().lookupInstComponent(String name) = InstLookupResult.notFound();
598    // This equation is necessary since InstAccesses may be present in FExps.
599    eq FlatRoot.getChild().lookupInstComponent(String name)   = InstLookupResult.notFound();
600
601    inh InstLookupResult<InstComponentDecl> InstRecordConstructor.lookupInstComponent(String name);
602    eq InstRecordConstructor.getChild().lookupInstComponent(String name)             = lookupInstComponent(name);
603    eq InstRecordConstructor.getInstComponentDecl().lookupInstComponent(String name) = genericLookupInstComponent(name);
604
605    syn lazy InstLookupResult<InstComponentDecl> InstRecordConstructor.genericLookupInstComponent(String name) {
606        InstLookupResult<InstComponentDecl> res = localLookupInstComponent(name);
607        return res.successful() ? res : lookupInstComponent(name);
608    }
609
610    syn lazy InstLookupResult<InstComponentDecl> InstRecordConstructor.localLookupInstComponent(String name) {
611        for (InstComponentDecl icd : getInstComponentDecls()) {
612            if (icd.matches(name)) {
613                return InstLookupResult.<InstComponentDecl>found(icd);
614            }
615        }
616        for (InstExtends ie : getInstExtendss()) {
617            InstLookupResult<InstComponentDecl> res = ie.memberInstComponent(name);
618            if (res.successful()) {
619                return res;
620            }
621        }
622        return InstLookupResult.notFound();
623    }
624
625    /**
626     * Lookup name in the record declaration.
627     */
628    syn InstComponentDecl InstRecordConstructor.declarationInstComponent(String name) = 
629        myInstClassDecl().memberInstComponent(name).target(INST_UNKNOWN_COMPONENT, this);
630
631    syn lazy InstLookupResult<InstComponentDecl> InstNode.genericLookupInstComponent(String name) {
632        InstLookupResult<InstComponentDecl> res = memberInstComponent(name);
633        if (res.successful())
634            return res;
635        for (InstImport ii : getInstImports()) {
636            res = ii.lookupInstConstantInImport(name);
637            if (res.successful())
638                return res;
639        }
640        return genericLookupInstConstant(name);
641    }
642    eq InstSimpleShortClassDecl.genericLookupInstComponent(String name) = actualInstClass().genericLookupInstComponent(name);
643    eq InstLibNode.genericLookupInstComponent(String name)              = actualInstClass().genericLookupInstComponent(name);
644
645    syn InstLookupResult<InstComponentDecl> InstNode.genericLookupInstConstant(String name) = lookupInstConstant(name);
646    eq InstComponentDecl.genericLookupInstConstant(String name)                             = myInstClass().lookupInstConstant(name);
647    eq InstExtends.genericLookupInstConstant(String name)                                   = myInstClass().lookupInstConstant(name);
648
649
650    syn InstLookupResult<InstComponentDecl> InstNode.arrayMemberInstComponent(String name, int ndims) {
651        if (ndims == 0) 
652            return memberInstComponent(name);
653        return getInstComponentDecl(0).arrayMemberInstComponent(name, ndims - 1);
654    }
655    eq InstSimpleShortClassDecl.arrayMemberInstComponent(String name, int ndims) = actualInstClass().arrayMemberInstComponent(name, ndims);
656    eq InstLibNode.arrayMemberInstComponent(String name, int ndims)              = actualInstClass().arrayMemberInstComponent(name, ndims);
657
658    syn InstLookupResult<InstComponentDecl> InstNode.memberInstComponent(String name) { 
659        if (isArray()) {
660            return arrayMemberInstComponent(name, ndims());
661        } else {   
662            return memberInstComponentCached(name);
663        }
664    }
665   
666    syn lazy InstLookupResult<InstComponentDecl> InstNode.memberInstComponentCached(String name)  {
667        for (InstComponentDecl ic : getInstComponentDecls()) {
668            if (ic.matches(name)) {
669                return findInnerComponentIfAny(ic.duplicateOriginal());
670            }
671        }
672
673        for (InstExtends ie : getInstExtendss()) {
674            InstLookupResult<InstComponentDecl> res = ie.memberInstComponent(name);
675            if (res.successful()) {
676                return res;
677            }
678        }
679       
680        return InstLookupResult.notFound();
681    }
682    eq InstSimpleShortClassDecl.memberInstComponent(String name) = actualInstClass().memberInstComponent(name);
683    eq InstLibNode.memberInstComponent(String name)              = actualInstClass().memberInstComponent(name);
684   
685    public InstLookupResult InstNode.findInnerComponentIfAny(InstComponentDecl icd) {
686        if (icd.isOuter()) {
687            return InstLookupResult.outer(icd);
688        }
689        return InstLookupResult.found(icd);
690    }
691   
692   
693    inh lazy InstLookupResult<InstComponentDecl> InstNode.lookupInstConstant(String name);
694    eq Root.getChild().lookupInstConstant(String name)        = InstLookupResult.notFound();
695    eq InstNode.getChild().lookupInstConstant(String name)    = memberInstConstantFirst(name);
696    eq InstLibNode.getChild().lookupInstConstant(String name) = lookupInstConstant(name);
697
698    syn InstLookupResult<InstComponentDecl> InstNode.memberInstConstantFirst(String name) {
699        InstLookupResult<InstComponentDecl> res = memberInstConstantWithExtends(name);
700        if (res.successful())
701            return res;
702       
703        for (InstImport ii : getInstImports()) {
704            res = ii.lookupInstConstantInImport(name);
705            if (res.successful())
706                return res;
707        }
708       
709        return lookupInstConstant(name);
710    }
711    eq InstSimpleShortClassDecl.memberInstConstantFirst(String name) = actualInstClass().memberInstConstantFirst(name);
712    eq InstLibNode.memberInstConstantFirst(String name)              = actualInstClass().memberInstConstantFirst(name);
713
714    syn lazy InstLookupResult<InstComponentDecl> InstNode.memberInstConstantWithExtends(String name) {
715        InstLookupResult<InstComponentDecl> res = memberInstConstant(name);
716        if (res.successful())
717            return res;
718       
719        for (InstExtends ie : getInstExtendss()) {
720            res = ie.memberInstConstantWithExtends(name);
721            if (res.successful())
722                return res;
723        }
724       
725        return InstLookupResult.notFound();
726    }
727    eq InstSimpleShortClassDecl.memberInstConstantWithExtends(String name) = actualInstClass().memberInstConstantWithExtends(name);
728    eq InstLibNode.memberInstConstantWithExtends(String name)              = actualInstClass().memberInstConstantWithExtends(name);
729
730    syn lazy InstLookupResult<InstComponentDecl> InstNode.memberInstConstant(String name) {
731        for (InstComponentDecl ic : getInstComponentDecls()) 
732            if (ic.getSrcComponentDecl().isConstant() && ic.matches(name))
733                return InstLookupResult.found(ic.duplicateOriginal());
734       
735        return InstLookupResult.notFound();
736    }
737    eq InstSimpleShortClassDecl.memberInstConstant(String name) = actualInstClass().memberInstConstant(name);
738    eq InstLibNode.memberInstConstant(String name)              = actualInstClass().memberInstConstant(name);
739
740    syn InstLookupResult<InstComponentDecl> InstImport.lookupInstConstantInImport(String name) {
741        // Assume import points to a single (constant) component
742        if (name.equals(name())) {
743            String className = getPackageName().enclosingName();
744            if (!className.equals("")) {
745                InstClassDecl icd = ((SourceRoot)root()).getProgram().getInstProgramRoot().
746                   simpleLookupInstClassDecl(className);
747                return icd.memberInstConstant(getPackageName().getLastInstAccess().name());
748            }
749        }
750        return InstLookupResult.notFound();
751    }
752
753    eq InstImportUnqualified.lookupInstConstantInImport(String name)  {
754        return getImportedClass().memberInstConstant(name);
755    }
756
757    // This is needed since the member components of InstPrimitive:s (which are attributes)
758    // are not instantiated
759    eq InstPrimitive.memberInstComponent(String name)      = myInstClass().memberInstComponent(name);
760    eq InstExtends.memberInstComponent(String name)   = 
761        extendsPrimitive() ? myInstClass().memberInstComponent(name) : super.memberInstComponent(name);
762
763    eq InstComponentDecl.matches(String str) = name().equals(str);
764    eq InstForIndex.matches(String str)      = getInstPrimitive().matches(str);
765
766
767    /**
768     * Check if this access has a lookup error.
769     */
770    syn boolean InstAccess.hasLookupProblem()      = false;
771    eq InstAmbiguousAccess.hasLookupProblem()      = true;
772    eq InstAmbiguousArrayAccess.hasLookupProblem() = true;
773    eq InstGlobalAccess.hasLookupProblem()         = getInstAccess().hasLookupProblem();
774    eq InstDot.hasLookupProblem()                  = getInstAccess(getNumInstAccess() - 1).hasLookupProblem();
775    eq InstNamedAccess.hasLookupProblem()          = myInstLookup().isProblem();
776
777    syn InstComponentDecl InstAccess.myInstComponentDecl() = unknownInstComponentDecl();
778    eq InstDot.myInstComponentDecl()                       = getLastInstAccess().myInstComponentDecl();
779    eq InstGlobalAccess.myInstComponentDecl()              = getInstAccess().myInstComponentDecl();
780    eq InstComponentAccess.myInstComponentDecl()           = myInstLookup().target(INST_UNKNOWN_COMPONENT, this);
781    eq InstComponentArrayAccess.myInstComponentDecl()      = myInstLookup().target(INST_UNKNOWN_COMPONENT, this);
782   
783    syn InstLookupResult<InstComponentDecl> InstAccess.myInstLookupComponent() = lookupInstComponent(name());
784   
785    syn InstLookupResult<? extends InstLookupResult.Item>  InstAccess.myInstLookup() = myInstLookupClass();
786    eq InstDot.myInstLookup()          = getLastInstAccess().myInstLookup();
787    eq InstGlobalAccess.myInstLookup() = getInstAccess().myInstLookup();
788    syn lazy InstLookupResult<InstComponentDecl> InstComponentAccess.myInstLookup()      = myInstLookupComponent();
789    syn lazy InstLookupResult<InstComponentDecl> InstComponentArrayAccess.myInstLookup() = myInstLookupComponent();
790
791    syn InstComponentDecl InstAccess.myInstComponentElement() = unknownInstComponentDecl();
792    eq InstDot.myInstComponentElement()                       = getLastInstAccess().myInstComponentElement();
793    eq InstGlobalAccess.myInstComponentElement()              = getInstAccess().myInstComponentElement();
794    eq InstComponentAccess.myInstComponentElement()           = 
795        lookupArrayElement(myInstLookup()).target(INST_UNKNOWN_COMPONENT, this);
796    eq InstComponentArrayAccess.myInstComponentElement()      = 
797        lookupArrayElement(myInstLookup()).target(INST_UNKNOWN_COMPONENT, this);
798}
799
800aspect LookupInstComponentsInModifications {
801
802    eq InstNamedModification.getName().lookupInstComponent(String name) = lookupInstComponentInInstElement(name);
803
804    /**
805     * This attribute defines the lookup mechanism for left hand component references in modifications.
806     * They are looked up in the element that the modification is attached to, not the surrounding scope.
807     */
808    inh InstLookupResult<InstComponentDecl> InstElementModification.lookupInstComponentInInstElement(String name);
809    inh InstLookupResult<InstComponentDecl> InstNamedModification.lookupInstComponentInInstElement(String name);
810    inh InstLookupResult<InstComponentDecl> InstComponentRedeclare.lookupInstComponentInInstElement(String name);
811
812    eq InstConstrainingClass.getInstClassModification().lookupInstComponentInInstElement(String name)     = getInstNode().memberInstComponent(name).unresolved();
813    eq InstConstrainingComponent.getInstClassModification().lookupInstComponentInInstElement(String name) = getInstNode().memberInstComponent(name).unresolved();
814    eq InstComponentDecl.getInstModification().lookupInstComponentInInstElement(String name)              = memberInstComponent(name).unresolved();
815    eq InstNode.getElementInstModification().lookupInstComponentInInstElement(String name)                = memberInstComponent(name).unresolved();
816    eq InstElementModification.getInstModification().lookupInstComponentInInstElement(String name)        = getName().qualifiedLookupInstComponent(name);
817    eq InstNormalExtends.getInstClassModification().lookupInstComponentInInstElement(String name)         = memberInstComponent(name).unresolved();
818    eq InstComponentRedeclare.getName().lookupInstComponent(String name)                                  = lookupInstComponentInInstElement(name);
819    eq InstRoot.getChild().lookupInstComponentInInstElement(String name)                                  = InstLookupResult.notFound();
820    eq FlatRoot.getChild().lookupInstComponentInInstElement(String name)                                  = InstLookupResult.notFound();
821
822    /**
823     * Find the actual redeclared component for a redeclaration modification.
824     */
825    syn InstComponentDecl InstComponentRedeclare.myInstReplacingComponent() = 
826        lookupInstReplacingComponent(name()).target(INST_UNKNOWN_COMPONENT, this);
827
828    inh InstLookupResult<InstComponentDecl> InstComponentRedeclare.lookupInstReplacingComponent(String name);
829    eq InstNamedModification.getChild().lookupInstReplacingComponent(String name) = getName().qualifiedLookupInstComponent(name);
830    eq InstNode.getChild().lookupInstReplacingComponent(String name)              = memberInstComponent(name).unresolved();
831    eq Root.getChild().lookupInstReplacingComponent(String name)                  = InstLookupResult.notFound();
832
833}
834
835aspect SimpleLookupInstComponentDecl {
836    syn InstComponentDecl InstNode.simpleLookupInstComponentDecl(String name) {
837        for (InstComponentDecl icd : getInstComponentDecls()) {
838            if (icd.name().matches(name))
839                return icd;
840        }
841        for (InstExtends ie : getInstExtendss()) {
842            InstComponentDecl match = ie.simpleLookupInstComponentDecl(name);
843            if (match != null)
844                return match;
845        }
846        return null;
847    }
848}
Note: See TracBrowser for help on using the repository browser.