Beispiel #1
0
  // Generate a statement with assignment
  // E.g. input: x.f(y) ==> x = x.f(y);
  public static ExpressionStatement genAssignmentStatement(Expression exp) {
    Assignment assignExp = AST.newAST(AST.JLS8).newAssignment();
    // generate a new left hand side variable
    assignExp.setLeftHandSide(
        (Expression)
            ASTNode.copySubtree(assignExp.getAST(), genSimpleName(VariableGenerator.genVar())));

    assignExp.setRightHandSide((Expression) ASTNode.copySubtree(assignExp.getAST(), exp));
    assignExp.setOperator(Assignment.Operator.ASSIGN);

    AST newAst = AST.newAST(AST.JLS8);
    return newAst.newExpressionStatement((Expression) ASTNode.copySubtree(newAst, assignExp));
  }
  public void testCopySubtree() {
    CalloutMappingDeclaration calloutDecl =
        (CalloutMappingDeclaration) _role.bodyDeclarations().get(7);
    List parameterMappings = calloutDecl.getParameterMappings();
    ParameterMapping testObj = (ParameterMapping) parameterMappings.get(2);

    ParameterMapping clonedTestObject =
        (ParameterMapping) ASTNode.copySubtree(AST.newAST(AST.JLS4), testObj);
    boolean actual = testObj.subtreeMatch(new ASTMatcher(), clonedTestObject);

    assertTrue("Copy of subtree not correct", actual);
  }
  private Example makeExample(
      MethodDeclaration node,
      Set<? extends Expression> envolvedInvocations,
      List<ApiMethod> envolvedApiMethods) {

    //  Visitor responsável por realizar o slicing de programas
    SlicingStatementVisitor visitor =
        new SlicingStatementVisitor(node, new HashSet<ASTNode>(envolvedInvocations));
    node.accept(visitor);

    Collection<Statement> relatedStatements = visitor.getSlicedStatements();

    ASTNode newAST =
        ASTUtil.copyStatements(node.getBody(), relatedStatements, AST.newAST(AST.JLS3));
    if (!relatedStatements.isEmpty()) {
      LOGGER.error("Some statements were not included!");
    }

    if (newAST == null) {
      LOGGER.error("Slicing process failed for node ");
      // TODO Se AST retornada for nula é porque faltou incluir statement(s)
      return null;
    } else if (((Block) newAST).statements().isEmpty()) {
      LOGGER.error("Slicing process failed for node ");
      // TODO Se o Block retornado for vazio é porque faltou incluir statement(s)
      return null;
    }

    ASTUtil.removeEmptyBlocks((Block) newAST);

    // Adiciona declarações de variáveis que não foram encontradas no escopo do método
    // Para facilitar, tipos iguais são declarados no mesmo Statement
    Set<String> additionalDeclarationLines = new HashSet<String>();
    Map<ITypeBinding, List<IVariableBinding>> typesMap =
        new HashMap<ITypeBinding, List<IVariableBinding>>();
    for (IVariableBinding ivb : visitor.getUndiscoveredDeclarations()) {
      if (!typesMap.containsKey(ivb.getType())) {
        typesMap.put(ivb.getType(), new ArrayList<IVariableBinding>(2));
      }
      typesMap.get(ivb.getType()).add(ivb);
    }

    for (ITypeBinding typeBinding : typesMap.keySet()) {
      List<IVariableBinding> variableBindings = typesMap.get(typeBinding);

      Stack<VariableDeclarationFragment> fragments = new Stack<VariableDeclarationFragment>();
      for (IVariableBinding ivb : variableBindings) {
        VariableDeclarationFragment declarationFragment =
            newAST.getAST().newVariableDeclarationFragment();
        declarationFragment.setName(newAST.getAST().newSimpleName(ivb.getName()));
        fragments.add(declarationFragment);
      }

      VariableDeclarationStatement statement =
          newAST.getAST().newVariableDeclarationStatement(fragments.pop());
      while (!fragments.isEmpty()) {
        statement.fragments().add(fragments.pop());
      }

      statement.setType(this.getType(typeBinding, newAST.getAST()));

      additionalDeclarationLines.add(statement.toString());
      ((Block) newAST).statements().add(0, statement);
    }

    Example example = new Example();
    example.setAttachment(this.attachmentMap.get(node.getRoot()));
    example.setApiMethods(new HashSet<ApiElement>(envolvedApiMethods));
    example.setImports(visitor.getImports());

    for (Expression seed : envolvedInvocations) {
      example.getSeeds().add(seed.toString());
    }

    example.setSourceMethod(node.toString());
    example.setAddedAt(new Date(System.currentTimeMillis()));

    try {
      IMethodBinding nodeBinding = node.resolveBinding();
      if (!this.methodMap.containsKey(nodeBinding)) {
        ApiClass newApiClass = new ApiClass(nodeBinding.getDeclaringClass().getQualifiedName());
        methodDeclarationHandler(node, newApiClass);
      }
      example.setSourceMethodCall(this.methodMap.get(nodeBinding).getFullName());
    } catch (Exception e) {
      LOGGER.error(e);
      if (example.getSourceMethodCall() == null) {
        example.setSourceMethodCall("?");
      }
    }

    String codeExample = newAST.toString();
    for (String line : additionalDeclarationLines) {
      codeExample =
          codeExample.replace(
              line,
              line.replace("\n", "").concat("  ").concat("//initialized previously").concat("\n"));
    }

    // FIXME
    codeExample = codeExample.replaceAll("(\\{\n)(\\s+)(\\})", "$1 //do something \n$3");

    try {
      example.setCodeExample(codeExample);
      example.setFormattedCodeExample(ASTUtil.codeFormatter(codeExample));
    } catch (Exception e) {
      LOGGER.error(e);
      if (example.getFormattedCodeExample() == null) {
        example.setFormattedCodeExample(codeExample);
      }
    }

    // TODO Obter métricas do exemplo
    example
        .getMetrics()
        .put(ExampleMetric.LOC.name(), example.getFormattedCodeExample().split("\n").length - 1);
    example.getMetrics().put(ExampleMetric.ARGUMENTS.name(), visitor.getNumberOfArguments());
    example
        .getMetrics()
        .put(ExampleMetric.DECISION_STATEMENTS.name(), visitor.getNumberOfDecisionStatements());
    example.getMetrics().put(ExampleMetric.INVOCATIONS.name(), visitor.getNumberOfInvocations());
    example
        .getMetrics()
        .put(ExampleMetric.NULL_ARGUMENTS.name(), visitor.getNumberOfNullArguments());
    example
        .getMetrics()
        .put(ExampleMetric.PRIMITIVE_ARGUMENTS.name(), visitor.getNumberOfPrimitiveArguments());
    example
        .getMetrics()
        .put(ExampleMetric.FIELD_ARGUMENTS.name(), visitor.getNumberOfFieldArguments());
    example
        .getMetrics()
        .put(
            ExampleMetric.UNDISCOVERED_DECLARATIONS.name(),
            visitor.getNumberOfUndiscoveredDeclarations());
    example
        .getMetrics()
        .put(ExampleMetric.UNHANDLED_EXCEPTIONS.name(), visitor.getNumberOfUnhandledExceptions());

    return example;
  }
 public AST newTree() {
   return AST.newAST(this.level.getValue());
 }
