001    /*
002     * The JastAdd Extensible Java Compiler (http://jastadd.org) is covered
003     * by the modified BSD License. You should have received a copy of the
004     * modified BSD license with this compiler.
005     * 
006     * Copyright (c) 2005-2008, Torbjorn Ekman
007     * All rights reserved.
008     */
009    
010    aspect SyntacticClassification {
011      // 6.5.1 Syntactic Classification of Name According to Context
012    
013      // Replace the parsed name with a name reclassified according to context
014      // This is done upon first access to a name node
015      rewrite ParseName {
016        to Access nameType().reclassify(name(), start, end);
017      }
018    
019      // The syntactic classification context
020      inh NameType Expr.nameType();
021      inh NameType BodyDecl.nameType();
022      
023      // NameType is basically an Enum for the different kinds of names
024      // The factory method reclassify builds name nodes of a particular kind
025      class NameType {
026        private NameType() {
027          super();
028        }
029        public static final NameType NO_NAME = new NameType();
030        public static final NameType PACKAGE_NAME = new NameType() {
031          public Access reclassify(String name, int start, int end) { return new PackageAccess(name, start, end); }
032        };
033        public static final NameType TYPE_NAME = new NameType() {
034          public Access reclassify(String name, int start, int end) { return new TypeAccess(name, start, end); }
035        };
036        public static final NameType PACKAGE_OR_TYPE_NAME = new NameType() {
037          public Access reclassify(String name, int start, int end) { return new PackageOrTypeAccess(name, start, end); }
038        };
039        public static final NameType AMBIGUOUS_NAME = new NameType() {
040          public Access reclassify(String name, int start, int end) { return new AmbiguousAccess(name, start, end); }
041        };
042        public static final NameType METHOD_NAME = new NameType();
043        public static final NameType ARRAY_TYPE_NAME = new NameType();
044        public static final NameType ARRAY_READ_NAME = new NameType();
045        public static final NameType EXPRESSION_NAME = new NameType() {
046          public Access reclassify(String name, int start, int end) { return new VarAccess(name, start, end); }
047        };
048    
049        public Access reclassify(String name, int start, int end) {
050          throw new Error("Can not reclassify ParseName node " + name);
051        }
052      }
053    
054      // predNameType() defines the expected kind of name 
055      // for the left hand side in a qualified name
056      syn NameType Access.predNameType() = NameType.NO_NAME;
057      
058      // propagate predNameType() to the left hand side of a qualified name
059      eq AbstractDot.getLeft().nameType() = getRight().predNameType();
060      eq AbstractDot.predNameType() = getLeft() instanceof Access ? ((Access)getLeft()).predNameType() : NameType.NO_NAME;
061    
062      // Equations for the syntactic classification context
063      
064      eq Program.getChild().nameType() = NameType.NO_NAME;
065    
066      // Package name
067      
068      eq PackageAccess.predNameType() = NameType.PACKAGE_NAME;
069      eq CompilationUnit.getImportDecl().nameType() = NameType.PACKAGE_NAME;
070      
071      // Type Name
072      eq SingleTypeImportDecl.getAccess().nameType() = NameType.TYPE_NAME;
073      eq ClassDecl.getSuperClassAccess().nameType() = NameType.TYPE_NAME;
074      eq ClassDecl.getImplements().nameType() = NameType.TYPE_NAME;
075      eq InterfaceDecl.getSuperInterfaceId().nameType() = NameType.TYPE_NAME;
076    
077      eq FieldDecl.getTypeAccess().nameType() = NameType.TYPE_NAME;
078      eq FieldDeclaration.getTypeAccess().nameType() = NameType.TYPE_NAME;
079      eq MethodDecl.getTypeAccess().nameType() = NameType.TYPE_NAME;
080      eq MethodDecl.getParameter().nameType() = NameType.TYPE_NAME;
081      eq ConstructorDecl.getParameter().nameType() = NameType.TYPE_NAME;
082      eq MethodDecl.getException().nameType() = NameType.TYPE_NAME;
083      eq ConstructorDecl.getException().nameType() = NameType.TYPE_NAME;
084      eq VarDeclStmt.getTypeAccess().nameType() = NameType.TYPE_NAME;
085      eq VariableDeclaration.getTypeAccess().nameType() = NameType.TYPE_NAME;
086      eq BasicCatch.getParameter().nameType() = NameType.TYPE_NAME;
087      eq ArrayCreationExpr.getTypeAccess().nameType() = NameType.TYPE_NAME;
088      eq CastExpr.getTypeAccess().nameType() = NameType.TYPE_NAME;
089      eq InstanceOfExpr.getTypeAccess().nameType() = NameType.TYPE_NAME;
090    
091      eq ClassAccess.predNameType() = NameType.TYPE_NAME;
092      eq ThisAccess.predNameType() = NameType.TYPE_NAME;
093      eq SuperAccess.predNameType() = NameType.TYPE_NAME;
094      
095      // Expression Name
096      eq SuperConstructorAccess.predNameType() = NameType.EXPRESSION_NAME;
097      eq ClassInstanceExpr.predNameType() = NameType.EXPRESSION_NAME;
098      eq PostfixExpr.getOperand().nameType() = NameType.EXPRESSION_NAME;
099      eq AssignExpr.getDest().nameType() = NameType.EXPRESSION_NAME;
100      eq ArrayAccess.predNameType() = NameType.EXPRESSION_NAME;
101    
102      // Method Name
103      // The parser builds the correct node since it has a different structure
104    
105      // Package Or Type Name
106      eq TypeAccess.predNameType() = NameType.PACKAGE_OR_TYPE_NAME;
107      eq TypeImportOnDemandDecl.getAccess().nameType() = NameType.PACKAGE_OR_TYPE_NAME;
108      eq PackageOrTypeAccess.predNameType() = NameType.PACKAGE_OR_TYPE_NAME;
109    
110      // Ambiguous Name
111      eq VarAccess.predNameType() = NameType.AMBIGUOUS_NAME;
112      eq AmbiguousAccess.predNameType() = NameType.AMBIGUOUS_NAME;
113      eq MethodAccess.predNameType() = NameType.AMBIGUOUS_NAME;
114    
115      // Extras
116      eq Block.getStmt().nameType() = NameType.EXPRESSION_NAME;
117      eq ConstructorDecl.getConstructorInvocation().nameType() = NameType.EXPRESSION_NAME;
118      eq TypeDecl.getBodyDecl().nameType() = NameType.EXPRESSION_NAME;
119    
120      eq MethodAccess.getArg().nameType() = NameType.EXPRESSION_NAME;
121      eq ConstructorAccess.getArg().nameType() = NameType.EXPRESSION_NAME;
122      eq ArrayAccess.getExpr().nameType() = NameType.EXPRESSION_NAME;
123      eq ArrayTypeWithSizeAccess.getExpr().nameType() = NameType.EXPRESSION_NAME;
124    
125      eq ClassInstanceExpr.getAccess().nameType() = NameType.TYPE_NAME;
126      eq ClassInstanceExpr.getTypeDecl().nameType() = NameType.TYPE_NAME;
127      eq ClassInstanceExpr.getArg().nameType() = NameType.EXPRESSION_NAME;
128    
129      eq ConstructorAccess.predNameType() = NameType.AMBIGUOUS_NAME;
130      eq ArrayTypeAccess.predNameType() = NameType.AMBIGUOUS_NAME;
131    }