private ASTRewrite doAddParam(CompilationUnit cu) { AST ast = cu.getAST(); SimpleName node = fOriginalNode; BodyDeclaration decl = ASTResolving.findParentBodyDeclaration(node); if (decl instanceof MethodDeclaration) { MethodDeclaration methodDeclaration = (MethodDeclaration) decl; ASTRewrite rewrite = ASTRewrite.create(ast); ImportRewrite imports = createImportRewrite((CompilationUnit) decl.getRoot()); ImportRewriteContext importRewriteContext = new ContextSensitiveImportRewriteContext(decl, imports); SingleVariableDeclaration newDecl = ast.newSingleVariableDeclaration(); newDecl.setType( evaluateVariableType( ast, imports, importRewriteContext, methodDeclaration.resolveBinding())); newDecl.setName(ast.newSimpleName(node.getIdentifier())); ListRewrite listRewriter = rewrite.getListRewrite(decl, MethodDeclaration.PARAMETERS_PROPERTY); listRewriter.insertLast(newDecl, null); addLinkedPosition(rewrite.track(node), true, KEY_NAME); // add javadoc tag Javadoc javadoc = methodDeclaration.getJavadoc(); if (javadoc != null) { HashSet<String> leadingNames = new HashSet<String>(); for (Iterator<SingleVariableDeclaration> iter = methodDeclaration.parameters().iterator(); iter.hasNext(); ) { SingleVariableDeclaration curr = iter.next(); leadingNames.add(curr.getName().getIdentifier()); } SimpleName newTagRef = ast.newSimpleName(node.getIdentifier()); TagElement newTagElement = ast.newTagElement(); newTagElement.setTagName(TagElement.TAG_PARAM); newTagElement.fragments().add(newTagRef); TextElement commentStart = ast.newTextElement(); newTagElement.fragments().add(commentStart); addLinkedPosition(rewrite.track(newTagRef), false, KEY_NAME); addLinkedPosition(rewrite.track(commentStart), false, "comment_start"); // $NON-NLS-1$ ListRewrite tagsRewriter = rewrite.getListRewrite(javadoc, Javadoc.TAGS_PROPERTY); JavadocTagsSubProcessor.insertTag(tagsRewriter, newTagElement, leadingNames); } addLinkedPosition(rewrite.track(newDecl.getType()), false, KEY_TYPE); addLinkedPosition(rewrite.track(newDecl.getName()), false, KEY_NAME); return rewrite; } return null; }
/* * (non-Javadoc) * * @see org.eclipse.andmore.android.model.java.JavaClass#addComments() */ @Override protected void addComments() throws AndroidException { ASTNode todoComment; ASTParser parser = ASTParser.newParser(AST.JLS3); parser.setSource(document.get().toCharArray()); compUnit = (CompilationUnit) parser.createAST(null); ast = compUnit.getAST(); rewrite = ASTRewrite.create(ast); todoComment = rewrite.createStringPlaceholder( CodeUtilsNLS.MODEL_Common_ToDoPutYourCodeHere, ASTNode.EMPTY_STATEMENT); TypeDeclaration receiverClass = (TypeDeclaration) compUnit.types().get(0); MethodDeclaration method; Block block; // Adds the Override annotation and ToDo comment to all overridden // methods for (int i = 0; i < receiverClass.bodyDeclarations().size(); i++) { method = (MethodDeclaration) receiverClass.bodyDeclarations().get(i); // Adds the Override annotation rewrite .getListRewrite(method, method.getModifiersProperty()) .insertFirst(OVERRIDE_ANNOTATION, null); // Adds the ToDo comment block = method.getBody(); rewrite.getListRewrite(block, Block.STATEMENTS_PROPERTY).insertFirst(todoComment, null); } try { // Writes the modifications TextEdit modifications = rewrite.rewriteAST(document, null); modifications.apply(document); } catch (IllegalArgumentException e) { String errMsg = NLS.bind(CodeUtilsNLS.EXC_JavaClass_ErrorApplyingCommentsToCode, className); AndmoreLogger.error(BroadcastReceiverClass.class, errMsg, e); throw new AndroidException(errMsg); } catch (MalformedTreeException e) { String errMsg = NLS.bind(CodeUtilsNLS.EXC_JavaClass_ErrorApplyingCommentsToCode, className); AndmoreLogger.error(BroadcastReceiverClass.class, errMsg, e); throw new AndroidException(errMsg); } catch (BadLocationException e) { String errMsg = NLS.bind(CodeUtilsNLS.EXC_JavaClass_ErrorApplyingCommentsToCode, className); AndmoreLogger.error(BroadcastReceiverClass.class, errMsg, e); throw new AndroidException(errMsg); } }
private ASTRewrite doAddEnumConst(CompilationUnit astRoot) { SimpleName node = fOriginalNode; ASTNode newTypeDecl = astRoot.findDeclaringNode(fSenderBinding); if (newTypeDecl == null) { astRoot = ASTResolving.createQuickFixAST(getCompilationUnit(), null); newTypeDecl = astRoot.findDeclaringNode(fSenderBinding.getKey()); } if (newTypeDecl != null) { AST ast = newTypeDecl.getAST(); ASTRewrite rewrite = ASTRewrite.create(ast); EnumConstantDeclaration constDecl = ast.newEnumConstantDeclaration(); constDecl.setName(ast.newSimpleName(node.getIdentifier())); ListRewrite listRewriter = rewrite.getListRewrite(newTypeDecl, EnumDeclaration.ENUM_CONSTANTS_PROPERTY); listRewriter.insertLast(constDecl, null); addLinkedPosition(rewrite.track(constDecl.getName()), false, KEY_NAME); return rewrite; } return null; }
@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; }
/** * 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); } }
@Override protected void repairBug(ASTRewrite rewrite, CompilationUnit workingUnit, BugInstance bug) throws BugResolutionException { assert rewrite != null; assert workingUnit != null; assert bug != null; TypeDeclaration type = getTypeDeclaration(workingUnit, bug.getPrimaryClass()); MethodDeclaration method = getMethodDeclaration(type, bug.getPrimaryMethod()); Modifier originalModifier = getPublicModifier(method); ListRewrite listRewrite = rewrite.getListRewrite(method, MethodDeclaration.MODIFIERS2_PROPERTY); Modifier protectedModifier = workingUnit.getAST().newModifier(PROTECTED_KEYWORD); listRewrite.replace(originalModifier, protectedModifier, null); }
/** * Removes the current variable declaration from the AST and inserts it into the lowest possible * scope where the variable is first used. Returns the modification to the AST within a Change * object. */ private Change recordASTModifications() { AST ast = compilationUnit.getAST(); ASTRewrite rewriter = ASTRewrite.create(ast); // duplicate the original variable declaration in lower scope before getting rid of it VariableDeclarationStatement oldDeclaration = (VariableDeclarationStatement) variableVisitor.getDeclaration(); assert variableVisitor.getFirstAssignment() instanceof Assignment; Assignment variableAssignment = (Assignment) variableVisitor.getFirstAssignment(); ASTNode newScopeParent = variableAssignment.getParent().getParent(); String codeString = oldDeclaration.toString(); ASTNode newDeclaration = rewriter.createStringPlaceholder( codeString.substring(0, codeString.length() - 1), ASTNode.VARIABLE_DECLARATION_STATEMENT); ListRewrite listRewrite = rewriter.getListRewrite(newScopeParent, Block.STATEMENTS_PROPERTY); listRewrite.insertAt(newDeclaration, 0, null); // get rid of the higher scope declaration rewriter.remove(oldDeclaration, null); ICompilationUnit iCompUnit = method.getCompilationUnit(); final String description = "ReduceScopeOfVariable"; final String comment = "ReduceScopeOfVariable does blah..."; // record the change CompilationUnitChange change = new CompilationUnitChange("Reduce scope of variable", iCompUnit) { public ChangeDescriptor getDescriptor() { Map<Object, Object> arguments = new HashMap<Object, Object>(); arguments.put("method", method); arguments.put("var", varName); return new RefactoringChangeDescriptor( new ReduceScopeOfVariableDescriptor( method.getJavaProject().getElementName(), description, comment, arguments)); } }; try { change.setEdit(rewriter.rewriteAST()); } catch (Exception e) { } return change; }
private void insertAllMissingTypeTags(ASTRewrite rewriter, TypeDeclaration typeDecl) { AST ast = typeDecl.getAST(); Javadoc javadoc = typeDecl.getJavadoc(); ListRewrite tagsRewriter = rewriter.getListRewrite(javadoc, Javadoc.TAGS_PROPERTY); List<TypeParameter> typeParams = typeDecl.typeParameters(); for (int i = typeParams.size() - 1; i >= 0; i--) { TypeParameter decl = typeParams.get(i); String name = '<' + decl.getName().getIdentifier() + '>'; if (findTag(javadoc, TagElement.TAG_PARAM, name) == null) { TagElement newTag = ast.newTagElement(); newTag.setTagName(TagElement.TAG_PARAM); TextElement text = ast.newTextElement(); text.setText(name); newTag.fragments().add(text); insertTabStop(rewriter, newTag.fragments(), "typeParam" + i); // $NON-NLS-1$ insertTag(tagsRewriter, newTag, getPreviousTypeParamNames(typeParams, decl)); } } }
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); } } }
public void testASTRewriteExample() throws Exception { // create a new project IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject("Test"); project.create(null); project.open(null); try { // set the Java nature and Java build path IProjectDescription description = project.getDescription(); description.setNatureIds(new String[] {JavaCore.NATURE_ID}); project.setDescription(description, null); IJavaProject javaProject = JavaCore.create(project); // build path is: project as source folder and JRE container IClasspathEntry[] cpentry = new IClasspathEntry[] { JavaCore.newSourceEntry(javaProject.getPath()), JavaRuntime.getDefaultJREContainerEntry() }; javaProject.setRawClasspath(cpentry, javaProject.getPath(), null); Map<String, String> options = new HashMap<>(); options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.SPACE); options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, "4"); javaProject.setOptions(options); // create a test file IPackageFragmentRoot root = javaProject.getPackageFragmentRoot(project); IPackageFragment pack1 = root.createPackageFragment("test1", false, null); StringBuffer buf = new StringBuffer(); buf.append("package test1;\n"); buf.append("public class E {\n"); buf.append(" public void foo(int i) {\n"); buf.append(" while (--i > 0) {\n"); buf.append(" System.beep();\n"); buf.append(" }\n"); buf.append(" }\n"); buf.append("}\n"); ICompilationUnit cu = pack1.createCompilationUnit("E.java", buf.toString(), false, null); // create an AST ASTParser parser = ASTParser.newParser(IASTSharedValues.SHARED_AST_LEVEL); parser.setSource(cu); parser.setResolveBindings(false); CompilationUnit astRoot = (CompilationUnit) parser.createAST(null); AST ast = astRoot.getAST(); // create the descriptive ast rewriter ASTRewrite rewrite = ASTRewrite.create(ast); // get the block node that contains the statements in the method body TypeDeclaration typeDecl = (TypeDeclaration) astRoot.types().get(0); MethodDeclaration methodDecl = typeDecl.getMethods()[0]; Block block = methodDecl.getBody(); // create new statements to insert MethodInvocation newInv1 = ast.newMethodInvocation(); newInv1.setName(ast.newSimpleName("bar1")); Statement newStatement1 = ast.newExpressionStatement(newInv1); MethodInvocation newInv2 = ast.newMethodInvocation(); newInv2.setName(ast.newSimpleName("bar2")); Statement newStatement2 = ast.newExpressionStatement(newInv2); // describe that the first node is inserted as first statement in block, the other one as last // statement // note: AST is not modified by this ListRewrite listRewrite = rewrite.getListRewrite(block, Block.STATEMENTS_PROPERTY); listRewrite.insertFirst(newStatement1, null); listRewrite.insertLast(newStatement2, null); // evaluate the text edits corresponding to the described changes. AST and CU still // unmodified. TextEdit res = rewrite.rewriteAST(); // apply the text edits to the compilation unit Document document = new Document(cu.getSource()); res.apply(document); cu.getBuffer().setContents(document.get()); // test result String preview = cu.getSource(); buf = new StringBuffer(); buf.append("package test1;\n"); buf.append("public class E {\n"); buf.append(" public void foo(int i) {\n"); buf.append(" bar1();\n"); buf.append(" while (--i > 0) {\n"); buf.append(" System.beep();\n"); buf.append(" }\n"); buf.append(" bar2();\n"); buf.append(" }\n"); buf.append("}\n"); assertEquals(preview, buf.toString()); } finally { project.delete(true, null); } }
private ASTRewrite doAddField(CompilationUnit astRoot) { SimpleName node = fOriginalNode; boolean isInDifferentCU = false; ASTNode newTypeDecl = astRoot.findDeclaringNode(fSenderBinding); if (newTypeDecl == null) { astRoot = ASTResolving.createQuickFixAST(getCompilationUnit(), null); newTypeDecl = astRoot.findDeclaringNode(fSenderBinding.getKey()); isInDifferentCU = true; } ImportRewrite imports = createImportRewrite(astRoot); ImportRewriteContext importRewriteContext = new ContextSensitiveImportRewriteContext( ASTResolving.findParentBodyDeclaration(node), imports); if (newTypeDecl != null) { AST ast = newTypeDecl.getAST(); ASTRewrite rewrite = ASTRewrite.create(ast); VariableDeclarationFragment fragment = ast.newVariableDeclarationFragment(); fragment.setName(ast.newSimpleName(node.getIdentifier())); Type type = evaluateVariableType(ast, imports, importRewriteContext, fSenderBinding); FieldDeclaration newDecl = ast.newFieldDeclaration(fragment); newDecl.setType(type); newDecl .modifiers() .addAll(ASTNodeFactory.newModifiers(ast, evaluateFieldModifiers(newTypeDecl))); if (fSenderBinding.isInterface() || fVariableKind == CONST_FIELD) { fragment.setInitializer(ASTNodeFactory.newDefaultExpression(ast, type, 0)); } ChildListPropertyDescriptor property = ASTNodes.getBodyDeclarationsProperty(newTypeDecl); List<BodyDeclaration> decls = ASTNodes.<BodyDeclaration>getChildListProperty(newTypeDecl, property); int maxOffset = isInDifferentCU ? -1 : node.getStartPosition(); int insertIndex = findFieldInsertIndex(decls, newDecl, maxOffset); ListRewrite listRewriter = rewrite.getListRewrite(newTypeDecl, property); listRewriter.insertAt(newDecl, insertIndex, null); ModifierCorrectionSubProcessor.installLinkedVisibilityProposals( getLinkedProposalModel(), rewrite, newDecl.modifiers(), fSenderBinding.isInterface()); addLinkedPosition(rewrite.track(newDecl.getType()), false, KEY_TYPE); if (!isInDifferentCU) { addLinkedPosition(rewrite.track(node), true, KEY_NAME); } addLinkedPosition(rewrite.track(fragment.getName()), false, KEY_NAME); if (fragment.getInitializer() != null) { addLinkedPosition(rewrite.track(fragment.getInitializer()), false, KEY_INITIALIZER); } return rewrite; } return null; }
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 insertAllMissingMethodTags(ASTRewrite rewriter, MethodDeclaration methodDecl) { AST ast = methodDecl.getAST(); Javadoc javadoc = methodDecl.getJavadoc(); ListRewrite tagsRewriter = rewriter.getListRewrite(javadoc, Javadoc.TAGS_PROPERTY); List<TypeParameter> typeParams = methodDecl.typeParameters(); ASTNode root = methodDecl.getRoot(); if (root instanceof CompilationUnit) { ITypeRoot typeRoot = ((CompilationUnit) root).getTypeRoot(); if (typeRoot != null && !StubUtility.shouldGenerateMethodTypeParameterTags(typeRoot.getJavaProject())) typeParams = Collections.emptyList(); } List<String> typeParamNames = new ArrayList<>(); for (int i = typeParams.size() - 1; i >= 0; i--) { TypeParameter decl = typeParams.get(i); String name = '<' + decl.getName().getIdentifier() + '>'; if (findTag(javadoc, TagElement.TAG_PARAM, name) == null) { TagElement newTag = ast.newTagElement(); newTag.setTagName(TagElement.TAG_PARAM); TextElement text = ast.newTextElement(); text.setText(name); newTag.fragments().add(text); insertTabStop(rewriter, newTag.fragments(), "typeParam" + i); // $NON-NLS-1$ insertTag(tagsRewriter, newTag, getPreviousTypeParamNames(typeParams, decl)); } typeParamNames.add(name); } List<SingleVariableDeclaration> params = methodDecl.parameters(); for (int i = params.size() - 1; i >= 0; i--) { SingleVariableDeclaration decl = params.get(i); String name = decl.getName().getIdentifier(); if (findTag(javadoc, TagElement.TAG_PARAM, name) == null) { TagElement newTag = ast.newTagElement(); newTag.setTagName(TagElement.TAG_PARAM); newTag.fragments().add(ast.newSimpleName(name)); insertTabStop(rewriter, newTag.fragments(), "methParam" + i); // $NON-NLS-1$ Set<String> sameKindLeadingNames = getPreviousParamNames(params, decl); sameKindLeadingNames.addAll(typeParamNames); insertTag(tagsRewriter, newTag, sameKindLeadingNames); } } if (!methodDecl.isConstructor()) { Type type = methodDecl.getReturnType2(); if (!type.isPrimitiveType() || (((PrimitiveType) type).getPrimitiveTypeCode() != PrimitiveType.VOID)) { if (findTag(javadoc, TagElement.TAG_RETURN, null) == null) { TagElement newTag = ast.newTagElement(); newTag.setTagName(TagElement.TAG_RETURN); insertTabStop(rewriter, newTag.fragments(), "return"); // $NON-NLS-1$ insertTag(tagsRewriter, newTag, null); } } } List<Type> thrownExceptions = methodDecl.thrownExceptionTypes(); for (int i = thrownExceptions.size() - 1; i >= 0; i--) { Type exception = thrownExceptions.get(i); ITypeBinding binding = exception.resolveBinding(); if (binding != null) { String name = binding.getName(); if (findThrowsTag(javadoc, name) == null) { TagElement newTag = ast.newTagElement(); newTag.setTagName(TagElement.TAG_THROWS); TextElement excNode = ast.newTextElement(); excNode.setText(ASTNodes.getQualifiedTypeName(exception)); newTag.fragments().add(excNode); insertTabStop(rewriter, newTag.fragments(), "exception" + i); // $NON-NLS-1$ insertTag(tagsRewriter, newTag, getPreviousExceptionNames(thrownExceptions, exception)); } } } }
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()); } }
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); } }