@Override public boolean visit(MethodDeclaration node) { if (node.getBody() == null) { return VISIT_SUBTREE; } List<Statement> bodyStmts = statements(node.getBody()); if (bodyStmts.size() == 1) { SuperMethodInvocation bodyMi = asExpression(bodyStmts.get(0), SuperMethodInvocation.class); if (bodyMi != null) { IMethodBinding bodyMethodBinding = bodyMi.resolveMethodBinding(); IMethodBinding declMethodBinding = node.resolveBinding(); if (declMethodBinding != null && bodyMethodBinding != null && declMethodBinding.overrides(bodyMethodBinding) && !hasSignificantAnnotations(declMethodBinding) && haveSameModifiers(bodyMethodBinding, declMethodBinding)) { if (Modifier.isProtected(declMethodBinding.getModifiers()) && !declaredInSamePackage(bodyMethodBinding, declMethodBinding)) { // protected also means package visibility, so check if it is required if (!isMethodUsedInItsPackage(declMethodBinding, node)) { this.ctx.getRefactorings().remove(node); return DO_NOT_VISIT_SUBTREE; } } else { this.ctx.getRefactorings().remove(node); return DO_NOT_VISIT_SUBTREE; } } } } return VISIT_SUBTREE; }
/* * @see ASTVisitor#visit(MethodDeclaration) */ public boolean visit(MethodDeclaration node) { if (node.getJavadoc() != null) { node.getJavadoc().accept(this); } if (node.getAST().apiLevel() >= AST.JLS3) { printModifiers(node.modifiers()); if (!node.typeParameters().isEmpty()) { this.fBuffer.append("<"); // $NON-NLS-1$ for (Iterator it = node.typeParameters().iterator(); it.hasNext(); ) { TypeParameter t = (TypeParameter) it.next(); t.accept(this); if (it.hasNext()) { this.fBuffer.append(", "); // $NON-NLS-1$ } } this.fBuffer.append("> "); // $NON-NLS-1$ } } if (!node.isConstructor()) { if (node.getReturnType2() != null) { node.getReturnType2().accept(this); } else { // methods really ought to have a return type this.fBuffer.append("void"); // $NON-NLS-1$ } this.fBuffer.append(" "); // $NON-NLS-1$ } node.getName().accept(this); this.fBuffer.append("("); // $NON-NLS-1$ for (Iterator it = node.parameters().iterator(); it.hasNext(); ) { SingleVariableDeclaration v = (SingleVariableDeclaration) it.next(); v.accept(this); if (it.hasNext()) { this.fBuffer.append(", "); // $NON-NLS-1$ } } this.fBuffer.append(")"); // $NON-NLS-1$ for (int i = 0; i < node.getExtraDimensions(); i++) { this.fBuffer.append("[]"); // $NON-NLS-1$ } if (!node.thrownExceptions().isEmpty()) { this.fBuffer.append(" throws "); // $NON-NLS-1$ for (Iterator it = node.thrownExceptions().iterator(); it.hasNext(); ) { Name n = (Name) it.next(); n.accept(this); if (it.hasNext()) { this.fBuffer.append(", "); // $NON-NLS-1$ } } this.fBuffer.append(" "); // $NON-NLS-1$ } if (node.getBody() == null) { this.fBuffer.append(";"); // $NON-NLS-1$ } else { node.getBody().accept(this); } return false; }
private static boolean canAddFinal(IBinding binding, ASTNode declNode) { if (!(binding instanceof IVariableBinding)) return false; IVariableBinding varbinding = (IVariableBinding) binding; int modifiers = varbinding.getModifiers(); if (Modifier.isFinal(modifiers) || Modifier.isVolatile(modifiers) || Modifier.isTransient(modifiers)) return false; ASTNode parent = ASTNodes.getParent(declNode, VariableDeclarationExpression.class); if (parent != null && ((VariableDeclarationExpression) parent).fragments().size() > 1) return false; if (varbinding.isField() && !Modifier.isPrivate(modifiers)) return false; if (varbinding.isParameter()) { ASTNode varDecl = declNode.getParent(); if (varDecl instanceof MethodDeclaration) { MethodDeclaration declaration = (MethodDeclaration) varDecl; if (declaration.getBody() == null) return false; } } return true; }
private String generateMethodBody(MethodDeclaration m) { String methodBody; if (Modifier.isNative(m.getModifiers())) { if (hasNativeCode(m, true)) { methodBody = extractNativeMethodBody(m); } else if (Options.generateNativeStubs()) { return generateNativeStub(m); } else { return null; } } else if (Modifier.isAbstract(m.getModifiers())) { // Generate a body which throws a NSInvalidArgumentException. String body = "{\n // can't call an abstract method\n " + "[self doesNotRecognizeSelector:_cmd];\n "; if (!Types.isVoidType(m.getReturnType2())) { body += "return 0;\n"; // Never executes, but avoids a gcc warning. } return body + "}"; } else { // generate a normal method body methodBody = generateStatement(m.getBody(), false); } boolean isStatic = (m.getModifiers() & Modifier.STATIC) != 0; boolean isSynchronized = (m.getModifiers() & Modifier.SYNCHRONIZED) != 0; if (isStatic && isSynchronized) { methodBody = "{\n@synchronized([self class]) {\n" + methodBody + "}\n}\n"; } else if (isSynchronized) { methodBody = "{\n@synchronized(self) {\n" + methodBody + "}\n}\n"; } return methodBody; }
private boolean callsWritingConstructor( MethodDeclaration methodDeclaration, HashSet writingConstructorBindings, Set visitedMethodDeclarations) { Block body = methodDeclaration.getBody(); if (body == null) return false; List statements = body.statements(); if (statements.size() == 0) return false; Statement statement = (Statement) statements.get(0); if (!(statement instanceof ConstructorInvocation)) return false; ConstructorInvocation invocation = (ConstructorInvocation) statement; IMethodBinding constructorBinding = invocation.resolveConstructorBinding(); if (constructorBinding == null) return false; if (writingConstructorBindings.contains(constructorBinding)) { return true; } else { ASTNode declaration = ASTNodes.findDeclaration(constructorBinding, methodDeclaration.getParent()); if (!(declaration instanceof MethodDeclaration)) return false; if (visitedMethodDeclarations.contains(declaration)) { return false; } visitedMethodDeclarations.add(methodDeclaration); return callsWritingConstructor( (MethodDeclaration) declaration, writingConstructorBindings, visitedMethodDeclarations); } }
/** * Visits the method invocation to get number of assertion in this test method. * * @param md Visit method declaration in source code. * @return False because we don't look into child nodes. */ public boolean visit(MethodDeclaration md) { if (md.getName() != null) { this.numOfMethods++; if (md.getName().getIdentifier().startsWith("test")) { this.numOfTestMethods++; } else if (isJUnit4Test(md)) { this.numOfTestMethods++; } // Check test method body to look for assertion statement. Block methodBody = md.getBody(); if (methodBody != null && methodBody.statements() != null) { List stmts = methodBody.statements(); this.numOfStatements += stmts.size(); // Looks through all statements in this method body. for (Iterator i = stmts.iterator(); i.hasNext(); ) { Statement stmt = (Statement) i.next(); // NOPMD // MethodInvocation is one kind of expression statement. if (stmt instanceof ExpressionStatement) { ExpressionStatement estmt = (ExpressionStatement) stmt; checkAssertions(estmt); } } } } // No need to visit child nodes anymore. return false; }
private void printStaticInterface( AbstractTypeDeclaration node, String typeName, List<FieldDeclaration> fields, List<MethodDeclaration> methods) { List<IVariableBinding> staticFields = getStaticFieldsNeedingAccessors(fields, /* isInterface */ true); if (staticFields.isEmpty()) { if (!Options.stripReflection()) { printf("\n@interface %s : NSObject\n@end\n", typeName); } else { return; } } printf("\n@implementation %s\n\n", typeName); printStaticVars(fields, /* isInterface */ true); printStaticFieldAccessors(staticFields, methods); for (MethodDeclaration method : methods) { if (method.getBody() != null) { printNormalMethod(method); } } if (!Options.stripReflection()) { printMetadata(node); } println("@end"); }
/* * (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); } }
@Test public void testIsThrowStatementInCatchClause() { TryStatement tryStatement; CatchClause catchStatement; // 測試 符合的例子 是否會抓出 MethodDeclaration md = null; md = ASTNodeFinder.getMethodDeclarationNodeByName(compilationUnit, "false_throwAndPrint"); tryStatement = (TryStatement) md.getBody().statements().get(0); catchStatement = (CatchClause) tryStatement.catchClauses().get(0); assertTrue(dummyHandlerVisitor.isThrowStatementInCatchClause(catchStatement)); // 測試 不符合例子 是否會抓出 md = ASTNodeFinder.getMethodDeclarationNodeByName( compilationUnit, "true_DummyHandlerTryNestedTry"); tryStatement = (TryStatement) md.getBody().statements().get(1); catchStatement = (CatchClause) tryStatement.catchClauses().get(0); assertFalse(dummyHandlerVisitor.isThrowStatementInCatchClause(catchStatement)); }
@Override protected void printStaticConstructorDeclaration(MethodDeclaration m) { String className = NameTable.getFullName(Types.getMethodBinding(m).getDeclaringClass()); StringBuffer sb = new StringBuffer(); sb.append("{\nif (self == [" + className + " class]) {\n"); for (Statement statement : ASTUtil.getStatements(m.getBody())) { sb.append(generateStatement(statement, false)); } sb.append("}\n}"); print("+ (void)initialize " + reindent(sb.toString()) + "\n\n"); }
@Override public boolean visit(MethodDeclaration node) { Block body = node.getBody(); if (body == null) return false; Selection selection = getSelection(); int nodeStart = body.getStartPosition(); int nodeExclusiveEnd = nodeStart + body.getLength(); // if selection node inside of the method body ignore method if (!(nodeStart < selection.getOffset() && selection.getExclusiveEnd() < nodeExclusiveEnd)) return false; return super.visit(node); }
@Override public boolean visit(final MethodDeclaration node) { @SuppressWarnings("rawtypes") final List l = node.getBody().statements(); this.b_last = node.getBody(); // use method's body as virtual last if (l.size() == 0) { this.b_init = this.b_last; return false; // empty body } int i = 0; // we need to find the first actual SJ statement while ((i != l.size()) && (l.get(i) instanceof VariableDeclarationStatement)) { i++; } if (l.size() == i) { this.b_init = this.b_last; return false; // no SJ statements in body } else { this.b_init = (Statement) l.get(i); // first SJ statement // add edge from last statement in method body to virtual b_last addEdge(last(l), this.b_last); } return true; }
@Override protected String constructorDeclaration(MethodDeclaration m) { String methodBody; IMethodBinding binding = Types.getMethodBinding(m); boolean memDebug = Options.memoryDebug(); List<Statement> statements = ASTUtil.getStatements(m.getBody()); if (binding.getDeclaringClass().isEnum()) { return enumConstructorDeclaration(m, statements, binding); } StringBuffer sb = new StringBuffer("{\n"); int constructorIdx = findConstructorInvocation(statements); int idx = 0; while (idx < constructorIdx) { sb.append(generateStatement(statements.get(idx++), false)); } String superCall = idx == constructorIdx ? generateStatement(statements.get(idx++), false) : "[super init]"; if (idx >= statements.size()) { sb.append("return "); if (memDebug) { sb.append("JreMemDebugAdd("); } sb.append(superCall).append(memDebug ? ");\n}" : ";\n}"); } else { sb.append("if (self = ").append(superCall).append(") {\n"); while (idx < statements.size()) { sb.append(generateStatement(statements.get(idx++), false)); } if (memDebug) { sb.append("JreMemDebugAdd(self);\n"); } sb.append("}\nreturn self;\n}"); } methodBody = sb.toString(); if (invokedConstructors.contains(methodKey(binding))) { return super.constructorDeclaration(m, true) + " " + reindent(methodBody) + "\n\n" + super.constructorDeclaration(m, false) + " {\n return " + generateStatement(createInnerConstructorInvocation(m), false) + ";\n}\n\n"; } else { return super.constructorDeclaration(m, false) + " " + reindent(methodBody) + "\n\n"; } }
protected List getFeatureMethodSwitch(String type) { List cases = featureSwitchMap.get(type); if (cases == null) { MethodDeclaration method = newMethodDeclaration( "void", type, newSingleVariableDeclaration(FeatureDescriptor.class.getName(), "featureDesc")); SwitchStatement switchStm = newSwitchStatement(newMethodInvocation("featureDesc", "getOrdinal")); method.getBody().statements().add(switchStm); addBodyDeclaration(method); featureSwitchMap.put(type, cases = switchStm.statements()); } return cases; }
/** Verify that an anonymous class is moved to the compilation unit's types list. */ public void testAnonymousClassExtracted() { List<TypeDeclaration> types = translateClassBody( "Object test() { return new java.util.Enumeration<Object>() { " + "public boolean hasMoreElements() { return false; } " + "public Object nextElement() { return null; } }; }"); assertEquals(2, types.size()); TypeDeclaration type = types.get(1); assertEquals("$1", type.getName().getIdentifier()); type = types.get(0); assertEquals("Test", type.getName().getIdentifier()); MethodDeclaration testMethod = (MethodDeclaration) type.bodyDeclarations().get(0); ReturnStatement stmt = (ReturnStatement) testMethod.getBody().statements().get(0); ClassInstanceCreation expr = (ClassInstanceCreation) stmt.getExpression(); assertNull(expr.getAnonymousClassDeclaration()); }
protected List getEnumMethodSwitch(String type) { if (enumCases == null) { MethodDeclaration method = newMethodDeclaration( "void", "wEntity", newSingleVariableDeclaration( newParameterizedType(EntityDescriptor.class.getName(), ast.newWildcardType()), "entityDesc"), newSingleVariableDeclaration(EnumValue.class.getName(), "value")); SwitchStatement switchStm = newSwitchStatement(newMethodInvocation("entityDesc", "getOrdinal")); method.getBody().statements().add(switchStm); addBodyDeclaration(method); enumCases = switchStm.statements(); } return enumCases; }
protected List getMethodSwitch(String type) { List cases = switchMap.get(type); if (cases == null) { MethodDeclaration method = newMethodDeclaration( "void", type, newSingleVariableDeclaration( newParameterizedType(EntityDescriptor.class.getName(), ast.newWildcardType()), "entityDesc")); SwitchStatement switchStm = newSwitchStatement(newMethodInvocation("entityDesc", "getOrdinal")); method.getBody().statements().add(switchStm); addBodyDeclaration(method); switchMap.put(type, cases = switchStm.statements()); } return cases; }
@SuppressWarnings("unchecked") public void removeUnallowedAssignments() { CompilationUnit cu = catroidSource.getSourceAst(); final List<AbstractTypeDeclaration> types = cu.types(); assert types.size() > 0; for (AbstractTypeDeclaration abstractTypeDecl : types) { for (BodyDeclaration bodyDecl : new ArrayList<BodyDeclaration>(abstractTypeDecl.bodyDeclarations())) { if (bodyDecl.getNodeType() != ASTNode.METHOD_DECLARATION) { continue; } MethodDeclaration methodDeclaration = (MethodDeclaration) bodyDecl; Block body = methodDeclaration.getBody(); if ((body == null) || (body.statements().size() == 0)) { continue; } methodDeclaration.accept(this); } } }
/** * Regression test: verify that a class passed in the constructor of an anonymous class is * converted. */ public void testAnonymousClassWithTypeArgParameter() { List<TypeDeclaration> types = translateClassBody( "public Test(Class c) {} static Test t = " + "new Test(Test.class) { @Override public int hashCode() { return 1; } };"); assertEquals(2, types.size()); TypeDeclaration type = types.get(0); List<BodyDeclaration> members = type.bodyDeclarations(); for (BodyDeclaration member : members) { if (member instanceof MethodDeclaration) { MethodDeclaration m = (MethodDeclaration) member; if (m.getName().getIdentifier().equals("initialize")) { Block b = (Block) m.getBody().statements().get(0); ExpressionStatement expStmt = (ExpressionStatement) b.statements().get(0); Assignment assign = (Assignment) expStmt.getExpression(); ClassInstanceCreation create = (ClassInstanceCreation) assign.getRightHandSide(); assertTrue(create.arguments().get(0) instanceof TypeLiteral); } } } }
/* * @see ASTVisitor#visit(MethodDeclaration) */ @Override public boolean visit(MethodDeclaration node) { if (!isAffected(node)) { return false; } doVisitNode(node.getJavadoc()); doVisitChildren(node.modifiers()); doVisitChildren(node.typeParameters()); if (!node.isConstructor()) { doVisitNode(node.getReturnType2()); } // name not visited int apiLevel = node.getAST().apiLevel(); if (apiLevel >= AST.JLS8) { doVisitNode(node.getReceiverType()); } // receiverQualifier not visited: // Enclosing class names cannot be shadowed by an import (qualification is always redundant). doVisitChildren(node.parameters()); if (apiLevel >= AST.JLS8) { doVisitChildren(node.extraDimensions()); doVisitChildren(node.thrownExceptionTypes()); } else { Iterator<Name> iter = getThrownExceptions(node).iterator(); while (iter.hasNext()) { typeRefFound(iter.next()); } } if (!fSkipMethodBodies) { doVisitNode(node.getBody()); } return false; }
/* * @see ASTVisitor#visit(MethodDeclaration) */ @Override public boolean visit(MethodDeclaration node) { if (node.getJavadoc() != null) { node.getJavadoc().accept(this); } if (node.getAST().apiLevel() >= JLS3) { printModifiers(node.modifiers()); if (!node.typeParameters().isEmpty()) { this.fBuffer.append("<"); // $NON-NLS-1$ for (Iterator<TypeParameter> it = node.typeParameters().iterator(); it.hasNext(); ) { TypeParameter t = it.next(); t.accept(this); if (it.hasNext()) { this.fBuffer.append(", "); // $NON-NLS-1$ } } this.fBuffer.append("> "); // $NON-NLS-1$ } } if (!node.isConstructor()) { if (node.getReturnType2() != null) { node.getReturnType2().accept(this); } else { // methods really ought to have a return type this.fBuffer.append("void"); // $NON-NLS-1$ } this.fBuffer.append(" "); // $NON-NLS-1$ } node.getName().accept(this); this.fBuffer.append("("); // $NON-NLS-1$ if (node.getAST().apiLevel() >= AST.JLS8) { Type receiverType = node.getReceiverType(); if (receiverType != null) { receiverType.accept(this); this.fBuffer.append(' '); SimpleName qualifier = node.getReceiverQualifier(); if (qualifier != null) { qualifier.accept(this); this.fBuffer.append('.'); } this.fBuffer.append("this"); // $NON-NLS-1$ if (node.parameters().size() > 0) { this.fBuffer.append(','); } } } for (Iterator<SingleVariableDeclaration> it = node.parameters().iterator(); it.hasNext(); ) { SingleVariableDeclaration v = it.next(); v.accept(this); if (it.hasNext()) { this.fBuffer.append(", "); // $NON-NLS-1$ } } this.fBuffer.append(")"); // $NON-NLS-1$ if (node.getAST().apiLevel() >= AST.JLS8) { List<Dimension> dimensions = node.extraDimensions(); for (Iterator<Dimension> it = dimensions.iterator(); it.hasNext(); ) { Dimension e = it.next(); e.accept(this); } } else { for (int i = 0; i < node.getExtraDimensions(); i++) { this.fBuffer.append("[]"); // $NON-NLS-1$ } } List<? extends ASTNode> thrownExceptions = node.getAST().apiLevel() >= AST.JLS8 ? node.thrownExceptionTypes() : getThrownExceptions(node); if (!thrownExceptions.isEmpty()) { this.fBuffer.append(" throws "); // $NON-NLS-1$ for (Iterator<? extends ASTNode> it = thrownExceptions.iterator(); it.hasNext(); ) { ASTNode n = it.next(); n.accept(this); if (it.hasNext()) { this.fBuffer.append(", "); // $NON-NLS-1$ } } this.fBuffer.append(" "); // $NON-NLS-1$ } if (node.getBody() == null) { this.fBuffer.append(";"); // $NON-NLS-1$ } else { node.getBody().accept(this); } return false; }
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 Example makeExample( MethodDeclaration node, Set<? extends Expression> envolvedInvocations, List<ApiMethod> envolvedApiMethods) { // Visitor responsável por realizar o slicing de programas SlicingStatementVisitor visitor = new SlicingStatementVisitor(node, new HashSet<ASTNode>(envolvedInvocations)); node.accept(visitor); Collection<Statement> relatedStatements = visitor.getSlicedStatements(); ASTNode newAST = ASTUtil.copyStatements(node.getBody(), relatedStatements, AST.newAST(AST.JLS3)); if (!relatedStatements.isEmpty()) { LOGGER.error("Some statements were not included!"); } if (newAST == null) { LOGGER.error("Slicing process failed for node "); // TODO Se AST retornada for nula é porque faltou incluir statement(s) return null; } else if (((Block) newAST).statements().isEmpty()) { LOGGER.error("Slicing process failed for node "); // TODO Se o Block retornado for vazio é porque faltou incluir statement(s) return null; } ASTUtil.removeEmptyBlocks((Block) newAST); // Adiciona declarações de variáveis que não foram encontradas no escopo do método // Para facilitar, tipos iguais são declarados no mesmo Statement Set<String> additionalDeclarationLines = new HashSet<String>(); Map<ITypeBinding, List<IVariableBinding>> typesMap = new HashMap<ITypeBinding, List<IVariableBinding>>(); for (IVariableBinding ivb : visitor.getUndiscoveredDeclarations()) { if (!typesMap.containsKey(ivb.getType())) { typesMap.put(ivb.getType(), new ArrayList<IVariableBinding>(2)); } typesMap.get(ivb.getType()).add(ivb); } for (ITypeBinding typeBinding : typesMap.keySet()) { List<IVariableBinding> variableBindings = typesMap.get(typeBinding); Stack<VariableDeclarationFragment> fragments = new Stack<VariableDeclarationFragment>(); for (IVariableBinding ivb : variableBindings) { VariableDeclarationFragment declarationFragment = newAST.getAST().newVariableDeclarationFragment(); declarationFragment.setName(newAST.getAST().newSimpleName(ivb.getName())); fragments.add(declarationFragment); } VariableDeclarationStatement statement = newAST.getAST().newVariableDeclarationStatement(fragments.pop()); while (!fragments.isEmpty()) { statement.fragments().add(fragments.pop()); } statement.setType(this.getType(typeBinding, newAST.getAST())); additionalDeclarationLines.add(statement.toString()); ((Block) newAST).statements().add(0, statement); } Example example = new Example(); example.setAttachment(this.attachmentMap.get(node.getRoot())); example.setApiMethods(new HashSet<ApiElement>(envolvedApiMethods)); example.setImports(visitor.getImports()); for (Expression seed : envolvedInvocations) { example.getSeeds().add(seed.toString()); } example.setSourceMethod(node.toString()); example.setAddedAt(new Date(System.currentTimeMillis())); try { IMethodBinding nodeBinding = node.resolveBinding(); if (!this.methodMap.containsKey(nodeBinding)) { ApiClass newApiClass = new ApiClass(nodeBinding.getDeclaringClass().getQualifiedName()); methodDeclarationHandler(node, newApiClass); } example.setSourceMethodCall(this.methodMap.get(nodeBinding).getFullName()); } catch (Exception e) { LOGGER.error(e); if (example.getSourceMethodCall() == null) { example.setSourceMethodCall("?"); } } String codeExample = newAST.toString(); for (String line : additionalDeclarationLines) { codeExample = codeExample.replace( line, line.replace("\n", "").concat(" ").concat("//initialized previously").concat("\n")); } // FIXME codeExample = codeExample.replaceAll("(\\{\n)(\\s+)(\\})", "$1 //do something \n$3"); try { example.setCodeExample(codeExample); example.setFormattedCodeExample(ASTUtil.codeFormatter(codeExample)); } catch (Exception e) { LOGGER.error(e); if (example.getFormattedCodeExample() == null) { example.setFormattedCodeExample(codeExample); } } // TODO Obter métricas do exemplo example .getMetrics() .put(ExampleMetric.LOC.name(), example.getFormattedCodeExample().split("\n").length - 1); example.getMetrics().put(ExampleMetric.ARGUMENTS.name(), visitor.getNumberOfArguments()); example .getMetrics() .put(ExampleMetric.DECISION_STATEMENTS.name(), visitor.getNumberOfDecisionStatements()); example.getMetrics().put(ExampleMetric.INVOCATIONS.name(), visitor.getNumberOfInvocations()); example .getMetrics() .put(ExampleMetric.NULL_ARGUMENTS.name(), visitor.getNumberOfNullArguments()); example .getMetrics() .put(ExampleMetric.PRIMITIVE_ARGUMENTS.name(), visitor.getNumberOfPrimitiveArguments()); example .getMetrics() .put(ExampleMetric.FIELD_ARGUMENTS.name(), visitor.getNumberOfFieldArguments()); example .getMetrics() .put( ExampleMetric.UNDISCOVERED_DECLARATIONS.name(), visitor.getNumberOfUndiscoveredDeclarations()); example .getMetrics() .put(ExampleMetric.UNHANDLED_EXCEPTIONS.name(), visitor.getNumberOfUnhandledExceptions()); return example; }
private List<ClassObject> parseAST(CompilationUnit compilationUnit, IFile iFile) { List<ClassObject> classObjects = new ArrayList<ClassObject>(); List<AbstractTypeDeclaration> topLevelTypeDeclarations = compilationUnit.types(); for (AbstractTypeDeclaration abstractTypeDeclaration : topLevelTypeDeclarations) { if (abstractTypeDeclaration instanceof TypeDeclaration) { TypeDeclaration topLevelTypeDeclaration = (TypeDeclaration) abstractTypeDeclaration; List<TypeDeclaration> typeDeclarations = new ArrayList<TypeDeclaration>(); typeDeclarations.add(topLevelTypeDeclaration); typeDeclarations.addAll(getRecursivelyInnerTypes(topLevelTypeDeclaration)); for (TypeDeclaration typeDeclaration : typeDeclarations) { final ClassObject classObject = new ClassObject(); classObject.setIFile(iFile); classObject.setName(typeDeclaration.resolveBinding().getQualifiedName()); classObject.setTypeDeclaration(typeDeclaration); if (typeDeclaration.isInterface()) { classObject.setInterface(true); } int modifiers = typeDeclaration.getModifiers(); if ((modifiers & Modifier.ABSTRACT) != 0) classObject.setAbstract(true); if ((modifiers & Modifier.PUBLIC) != 0) classObject.setAccess(Access.PUBLIC); else if ((modifiers & Modifier.PROTECTED) != 0) classObject.setAccess(Access.PROTECTED); else if ((modifiers & Modifier.PRIVATE) != 0) classObject.setAccess(Access.PRIVATE); else classObject.setAccess(Access.NONE); if ((modifiers & Modifier.STATIC) != 0) classObject.setStatic(true); Type superclassType = typeDeclaration.getSuperclassType(); if (superclassType != null) { ITypeBinding binding = superclassType.resolveBinding(); String qualifiedName = binding.getQualifiedName(); TypeObject typeObject = TypeObject.extractTypeObject(qualifiedName); classObject.setSuperclass(typeObject); } List<Type> superInterfaceTypes = typeDeclaration.superInterfaceTypes(); for (Type interfaceType : superInterfaceTypes) { ITypeBinding binding = interfaceType.resolveBinding(); String qualifiedName = binding.getQualifiedName(); TypeObject typeObject = TypeObject.extractTypeObject(qualifiedName); classObject.addInterface(typeObject); } FieldDeclaration[] fieldDeclarations = typeDeclaration.getFields(); for (FieldDeclaration fieldDeclaration : fieldDeclarations) { Type fieldType = fieldDeclaration.getType(); ITypeBinding binding = fieldType.resolveBinding(); List<VariableDeclarationFragment> fragments = fieldDeclaration.fragments(); for (VariableDeclarationFragment fragment : fragments) { String qualifiedName = binding.getQualifiedName(); TypeObject typeObject = TypeObject.extractTypeObject(qualifiedName); typeObject.setArrayDimension( typeObject.getArrayDimension() + fragment.getExtraDimensions()); FieldObject fieldObject = new FieldObject(typeObject, fragment.getName().getIdentifier()); fieldObject.setClassName(classObject.getName()); fieldObject.setVariableDeclarationFragment(fragment); int fieldModifiers = fieldDeclaration.getModifiers(); if ((fieldModifiers & Modifier.PUBLIC) != 0) fieldObject.setAccess(Access.PUBLIC); else if ((fieldModifiers & Modifier.PROTECTED) != 0) fieldObject.setAccess(Access.PROTECTED); else if ((fieldModifiers & Modifier.PRIVATE) != 0) fieldObject.setAccess(Access.PRIVATE); else fieldObject.setAccess(Access.NONE); if ((fieldModifiers & Modifier.STATIC) != 0) fieldObject.setStatic(true); classObject.addField(fieldObject); } } MethodDeclaration[] methodDeclarations = typeDeclaration.getMethods(); for (MethodDeclaration methodDeclaration : methodDeclarations) { String methodName = methodDeclaration.getName().getIdentifier(); final ConstructorObject constructorObject = new ConstructorObject(); constructorObject.setMethodDeclaration(methodDeclaration); constructorObject.setName(methodName); constructorObject.setClassName(classObject.getName()); int methodModifiers = methodDeclaration.getModifiers(); if ((methodModifiers & Modifier.PUBLIC) != 0) constructorObject.setAccess(Access.PUBLIC); else if ((methodModifiers & Modifier.PROTECTED) != 0) constructorObject.setAccess(Access.PROTECTED); else if ((methodModifiers & Modifier.PRIVATE) != 0) constructorObject.setAccess(Access.PRIVATE); else constructorObject.setAccess(Access.NONE); List<SingleVariableDeclaration> parameters = methodDeclaration.parameters(); for (SingleVariableDeclaration parameter : parameters) { Type parameterType = parameter.getType(); ITypeBinding binding = parameterType.resolveBinding(); String qualifiedName = binding.getQualifiedName(); TypeObject typeObject = TypeObject.extractTypeObject(qualifiedName); typeObject.setArrayDimension( typeObject.getArrayDimension() + parameter.getExtraDimensions()); if (parameter.isVarargs()) { typeObject.setArrayDimension(1); } ParameterObject parameterObject = new ParameterObject(typeObject, parameter.getName().getIdentifier()); parameterObject.setSingleVariableDeclaration(parameter); constructorObject.addParameter(parameterObject); } Block methodBody = methodDeclaration.getBody(); if (methodBody != null) { MethodBodyObject methodBodyObject = new MethodBodyObject(methodBody); constructorObject.setMethodBody(methodBodyObject); } if (methodDeclaration.isConstructor()) { classObject.addConstructor(constructorObject); } else { MethodObject methodObject = new MethodObject(constructorObject); List<IExtendedModifier> extendedModifiers = methodDeclaration.modifiers(); for (IExtendedModifier extendedModifier : extendedModifiers) { if (extendedModifier.isAnnotation()) { Annotation annotation = (Annotation) extendedModifier; if (annotation.getTypeName().getFullyQualifiedName().equals("Test")) { methodObject.setTestAnnotation(true); break; } } } Type returnType = methodDeclaration.getReturnType2(); ITypeBinding binding = returnType.resolveBinding(); String qualifiedName = binding.getQualifiedName(); TypeObject typeObject = TypeObject.extractTypeObject(qualifiedName); methodObject.setReturnType(typeObject); if ((methodModifiers & Modifier.ABSTRACT) != 0) methodObject.setAbstract(true); if ((methodModifiers & Modifier.STATIC) != 0) methodObject.setStatic(true); if ((methodModifiers & Modifier.SYNCHRONIZED) != 0) methodObject.setSynchronized(true); if ((methodModifiers & Modifier.NATIVE) != 0) methodObject.setNative(true); classObject.addMethod(methodObject); FieldInstructionObject fieldInstruction = methodObject.isGetter(); if (fieldInstruction != null) systemObject.addGetter(methodObject.generateMethodInvocation(), fieldInstruction); fieldInstruction = methodObject.isSetter(); if (fieldInstruction != null) systemObject.addSetter(methodObject.generateMethodInvocation(), fieldInstruction); fieldInstruction = methodObject.isCollectionAdder(); if (fieldInstruction != null) systemObject.addCollectionAdder( methodObject.generateMethodInvocation(), fieldInstruction); MethodInvocationObject methodInvocation = methodObject.isDelegate(); if (methodInvocation != null) systemObject.addDelegate(methodObject.generateMethodInvocation(), methodInvocation); } } classObjects.add(classObject); } } } return classObjects; }
/*(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; } }
@Override protected void generate(EnumDeclaration node) { List<EnumConstantDeclaration> constants = ASTUtil.getEnumConstants(node); List<MethodDeclaration> methods = Lists.newArrayList(); List<FieldDeclaration> fields = Lists.newArrayList(); MethodDeclaration initializeMethod = null; for (BodyDeclaration decl : ASTUtil.getBodyDeclarations(node)) { if (decl instanceof FieldDeclaration) { fields.add((FieldDeclaration) decl); } else if (decl instanceof MethodDeclaration) { MethodDeclaration md = (MethodDeclaration) decl; if (md.getName().getIdentifier().equals("initialize")) { initializeMethod = md; } else { methods.add(md); } } } syncLineNumbers(node.getName()); // avoid doc-comment String typeName = NameTable.getFullName(node); newline(); for (EnumConstantDeclaration constant : constants) { IVariableBinding var = Types.getVariableBinding(constant.getName()); printf("static %s *%s;\n", typeName, NameTable.getStaticVarQualifiedName(var)); } printf("IOSObjectArray *%s_values;\n", typeName); newline(); printf("@implementation %s\n\n", typeName); printStaticVars(fields, /* isInterface */ false); printStaticReferencesMethod(fields, typeName + "_values"); for (EnumConstantDeclaration constant : constants) { String name = NameTable.getName(constant.getName()); printf("+ (%s *)%s {\n", typeName, name); printf(" return %s_%s;\n", typeName, name); println("}"); } newline(); // Enum constants needs to implement NSCopying. Being singletons, they // can just return self, as long the retain count is incremented. String selfString = Options.useReferenceCounting() ? "[self retain]" : "self"; printf("- (id)copyWithZone:(NSZone *)zone {\n return %s;\n}\n\n", selfString); printStaticFieldAccessors(fields, methods, /* isInterface */ false); printMethodsAndOcni(node, methods, blockComments.get(node)); printf("+ (void)initialize {\n if (self == [%s class]) {\n", typeName); for (int i = 0; i < constants.size(); i++) { EnumConstantDeclaration constant = constants.get(i); List<Expression> args = ASTUtil.getArguments(constant); String name = NameTable.getName(constant.getName()); String constantTypeName = NameTable.getFullName(Types.getMethodBinding(constant).getDeclaringClass()); printf(" %s_%s = [[%s alloc] init", typeName, name, constantTypeName); if (args.isEmpty()) { print("With"); } else { print( StatementGenerator.generateArguments( Types.getMethodBinding(constant), args, fieldHiders, getBuilder().getSourcePosition())); print(" with"); } printf("NSString:@\"%s\" withInt:%d];\n", name, i); } printf(" %s_values = [[IOSObjectArray alloc] initWithObjects:(id[]){ ", typeName); for (EnumConstantDeclaration constant : constants) { printf("%s_%s, ", typeName, NameTable.getName(constant.getName())); } printf( "nil } count:%d type:[IOSClass classWithClass:[%s class]]];\n", constants.size(), typeName); if (initializeMethod != null) { for (Statement s : ASTUtil.getStatements(initializeMethod.getBody())) { printf( " %s", StatementGenerator.generate(s, fieldHiders, false, getBuilder().getSourcePosition())); } } println(" }\n}\n"); // Print generated values and valueOf methods. println("+ (IOSObjectArray *)values {"); printf(" return [IOSObjectArray arrayWithArray:%s_values];\n", typeName); println("}\n"); printf("+ (%s *)valueOfWithNSString:(NSString *)name {\n", typeName); printf(" for (int i = 0; i < [%s_values count]; i++) {\n", typeName); printf(" %s *e = %s_values->buffer_[i];\n", typeName, typeName); printf(" if ([name isEqual:[e name]]) {\n"); printf(" return e;\n"); printf(" }\n"); printf(" }\n"); if (Options.useReferenceCounting()) { printf( " @throw [[[JavaLangIllegalArgumentException alloc] initWithNSString:name]" + " autorelease];\n"); } else { printf(" @throw [[JavaLangIllegalArgumentException alloc] initWithNSString:name];\n"); } printf(" return nil;\n"); println("}\n"); if (!Options.stripReflection()) { printTypeAnnotationsMethod(node); printMetadata(node); } println("@end"); }