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

Last change on this file since 13800 was 13800, checked in by randersson, 8 weeks ago

#5819 Merged 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            String name = ln.name().toLowerCase();
264            if (!map.containsKey(name)) {
265                map.put(name, ln);
266            }
267        }
268        return map;
269    }
270
271    syn lazy InstLookupResult<InstClassDecl> InstProgramRoot.lookupLibrary(String name) {
272        SrcLibNode ln = libraryMap().get(name.toLowerCase());
273        if (ln != null) {
274            InstClassDecl icd = createInstClassDecl(ln);
275            if (icd instanceof InstFullClassDecl || icd instanceof InstLibNode) {
276                // Add to instance tree
277                addInstLibClassDecl(icd);
278                // Make sure is$Final is true;
279                getInstLibClassDecl(getNumInstLibClassDecl() - 1);
280                return InstLookupResult.found(icd);
281            }
282        }
283        return InstLookupResult.notFound();
284    }
285
286    eq InstProgramRoot.getChild().lookupInstClass(String name) = genericLookupInstClass(name);
287
288
289    eq InstProgramRoot.getInstPredefinedType().lookupInstClass(String name) {
290        for (InstClassDecl bcd : getInstPredefinedTypes()) 
291            if (bcd.matches(name))
292                return InstLookupResult.found(bcd); 
293
294        for (InstClassDecl bcd : getInstBuiltInTypes()) 
295            if (bcd.matches(name))
296                return InstLookupResult.found(bcd); 
297
298        return InstLookupResult.notFound();
299    }
300
301
302    syn lazy InstLookupResult<InstClassDecl> InstProgramRoot.genericLookupInstClass(String name) {
303        for (InstClassDecl bcd : getInstClassDecls()) 
304            if (bcd.matches(name))
305                return InstLookupResult.found(bcd); 
306       
307        for (InstClassDecl bcd : getInstPredefinedTypes()) 
308            if (bcd.matches(name))
309                return InstLookupResult.found(bcd); 
310
311        for (InstClassDecl bcd : getInstBuiltInFunctions()) 
312            if (bcd.matches(name))
313                return InstLookupResult.found(bcd); 
314
315        // TODO: propagate information about the class from where
316        // the lookup is requested, so that version information
317        // stored in annotations can be retreived.
318        return lookupLibrary(name);
319    }
320
321    eq InstDot.getInstAccess(int i).lookupInstClass(String name)             = 
322        (i == 0) ? lookupInstClass(name) : getInstAccessNoListTrans(i - 1).qualifiedLookupInstClass(name);
323    eq InstGlobalAccess.getInstAccess().lookupInstClass(String name)         = lookupInstClassFromTop(name);
324    eq InstScalarAccess.getExpandedSubscripts().lookupInstClass(String name) = getTopInstAccess().lookupInstClass(name);
325    eq InstArrayAccess.getFArraySubscripts().lookupInstClass(String name)    = getTopInstAccess().lookupInstClass(name);
326
327
328    syn InstLookupResult<InstClassDecl> InstAccess.qualifiedLookupInstClass(String name) {
329        InstLookupResult<InstClassDecl> res = qualifiedLookupInstClassUnconstrained(name);
330        if (res.successful()) { // TODO: limit to only replaceable and replaced components and their children?
331            InstNode constr = lookupConstrainingInstNode();
332            if (constr != null && !constr.memberInstClass(name).successful())
333                return InstLookupResult.<InstClassDecl>constrained(res, closestConstrainingDecl());
334        }
335        return res;
336    }
337
338    syn InstLookupResult<InstClassDecl> InstAccess.qualifiedLookupInstClassUnconstrained(String name) = 
339        InstLookupResult.notFound();
340    eq InstClassAccess.qualifiedLookupInstClassUnconstrained(String name)                             = 
341        myInstClassDecl().memberInstClass(name);
342    eq InstComponentAccess.qualifiedLookupInstClassUnconstrained(String name)                         = 
343        myInstComponentDecl().memberInstClass(name);
344    eq InstComponentArrayAccess.qualifiedLookupInstClassUnconstrained(String name)                    = 
345       lookupArrayElement(myInstComponentDecl()).memberInstClass(name);
346
347
348    eq InstClassAccess.lookupConstrainingInstNode() = 
349        inQualified() ? lookupConstrainingInstClass(name()) : lookupConstrainingInstClassHelper(null, name());
350
351    inh InstClassDecl InstAccess.lookupConstrainingInstClass(String name);
352    eq BaseNode.getChild().lookupConstrainingInstClass(String name) = null;
353    eq InstDot.getInstAccess(int i).lookupConstrainingInstClass(String name) =
354        lookupConstrainingInstClassHelper((i == 0) ? null : getInstAccessNoListTrans(i - 1), name);
355
356    syn InstClassDecl InstAccess.lookupConstrainingInstClassHelper(InstAccess part, String name) {
357        InstLookupResult<InstClassDecl> res;
358        if (part == null) {
359            res = lookupInstClass(name);
360        } else {
361            InstNode parent = part.lookupConstrainingInstNode();
362            res = (parent != null) ? parent.memberInstClass(name) : InstLookupResult.<InstClassDecl>notFound();
363        }
364        if (!res.successful())
365            return null;
366        InstClassDecl icd = res.target().resolveLib();
367        if (!icd.hasInstConstrainingClass() || !icd.isReplaceable())
368            return icd;
369        return (InstClassDecl) icd.getInstConstrainingClass().getInstNode();
370    }
371
372
373    syn InstLookupResult<InstClassDecl> InstNode.lookupInstClassInSurrounding(String name)     = lookupInstClass(name);
374    eq InstReplacingFullClassDecl.lookupInstClassInSurrounding(String name)                    = 
375        getInstClassRedeclare().lookupInstClass(name);
376    eq InstReplacingShortClassDecl.lookupInstClassInSurrounding(String name)                   = 
377        getInstClassRedeclare().lookupInstClass(name);
378
379    syn lazy InstLookupResult<InstClassDecl> InstNode.genericLookupInstClass(String name) {
380        for (InstClassDecl icd : getInstClassDecls()) 
381            if (icd.matches(name)) 
382                return InstLookupResult.found(icd);
383       
384        for (InstExtends ie : getInstExtendss()) {
385            InstLookupResult<InstClassDecl> res = ie.memberInstClass(name);
386            if (res.successful())
387                return res;
388        }
389       
390        for (InstImport ii : getInstImports()) {
391            InstLookupResult<InstClassDecl> res = ii.lookupInstClassInImport(name);
392            if (res.successful())
393                return res;
394        }
395       
396        return lookupInstClassInSurrounding(name);
397    }
398    eq InstSimpleShortClassDecl.genericLookupInstClass(String name) = actualInstClass().genericLookupInstClass(name);
399    eq InstLibNode.genericLookupInstClass(String name)              = actualInstClass().genericLookupInstClass(name);
400
401    syn InstLookupResult<InstClassDecl> InstNode.superLookupInstClass(String name) {
402        InstLookupResult<InstClassDecl> res = superLookupInstClassLocal(name);
403        return res.successful() ? res : superLookupInstClassSurrounding(name);
404    }
405
406    syn InstLookupResult<InstClassDecl> InstNode.superLookupInstClassSurrounding(String name) = lookupInstClass(name);
407    eq InstReplacingSimpleShortClassDecl.superLookupInstClass(String name)                    = getInstClassRedeclare().lookupInstClass(name);
408
409    syn InstLookupResult<InstClassDecl> InstNode.superLookupInstClassLocal(String name) {
410        for (InstImport ii : getInstImports()) {
411            InstLookupResult<InstClassDecl> res = ii.lookupInstClassInImport(name);
412            if (res.successful())
413                return res;
414        }
415       
416        for (InstClassDecl icd : getInstClassDecls()) {
417            if (icd.matches(name)) {
418                return InstLookupResult.found(icd);
419            }
420        }
421       
422        return InstLookupResult.notFound();
423    }
424    eq InstSimpleShortClassDecl.superLookupInstClassLocal(String name) = actualInstClass().superLookupInstClassLocal(name);
425    eq InstLibNode.superLookupInstClassLocal(String name)              = actualInstClass().superLookupInstClassLocal(name);
426
427    syn InstLookupResult<InstClassDecl> InstComponentDecl.genericLookupInstClass(String name) {
428        InstLookupResult<InstClassDecl> res = memberInstClass(name);
429        if (res.successful())
430            return res;
431       
432        for (InstImport ii : getInstImports()) {
433            res = ii.lookupInstClassInImport(name);
434            if (res.successful())
435                return res;
436        }
437       
438        return myInstClass().lookupInstClassInSurrounding(name);
439    }
440
441    syn boolean InstClassDecl.isRedeclaredNonSimple()      = false;
442    eq InstReplacingShortClassDecl.isRedeclaredNonSimple() = true;
443    eq InstReplacingFullClassDecl.isRedeclaredNonSimple()  = true;
444
445    syn InstLookupResult<InstClassDecl> InstComponentDecl.superLookupInstClassInComponent(String name) {
446        // TODO: Why do we do this? Seems to be needed, as tests fail without it
447        if (myInstClass().isRedeclaredNonSimple())
448            return myInstClass().lookupInstClassInInstClassRedeclare(name);
449       
450        for (InstImport ii : getInstImports()) {
451            InstLookupResult<InstClassDecl> res = ii.lookupInstClassInImport(name);
452            if (res.successful())
453                return res;
454        }
455       
456        for (InstClassDecl icd : getInstClassDecls()) 
457            if (icd.matches(name)) 
458                return InstLookupResult.found(icd);
459   
460        return myInstClass().superLookupInstClass(name);
461    }
462
463
464    syn lazy InstLookupResult<InstClassDecl> InstExtends.genericLookupInstClassInExtends(String name) {
465        for (InstClassDecl icd : getInstClassDecls()) 
466            if (icd.matches(name)) 
467                return InstLookupResult.found(icd);
468       
469        for (InstExtends ie : getInstExtendss()) {
470            InstLookupResult<InstClassDecl> res = ie.memberInstClass(name);
471            if (res.successful())
472                return res;
473        }
474       
475        return myInstClass().genericLookupInstClass(name);
476    }
477
478    syn InstLookupResult<InstClassDecl> InstExtends.superLookupInstClassInExtends(String name) {
479        for (InstClassDecl icd : getInstClassDecls()) 
480            if (icd.matches(name)) 
481                return InstLookupResult.found(icd);
482       
483        return myInstClass().superLookupInstClass(name);
484    }
485
486
487    syn InstLookupResult<InstClassDecl> InstNode.memberInstClass(String name) = InstLookupResult.notFound();
488    eq InstFullClassDecl.memberInstClass(String name) {
489        for (InstClassDecl icd : getInstClassDecls()) 
490            if (icd.matches(name)) 
491                return InstLookupResult.found(findInnerClassIfAny(icd));
492       
493        for (InstExtends ie : getInstExtendss()) {
494            InstLookupResult<InstClassDecl> res = ie.memberInstClass(name);
495            if (res.successful())
496                return res;
497        }
498       
499        return InstLookupResult.notFound();
500    }
501
502    eq InstShortClassDecl.memberInstClass(String name)       = getInstExtends(0).memberInstClass(name);
503    eq InstSimpleShortClassDecl.memberInstClass(String name) = actualInstClass().memberInstClass(name);
504    eq InstLibNode.memberInstClass(String name)              = actualInstClass().memberInstClass(name);
505
506    eq InstExtends.memberInstClass(String name) {
507        for (InstClassDecl icd : getInstClassDecls()) 
508            if (icd.matches(name)) 
509                return InstLookupResult.found(icd);
510       
511        for (InstExtends ie : getInstExtendss()) {
512            InstLookupResult<InstClassDecl> res = ie.memberInstClass(name);
513            if (res.successful())
514                return res;
515        }
516       
517        return InstLookupResult.notFound();
518    }
519
520    /**
521     * Returns the InstComponentDecl representing the first cell of the array.
522     *
523     * @param ndims  the number of dimensions of the array.
524     */
525    syn InstComponentDecl InstComponentDecl.arrayCellInstComponent(int ndims) {
526        if (ndims == 0) 
527            return this;
528        if (getNumInstComponentDecl() == 0)
529            return unknownInstComponentDecl();
530        return getInstComponentDecl(0).arrayCellInstComponent(ndims - 1);
531    }
532
533    eq InstComponentDecl.memberInstClass(String name) {
534        if (isArray() && !isPrimitive()) {
535            return arrayCellInstComponent(ndims()).memberInstClass(name);
536        } else {
537            for (InstClassDecl icd : getInstClassDecls()) 
538                if (icd.matches(name)) 
539                    return InstLookupResult.found(findInnerClassIfAny(icd));
540           
541            for (InstExtends ie : getInstExtendss()) {
542                InstLookupResult<InstClassDecl> res = ie.memberInstClass(name);
543                if (res.successful())
544                    return res;
545            }
546           
547            return InstLookupResult.notFound();
548        }
549    }
550
551    /**
552     * If icd is in an outer component, try to find corresponding class in inner decl.
553     *
554     * If inner decl isn't found, return icd to avoid extra error messages.
555     */
556    public InstClassDecl InstNode.findInnerClassIfAny(InstClassDecl icd) {
557        if (icd.inOrIsOuter()) {
558            InstClassDecl inner = icd.myInnerInstClassDecl();
559            if (inner != null) 
560                icd = inner;
561        }
562        return icd;
563    }
564
565    eq InstClassDecl.matches(String str) = name().equals(str);
566    eq InstLibNode.matches(String str) {
567        if (name().equalsIgnoreCase(str)) {
568            resolveLib();
569        }
570        return name().equals(str);
571    }
572
573    syn InstClassDecl InstAccess.myInstClassDecl() = unknownInstClassDecl();
574    eq InstDot.myInstClassDecl()          = getLastInstAccess().myInstClassDecl();
575    eq InstGlobalAccess.myInstClassDecl() = getInstAccess().myInstClassDecl();
576    syn InstClassDecl InstClassAccess.myInstClassDecl() = myInstLookup().target(INST_UNKNOWN_CLASS, this).resolveLib();
577   
578    syn lazy InstLookupResult<InstClassDecl> InstClassAccess.myInstLookup() {
579        // If we return back during same lookup, return unknown to avoid infinite loop
580        if (isInMyInstClassDecl) {
581            return InstLookupResult.notFound();
582        }
583        isInMyInstClassDecl = true;
584        InstLookupResult<InstClassDecl> res = myInstLookupClass();
585        isInMyInstClassDecl = false;
586        return res;
587    }
588   
589    private boolean InstClassAccess.isInMyInstClassDecl = false;
590   
591    syn InstLookupResult<InstClassDecl> InstAccess.myInstLookupClass() = lookupInstClass(name());
592
593    syn InstClassDecl FAbstractFunctionCall.myInstClassDecl() = null;
594    eq InstFunctionCall.myInstClassDecl()                     = getName().myInstClassDecl(); 
595    eq InstRecordConstructor.myInstClassDecl()                = getRecord().myInstClassDecl(); 
596
597    syn InstClassDecl InstNode.myInstClass()  = unknownInstClassDecl(); 
598    eq InstComponentDecl.myInstClass()        = getClassName().myInstClassDecl();
599    eq InstArrayComponentDecl.myInstClass()   = instComponentDecl().myInstClass();
600    //eq InstShortClassDecl.myInstClass()       = getClassName().myInstClassDecl();
601    eq InstClassDecl.myInstClass()            = this;
602    eq InstExtends.myInstClass()              = getClassName().myInstClassDecl();
603    eq UnknownInstComponentDecl.myInstClass() = unknownInstClassDecl();
604   
605    protected static final InstLookupResult.DefaultGenerator<InstCallable> ASTNode.INST_UNKNOWN_CALLABLE = 
606            new InstLookupResult.DefaultGenerator<InstCallable>() {
607        public InstCallable generate(ASTNode src) {
608            return src.unknownInstClassDecl();
609        }
610    };
611
612}
613
614aspect InstLookupImport {
615
616    eq InstImport.getPackageName().lookupInstClass(String name) = lookupInstClassFromTop(name);
617
618    syn lazy InstClassDecl InstImport.getImportedClass() {
619        return getPackageName().myInstClassDecl();
620    }
621
622    syn InstLookupResult<InstClassDecl> InstImport.lookupInstClassInImport(String name) {
623        if (name.equals(name())) { 
624            InstClassDecl icd = getImportedClass();
625            if (!icd.isUnknown()) 
626                return InstLookupResult.found(icd);
627        }
628        return InstLookupResult.notFound();
629    }
630
631    eq InstImportUnqualified.lookupInstClassInImport(String name)  {
632        return getImportedClass().memberInstClass(name);
633    }
634
635}
636
637aspect InstLookupClassesInModifications {
638
639    eq InstElementModification.getName().lookupInstClass(String name) = lookupInstClassInInstElement(name);
640    eq InstClassRedeclare.getName().lookupInstClass(String name)      = lookupInstClassInInstElement(name);
641
642    /**
643     * This attribute defines the lookup mechanism for left hand class references in modifications.
644     * They are looked up in the element that the modification is attached to, not the surrounding scope.
645     */
646    inh InstLookupResult<InstClassDecl> InstElementModification.lookupInstClassInInstElement(String name);
647    inh InstLookupResult<InstClassDecl> InstClassRedeclare.lookupInstClassInInstElement(String name);
648
649    eq InstArrayComponentDecl.getInstModification().lookupInstClassInInstElement(String name)  = instComponentDecl().memberInstClass(name);
650    eq InstComponentDecl.getInstModification().lookupInstClassInInstElement(String name)       = memberInstClass(name);
651    eq InstElementModification.getInstModification().lookupInstClassInInstElement(String name) = getName().myInstComponentDecl().memberInstClass(name);
652    eq InstNormalExtends.getInstClassModification().lookupInstClassInInstElement(String name)  = memberInstClass(name);
653    eq InstConstraining.getInstClassModification().lookupInstClassInInstElement(String name)   = getInstNode().memberInstClass(name);
654    eq InstRoot.getChild().lookupInstClassInInstElement(String name)                           = InstLookupResult.notFound();
655    eq FlatRoot.getChild().lookupInstClassInInstElement(String name)                           = InstLookupResult.notFound();
656       
657}
658
659aspect SimpleInstClassLookup {
660
661    /**
662     * This method offers a simplified way of looking up qualified class names
663     * in the instance class structure.
664     *
665     * @param name A string containing a qualified name, for example 'A.B.C'.
666     */
667    syn lazy InstClassDecl InstProgramRoot.simpleLookupInstClassDecl(String name) = 
668        simpleLookupInstClassDeclRecursive(name);
669
670    public InstClassDecl InstNode.simpleLookupInstClassDeclRecursive(String name) {
671        String[] parts = name.split("\\.", 2);
672        InstClassDecl icd = findMatching(allInstClassDecls(), parts[0]);
673        if (icd != null) {
674            return icd = (parts.length == 1) ? icd : icd.actualInstClass().simpleLookupInstClassDeclRecursive(parts[1]);
675        } else {
676            return unknownInstClassDecl();
677        }
678    }
679
680    public InstClassDecl InstProgramRoot.simpleLookupInstClassDeclRecursive(String name) {
681        String[] parts = name.split("\\.", 2);
682        InstClassDecl icd = findMatching(getInstClassDecls(), parts[0]);
683        if (icd == null) {
684            InstLookupResult<InstClassDecl> result = lookupLibrary(parts[0]);
685            if (result.successful()) {
686                icd = result.target();
687            }
688        }
689        if (icd != null) {
690            return icd = (parts.length == 1) ? icd : icd.actualInstClass().simpleLookupInstClassDeclRecursive(parts[1]);
691        } else {
692            return unknownInstClassDecl();
693        }
694    }
695
696    /**
697     * Look up qualified class names in the instance class structure.
698     *
699     * @param name  a qualified name, for example 'A.B.C'
700     */
701    syn InstLookupResult<InstClassDecl> InstNode.lookupInstClassQualified(String name) {
702        return lookupInstClassQualified(name, false);
703    }
704
705    /**
706     * Look up qualified class names in the instance class structure.
707     *
708     * @param name  a qualified name, for example 'A.B.C'
709     */
710    syn InstLookupResult<InstClassDecl> InstNode.lookupInstClassQualifiedGlobal(String name) {
711        return lookupInstClassQualified(name, true);
712    }
713
714    /**
715     * Look up qualified class names in the instance class structure.
716     *
717     * @param name    a qualified name, for example 'A.B.C'
718     * @param global  should the lookup start in the global scope?
719     */
720    syn InstLookupResult<InstClassDecl> InstNode.lookupInstClassQualified(String name, boolean global) {
721        String[] parts = name.split("\\.");
722        InstNode icd = this;
723        InstLookupResult<InstClassDecl> res = null;
724        boolean first = true;
725        for (String part : parts) {
726            res = icd.lookupInstClassQualifiedPart(part, first, global);
727            if (!res.successful())
728                return res;
729            icd = res.target().resolveLib();
730            first = false;
731        }
732        return res;
733    }
734
735    syn InstLookupResult<InstClassDecl> InstNode.lookupInstClassQualifiedPart(
736            String name, boolean first, boolean global) {
737        if (!first) {
738            return memberInstClass(name);
739        } else if (global) {
740            return lookupInstClassFromTop(name);
741        } else {
742            return lookupInstClass(name);
743        }
744    }
745    eq InstProgramRoot.lookupInstClassQualifiedPart(String name, boolean first, boolean global) = 
746        genericLookupInstClass(name);
747
748    syn InstLookupResult<InstClassDecl> InstModification.lookupInstClassQualified(String name) = myInstNode().lookupInstClassQualified(name);
749}
750
751
752aspect EnumLookup {
753
754    eq InstEnumClassDecl.getChild().lookupInstClass(String name) = lookupInstBuiltInClass(name);
755
756    inh InstLookupResult<InstClassDecl> InstEnumClassDecl.lookupInstBuiltInClass(String name);
757    eq InstRoot.getChild().lookupInstBuiltInClass(String name) = InstLookupResult.notFound();
758    eq FlatRoot.getChild().lookupInstBuiltInClass(String name) = InstLookupResult.notFound();
759    eq InstProgramRoot.getChild().lookupInstBuiltInClass(String name) {
760        for (InstClassDecl bcd : getInstBuiltInTypes()) {
761            if (bcd.matches(name))
762                return InstLookupResult.found(bcd); 
763        }
764       
765        return InstLookupResult.notFound();
766    }
767
768}
Note: See TracBrowser for help on using the repository browser.