private String generateMethodBody(MethodDeclaration m) {
    String methodBody;
    if (Modifier.isNative(m.getModifiers())) {
      if (hasNativeCode(m, true)) {
        methodBody = extractNativeMethodBody(m);
      } else if (Options.generateNativeStubs()) {
        return generateNativeStub(m);
      } else {
        return null;
      }
    } else if (Modifier.isAbstract(m.getModifiers())) {
      // Generate a body which throws a NSInvalidArgumentException.
      String body =
          "{\n // can't call an abstract method\n " + "[self doesNotRecognizeSelector:_cmd];\n ";
      if (!Types.isVoidType(m.getReturnType2())) {
        body += "return 0;\n"; // Never executes, but avoids a gcc warning.
      }
      return body + "}";
    } else {
      // generate a normal method body
      methodBody = generateStatement(m.getBody(), false);
    }

    boolean isStatic = (m.getModifiers() & Modifier.STATIC) != 0;
    boolean isSynchronized = (m.getModifiers() & Modifier.SYNCHRONIZED) != 0;
    if (isStatic && isSynchronized) {
      methodBody = "{\n@synchronized([self class]) {\n" + methodBody + "}\n}\n";
    } else if (isSynchronized) {
      methodBody = "{\n@synchronized(self) {\n" + methodBody + "}\n}\n";
    }

    return methodBody;
  }
  private static boolean canAddFinal(IBinding binding, ASTNode declNode) {
    if (!(binding instanceof IVariableBinding)) return false;

    IVariableBinding varbinding = (IVariableBinding) binding;
    int modifiers = varbinding.getModifiers();
    if (Modifier.isFinal(modifiers)
        || Modifier.isVolatile(modifiers)
        || Modifier.isTransient(modifiers)) return false;

    ASTNode parent = ASTNodes.getParent(declNode, VariableDeclarationExpression.class);
    if (parent != null && ((VariableDeclarationExpression) parent).fragments().size() > 1)
      return false;

    if (varbinding.isField() && !Modifier.isPrivate(modifiers)) return false;

    if (varbinding.isParameter()) {
      ASTNode varDecl = declNode.getParent();
      if (varDecl instanceof MethodDeclaration) {
        MethodDeclaration declaration = (MethodDeclaration) varDecl;
        if (declaration.getBody() == null) return false;
      }
    }

    return true;
  }
 private boolean testModifier(IVariableBinding curr) {
   int modifiers = curr.getModifiers();
   int staticFinal = Modifier.STATIC | Modifier.FINAL;
   if ((modifiers & staticFinal) == staticFinal) {
     return false;
   }
   if (Modifier.isStatic(modifiers) && !Modifier.isStatic(fMethodDecl.getModifiers())) {
     return false;
   }
   return true;
 }
 private Modifier getPublicModifier(MethodDeclaration method) {
   List<?> list = method.modifiers();
   for (Object o : list) {
     if (o.getClass().equals(Modifier.class)) {
       Modifier mdf = (Modifier) o;
       if (mdf.getKeyword().equals(PUBLIC_KEYWORD)) {
         return mdf;
       }
     }
   }
   return null;
 }
 @Override
 public boolean visit(MethodDeclaration node) {
   if (node.getBody() == null) {
     return VISIT_SUBTREE;
   }
   List<Statement> bodyStmts = statements(node.getBody());
   if (bodyStmts.size() == 1) {
     SuperMethodInvocation bodyMi = asExpression(bodyStmts.get(0), SuperMethodInvocation.class);
     if (bodyMi != null) {
       IMethodBinding bodyMethodBinding = bodyMi.resolveMethodBinding();
       IMethodBinding declMethodBinding = node.resolveBinding();
       if (declMethodBinding != null
           && bodyMethodBinding != null
           && declMethodBinding.overrides(bodyMethodBinding)
           && !hasSignificantAnnotations(declMethodBinding)
           && haveSameModifiers(bodyMethodBinding, declMethodBinding)) {
         if (Modifier.isProtected(declMethodBinding.getModifiers())
             && !declaredInSamePackage(bodyMethodBinding, declMethodBinding)) {
           // protected also means package visibility, so check if it is required
           if (!isMethodUsedInItsPackage(declMethodBinding, node)) {
             this.ctx.getRefactorings().remove(node);
             return DO_NOT_VISIT_SUBTREE;
           }
         } else {
           this.ctx.getRefactorings().remove(node);
           return DO_NOT_VISIT_SUBTREE;
         }
       }
     }
   }
   return VISIT_SUBTREE;
 }
