source: trunk/Compiler/ModelicaFrontEnd/src/jastadd/source/SimpleLookup.jrag @ 12995

Last change on this file since 12995 was 12995, checked in by tgutzmann, 6 months ago

#5791 Fix for source-tree lookup for component names from modifications

File size: 29.0 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 a 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 a 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 SrcClassDecl classDecl;
164        private SrcComponentDecl componentDecl;
165        private String context;
166        private 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
264    public class ComponentAccess extends ResolvedAccess {
265       
266        public ComponentAccess(SrcClassDecl classDecl, SrcComponentDecl componentDecl, String context, boolean isProtected) {
267            super(classDecl, componentDecl, context, isProtected);
268        }
269       
270        @Override
271        public String name() {
272            return getComponentDecl().name();
273        }
274       
275        @Override
276        public boolean isUnknown() {
277            return getComponentDecl().isUnknown();
278        }
279
280        @Override
281        public ResolvedAccess fromContext(String context, boolean isProtected) {
282            return new ComponentAccess(getClassDecl(), getComponentDecl(), context, isProtected || isProtected());
283        }
284
285        @Override
286        public ResolvedAccess simpleLookupMemberScope(String name) {
287            return getComponentDecl().findClassDecl().simpleLookupMemberScope(name);
288        }
289       
290        @Override
291        public boolean isComponentDecl() {
292            return true;
293        }
294    }
295
296    /**
297    * Lookup helper method for SrcAccess and SrcClassDecl. Obtain the SrcClassDecl
298    * by looking after the target class one "name" piece at a time in the correct scope.
299    */
300    inh ResolvedAccess ASTNode.simpleLookupHelper(String name);
301    eq SrcDot.getSrcAccess(int i).simpleLookupHelper(String name)             = simpleLookupDot(name, i);
302    eq SrcGlobalAccess.getSrcAccess().simpleLookupHelper(String name)         = simpleLookupGlobalScope(name);
303    eq SrcArrayAccess.getSrcArraySubscripts().simpleLookupHelper(String name) = simpleLookupBypassDot(name);
304    eq SrcImportClause.getPackageName().simpleLookupHelper(String name)       = simpleLookupGlobalScope(name);
305    eq SrcExtendsClause.getSuper().simpleLookupHelper(String name)            = simpleLookupFromExtends(name);
306    eq SrcFullClassDecl.getChild().simpleLookupHelper(String name)            = simpleLookupDefaultScope(name);
307    eq Program.getChild().simpleLookupHelper(String name)                     = simpleLookupDefaultScope(name);
308    eq SrcForStmt.getChild().simpleLookupHelper(String name)                  = simpleLookupInForStmt(name);
309    eq SrcComponentDecl.getSrcModification().simpleLookupHelper(String name)  = simpleLookupFromModification(name);
310    eq SrcValueModification.getSrcExp().simpleLookupHelper(String name)       = simpleLookupFromValue(name);
311    eq SrcComponentRedeclare.getSrcComponentClause().simpleLookupHelper(String name) = simpleLookupFromValue(name);
312    eq SrcClassRedeclare.getSrcBaseClassDecl().simpleLookupHelper(String name)       = simpleLookupFromValue(name);
313    eq SrcInlineExtendsClause.getChild().simpleLookupHelper(String name)       = enclosingClassDecl().asFullClassDecl().simpleLookupInExtends(name);
314   
315    inh ResolvedAccess SrcModification.simpleLookupFromValue(String name);
316    eq SrcComponentDecl.getChild().simpleLookupFromValue(String name)         = simpleLookupHelper(name);
317    eq SrcExtendsClause.getChild().simpleLookupFromValue(String name)         = simpleLookupHelper(name);
318    eq SrcConstrainingClause.getChild().simpleLookupFromValue(String name)    = simpleLookupHelper(name);
319    eq SrcFullClassDecl.getChild().simpleLookupFromValue(String name)         = simpleLookupDefaultScope(name);
320
321    /**
322    * Lookup helper method for SrcExtendsClause. Obtain the SrcClassDecl
323    * with the given name. Has to be an unqualified classname.
324    */
325    inh ResolvedAccess SrcExtendsClause.simpleLookupFromExtends(String name);
326    eq SrcFullClassDecl.getChild().simpleLookupFromExtends(String name) = simpleLookupLocalScope(name);
327    eq Program.getChild().simpleLookupFromExtends(String name)       = simpleLookupDefaultScope(name);
328
329    /**
330    * Lookup simple name in global scope. Has to be an unqualified classname.
331    */
332    inh ResolvedAccess SrcAccess.simpleLookupGlobalScope(String name);
333    inh ResolvedAccess SrcClassDecl.simpleLookupGlobalScope(String name);
334    inh ResolvedAccess SrcImportClause.simpleLookupGlobalScope(String name);
335    eq Program.getChild().simpleLookupGlobalScope(String name) = simpleLookupDefaultScope(name);
336
337    /**
338    * Lookup simple name in global scope. Has to be an simple (unqualified) classname.
339    */
340    syn lazy ResolvedAccess Program.simpleLookupDefaultScope(String name) {
341        for (SrcStoredDefinition sd : getUnstructuredEntitys()) {
342            for (SrcClassDecl cd : sd.getSrcClassDecls()) {
343                if (cd.matches(name)) {
344                    return createResolvedAccess(cd, null);
345                }
346            }
347        }
348       
349        ResolvedAccess res = simpleLookupPredefined(name);
350        if (!res.isUnknown()) {
351            return res;
352        }
353
354        return simpleLookupInLibNodeList(getSrcLibNodes(), name);
355    }
356
357    /**
358     * Lookup in contained elements, extended classes, imports and surrounding classes.
359     * Has to be a simple (unqualified) classname.
360     * Result is Cached.
361     */
362    syn lazy ResolvedAccess SrcFullClassDecl.simpleLookupDefaultScope(String name) {
363        ResolvedAccess res = simpleLookupIncludeImports(name);
364        if (res.isUnknown()) {
365            return isEncapsulated() ? simpleLookupPredefined(name) : simpleLookupHelper(name);
366        }
367        return res;
368    }
369    syn ResolvedAccess SrcClassDecl.simpleLookupDefaultScope(String name) = simpleLookupIncludeImports(name);
370
371    /**
372     * Lookup a predefined type, function or operator in global scope. Has to be an simple (unqualified) classname.
373     */
374    inh ResolvedAccess SrcClassDecl.simpleLookupPredefined(String name);
375    eq Program.getChild().simpleLookupPredefined(String name) = simpleLookupPredefined(name);
376
377    /**
378     * Lookup a predefined type, function or operator in global scope. Has to be an simple (unqualified) classname.
379     */
380    syn ResolvedAccess Program.simpleLookupPredefined(String name) {
381        ResolvedAccess res = simpleLookupInClassList(getPredefinedTypes(), name, null);
382        if (!res.isUnknown()) {
383            return res;
384        }
385
386        res = simpleLookupInClassList(getBuiltInTypes(), name, null);
387        if (!res.isUnknown()) {
388            return res;
389        }
390
391        return simpleLookupInClassList(getBuiltInFunctions(), name, null);
392    }
393
394    /**
395     * Lookup simple name in contained classes, extends and imports but not in surrounding classes.
396     * Has to be an simple (unqualified) classname.
397     * Result is Cached.
398     */
399    syn ResolvedAccess SrcClassDecl.simpleLookupIncludeImports(String name) = simpleLookupMemberScope(name);
400    eq SrcFullClassDecl.simpleLookupIncludeImports(String name) {
401        ResolvedAccess res = simpleLookupMemberScope(name);
402        if (res.isUnknown()) {
403            res = simpleLookupInImports(name);
404        }
405        return res;
406    }
407
408    /**
409     * Lookup in contained classes, components, imports and surrounding classes.
410     * Has to be an simple (unqualified) name.
411     * Result is cached.
412     */
413    syn lazy ResolvedAccess SrcFullClassDecl.simpleLookupLocalScope(String name) {
414        if (duringFindClassDeclRevisits > MAX_FIND_CLASS_DECL_REVISITS) {
415            return unknownAccess();
416        }
417        duringFindClassDeclRevisits++;
418
419        ResolvedAccess res = simpleLookupInClassList(classes(), name, qualifiedName());
420        if (res.isUnknown()) {
421            res = simpleLookupInComponentList(components(), name, qualifiedName());
422            if (res.isUnknown()) {
423                res = simpleLookupInImports(name);
424            }
425        }
426        duringFindClassDeclRevisits--;
427        if (res.isUnknown()) {
428            return isEncapsulated() ? simpleLookupPredefined(name) : simpleLookupHelper(name);
429        }
430        return res;
431    }
432
433
434    /**
435     * Lookup in contained classes and extended classes. Has to be an unqualified classname.
436     * Internal helper method resolving a simple (unqualified) name. Result is Cached.
437     */
438    syn ResolvedAccess SrcClassDecl.simpleLookupMemberScope(String name);
439    eq SrcBadClassDecl.simpleLookupMemberScope(String name)      = unknownAccess();
440    eq SrcBuiltInClassDecl.simpleLookupMemberScope(String name)  = unknownAccess();
441    eq SrcUnknownClassDecl.simpleLookupMemberScope(String name)  = unknownAccess();
442
443    /**
444     * Lookup in contained classes, components and extended classes.
445     * Has to be an simple (unqualified) name.
446     * Method doesn't lookup in surrounding classes.
447     * This method returns the unknown class when the class isn't found.
448     * Result is Cached.
449     */
450    syn lazy ResolvedAccess SrcFullClassDecl.simpleLookupMemberScope(String name) {
451        if (duringFindClassDeclRevisits > MAX_FIND_CLASS_DECL_REVISITS) { 
452            return unknownAccess();
453        }
454        duringFindClassDeclRevisits++;
455
456        ResolvedAccess res = simpleLookupInClassList(classes(), name, qualifiedName());
457        if (res.isUnknown()) {
458            res = simpleLookupInComponentList(components(), name, qualifiedName());
459            if (res.isUnknown()) {
460                res = simpleLookupInExtends(name);
461            }
462        }
463        duringFindClassDeclRevisits--;
464        return res;
465        }
466    eq SrcLibClassDecl.simpleLookupMemberScope(String name) {
467        if (duringFindClassDeclRevisits > MAX_FIND_CLASS_DECL_REVISITS) {
468            return unknownAccess();
469        }
470        duringFindClassDeclRevisits++;
471
472
473        ResolvedAccess res = super.simpleLookupMemberScope(name);
474        if (res.isUnknown()) {
475            ResolvedAccess libRes = simpleLookupInLibNodeList(getSrcLibNodes(), name);
476            if (!libRes.isUnknown()) {
477                res = libRes;
478            }
479        }
480        duringFindClassDeclRevisits--;
481        return res;
482    }
483
484    eq SrcShortClassDecl.simpleLookupMemberScope(String name) = 
485        getSrcExtendsClauseShortClass().findClassDecl().simpleLookupMemberScope(name);
486    eq SrcLibNode.simpleLookupMemberScope(String name)        = 
487        myClass().simpleLookupMemberScope(name);
488
489    syn ResolvedAccess SrcForStmt.simpleLookupInForStmt(String name) {
490        for (SrcForIndex index : getSrcForIndexs()) {
491            SrcForIndexDecl indexDecl = index.getSrcForIndexDecl();
492            if (indexDecl.name().equals(name)) {
493                return createResolvedAccess(indexDecl, indexDecl.enclosingClassDecl().qualifiedName());
494            }
495        }
496        return simpleLookupHelper(name);
497    }
498
499    syn ResolvedAccess SrcDot.simpleLookupDot(String name, int i) {
500        if (i == 0) {
501            return simpleLookupHelper(name);
502        }
503        ResolvedAccess access = getSrcAccess(i - 1).resolveAccess();
504        return access.simpleLookupMemberScope(name).fromContext(access.qualifiedName(), access.isProtected());
505    }
506
507    inh ResolvedAccess SrcAccess.simpleLookupBypassDot(String name);
508    eq BaseNode.getChild(int i).simpleLookupBypassDot(String name) = getChild(i).simpleLookupHelper(name);
509    eq SrcDot.getSrcAccess().simpleLookupBypassDot(String name)    = simpleLookupHelper(name);
510
511
512    /**
513    * Internal helper method which search for the class in the imported class.
514    * Has to be an simple (unqualified) classname.
515    * Result is Cached.
516    */
517    syn ResolvedAccess SrcImportClause.simpleLookupInImport(String name) = 
518        matches(name) ? getPackageName().resolveAccess() : unknownAccess();
519    eq SrcImportClauseUnqualified.simpleLookupInImport(String name) = 
520        getPackageName().resolveAccess().simpleLookupMemberScope(name);
521
522
523    /**
524     * Internal helper method which looks for the class with the given name among this class's imported classes.
525     * Has to be an simple (unqualified) classname.
526     * This method returns the unknown class when the class isn't found.
527     * Result is Cached.
528     */
529    protected ResolvedAccess SrcFullClassDecl.simpleLookupInImports(String name) {
530        ResolvedAccess res;
531        for (SrcImportClause imp : imports()) {
532            res = imp.simpleLookupInImport(name);
533            if (!res.isUnknown()) {
534                return res;
535            }
536        }
537       
538        return unknownAccess();
539    }
540
541    /**
542     * Internal helper method which looks for the class with the given name among this class's super classes.
543     * Has to be an simple (unqualified) classname.
544     * This method returns the unknown class when the class isn't found.
545     * Result is Cached.
546     */
547    protected ResolvedAccess SrcFullClassDecl.simpleLookupInExtends(String name) {
548        ResolvedAccess res;
549        for (SrcExtendsClause superClass : superClasses()) {
550            res = superClass.findClassDecl().simpleLookupMemberScope(name);
551            if (!res.isUnknown()) {
552                return res.fromContext(qualifiedName(), superClass.isProtected());
553            }
554        }
555       
556        return unknownAccess();
557    }
558   
559   /**
560    *  Internal helper method resolving a simple (unqualified) name. Result is Cached.
561    */
562    protected ResolvedAccess SrcComponentDecl.simpleLookupFromModification(String name) {
563        ResolvedAccess res = findClassDecl().simpleLookupMemberScope(name);
564        if (!res.isUnknown()) {
565            return res.fromContext(enclosingClassDecl().qualifiedName() + "." + name(), isProtected());
566        }
567        return res;
568    }
569
570    /**
571     * Convenience method for looking up a class in a list of SrcClassDecls.
572     * Has to be an simple (unqualified) classname.
573     * This method returns null when the class isn't found.
574     */
575    public ResolvedAccess ASTNode.simpleLookupInClassList(Iterable<? extends SrcClassDecl> list, String name, String enclosingClass) {
576        for (SrcClassDecl cd : list) {
577            if (cd.matches(name)) {
578                return createResolvedAccess(cd, enclosingClass);
579            }
580        }
581        return unknownAccess();
582    }
583
584    /**
585     * Convenience method for looking up a component in a list of SrcComponentDecls.
586     * Has to be an simple (unqualified) name.
587     * This method returns null when the component isn't found.
588     */
589    public ResolvedAccess ASTNode.simpleLookupInComponentList(Iterable<? extends SrcComponentDecl> list,
590            String name, String enclosingElement) {
591        for (SrcComponentDecl cd : list) {
592            if (cd.matches(name)) {
593                return createResolvedAccess(cd, enclosingElement);
594            }
595        }
596        return unknownAccess();
597    }
598
599    /**
600     * Convenience method for looking up a class in the given list of SrcLibNodes.
601     * Has to be an simple (unqualified) classname.
602     * This method returns null when the class isn't found.
603     */
604    public ResolvedAccess ASTNode.simpleLookupInLibNodeList(List<SrcLibNode> list, String name) {
605        for (SrcLibNode ln : list) {
606            if (ln.matches(name)) {
607                return createResolvedAccess((SrcClassDecl) ln, null);
608            }
609        }
610        return unknownAccess();
611    }
612
613    /**
614     * Find if the name/identifier for this node matches the provided.
615     */
616    eq SrcIdDecl.matches(String str)                = getID().equals(str);
617    eq SrcBaseClassDecl.matches(String str)         = getName().matches(str);
618    eq SrcComponentDecl.matches(String str)         = getName().matches(str);
619    eq SrcImportClauseRename.matches(String str)    = getSrcIdDecl().matches(str);
620    eq SrcImportClauseQualified.matches(String str) = 
621        getPackageName().getLastAccess().matches(str);
622    eq SrcLibNode.matches(String str) {
623        if (name().equalsIgnoreCase(str)) {
624            myClass();
625        }
626        return name().equals(str);
627    }
628}
629
630aspect TestSimpleLookup {
631    /**
632    * Test the lookup of classes for classes in a model.
633    * This method is only for use by JUnit tests testing the simpleLookupClass functionality.
634    *
635    * The required input is pairs of class to start from and the class which should be search for in an array.
636    *
637    * The lookup result will be returned in a string with the start class and found class pairs.
638    *
639    * The classes are identified with their qualified names.
640    */ 
641    public String SourceRoot.testSimpleClassLookup(String[] lookupPairs) {
642        Program prog = getProgram();
643        StringBuilder sb=new StringBuilder();
644        for (int i = 0; i < lookupPairs.length; i += 2) {
645            SrcClassDecl scd = prog.simpleLookupClass(lookupPairs[i]);
646            SrcClassDecl foundClass = scd.simpleLookupClass(lookupPairs[i+1]);
647            sb.append(scd.qualifiedName() + "\n->\n" + foundClass.qualifiedName() + "\n\n");
648        }
649        return sb.toString();
650    }
651
652    /**
653    * Test the lookup of all extends, imports and components which can be looked up in a given class.
654    * This method is only for use by JUnit tests testing the simpleLookupClass functionality.
655    */
656    public String SourceRoot.testFindMyClassDecl(String whichClass) {
657        StringBuilder sb = new StringBuilder();
658        SrcClassDecl scd = getProgram().simpleLookupClass(whichClass);
659        if (scd.isUnknown()) {
660            throw new AssertionError("The test class " + whichClass + "can't be found using simple lookup.");
661        }
662        testLookupAllClassDecls(sb, scd);
663        return sb.toString();
664    }
665
666    /**
667    * This method is only for use by JUnit tests testing the simpleLookupClass functionality.
668    */
669    private void SourceRoot.testLookupAllClassDecls(StringBuilder sb, ASTNode node) {
670        for (Object sub : node) {
671            if (sub instanceof ClassLookupable) {
672                sb.append(sub.toString() + " : " + ((ClassLookupable) sub).findClassDecl().qualifiedName()+ "\n\n");
673            }
674            testLookupAllClassDecls(sb, (ASTNode) sub);
675        }
676    }
677
678
679    public String InstClassDecl.testSimpleLookup() {
680        SrcClassDecl sourceClass = getSrcClassDecl();
681        StringBuilder sb = new StringBuilder();
682        sourceClass.testSimpleLookup(sb, new HashSet<String>() {
683            public boolean contains(Object key) {
684                return true;
685            }
686        });
687        return sb.toString();
688    }
689
690    public String InstClassDecl.testSimpleLookup(String args) {
691        SrcClassDecl sourceClass = getSrcClassDecl();
692        StringBuilder sb = new StringBuilder();
693        sourceClass.testSimpleLookup(sb, new HashSet<>(Arrays.asList(args.split(", "))));
694        return sb.toString();
695    }
696
697    /**
698     * Returns the result of performing name lookup for all named accesses in the source tree with IDs contained in {@code arguments}.
699     * @param sb accumulates the result
700     * @param arguments the set of IDs of accesses we are looking for
701     */
702    protected void ASTNode.testSimpleLookup(StringBuilder sb, Set<String> arguments) {
703        for (ASTNode child : this) {
704            child.testSimpleLookup(sb, arguments);
705        }
706    }
707
708    @Override
709    protected void SrcNamedAccess.testSimpleLookup(StringBuilder sb, Set<String> arguments) {
710        if (arguments.contains(getID())) {
711            ResolvedAccess access = resolveAccess();
712            sb.append(getID());
713            sb.append("=");
714            sb.append(access);
715            sb.append('\n');
716        }
717    }
718
719    @Override
720    protected void SrcArrayAccess.testSimpleLookup(StringBuilder sb, Set<String> arguments) {
721        super.testSimpleLookup(sb, arguments);
722        getSrcArraySubscripts().testSimpleLookup(sb, arguments);
723    }
724
725    @Override
726    protected void SrcParseAnnotation.testSimpleLookup(StringBuilder sb, Set<String> arguments) {
727    }
728}
Note: See TracBrowser for help on using the repository browser.