/** * Updates a javadoc tag, by either adding a new one or removing an existing one * * @param body */ private void updateTag(BodyDeclaration body) { Javadoc docnode = body.getJavadoc(); AST ast = body.getAST(); if (docnode == null) { docnode = ast.newJavadoc(); rewrite.set(body, body.getJavadocProperty(), docnode, null); } ListRewrite lrewrite = rewrite.getListRewrite(docnode, Javadoc.TAGS_PROPERTY); if (remove) { List<TagElement> tags = (List<TagElement>) docnode.getStructuralProperty(Javadoc.TAGS_PROPERTY); if (tags != null) { TagElement tag = null; for (int i = 0; i < tags.size(); i++) { tag = tags.get(i); if (tagname.equals(tag.getTagName())) { lrewrite.remove(tag, null); } } } } else { TagElement newtag = ast.newTagElement(); newtag.setTagName(tagname); lrewrite.insertLast(newtag, null); } }
private void updatePackageStatement( CompilationUnit astCU, String[] pkgName, ASTRewrite rewriter, ICompilationUnit cu) throws JavaModelException { boolean defaultPackage = pkgName.length == 0; AST ast = astCU.getAST(); if (defaultPackage) { // remove existing package statement PackageDeclaration pkg = astCU.getPackage(); if (pkg != null) { int pkgStart; Javadoc javadoc = pkg.getJavadoc(); if (javadoc != null) { pkgStart = javadoc.getStartPosition() + javadoc.getLength() + 1; } else { pkgStart = pkg.getStartPosition(); } int extendedStart = astCU.getExtendedStartPosition(pkg); if (pkgStart != extendedStart) { // keep the comments associated with package declaration // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=247757 String commentSource = cu.getSource().substring(extendedStart, pkgStart); ASTNode comment = rewriter.createStringPlaceholder(commentSource, ASTNode.PACKAGE_DECLARATION); rewriter.set(astCU, CompilationUnit.PACKAGE_PROPERTY, comment, null); } else { rewriter.set(astCU, CompilationUnit.PACKAGE_PROPERTY, null, null); } } } else { org.eclipse.jdt.core.dom.PackageDeclaration pkg = astCU.getPackage(); if (pkg != null) { // rename package statement Name name = ast.newName(pkgName); rewriter.set(pkg, PackageDeclaration.NAME_PROPERTY, name, null); } else { // create new package statement pkg = ast.newPackageDeclaration(); pkg.setName(ast.newName(pkgName)); rewriter.set(astCU, CompilationUnit.PACKAGE_PROPERTY, pkg, null); } } }
public void run(ISelection selection) { String errorTitle = CompareMessages.AddFromHistory_title; String errorMessage = CompareMessages.AddFromHistory_internalErrorMessage; Shell shell = getShell(); ICompilationUnit cu = null; IParent parent = null; IMember input = null; // analyze selection if (selection.isEmpty()) { // no selection: we try to use the editor's input JavaEditor editor = getEditor(); if (editor != null) { IEditorInput editorInput = editor.getEditorInput(); IWorkingCopyManager manager = JavaPlugin.getDefault().getWorkingCopyManager(); if (manager != null) { cu = manager.getWorkingCopy(editorInput); parent = cu; } } } else { input = getEditionElement(selection); if (input != null) { cu = input.getCompilationUnit(); parent = input; input = null; } else { if (selection instanceof IStructuredSelection) { Object o = ((IStructuredSelection) selection).getFirstElement(); if (o instanceof ICompilationUnit) { cu = (ICompilationUnit) o; parent = cu; } } } } if (parent == null || cu == null) { String invalidSelectionMessage = CompareMessages.AddFromHistory_invalidSelectionMessage; MessageDialog.openInformation(shell, errorTitle, invalidSelectionMessage); return; } IFile file = getFile(parent); if (file == null) { MessageDialog.openError(shell, errorTitle, errorMessage); return; } boolean inEditor = beingEdited(file); IStatus status = Resources.makeCommittable(file, shell); if (!status.isOK()) { return; } // get the document where to insert the text IPath path = file.getFullPath(); ITextFileBufferManager bufferManager = FileBuffers.getTextFileBufferManager(); ITextFileBuffer textFileBuffer = null; try { bufferManager.connect(path, LocationKind.IFILE, null); textFileBuffer = bufferManager.getTextFileBuffer(path, LocationKind.IFILE); IDocument document = textFileBuffer.getDocument(); // configure EditionSelectionDialog and let user select an edition ITypedElement target = new JavaTextBufferNode(file, document, inEditor); ITypedElement[] editions = buildEditions(target, file); ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_NAME); EditionSelectionDialog d = new EditionSelectionDialog(shell, bundle); d.setAddMode(true); d.setHelpContextId(IJavaHelpContextIds.ADD_ELEMENT_FROM_HISTORY_DIALOG); ITypedElement selected = d.selectEdition(target, editions, parent); if (selected == null) return; // user cancel ICompilationUnit cu2 = cu; if (parent instanceof IMember) cu2 = ((IMember) parent).getCompilationUnit(); CompilationUnit root = parsePartialCompilationUnit(cu2); ASTRewrite rewriter = ASTRewrite.create(root.getAST()); ITypedElement[] results = d.getSelection(); for (int i = 0; i < results.length; i++) { // create an AST node ASTNode newNode = createASTNode( rewriter, results[i], TextUtilities.getDefaultLineDelimiter(document), cu.getJavaProject()); if (newNode == null) { MessageDialog.openError(shell, errorTitle, errorMessage); return; } // now determine where to put the new node if (newNode instanceof PackageDeclaration) { rewriter.set(root, CompilationUnit.PACKAGE_PROPERTY, newNode, null); } else if (newNode instanceof ImportDeclaration) { ListRewrite lw = rewriter.getListRewrite(root, CompilationUnit.IMPORTS_PROPERTY); lw.insertFirst(newNode, null); } else { // class, interface, enum, annotation, method, field if (parent instanceof ICompilationUnit) { // top level ListRewrite lw = rewriter.getListRewrite(root, CompilationUnit.TYPES_PROPERTY); int index = ASTNodes.getInsertionIndex((BodyDeclaration) newNode, root.types()); lw.insertAt(newNode, index, null); } else if (parent instanceof IType) { ASTNode declaration = getBodyContainer(root, (IType) parent); if (declaration instanceof TypeDeclaration || declaration instanceof AnnotationTypeDeclaration) { List container = ASTNodes.getBodyDeclarations(declaration); int index = ASTNodes.getInsertionIndex((BodyDeclaration) newNode, container); ListRewrite lw = rewriter.getListRewrite( declaration, ASTNodes.getBodyDeclarationsProperty(declaration)); lw.insertAt(newNode, index, null); } else if (declaration instanceof EnumDeclaration) { List container = ((EnumDeclaration) declaration).enumConstants(); int index = ASTNodes.getInsertionIndex((FieldDeclaration) newNode, container); ListRewrite lw = rewriter.getListRewrite(declaration, EnumDeclaration.ENUM_CONSTANTS_PROPERTY); lw.insertAt(newNode, index, null); } } else { JavaPlugin.logErrorMessage( "JavaAddElementFromHistoryImpl: unknown container " + parent); // $NON-NLS-1$ } } } Map options = null; IJavaProject javaProject = cu2.getJavaProject(); if (javaProject != null) options = javaProject.getOptions(true); applyChanges(rewriter, document, textFileBuffer, shell, inEditor, options); } catch (InvocationTargetException ex) { ExceptionHandler.handle(ex, shell, errorTitle, errorMessage); } catch (InterruptedException ex) { // shouldn't be called because is not cancelable Assert.isTrue(false); } catch (CoreException ex) { ExceptionHandler.handle(ex, shell, errorTitle, errorMessage); } finally { try { if (textFileBuffer != null) bufferManager.disconnect(path, LocationKind.IFILE, null); } catch (CoreException e) { JavaPlugin.log(e); } } }
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; }
/*(non-Javadoc) * @see org.eclipse.jdt.internal.ui.text.correction.ASTRewriteCorrectionProposal#getRewrite() */ @Override protected ASTRewrite getRewrite() { AST ast = fMethodDecl.getAST(); ITypeBinding returnBinding = getReturnTypeBinding(); if (fExistingReturn != null) { ASTRewrite rewrite = ASTRewrite.create(ast); Expression expression = evaluateReturnExpressions(ast, returnBinding, fExistingReturn.getStartPosition()); if (expression != null) { rewrite.set(fExistingReturn, ReturnStatement.EXPRESSION_PROPERTY, expression, null); addLinkedPosition(rewrite.track(expression), true, RETURN_EXPRESSION_KEY); } return rewrite; } else { ASTRewrite rewrite = ASTRewrite.create(ast); Block block = fMethodDecl.getBody(); List<Statement> statements = block.statements(); int nStatements = statements.size(); ASTNode lastStatement = null; if (nStatements > 0) { lastStatement = statements.get(nStatements - 1); } if (returnBinding != null && lastStatement instanceof ExpressionStatement && lastStatement.getNodeType() != ASTNode.ASSIGNMENT) { Expression expression = ((ExpressionStatement) lastStatement).getExpression(); ITypeBinding binding = expression.resolveTypeBinding(); if (binding != null && binding.isAssignmentCompatible(returnBinding)) { Expression placeHolder = (Expression) rewrite.createMoveTarget(expression); ReturnStatement returnStatement = ast.newReturnStatement(); returnStatement.setExpression(placeHolder); rewrite.replace(lastStatement, returnStatement, null); return rewrite; } } int offset; if (lastStatement == null) { offset = block.getStartPosition() + 1; } else { offset = lastStatement.getStartPosition() + lastStatement.getLength(); } ReturnStatement returnStatement = ast.newReturnStatement(); Expression expression = evaluateReturnExpressions(ast, returnBinding, offset); returnStatement.setExpression(expression); rewrite.getListRewrite(block, Block.STATEMENTS_PROPERTY).insertLast(returnStatement, null); addLinkedPosition( rewrite.track(returnStatement.getExpression()), true, RETURN_EXPRESSION_KEY); return rewrite; } }
private void insertMissingJavadocTag( ASTRewrite rewrite, ASTNode missingNode, BodyDeclaration bodyDecl) { AST ast = bodyDecl.getAST(); Javadoc javadoc = bodyDecl.getJavadoc(); if (javadoc == null) { javadoc = ast.newJavadoc(); rewrite.set(bodyDecl, bodyDecl.getJavadocProperty(), javadoc, null); } ListRewrite tagsRewriter = rewrite.getListRewrite(javadoc, Javadoc.TAGS_PROPERTY); StructuralPropertyDescriptor location = missingNode.getLocationInParent(); TagElement newTag; if (location == SingleVariableDeclaration.NAME_PROPERTY) { // normal parameter SingleVariableDeclaration decl = (SingleVariableDeclaration) missingNode.getParent(); String name = ((SimpleName) missingNode).getIdentifier(); newTag = ast.newTagElement(); newTag.setTagName(TagElement.TAG_PARAM); newTag.fragments().add(ast.newSimpleName(name)); MethodDeclaration methodDeclaration = (MethodDeclaration) bodyDecl; List<SingleVariableDeclaration> params = methodDeclaration.parameters(); Set<String> sameKindLeadingNames = getPreviousParamNames(params, decl); List<TypeParameter> typeParams = methodDeclaration.typeParameters(); for (int i = 0; i < typeParams.size(); i++) { String curr = '<' + typeParams.get(i).getName().getIdentifier() + '>'; sameKindLeadingNames.add(curr); } insertTag(tagsRewriter, newTag, sameKindLeadingNames); } else if (location == TypeParameter.NAME_PROPERTY) { // type parameter TypeParameter typeParam = (TypeParameter) missingNode.getParent(); String name = '<' + ((SimpleName) missingNode).getIdentifier() + '>'; newTag = ast.newTagElement(); newTag.setTagName(TagElement.TAG_PARAM); TextElement text = ast.newTextElement(); text.setText(name); newTag.fragments().add(text); List<TypeParameter> params; if (bodyDecl instanceof TypeDeclaration) { params = ((TypeDeclaration) bodyDecl).typeParameters(); } else { params = ((MethodDeclaration) bodyDecl).typeParameters(); } insertTag(tagsRewriter, newTag, getPreviousTypeParamNames(params, typeParam)); } else if (location == MethodDeclaration.RETURN_TYPE2_PROPERTY) { newTag = ast.newTagElement(); newTag.setTagName(TagElement.TAG_RETURN); insertTag(tagsRewriter, newTag, null); } else if (location == MethodDeclaration.THROWN_EXCEPTION_TYPES_PROPERTY) { newTag = ast.newTagElement(); newTag.setTagName(TagElement.TAG_THROWS); TextElement excNode = ast.newTextElement(); excNode.setText(ASTNodes.getQualifiedTypeName((Type) missingNode)); newTag.fragments().add(excNode); List<Type> exceptions = ((MethodDeclaration) bodyDecl).thrownExceptionTypes(); insertTag(tagsRewriter, newTag, getPreviousExceptionNames(exceptions, missingNode)); } else { Assert.isTrue( false, "AddMissingJavadocTagProposal: unexpected node location"); // $NON-NLS-1$ return; } TextElement textElement = ast.newTextElement(); textElement.setText(""); // $NON-NLS-1$ newTag.fragments().add(textElement); addLinkedPosition(rewrite.track(textElement), false, "comment_start"); // $NON-NLS-1$ if (bodyDecl.getJavadoc() == null) { // otherwise the linked position spans over a line delimiter newTag.fragments().add(ast.newTextElement()); } }