예제 #6
0
  private boolean initializeAndCollectInhData(
      IMethodBinding binding, List<MethodPathItem> inhMethods) {
    if (binding == null) return false;

    // check if method is abstract
    if (Modifier.isAbstract(binding.getModifiers())) return false;

    ITypeBinding declTypeBinding = binding.getDeclaringClass();

    // check only for classes
    if (declTypeBinding == null || !declTypeBinding.isClass()) return false;

    Set<String> checkedInterfaces = new HashSet<String>();

    // (recursively) collects all keys of methods in abstract classes which
    // belongs to this declaration
    OverridingRelationUtils.collectSimilarMethodKeysInSuperClasses(
        binding, declTypeBinding.getSuperclass(), inhMethods, checkedInterfaces);

    // (recursively) collects all keys of methods in interfaces which
    // belongs to this declaration
    OverridingRelationUtils.collectSimilarMethodKeysInInterfaces(
        binding, declTypeBinding.getInterfaces(), inhMethods, checkedInterfaces);

    // the set should contain at least one inherited method
    if (inhMethods.size() == 0) return false;

    return true;
  }
  private void computeConstantDeclarationLocation() throws JavaModelException {
    if (isDeclarationLocationComputed()) return;

    BodyDeclaration lastStaticDependency = null;
    Iterator<BodyDeclaration> decls =
        getContainingTypeDeclarationNode().bodyDeclarations().iterator();

    while (decls.hasNext()) {
      BodyDeclaration decl = decls.next();

      int modifiers;
      if (decl instanceof FieldDeclaration) modifiers = ((FieldDeclaration) decl).getModifiers();
      else if (decl instanceof Initializer) modifiers = ((Initializer) decl).getModifiers();
      else {
        continue; /* this declaration is not a field declaration
                  or initializer, so the placement of the constant
                  declaration relative to it does not matter */
      }

      if (Modifier.isStatic(modifiers) && depends(getSelectedExpression(), decl))
        lastStaticDependency = decl;
    }

    if (lastStaticDependency == null) fInsertFirst = true;
    else fToInsertAfter = lastStaticDependency;
  }
 private List<VariableDeclarationFragment> getProperties(FieldDeclaration[] fields) {
   List<VariableDeclarationFragment> properties = Lists.newArrayList();
   for (FieldDeclaration field : fields) {
     if (!Modifier.isStatic(field.getModifiers())) {
       properties.addAll(ASTUtil.getFragments(field));
     }
   }
   return properties;
 }
예제 #9
0
  public static Modifier createModifier(AST ast, ModifierKeyword keyword, int start, int end) {
    Modifier modifier = null;
    try {
      modifier = Reflection.modifierConstructor.newInstance(ast);
    } catch (InstantiationException e) {
      throw Lombok.sneakyThrow(e);
    } catch (IllegalAccessException e) {
      throw Lombok.sneakyThrow(e);
    } catch (InvocationTargetException e) {
      throw Lombok.sneakyThrow(e);
    }

    if (modifier != null) {
      modifier.setKeyword(keyword);
      modifier.setSourceRange(start, end - start + 1);
    }
    return modifier;
  }
예제 #10
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());
          }
        }
      }
    }
  }