Beispiel #5
0
  // generate a variable declaration with an initializer specified by the given expression
  // e.g. given x.f(a,b) ==> int y = x.f(a,b);
  public static List<Statement> genVarDeclStatement(Expression exp) {

    List<Statement> result = new ArrayList<Statement>();

    VariableDeclarationFragment fragment = AST.newAST(AST.JLS8).newVariableDeclarationFragment();

    ExpressionStatement assignmentStmt = genAssignmentStatement(exp);

    // The type of the generated variable
    Type varType = AST.newAST(AST.JLS8).newWildcardType();
    if (exp.resolveTypeBinding() != null) {
      if (exp.resolveTypeBinding().isPrimitive()) {
        switch (exp.resolveTypeBinding().getName()) {
          case "void":
            varType = AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.VOID);
            break;
          case "int":
            varType = AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.INT);
            break;
          case "char":
            varType = AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.CHAR);
            break;
          case "long":
            varType = AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.LONG);
            break;
          case "boolean":
            varType = AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.BOOLEAN);
            break;
          case "float":
            varType = AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.FLOAT);
            break;
          case "short":
            varType = AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.SHORT);
            break;
          case "byte":
            varType = AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.BYTE);
            break;
          case "double":
            varType = AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.DOUBLE);
            break;
        }
      } else {

        // Option 1: only use the simplename
        /*
        SimpleName typeName = AST.newAST(AST.JLS8).newSimpleName(exp.resolveTypeBinding().getName());
        AST tempAST = AST.newAST(AST.JLS8);
        varType = tempAST.newSimpleType((Name) ASTNode.copySubtree(tempAST, typeName));
        */

        varType = resolveQualifiedType(exp.resolveTypeBinding().getQualifiedName());
      }
    }
    // Declaration Fragment
    fragment.setName(
        (SimpleName)
            ASTNode.copySubtree(
                fragment.getAST(),
                ((SimpleName) ((Assignment) assignmentStmt.getExpression()).getLeftHandSide())));
    // fragment.setInitializer((Expression) ASTNode.copySubtree(fragment.getAST(), exp));

    AST varDeclFragAST = AST.newAST(AST.JLS8);
    VariableDeclarationStatement decl =
        varDeclFragAST.newVariableDeclarationStatement(
            (VariableDeclarationFragment) ASTNode.copySubtree(varDeclFragAST, fragment));

    decl.setType((Type) ASTNode.copySubtree(decl.getAST(), varType));

    result.add(decl);

    // initializer is defined here as a separate statement
    Assignment assign = varDeclFragAST.newAssignment();
    assign.setLeftHandSide((Expression) ASTNode.copySubtree(varDeclFragAST, fragment.getName()));
    assign.setRightHandSide((Expression) ASTNode.copySubtree(varDeclFragAST, exp));
    ExpressionStatement assignStmt = varDeclFragAST.newExpressionStatement(assign);

    result.add(assignStmt);

    return result;
  }
