001    /* Copyright (c) 2005-2008, Torbjorn Ekman
002     *                    2011, Jesper Öqvist <jesper.oqvist@cs.lth.se>
003     * All rights reserved.
004     *
005     * Redistribution and use in source and binary forms, with or without
006     * modification, are permitted provided that the following conditions are met:
007     *
008     * 1. Redistributions of source code must retain the above copyright notice,
009     * this list of conditions and the following disclaimer.
010     *
011     * 2. Redistributions in binary form must reproduce the above copyright notice,
012     * this list of conditions and the following disclaimer in the documentation
013     * and/or other materials provided with the distribution.
014     *
015     * 3. Neither the name of the copyright holder nor the names of its
016     * contributors may be used to endorse or promote products derived from this
017     * software without specific prior written permission.
018     *
019     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
020     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
021     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
022     * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
023     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
024     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
025     * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
026     * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
027     * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
028     * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
029     * POSSIBILITY OF SUCH DAMAGE.
030     */
031    
032    aspect Variables {
033      VariableDeclaration implements Variable;
034      syn boolean VariableDeclaration.isParameter() = false;
035      // 4.5.3
036      syn boolean VariableDeclaration.isClassVariable() = false;
037      syn boolean VariableDeclaration.isInstanceVariable() = false;
038      syn boolean VariableDeclaration.isMethodParameter() = false;
039      syn boolean VariableDeclaration.isConstructorParameter() = false;
040      syn boolean VariableDeclaration.isExceptionHandlerParameter() = false;
041      syn boolean VariableDeclaration.isLocalVariable() = true;
042      // 4.5.4
043      syn boolean VariableDeclaration.isFinal() = getModifiers().isFinal();
044      syn boolean VariableDeclaration.isVolatile() = getModifiers().isVolatile();
045      syn boolean VariableDeclaration.isBlank() = !hasInit();
046      syn boolean VariableDeclaration.isStatic() = false;
047    
048      syn String VariableDeclaration.name() = getID();
049    
050      syn lazy Constant VariableDeclaration.constant() = type().cast(getInit().constant());
051    
052      FieldDeclaration implements Variable;
053      syn boolean FieldDeclaration.isParameter() = false;
054      // 4.5.3
055      syn boolean FieldDeclaration.isClassVariable() = isStatic() || hostType().isInterfaceDecl();
056      syn boolean FieldDeclaration.isInstanceVariable() = (hostType().isClassDecl() || hostType().isAnonymous() )&& !isStatic();
057      syn boolean FieldDeclaration.isMethodParameter() = false;
058      syn boolean FieldDeclaration.isConstructorParameter() = false;
059      syn boolean FieldDeclaration.isExceptionHandlerParameter() = false;
060      syn boolean FieldDeclaration.isLocalVariable() = false;
061    
062      syn boolean FieldDeclaration.isBlank() = !hasInit();
063    
064      syn String FieldDeclaration.name() = getID();
065      syn lazy Constant FieldDeclaration.constant() = type().cast(getInit().constant());
066    
067      ParameterDeclaration implements Variable;
068      syn boolean ParameterDeclaration.isParameter() = true;
069    
070      // 4.5.3
071      syn boolean ParameterDeclaration.isClassVariable() = false;
072      syn boolean ParameterDeclaration.isInstanceVariable() = false;
073      inh boolean ParameterDeclaration.isMethodParameter();
074      inh boolean ParameterDeclaration.isConstructorParameter();
075      inh boolean ParameterDeclaration.isExceptionHandlerParameter();
076      syn boolean ParameterDeclaration.isLocalVariable() = false;
077    
078      // 4.5.3
079      eq ConstructorDecl.getParameter().isMethodParameter() = false;
080      eq ConstructorDecl.getParameter().isConstructorParameter() = true;
081      eq ConstructorDecl.getParameter().isExceptionHandlerParameter() = false;
082      eq MethodDecl.getParameter().isMethodParameter() = true;
083      eq MethodDecl.getParameter().isConstructorParameter() = false;
084      eq MethodDecl.getParameter().isExceptionHandlerParameter() = false;
085      eq BasicCatch.getParameter().isMethodParameter() = false;
086      eq BasicCatch.getParameter().isConstructorParameter() = false;
087      eq BasicCatch.getParameter().isExceptionHandlerParameter() = true;
088    
089      eq Program.getChild().isMethodParameter() = false;
090      eq Program.getChild().isConstructorParameter() = false;
091      eq Program.getChild().isExceptionHandlerParameter() = false;
092    
093      // 4.5.4
094      syn boolean ParameterDeclaration.isFinal() = getModifiers().isFinal();
095      syn boolean ParameterDeclaration.isVolatile() = getModifiers().isVolatile();
096      syn boolean ParameterDeclaration.isBlank() = true;
097      syn boolean ParameterDeclaration.isStatic() = false;
098    
099      syn String ParameterDeclaration.name() = getID();
100    
101      syn boolean ParameterDeclaration.hasInit() = false;
102      syn Expr ParameterDeclaration.getInit() { throw new UnsupportedOperationException(); }
103      syn Constant ParameterDeclaration.constant() { throw new UnsupportedOperationException(); }
104    
105      syn String VariableDecl.name() = getID();
106    
107    }
108    
109    aspect VariableDeclarationTransformation {
110      // when splitting a FieldDecl into multiple FieldDeclarations, provide every FieldDeclaration with a reference
111      // to the original FieldDecl; if only a single FieldDeclaration results, no reference is stored
112      private FieldDecl FieldDeclaration.fieldDecl = null;
113      public FieldDecl FieldDeclaration.getFieldDecl() {
114        return fieldDecl;
115      }
116      public void FieldDeclaration.setFieldDecl(FieldDecl fieldDecl) {
117        this.fieldDecl = fieldDecl;
118      }
119    
120      // FieldDecl with single VariableDecl -> FieldDeclaration
121      rewrite FieldDecl {
122        when(getNumVariableDecl() == 1)
123        to FieldDeclaration {
124          FieldDeclaration decl = getVariableDecl(0).createFieldDeclarationFrom(getModifiers(), getTypeAccess());
125          decl.setStart(start); // copy location information
126          decl.setEnd(end); // copy location information
127          return decl;
128        }
129      }
130    
131      // FieldDecl with multiple VariableDecl to FieldDeclaration list.
132      rewrite FieldDecl in TypeDecl.getBodyDecl() {
133        when(getNumVariableDecl() > 1)
134        to List {
135          List varList = new List();
136          for (int j = 0; j < getNumVariableDecl(); j++) {
137            FieldDeclaration f = getVariableDecl(j).createFieldDeclarationFrom(
138                (Modifiers) getModifiers().treeCopyNoTransform(),
139                (Access) getTypeAccess().treeCopyNoTransform()
140                );
141            if (j == 0) {
142              f.setStart(start);
143            } else {
144              f.getModifiersNoTransform().clearLocations();
145              f.getTypeAccessNoTransform().clearLocations();
146            }
147            f.setFieldDecl(this);
148            varList.add(f);
149          }
150          return varList;
151        }
152      }
153    
154      public void ASTNode.clearLocations() {
155        setStart(0);
156        setEnd(0);
157        for (int i = 0; i < getNumChildNoTransform(); i++) {
158          getChildNoTransform(i).clearLocations();
159        }
160      }
161    
162    
163      syn lazy List<VariableDeclaration> VarDeclStmt.getSingleDeclList() {
164        List<VariableDeclaration> decls = new List<VariableDeclaration>();
165        for (int i = 0; i < getNumVariableDecl(); ++i) {
166          VariableDecl varDecl = getVariableDecl(i);
167          VariableDeclaration decl = varDecl.createVariableDeclarationFrom(getModifiers(), getTypeAccess());
168          decls.add(decl);
169        }
170        return decls;
171      }
172    
173      public VariableDeclaration VariableDecl.createVariableDeclarationFrom(Modifiers modifiers, Access type) {
174        // TODO should treeCopy modifiers init opt etc???
175        VariableDeclaration decl = new VariableDeclaration(
176          modifiers,
177          type.addArrayDims(getDimsList()),
178          getID(),
179          getInitOpt()
180        );
181        decl.setStart(start); // copy location information
182        decl.setEnd(end); // copy location information
183        decl.IDstart = IDstart;
184        decl.IDend = IDend;
185        return decl;
186      }
187    
188      public FieldDeclaration VariableDecl.createFieldDeclarationFrom(Modifiers modifiers, Access type) {
189        // TODO should treeCopy modifiers init opt etc???
190        FieldDeclaration decl = new FieldDeclaration(
191          modifiers,
192          type.addArrayDims(getDimsList()),
193          getID(),
194          getInitOpt()
195        );
196        decl.setStart(start); // copy location information
197        decl.setEnd(end); // copy location information
198        decl.IDstart = IDstart;
199        decl.IDend = IDend;
200        return decl;
201      }
202    }