예제 #11
0
  private void handleFieldChecks(Name node, IVariableBinding binding) {

    // add field access check
    checks.add(new FieldAccessCheck(file, jdtTypingProvider, bridge(node), binding));

    // add assignment check for final fields
    if (Modifier.isFinal((binding).getModifiers())) {

      ITypeBinding declClass = binding.getDeclaringClass();

      if (declClass != null && declClass.isFromSource())
        checks.add(new FieldAssignmentCheck(file, jdtTypingProvider, bridge(node), binding));
    }
  }
예제 #12
0
  /** Verifies that abstract methods to implement an interface are added to an abstract class. */
  public void testAbstractMethodsAdded() {
    String source =
        "import java.util.Iterator; public abstract class Test implements Iterator<Test> { "
            + "public boolean hasNext() { 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(4, 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("hasNext")) {
        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));
        assertEquals(0, m.getParameters().size());
        if (name.equals("next")) {
          assertEquals(testType.getTypeBinding(), m.getReturnType().getTypeBinding());
        } else if (name.equals("remove")) {
          ITypeBinding voidType = Types.resolveJavaType("void");
          assertEquals(voidType, m.getReturnType().getTypeBinding());
        } else {
          fail("unknown method added: " + name);
        }
      }
    }
  }
  private static boolean isStaticFieldOrStaticInitializer(BodyDeclaration node) {
    if (node instanceof MethodDeclaration || node instanceof AbstractTypeDeclaration) return false;

    int modifiers;
    if (node instanceof FieldDeclaration) {
      modifiers = ((FieldDeclaration) node).getModifiers();
    } else if (node instanceof Initializer) {
      modifiers = ((Initializer) node).getModifiers();
    } else {
      Assert.isTrue(false);
      return false;
    }

    if (!Modifier.isStatic(modifiers)) return false;

    return true;
  }
  private void possibleStaticImportFound(Name name) {
    if (fStaticImports == null || fASTRoot == null) {
      return;
    }

    while (name.isQualifiedName()) {
      name = ((QualifiedName) name).getQualifier();
    }
    if (!isAffected(name)) {
      return;
    }

    IBinding binding = name.resolveBinding();
    SimpleName simpleName = (SimpleName) name;
    if (binding == null
        || binding instanceof ITypeBinding
        || !Modifier.isStatic(binding.getModifiers())
        || simpleName.isDeclaration()) {
      return;
    }

    if (binding instanceof IVariableBinding) {
      IVariableBinding varBinding = (IVariableBinding) binding;
      if (varBinding.isField()) {
        varBinding = varBinding.getVariableDeclaration();
        ITypeBinding declaringClass = varBinding.getDeclaringClass();
        if (declaringClass != null && !declaringClass.isLocal()) {
          if (new ScopeAnalyzer(fASTRoot)
              .isDeclaredInScope(
                  varBinding, simpleName, ScopeAnalyzer.VARIABLES | ScopeAnalyzer.CHECK_VISIBILITY))
            return;
          fStaticImports.add(simpleName);
        }
      }
    } else if (binding instanceof IMethodBinding) {
      IMethodBinding methodBinding = ((IMethodBinding) binding).getMethodDeclaration();
      ITypeBinding declaringClass = methodBinding.getDeclaringClass();
      if (declaringClass != null && !declaringClass.isLocal()) {
        if (new ScopeAnalyzer(fASTRoot)
            .isDeclaredInScope(
                methodBinding, simpleName, ScopeAnalyzer.METHODS | ScopeAnalyzer.CHECK_VISIBILITY))
          return;
        fStaticImports.add(simpleName);
      }
    }
  }
  // Método para configurar os modificadores
  @SuppressWarnings("unchecked")
  private void setModifiers(ApiElement apiElement, BodyDeclaration node) {

    for (Object o : node.modifiers()) {
      if (o instanceof Modifier) {
        Modifier modifier = (Modifier) o;
        if (modifier.isAbstract()) {
          apiElement.setAbstract(true);
        } else if (modifier.isFinal()) {
          apiElement.setFinal(true);
        } else if (modifier.isPrivate()) {
          apiElement.setPrivate(true);
        } else if (modifier.isProtected()) {
          apiElement.setProtected(true);
        } else if (modifier.isPublic()) {
          apiElement.setPublic(true);
        } else if (modifier.isStatic()) {
          apiElement.setFinal(true);
        }
      }
    }

    apiElement.setDefault(
        !(apiElement.isPrivate() || apiElement.isPublic() || apiElement.isProtected()));

    Javadoc javadoc = node.getJavadoc();
    if (javadoc != null) {
      apiElement.setHasJavadoc(true);
      apiElement.setHidden(false);
      Stack<Object> tags = new Stack<Object>();
      tags.addAll(javadoc.tags());
      while (!tags.isEmpty()) {
        Object tag = tags.pop();
        if (tag instanceof TagElement) {
          String tagName = ((TagElement) tag).getTagName();
          if (tagName != null && tagName.equalsIgnoreCase("@hide")) {
            apiElement.setHidden(true);
            break;
          }
          tags.addAll(((TagElement) tag).fragments());
        }
      }
    } else {
      apiElement.setHasJavadoc(false);
      apiElement.setHidden(true);
    }
  }