Beispiel #6
0
  private static Type resolveQualifiedType(String s) {

    if (s.equals("byte")) {
      return AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.BYTE);
    }

    if (s.equals("")) {
      return AST.newAST(AST.JLS8).newWildcardType();
    }

    // It's a type parameter
    if (s.contains("<") && s.contains(">")) {
      // TODO: resolve type parameters
      String s0 = s.substring(0, s.indexOf("<"));
      Type hd = resolveQualifiedType(s0);
      AST tAST = AST.newAST(AST.JLS8);
      ParameterizedType pt = tAST.newParameterizedType((Type) ASTNode.copySubtree(tAST, hd));

      for (String i : splitTypeArgs(s.substring(s.indexOf("<") + 1, s.lastIndexOf(">")))) {
        pt.typeArguments().add(ASTNode.copySubtree(tAST, resolveQualifiedType(i)));
      }
      return pt;
    }

    // It's an array type
    if (s.contains("[") && s.contains("]")) {
      String s0 = s.substring(0, s.indexOf("["));
      Type hd = resolveQualifiedType(s0);
      AST tast = AST.newAST(AST.JLS8);
      ArrayType pt = tast.newArrayType((Type) ASTNode.copySubtree(tast, hd));
      return pt;
    }

    if (!s.contains(".")) {
      AST ast = AST.newAST(AST.JLS8);
      if (s == null || s.equals("null")) {
        return ast.newSimpleType((Name) ASTNode.copySubtree(ast, genSimpleName("String")));
      }
      switch (s) {
        case "void":
          return AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.VOID);
        case "int":
          return AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.INT);
        case "char":
          return AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.CHAR);
        case "long":
          return AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.LONG);
        case "boolean":
          return AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.BOOLEAN);
        case "float":
          return AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.FLOAT);
        case "short":
          return AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.SHORT);
        case "byte":
          return AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.BYTE);
        case "double":
          return AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.DOUBLE);
      }
      return ast.newSimpleType((Name) ASTNode.copySubtree(ast, genSimpleName(s)));
    } else {
      int last = s.lastIndexOf(".");
      AST ast = AST.newAST(AST.JLS8);
      String lastFrag = s.substring(last + 1);
      return ast.newQualifiedType(
          (Type) ASTNode.copySubtree(ast, resolveQualifiedType(s.substring(0, last))),
          (SimpleName) ASTNode.copySubtree(ast, genSimpleName(lastFrag)));
    }
  }
