import java.util.HashSet; aspect NameResolution { // ***API*** // Declaration of *decl* // *decl* refers to the appropriate declaration of the Access, // or to unknownDecl if the declaration is missing syn lazy Decl Access.decl(); // ***Implementation*** // Definitions of *decl* eq IdUse.decl() = lookup(getName()); eq Dot.decl() = getIdUse().decl(); // Definitions of *lookup* eq Program.getBlock().lookup(String name) = localLookup(name); // lookup predefined types eq Program.getPredefinedType(int index).lookup(String name) = unknownDecl(); eq Block.getBlockStmt(int index).lookup(String name) { // First, look in the local declarations if (!localLookup(name).isUnknown()) return localLookup(name); // Then, look in surrounding context return lookup(name); } eq ClassDecl.getBody().lookup(String name) { // First, look in superclass chain if (superClass() != null && !superClass().remoteLookup(name).isUnknown()) return superClass().remoteLookup(name); // Then, look in surrounding context return lookup(name); } eq Dot.getIdUse().lookup(String name) = // Do a remote lookup on the object's type. getObjectReference().decl().type().remoteLookup(name); // *remoteLookup* // Looks through declarations of this type that are accessible from outside the type // By default, there are no such declarations, so return unknownDecl. syn Decl TypeDecl.remoteLookup(String name) = unknownDecl(); // *remoteLookup* - looks through the declarations in this class and superclasses eq ClassDecl.remoteLookup(String name) { // First, look in local declarations if (!getBody().localLookup(name).isUnknown()) return getBody().localLookup(name); // Then, look in the superclass chain if (superClass() != null && !superClass().remoteLookup(name).isUnknown()) return superClass().remoteLookup(name); // Otherwise, return null object unknown return unknownDecl(); } // Expose *lookup* at various places in the AST inh Decl IdUse.lookup(String name); inh Decl Block.lookup(String name); inh Decl TypeDecl.lookup(String name); // *localLookup* - looks through the local declarations in a block syn lazy Decl Block.localLookup(String name) { for (int k = 0; k < getNumBlockStmt(); k++) { Decl d = getBlockStmt(k).declarationOf(name); if (d != null) return d; } return unknownDecl(); } syn lazy Decl Program.localLookup(String name) { for (int k = 0; k < getNumPredefinedType(); k++) { Decl d = getPredefinedType(k).declarationOf(name); if (d != null) return d; } return unknownDecl(); } syn Decl BlockStmt.declarationOf(String name) = null; eq Decl.declarationOf(String name) { if (getName().equals(name)) return this; return null; } }