예제 #16
0
  /**
   * Get a method's signature for dead code elimination purposes.
   *
   * <p>Since DeadCodeEliminator runs before InnerClassExtractor, inner class constructors do not
   * yet have the parameter for capturing outer class, and therefore we need this special case.
   */
  public static String getProGuardSignature(IMethodBinding binding) {
    StringBuilder sb = new StringBuilder("(");

    // If the method is an inner class constructor, prepend the outer class type.
    if (binding.isConstructor()) {
      ITypeBinding declClass = binding.getDeclaringClass();
      ITypeBinding outerClass = declClass.getDeclaringClass();
      if (outerClass != null
          && !declClass.isInterface()
          && !declClass.isAnnotation()
          && !Modifier.isStatic(declClass.getModifiers())) {
        appendParameterSignature(outerClass.getErasure(), sb);
      }
    }

    appendParametersSignature(binding, sb);
    sb.append(')');
    appendReturnTypeSignature(binding, sb);
    return sb.toString();
  }
예제 #17
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;
  }
  @Override
  protected void printFunctionDeclaration(FunctionDeclaration function) {
    newline();
    // We expect native functions to be defined externally.
    if (!Modifier.isNative(function.getModifiers())) {
      print("__attribute__((unused)) static ");
    }
    print(getFunctionSignature(function));
    if (function.returnsRetained()) {
      print(" NS_RETURNS_RETAINED");
    }
    println(";");

    // TODO(kstanger): Remove when users have migrated.
    String name = function.getName();
    String oldName = function.getOldName();
    if (!oldName.equals(name)) {
      println("#ifdef J2OBJC_RENAME2_ALIASES");
      printf("#define %s %s\n", oldName, name);
      println("#endif // J2OBJC_RENAME2_ALIASES");
    }
  }
 // 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();
   }
 }
예제 #21
0
 public static boolean isVolatile(IVariableBinding binding) {
   return Modifier.isVolatile(binding.getModifiers());
 }
예제 #22
0
 public boolean isFinal() {
   return Modifier.isFinal(fDeclaration.getModifiers());
 }
예제 #23
0
 public static boolean isSynchronized(IBinding binding) {
   return Modifier.isSynchronized(binding.getModifiers());
 }
 /*
  * @see ASTVisitor#visit(Modifier)
  * @since 3.0
  */
 public boolean visit(Modifier node) {
   this.fBuffer.append(node.getKeyword().toString());
   return false;
 }
예제 #25
0
 public static boolean isFinal(IBinding binding) {
   return Modifier.isFinal(binding.getModifiers());
 }