Beispiel #7
0
 // generate a SimpleName node
 public static SimpleName genSimpleName(String s) {
   return AST.newAST(AST.JLS8).newSimpleName(s);
 }
Beispiel #8
0
 // generate an empty block
 public static Block genBlock() {
   return AST.newAST(AST.JLS8).newBlock();
 }
  @SuppressWarnings("unchecked")
  @Before
  public void setUp() {
    manager = ModelManager.getInstance();
    manager.clearModel();

    AST ast2 = AST.newAST(AST.JLS3);
    CompilationUnit cu2 = ast2.newCompilationUnit();
    PackageDeclaration pack2 = ast2.newPackageDeclaration();
    pack2.setName(ast2.newName("be.ac.ua.test.otherpack"));
    cu2.setPackage(pack2);
    TypeDeclaration type2 = ast2.newTypeDeclaration();
    type2.setName(ast2.newSimpleName("Foo"));

    cu2.types().add(type2); // created mock compilationunit containing package and class

    PackageRecorder prec2 = new PackageRecorder(pack2);
    prec2.storeChange(new Add()); // store the package addition
    ClassRecorder crec2 = new ClassRecorder(type2);
    declaredclassadd = new Add();
    crec2.storeChange(declaredclassadd);

    AST ast = AST.newAST(AST.JLS3);
    CompilationUnit cu = ast.newCompilationUnit();
    PackageDeclaration pack = ast.newPackageDeclaration();
    pack.setName(ast.newName(packname));
    cu.setPackage(pack);
    TypeDeclaration type = ast.newTypeDeclaration();
    type.setName(ast.newSimpleName(classname));

    cu.types().add(type);

    PackageRecorder prec = new PackageRecorder(pack);
    prec.storeChange(new Add()); // store the package addition
    ClassRecorder crec = new ClassRecorder(type);
    classadd = new Add();
    crec.storeChange(classadd);

    // Class and package created and changes logged, now create the Field.

    VariableDeclarationFragment frag1 = ast.newVariableDeclarationFragment();
    frag1.setName(ast.newSimpleName(intfieldname));
    FieldDeclaration field = ast.newFieldDeclaration(frag1);
    field.setType(ast.newPrimitiveType(PrimitiveType.INT)); // field has type int
    type.bodyDeclarations().add(field);

    VariableDeclarationFragment frag2 = ast.newVariableDeclarationFragment();
    frag2.setName(ast.newSimpleName(fieldname));
    FieldDeclaration field2 = ast.newFieldDeclaration(frag2);
    field2.setType(ast.newSimpleType(ast.newName(declaredTypeName))); // field has type Foo
    type.bodyDeclarations().add(field2);

    VariableDeclarationFragment frag3 = ast.newVariableDeclarationFragment();
    frag3.setName(ast.newSimpleName(field3Name));
    FieldDeclaration field3 = ast.newFieldDeclaration(frag3);
    field3.setType(ast.newSimpleType(ast.newName("Foo"))); // field has type Foo
    type.bodyDeclarations().add(field3);

    ImportDeclaration imp = ast.newImportDeclaration();
    imp.setName(ast.newName(declaredTypeName));
    cu.imports().add(imp);

    // created mock compilationunit containing package and class

    recorder1 = new FieldRecorder(field);
    recorder2 = new FieldRecorder(field2);
    recorder3 = new FieldRecorder(field3);
  }