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     *                    2011, Jesper Öqvist <jesper.oqvist@cs.lth.se>
008     * All rights reserved.
009     */
010    
011    aspect Variables {
012      VariableDeclaration implements Variable;
013      syn boolean VariableDeclaration.isParameter() = false;
014      // 4.5.3
015      syn boolean VariableDeclaration.isClassVariable() = false;
016      syn boolean VariableDeclaration.isInstanceVariable() = false;
017      syn boolean VariableDeclaration.isMethodParameter() = false;
018      syn boolean VariableDeclaration.isConstructorParameter() = false;
019      syn boolean VariableDeclaration.isExceptionHandlerParameter() = false;
020      syn boolean VariableDeclaration.isLocalVariable() = true;
021      // 4.5.4
022      syn boolean VariableDeclaration.isFinal() = getModifiers().isFinal();
023      syn boolean VariableDeclaration.isVolatile() = getModifiers().isVolatile();
024      syn boolean VariableDeclaration.isBlank() = !hasInit();
025      syn boolean VariableDeclaration.isStatic() = false;
026      
027      syn String VariableDeclaration.name() = getID();
028    
029      syn lazy Constant VariableDeclaration.constant() = type().cast(getInit().constant());
030    
031      FieldDeclaration implements Variable;
032      syn boolean FieldDeclaration.isParameter() = false;
033      // 4.5.3
034      syn boolean FieldDeclaration.isClassVariable() = isStatic() || hostType().isInterfaceDecl();
035      syn boolean FieldDeclaration.isInstanceVariable() = (hostType().isClassDecl() || hostType().isAnonymous() )&& !isStatic();
036      syn boolean FieldDeclaration.isMethodParameter() = false;
037      syn boolean FieldDeclaration.isConstructorParameter() = false;
038      syn boolean FieldDeclaration.isExceptionHandlerParameter() = false;
039      syn boolean FieldDeclaration.isLocalVariable() = false;
040    
041      syn boolean FieldDeclaration.isBlank() = !hasInit();
042      
043      syn String FieldDeclaration.name() = getID();
044      syn lazy Constant FieldDeclaration.constant() = type().cast(getInit().constant());
045    
046      ParameterDeclaration implements Variable;
047      syn boolean ParameterDeclaration.isParameter() = true;
048    
049      // 4.5.3
050      syn boolean ParameterDeclaration.isClassVariable() = false;
051      syn boolean ParameterDeclaration.isInstanceVariable() = false;
052      inh boolean ParameterDeclaration.isMethodParameter();
053      inh boolean ParameterDeclaration.isConstructorParameter();
054      inh boolean ParameterDeclaration.isExceptionHandlerParameter();
055      syn boolean ParameterDeclaration.isLocalVariable() = false;
056      
057      // 4.5.3
058      eq ConstructorDecl.getParameter().isMethodParameter() = false;
059      eq ConstructorDecl.getParameter().isConstructorParameter() = true;
060      eq ConstructorDecl.getParameter().isExceptionHandlerParameter() = false;
061      eq MethodDecl.getParameter().isMethodParameter() = true;
062      eq MethodDecl.getParameter().isConstructorParameter() = false;
063      eq MethodDecl.getParameter().isExceptionHandlerParameter() = false;
064      eq BasicCatch.getParameter().isMethodParameter() = false;
065      eq BasicCatch.getParameter().isConstructorParameter() = false;
066      eq BasicCatch.getParameter().isExceptionHandlerParameter() = true;
067    
068      eq Program.getChild().isMethodParameter() = false;
069      eq Program.getChild().isConstructorParameter() = false;
070      eq Program.getChild().isExceptionHandlerParameter() = false;
071      
072      // 4.5.4
073      syn boolean ParameterDeclaration.isFinal() = getModifiers().isFinal();
074      syn boolean ParameterDeclaration.isVolatile() = getModifiers().isVolatile();
075      syn boolean ParameterDeclaration.isBlank() = true;
076      syn boolean ParameterDeclaration.isStatic() = false;
077      
078      syn String ParameterDeclaration.name() = getID();
079    
080      syn boolean ParameterDeclaration.hasInit() = false;
081      syn Expr ParameterDeclaration.getInit() { throw new UnsupportedOperationException(); }
082      syn Constant ParameterDeclaration.constant() { throw new UnsupportedOperationException(); }
083    
084      syn String VariableDecl.name() = getID();
085    
086    }
087    
088    aspect VariableDeclarationTransformation {
089      // when splitting a FieldDecl into multiple FieldDeclarations, provide every FieldDeclaration with a reference
090      // to the original FieldDecl; if only a single FieldDeclaration results, no reference is stored
091      private FieldDecl FieldDeclaration.fieldDecl = null;
092      public FieldDecl FieldDeclaration.getFieldDecl() {
093          return fieldDecl;
094      }
095      public void FieldDeclaration.setFieldDecl(FieldDecl fieldDecl) {
096          this.fieldDecl = fieldDecl;
097      }
098        
099      // FieldDecl with single VariableDecl -> FieldDeclaration
100      rewrite FieldDecl {
101        when(getNumVariableDecl() == 1)
102        to FieldDeclaration {
103          FieldDeclaration decl = getVariableDecl(0).createFieldDeclarationFrom(getModifiers(), getTypeAccess());
104          decl.setStart(start); // copy location information
105          decl.setEnd(end); // copy location information
106          return decl;
107        }
108      }
109    
110      // FieldDecl with multiple VariableDecl -> FieldDeclaration+
111      rewrite FieldDecl in TypeDecl.getBodyDecl() {
112        when(getNumVariableDecl() > 1)
113        to List {
114          List varList = new List();
115          for(int j = 0; j < getNumVariableDecl(); j++) {
116            FieldDeclaration f = 
117              getVariableDecl(j).createFieldDeclarationFrom(
118                (Modifiers)getModifiers().fullCopy(),
119                (Access)getTypeAccess().fullCopy()
120              );
121            if(j == 0)
122              f.setStart(start);
123            else {
124              f.getModifiersNoTransform().clearLocations();
125              f.getTypeAccessNoTransform().clearLocations();
126            }
127            f.setFieldDecl(this);
128            varList.add(f);
129          }
130          return varList;
131        }
132      }
133    
134      public void ASTNode.clearLocations() {
135        setStart(0);
136        setEnd(0);
137        for(int i = 0; i < getNumChildNoTransform(); i++)
138          getChildNoTransform(i).clearLocations();
139      }
140         
141    
142      // VarDeclStmt with single VariableDecl -> VariableDeclaration
143      rewrite VarDeclStmt {
144        when(getNumVariableDecl() == 1)
145        to VariableDeclaration {
146          VariableDeclaration decl = getVariableDecl(0).createVariableDeclarationFrom(getModifiers(), getTypeAccess());
147          decl.setStart(start); // copy location information
148          decl.setEnd(end); // copy location information
149          return decl;
150        }
151      }
152    
153      // VarDeclStmt with multiple VariableDecl -> VariableDeclaration+
154      rewrite VarDeclStmt in Block.getStmt() {
155        when(getNumVariableDecl() > 1)
156        to List createVariableDeclarationList();
157      }
158      rewrite VarDeclStmt in ForStmt.getInitStmt() {
159        when(getNumVariableDecl() > 1)
160        to List createVariableDeclarationList();
161      }
162    
163      private List VarDeclStmt.createVariableDeclarationList() {
164        List varList = new List();
165        for(int j = 0; j < getNumVariableDecl(); j++) {
166          VariableDeclaration v =
167            getVariableDecl(j).createVariableDeclarationFrom(
168              (Modifiers)getModifiers().fullCopy(),
169              (Access)getTypeAccess().fullCopy()
170            );
171          if(j == 0)
172            v.setStart(start);
173          else {
174            v.getModifiersNoTransform().clearLocations();
175            v.getTypeAccessNoTransform().clearLocations();
176          }
177          varList.add(v);
178        }
179        return varList;
180      }
181    
182      public VariableDeclaration VariableDecl.createVariableDeclarationFrom(Modifiers modifiers, Access type) {
183        VariableDeclaration decl = new VariableDeclaration(
184          modifiers,
185          type.addArrayDims(getDimsList()),
186          getID(),
187          getInitOpt()
188        );
189        decl.setStart(start); // copy location information
190        decl.setEnd(end); // copy location information
191        decl.IDstart = IDstart;
192        decl.IDend = IDend;
193        return decl;
194      }
195    
196      public FieldDeclaration VariableDecl.createFieldDeclarationFrom(Modifiers modifiers, Access type) {
197        FieldDeclaration decl = new FieldDeclaration(
198          modifiers,
199          type.addArrayDims(getDimsList()),
200          getID(),
201          getInitOpt()
202        );
203        decl.setStart(start); // copy location information
204        decl.setEnd(end); // copy location information
205        decl.IDstart = IDstart;
206        decl.IDend = IDend;
207        return decl;
208      }
209    }