source: branches/dev-5819/Compiler/ModelicaFrontEnd/src/jastadd/source/SimpleLookup.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: 29.3 KB
Line 
1/*
2    Copyright (C) 2011 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*/
16import org.jmodelica.util.QualifiedName;
17aspect SimpleLookup {
18    /**
19      * Warning: This is only a prototype and is currently not well tested.
20      *          Use with care.
21      */
22
23     /**
24      * Interface implemented by nodes for which the SrcClassDecl can be resolved.
25      */
26    interface ClassLookupable {
27        /**
28         * Find the SrcClassDecl for this clause or component.
29         * An unknown class is obtained in the case the SrcClassDecl can't be found.
30         */
31        public SrcClassDecl findClassDecl();
32    }
33    SrcExtendsClause implements ClassLookupable;
34    SrcComponentDecl implements ClassLookupable;
35    SrcComponentClause implements ClassLookupable;
36    SrcImportClause implements ClassLookupable;
37
38    syn SrcClassDecl SrcExtendsClause.findClassDecl()   = getSuper().findClassDecl();
39    syn SrcClassDecl SrcComponentDecl.findClassDecl()   = myComponentClause().findClassDecl();
40    syn SrcClassDecl SrcComponentClause.findClassDecl() = getClassName().findClassDecl();
41    syn SrcClassDecl SrcImportClause.findClassDecl()    = getPackageName().findClassDecl();
42
43    // Used to prevent circular lookups without the repetitions imposed by declaring attributes circular.
44    protected boolean SrcAccess.duringFindClassDecl = false;
45    protected int SrcClassDecl.duringFindClassDeclRevisits = 0;
46    protected static final int SrcClassDecl.MAX_FIND_CLASS_DECL_REVISITS = 20;
47
48    /**
49    * Find the SrcClassDecl referenced by this access.
50    */
51    syn SrcClassDecl SrcAccess.findClassDecl() = resolveAccess().getClassDecl();
52   
53    syn ResolvedAccess SrcAccess.resolveAccess();
54    syn lazy ResolvedAccess SrcNamedAccess.resolveAccess() {
55        if (duringFindClassDecl) {
56            return unknownAccess();
57        }
58        duringFindClassDecl = true;
59        try {
60            return simpleLookupHelper(getID());
61        } finally {
62            duringFindClassDecl = false;
63        }
64    }
65    eq SrcDot.resolveAccess()          = getLastAccess().resolveAccess();
66    eq SrcGlobalAccess.resolveAccess() = getSrcAccess().resolveAccess();
67
68    /**
69     * Lookup SrcClassDecl indicated by the provided name.
70     * Support lookup of both global and relative qualified names.
71     * Returns null when the class isn't found.
72     */
73    public SrcClassDecl SrcClassDecl.simpleLookupClass(String name) {
74        return simpleLookupClass(new QualifiedName(name));
75    }
76
77    /**
78     * legacy support needed for old programs. Delegates to the new method which handles all the cases.
79     */
80    syn SrcClassDecl SrcClassDecl.simpleLookupClassDotted(String name) = simpleLookupClass(name);
81    /**
82     * legacy support needed for old programs. Delegates to the new method which handles all the cases.
83     */
84    syn SrcClassDecl Program.simpleLookupClassDotted(String name) = simpleLookupClass(name);
85
86    /**
87     * Lookup the class referenced by the QualifiedName.
88     * Lookup is both uncached and only among the class members and imported.
89     * This method is intended as an entry point
90     */
91     public SrcClassDecl SrcClassDecl.LookupMyMembers(QualifiedName qName) {
92        SrcClassDecl cd = this;
93        cd = simpleLookupMemberScope(qName.next()).getClassDecl();
94
95        while (cd != null && qName.hasNext()) {
96            cd = cd.simpleLookupMemberScope(qName.next()).getClassDecl();
97            if (cd == null) {
98                return null;
99            }
100        }
101        return cd;
102    }
103
104    /**
105     * Lookup the class referenced by the QualifiedName. The QualifiedName
106     * determines if the lookup is in relative or global scope.
107     * This method is intended as an entry point
108     *
109     */
110    public SrcClassDecl SrcClassDecl.simpleLookupClass(QualifiedName qName) {
111        SrcClassDecl cd = this;
112        if (qName.isGlobal()) {
113            cd = simpleLookupGlobalScope(qName.next()).getClassDecl();
114        } else {
115            cd = simpleLookupDefaultScope(qName.next()).getClassDecl();
116        }
117
118        while (cd != null && qName.hasNext()) {
119            cd = cd.simpleLookupMemberScope(qName.next()).getClassDecl();
120            if (cd == null) {
121                return null;
122            }
123        }
124
125        if (cd.isUnknown() && !qName.isGlobal() &&
126                enclosingClassDecl() != null && !isEncapsulated()) {
127            return enclosingClassDecl().simpleLookupClass(qName.resetedCopy());
128        }
129        return cd;
130    }
131
132   /**
133    * Lookup SrcClassDecl indicated by the provided name.
134    * Support lookup of both global and relative qualified names.
135    * Returns null when the class isn't found.
136    * This method is intended as entry point.
137    */
138    public SrcClassDecl Program.simpleLookupClass(String name) {
139        QualifiedName qName = new QualifiedName(name);
140        SrcClassDecl cd = simpleLookupDefaultScope(qName.next()).getClassDecl();
141        while (cd != null && qName.hasNext()) {
142            cd = cd.simpleLookupMemberScope(qName.next()).getClassDecl();
143            if (cd == null) {
144                return null;
145            }
146        }
147        return cd;
148    }
149
150
151    syn ResolvedAccess ASTNode.unknownAccess()         = root().unknownAccess();
152    syn lazy ResolvedAccess SourceRoot.unknownAccess() = new UnknownAccess(unknownClassDecl(), unknownComponentDecl());
153   
154    public ResolvedAccess ASTNode.createResolvedAccess(SrcClassDecl decl, String context) {
155        return new ClassAccess(decl, unknownComponentDecl(), context, decl.isProtected());
156    }
157    public ResolvedAccess ASTNode.createResolvedAccess(SrcComponentDecl decl, String context) {
158        return new ComponentAccess(unknownClassDecl(), decl, context, decl.isProtected());
159    }
160
161    public abstract class ResolvedAccess {
162
163        private final SrcClassDecl classDecl;
164        private final SrcComponentDecl componentDecl;
165        private final String context;
166        private final boolean isProtected;
167       
168        public ResolvedAccess(SrcClassDecl classDecl, SrcComponentDecl componentDecl, String context, boolean isProtected) {
169            this.classDecl = classDecl;
170            this.componentDecl = componentDecl;
171            this.context = context;
172            this.isProtected = isProtected;
173        }
174       
175        public abstract String name();
176        public abstract boolean isUnknown();
177        public abstract ResolvedAccess fromContext(String context, boolean isProtected);
178        public abstract ResolvedAccess simpleLookupMemberScope(String name);
179       
180        public boolean isClassDecl() {
181            return false;
182        }
183       
184        public boolean isComponentDecl() {
185            return false;
186        }
187       
188        public SrcClassDecl getClassDecl() {
189            return classDecl;
190        }
191        public SrcComponentDecl getComponentDecl() {
192            return componentDecl;
193        }
194        public boolean isProtected() {
195            return isProtected;
196        }
197        public String qualifiedName() {
198            return context != null ? context + "." + name() : name();
199        }
200        public String globalAccess() {
201            return "." + qualifiedName();
202        }
203        public String toString() {
204            return qualifiedName();
205        }
206    }
207
208    public class UnknownAccess extends ResolvedAccess {
209       
210        public UnknownAccess(SrcClassDecl classDecl, SrcComponentDecl componentDecl) {
211            super(classDecl, componentDecl, null, false);
212        }
213
214        @Override
215        public String name() {
216            return "Unknown";
217        }
218        @Override
219        public boolean isUnknown() {
220            return true;
221        }
222        @Override
223        public ResolvedAccess fromContext(String context, boolean isProtected) {
224            return this;
225        }
226        @Override
227        public ResolvedAccess simpleLookupMemberScope(String name) {
228            return this;
229        }
230    }
231
232    public class ClassAccess extends ResolvedAccess {
233       
234        public ClassAccess(SrcClassDecl classDecl, SrcComponentDecl componentDecl, String context, boolean isProtected) {
235            super(classDecl, componentDecl, context, isProtected);
236        }
237       
238        @Override
239        public String name() {
240            return getClassDecl().name();
241        }
242       
243        @Override
244        public boolean isUnknown() {
245            return getClassDecl().isUnknown();
246        }
247       
248        @Override
249        public ResolvedAccess fromContext(String context, boolean isProtected) {
250            return new ClassAccess(getClassDecl(), getComponentDecl(), context, isProtected || isProtected());
251        }
252       
253        @Override
254        public ResolvedAccess simpleLookupMemberScope(String name) {
255            return getClassDecl().simpleLookupMemberScope(name);
256        }
257       
258        @Override
259        public boolean isClassDecl() {
260            return true;
261        }
262       
263        @Override
264        public String globalAccess() {
265            if (getClassDecl().isBuiltInClass()) {
266                return qualifiedName();
267            }
268            return super.globalAccess();
269        }
270    }
271
272    public class ComponentAccess extends ResolvedAccess {
273       
274        public ComponentAccess(SrcClassDecl classDecl, SrcComponentDecl componentDecl, String context, boolean isProtected) {
275            super(classDecl, componentDecl, context, isProtected);
276        }
277       
278        @Override
279        public String name() {
280            return getComponentDecl().name();
281        }
282       
283        @Override
284        public boolean isUnknown() {
285            return getComponentDecl().isUnknown();
286        }
287
288        @Override
289        public ResolvedAccess fromContext(String context, boolean isProtected) {
290            return new ComponentAccess(getClassDecl(), getComponentDecl(), context, isProtected || isProtected());
291        }
292
293        @Override
294        public ResolvedAccess simpleLookupMemberScope(String name) {
295            return getComponentDecl().findClassDecl().simpleLookupMemberScope(name);
296        }
297       
298        @Override
299        public boolean isComponentDecl() {
300            return true;
301        }
302    }
303
304    /**
305    * Lookup helper method for SrcAccess and SrcClassDecl. Obtain the SrcClassDecl
306    * by looking after the target class one "name" piece at a time in the correct scope.
307    */
308    inh ResolvedAccess ASTNode.simpleLookupHelper(String name);
309    eq SrcDot.getSrcNamedAccess(int i).simpleLookupHelper(String name)        = simpleLookupDot(name, i);
310    eq SrcGlobalAccess.getSrcAccess().simpleLookupHelper(String name)         = simpleLookupGlobalScope(name);
311    eq SrcArrayAccess.getSrcArraySubscripts().simpleLookupHelper(String name) = simpleLookupBypassDot(name);
312    eq SrcImportClause.getPackageName().simpleLookupHelper(String name)       = simpleLookupGlobalScope(name);
313    eq SrcExtendsClause.getSuper().simpleLookupHelper(String name)            = simpleLookupFromExtends(name);
314    eq SrcFullClassDecl.getChild().simpleLookupHelper(String name)            = simpleLookupDefaultScope(name);
315    eq Program.getChild().simpleLookupHelper(String name)                     = simpleLookupDefaultScope(name);
316    eq SrcForStmt.getChild().simpleLookupHelper(String name)                  = simpleLookupInForStmt(name);
317    eq SrcComponentDecl.getSrcModification().simpleLookupHelper(String name)  = simpleLookupFromModification(name);
318    eq SrcValueModification.getSrcExp().simpleLookupHelper(String name)       = simpleLookupFromValue(name);
319    eq SrcComponentRedeclare.getSrcComponentClause().simpleLookupHelper(String name) = simpleLookupFromValue(name);
320    eq SrcClassRedeclare.getSrcBaseClassDecl().simpleLookupHelper(String name)       = simpleLookupFromValue(name);
321    eq SrcInlineExtendsClause.getChild().simpleLookupHelper(String name)       = enclosingClassDecl().asFullClassDecl().simpleLookupInExtends(name);
322   
323    inh ResolvedAccess SrcModification.simpleLookupFromValue(String name);
324    eq SrcComponentDecl.getChild().simpleLookupFromValue(String name)         = simpleLookupHelper(name);
325    eq SrcExtendsClause.getChild().simpleLookupFromValue(String name)         = simpleLookupHelper(name);
326    eq SrcConstrainingClause.getChild().simpleLookupFromValue(String name)    = simpleLookupHelper(name);
327    eq SrcFullClassDecl.getChild().simpleLookupFromValue(String name)         = simpleLookupDefaultScope(name);
328
329    /**
330    * Lookup helper method for SrcExtendsClause. Obtain the SrcClassDecl
331    * with the given name. Has to be an unqualified classname.
332    */
333    inh ResolvedAccess SrcExtendsClause.simpleLookupFromExtends(String name);
334    eq SrcFullClassDecl.getChild().simpleLookupFromExtends(String name) = simpleLookupLocalScope(name);
335    eq Program.getChild().simpleLookupFromExtends(String name)       = simpleLookupDefaultScope(name);
336
337    /**
338    * Lookup simple name in global scope. Has to be an unqualified classname.
339    */
340    inh ResolvedAccess SrcAccess.simpleLookupGlobalScope(String name);
341    inh ResolvedAccess SrcClassDecl.simpleLookupGlobalScope(String name);
342    inh ResolvedAccess SrcImportClause.simpleLookupGlobalScope(String name);
343    eq Program.getChild().simpleLookupGlobalScope(String name) = simpleLookupDefaultScope(name);
344
345    /**
346    * Lookup simple name in global scope. Has to be an simple (unqualified) classname.
347    */
348    syn lazy ResolvedAccess Program.simpleLookupDefaultScope(String name) {
349        for (SrcStoredDefinition sd : getUnstructuredEntitys()) {
350            for (SrcClassDecl cd : sd.getSrcClassDecls()) {
351                if (cd.matches(name)) {
352                    return createResolvedAccess(cd, null);
353                }
354            }
355        }
356       
357        ResolvedAccess res = simpleLookupPredefined(name);
358        if (!res.isUnknown()) {
359            return res;
360        }
361
362        return simpleLookupInLibNodeList(getSrcLibNodes(), name);
363    }
364
365    /**
366     * Lookup in contained elements, extended classes, imports and surrounding classes.
367     * Has to be a simple (unqualified) classname.
368     * Result is Cached.
369     */
370    syn lazy ResolvedAccess SrcFullClassDecl.simpleLookupDefaultScope(String name) {
371        ResolvedAccess res = simpleLookupIncludeImports(name);
372        if (res.isUnknown()) {
373            return isEncapsulated() ? simpleLookupPredefined(name) : simpleLookupHelper(name);
374        }
375        return res;
376    }
377    syn ResolvedAccess SrcClassDecl.simpleLookupDefaultScope(String name) = simpleLookupIncludeImports(name);
378
379    /**
380     * Lookup a predefined type, function or operator in global scope. Has to be an simple (unqualified) classname.
381     */
382    inh ResolvedAccess SrcClassDecl.simpleLookupPredefined(String name);
383    eq Program.getChild().simpleLookupPredefined(String name) = simpleLookupPredefined(name);
384
385    /**
386     * Lookup a predefined type, function or operator in global scope. Has to be an simple (unqualified) classname.
387     */
388    syn ResolvedAccess Program.simpleLookupPredefined(String name) {
389        ResolvedAccess res = simpleLookupInClassList(getPredefinedTypes(), name, null);
390        if (!res.isUnknown()) {
391            return res;
392        }
393
394        res = simpleLookupInClassList(getBuiltInTypes(), name, null);
395        if (!res.isUnknown()) {
396            return res;
397        }
398
399        return simpleLookupInClassList(getBuiltInFunctions(), name, null);
400    }
401
402    /**
403     * Lookup simple name in contained classes, extends and imports but not in surrounding classes.
404     * Has to be an simple (unqualified) classname.
405     * Result is Cached.
406     */
407    syn ResolvedAccess SrcClassDecl.simpleLookupIncludeImports(String name) = simpleLookupMemberScope(name);
408    eq SrcFullClassDecl.simpleLookupIncludeImports(String name) {
409        ResolvedAccess res = simpleLookupMemberScope(name);
410        if (res.isUnknown()) {
411            res = simpleLookupInImports(name);
412        }
413        return res;
414    }
415
416    /**
417     * Lookup in contained classes, components, imports and surrounding classes.
418     * Has to be an simple (unqualified) name.
419     * Result is cached.
420     */
421    syn lazy ResolvedAccess SrcFullClassDecl.simpleLookupLocalScope(String name) {
422        if (duringFindClassDeclRevisits > MAX_FIND_CLASS_DECL_REVISITS) {
423            return unknownAccess();
424        }
425        duringFindClassDeclRevisits++;
426
427        ResolvedAccess res = simpleLookupInClassList(classes(), name, qualifiedName());
428        if (res.isUnknown()) {
429            res = simpleLookupInComponentList(components(), name, qualifiedName());
430            if (res.isUnknown()) {
431                res = simpleLookupInImports(name);
432            }
433        }
434        duringFindClassDeclRevisits--;
435        if (res.isUnknown()) {
436            return isEncapsulated() ? simpleLookupPredefined(name) : simpleLookupHelper(name);
437        }
438        return res;
439    }
440
441
442    /**
443     * Lookup in contained classes and extended classes. Has to be an unqualified classname.
444     * Internal helper method resolving a simple (unqualified) name. Result is Cached.
445     */
446    syn ResolvedAccess SrcClassDecl.simpleLookupMemberScope(String name);
447    eq SrcBadClassDecl.simpleLookupMemberScope(String name)      = unknownAccess();
448    eq SrcBuiltInClassDecl.simpleLookupMemberScope(String name)  = unknownAccess();
449    eq SrcUnknownClassDecl.simpleLookupMemberScope(String name)  = unknownAccess();
450
451    /**
452     * Lookup in contained classes, components and extended classes.
453     * Has to be an simple (unqualified) name.
454     * Method doesn't lookup in surrounding classes.
455     * This method returns the unknown class when the class isn't found.
456     * Result is Cached.
457     */
458    syn lazy ResolvedAccess SrcFullClassDecl.simpleLookupMemberScope(String name) {
459        if (duringFindClassDeclRevisits > MAX_FIND_CLASS_DECL_REVISITS) { 
460            return unknownAccess();
461        }
462        duringFindClassDeclRevisits++;
463
464        ResolvedAccess res = simpleLookupInClassList(classes(), name, qualifiedName());
465        if (res.isUnknown()) {
466            res = simpleLookupInComponentList(components(), name, qualifiedName());
467            if (res.isUnknown()) {
468                res = simpleLookupInExtends(name);
469            }
470        }
471        duringFindClassDeclRevisits--;
472        return res;
473        }
474    eq SrcLibClassDecl.simpleLookupMemberScope(String name) {
475        if (duringFindClassDeclRevisits > MAX_FIND_CLASS_DECL_REVISITS) {
476            return unknownAccess();
477        }
478        duringFindClassDeclRevisits++;
479
480
481        ResolvedAccess res = super.simpleLookupMemberScope(name);
482        if (res.isUnknown()) {
483            ResolvedAccess libRes = simpleLookupInLibNodeList(getSrcLibNodes(), name);
484            if (!libRes.isUnknown()) {
485                res = libRes;
486            }
487        }
488        duringFindClassDeclRevisits--;
489        return res;
490    }
491
492    eq SrcShortClassDecl.simpleLookupMemberScope(String name) = 
493        getSrcExtendsClauseShortClass().findClassDecl().simpleLookupMemberScope(name);
494    eq SrcLibNode.simpleLookupMemberScope(String name)        = 
495        myClass().simpleLookupMemberScope(name);
496
497    syn ResolvedAccess SrcForStmt.simpleLookupInForStmt(String name) {
498        for (SrcForIndex index : getSrcForIndexs()) {
499            SrcForIndexDecl indexDecl = index.getSrcForIndexDecl();
500            if (indexDecl.name().equals(name)) {
501                return createResolvedAccess(indexDecl, indexDecl.enclosingClassDecl().qualifiedName());
502            }
503        }
504        return simpleLookupHelper(name);
505    }
506
507    syn ResolvedAccess SrcDot.simpleLookupDot(String name, int i) {
508        if (i == 0) {
509            return simpleLookupHelper(name);
510        }
511        ResolvedAccess access = getSrcNamedAccess(i - 1).resolveAccess();
512        return access.simpleLookupMemberScope(name).fromContext(access.qualifiedName(), access.isProtected());
513    }
514
515    inh ResolvedAccess SrcAccess.simpleLookupBypassDot(String name);
516    eq BaseNode.getChild(int i).simpleLookupBypassDot(String name) = getChild(i).simpleLookupHelper(name);
517    eq SrcDot.getSrcNamedAccess().simpleLookupBypassDot(String name)    = simpleLookupHelper(name);
518
519
520    /**
521    * Internal helper method which search for the class in the imported class.
522    * Has to be an simple (unqualified) classname.
523    * Result is Cached.
524    */
525    syn ResolvedAccess SrcImportClause.simpleLookupInImport(String name) = 
526        matches(name) ? getPackageName().resolveAccess() : unknownAccess();
527    eq SrcImportClauseUnqualified.simpleLookupInImport(String name) = 
528        getPackageName().resolveAccess().simpleLookupMemberScope(name);
529
530
531    /**
532     * Internal helper method which looks for the class with the given name among this class's imported classes.
533     * Has to be an simple (unqualified) classname.
534     * This method returns the unknown class when the class isn't found.
535     * Result is Cached.
536     */
537    protected ResolvedAccess SrcFullClassDecl.simpleLookupInImports(String name) {
538        ResolvedAccess res;
539        for (SrcImportClause imp : imports()) {
540            res = imp.simpleLookupInImport(name);
541            if (!res.isUnknown()) {
542                return res;
543            }
544        }
545       
546        return unknownAccess();
547    }
548
549    /**
550     * Internal helper method which looks for the class with the given name among this class's super classes.
551     * Has to be an simple (unqualified) classname.
552     * This method returns the unknown class when the class isn't found.
553     * Result is Cached.
554     */
555    protected ResolvedAccess SrcFullClassDecl.simpleLookupInExtends(String name) {
556        ResolvedAccess res;
557        for (SrcExtendsClause superClass : superClasses()) {
558            res = superClass.findClassDecl().simpleLookupMemberScope(name);
559            if (!res.isUnknown()) {
560                return res.fromContext(qualifiedName(), superClass.isProtected());
561            }
562        }
563       
564        return unknownAccess();
565    }
566   
567   /**
568    *  Internal helper method resolving a simple (unqualified) name. Result is Cached.
569    */
570    protected ResolvedAccess SrcComponentDecl.simpleLookupFromModification(String name) {
571        ResolvedAccess res = findClassDecl().simpleLookupMemberScope(name);
572        if (!res.isUnknown()) {
573            return res.fromContext(enclosingClassDecl().qualifiedName() + "." + name(), isProtected());
574        }
575        return res;
576    }
577
578    /**
579     * Convenience method for looking up a class in a list of SrcClassDecls.
580     * Has to be an simple (unqualified) classname.
581     * This method returns null when the class isn't found.
582     */
583    public ResolvedAccess ASTNode.simpleLookupInClassList(Iterable<? extends SrcClassDecl> list, String name, String enclosingClass) {
584        for (SrcClassDecl cd : list) {
585            if (cd.matches(name)) {
586                return createResolvedAccess(cd, enclosingClass);
587            }
588        }
589        return unknownAccess();
590    }
591
592    /**
593     * Convenience method for looking up a component in a list of SrcComponentDecls.
594     * Has to be an simple (unqualified) name.
595     * This method returns null when the component isn't found.
596     */
597    public ResolvedAccess ASTNode.simpleLookupInComponentList(Iterable<? extends SrcComponentDecl> list,
598            String name, String enclosingElement) {
599        for (SrcComponentDecl cd : list) {
600            if (cd.matches(name)) {
601                return createResolvedAccess(cd, enclosingElement);
602            }
603        }
604        return unknownAccess();
605    }
606
607    /**
608     * Convenience method for looking up a class in the given list of SrcLibNodes.
609     * Has to be an simple (unqualified) classname.
610     * This method returns null when the class isn't found.
611     */
612    public ResolvedAccess ASTNode.simpleLookupInLibNodeList(List<SrcLibNode> list, String name) {
613        for (SrcLibNode ln : list) {
614            if (ln.matches(name)) {
615                return createResolvedAccess((SrcClassDecl) ln, null);
616            }
617        }
618        return unknownAccess();
619    }
620
621    /**
622     * Find if the name/identifier for this node matches the provided.
623     */
624    eq SrcIdDecl.matches(String str)                = getID().equals(str);
625    eq SrcBaseClassDecl.matches(String str)         = getName().matches(str);
626    eq SrcComponentDecl.matches(String str)         = getName().matches(str);
627    eq SrcImportClauseRename.matches(String str)    = getSrcIdDecl().matches(str);
628    eq SrcImportClauseQualified.matches(String str) = 
629        getPackageName().getLastAccess().matches(str);
630    eq SrcLibNode.matches(String str) {
631        if (name().equalsIgnoreCase(str)) {
632            myClass();
633        }
634        return name().equals(str);
635    }
636}
637
638aspect TestSimpleLookup {
639    /**
640    * Test the lookup of classes for classes in a model.
641    * This method is only for use by JUnit tests testing the simpleLookupClass functionality.
642    *
643    * The required input is pairs of class to start from and the class which should be search for in an array.
644    *
645    * The lookup result will be returned in a string with the start class and found class pairs.
646    *
647    * The classes are identified with their qualified names.
648    */ 
649    public String SourceRoot.testSimpleClassLookup(String[] lookupPairs) {
650        Program prog = getProgram();
651        StringBuilder sb=new StringBuilder();
652        for (int i = 0; i < lookupPairs.length; i += 2) {
653            SrcClassDecl scd = prog.simpleLookupClass(lookupPairs[i]);
654            SrcClassDecl foundClass = scd.simpleLookupClass(lookupPairs[i+1]);
655            sb.append(scd.qualifiedName() + "\n->\n" + foundClass.qualifiedName() + "\n\n");
656        }
657        return sb.toString();
658    }
659
660    /**
661    * Test the lookup of all extends, imports and components which can be looked up in a given class.
662    * This method is only for use by JUnit tests testing the simpleLookupClass functionality.
663    */
664    public String SourceRoot.testFindMyClassDecl(String whichClass) {
665        StringBuilder sb = new StringBuilder();
666        SrcClassDecl scd = getProgram().simpleLookupClass(whichClass);
667        if (scd.isUnknown()) {
668            throw new AssertionError("The test class " + whichClass + "can't be found using simple lookup.");
669        }
670        testLookupAllClassDecls(sb, scd);
671        return sb.toString();
672    }
673
674    /**
675    * This method is only for use by JUnit tests testing the simpleLookupClass functionality.
676    */
677    private void SourceRoot.testLookupAllClassDecls(StringBuilder sb, ASTNode node) {
678        for (Object sub : node) {
679            if (sub instanceof ClassLookupable) {
680                sb.append(sub.toString() + " : " + ((ClassLookupable) sub).findClassDecl().qualifiedName()+ "\n\n");
681            }
682            testLookupAllClassDecls(sb, (ASTNode) sub);
683        }
684    }
685
686
687    public String InstClassDecl.testSimpleLookup() {
688        SrcClassDecl sourceClass = getSrcClassDecl();
689        StringBuilder sb = new StringBuilder();
690        sourceClass.testSimpleLookup(sb, new HashSet<String>() {
691            public boolean contains(Object key) {
692                return true;
693            }
694        });
695        return sb.toString();
696    }
697
698    public String InstClassDecl.testSimpleLookup(String args) {
699        SrcClassDecl sourceClass = getSrcClassDecl();
700        StringBuilder sb = new StringBuilder();
701        sourceClass.testSimpleLookup(sb, new HashSet<>(Arrays.asList(args.split(", "))));
702        return sb.toString();
703    }
704
705    /**
706     * Returns the result of performing name lookup for all named accesses in the source tree with IDs contained in {@code arguments}.
707     * @param sb accumulates the result
708     * @param arguments the set of IDs of accesses we are looking for
709     */
710    protected void ASTNode.testSimpleLookup(StringBuilder sb, Set<String> arguments) {
711        for (ASTNode child : this) {
712            child.testSimpleLookup(sb, arguments);
713        }
714    }
715
716    @Override
717    protected void SrcNamedAccess.testSimpleLookup(StringBuilder sb, Set<String> arguments) {
718        if (arguments.contains(getID())) {
719            ResolvedAccess access = resolveAccess();
720            sb.append(getID());
721            sb.append("=");
722            sb.append(access);
723            sb.append('\n');
724        }
725    }
726
727    @Override
728    protected void SrcArrayAccess.testSimpleLookup(StringBuilder sb, Set<String> arguments) {
729        super.testSimpleLookup(sb, arguments);
730        getSrcArraySubscripts().testSimpleLookup(sb, arguments);
731    }
732
733    @Override
734    protected void SrcParseAnnotation.testSimpleLookup(StringBuilder sb, Set<String> arguments) {
735    }
736}
Note: See TracBrowser for help on using the repository browser.