예제 #26
0
 public static boolean isPrivate(IBinding binding) {
   return Modifier.isPrivate(binding.getModifiers());
 }
    private boolean fieldCanBeFinal(
        VariableDeclarationFragment fragment, IVariableBinding binding) {
      if (Modifier.isStatic(((FieldDeclaration) fragment.getParent()).getModifiers())) return false;

      if (!fWrittenVariables.containsKey(binding)) {
        // variable is not written
        if (fragment.getInitializer() == null) { // variable is not initialized
          return false;
        } else {
          return true;
        }
      }

      if (fragment.getInitializer() != null) // variable is initialized and written
      return false;

      ITypeBinding declaringClass = binding.getDeclaringClass();
      if (declaringClass == null) return false;

      ArrayList writes = (ArrayList) fWrittenVariables.get(binding);
      if (!isWrittenInTypeConstructors(writes, declaringClass)) return false;

      HashSet writingConstructorBindings = new HashSet();
      ArrayList writingConstructors = new ArrayList();
      for (int i = 0; i < writes.size(); i++) {
        SimpleName name = (SimpleName) writes.get(i);
        MethodDeclaration constructor = getWritingConstructor(name);
        if (writingConstructors.contains(
            constructor)) // variable is written twice or more in constructor
        return false;

        if (canReturn(constructor)) return false;

        writingConstructors.add(constructor);
        IMethodBinding constructorBinding = constructor.resolveBinding();
        if (constructorBinding == null) return false;

        writingConstructorBindings.add(constructorBinding);
      }

      for (int i = 0; i < writingConstructors.size(); i++) {
        MethodDeclaration constructor = (MethodDeclaration) writingConstructors.get(i);
        if (callsWritingConstructor(
            constructor,
            writingConstructorBindings)) // writing constructor calls other writing constructor
        return false;
      }

      MethodDeclaration constructor = (MethodDeclaration) writingConstructors.get(0);
      TypeDeclaration typeDecl =
          (TypeDeclaration) ASTNodes.getParent(constructor, TypeDeclaration.class);
      if (typeDecl == null) return false;

      MethodDeclaration[] methods = typeDecl.getMethods();
      for (int i = 0; i < methods.length; i++) {
        if (methods[i].isConstructor()) {
          IMethodBinding methodBinding = methods[i].resolveBinding();
          if (methodBinding == null) return false;

          if (!writingConstructorBindings.contains(methodBinding)) {
            if (!callsWritingConstructor(
                methods[i],
                writingConstructorBindings)) // non writing constructor does not call a writing
              // constructor
              return false;
          }
        }
      }

      return true;
    }
  private void createTryCatchStatement(org.eclipse.jdt.core.IBuffer buffer, String lineDelimiter)
      throws CoreException {
    List<Statement> result = new ArrayList<>(1);
    TryStatement tryStatement = getAST().newTryStatement();
    ITypeBinding[] exceptions = fAnalyzer.getExceptions();
    ImportRewriteContext context =
        new ContextSensitiveImportRewriteContext(
            fAnalyzer.getEnclosingBodyDeclaration(), fImportRewrite);

    if (!fIsMultiCatch) {
      for (int i = 0; i < exceptions.length; i++) {
        ITypeBinding exception = exceptions[i];
        CatchClause catchClause = getAST().newCatchClause();
        tryStatement.catchClauses().add(catchClause);
        SingleVariableDeclaration decl = getAST().newSingleVariableDeclaration();
        String varName = StubUtility.getExceptionVariableName(fCUnit.getJavaProject());

        String name = fScope.createName(varName, false);
        decl.setName(getAST().newSimpleName(name));
        Type type = fImportRewrite.addImport(exception, getAST(), context);
        decl.setType(type);
        catchClause.setException(decl);
        Statement st = getCatchBody(ASTNodes.getQualifiedTypeName(type), name, lineDelimiter);
        if (st != null) {
          catchClause.getBody().statements().add(st);
        }
        fLinkedProposalModel
            .getPositionGroup(GROUP_EXC_TYPE + i, true)
            .addPosition(fRewriter.track(decl.getType()), i == 0);
        fLinkedProposalModel
            .getPositionGroup(GROUP_EXC_NAME + i, true)
            .addPosition(fRewriter.track(decl.getName()), false);
      }
    } else {
      List<ITypeBinding> filteredExceptions = filterSubtypeExceptions(exceptions);
      CatchClause catchClause = getAST().newCatchClause();
      SingleVariableDeclaration decl = getAST().newSingleVariableDeclaration();
      String varName = StubUtility.getExceptionVariableName(fCUnit.getJavaProject());
      String name = fScope.createName(varName, false);
      decl.setName(getAST().newSimpleName(name));

      UnionType unionType = getAST().newUnionType();
      List<Type> types = unionType.types();
      int i = 0;
      for (ITypeBinding exception : filteredExceptions) {
        Type type = fImportRewrite.addImport(exception, getAST(), context);
        types.add(type);
        fLinkedProposalModel
            .getPositionGroup(GROUP_EXC_TYPE + i, true)
            .addPosition(fRewriter.track(type), i == 0);
        i++;
      }

      decl.setType(unionType);
      catchClause.setException(decl);
      fLinkedProposalModel
          .getPositionGroup(GROUP_EXC_NAME + 0, true)
          .addPosition(fRewriter.track(decl.getName()), false);
      Statement st = getCatchBody("Exception", name, lineDelimiter); // $NON-NLS-1$
      if (st != null) {
        catchClause.getBody().statements().add(st);
      }
      tryStatement.catchClauses().add(catchClause);
    }
    List<ASTNode> variableDeclarations = getSpecialVariableDeclarationStatements();
    ListRewrite statements =
        fRewriter.getListRewrite(tryStatement.getBody(), Block.STATEMENTS_PROPERTY);
    boolean selectedNodeRemoved = false;
    ASTNode expressionStatement = null;
    for (int i = 0; i < fSelectedNodes.length; i++) {
      ASTNode node = fSelectedNodes[i];
      if (node instanceof VariableDeclarationStatement && variableDeclarations.contains(node)) {
        AST ast = getAST();
        VariableDeclarationStatement statement = (VariableDeclarationStatement) node;
        // Create a copy and remove the initializer
        VariableDeclarationStatement copy =
            (VariableDeclarationStatement) ASTNode.copySubtree(ast, statement);
        List<IExtendedModifier> modifiers = copy.modifiers();
        for (Iterator<IExtendedModifier> iter = modifiers.iterator(); iter.hasNext(); ) {
          IExtendedModifier modifier = iter.next();
          if (modifier.isModifier()
              && Modifier.isFinal(((Modifier) modifier).getKeyword().toFlagValue())) {
            iter.remove();
          }
        }
        List<VariableDeclarationFragment> fragments = copy.fragments();
        for (Iterator<VariableDeclarationFragment> iter = fragments.iterator(); iter.hasNext(); ) {
          VariableDeclarationFragment fragment = iter.next();
          fragment.setInitializer(null);
        }
        CompilationUnit root = (CompilationUnit) statement.getRoot();
        int extendedStart = root.getExtendedStartPosition(statement);
        // we have a leading comment and the comment is covered by the selection
        if (extendedStart != statement.getStartPosition()
            && extendedStart >= fSelection.getOffset()) {
          String commentToken =
              buffer.getText(extendedStart, statement.getStartPosition() - extendedStart);
          commentToken = Strings.trimTrailingTabsAndSpaces(commentToken);
          Type type = statement.getType();
          String typeName = buffer.getText(type.getStartPosition(), type.getLength());
          copy.setType(
              (Type)
                  fRewriter.createStringPlaceholder(commentToken + typeName, type.getNodeType()));
        }
        result.add(copy);
        // convert the fragments into expression statements
        fragments = statement.fragments();
        if (!fragments.isEmpty()) {
          List<ExpressionStatement> newExpressionStatements = new ArrayList<>();
          for (Iterator<VariableDeclarationFragment> iter = fragments.iterator();
              iter.hasNext(); ) {
            VariableDeclarationFragment fragment = iter.next();
            Expression initializer = fragment.getInitializer();
            if (initializer != null) {
              Assignment assignment = ast.newAssignment();
              assignment.setLeftHandSide(
                  (Expression) fRewriter.createCopyTarget(fragment.getName()));
              assignment.setRightHandSide((Expression) fRewriter.createCopyTarget(initializer));
              newExpressionStatements.add(ast.newExpressionStatement(assignment));
            }
          }
          if (!newExpressionStatements.isEmpty()) {
            if (fSelectedNodes.length == 1) {
              expressionStatement =
                  fRewriter.createGroupNode(
                      newExpressionStatements.toArray(new ASTNode[newExpressionStatements.size()]));
            } else {
              fRewriter.replace(
                  statement,
                  fRewriter.createGroupNode(
                      newExpressionStatements.toArray(new ASTNode[newExpressionStatements.size()])),
                  null);
            }
          } else {
            fRewriter.remove(statement, null);
            selectedNodeRemoved = true;
          }
        } else {
          fRewriter.remove(statement, null);
          selectedNodeRemoved = true;
        }
      }
    }
    result.add(tryStatement);
    ASTNode replacementNode;
    if (result.size() == 1) {
      replacementNode = result.get(0);
    } else {
      replacementNode = fRewriter.createGroupNode(result.toArray(new ASTNode[result.size()]));
    }
    if (fSelectedNodes.length == 1) {
      ASTNode selectedNode = fSelectedNodes[0];

      if (selectedNode instanceof MethodReference) {
        MethodReference methodReference = (MethodReference) selectedNode;
        IMethodBinding functionalMethod =
            QuickAssistProcessor.getFunctionalMethodForMethodReference(methodReference);
        // functionalMethod is non-null and non-generic. See
        // ExceptionAnalyzer.handleMethodReference(MethodReference node).
        Assert.isTrue(functionalMethod != null && !functionalMethod.isGenericMethod());
        LambdaExpression lambda =
            QuickAssistProcessor.convertMethodRefernceToLambda(
                methodReference, functionalMethod, fRootNode, fRewriter, null, true);
        ASTNode statementInBlock = (ASTNode) ((Block) lambda.getBody()).statements().get(0);
        fRewriter.replace(statementInBlock, replacementNode, null);
        statements.insertLast(statementInBlock, null);
        return;
      }

      LambdaExpression enclosingLambda = ASTResolving.findEnclosingLambdaExpression(selectedNode);
      if (enclosingLambda != null
          && selectedNode.getLocationInParent() == LambdaExpression.BODY_PROPERTY
          && enclosingLambda.resolveMethodBinding() != null) {
        QuickAssistProcessor.changeLambdaBodyToBlock(enclosingLambda, getAST(), fRewriter);
        Block blockBody = (Block) fRewriter.get(enclosingLambda, LambdaExpression.BODY_PROPERTY);
        ASTNode statementInBlock = (ASTNode) blockBody.statements().get(0);
        fRewriter.replace(statementInBlock, replacementNode, null);
        statements.insertLast(statementInBlock, null);
        return;
      }

      if (expressionStatement != null) {
        statements.insertLast(expressionStatement, null);
      } else {
        if (!selectedNodeRemoved)
          statements.insertLast(fRewriter.createMoveTarget(selectedNode), null);
      }
      fRewriter.replace(selectedNode, replacementNode, null);
    } else {
      ListRewrite source =
          fRewriter.getListRewrite(
              fSelectedNodes[0].getParent(),
              (ChildListPropertyDescriptor) fSelectedNodes[0].getLocationInParent());
      ASTNode toMove =
          source.createMoveTarget(
              fSelectedNodes[0], fSelectedNodes[fSelectedNodes.length - 1], replacementNode, null);
      statements.insertLast(toMove, null);
    }
  }
