// Generate a statement with assignment // E.g. input: x.f(y) ==> x = x.f(y); public static ExpressionStatement genAssignmentStatement(Expression exp) { Assignment assignExp = AST.newAST(AST.JLS8).newAssignment(); // generate a new left hand side variable assignExp.setLeftHandSide( (Expression) ASTNode.copySubtree(assignExp.getAST(), genSimpleName(VariableGenerator.genVar()))); assignExp.setRightHandSide((Expression) ASTNode.copySubtree(assignExp.getAST(), exp)); assignExp.setOperator(Assignment.Operator.ASSIGN); AST newAst = AST.newAST(AST.JLS8); return newAst.newExpressionStatement((Expression) ASTNode.copySubtree(newAst, assignExp)); }
/** * Inserts the provided {@code statement} after the the node this inserter was created for. Tries * to put the {@code statement} as close to the {@code marker} as possible. * * @param statement The statement to insert after the insertion node. */ void insertAfter(final Statement statement) { Validate.notNull(statement); Validate.validState( this.insertionList != null, "Insertion is only possible after the inserter has been set up."); Validate.validState( this.insertionList.isPresent(), "Insertion is only possible if setting up the inserter succeeded."); if (this.differentAfterList) { this.afterList.add(0, statement); } else if (this.breakDetector.containsControlFlowBreakingStatement(this.markedStatement)) { // we are trying to insert after a control flow breaking statement. That’s // dangerous, better surround with try…finally final AST factory = this.markedStatement.getAST(); final TryStatement tryStatement = factory.newTryStatement(); tryStatement.setFinally(factory.newBlock()); @SuppressWarnings("unchecked") final List<Statement> tryBodyStatements = tryStatement.getBody().statements(); @SuppressWarnings("unchecked") final List<Statement> finallyStatements = tryStatement.getFinally().statements(); final Statement copy = (Statement) ASTNode.copySubtree(factory, this.markedStatement); tryBodyStatements.add(copy); finallyStatements.add(statement); this.insertionList.get().set(this.markerIndex, tryStatement); this.markedStatement = tryStatement; this.differentAfterList = true; this.afterList = finallyStatements; } else { this.insertionList.get().add(this.markerIndex, statement); } }
@Override public O addInterface(final String type) { if (!this.hasInterface(type)) { Type interfaceType = JDTHelper.getInterfaces( JavaParser.parse( JavaInterfaceImpl.class, "public interface Mock extends " + Types.toSimpleName(type) + " {}") .getBodyDeclaration()) .get(0); if (this.hasInterface(Types.toSimpleName(type)) || this.hasImport(Types.toSimpleName(type))) { interfaceType = JDTHelper.getInterfaces( JavaParser.parse( JavaInterfaceImpl.class, "public interface Mock extends " + type + " {}") .getBodyDeclaration()) .get(0); } this.addImport(type); ASTNode node = ASTNode.copySubtree(unit.getAST(), interfaceType); JDTHelper.getInterfaces(getBodyDeclaration()).add((Type) node); } return (O) this; }
public void testCopySubtree() { CalloutMappingDeclaration calloutDecl = (CalloutMappingDeclaration) _role.bodyDeclarations().get(7); List parameterMappings = calloutDecl.getParameterMappings(); ParameterMapping testObj = (ParameterMapping) parameterMappings.get(2); ParameterMapping clonedTestObject = (ParameterMapping) ASTNode.copySubtree(AST.newAST(AST.JLS4), testObj); boolean actual = testObj.subtreeMatch(new ASTMatcher(), clonedTestObject); assertTrue("Copy of subtree not correct", actual); }
@SuppressWarnings("unchecked") public <N extends ASTNode> N copy(N node) { return (N) ASTNode.copySubtree(ast, node); }
/** * Returns a copy of the provided {@link ASTNode}. This method loses code comments. Prefer using * {@link #copy(ASTNode)}. * * @param <T> the actual node type * @param node the node to copy * @return a copy of the node */ @SuppressWarnings("unchecked") public <T extends ASTNode> T copySubtree(T node) { return (T) ASTNode.copySubtree(ast, node); }
// generate a variable declaration with an initializer specified by the given expression // e.g. given x.f(a,b) ==> int y = x.f(a,b); public static List<Statement> genVarDeclStatement(Expression exp) { List<Statement> result = new ArrayList<Statement>(); VariableDeclarationFragment fragment = AST.newAST(AST.JLS8).newVariableDeclarationFragment(); ExpressionStatement assignmentStmt = genAssignmentStatement(exp); // The type of the generated variable Type varType = AST.newAST(AST.JLS8).newWildcardType(); if (exp.resolveTypeBinding() != null) { if (exp.resolveTypeBinding().isPrimitive()) { switch (exp.resolveTypeBinding().getName()) { case "void": varType = AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.VOID); break; case "int": varType = AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.INT); break; case "char": varType = AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.CHAR); break; case "long": varType = AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.LONG); break; case "boolean": varType = AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.BOOLEAN); break; case "float": varType = AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.FLOAT); break; case "short": varType = AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.SHORT); break; case "byte": varType = AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.BYTE); break; case "double": varType = AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.DOUBLE); break; } } else { // Option 1: only use the simplename /* SimpleName typeName = AST.newAST(AST.JLS8).newSimpleName(exp.resolveTypeBinding().getName()); AST tempAST = AST.newAST(AST.JLS8); varType = tempAST.newSimpleType((Name) ASTNode.copySubtree(tempAST, typeName)); */ varType = resolveQualifiedType(exp.resolveTypeBinding().getQualifiedName()); } } // Declaration Fragment fragment.setName( (SimpleName) ASTNode.copySubtree( fragment.getAST(), ((SimpleName) ((Assignment) assignmentStmt.getExpression()).getLeftHandSide()))); // fragment.setInitializer((Expression) ASTNode.copySubtree(fragment.getAST(), exp)); AST varDeclFragAST = AST.newAST(AST.JLS8); VariableDeclarationStatement decl = varDeclFragAST.newVariableDeclarationStatement( (VariableDeclarationFragment) ASTNode.copySubtree(varDeclFragAST, fragment)); decl.setType((Type) ASTNode.copySubtree(decl.getAST(), varType)); result.add(decl); // initializer is defined here as a separate statement Assignment assign = varDeclFragAST.newAssignment(); assign.setLeftHandSide((Expression) ASTNode.copySubtree(varDeclFragAST, fragment.getName())); assign.setRightHandSide((Expression) ASTNode.copySubtree(varDeclFragAST, exp)); ExpressionStatement assignStmt = varDeclFragAST.newExpressionStatement(assign); result.add(assignStmt); return result; }
private static Type resolveQualifiedType(String s) { if (s.equals("byte")) { return AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.BYTE); } if (s.equals("")) { return AST.newAST(AST.JLS8).newWildcardType(); } // It's a type parameter if (s.contains("<") && s.contains(">")) { // TODO: resolve type parameters String s0 = s.substring(0, s.indexOf("<")); Type hd = resolveQualifiedType(s0); AST tAST = AST.newAST(AST.JLS8); ParameterizedType pt = tAST.newParameterizedType((Type) ASTNode.copySubtree(tAST, hd)); for (String i : splitTypeArgs(s.substring(s.indexOf("<") + 1, s.lastIndexOf(">")))) { pt.typeArguments().add(ASTNode.copySubtree(tAST, resolveQualifiedType(i))); } return pt; } // It's an array type if (s.contains("[") && s.contains("]")) { String s0 = s.substring(0, s.indexOf("[")); Type hd = resolveQualifiedType(s0); AST tast = AST.newAST(AST.JLS8); ArrayType pt = tast.newArrayType((Type) ASTNode.copySubtree(tast, hd)); return pt; } if (!s.contains(".")) { AST ast = AST.newAST(AST.JLS8); if (s == null || s.equals("null")) { return ast.newSimpleType((Name) ASTNode.copySubtree(ast, genSimpleName("String"))); } switch (s) { case "void": return AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.VOID); case "int": return AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.INT); case "char": return AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.CHAR); case "long": return AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.LONG); case "boolean": return AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.BOOLEAN); case "float": return AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.FLOAT); case "short": return AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.SHORT); case "byte": return AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.BYTE); case "double": return AST.newAST(AST.JLS8).newPrimitiveType(PrimitiveType.DOUBLE); } return ast.newSimpleType((Name) ASTNode.copySubtree(ast, genSimpleName(s))); } else { int last = s.lastIndexOf("."); AST ast = AST.newAST(AST.JLS8); String lastFrag = s.substring(last + 1); return ast.newQualifiedType( (Type) ASTNode.copySubtree(ast, resolveQualifiedType(s.substring(0, last))), (SimpleName) ASTNode.copySubtree(ast, genSimpleName(lastFrag))); } }
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); } }