/*
   * Evaluates possible return expressions. The favourite expression is returned.
   */
  private Expression evaluateReturnExpressions(
      AST ast, ITypeBinding returnBinding, int returnOffset) {
    CompilationUnit root = (CompilationUnit) fMethodDecl.getRoot();

    Expression result = null;
    if (returnBinding != null) {
      ScopeAnalyzer analyzer = new ScopeAnalyzer(root);
      IBinding[] bindings =
          analyzer.getDeclarationsInScope(
              returnOffset, ScopeAnalyzer.VARIABLES | ScopeAnalyzer.CHECK_VISIBILITY);
      for (int i = 0; i < bindings.length; i++) {
        IVariableBinding curr = (IVariableBinding) bindings[i];
        ITypeBinding type = curr.getType();
        if (type != null && type.isAssignmentCompatible(returnBinding) && testModifier(curr)) {
          if (result == null) {
            result = ast.newSimpleName(curr.getName());
          }
          addLinkedPositionProposal(RETURN_EXPRESSION_KEY, curr.getName(), null);
        }
      }
    }
    Expression defaultExpression =
        ASTNodeFactory.newDefaultExpression(
            ast, fMethodDecl.getReturnType2(), fMethodDecl.getExtraDimensions());
    addLinkedPositionProposal(RETURN_EXPRESSION_KEY, ASTNodes.asString(defaultExpression), null);
    if (result == null) {
      return defaultExpression;
    }
    return result;
  }
 private ITypeBinding[] computeTypeVariables(ITypeBinding[] bindings) {
   Selection selection = getSelection();
   Set<ITypeBinding> result = new HashSet<>();
   // first remove all type variables that come from outside of the method
   // or are covered by the selection
   CompilationUnit compilationUnit = (CompilationUnit) fEnclosingBodyDeclaration.getRoot();
   for (int i = 0; i < bindings.length; i++) {
     ASTNode decl = compilationUnit.findDeclaringNode(bindings[i]);
     if (decl == null
         || (!selection.covers(decl) && decl.getParent() instanceof MethodDeclaration))
       result.add(bindings[i]);
   }
   // all all type variables which are needed since a local variable uses it
   for (int i = 0; i < fArguments.length; i++) {
     IVariableBinding arg = fArguments[i];
     ITypeBinding type = arg.getType();
     if (type != null && type.isTypeVariable()) {
       ASTNode decl = compilationUnit.findDeclaringNode(type);
       if (decl == null
           || (!selection.covers(decl) && decl.getParent() instanceof MethodDeclaration))
         result.add(type);
     }
   }
   return result.toArray(new ITypeBinding[result.size()]);
 }
예제 #3
0
 public static boolean isPrimitiveConstant(IVariableBinding binding) {
   return isFinal(binding)
       && binding.getType().isPrimitive()
       && binding.getConstantValue() != null
       // Exclude local variables declared final.
       && binding.getDeclaringClass() != null;
 }
  @Override
  public void endVisit(SuperMethodInvocation node) {
    Name qualifier = node.getQualifier();
    if (qualifier == null) {
      return;
    }
    IMethodBinding method = node.getMethodBinding();
    ITypeBinding exprType = node.getTypeBinding();
    IVariableBinding var = TreeUtil.getVariableBinding(qualifier);
    assert var != null : "Expected qualifier to be a variable";
    ITypeBinding qualifierType = var.getType();

    SuperMethodBindingPair superMethod = new SuperMethodBindingPair(qualifierType, method);
    superMethods.add(superMethod);

    FunctionBinding binding =
        new FunctionBinding(getSuperFunctionName(superMethod), exprType, qualifierType);
    binding.addParameters(qualifierType, typeEnv.getIdType());
    binding.addParameters(method.getParameterTypes());
    FunctionInvocation invocation = new FunctionInvocation(binding, exprType);
    List<Expression> args = invocation.getArguments();
    args.add(TreeUtil.remove(qualifier));
    String selectorExpr = UnicodeUtils.format("@selector(%s)", nameTable.getMethodSelector(method));
    args.add(new NativeExpression(selectorExpr, typeEnv.getIdType()));
    TreeUtil.copyList(node.getArguments(), args);
    node.replaceWith(invocation);
  }
예제 #5
0
 private Statement createVolatileRetainStatement(IVariableBinding var) {
   ITypeBinding idType = typeEnv.resolveIOSType("id");
   FunctionInvocation invocation =
       new FunctionInvocation("JreRetainVolatile", idType, idType, null);
   invocation
       .getArguments()
       .add(
           new PrefixExpression(
               typeEnv.getPointerType(var.getType()),
               PrefixExpression.Operator.ADDRESS_OF,
               new SimpleName(var)));
   return new ExpressionStatement(invocation);
 }
예제 #6
0
 private List<Statement> getFieldAdjustments(TypeDeclaration node) {
   List<Statement> adjustments = Lists.newArrayList();
   for (VariableDeclarationFragment decl : TreeUtil.getAllFields(node)) {
     IVariableBinding var = decl.getVariableBinding();
     if (BindingUtil.isStatic(var) || var.getType().isPrimitive()) {
       continue;
     }
     boolean isWeak = BindingUtil.isWeakReference(var);
     boolean isVolatile = BindingUtil.isVolatile(var);
     if (isWeak && !isVolatile) {
       adjustments.add(createReleaseStatement(var));
     } else if (!isWeak && isVolatile) {
       adjustments.add(createVolatileRetainStatement(var));
     }
   }
   return adjustments;
 }
