List of usage examples for org.eclipse.jdt.core.dom Block statements
ASTNode.NodeList statements
To view the source code for org.eclipse.jdt.core.dom Block statements.
Click Source Link
From source file:org.whole.lang.visitors.JavaJavaModelGeneratorVisitor.java
License:Open Source License
public void visit(Block entity) { org.eclipse.jdt.core.dom.Block body = builder().newBlock(); for (int i = 0; i < entity.wSize(); i++) { body.statements().add(astOf((Statement) entity.wGet(i))); }// ww w . j a v a 2s . c o m setStatement(body); }
From source file:parser.AnnotationType.java
License:Open Source License
public boolean visit(Block node) { this.buffer.append(" ");//$NON-NLS-1$ this.indent++; for (Iterator it = node.statements().iterator(); it.hasNext();) { Statement s = (Statement) it.next(); this.buffer.append(strSplitCharacter); s.accept(this); this.buffer.append(strSplitCharacter); }/*from ww w . ja va2 s .c o m*/ this.indent--; printIndent(); this.buffer.append(" ");//$NON-NLS-1$ return false; }
From source file:ptolemy.backtrack.eclipse.ast.ASTFormatter.java
License:Open Source License
/** Visit an ast node, and return whether its children should be further * visited./*from ww w .jav a2s.c o m*/ * * @param node The AST node. * @return Whether its children should be further visited. */ public boolean visit(Block node) { boolean newLineAfterBlock = _newLineAfterBlock; // Indent if it is in a list of statements. if (node.getLocationInParent().isChildListProperty()) { _output(_indent); } _openBrace(); for (Iterator it = node.statements().iterator(); it.hasNext();) { Statement s = (Statement) it.next(); s.accept(this); } _checkComments((node.getStartPosition() + node.getLength()) - 1); _closeBrace(newLineAfterBlock); _newLineAfterBlock = true; return false; }
From source file:ptolemy.backtrack.eclipse.ast.transform.AssignmentTransformer.java
License:Open Source License
/** Fix the refactoring result when the set of cross-analyzed types * changes.//from ww w . ja va2s. c o m * <p> * The set of cross-analyzed types defines the growing set of types that * are analyzed in a run. Special care is taken for cross-analyzed types * because they are monitored by checkpoint objects, and * checkpoint-related extra methods are added to them. Unfortunately, it * is not possible to know all the cross-analyzed types at the beginning. * It is then necessary to fix the refactoring result when more * cross-analyzed types are discovered later. * * @param state The current state of the type analyzer. */ public void handle(TypeAnalyzerState state) { Set crossAnalyzedTypes = state.getCrossAnalyzedTypes(); Iterator crossAnalysisIter = crossAnalyzedTypes.iterator(); while (crossAnalysisIter.hasNext()) { String nextClassName = (String) crossAnalysisIter.next(); List<Block> blockList = _fixSetCheckpoint.get(nextClassName); if (blockList != null) { Iterator nodesIter = blockList.iterator(); while (nodesIter.hasNext()) { Block body = (Block) nodesIter.next(); AST ast = body.getAST(); Statement invocation = _createSetCheckpointInvocation(ast); List<Statement> statements = body.statements(); statements.add(statements.size() - 2, invocation); nodesIter.remove(); } } List<RehandleDeclarationRecord> recordList = _rehandleDeclaration.get(nextClassName); if (recordList != null) { Iterator<RehandleDeclarationRecord> recordsIter = recordList.iterator(); while (recordsIter.hasNext()) { RehandleDeclarationRecord record = recordsIter.next(); Iterator<ASTNode> extendedIter = record._getExtendedDeclarations().iterator(); while (extendedIter.hasNext()) { ASTNode declaration = extendedIter.next(); if (declaration != null) { removeNode(declaration); } } Iterator<ASTNode> fixedIter = record._getFixedDeclarations().iterator(); while (fixedIter.hasNext()) { ASTNode declaration = fixedIter.next(); if (declaration != null) { record._getBodyDeclarations().add(declaration); } } recordsIter.remove(); } } List<NodeReplace> list = _nodeSubstitution.get(nextClassName); if (list != null) { Iterator<NodeReplace> replaceIter = list.iterator(); while (replaceIter.hasNext()) { NodeReplace nodeReplace = replaceIter.next(); if (nodeReplace._getToNode() == null) { removeNode(nodeReplace._getFromNode()); } else { replaceNode(nodeReplace._getFromNode(), nodeReplace._getToNode()); } replaceIter.remove(); } } } }
From source file:ptolemy.backtrack.eclipse.ast.transform.AssignmentTransformer.java
License:Open Source License
/** Create the body of an assignment method, which backs up the field * before a new value is assigned to it. * * @param ast The {@link AST} object./*from w ww. j a v a 2 s .c o m*/ * @param state The current state of the type analyzer. * @param fieldName The name of the field. * @param fieldType The type of the left-hand side (with <tt>indices</tt> * dimensions less than the original field type). * @param indices The number of indices. * @param special Whether to handle special assign operators. * @return The body of the assignment method. */ private Block _createAssignmentBlock(AST ast, TypeAnalyzerState state, String fieldName, Type fieldType, int indices, boolean special) { Block block = ast.newBlock(); // Test if the checkpoint object is not null. IfStatement ifStatement = ast.newIfStatement(); InfixExpression testExpression = ast.newInfixExpression(); InfixExpression condition1 = ast.newInfixExpression(); condition1.setLeftOperand(ast.newSimpleName(CHECKPOINT_NAME)); condition1.setOperator(InfixExpression.Operator.NOT_EQUALS); condition1.setRightOperand(ast.newNullLiteral()); InfixExpression condition2 = ast.newInfixExpression(); MethodInvocation getTimestamp = ast.newMethodInvocation(); getTimestamp.setExpression(ast.newSimpleName(CHECKPOINT_NAME)); getTimestamp.setName(ast.newSimpleName("getTimestamp")); condition2.setLeftOperand(getTimestamp); condition2.setOperator(InfixExpression.Operator.GREATER); condition2.setRightOperand(ast.newNumberLiteral("0")); testExpression.setLeftOperand(condition1); testExpression.setOperator(InfixExpression.Operator.CONDITIONAL_AND); testExpression.setRightOperand(condition2); ifStatement.setExpression(testExpression); // The "then" branch. Block thenBranch = ast.newBlock(); // Method call to store old value. MethodInvocation recordInvocation = ast.newMethodInvocation(); recordInvocation.setExpression(ast.newSimpleName(_getRecordName(fieldName))); recordInvocation.setName(ast.newSimpleName("add")); // If there are indices, create an integer array of those indices, // and add it as an argument. if (indices == 0) { recordInvocation.arguments().add(ast.newNullLiteral()); } else { ArrayCreation arrayCreation = ast.newArrayCreation(); ArrayType arrayType = ast.newArrayType(ast.newPrimitiveType(PrimitiveType.INT)); ArrayInitializer initializer = ast.newArrayInitializer(); for (int i = 0; i < indices; i++) { initializer.expressions().add(ast.newSimpleName("index" + i)); } arrayCreation.setType(arrayType); arrayCreation.setInitializer(initializer); recordInvocation.arguments().add(arrayCreation); } // If there are indices, add them ("index0", "index1", ...) after the // field. Expression field = ast.newSimpleName(fieldName); if (indices > 0) { for (int i = 0; i < indices; i++) { ArrayAccess arrayAccess = ast.newArrayAccess(); arrayAccess.setArray(field); arrayAccess.setIndex(ast.newSimpleName("index" + i)); field = arrayAccess; } } // Set the field as the next argument. recordInvocation.arguments().add(field); // Get current timestamp from the checkpoint object. MethodInvocation timestampGetter = ast.newMethodInvocation(); timestampGetter.setExpression(ast.newSimpleName(CHECKPOINT_NAME)); timestampGetter.setName(ast.newSimpleName("getTimestamp")); // Set the timestamp as the next argument. recordInvocation.arguments().add(timestampGetter); // The statement of the method call. ExpressionStatement recordStatement = ast.newExpressionStatement(recordInvocation); thenBranch.statements().add(recordStatement); ifStatement.setThenStatement(thenBranch); block.statements().add(ifStatement); // Finally, assign the new value to the field. Assignment assignment = ast.newAssignment(); assignment.setLeftHandSide((Expression) ASTNode.copySubtree(ast, field)); assignment.setRightHandSide(ast.newSimpleName("newValue")); assignment.setOperator(Assignment.Operator.ASSIGN); // Set the checkpoint object of the new value, if necessary. Class c; try { c = fieldType.toClass(state.getClassLoader()); } catch (ClassNotFoundException e) { throw new ASTClassNotFoundException(fieldType.getName()); } if (hasMethod(c, _getSetCheckpointMethodName(false), new Class[] { Checkpoint.class }) || state.getCrossAnalyzedTypes().contains(c.getName())) { block.statements().add(_createSetCheckpointInvocation(ast)); } else { addToLists(_fixSetCheckpoint, c.getName(), block); } // Return the result of the assignment. if (special && _assignOperators.containsKey(fieldType.getName())) { String[] operators = _assignOperators.get(fieldType.getName()); SwitchStatement switchStatement = ast.newSwitchStatement(); switchStatement.setExpression(ast.newSimpleName("operator")); boolean isPostfix = true; for (int i = 0; i < operators.length; i++) { String operator = operators[i]; SwitchCase switchCase = ast.newSwitchCase(); switchCase.setExpression(ast.newNumberLiteral(Integer.toString(i))); switchStatement.statements().add(switchCase); ReturnStatement returnStatement = ast.newReturnStatement(); if (operator.equals("=")) { Assignment newAssignment = (Assignment) ASTNode.copySubtree(ast, assignment); returnStatement.setExpression(newAssignment); } else if (operator.equals("++") || operator.equals("--")) { Expression expression; if (isPostfix) { PostfixExpression postfix = ast.newPostfixExpression(); postfix.setOperand((Expression) ASTNode.copySubtree(ast, assignment.getLeftHandSide())); postfix.setOperator(PostfixExpression.Operator.toOperator(operator)); expression = postfix; // Produce prefix operators next time. if (operator.equals("--")) { isPostfix = false; } } else { PrefixExpression prefix = ast.newPrefixExpression(); prefix.setOperand((Expression) ASTNode.copySubtree(ast, assignment.getLeftHandSide())); prefix.setOperator(PrefixExpression.Operator.toOperator(operator)); expression = prefix; } returnStatement.setExpression(expression); } else { Assignment newAssignment = (Assignment) ASTNode.copySubtree(ast, assignment); newAssignment.setOperator(Assignment.Operator.toOperator(operator)); returnStatement.setExpression(newAssignment); } switchStatement.statements().add(returnStatement); } // The default statement: just return the old value. // This case should not be reached. SwitchCase defaultCase = ast.newSwitchCase(); defaultCase.setExpression(null); switchStatement.statements().add(defaultCase); ReturnStatement defaultReturn = ast.newReturnStatement(); defaultReturn.setExpression((Expression) ASTNode.copySubtree(ast, assignment.getLeftHandSide())); switchStatement.statements().add(defaultReturn); block.statements().add(switchStatement); } else { ReturnStatement returnStatement = ast.newReturnStatement(); returnStatement.setExpression(assignment); block.statements().add(returnStatement); } return block; }
From source file:ptolemy.backtrack.eclipse.ast.transform.AssignmentTransformer.java
License:Open Source License
/** Create a backup method that backs up an array (possibly with some given * indices) in memory, and return the same array to be aliased. * * @param ast The {@link AST} object.// ww w . j a va2s . c o m * @param root The root of the AST. * @param state The current state of the type analyzer. * @param fieldName The name of the field to be backed up. * @param fieldType The type of the field. * @param indices The number of indices. * @param isStatic Whether the field is static. * @return The declaration of the backup method. */ private MethodDeclaration _createBackupMethod(AST ast, CompilationUnit root, TypeAnalyzerState state, String fieldName, Type fieldType, int indices, boolean isStatic) { Class currentClass = state.getCurrentClass(); ClassLoader loader = state.getClassLoader(); String methodName = _getBackupMethodName(fieldName); // Check if the method is duplicated (possibly because the source // program is refactored twice). if (_isMethodDuplicated(currentClass, methodName, fieldType, indices, isStatic, loader, false)) { throw new ASTDuplicatedMethodException(currentClass.getName(), methodName); } // Get the type of the new value. The return value has the same // type. for (int i = 0; i < indices; i++) { try { fieldType = fieldType.removeOneDimension(); } catch (ClassNotFoundException e) { throw new ASTClassNotFoundException(fieldType); } } String fieldTypeName = fieldType.getName(); MethodDeclaration method = ast.newMethodDeclaration(); method.setName(ast.newSimpleName(methodName)); method.setReturnType2(createType(ast, getClassName(fieldTypeName, state, root))); // If the field is static, add a checkpoint object argument. if (isStatic) { // Add a "$CHECKPOINT" argument. SingleVariableDeclaration checkpoint = ast.newSingleVariableDeclaration(); String checkpointType = getClassName(Checkpoint.class, state, root); checkpoint.setType(ast.newSimpleType(createName(ast, checkpointType))); checkpoint.setName(ast.newSimpleName(CHECKPOINT_NAME)); method.parameters().add(checkpoint); } // Add all the indices. for (int i = 0; i < indices; i++) { SingleVariableDeclaration index = ast.newSingleVariableDeclaration(); index.setType(ast.newPrimitiveType(PrimitiveType.INT)); index.setName(ast.newSimpleName("index" + i)); method.parameters().add(index); } Block body = ast.newBlock(); method.setBody(body); // The first statement: backup the whole array. MethodInvocation backup = ast.newMethodInvocation(); backup.setExpression(ast.newSimpleName(_getRecordName(fieldName))); backup.setName(ast.newSimpleName("backup")); if (indices == 0) { backup.arguments().add(ast.newNullLiteral()); } else { ArrayCreation arrayCreation = ast.newArrayCreation(); ArrayType arrayType = ast.newArrayType(ast.newPrimitiveType(PrimitiveType.INT)); ArrayInitializer initializer = ast.newArrayInitializer(); for (int i = 0; i < indices; i++) { initializer.expressions().add(ast.newSimpleName("index" + i)); } arrayCreation.setType(arrayType); arrayCreation.setInitializer(initializer); backup.arguments().add(arrayCreation); } //If there are indices, add them ("index0", "index1", ...) after the // field. Expression field = ast.newSimpleName(fieldName); if (indices > 0) { for (int i = 0; i < indices; i++) { ArrayAccess arrayAccess = ast.newArrayAccess(); arrayAccess.setArray(field); arrayAccess.setIndex(ast.newSimpleName("index" + i)); field = arrayAccess; } } // Set the field as the next argument. backup.arguments().add(field); // Get current timestamp from the checkpoint object. MethodInvocation timestampGetter = ast.newMethodInvocation(); timestampGetter.setExpression(ast.newSimpleName(CHECKPOINT_NAME)); timestampGetter.setName(ast.newSimpleName("getTimestamp")); // Set the timestamp as the next argument. backup.arguments().add(timestampGetter); body.statements().add(ast.newExpressionStatement(backup)); // The second statement: return the array. ReturnStatement returnStatement = ast.newReturnStatement(); returnStatement.setExpression((Expression) ASTNode.copySubtree(ast, field)); body.statements().add(returnStatement); // If the field is static, the method is also static; the method // is also private. List modifiers = method.modifiers(); modifiers.add(ast.newModifier(Modifier.ModifierKeyword.PRIVATE_KEYWORD)); modifiers.add(ast.newModifier(Modifier.ModifierKeyword.FINAL_KEYWORD)); if (isStatic) { modifiers.add(ast.newModifier(Modifier.ModifierKeyword.STATIC_KEYWORD)); } return method; }
From source file:ptolemy.backtrack.eclipse.ast.transform.AssignmentTransformer.java
License:Open Source License
/** Create a commit method for a class, which commits its state up to the * given time./* w w w .ja va 2 s.c o m*/ * * @param ast The {@link AST} object. * @param root The root of the AST. * @param state The current state of the type analyzer. * @param fieldNames The list of all the accessed fields. * @param fieldTypes The types corresponding to the accessed fields. * @param isAnonymous Whether the current class is anonymous. * @param isInterface Whether the current type is an interface. * @return The declaration of the method that restores the old value * of all the private fields. */ private MethodDeclaration _createCommitMethod(AST ast, CompilationUnit root, TypeAnalyzerState state, List fieldNames, List fieldTypes, boolean isAnonymous, boolean isInterface) { Class currentClass = state.getCurrentClass(); Class parent = currentClass.getSuperclass(); String methodName = _getCommitMethodName(isAnonymous); // Check if the method is duplicated (possibly because the source // program is refactored twice). if (hasMethod(currentClass, methodName, new Class[] { int.class }, true)) { throw new ASTDuplicatedMethodException(currentClass.getName(), methodName); } MethodDeclaration method = ast.newMethodDeclaration(); // Set the method name. method.setName(ast.newSimpleName(methodName)); // Add a timestamp parameter. SingleVariableDeclaration timestamp = ast.newSingleVariableDeclaration(); timestamp.setType(ast.newPrimitiveType(PrimitiveType.LONG)); timestamp.setName(ast.newSimpleName("timestamp")); method.parameters().add(timestamp); // Return type default to "void". if (!isInterface) { // The method body. Block body = ast.newBlock(); method.setBody(body); // Add a call to the static commit method of FieldRecord. MethodInvocation commitFields = ast.newMethodInvocation(); commitFields.setExpression(createName(ast, getClassName(FieldRecord.class.getName(), state, root))); commitFields.setName(ast.newSimpleName("commit")); commitFields.arguments().add(ast.newSimpleName(RECORDS_NAME)); commitFields.arguments().add(ast.newSimpleName("timestamp")); MethodInvocation topTimestamp = ast.newMethodInvocation(); topTimestamp.setExpression(ast.newSimpleName(CHECKPOINT_RECORD_NAME)); topTimestamp.setName(ast.newSimpleName("getTopTimestamp")); commitFields.arguments().add(topTimestamp); body.statements().add(ast.newExpressionStatement(commitFields)); // Add a call to the commit method in the superclass, if necessary. SuperMethodInvocation superRestore = ast.newSuperMethodInvocation(); superRestore.setName(ast.newSimpleName(_getCommitMethodName(false))); superRestore.arguments().add(ast.newSimpleName("timestamp")); if ((parent != null) && (state.getCrossAnalyzedTypes().contains(parent.getName()) || hasMethod(parent, methodName, new Class[] { int.class, boolean.class }))) { body.statements().add(ast.newExpressionStatement(superRestore)); } else { // Commit the checkpoint record. MethodInvocation commitCheckpoint = ast.newMethodInvocation(); commitCheckpoint.setExpression(ast.newSimpleName(CHECKPOINT_RECORD_NAME)); commitCheckpoint.setName(ast.newSimpleName("commit")); commitCheckpoint.arguments().add(ast.newSimpleName("timestamp")); body.statements().add(ast.newExpressionStatement(commitCheckpoint)); if (parent != null) { addToLists(_nodeSubstitution, parent.getName(), new NodeReplace(commitCheckpoint, superRestore)); } } } method.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD)); return method; }
From source file:ptolemy.backtrack.eclipse.ast.transform.AssignmentTransformer.java
License:Open Source License
/** Create a get checkpoint method that returns the checkpoint object. * * @param ast The {@link AST} object.//from w ww .ja va2 s .co m * @param root The root of the AST. * @param state The current state of the type analyzer. * @param isAnonymous Whether the current class is anonymous. * @param isInterface Whether the current type is an interface. * @return The declaration of the get checkpoint method. */ private MethodDeclaration _createGetCheckpointMethod(AST ast, CompilationUnit root, TypeAnalyzerState state, boolean isAnonymous, boolean isInterface) { String methodName = _getGetCheckpointMethodName(isAnonymous); Class currentClass = state.getCurrentClass(); Class parent = currentClass.getSuperclass(); // Check if the method is duplicated (possibly because the source // program is refactored twice). if (hasMethod(currentClass, methodName, new Class[0])) { throw new ASTDuplicatedMethodException(currentClass.getName(), methodName); } if (!isAnonymous && (parent != null) && (state.getCrossAnalyzedTypes().contains(parent.getName()) || hasMethod(parent, methodName, new Class[] {}))) { return null; } MethodDeclaration method = ast.newMethodDeclaration(); method.setName(ast.newSimpleName(methodName)); String typeName = getClassName(Checkpoint.class, state, root); method.setReturnType2(createType(ast, typeName)); if (!isInterface) { // The body, just to return the checkpoint object. Block body = ast.newBlock(); method.setBody(body); ReturnStatement returnStatement = ast.newReturnStatement(); returnStatement.setExpression(ast.newSimpleName(CHECKPOINT_NAME)); body.statements().add(returnStatement); } method.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD)); if (!isInterface) { method.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.FINAL_KEYWORD)); } if (!isAnonymous && (parent != null)) { addToLists(_nodeSubstitution, parent.getName(), new NodeReplace(method, null)); } return method; }
From source file:ptolemy.backtrack.eclipse.ast.transform.AssignmentTransformer.java
License:Open Source License
/** Create a proxy class for an anonymous class. The proxy class implements * the {@link Rollbackable} interface.//from w ww . j a va2 s . c o m * * @param ast The {@link AST} object. * @param root The root of the AST. * @param state The current state of the type analyzer. * @return The type declaration of the proxy class. */ private TypeDeclaration _createProxyClass(AST ast, CompilationUnit root, TypeAnalyzerState state) { // Create the nested class. TypeDeclaration classDeclaration = ast.newTypeDeclaration(); classDeclaration.setName(ast.newSimpleName(_getProxyName())); String rollbackType = getClassName(Rollbackable.class, state, root); classDeclaration.superInterfaceTypes().add(ast.newSimpleType(createName(ast, rollbackType))); // Add a commit method. MethodDeclaration commit = ast.newMethodDeclaration(); commit.setName(ast.newSimpleName(_getCommitMethodName(false))); // Add two parameters. SingleVariableDeclaration timestamp = ast.newSingleVariableDeclaration(); timestamp.setType(ast.newPrimitiveType(PrimitiveType.LONG)); timestamp.setName(ast.newSimpleName("timestamp")); commit.parameters().add(timestamp); // Add a call to the restore method in the enclosing anonymous class. MethodInvocation invocation = ast.newMethodInvocation(); invocation.setName(ast.newSimpleName(_getCommitMethodName(true))); invocation.arguments().add(ast.newSimpleName("timestamp")); Block body = ast.newBlock(); body.statements().add(ast.newExpressionStatement(invocation)); commit.setBody(body); commit.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD)); commit.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.FINAL_KEYWORD)); classDeclaration.bodyDeclarations().add(commit); // Add a restore method. MethodDeclaration restore = ast.newMethodDeclaration(); restore.setName(ast.newSimpleName(_getRestoreMethodName(false))); // Add two parameters. timestamp = ast.newSingleVariableDeclaration(); timestamp.setType(ast.newPrimitiveType(PrimitiveType.LONG)); timestamp.setName(ast.newSimpleName("timestamp")); restore.parameters().add(timestamp); SingleVariableDeclaration trim = ast.newSingleVariableDeclaration(); trim.setType(ast.newPrimitiveType(PrimitiveType.BOOLEAN)); trim.setName(ast.newSimpleName("trim")); restore.parameters().add(trim); // Add a call to the restore method in the enclosing anonymous class. invocation = ast.newMethodInvocation(); invocation.setName(ast.newSimpleName(_getRestoreMethodName(true))); invocation.arguments().add(ast.newSimpleName("timestamp")); invocation.arguments().add(ast.newSimpleName("trim")); body = ast.newBlock(); body.statements().add(ast.newExpressionStatement(invocation)); restore.setBody(body); restore.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD)); restore.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.FINAL_KEYWORD)); classDeclaration.bodyDeclarations().add(restore); // Add a get checkpoint method. MethodDeclaration getCheckpoint = ast.newMethodDeclaration(); String checkpointType = getClassName(Checkpoint.class, state, root); getCheckpoint.setName(ast.newSimpleName(_getGetCheckpointMethodName(false))); getCheckpoint.setReturnType2(createType(ast, checkpointType)); invocation = ast.newMethodInvocation(); invocation.setName(ast.newSimpleName(_getGetCheckpointMethodName(true))); body = ast.newBlock(); ReturnStatement returnStatement = ast.newReturnStatement(); returnStatement.setExpression(invocation); body.statements().add(returnStatement); getCheckpoint.setBody(body); getCheckpoint.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD)); getCheckpoint.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.FINAL_KEYWORD)); classDeclaration.bodyDeclarations().add(getCheckpoint); // Add a set checkpoint method. MethodDeclaration setCheckpoint = ast.newMethodDeclaration(); setCheckpoint.setName(ast.newSimpleName(_getSetCheckpointMethodName(false))); setCheckpoint.setReturnType2(createType(ast, getClassName(Object.class, state, root))); // Add a single checkpoint parameter. SingleVariableDeclaration checkpoint = ast.newSingleVariableDeclaration(); checkpoint.setType(createType(ast, checkpointType)); checkpoint.setName(ast.newSimpleName("checkpoint")); setCheckpoint.parameters().add(checkpoint); // Add a call to the setcheckpoint method in the enclosing anonymous // class. invocation = ast.newMethodInvocation(); invocation.setName(ast.newSimpleName(_getSetCheckpointMethodName(true))); invocation.arguments().add(ast.newSimpleName("checkpoint")); // Return this object. returnStatement = ast.newReturnStatement(); returnStatement.setExpression(ast.newThisExpression()); body = ast.newBlock(); body.statements().add(ast.newExpressionStatement(invocation)); body.statements().add(returnStatement); setCheckpoint.setBody(body); setCheckpoint.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD)); setCheckpoint.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.FINAL_KEYWORD)); classDeclaration.bodyDeclarations().add(setCheckpoint); classDeclaration.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.FINAL_KEYWORD)); return classDeclaration; }
From source file:ptolemy.backtrack.eclipse.ast.transform.AssignmentTransformer.java
License:Open Source License
/** Create a restore method for a class, which restores all its state * variables./*from w w w . j a v a 2 s .co m*/ * * @param ast The {@link AST} object. * @param root The root of the AST. * @param state The current state of the type analyzer. * @param fieldNames The list of all the accessed fields. * @param fieldTypes The types corresponding to the accessed fields. * @param isAnonymous Whether the current class is anonymous. * @param isInterface Whether the current type is an interface. * @return The declaration of the method that restores the old value * of all the private fields. */ private MethodDeclaration _createRestoreMethod(AST ast, CompilationUnit root, TypeAnalyzerState state, List fieldNames, List fieldTypes, boolean isAnonymous, boolean isInterface) { Class currentClass = state.getCurrentClass(); Class parent = currentClass.getSuperclass(); String methodName = _getRestoreMethodName(isAnonymous); // Check if the method is duplicated (possibly because the source // program is refactored twice). if (hasMethod(currentClass, methodName, new Class[] { int.class, boolean.class }, true)) { throw new ASTDuplicatedMethodException(currentClass.getName(), methodName); } MethodDeclaration method = ast.newMethodDeclaration(); // Set the method name. method.setName(ast.newSimpleName(methodName)); // Add a timestamp parameter. SingleVariableDeclaration timestamp = ast.newSingleVariableDeclaration(); timestamp.setType(ast.newPrimitiveType(PrimitiveType.LONG)); timestamp.setName(ast.newSimpleName("timestamp")); method.parameters().add(timestamp); // Add a trim parameter. SingleVariableDeclaration trim = ast.newSingleVariableDeclaration(); trim.setType(ast.newPrimitiveType(PrimitiveType.BOOLEAN)); trim.setName(ast.newSimpleName("trim")); method.parameters().add(trim); // Return type default to "void". if (!isInterface) { // The method body. Block body = ast.newBlock(); method.setBody(body); // Create a restore statement for each managed field. Iterator namesIter = fieldNames.iterator(); Iterator typesIter = fieldTypes.iterator(); while (namesIter.hasNext()) { String fieldName = (String) namesIter.next(); Type fieldType = (Type) typesIter.next(); MethodInvocation restoreMethodCall = ast.newMethodInvocation(); restoreMethodCall.setExpression(ast.newSimpleName(_getRecordName(fieldName))); // Set the restore method name. restoreMethodCall.arguments().add(ast.newSimpleName(fieldName)); restoreMethodCall.setName(ast.newSimpleName("restore")); // Add two arguments to the restore method call. restoreMethodCall.arguments().add(ast.newSimpleName("timestamp")); restoreMethodCall.arguments().add(ast.newSimpleName("trim")); boolean isFinal = false; try { Field field = currentClass.getDeclaredField(fieldName); if (java.lang.reflect.Modifier.isFinal(field.getModifiers())) { isFinal = true; } } catch (NoSuchFieldException e) { } if (isFinal) { if ((_getAccessedField(currentClass.getName(), fieldName) != null) || !Type.isPrimitive(Type.getElementType(fieldType.getName()))) { body.statements().add(ast.newExpressionStatement(restoreMethodCall)); } } else { Expression rightHandSide; if (fieldType.isPrimitive()) { rightHandSide = restoreMethodCall; } else { CastExpression castExpression = ast.newCastExpression(); String typeName = getClassName(fieldType.getName(), state, root); castExpression.setType(createType(ast, typeName)); castExpression.setExpression(restoreMethodCall); rightHandSide = castExpression; } Assignment assignment = ast.newAssignment(); assignment.setLeftHandSide(ast.newSimpleName(fieldName)); assignment.setRightHandSide(rightHandSide); body.statements().add(ast.newExpressionStatement(assignment)); } } // Add a call to the restore method in the superclass, if necessary. SuperMethodInvocation superRestore = ast.newSuperMethodInvocation(); superRestore.setName(ast.newSimpleName(_getRestoreMethodName(false))); superRestore.arguments().add(ast.newSimpleName("timestamp")); superRestore.arguments().add(ast.newSimpleName("trim")); Statement superRestoreStatement = ast.newExpressionStatement(superRestore); if ((parent != null) && (state.getCrossAnalyzedTypes().contains(parent.getName()) || hasMethod(parent, methodName, new Class[] { int.class, boolean.class }))) { body.statements().add(superRestoreStatement); } else { // Restore the previous checkpoint, if necessary. IfStatement restoreCheckpoint = ast.newIfStatement(); InfixExpression timestampTester = ast.newInfixExpression(); timestampTester.setLeftOperand(ast.newSimpleName("timestamp")); timestampTester.setOperator(InfixExpression.Operator.LESS_EQUALS); MethodInvocation topTimestamp = ast.newMethodInvocation(); topTimestamp.setExpression(ast.newSimpleName(CHECKPOINT_RECORD_NAME)); topTimestamp.setName(ast.newSimpleName("getTopTimestamp")); timestampTester.setRightOperand(topTimestamp); restoreCheckpoint.setExpression(timestampTester); Block restoreBlock = ast.newBlock(); restoreCheckpoint.setThenStatement(restoreBlock); // Assign the old checkpoint. Assignment assignCheckpoint = ast.newAssignment(); assignCheckpoint.setLeftHandSide(ast.newSimpleName(CHECKPOINT_NAME)); MethodInvocation restoreCheckpointInvocation = ast.newMethodInvocation(); restoreCheckpointInvocation.setExpression(ast.newSimpleName(CHECKPOINT_RECORD_NAME)); restoreCheckpointInvocation.setName(ast.newSimpleName("restore")); restoreCheckpointInvocation.arguments().add(ast.newSimpleName(CHECKPOINT_NAME)); restoreCheckpointInvocation.arguments().add(_createRollbackableObject(ast, isAnonymous)); restoreCheckpointInvocation.arguments().add(ast.newSimpleName("timestamp")); restoreCheckpointInvocation.arguments().add(ast.newSimpleName("trim")); assignCheckpoint.setRightHandSide(restoreCheckpointInvocation); restoreBlock.statements().add(ast.newExpressionStatement(assignCheckpoint)); // Pop the old states. MethodInvocation popStates = ast.newMethodInvocation(); String recordType = getClassName(FieldRecord.class, state, root); popStates.setExpression(createName(ast, recordType)); popStates.setName(ast.newSimpleName("popState")); popStates.arguments().add(ast.newSimpleName(RECORDS_NAME)); restoreBlock.statements().add(ast.newExpressionStatement(popStates)); // Recall the restore method. MethodInvocation recursion = ast.newMethodInvocation(); recursion.setName(ast.newSimpleName(methodName)); recursion.arguments().add(ast.newSimpleName("timestamp")); recursion.arguments().add(ast.newSimpleName("trim")); restoreBlock.statements().add(ast.newExpressionStatement(recursion)); body.statements().add(restoreCheckpoint); if (parent != null) { addToLists(_nodeSubstitution, parent.getName(), new NodeReplace(restoreCheckpoint, superRestoreStatement)); } } } method.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD)); return method; }