source: branches/dev-5819/Compiler/ModelicaFrontEnd/src/jastadd/instance/InstLookupClasses.jrag @ 13600

Last change on this file since 13600 was 13600, checked in by randersson, 2 months ago

#5819 Merged JM trunk into branch.

File size: 39.2 KB
Line 
1/*
2    Copyright (C) 2009-2014 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
17aspect InstLookupClasses {
18
19
20    protected static final InstLookupResult.DefaultGenerator<InstClassDecl> ASTNode.INST_UNKNOWN_CLASS = 
21            new InstLookupResult.DefaultGenerator<InstClassDecl>() {
22        public InstClassDecl generate(ASTNode src) {
23            return src.unknownInstClassDecl();
24        }
25    };
26
27    inh InstLookupResult<InstClassDecl> InstAccess.lookupInstClass(String name);
28    inh InstLookupResult<InstClassDecl> InstNode.lookupInstClass(String name);
29    inh InstLookupResult<InstClassDecl> InstModification.lookupInstClass(String name);
30    inh InstLookupResult<InstClassDecl> InstConstraining.lookupInstClass(String name);
31    inh InstLookupResult<InstClassDecl> FType.lookupInstClass(String name);
32
33    syn InstLookupResult<InstClassDecl> InstNode.lookupInstClassRedirect(String name)         = genericLookupInstClass(name);
34    syn InstLookupResult<InstClassDecl> InstModification.lookupInstClassRedirect(String name) = lookupInstClass(name);
35    eq InstClassDecl.lookupInstClassRedirect(String name)                                     = actualInstClass().genericLookupInstClass(name);
36    eq InstEnumClassDecl.lookupInstClassRedirect(String name)                                 = lookupInstBuiltInClass(name);
37    eq InstReplacingPrimitive.lookupInstClassRedirect(String name)                            = lookupInstClass(name);
38    eq InstExtends.lookupInstClassRedirect(String name)                                       = genericLookupInstClassInExtends(name);
39
40    eq InstNode.getInstClassDecl().lookupInstClass(String name)                  = genericLookupInstClass(name); 
41    eq InstNode.getRedeclaredInstClassDecl().lookupInstClass(String name)        = genericLookupInstClass(name); 
42    eq InstNode.getInstComponentDecl().lookupInstClass(String name)              = genericLookupInstClass(name); 
43    eq InstNode.getFAbstractEquation().lookupInstClass(String name)              = genericLookupInstClass(name); 
44    eq InstNode.getElementInstModification().lookupInstClass(String name)        = genericLookupInstClass(name); 
45    eq InstNode.getInstExtends().lookupInstClass(String name)                    = superLookupInstClass(name);
46
47    eq InstComponentDecl.getInstExtends().lookupInstClass(String name)           = superLookupInstClassInComponent(name);
48    eq InstArrayComponentDecl.getInstExtends().lookupInstClass(String name)      = instComponentDecl().superLookupInstClassInComponent(name);
49
50    eq InstArrayComponentDecl.getChild().lookupInstClass(String name)            = lookupInstClass(name);
51    eq InstExternalObject.getDestructorCall().lookupInstClass(String name)       = lookupInstClass(name);
52
53    eq InstExpandableConnectorDecl.getInstComponentDecl(int i).lookupInstClass(String name)          = 
54        useTemplate(i) ? template(i).lookupInstClass(name) : genericLookupInstClass(name);
55    eq InstArrayExpandableConnector.getInstComponentDecl(int i).lookupInstClass(String name)         = 
56        useTemplate(i) ? template(i).lookupInstClass(name) : genericLookupInstClass(name);
57    eq InstReplacingExpandableConnectorDecl.getInstComponentDecl(int i).lookupInstClass(String name) = 
58        useTemplate(i) ? template(i).lookupInstClass(name) : genericLookupInstClass(name);
59
60    eq InstExtends.getInstClassDecl().lookupInstClass(String name)               = genericLookupInstClassInExtends(name);
61    eq InstExtends.getInstComponentDecl().lookupInstClass(String name)           = genericLookupInstClassInExtends(name);
62    eq InstExtends.getInstExtends().lookupInstClass(String name)                 = superLookupInstClassInExtends(name);
63    eq InstExtends.getRedeclaredInstClassDecl().lookupInstClass(String name)     = genericLookupInstClassInExtends(name);
64    eq InstExtends.getFAbstractEquation().lookupInstClass(String name)           = genericLookupInstClassInExtends(name);
65    eq InstExtends.getElementInstModification().lookupInstClass(String name)     = genericLookupInstClassInExtends(name); 
66    eq InstNormalExtends.getInstClassModification().lookupInstClass(String name) = lookupInstClassFromMod(name);
67
68    inh InstLookupResult<InstClassDecl> InstExtends.lookupInstClassFromMod(String name);
69    eq InstNode.getInstExtends().lookupInstClassFromMod(String name)              = genericLookupInstClass(name);
70    eq InstComponentDecl.getInstExtends().lookupInstClassFromMod(String name)     = genericLookupInstClass(name);
71    eq InstExtends.getInstExtends().lookupInstClassFromMod(String name)           = genericLookupInstClassInExtends(name);
72    eq Root.getChild().lookupInstClassFromMod(String name)                        = InstLookupResult.notFound();
73    eq InstRecordConstructor.getInstExtends().lookupInstClassFromMod(String name) = 
74            myInstClassDecl().genericLookupInstClass(name);
75
76    eq InstInlineExtends.getClassName().lookupInstClass(String name) = 
77        getClassName().name().equals(name) ? lookupRedeclareExtendsInstClass(name) : lookupInstClass(name);
78
79    // The lexical scope of modifiers in short classes is the "outer" scope, although
80    // the short class declaration is modeled as containing an extends clause
81    eq InstExtendsShortClass.getInstClassModification().lookupInstClass(String name)             = getLookupNode().lookupInstClass(name);
82    eq InstExtendsShortClass.getClassName().lookupInstClass(String name)                         = lookupInstClassInChain(name);
83    eq InstReplacingExtendsShortClass.getClassName().lookupInstClass(String name)                = lookupInstClassInChain(name);
84    eq InstShortClassDecl.getChild().lookupInstClass(String name)                                = lookupInstClass(name);
85    eq InstSimpleShortClassDecl.getChild().lookupInstClass(String name)                          = lookupInstClass(name);
86    eq InstLibNode.getChild().lookupInstClass(String name)                                       = lookupInstClass(name);
87    eq InstReplacingShortClassDecl.getChild().lookupInstClass(String name)                       = getInstClassRedeclare().lookupInstClass(name);
88    eq InstReplacingSimpleShortClassDecl.getChild().lookupInstClass(String name)                 = getInstClassRedeclare().lookupInstClass(name);
89    eq InstReplacingShortClassDecl.getOriginalInstClass().lookupInstClass(String name)           = lookupInstClass(name);
90    eq InstReplacingSimpleShortClassDecl.getOriginalInstClass().lookupInstClass(String name)     = lookupInstClass(name);
91    eq InstReplacingFullClassDecl.getOriginalInstClass().lookupInstClass(String name)            = lookupInstClass(name);
92    eq InstReplacingShortClassDecl.getInstConstrainingClass().lookupInstClass(String name)       = lookupInstClass(name);
93    eq InstReplacingSimpleShortClassDecl.getInstConstrainingClass().lookupInstClass(String name) = lookupInstClass(name);
94    eq InstReplacingFullClassDecl.getInstConstrainingClass().lookupInstClass(String name)        = lookupInstClass(name);
95    eq InstConstrainingComponent.getChild().lookupInstClass(String name)                         = 
96        (getInstRedeclare() != null) ? getInstRedeclare().lookupInstClass(name) : lookupInstClass(name);
97    eq InstConstrainingClass.getChild().lookupInstClass(String name)                             = 
98        (getInstRedeclare() != null) ? getInstRedeclare().lookupInstClass(name) : lookupInstClass(name);
99
100    eq InstReplacingRecord.getOriginalInstComponent().lookupInstClass(String name)    = lookupInstClass(name);
101    eq InstReplacingComposite.getOriginalInstComponent().lookupInstClass(String name) = lookupInstClass(name);
102    eq InstReplacingPrimitive.getOriginalInstComponent().lookupInstClass(String name) = lookupInstClass(name);
103
104    eq InstReplacingRecord.getClassName().lookupInstClass(String name)    = getInstComponentRedeclare().lookupInstClass(name);
105    eq InstReplacingComposite.getClassName().lookupInstClass(String name) = getInstComponentRedeclare().lookupInstClass(name);
106    eq InstReplacingPrimitive.getClassName().lookupInstClass(String name) = getInstComponentRedeclare().lookupInstClass(name);
107
108    eq InstCreateComponentDecl.getChild().lookupInstClass(String name)     = 
109        (getLookupNode() == null) ? lookupInstClass(name) : getLookupNode().lookupInstClassRedirect(name);
110    eq InstCreateForIndexPrimitive.getChild().lookupInstClass(String name) = 
111        (getLookupNode() == null) ? lookupInstClass(name) : getLookupNode().lookupInstClassRedirect(name);
112
113    eq InstConstrainingClass.getInstNode().lookupInstClass(String name) = getClassName().myInstClassDecl().lookupInstClass(name);
114
115    eq InstGeneratedInner.getChild().lookupInstClass(String name) = getCopiedOuter().lookupInstClass(name);
116   
117    eq InstRecordConstructor.getInstComponentDecl().lookupInstClass(String name) = 
118        myInstClassDecl().genericLookupInstClass(name);
119    eq InstRecordConstructor.getInstExtends().lookupInstClass(String name) = 
120        myInstClassDecl().genericLookupInstClass(name);
121
122
123    syn InstLookupResult<InstClassDecl> InstClassDecl.lookupInstClassInInstClassRedeclare(String name) = InstLookupResult.notFound();
124    eq InstReplacingShortClassDecl.lookupInstClassInInstClassRedeclare(String name) = getInstClassRedeclare().lookupInstClass(name);
125    eq InstReplacingFullClassDecl.lookupInstClassInInstClassRedeclare(String name)  = getInstClassRedeclare().lookupInstClass(name);
126
127    inh InstLookupResult<InstClassDecl> InstExtendsShortClass.lookupInstClassInChain(String name);
128    inh InstLookupResult<InstClassDecl> InstReplacingExtendsShortClass.lookupInstClassInChain(String name);
129
130    eq InstNode.getInstClassDecl(int index).lookupInstClassInChain(String name)             =
131            getInstClassDecl(index).lookupInstClass(name);
132    eq InstNode.getInstExtends(int index).lookupInstClassInChain(String name)               =
133            getInstExtends(index).lookupInstClass(name);
134    eq InstNode.getRedeclaredInstClassDecl(int index).lookupInstClassInChain(String name)   =
135            getRedeclaredInstClassDecl(index).lookupInstClass(name);
136    eq InstNode.getInstComponentDecl(int index).lookupInstClassInChain(String name)         =
137            getInstComponentDecl(index).lookupInstClass(name);
138
139    eq InstRecordConstructor.getInstComponentDecl().lookupInstClassInChain(String name)    = 
140        myInstClassDecl().genericLookupInstClass(name);
141    eq InstRecordConstructor.getInstExtends().lookupInstClassInChain(String name) = 
142        myInstClassDecl().genericLookupInstClass(name);
143    eq InstExtendsShortClass.getInstExtends().lookupInstClassInChain(String name)          = 
144        myInstClass().superLookupInstClassFromChain(name);
145    eq InstReplacingExtendsShortClass.getInstExtends().lookupInstClassInChain(String name) = 
146        myInstClass().superLookupInstClassFromChain(name);
147
148    syn InstLookupResult<InstClassDecl> InstClassDecl.superLookupInstClassFromChain(String name) = superLookupInstClass(name);
149    eq InstReplacingShortClassDecl.superLookupInstClassFromChain(String name)                    = getInstExtends(0).lookupInstClass(name);
150
151    inh InstLookupResult<InstClassDecl> InstAccess.lookupInstClassFromTop(String name);
152    inh InstLookupResult<InstClassDecl> InstNode.lookupInstClassFromTop(String name);
153    inh InstLookupResult<InstClassDecl> InstImport.lookupInstClassFromTop(String name);
154    eq InstRoot.getChild().lookupInstClassFromTop(String name) = genericLookupInstClass(name);
155    eq Root.getChild().lookupInstClassFromTop(String name)     = InstLookupResult.notFound();
156
157    eq SourceRoot.getChild().lookupInstClass(String name) = InstLookupResult.notFound();
158    eq FlatRoot.getChild().lookupInstClass(String name)   = InstLookupResult.notFound();
159
160    /**
161     * Look up the class being redeclared & extended in a "redeclare class extends" declaration.
162     */
163    inh InstLookupResult<InstClassDecl> InstNode.lookupRedeclareExtendsInstClass(String name);
164    eq InstNode.getChild().lookupRedeclareExtendsInstClass(String name)                    = InstLookupResult.notFound();
165    eq Root.getChild().lookupRedeclareExtendsInstClass(String name)                        = InstLookupResult.notFound();
166    eq InstExtendClassDecl.getChild().lookupRedeclareExtendsInstClass(String name)         = lookupRedeclareExtendsInstClass(name);
167    eq InstReplacingFullClassDecl.getChild().lookupRedeclareExtendsInstClass(String name)  = lookupRedeclareExtendsInstClass(name);
168    eq InstReplacingShortClassDecl.getChild().lookupRedeclareExtendsInstClass(String name) = lookupRedeclareExtendsInstClass(name);
169    eq InstExtends.getInstClassDecl().lookupRedeclareExtendsInstClass(String name)         = lookupTopRedeclareExtendsInstClass(name);
170    eq InstExtends.getInstExtends().lookupRedeclareExtendsInstClass(String name)           = myInstClass().lookupRedeclareExtendsInstClass(name);
171    eq InstRecordConstructor.getInstExtends().lookupRedeclareExtendsInstClass(String name) = myInstClassDecl().genericLookupInstClass(name);
172    eq InstNode.getRedeclaredInstClassDecl().lookupRedeclareExtendsInstClass(String name)  = lookupNextRedeclareExtendsInstClass(name);
173    eq InstInlineExtends.getInstExtends().lookupRedeclareExtendsInstClass(String name)     = 
174        myInstClass().lookupRedeclareExtendsInstClass(name);
175    eq InstExtendsShortClass.getInstExtends().lookupRedeclareExtendsInstClass(String name) = 
176        myInstClass().lookupRedeclareExtendsInstClass(name);
177    eq InstReplacingExtendsShortClass.getInstExtends().lookupRedeclareExtendsInstClass(String name) = 
178        myInstClass().lookupRedeclareExtendsInstClass(name);
179    eq InstComponentDecl.getChild().lookupRedeclareExtendsInstClass(String name)           = 
180        myInstClass().lookupRedeclareExtendsInstClassFromComponent(name);
181
182    syn InstLookupResult<InstClassDecl> InstClassDecl.lookupRedeclareExtendsInstClassFromComponent(String name) = lookupLastRedeclareExtendsInstClass(name);
183    eq InstReplacingFullClassDecl.lookupRedeclareExtendsInstClassFromComponent(String name)        = lookupRedeclareExtendsInstClass(name);
184    eq InstReplacingShortClassDecl.lookupRedeclareExtendsInstClassFromComponent(String name)       = lookupRedeclareExtendsInstClass(name);
185    eq InstReplacingSimpleShortClassDecl.lookupRedeclareExtendsInstClassFromComponent(String name) = lookupRedeclareExtendsInstClass(name);
186
187    /**
188     * Look up the class being redeclared & extended in the last step of a chain
189     * of "redeclare class extends" declarations.
190     */
191    inh InstLookupResult<InstClassDecl> InstExtends.lookupTopRedeclareExtendsInstClass(String name);
192    eq InstBaseNode.getInstExtends().lookupTopRedeclareExtendsInstClass(String name) = lookupLastRedeclareExtendsInstClass(name);
193    eq Root.getChild().lookupTopRedeclareExtendsInstClass(String name)               = InstLookupResult.notFound();
194
195    /**
196     * Resolve classes that are just references to other classes.
197     */
198    syn InstClassDecl InstClassDecl.actualInstClass() = this;
199    eq InstSimpleShortClassDecl.actualInstClass()     = 
200        isRecursive() ? unknownInstClassDecl() : myTargetInstClassDecl().actualInstClass();
201    eq InstLibNode.actualInstClass()                  = resolveLib().actualInstClass();
202
203    /**
204     * Get loaded version of library class.
205     */
206    syn InstClassDecl InstClassDecl.resolveLib() = this;
207    eq InstLibNode.resolveLib()                  = getActualInstClass();
208
209    /**
210     * Get loaded version of library class.
211     */
212    syn SrcClassDecl SrcClassDecl.resolveLib() = this;
213    eq SrcLibNode.resolveLib()              = myClass();
214
215    /**
216     * Lookup the class being redeclared & extended in the last step of a chain
217     * of "redeclare class extends" declarations, where it is known that the last
218     * redeclaring class is below this node.
219     */
220    syn InstLookupResult<InstClassDecl> InstNode.lookupLastRedeclareExtendsInstClass(String name) {
221        // TODO: find better way of detecting if there is only one "redeclare class extends" in chain
222        InstLookupResult<InstClassDecl> first = lookupCurRedeclareExtendsInstClass(name);
223        if (first.successful()) {
224            InstLookupResult<InstClassDecl> second = first.target().resolveLib().lookupRedeclareExtendsInstClass(name);
225            if (second.successful())
226                return second;
227        }
228        return first;
229    }
230
231    /**
232     * Look up the next class being redeclared & extended in a chain of
233     * "redeclare class extends" declarations.
234     */
235    syn InstLookupResult<InstClassDecl> InstNode.lookupNextRedeclareExtendsInstClass(String name) {
236        for (InstExtends ie : getInstExtendss()) {
237            InstLookupResult<InstClassDecl> res = ie.lookupCurRedeclareExtendsInstClass(name);
238            if (res.successful())
239                return res;
240        }
241        for (InstClassDecl icd : getInstClassDecls()) 
242            if (icd.matches(name)) 
243                return InstLookupResult.found(icd.originalInstClass());
244        return InstLookupResult.notFound();
245    }
246
247    /**
248     * Look up the next class being redeclared & extended in a chain of
249     * "redeclare class extends" declarations, including among direct children.
250     */
251    syn InstLookupResult<InstClassDecl> InstNode.lookupCurRedeclareExtendsInstClass(String name) {
252        for (InstClassDecl icd : getRedeclaredInstClassDecls()) 
253            if (icd.matches(name)) 
254                return InstLookupResult.found(icd);
255        return lookupNextRedeclareExtendsInstClass(name);
256    }
257
258
259    syn lazy HashMap<String,SrcLibNode> InstProgramRoot.libraryMap() {
260        Program prog = root().asSourceRoot().getProgram();
261        HashMap<String,SrcLibNode> map = new HashMap<String,SrcLibNode>(prog.getNumSrcLibNode() * 4 / 3 + 1);
262        for (SrcLibNode ln : prog.getSrcLibNodes()) {
263            if (!map.containsKey(ln.name())) {
264                map.put(ln.name(), ln);
265            }
266        }
267        return map;
268    }
269
270    syn lazy InstLookupResult<InstClassDecl> InstProgramRoot.lookupLibrary(String name) {
271        SrcLibNode ln = libraryMap().get(name);
272        if (ln != null) {
273            InstClassDecl icd = createInstClassDecl(ln);
274            if (icd instanceof InstFullClassDecl || icd instanceof InstLibNode) {
275                // Add to instance tree
276                addInstLibClassDecl(icd);
277                // Make sure is$Final is true;
278                getInstLibClassDecl(getNumInstLibClassDecl() - 1);
279                return InstLookupResult.found(icd);
280            }
281        }
282        return InstLookupResult.notFound();
283    }
284
285    eq InstProgramRoot.getChild().lookupInstClass(String name) = genericLookupInstClass(name);
286
287
288    eq InstProgramRoot.getInstPredefinedType().lookupInstClass(String name) {
289        for (InstClassDecl bcd : getInstPredefinedTypes()) 
290            if (bcd.matches(name))
291                return InstLookupResult.found(bcd); 
292
293        for (InstClassDecl bcd : getInstBuiltInTypes()) 
294            if (bcd.matches(name))
295                return InstLookupResult.found(bcd); 
296
297        return InstLookupResult.notFound();
298    }
299
300
301    syn lazy InstLookupResult<InstClassDecl> InstProgramRoot.genericLookupInstClass(String name) {
302        for (InstClassDecl bcd : getInstClassDecls()) 
303            if (bcd.matches(name))
304                return InstLookupResult.found(bcd); 
305       
306        for (InstClassDecl bcd : getInstPredefinedTypes()) 
307            if (bcd.matches(name))
308                return InstLookupResult.found(bcd); 
309
310        for (InstClassDecl bcd : getInstBuiltInFunctions()) 
311            if (bcd.matches(name))
312                return InstLookupResult.found(bcd); 
313
314        // TODO: propagate information about the class from where
315        // the lookup is requested, so that version information
316        // stored in annotations can be retreived.
317        return lookupLibrary(name);
318    }
319
320    eq InstDot.getInstAccess(int i).lookupInstClass(String name)             = 
321        (i == 0) ? lookupInstClass(name) : getInstAccessNoListTrans(i - 1).qualifiedLookupInstClass(name);
322    eq InstGlobalAccess.getInstAccess().lookupInstClass(String name)         = lookupInstClassFromTop(name);
323    eq InstScalarAccess.getExpandedSubscripts().lookupInstClass(String name) = getTopInstAccess().lookupInstClass(name);
324    eq InstArrayAccess.getFArraySubscripts().lookupInstClass(String name)    = getTopInstAccess().lookupInstClass(name);
325
326
327    syn InstLookupResult<InstClassDecl> InstAccess.qualifiedLookupInstClass(String name) {
328        InstLookupResult<InstClassDecl> res = qualifiedLookupInstClassUnconstrained(name);
329        if (res.successful()) { // TODO: limit to only replaceable and replaced components and their children?
330            InstNode constr = lookupConstrainingInstNode();
331            if (constr != null && !constr.memberInstClass(name).successful())
332                return InstLookupResult.<InstClassDecl>constrained(res, closestConstrainingDecl());
333        }
334        return res;
335    }
336
337    syn InstLookupResult<InstClassDecl> InstAccess.qualifiedLookupInstClassUnconstrained(String name) = 
338        InstLookupResult.notFound();
339    eq InstClassAccess.qualifiedLookupInstClassUnconstrained(String name)                             = 
340        myInstClassDecl().memberInstClass(name);
341    eq InstComponentAccess.qualifiedLookupInstClassUnconstrained(String name)                         = 
342        myInstComponentDecl().memberInstClass(name);
343    eq InstComponentArrayAccess.qualifiedLookupInstClassUnconstrained(String name)                    = 
344       lookupArrayElement(myInstComponentDecl()).memberInstClass(name);
345
346
347    eq InstClassAccess.lookupConstrainingInstNode() = 
348        inQualified() ? lookupConstrainingInstClass(name()) : lookupConstrainingInstClassHelper(null, name());
349
350    inh InstClassDecl InstAccess.lookupConstrainingInstClass(String name);
351    eq BaseNode.getChild().lookupConstrainingInstClass(String name) = null;
352    eq InstDot.getInstAccess(int i).lookupConstrainingInstClass(String name) =
353        lookupConstrainingInstClassHelper((i == 0) ? null : getInstAccessNoListTrans(i - 1), name);
354
355    syn InstClassDecl InstAccess.lookupConstrainingInstClassHelper(InstAccess part, String name) {
356        InstLookupResult<InstClassDecl> res;
357        if (part == null) {
358            res = lookupInstClass(name);
359        } else {
360            InstNode parent = part.lookupConstrainingInstNode();
361            res = (parent != null) ? parent.memberInstClass(name) : InstLookupResult.<InstClassDecl>notFound();
362        }
363        if (!res.successful())
364            return null;
365        InstClassDecl icd = res.target().resolveLib();
366        if (!icd.hasInstConstrainingClass() || !icd.isReplaceable())
367            return icd;
368        return (InstClassDecl) icd.getInstConstrainingClass().getInstNode();
369    }
370
371
372    syn InstLookupResult<InstClassDecl> InstNode.lookupInstClassInSurrounding(String name)     = lookupInstClass(name);
373    eq InstReplacingFullClassDecl.lookupInstClassInSurrounding(String name)                    = 
374        getInstClassRedeclare().lookupInstClass(name);
375    eq InstReplacingShortClassDecl.lookupInstClassInSurrounding(String name)                   = 
376        getInstClassRedeclare().lookupInstClass(name);
377
378    syn lazy InstLookupResult<InstClassDecl> InstNode.genericLookupInstClass(String name) {
379        for (InstClassDecl icd : getInstClassDecls()) 
380            if (icd.matches(name)) 
381                return InstLookupResult.found(icd);
382       
383        for (InstExtends ie : getInstExtendss()) {
384            InstLookupResult<InstClassDecl> res = ie.memberInstClass(name);
385            if (res.successful())
386                return res;
387        }
388       
389        for (InstImport ii : getInstImports()) {
390            InstLookupResult<InstClassDecl> res = ii.lookupInstClassInImport(name);
391            if (res.successful())
392                return res;
393        }
394       
395        return lookupInstClassInSurrounding(name);
396    }
397    eq InstSimpleShortClassDecl.genericLookupInstClass(String name) = actualInstClass().genericLookupInstClass(name);
398    eq InstLibNode.genericLookupInstClass(String name)              = actualInstClass().genericLookupInstClass(name);
399
400    syn InstLookupResult<InstClassDecl> InstNode.superLookupInstClass(String name) {
401        InstLookupResult<InstClassDecl> res = superLookupInstClassLocal(name);
402        return res.successful() ? res : superLookupInstClassSurrounding(name);
403    }
404
405    syn InstLookupResult<InstClassDecl> InstNode.superLookupInstClassSurrounding(String name) = lookupInstClass(name);
406    eq InstReplacingSimpleShortClassDecl.superLookupInstClass(String name)                    = getInstClassRedeclare().lookupInstClass(name);
407
408    syn InstLookupResult<InstClassDecl> InstNode.superLookupInstClassLocal(String name) {
409        for (InstImport ii : getInstImports()) {
410            InstLookupResult<InstClassDecl> res = ii.lookupInstClassInImport(name);
411            if (res.successful())
412                return res;
413        }
414       
415        for (InstClassDecl icd : getInstClassDecls()) {
416            if (icd.matches(name)) {
417                return InstLookupResult.found(icd);
418            }
419        }
420       
421        return InstLookupResult.notFound();
422    }
423    eq InstSimpleShortClassDecl.superLookupInstClassLocal(String name) = actualInstClass().superLookupInstClassLocal(name);
424    eq InstLibNode.superLookupInstClassLocal(String name)              = actualInstClass().superLookupInstClassLocal(name);
425
426    syn InstLookupResult<InstClassDecl> InstComponentDecl.genericLookupInstClass(String name) {
427        InstLookupResult<InstClassDecl> res = memberInstClass(name);
428        if (res.successful())
429            return res;
430       
431        for (InstImport ii : getInstImports()) {
432            res = ii.lookupInstClassInImport(name);
433            if (res.successful())
434                return res;
435        }
436       
437        return myInstClass().lookupInstClassInSurrounding(name);
438    }
439
440    syn boolean InstClassDecl.isRedeclaredNonSimple()      = false;
441    eq InstReplacingShortClassDecl.isRedeclaredNonSimple() = true;
442    eq InstReplacingFullClassDecl.isRedeclaredNonSimple()  = true;
443
444    syn InstLookupResult<InstClassDecl> InstComponentDecl.superLookupInstClassInComponent(String name) {
445        // TODO: Why do we do this? Seems to be needed, as tests fail without it
446        if (myInstClass().isRedeclaredNonSimple())
447            return myInstClass().lookupInstClassInInstClassRedeclare(name);
448       
449        for (InstImport ii : getInstImports()) {
450            InstLookupResult<InstClassDecl> res = ii.lookupInstClassInImport(name);
451            if (res.successful())
452                return res;
453        }
454       
455        for (InstClassDecl icd : getInstClassDecls()) 
456            if (icd.matches(name)) 
457                return InstLookupResult.found(icd);
458   
459        return myInstClass().superLookupInstClass(name);
460    }
461
462
463    syn lazy InstLookupResult<InstClassDecl> InstExtends.genericLookupInstClassInExtends(String name) {
464        for (InstClassDecl icd : getInstClassDecls()) 
465            if (icd.matches(name)) 
466                return InstLookupResult.found(icd);
467       
468        for (InstExtends ie : getInstExtendss()) {
469            InstLookupResult<InstClassDecl> res = ie.memberInstClass(name);
470            if (res.successful())
471                return res;
472        }
473       
474        return myInstClass().genericLookupInstClass(name);
475    }
476
477    syn InstLookupResult<InstClassDecl> InstExtends.superLookupInstClassInExtends(String name) {
478        for (InstClassDecl icd : getInstClassDecls()) 
479            if (icd.matches(name)) 
480                return InstLookupResult.found(icd);
481       
482        return myInstClass().superLookupInstClass(name);
483    }
484
485
486    syn InstLookupResult<InstClassDecl> InstNode.memberInstClass(String name) = InstLookupResult.notFound();
487    eq InstFullClassDecl.memberInstClass(String name) {
488        for (InstClassDecl icd : getInstClassDecls()) 
489            if (icd.matches(name)) 
490                return InstLookupResult.found(findInnerClassIfAny(icd));
491       
492        for (InstExtends ie : getInstExtendss()) {
493            InstLookupResult<InstClassDecl> res = ie.memberInstClass(name);
494            if (res.successful())
495                return res;
496        }
497       
498        return InstLookupResult.notFound();
499    }
500
501    eq InstShortClassDecl.memberInstClass(String name)       = getInstExtends(0).memberInstClass(name);
502    eq InstSimpleShortClassDecl.memberInstClass(String name) = actualInstClass().memberInstClass(name);
503    eq InstLibNode.memberInstClass(String name)              = actualInstClass().memberInstClass(name);
504
505    eq InstExtends.memberInstClass(String name) {
506        for (InstClassDecl icd : getInstClassDecls()) 
507            if (icd.matches(name)) 
508                return InstLookupResult.found(icd);
509       
510        for (InstExtends ie : getInstExtendss()) {
511            InstLookupResult<InstClassDecl> res = ie.memberInstClass(name);
512            if (res.successful())
513                return res;
514        }
515       
516        return InstLookupResult.notFound();
517    }
518
519    /**
520     * Returns the InstComponentDecl representing the first cell of the array.
521     *
522     * @param ndims  the number of dimensions of the array.
523     */
524    syn InstComponentDecl InstComponentDecl.arrayCellInstComponent(int ndims) {
525        if (ndims == 0) 
526            return this;
527        if (getNumInstComponentDecl() == 0)
528            return unknownInstComponentDecl();
529        return getInstComponentDecl(0).arrayCellInstComponent(ndims - 1);
530    }
531
532    eq InstComponentDecl.memberInstClass(String name) {
533        if (isArray() && !isPrimitive()) {
534            return arrayCellInstComponent(ndims()).memberInstClass(name);
535        } else {
536            for (InstClassDecl icd : getInstClassDecls()) 
537                if (icd.matches(name)) 
538                    return InstLookupResult.found(findInnerClassIfAny(icd));
539           
540            for (InstExtends ie : getInstExtendss()) {
541                InstLookupResult<InstClassDecl> res = ie.memberInstClass(name);
542                if (res.successful())
543                    return res;
544            }
545           
546            return InstLookupResult.notFound();
547        }
548    }
549
550    /**
551     * If icd is in an outer component, try to find corresponding class in inner decl.
552     *
553     * If inner decl isn't found, return icd to avoid extra error messages.
554     */
555    public InstClassDecl InstNode.findInnerClassIfAny(InstClassDecl icd) {
556        if (icd.inOrIsOuter()) {
557            InstClassDecl inner = icd.myInnerInstClassDecl();
558            if (inner != null) 
559                icd = inner;
560        }
561        return icd;
562    }
563
564    eq InstClassDecl.matches(String str) = name().equals(str);
565    eq InstLibNode.matches(String str) {
566        if (name().equalsIgnoreCase(str)) {
567            resolveLib();
568        }
569        return name().equals(str);
570    }
571
572    syn InstClassDecl InstAccess.myInstClassDecl() = unknownInstClassDecl();
573    eq InstDot.myInstClassDecl()          = getLastInstAccess().myInstClassDecl();
574    eq InstGlobalAccess.myInstClassDecl() = getInstAccess().myInstClassDecl();
575    syn InstClassDecl InstClassAccess.myInstClassDecl() = myInstLookup().target(INST_UNKNOWN_CLASS, this).resolveLib();
576   
577    syn lazy InstLookupResult<InstClassDecl> InstClassAccess.myInstLookup() {
578        // If we return back during same lookup, return unknown to avoid infinite loop
579        if (isInMyInstClassDecl) {
580            return InstLookupResult.notFound();
581        }
582        isInMyInstClassDecl = true;
583        InstLookupResult<InstClassDecl> res = myInstLookupClass();
584        isInMyInstClassDecl = false;
585        return res;
586    }
587   
588    private boolean InstClassAccess.isInMyInstClassDecl = false;
589   
590    syn InstLookupResult<InstClassDecl> InstAccess.myInstLookupClass() = lookupInstClass(name());
591
592    syn InstClassDecl FAbstractFunctionCall.myInstClassDecl() = null;
593    eq InstFunctionCall.myInstClassDecl()                     = getName().myInstClassDecl(); 
594    eq InstRecordConstructor.myInstClassDecl()                = getRecord().myInstClassDecl(); 
595
596    syn InstClassDecl InstNode.myInstClass()  = unknownInstClassDecl(); 
597    eq InstComponentDecl.myInstClass()        = getClassName().myInstClassDecl();
598    eq InstArrayComponentDecl.myInstClass()   = instComponentDecl().myInstClass();
599    //eq InstShortClassDecl.myInstClass()       = getClassName().myInstClassDecl();
600    eq InstClassDecl.myInstClass()            = this;
601    eq InstExtends.myInstClass()              = getClassName().myInstClassDecl();
602    eq UnknownInstComponentDecl.myInstClass() = unknownInstClassDecl();
603   
604    protected static final InstLookupResult.DefaultGenerator<InstCallable> ASTNode.INST_UNKNOWN_CALLABLE = 
605            new InstLookupResult.DefaultGenerator<InstCallable>() {
606        public InstCallable generate(ASTNode src) {
607            return src.unknownInstClassDecl();
608        }
609    };
610
611}
612
613aspect InstLookupImport {
614
615    eq InstImport.getPackageName().lookupInstClass(String name) = lookupInstClassFromTop(name);
616
617    syn lazy InstClassDecl InstImport.getImportedClass() {
618        return getPackageName().myInstClassDecl();
619    }
620
621    syn InstLookupResult<InstClassDecl> InstImport.lookupInstClassInImport(String name) {
622        if (name.equals(name())) { 
623            InstClassDecl icd = getImportedClass();
624            if (!icd.isUnknown()) 
625                return InstLookupResult.found(icd);
626        }
627        return InstLookupResult.notFound();
628    }
629
630    eq InstImportUnqualified.lookupInstClassInImport(String name)  {
631        return getImportedClass().memberInstClass(name);
632    }
633
634}
635
636aspect InstLookupClassesInModifications {
637
638    eq InstElementModification.getName().lookupInstClass(String name) = lookupInstClassInInstElement(name);
639    eq InstClassRedeclare.getName().lookupInstClass(String name)      = lookupInstClassInInstElement(name);
640
641    /**
642     * This attribute defines the lookup mechanism for left hand class references in modifications.
643     * They are looked up in the element that the modification is attached to, not the surrounding scope.
644     */
645    inh InstLookupResult<InstClassDecl> InstElementModification.lookupInstClassInInstElement(String name);
646    inh InstLookupResult<InstClassDecl> InstClassRedeclare.lookupInstClassInInstElement(String name);
647
648    eq InstArrayComponentDecl.getInstModification().lookupInstClassInInstElement(String name)  = instComponentDecl().memberInstClass(name);
649    eq InstComponentDecl.getInstModification().lookupInstClassInInstElement(String name)       = memberInstClass(name);
650    eq InstElementModification.getInstModification().lookupInstClassInInstElement(String name) = getName().myInstComponentDecl().memberInstClass(name);
651    eq InstNormalExtends.getInstClassModification().lookupInstClassInInstElement(String name)  = memberInstClass(name);
652    eq InstConstraining.getInstClassModification().lookupInstClassInInstElement(String name)   = getInstNode().memberInstClass(name);
653    eq InstRoot.getChild().lookupInstClassInInstElement(String name)                           = InstLookupResult.notFound();
654    eq FlatRoot.getChild().lookupInstClassInInstElement(String name)                           = InstLookupResult.notFound();
655       
656}
657
658aspect SimpleInstClassLookup {
659
660    /**
661     * This method offers a simplified way of looking up qualified class names
662     * in the instance class structure.
663     *
664     * @param name A string containing a qualified name, for example 'A.B.C'.
665     */
666    syn lazy InstClassDecl InstProgramRoot.simpleLookupInstClassDecl(String name) = 
667        simpleLookupInstClassDeclRecursive(name);
668
669    public InstClassDecl InstNode.simpleLookupInstClassDeclRecursive(String name) {
670        String[] parts = name.split("\\.", 2);
671        InstClassDecl icd = findMatching(allInstClassDecls(), parts[0]);
672        if (icd != null) {
673            return icd = (parts.length == 1) ? icd : icd.actualInstClass().simpleLookupInstClassDeclRecursive(parts[1]);
674        } else {
675            return unknownInstClassDecl();
676        }
677    }
678
679    public InstClassDecl InstProgramRoot.simpleLookupInstClassDeclRecursive(String name) {
680        String[] parts = name.split("\\.", 2);
681        InstClassDecl icd = findMatching(getInstClassDecls(), parts[0]);
682        if (icd == null) {
683            InstLookupResult<InstClassDecl> result = lookupLibrary(parts[0]);
684            if (result.successful()) {
685                icd = result.target();
686            }
687        }
688        if (icd != null) {
689            return icd = (parts.length == 1) ? icd : icd.actualInstClass().simpleLookupInstClassDeclRecursive(parts[1]);
690        } else {
691            return unknownInstClassDecl();
692        }
693    }
694
695    /**
696     * Look up qualified class names in the instance class structure.
697     *
698     * @param name  a qualified name, for example 'A.B.C'
699     */
700    syn InstLookupResult<InstClassDecl> InstNode.lookupInstClassQualified(String name) {
701        return lookupInstClassQualified(name, false);
702    }
703
704    /**
705     * Look up qualified class names in the instance class structure.
706     *
707     * @param name  a qualified name, for example 'A.B.C'
708     */
709    syn InstLookupResult<InstClassDecl> InstNode.lookupInstClassQualifiedGlobal(String name) {
710        return lookupInstClassQualified(name, true);
711    }
712
713    /**
714     * Look up qualified class names in the instance class structure.
715     *
716     * @param name    a qualified name, for example 'A.B.C'
717     * @param global  should the lookup start in the global scope?
718     */
719    syn InstLookupResult<InstClassDecl> InstNode.lookupInstClassQualified(String name, boolean global) {
720        String[] parts = name.split("\\.");
721        InstNode icd = this;
722        InstLookupResult<InstClassDecl> res = null;
723        boolean first = true;
724        for (String part : parts) {
725            res = icd.lookupInstClassQualifiedPart(part, first, global);
726            if (!res.successful())
727                return res;
728            icd = res.target().resolveLib();
729            first = false;
730        }
731        return res;
732    }
733
734    syn InstLookupResult<InstClassDecl> InstNode.lookupInstClassQualifiedPart(
735            String name, boolean first, boolean global) {
736        if (!first) {
737            return memberInstClass(name);
738        } else if (global) {
739            return lookupInstClassFromTop(name);
740        } else {
741            return lookupInstClass(name);
742        }
743    }
744    eq InstProgramRoot.lookupInstClassQualifiedPart(String name, boolean first, boolean global) = 
745        genericLookupInstClass(name);
746
747    syn InstLookupResult<InstClassDecl> InstModification.lookupInstClassQualified(String name) = myInstNode().lookupInstClassQualified(name);
748}
749
750
751aspect EnumLookup {
752
753    eq InstEnumClassDecl.getChild().lookupInstClass(String name) = lookupInstBuiltInClass(name);
754
755    inh InstLookupResult<InstClassDecl> InstEnumClassDecl.lookupInstBuiltInClass(String name);
756    eq InstRoot.getChild().lookupInstBuiltInClass(String name) = InstLookupResult.notFound();
757    eq FlatRoot.getChild().lookupInstBuiltInClass(String name) = InstLookupResult.notFound();
758    eq InstProgramRoot.getChild().lookupInstBuiltInClass(String name) {
759        for (InstClassDecl bcd : getInstBuiltInTypes()) {
760            if (bcd.matches(name))
761                return InstLookupResult.found(bcd); 
762        }
763       
764        return InstLookupResult.notFound();
765    }
766
767}
Note: See TracBrowser for help on using the repository browser.