예제 #29
0
 public static boolean isAbstract(IBinding binding) {
   return Modifier.isAbstract(binding.getModifiers());
 }
 public Change createChange(IProgressMonitor pm) throws CoreException {
   if (fDeleteSource && fCurrentMode == Mode.INLINE_ALL) {
     TextChange change = fChangeManager.get((ICompilationUnit) fSourceProvider.getTypeRoot());
     TextEdit delete = fSourceProvider.getDeleteEdit();
     TextEditGroup description =
         new TextEditGroup(
             RefactoringCoreMessages.InlineMethodRefactoring_edit_delete, new TextEdit[] {delete});
     TextEdit root = change.getEdit();
     if (root != null) {
       // TODO instead of finding the right insert position the call inliner should
       // reuse the AST & rewriter of the source provide and we should rewrite the
       // whole AST at the end. However, since recursive calls aren't allowed there
       // shouldn't be a text edit overlap.
       // root.addChild(delete);
       TextChangeCompatibility.insert(root, delete);
     } else {
       change.setEdit(delete);
     }
     change.addTextEditGroup(description);
   }
   final Map arguments = new HashMap();
   String project = null;
   IJavaProject javaProject = fInitialTypeRoot.getJavaProject();
   if (javaProject != null) project = javaProject.getElementName();
   int flags =
       RefactoringDescriptor.STRUCTURAL_CHANGE
           | JavaRefactoringDescriptor.JAR_REFACTORING
           | JavaRefactoringDescriptor.JAR_SOURCE_ATTACHMENT;
   final IMethodBinding binding = fSourceProvider.getDeclaration().resolveBinding();
   final ITypeBinding declaring = binding.getDeclaringClass();
   if (!Modifier.isPrivate(binding.getModifiers())) flags |= RefactoringDescriptor.MULTI_CHANGE;
   final String description =
       Messages.format(
           RefactoringCoreMessages.InlineMethodRefactoring_descriptor_description_short,
           BasicElementLabels.getJavaElementName(binding.getName()));
   final String header =
       Messages.format(
           RefactoringCoreMessages.InlineMethodRefactoring_descriptor_description,
           new String[] {
             BindingLabelProvider.getBindingLabel(binding, JavaElementLabels.ALL_FULLY_QUALIFIED),
             BindingLabelProvider.getBindingLabel(declaring, JavaElementLabels.ALL_FULLY_QUALIFIED)
           });
   final JDTRefactoringDescriptorComment comment =
       new JDTRefactoringDescriptorComment(project, this, header);
   comment.addSetting(
       Messages.format(
           RefactoringCoreMessages.InlineMethodRefactoring_original_pattern,
           BindingLabelProvider.getBindingLabel(binding, JavaElementLabels.ALL_FULLY_QUALIFIED)));
   if (fDeleteSource)
     comment.addSetting(RefactoringCoreMessages.InlineMethodRefactoring_remove_method);
   if (fCurrentMode == Mode.INLINE_ALL)
     comment.addSetting(RefactoringCoreMessages.InlineMethodRefactoring_replace_references);
   final InlineMethodDescriptor descriptor =
       RefactoringSignatureDescriptorFactory.createInlineMethodDescriptor(
           project, description, comment.asString(), arguments, flags);
   arguments.put(
       JavaRefactoringDescriptorUtil.ATTRIBUTE_INPUT,
       JavaRefactoringDescriptorUtil.elementToHandle(project, fInitialTypeRoot));
   arguments.put(
       JavaRefactoringDescriptorUtil.ATTRIBUTE_SELECTION,
       new Integer(fSelectionStart).toString()
           + " "
           + new Integer(fSelectionLength).toString()); // $NON-NLS-1$
   arguments.put(ATTRIBUTE_DELETE, Boolean.valueOf(fDeleteSource).toString());
   arguments.put(ATTRIBUTE_MODE, new Integer(fCurrentMode == Mode.INLINE_ALL ? 1 : 0).toString());
   return new DynamicValidationRefactoringChange(
       descriptor,
       RefactoringCoreMessages.InlineMethodRefactoring_edit_inlineCall,
       fChangeManager.getAllChanges());
 }