001 import java.util.HashSet; 002 003 aspect NameResolution { 004 005 // ***API*** 006 007 // Declaration of *decl* 008 // *decl* refers to the appropriate declaration of the Access, 009 // or to unknownDecl if the declaration is missing 010 syn lazy Decl Access.decl(); 011 012 013 // ***Implementation*** 014 015 // Definitions of *decl* 016 eq IdUse.decl() = lookup(getName()); 017 eq Dot.decl() = getIdUse().decl(); 018 019 // Definitions of *lookup* 020 eq Program.getBlock().lookup(String name) = localLookup(name); // lookup predefined types 021 eq Program.getPredefinedType(int index).lookup(String name) = unknownDecl(); 022 023 eq Block.getBlockStmt(int index).lookup(String name) { 024 // First, look in the local declarations 025 if (!localLookup(name).isUnknown()) 026 return localLookup(name); 027 // Then, look in surrounding context 028 return lookup(name); 029 } 030 031 eq ClassDecl.getBody().lookup(String name) { 032 // First, look in superclass chain 033 034 // EMMA: alternative impl. for debugging 035 ClassDecl superClass = superClass(); 036 if (superClass != null) { 037 Decl remoteDecl = ((TypeDecl)superClass).remoteLookup(name); 038 if (remoteDecl != null) { 039 if (!remoteDecl.isUnknown()) 040 return remoteDecl; 041 } 042 } 043 return lookup(name); 044 045 046 /* 047 EMMA: old impl before debugging 048 if (superClass() != null && !superClass().remoteLookup(name).isUnknown()) 049 return superClass().remoteLookup(name); 050 // Then, look in surrounding context 051 return lookup(name); 052 */ 053 } 054 055 eq Dot.getIdUse().lookup(String name) = 056 // Do a remote lookup on the object's type. 057 getObjectReference().decl().type().remoteLookup(name); 058 059 // *remoteLookup* 060 // Looks through declarations of this type that are accessible from outside the type 061 // By default, there are no such declarations, so return unknownDecl. 062 syn Decl TypeDecl.remoteLookup(String name) = unknownDecl(); 063 064 // *remoteLookup* - looks through the declarations in this class and superclasses 065 eq ClassDecl.remoteLookup(String name) { 066 // First, look in local declarations 067 if (!getBody().localLookup(name).isUnknown()) 068 return getBody().localLookup(name); 069 // Then, look in the superclass chain 070 if (superClass() != null && superClass().remoteLookup(name) != null 071 && !superClass().remoteLookup(name).isUnknown()) 072 return superClass().remoteLookup(name); 073 // Otherwise, return null object unknown 074 return unknownDecl(); 075 } 076 077 // Expose *lookup* at various places in the AST 078 inh Decl IdUse.lookup(String name); 079 inh Decl Block.lookup(String name); 080 inh Decl TypeDecl.lookup(String name); 081 082 // *localLookup* - looks through the local declarations in a block 083 084 syn lazy Decl Block.localLookup(String name) { 085 for (int k = 0; k < getNumBlockStmt(); k++) { 086 Decl d = getBlockStmt(k).declarationOf(name); 087 if (d != null) return d; 088 } 089 return unknownDecl(); 090 } 091 092 syn lazy Decl Program.localLookup(String name) { 093 for (int k = 0; k < getNumPredefinedType(); k++) { 094 Decl d = getPredefinedType(k).declarationOf(name); 095 if (d != null) return d; 096 } 097 return unknownDecl(); 098 } 099 100 syn Decl BlockStmt.declarationOf(String name) = null; 101 eq Decl.declarationOf(String name) { 102 if (getName().equals(name)) return this; 103 return null; 104 } 105 106 }