/* * @see org.eclipse.jdt.internal.ui.text.java.LazyJavaCompletionProposal#apply(org.eclipse.jface.text.IDocument, char, int) */ @Override public void apply(IDocument document, char trigger, int offset) { try { boolean insertClosingParenthesis = trigger == '(' && autocloseBrackets(); if (insertClosingParenthesis) { StringBuffer replacement = new StringBuffer(getReplacementString()); updateReplacementWithParentheses(replacement); setReplacementString(replacement.toString()); trigger = '\0'; } super.apply(document, trigger, offset); if (fImportRewrite != null && fImportRewrite.hasRecordedChanges()) { int oldLen = document.getLength(); fImportRewrite .rewriteImports(new NullProgressMonitor()) .apply(document, TextEdit.UPDATE_REGIONS); setReplacementOffset(getReplacementOffset() + document.getLength() - oldLen); } if (insertClosingParenthesis) setUpLinkedMode(document, ')'); rememberSelection(); } catch (CoreException e) { JavaPlugin.log(e); } catch (BadLocationException e) { JavaPlugin.log(e); } }
@Override protected ASTRewrite getRewrite() throws CoreException { ASTNode boundNode = fAstRoot.findDeclaringNode(fBinding); ASTNode declNode = null; CompilationUnit newRoot = fAstRoot; if (boundNode != null) { declNode = boundNode; // is same CU } else { newRoot = ASTResolving.createQuickFixAST(getCompilationUnit(), null); declNode = newRoot.findDeclaringNode(fBinding.getKey()); } ImportRewrite imports = createImportRewrite(newRoot); if (declNode instanceof TypeDeclaration) { AST ast = declNode.getAST(); ASTRewrite rewrite = ASTRewrite.create(ast); ImportRewriteContext importRewriteContext = new ContextSensitiveImportRewriteContext(declNode, imports); Type newInterface = imports.addImport(fNewInterface, ast, importRewriteContext); ListRewrite listRewrite = rewrite.getListRewrite(declNode, TypeDeclaration.SUPER_INTERFACE_TYPES_PROPERTY); listRewrite.insertLast(newInterface, null); // set up linked mode final String KEY_TYPE = "type"; // $NON-NLS-1$ addLinkedPosition(rewrite.track(newInterface), true, KEY_TYPE); return rewrite; } return null; }
private Type evaluateVariableType( AST ast, ImportRewrite imports, ImportRewriteContext importRewriteContext, IBinding targetContext) { if (fOriginalNode.getParent() instanceof MethodInvocation) { MethodInvocation parent = (MethodInvocation) fOriginalNode.getParent(); if (parent.getExpression() == fOriginalNode) { // _x_.foo() -> guess qualifier type by looking for a type with method 'foo' ITypeBinding[] bindings = ASTResolving.getQualifierGuess( fOriginalNode.getRoot(), parent.getName().getIdentifier(), parent.arguments(), targetContext); if (bindings.length > 0) { for (int i = 0; i < bindings.length; i++) { addLinkedPositionProposal(KEY_TYPE, bindings[i]); } return imports.addImport(bindings[0], ast, importRewriteContext); } } } ITypeBinding binding = ASTResolving.guessBindingForReference(fOriginalNode); if (binding != null) { if (binding.isWildcardType()) { binding = ASTResolving.normalizeWildcardType(binding, isVariableAssigned(), ast); if (binding == null) { // only null binding applies binding = ast.resolveWellKnownType("java.lang.Object"); // $NON-NLS-1$ } } if (isVariableAssigned()) { ITypeBinding[] typeProposals = ASTResolving.getRelaxingTypes(ast, binding); for (int i = 0; i < typeProposals.length; i++) { addLinkedPositionProposal(KEY_TYPE, typeProposals[i]); } } return imports.addImport(binding, ast, importRewriteContext); } // no binding, find type AST node instead -> ABC a= x-> use 'ABC' as is Type type = ASTResolving.guessTypeForReference(ast, fOriginalNode); if (type != null) { return type; } if (fVariableKind == CONST_FIELD) { return ast.newSimpleType(ast.newSimpleName("String")); // $NON-NLS-1$ } return ast.newSimpleType(ast.newSimpleName("Object")); // $NON-NLS-1$ }
private Type getConstantType() throws JavaModelException { if (fConstantTypeCache == null) { IExpressionFragment fragment = getSelectedExpression(); ITypeBinding typeBinding = guessBindingForReference(fragment.getAssociatedExpression()); AST ast = fCuRewrite.getAST(); typeBinding = Bindings.normalizeForDeclarationUse(typeBinding, ast); ImportRewrite importRewrite = fCuRewrite.getImportRewrite(); ImportRewriteContext context = new ContextSensitiveImportRewriteContext( fCuRewrite.getRoot(), fSelectionStart, importRewrite); fConstantTypeCache = importRewrite.addImport(typeBinding, ast, context); } return fConstantTypeCache; }
private void rewriteImports() { if (fImportRewrite == null) return; if (isReadOnly()) return; ICompilationUnit cu = getCompilationUnit(); if (cu == null) return; try { Position position = new Position(getCompletionOffset(), 0); IDocument document = getDocument(); final String category = "__template_position_importer" + System.currentTimeMillis(); // $NON-NLS-1$ IPositionUpdater updater = new DefaultPositionUpdater(category); document.addPositionCategory(category); document.addPositionUpdater(updater); document.addPosition(position); try { JavaModelUtil.applyEdit(cu, fImportRewrite.rewriteImports(null), false, null); setCompletionOffset(position.getOffset()); } catch (CoreException e) { handleException(null, e); } finally { document.removePosition(position); document.removePositionUpdater(updater); document.removePositionCategory(category); } } catch (BadLocationException e) { handleException(null, e); } catch (BadPositionCategoryException e) { handleException(null, e); } }
public void applyRemoves(ImportRewrite importRewrite) { IBinding[] bindings = getImportsToRemove(); for (int i = 0; i < bindings.length; i++) { if (bindings[i] instanceof ITypeBinding) { ITypeBinding typeBinding = (ITypeBinding) bindings[i]; importRewrite.removeImport(typeBinding.getTypeDeclaration().getQualifiedName()); } else if (bindings[i] instanceof IMethodBinding) { IMethodBinding binding = (IMethodBinding) bindings[i]; importRewrite.removeStaticImport( binding.getDeclaringClass().getQualifiedName() + '.' + binding.getName()); } else if (bindings[i] instanceof IVariableBinding) { IVariableBinding binding = (IVariableBinding) bindings[i]; importRewrite.removeStaticImport( binding.getDeclaringClass().getQualifiedName() + '.' + binding.getName()); } } }
private void addImports(final ICompilationUnit unit, ClipboardData data) throws CoreException { final ImportRewrite rewrite = StubUtility.createImportRewrite(unit, true); String[] imports = data.getTypeImports(); for (int i = 0; i < imports.length; i++) { rewrite.addImport(imports[i]); } String[] staticImports = data.getStaticImports(); for (int i = 0; i < staticImports.length; i++) { String name = Signature.getSimpleName(staticImports[i]); boolean isField = !name.endsWith("()"); // $NON-NLS-1$ if (!isField) { name = name.substring(0, name.length() - 2); } String qualifier = Signature.getQualifier(staticImports[i]); rewrite.addStaticImport(qualifier, name, isField); } try { getProgressService() .busyCursorWhile( new IRunnableWithProgress() { public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { try { JavaModelUtil.applyEdit(unit, rewrite.rewriteImports(monitor), false, null); } catch (CoreException e) { throw new InvocationTargetException(e); } } }); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); if (cause instanceof CoreException) throw (CoreException) cause; throw new CoreException( new Status( IStatus.ERROR, JavaUI.ID_PLUGIN, IJavaStatusConstants.INTERNAL_ERROR, JavaUIMessages.JavaPlugin_internal_error, cause)); } catch (InterruptedException e) { // Canceled by the user } }
private String createImportForAccessor( MultiTextEdit parent, String accessorClassName, IPackageFragment accessorPackage, ICompilationUnit cu) throws CoreException { IType type = accessorPackage .getCompilationUnit(accessorClassName + JavaModelUtil.DEFAULT_CU_SUFFIX) .getType(accessorClassName); String fullyQualifiedName = type.getFullyQualifiedName(); ImportRewrite importRewrite = StubUtility.createImportRewrite(cu, true); String nameToUse = importRewrite.addImport(fullyQualifiedName); TextEdit edit = importRewrite.rewriteImports(null); parent.addChild(edit); return nameToUse; }
/* non Java-doc * @see IRefactoring#createChange(IProgressMonitor) */ @Override public Change createChange(IProgressMonitor pm) throws CoreException { final String NN = ""; // $NON-NLS-1$ if (pm == null) pm = new NullProgressMonitor(); pm.beginTask(NN, 2); try { final CompilationUnitChange result = new CompilationUnitChange(getName(), fCUnit); if (fLeaveDirty) result.setSaveMode(TextFileChange.LEAVE_DIRTY); MultiTextEdit root = new MultiTextEdit(); result.setEdit(root); fRewriter = ASTRewrite.create(fAnalyzer.getEnclosingBodyDeclaration().getAST()); fRewriter.setTargetSourceRangeComputer( new SelectionAwareSourceRangeComputer( fAnalyzer.getSelectedNodes(), fCUnit.getBuffer(), fSelection.getOffset(), fSelection.getLength())); fImportRewrite = StubUtility.createImportRewrite(fRootNode, true); fLinkedProposalModel = new LinkedProposalModel(); fScope = CodeScopeBuilder.perform(fAnalyzer.getEnclosingBodyDeclaration(), fSelection) .findScope(fSelection.getOffset(), fSelection.getLength()); fScope.setCursor(fSelection.getOffset()); fSelectedNodes = fAnalyzer.getSelectedNodes(); createTryCatchStatement(fCUnit.getBuffer(), fCUnit.findRecommendedLineSeparator()); if (fImportRewrite.hasRecordedChanges()) { TextEdit edit = fImportRewrite.rewriteImports(null); root.addChild(edit); result.addTextEditGroup(new TextEditGroup(NN, new TextEdit[] {edit})); } TextEdit change = fRewriter.rewriteAST(); root.addChild(change); result.addTextEditGroup(new TextEditGroup(NN, new TextEdit[] {change})); return result; } finally { pm.done(); } }
/** * Adds a static import for the member with name <code>qualifiedMemberName</code>. The member is * either a static field or a static method or a '*' to import all static members of a type. * * @param qualifiedMemberName the fully qualified name of the member to import or a qualified type * name plus a '.*' suffix. * @return returns either the simple member name if the import was successful or else the * qualified name. * @since 3.4 */ public String addStaticImport(String qualifiedMemberName) { if (isReadOnly()) return qualifiedMemberName; ICompilationUnit cu = getCompilationUnit(); if (cu == null) return qualifiedMemberName; int memberOffset = qualifiedMemberName.lastIndexOf('.'); if (memberOffset == -1) return qualifiedMemberName; String typeName = qualifiedMemberName.substring(0, memberOffset); String memberName = qualifiedMemberName.substring(memberOffset + 1, qualifiedMemberName.length()); try { boolean isField; if ("*".equals(memberName)) { // $NON-NLS-1$ isField = true; } else { IJavaProject javaProject = cu.getJavaProject(); IType type = javaProject.findType(typeName); if (type == null) return qualifiedMemberName; IField field = type.getField(memberName); if (field.exists()) { isField = true; } else if (hasMethod(type, memberName)) { isField = false; } else { return qualifiedMemberName; } } CompilationUnit root = getASTRoot(cu); if (fImportRewrite == null) { if (root == null) { fImportRewrite = StubUtility.createImportRewrite(cu, true); } else { fImportRewrite = StubUtility.createImportRewrite(root, true); } } ImportRewriteContext context; if (root == null) context = null; else context = new ContextSensitiveImportRewriteContext(root, getCompletionOffset(), fImportRewrite); return fImportRewrite.addStaticImport(typeName, memberName, isField, context); } catch (JavaModelException e) { handleException(null, e); return typeName; } }
/** * Adds an import for type with type name <code>type</code> if possible. Returns a string which * can be used to reference the type. * * @param type the fully qualified name of the type to import * @return returns a type to which the type binding can be assigned to. The returned type contains * is unqualified when an import could be added or was already known. It is fully qualified, * if an import conflict prevented the import. * @since 3.4 */ public String addImport(String type) { if (isReadOnly()) return type; ICompilationUnit cu = getCompilationUnit(); if (cu == null) return type; try { boolean qualified = type.indexOf('.') != -1; if (!qualified) { IJavaSearchScope searchScope = SearchEngine.createJavaSearchScope(new IJavaElement[] {cu.getJavaProject()}); SimpleName nameNode = null; TypeNameMatch[] matches = findAllTypes(type, searchScope, nameNode, null, cu); if (matches.length != 1) // only add import if we have a single match return type; type = matches[0].getFullyQualifiedName(); } CompilationUnit root = getASTRoot(cu); if (fImportRewrite == null) { if (root == null) { fImportRewrite = StubUtility.createImportRewrite(cu, true); } else { fImportRewrite = StubUtility.createImportRewrite(root, true); } } ImportRewriteContext context; if (root == null) context = null; else context = new ContextSensitiveImportRewriteContext(root, getCompletionOffset(), fImportRewrite); return fImportRewrite.addImport(type, context); } catch (JavaModelException e) { handleException(null, e); return type; } }
private void initReturnType(ImportRewrite rewriter) { AST ast = fEnclosingBodyDeclaration.getAST(); fReturnType = null; fReturnTypeBinding = null; switch (fReturnKind) { case ACCESS_TO_LOCAL: VariableDeclaration declaration = ASTNodes.findVariableDeclaration(fReturnValue, fEnclosingBodyDeclaration); fReturnType = ASTNodeFactory.newType( ast, declaration, rewriter, new ContextSensitiveImportRewriteContext(declaration, rewriter)); if (declaration.resolveBinding() != null) { fReturnTypeBinding = declaration.resolveBinding().getType(); } break; case EXPRESSION: Expression expression = (Expression) getFirstSelectedNode(); if (expression.getNodeType() == ASTNode.CLASS_INSTANCE_CREATION) { fExpressionBinding = ((ClassInstanceCreation) expression).getType().resolveBinding(); } else { fExpressionBinding = expression.resolveTypeBinding(); } if (fExpressionBinding != null) { if (fExpressionBinding.isNullType()) { getStatus() .addFatalError( RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_null_type, JavaStatusContext.create(fCUnit, expression)); } else { ITypeBinding normalizedBinding = Bindings.normalizeForDeclarationUse(fExpressionBinding, ast); if (normalizedBinding != null) { ImportRewriteContext context = new ContextSensitiveImportRewriteContext(fEnclosingBodyDeclaration, rewriter); fReturnType = rewriter.addImport(normalizedBinding, ast, context); fReturnTypeBinding = normalizedBinding; } } } else { fReturnType = ast.newPrimitiveType(PrimitiveType.VOID); fReturnTypeBinding = ast.resolveWellKnownType("void"); // $NON-NLS-1$ getStatus() .addError( RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_determine_return_type, JavaStatusContext.create(fCUnit, expression)); } break; case RETURN_STATEMENT_VALUE: LambdaExpression enclosingLambdaExpr = ASTResolving.findEnclosingLambdaExpression(getFirstSelectedNode()); if (enclosingLambdaExpr != null) { fReturnType = ASTNodeFactory.newReturnType(enclosingLambdaExpr, ast, rewriter, null); IMethodBinding methodBinding = enclosingLambdaExpr.resolveMethodBinding(); fReturnTypeBinding = methodBinding != null ? methodBinding.getReturnType() : null; } else if (fEnclosingBodyDeclaration.getNodeType() == ASTNode.METHOD_DECLARATION) { fReturnType = ((MethodDeclaration) fEnclosingBodyDeclaration).getReturnType2(); fReturnTypeBinding = fReturnType != null ? fReturnType.resolveBinding() : null; } break; default: fReturnType = ast.newPrimitiveType(PrimitiveType.VOID); fReturnTypeBinding = ast.resolveWellKnownType("void"); // $NON-NLS-1$ } if (fReturnType == null) { fReturnType = ast.newPrimitiveType(PrimitiveType.VOID); fReturnTypeBinding = ast.resolveWellKnownType("void"); // $NON-NLS-1$ } }
private ASTRewrite doAddLocal(CompilationUnit cu) { AST ast = cu.getAST(); Block body; BodyDeclaration decl = ASTResolving.findParentBodyDeclaration(fOriginalNode); IBinding targetContext = null; if (decl instanceof MethodDeclaration) { body = (((MethodDeclaration) decl).getBody()); targetContext = ((MethodDeclaration) decl).resolveBinding(); } else if (decl instanceof Initializer) { body = (((Initializer) decl).getBody()); targetContext = Bindings.getBindingOfParentType(decl); } else { return null; } ASTRewrite rewrite = ASTRewrite.create(ast); ImportRewrite imports = createImportRewrite((CompilationUnit) decl.getRoot()); ImportRewriteContext importRewriteContext = new ContextSensitiveImportRewriteContext(decl, imports); SimpleName[] names = getAllReferences(body); ASTNode dominant = getDominantNode(names); Statement dominantStatement = ASTResolving.findParentStatement(dominant); if (ASTNodes.isControlStatementBody(dominantStatement.getLocationInParent())) { dominantStatement = (Statement) dominantStatement.getParent(); } SimpleName node = names[0]; if (isAssigned(dominantStatement, node)) { // x = 1; -> int x = 1; Assignment assignment = (Assignment) node.getParent(); // trick to avoid comment removal around the statement: keep the expression statement // and replace the assignment with an VariableDeclarationExpression VariableDeclarationFragment newDeclFrag = ast.newVariableDeclarationFragment(); VariableDeclarationExpression newDecl = ast.newVariableDeclarationExpression(newDeclFrag); newDecl.setType(evaluateVariableType(ast, imports, importRewriteContext, targetContext)); Expression placeholder = (Expression) rewrite.createCopyTarget(assignment.getRightHandSide()); newDeclFrag.setInitializer(placeholder); newDeclFrag.setName(ast.newSimpleName(node.getIdentifier())); rewrite.replace(assignment, newDecl, null); addLinkedPosition(rewrite.track(newDecl.getType()), false, KEY_TYPE); addLinkedPosition(rewrite.track(newDeclFrag.getName()), true, KEY_NAME); setEndPosition(rewrite.track(assignment.getParent())); return rewrite; } else if ((dominant != dominantStatement) && isForStatementInit(dominantStatement, node)) { // for (x = 1;;) ->for (int x = 1;;) Assignment assignment = (Assignment) node.getParent(); VariableDeclarationFragment frag = ast.newVariableDeclarationFragment(); VariableDeclarationExpression expression = ast.newVariableDeclarationExpression(frag); frag.setName(ast.newSimpleName(node.getIdentifier())); Expression placeholder = (Expression) rewrite.createCopyTarget(assignment.getRightHandSide()); frag.setInitializer(placeholder); expression.setType(evaluateVariableType(ast, imports, importRewriteContext, targetContext)); rewrite.replace(assignment, expression, null); addLinkedPosition(rewrite.track(expression.getType()), false, KEY_TYPE); addLinkedPosition(rewrite.track(frag.getName()), true, KEY_NAME); setEndPosition(rewrite.track(expression)); return rewrite; } else if ((dominant != dominantStatement) && isEnhancedForStatementVariable(dominantStatement, node)) { // for (x: collectionOfT) -> for (T x: collectionOfT) EnhancedForStatement enhancedForStatement = (EnhancedForStatement) dominantStatement; SingleVariableDeclaration parameter = enhancedForStatement.getParameter(); Expression expression = enhancedForStatement.getExpression(); SimpleName newName = (SimpleName) rewrite.createMoveTarget(node); rewrite.set(parameter, SingleVariableDeclaration.NAME_PROPERTY, newName, null); ITypeBinding elementBinding = null; ITypeBinding typeBinding = expression.resolveTypeBinding(); if (typeBinding != null) { if (typeBinding.isArray()) { elementBinding = typeBinding.getElementType(); } else { ITypeBinding iterable = Bindings.findTypeInHierarchy(typeBinding, "java.lang.Iterable"); // $NON-NLS-1$ if (iterable != null) { ITypeBinding[] typeArguments = iterable.getTypeArguments(); if (typeArguments.length == 1) { elementBinding = typeArguments[0]; elementBinding = Bindings.normalizeForDeclarationUse(elementBinding, ast); } } } } Type type; if (elementBinding != null) { type = imports.addImport(elementBinding, ast, importRewriteContext); } else { type = ast.newSimpleType(ast.newSimpleName("Object")); // $NON-NLS-1$ } rewrite.set(parameter, SingleVariableDeclaration.TYPE_PROPERTY, type, null); addLinkedPosition(rewrite.track(type), false, KEY_TYPE); addLinkedPosition(rewrite.track(newName), true, KEY_NAME); setEndPosition(rewrite.track(expression)); return rewrite; } // foo(x) -> int x; foo(x) VariableDeclarationFragment newDeclFrag = ast.newVariableDeclarationFragment(); VariableDeclarationStatement newDecl = ast.newVariableDeclarationStatement(newDeclFrag); newDeclFrag.setName(ast.newSimpleName(node.getIdentifier())); newDecl.setType(evaluateVariableType(ast, imports, importRewriteContext, targetContext)); // newDeclFrag.setInitializer(ASTNodeFactory.newDefaultExpression(ast, newDecl.getType(), 0)); addLinkedPosition(rewrite.track(newDecl.getType()), false, KEY_TYPE); addLinkedPosition(rewrite.track(node), true, KEY_NAME); addLinkedPosition(rewrite.track(newDeclFrag.getName()), false, KEY_NAME); Statement statement = dominantStatement; List<? extends ASTNode> list = ASTNodes.getContainingList(statement); while (list == null && statement.getParent() instanceof Statement) { // parent must be if, for or while statement = (Statement) statement.getParent(); list = ASTNodes.getContainingList(statement); } if (list != null) { ASTNode parent = statement.getParent(); StructuralPropertyDescriptor childProperty = statement.getLocationInParent(); if (childProperty.isChildListProperty()) { rewrite .getListRewrite(parent, (ChildListPropertyDescriptor) childProperty) .insertBefore(newDecl, statement, null); return rewrite; } else { return null; } } return rewrite; }
/* * @see org.eclipse.jdt.internal.ui.text.java.LazyJavaCompletionProposal#computeReplacementString() */ @Override protected String computeReplacementString() { String replacement = super.computeReplacementString(); /* No import rewriting ever from within the import section. */ if (isImportCompletion()) return replacement; /* Always use the simple name for non-formal javadoc references to types. */ // TODO fix if (fProposal.getKind() == CompletionProposal.TYPE_REF && fInvocationContext.getCoreContext().isInJavadocText()) return getSimpleTypeName(); String qualifiedTypeName = getQualifiedTypeName(); // Type in package info must be fully qualified. if (fCompilationUnit != null && JavaModelUtil.isPackageInfo(fCompilationUnit)) return qualifiedTypeName; if (qualifiedTypeName.indexOf('.') == -1 && replacement.length() > 0) // default package - no imports needed return qualifiedTypeName; /* * If the user types in the qualification, don't force import rewriting on him - insert the * qualified name. */ IDocument document = fInvocationContext.getDocument(); if (document != null) { String prefix = getPrefix(document, getReplacementOffset() + getReplacementLength()); int dotIndex = prefix.lastIndexOf('.'); // match up to the last dot in order to make higher level matching still work (camel case...) if (dotIndex != -1 && qualifiedTypeName .toLowerCase() .startsWith(prefix.substring(0, dotIndex + 1).toLowerCase())) return qualifiedTypeName; } /* * The replacement does not contain a qualification (e.g. an inner type qualified by its * parent) - use the replacement directly. */ if (replacement.indexOf('.') == -1) { if (isInJavadoc()) return getSimpleTypeName(); // don't use the braces added for javadoc link proposals return replacement; } /* Add imports if the preference is on. */ if (fImportRewrite == null) fImportRewrite = createImportRewrite(); if (fImportRewrite != null) { return fImportRewrite.addImport(qualifiedTypeName, fImportContext); } // fall back for the case we don't have an import rewrite (see allowAddingImports) /* No imports for implicit imports. */ if (fCompilationUnit != null && JavaModelUtil.isImplicitImport( Signature.getQualifier(qualifiedTypeName), fCompilationUnit)) { return Signature.getSimpleName(qualifiedTypeName); } /* Default: use the fully qualified type name. */ return qualifiedTypeName; }
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); } }
public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException { pm.beginTask("", 20); // $NON-NLS-1$ fChangeManager = new TextChangeManager(); RefactoringStatus result = new RefactoringStatus(); fSourceProvider.initialize(); fTargetProvider.initialize(); pm.setTaskName(RefactoringCoreMessages.InlineMethodRefactoring_searching); RefactoringStatus searchStatus = new RefactoringStatus(); String binaryRefsDescription = Messages.format( RefactoringCoreMessages.ReferencesInBinaryContext_ref_in_binaries_description, BasicElementLabels.getJavaElementName(fSourceProvider.getMethodName())); ReferencesInBinaryContext binaryRefs = new ReferencesInBinaryContext(binaryRefsDescription); ICompilationUnit[] units = fTargetProvider.getAffectedCompilationUnits( searchStatus, binaryRefs, new SubProgressMonitor(pm, 1)); binaryRefs.addErrorIfNecessary(searchStatus); if (searchStatus.hasFatalError()) { result.merge(searchStatus); return result; } IFile[] filesToBeModified = getFilesToBeModified(units); result.merge(Checks.validateModifiesFiles(filesToBeModified, getValidationContext())); if (result.hasFatalError()) return result; result.merge( ResourceChangeChecker.checkFilesToBeChanged( filesToBeModified, new SubProgressMonitor(pm, 1))); checkOverridden(result, new SubProgressMonitor(pm, 4)); IProgressMonitor sub = new SubProgressMonitor(pm, 15); sub.beginTask("", units.length * 3); // $NON-NLS-1$ for (int c = 0; c < units.length; c++) { ICompilationUnit unit = units[c]; sub.subTask( Messages.format( RefactoringCoreMessages.InlineMethodRefactoring_processing, BasicElementLabels.getFileName(unit))); CallInliner inliner = null; try { boolean added = false; MultiTextEdit root = new MultiTextEdit(); CompilationUnitChange change = (CompilationUnitChange) fChangeManager.get(unit); change.setEdit(root); BodyDeclaration[] bodies = fTargetProvider.getAffectedBodyDeclarations(unit, new SubProgressMonitor(pm, 1)); if (bodies.length == 0) continue; inliner = new CallInliner(unit, (CompilationUnit) bodies[0].getRoot(), fSourceProvider); for (int b = 0; b < bodies.length; b++) { BodyDeclaration body = bodies[b]; inliner.initialize(body); RefactoringStatus nestedInvocations = new RefactoringStatus(); ASTNode[] invocations = removeNestedCalls( nestedInvocations, unit, fTargetProvider.getInvocations(body, new SubProgressMonitor(sub, 2))); for (int i = 0; i < invocations.length; i++) { ASTNode invocation = invocations[i]; result.merge(inliner.initialize(invocation, fTargetProvider.getStatusSeverity())); if (result.hasFatalError()) break; if (result.getSeverity() < fTargetProvider.getStatusSeverity()) { added = true; TextEditGroup group = new TextEditGroup(RefactoringCoreMessages.InlineMethodRefactoring_edit_inline); change.addTextEditGroup(group); result.merge(inliner.perform(group)); } else { fDeleteSource = false; } } // do this after we have inlined the method calls. We still want // to generate the modifications. if (!nestedInvocations.isOK()) { result.merge(nestedInvocations); fDeleteSource = false; } } if (!added) { fChangeManager.remove(unit); } else { root.addChild(inliner.getModifications()); ImportRewrite rewrite = inliner.getImportEdit(); if (rewrite.hasRecordedChanges()) { TextEdit edit = rewrite.rewriteImports(null); if (edit instanceof MultiTextEdit ? ((MultiTextEdit) edit).getChildrenSize() > 0 : true) { root.addChild(edit); change.addTextEditGroup( new TextEditGroup( RefactoringCoreMessages.InlineMethodRefactoring_edit_import, new TextEdit[] {edit})); } } } } finally { if (inliner != null) inliner.dispose(); } sub.worked(1); if (sub.isCanceled()) throw new OperationCanceledException(); } result.merge(searchStatus); sub.done(); pm.done(); return result; }