Program: 75058
Project: 75058
Buggy source:
/** 
 * Create a restore method for a class, which restores all its state variables.
 * @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 valueof 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);
  if (hasMethod(currentClass,methodName,new Class[]{int.class,boolean.class},true))   throw new ASTDuplicatedMethodException(currentClass.getName(),methodName);
  MethodDeclaration method=ast.newMethodDeclaration();
  method.setName(ast.newSimpleName(methodName));
  SingleVariableDeclaration timestamp=ast.newSingleVariableDeclaration();
  timestamp.setType(ast.newPrimitiveType(PrimitiveType.LONG));
  timestamp.setName(ast.newSimpleName("String_Node_Str"));
  method.parameters().add(timestamp);
  SingleVariableDeclaration trim=ast.newSingleVariableDeclaration();
  trim.setType(ast.newPrimitiveType(PrimitiveType.BOOLEAN));
  trim.setName(ast.newSimpleName("String_Node_Str"));
  method.parameters().add(trim);
  if (!isInterface) {
    Block body=ast.newBlock();
    method.setBody(body);
    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)));
      restoreMethodCall.arguments().add(ast.newSimpleName(fieldName));
      restoreMethodCall.setName(ast.newSimpleName("String_Node_Str"));
      restoreMethodCall.arguments().add(ast.newSimpleName("String_Node_Str"));
      restoreMethodCall.arguments().add(ast.newSimpleName("String_Node_Str"));
      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));
      }
    }
    SuperMethodInvocation superRestore=ast.newSuperMethodInvocation();
    superRestore.setName(ast.newSimpleName(_getRestoreMethodName(false)));
    superRestore.arguments().add(ast.newSimpleName("String_Node_Str"));
    superRestore.arguments().add(ast.newSimpleName("String_Node_Str"));
    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 {
      IfStatement restoreCheckpoint=ast.newIfStatement();
      InfixExpression timestampTester=ast.newInfixExpression();
      timestampTester.setLeftOperand(ast.newSimpleName("String_Node_Str"));
      timestampTester.setOperator(InfixExpression.Operator.LESS_EQUALS);
      MethodInvocation topTimestamp=ast.newMethodInvocation();
      topTimestamp.setExpression(ast.newSimpleName(CHECKPOINT_RECORD_NAME));
      topTimestamp.setName(ast.newSimpleName("String_Node_Str"));
      timestampTester.setRightOperand(topTimestamp);
      restoreCheckpoint.setExpression(timestampTester);
      Block restoreBlock=ast.newBlock();
      restoreCheckpoint.setThenStatement(restoreBlock);
      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("String_Node_Str"));
      restoreCheckpointInvocation.arguments().add(ast.newSimpleName(CHECKPOINT_NAME));
      restoreCheckpointInvocation.arguments().add(_createRollbackableObject(ast,isAnonymous));
      restoreCheckpointInvocation.arguments().add(ast.newSimpleName("String_Node_Str"));
      restoreCheckpointInvocation.arguments().add(ast.newSimpleName("String_Node_Str"));
      assignCheckpoint.setRightHandSide(restoreCheckpointInvocation);
      restoreBlock.statements().add(ast.newExpressionStatement(assignCheckpoint));
      MethodInvocation popStates=ast.newMethodInvocation();
      String recordType=getClassName(FieldRecord.class,state,root);
      popStates.setExpression(createName(ast,recordType));
      popStates.setName(ast.newSimpleName("String_Node_Str"));
      popStates.arguments().add(ast.newSimpleName(RECORDS_NAME));
      restoreBlock.statements().add(ast.newExpressionStatement(popStates));
      body.statements().add(restoreCheckpoint);
      if (parent != null)       addToLists(_nodeSubstitution,parent.getName(),new NodeReplace(restoreCheckpoint,superRestoreStatement));
    }
  }
  method.setModifiers(Modifier.PUBLIC);
  return method;
}

Fixed version (ground truth):
/** 
 * Create a restore method for a class, which restores all its state variables.
 * @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 valueof 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);
  if (hasMethod(currentClass,methodName,new Class[]{int.class,boolean.class},true))   throw new ASTDuplicatedMethodException(currentClass.getName(),methodName);
  MethodDeclaration method=ast.newMethodDeclaration();
  method.setName(ast.newSimpleName(methodName));
  SingleVariableDeclaration timestamp=ast.newSingleVariableDeclaration();
  timestamp.setType(ast.newPrimitiveType(PrimitiveType.LONG));
  timestamp.setName(ast.newSimpleName("String_Node_Str"));
  method.parameters().add(timestamp);
  SingleVariableDeclaration trim=ast.newSingleVariableDeclaration();
  trim.setType(ast.newPrimitiveType(PrimitiveType.BOOLEAN));
  trim.setName(ast.newSimpleName("String_Node_Str"));
  method.parameters().add(trim);
  if (!isInterface) {
    Block body=ast.newBlock();
    method.setBody(body);
    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)));
      restoreMethodCall.arguments().add(ast.newSimpleName(fieldName));
      restoreMethodCall.setName(ast.newSimpleName("String_Node_Str"));
      restoreMethodCall.arguments().add(ast.newSimpleName("String_Node_Str"));
      restoreMethodCall.arguments().add(ast.newSimpleName("String_Node_Str"));
      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));
      }
    }
    SuperMethodInvocation superRestore=ast.newSuperMethodInvocation();
    superRestore.setName(ast.newSimpleName(_getRestoreMethodName(false)));
    superRestore.arguments().add(ast.newSimpleName("String_Node_Str"));
    superRestore.arguments().add(ast.newSimpleName("String_Node_Str"));
    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 {
      IfStatement restoreCheckpoint=ast.newIfStatement();
      InfixExpression timestampTester=ast.newInfixExpression();
      timestampTester.setLeftOperand(ast.newSimpleName("String_Node_Str"));
      timestampTester.setOperator(InfixExpression.Operator.LESS_EQUALS);
      MethodInvocation topTimestamp=ast.newMethodInvocation();
      topTimestamp.setExpression(ast.newSimpleName(CHECKPOINT_RECORD_NAME));
      topTimestamp.setName(ast.newSimpleName("String_Node_Str"));
      timestampTester.setRightOperand(topTimestamp);
      restoreCheckpoint.setExpression(timestampTester);
      Block restoreBlock=ast.newBlock();
      restoreCheckpoint.setThenStatement(restoreBlock);
      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("String_Node_Str"));
      restoreCheckpointInvocation.arguments().add(ast.newSimpleName(CHECKPOINT_NAME));
      restoreCheckpointInvocation.arguments().add(_createRollbackableObject(ast,isAnonymous));
      restoreCheckpointInvocation.arguments().add(ast.newSimpleName("String_Node_Str"));
      restoreCheckpointInvocation.arguments().add(ast.newSimpleName("String_Node_Str"));
      assignCheckpoint.setRightHandSide(restoreCheckpointInvocation);
      restoreBlock.statements().add(ast.newExpressionStatement(assignCheckpoint));
      MethodInvocation popStates=ast.newMethodInvocation();
      String recordType=getClassName(FieldRecord.class,state,root);
      popStates.setExpression(createName(ast,recordType));
      popStates.setName(ast.newSimpleName("String_Node_Str"));
      popStates.arguments().add(ast.newSimpleName(RECORDS_NAME));
      restoreBlock.statements().add(ast.newExpressionStatement(popStates));
      MethodInvocation recursion=ast.newMethodInvocation();
      recursion.setName(ast.newSimpleName(methodName));
      recursion.arguments().add(ast.newSimpleName("String_Node_Str"));
      recursion.arguments().add(ast.newSimpleName("String_Node_Str"));
      restoreBlock.statements().add(ast.newExpressionStatement(recursion));
      body.statements().add(restoreCheckpoint);
      if (parent != null)       addToLists(_nodeSubstitution,parent.getName(),new NodeReplace(restoreCheckpoint,superRestoreStatement));
    }
  }
  method.setModifiers(Modifier.PUBLIC);
  return method;
}