001: /**
002: *
003: */package core;
004:
005: import org.eclipse.jdt.core.dom.AST;
006: import org.eclipse.jdt.core.dom.ASTVisitor;
007: import org.eclipse.jdt.core.dom.Assignment;
008: import org.eclipse.jdt.core.dom.Block;
009: import org.eclipse.jdt.core.dom.CompilationUnit;
010: import org.eclipse.jdt.core.dom.FieldAccess;
011: import org.eclipse.jdt.core.dom.FieldDeclaration;
012: import org.eclipse.jdt.core.dom.ITypeBinding;
013: import org.eclipse.jdt.core.dom.MethodDeclaration;
014: import org.eclipse.jdt.core.dom.Modifier;
015: import org.eclipse.jdt.core.dom.PrimitiveType;
016: import org.eclipse.jdt.core.dom.ReturnStatement;
017: import org.eclipse.jdt.core.dom.SimpleType;
018: import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
019: import org.eclipse.jdt.core.dom.ThisExpression;
020: import org.eclipse.jdt.core.dom.TypeDeclaration;
021: import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
022:
023: /**
024: * This class is responsible for create a field
025: * declaration and is used by the environment entry
026: * refactoring.
027: *
028: * @author sh
029: */
030: public class CreateFieldDeclaration extends AbstractAST {
031:
032: // the Info Object containing all necessary refactor info
033: private RefactorInfo info = null;
034:
035: /**
036: * This method creates a field declaration, getter
037: * and a setter method for an EnvEntry in the compilation
038: * unit.
039: *
040: * @param info the info object containing needed info for field creation
041: */
042: public void createFieldDeclarations(RefactorInfo info) {
043: CompilationUnit u = parse(info.getUnit());
044: this .info = info;
045: new FieldCreator().process(u);
046:
047: // write changes
048: ManipulateHelper.saveDirectlyModifiedUnit(u);
049: }
050:
051: private class FieldCreator extends ASTVisitor {
052:
053: /**
054: * Looks for type declarations.
055: * For an occurence a new field declaration object
056: * will be created at the beginning of the type, followed
057: * by the getter setter method creation at the end.
058: *
059: * @param node the node to visit
060: */
061: @Override
062: public boolean visit(TypeDeclaration node) {
063: AST ast = node.getAST();
064:
065: // add the member variable
066: node.bodyDeclarations().add(0, createMemberVariable(ast));
067:
068: // add the setter
069: int size = node.bodyDeclarations().size();
070: node.bodyDeclarations().add(size, createSetter(ast));
071:
072: // add the getter
073: node.bodyDeclarations().add(size, createGetter(ast));
074: return super .visit(node);
075: }
076:
077: /**
078: * This helper method creates a member variable in
079: * the given ast.
080: *
081: * @param ast the ast in which the member variable shoudl created
082: * @return field the created member variable
083: */
084: private FieldDeclaration createMemberVariable(AST ast) {
085: // create a variable declaration and set the name
086: VariableDeclarationFragment varFrag = ast
087: .newVariableDeclarationFragment();
088: varFrag.setName(ast.newSimpleName(info.getNewVarName()));
089: FieldDeclaration field = ast.newFieldDeclaration(varFrag);
090:
091: // set the type
092: ITypeBinding binding = ast.resolveWellKnownType(info
093: .getNewName());
094: if (binding != null) {
095: // set the new type in the declaration
096: PrimitiveType.Code code = PrimitiveType.toCode(binding
097: .getName());
098: PrimitiveType primType = ast.newPrimitiveType(code);
099: field.setType(primType);
100: } else {
101: SimpleType newType = ast.newSimpleType(ast.newName(info
102: .getNewName()));
103: field.setType(newType);
104: }
105:
106: // set the modifier
107: Modifier mf = ast
108: .newModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD);
109: field.modifiers().add(mf);
110:
111: return field;
112: }
113:
114: /**
115: * This helper method creates a setter method for the
116: * member variable stored in the info object.
117: *
118: * @param ast the ast in which the setter method should be created
119: * @return md the created method
120: */
121: private MethodDeclaration createSetter(AST ast) {
122: // ************ create the method declaration **************************
123: MethodDeclaration md = ast.newMethodDeclaration();
124: md.setConstructor(false);
125: Modifier mf = ast
126: .newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
127: md.modifiers().add(mf);
128:
129: // set the method name
130: String methodName = info.getNewVarName();
131: methodName = "set"
132: + methodName.substring(0, 1).toUpperCase()
133: + methodName.substring(1, methodName.length())
134: .toLowerCase();
135: md.setName(ast.newSimpleName(methodName));
136:
137: //************ add the method parameter ********************************
138: SingleVariableDeclaration varDecl = ast
139: .newSingleVariableDeclaration();
140:
141: // set the parameter type
142: ITypeBinding binding = ast.resolveWellKnownType(info
143: .getNewName());
144: if (binding != null) {
145: PrimitiveType.Code code = PrimitiveType.toCode(binding
146: .getName());
147: PrimitiveType primType = ast.newPrimitiveType(code);
148: varDecl.setType(primType);
149: } else {
150: SimpleType newType = ast.newSimpleType(ast.newName(info
151: .getNewName()));
152: varDecl.setType(newType);
153: }
154:
155: // set the parameter name
156: varDecl.setName(ast.newSimpleName(info.getNewVarName()));
157: md.parameters().add(varDecl);
158:
159: //************ add the method body *************************************
160: Block methodBlock = ast.newBlock();
161: md.setBody(methodBlock);
162:
163: // create the setter assignment statement
164: Assignment a = ast.newAssignment();
165: a.setOperator(Assignment.Operator.ASSIGN);
166: ThisExpression this Expr = ast.newThisExpression();
167: FieldAccess fieldAccess = ast.newFieldAccess();
168: fieldAccess
169: .setName(ast.newSimpleName(info.getNewVarName()));
170: fieldAccess.setExpression(this Expr);
171: a.setLeftHandSide(fieldAccess);
172: a.setRightHandSide(ast.newSimpleName(info.getNewVarName()));
173: methodBlock.statements().add(ast.newExpressionStatement(a));
174: return md;
175: }
176:
177: /**
178: * This helper method creates a getter method for the
179: * member variable stored in the info object.
180: *
181: * @param ast the ast in which the gtter method should be created
182: * @return md the created method
183: */
184: private MethodDeclaration createGetter(AST ast) {
185: // ************ create the method declaration **************************
186: MethodDeclaration md = ast.newMethodDeclaration();
187: md.setConstructor(false);
188: Modifier mf = ast
189: .newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD);
190: md.modifiers().add(mf);
191:
192: // set the method name
193: String methodName = info.getNewVarName();
194: methodName = "get"
195: + methodName.substring(0, 1).toUpperCase()
196: + methodName.substring(1, methodName.length())
197: .toLowerCase();
198: md.setName(ast.newSimpleName(methodName));
199:
200: // set the return type
201: ITypeBinding binding = ast.resolveWellKnownType(info
202: .getNewName());
203: if (binding != null) {
204: PrimitiveType.Code code = PrimitiveType.toCode(binding
205: .getName());
206: PrimitiveType primType = ast.newPrimitiveType(code);
207: md.setReturnType2(primType);
208: } else {
209: SimpleType newType = ast.newSimpleType(ast.newName(info
210: .getNewName()));
211: md.setReturnType2(newType);
212: }
213:
214: //************ add the method body *************************************
215: Block methodBlock = ast.newBlock();
216: md.setBody(methodBlock);
217:
218: // create the return statement
219: ThisExpression this Expr = ast.newThisExpression();
220: //thisExpr.setQualifier(ast.newSimpleName(info.getNewVarName()));
221:
222: FieldAccess fieldAccess = ast.newFieldAccess();
223: fieldAccess
224: .setName(ast.newSimpleName(info.getNewVarName()));
225: fieldAccess.setExpression(this Expr);
226:
227: ReturnStatement ret = ast.newReturnStatement();
228: ret.setExpression(fieldAccess);
229: methodBlock.statements().add(ret);
230: return md;
231: }
232:
233: /**
234: * Starts the process.
235: *
236: * @param unit the AST root node. Bindings have to been resolved.
237: */
238: public void process(CompilationUnit unit) {
239: unit.accept(this);
240: }
241: }
242: }
|