Example usage for org.eclipse.jdt.core.dom Block statements

List of usage examples for org.eclipse.jdt.core.dom Block statements

Introduction

In this page you can find the example usage for org.eclipse.jdt.core.dom Block statements.

Prototype

ASTNode.NodeList statements

To view the source code for org.eclipse.jdt.core.dom Block statements.

Click Source Link

Document

The list of statements (element type: Statement ).

Usage

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;
}