예제 #7
0
  @Override
  public boolean visit(ClassInstanceCreation node) {
    ITypeBinding newType = node.getTypeBinding().getTypeDeclaration();
    ITypeBinding declaringClass = newType.getDeclaringClass();
    if (Modifier.isStatic(newType.getModifiers()) || declaringClass == null) {
      return true;
    }

    GeneratedMethodBinding binding =
        new GeneratedMethodBinding(node.getMethodBinding().getMethodDeclaration());
    node.setMethodBinding(binding);
    addOuterArg(node, binding, declaringClass);

    for (IVariableBinding capturedVar : getCapturedVariables(node)) {
      node.getArguments().add(new SimpleName(capturedVar));
      binding.addParameter(capturedVar.getType());
    }

    assert binding.isVarargs() || node.getArguments().size() == binding.getParameterTypes().length;
    return true;
  }
예제 #8
0
  /** List has a toArray() method that uses array types. */
  public void testAbstractMethodsAddedWithArrayType() {
    String source =
        "import java.util.List; public abstract class Test implements List<Object> { "
            + "public boolean isEmpty() { return true; } }";
    CompilationUnit unit = translateType("Test", source);
    List<AbstractTypeDeclaration> types = unit.getTypes();
    assertEquals(1, types.size());
    assertTrue(types.get(0) instanceof TypeDeclaration);
    TypeDeclaration testType = (TypeDeclaration) types.get(0);
    List<MethodDeclaration> methods = TreeUtil.getMethodDeclarationsList(testType);
    assertEquals(26, methods.size());

    // verify added methods are abstract, and that existing method wasn't changed
    for (MethodDeclaration m : methods) {
      int modifiers = m.getModifiers();
      String name = m.getName().getIdentifier();
      if (name.equals("isEmpty")) {
        assertFalse(Modifier.isAbstract(modifiers));
      } else if (name.equals(NameTable.FINALIZE_METHOD)
          || name.equals(NameTable.DEALLOC_METHOD)
          || name.equals(NameTable.INIT_NAME)) {
        // it's ok.
      } else {
        // it's an added method
        assertTrue(Modifier.isAbstract(modifiers));
        ITypeBinding returnType = m.getReturnType().getTypeBinding();
        if (name.equals("toArray")) {
          assertEquals("IOSObjectArray", returnType.getName());
          if (!m.getParameters().isEmpty()) {
            assertEquals(1, m.getParameters().size());
            SingleVariableDeclaration param = m.getParameters().get(0);
            IVariableBinding paramBinding = param.getVariableBinding();
            assertTrue(paramBinding.getType().isArray());
          }
        }
      }
    }
  }
 // We generate the runtime debug method +memDebugStaticReferences.
 // This method will return an array of NSNumber containing pointers (casted into unsigned long)
 // to the objects referenced by a class variable with a strong reference.
 // It will be useful for debug purpose.
 //
 // Arrays returned by -memDebugStaticReferences and -memDebugStaticReferencesNames (see below)
 // must be the same size.
 //
 // In case of a Java enum, valuesVarNameis the name of the array of enum values.
 private void printStaticReferencesMethod(List<FieldDeclaration> fields, String valuesVarName) {
   if (Options.memoryDebug()) {
     if (!Options.useReferenceCounting()) {
       println("+ (NSArray *)memDebugStaticReferences {");
       println("  return nil;");
       println("}");
       return;
     }
     println("+ (NSArray *)memDebugStaticReferences {");
     println("  NSMutableArray *result = [NSMutableArray array];");
     for (FieldDeclaration f : fields) {
       if (Modifier.isStatic(f.getModifiers())) {
         for (VariableDeclarationFragment var : ASTUtil.getFragments(f)) {
           IVariableBinding binding = Types.getVariableBinding(var);
           // All non-primitive static variables are strong references.
           if (!binding.getType().isPrimitive()) {
             String name = NameTable.getStaticVarQualifiedName(binding);
             println(
                 String.format(
                     "  [result addObject:[JreMemDebugStrongReference "
                         + "strongReferenceWithObject:%s name:@\"%s\"]];",
                     name, name));
           }
         }
       }
     }
     if (valuesVarName != null) {
       println(
           String.format(
               "  [result addObject:[JreMemDebugStrongReference "
                   + "strongReferenceWithObject:%s name:@\"enumValues\"]];",
               valuesVarName));
     }
     println("  return result;");
     println("}\n");
   }
 }
 private void printStaticVars(List<FieldDeclaration> fields, boolean isInterface) {
   boolean hadStaticVar = false;
   for (FieldDeclaration f : fields) {
     if (Modifier.isStatic(f.getModifiers()) || isInterface) {
       for (VariableDeclarationFragment var : ASTUtil.getFragments(f)) {
         IVariableBinding binding = Types.getVariableBinding(var);
         if (!BindingUtil.isPrimitiveConstant(binding)) {
           String name = NameTable.getStaticVarQualifiedName(binding);
           String objcType = NameTable.getObjCType(binding.getType());
           Expression initializer = var.getInitializer();
           if (initializer != null) {
             printf("static %s %s = %s;\n", objcType, name, generateExpression(initializer));
           } else {
             printf("static %s %s;\n", objcType, name);
           }
           hadStaticVar = true;
         }
       }
     }
   }
   if (hadStaticVar) {
     newline();
   }
 }
  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;
  }