]> git.uio.no Git - ifi-stolz-refaktor.git/blobdiff - case-study/jdt-after/ui/org/eclipse/jdt/internal/ui/text/correction/ReturnTypeSubProcessor.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-after / ui / org / eclipse / jdt / internal / ui / text / correction / ReturnTypeSubProcessor.java
diff --git a/case-study/jdt-after/ui/org/eclipse/jdt/internal/ui/text/correction/ReturnTypeSubProcessor.java b/case-study/jdt-after/ui/org/eclipse/jdt/internal/ui/text/correction/ReturnTypeSubProcessor.java
new file mode 100644 (file)
index 0000000..66ba723
--- /dev/null
@@ -0,0 +1,343 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.ui.text.correction;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.eclipse.swt.graphics.Image;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
+import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
+import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
+import org.eclipse.jdt.core.dom.Block;
+import org.eclipse.jdt.core.dom.BodyDeclaration;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.EnumDeclaration;
+import org.eclipse.jdt.core.dom.Expression;
+import org.eclipse.jdt.core.dom.ITypeBinding;
+import org.eclipse.jdt.core.dom.Javadoc;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.PrimitiveType;
+import org.eclipse.jdt.core.dom.ReturnStatement;
+import org.eclipse.jdt.core.dom.TagElement;
+import org.eclipse.jdt.core.dom.TextElement;
+import org.eclipse.jdt.core.dom.Type;
+import org.eclipse.jdt.core.dom.TypeDeclaration;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
+import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext;
+
+import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext;
+import org.eclipse.jdt.internal.corext.dom.ASTNodes;
+import org.eclipse.jdt.internal.corext.dom.Bindings;
+import org.eclipse.jdt.internal.corext.util.Messages;
+
+import org.eclipse.jdt.ui.text.java.IInvocationContext;
+import org.eclipse.jdt.ui.text.java.IProblemLocation;
+import org.eclipse.jdt.ui.text.java.correction.ASTRewriteCorrectionProposal;
+import org.eclipse.jdt.ui.text.java.correction.ICommandAccess;
+
+import org.eclipse.jdt.internal.ui.JavaPluginImages;
+import org.eclipse.jdt.internal.ui.text.correction.proposals.LinkedCorrectionProposal;
+import org.eclipse.jdt.internal.ui.text.correction.proposals.MissingReturnTypeCorrectionProposal;
+import org.eclipse.jdt.internal.ui.text.correction.proposals.ReplaceCorrectionProposal;
+import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;
+import org.eclipse.jdt.internal.ui.viewsupport.BindingLabelProvider;
+
+
+public class ReturnTypeSubProcessor {
+
+       private static class ReturnStatementCollector extends ASTVisitor {
+               private ArrayList<ReturnStatement> fResult= new ArrayList<ReturnStatement>();
+
+               public ITypeBinding getTypeBinding(AST ast) {
+                       boolean couldBeObject= false;
+                       for (int i= 0; i < fResult.size(); i++) {
+                               ReturnStatement node= fResult.get(i);
+                               Expression expr= node.getExpression();
+                               if (expr != null) {
+                                       ITypeBinding binding= Bindings.normalizeTypeBinding(expr.resolveTypeBinding());
+                                       if (binding != null) {
+                                               return binding;
+                                       } else {
+                                               couldBeObject= true;
+                                       }
+                               } else {
+                                       return ast.resolveWellKnownType("void"); //$NON-NLS-1$
+                               }
+                       }
+                       if (couldBeObject) {
+                               return ast.resolveWellKnownType("java.lang.Object"); //$NON-NLS-1$
+                       }
+                       return ast.resolveWellKnownType("void"); //$NON-NLS-1$
+               }
+
+               @Override
+               public boolean visit(ReturnStatement node) {
+                       fResult.add(node);
+                       return false;
+               }
+
+               @Override
+               public boolean visit(AnonymousClassDeclaration node) {
+                       return false;
+               }
+
+               @Override
+               public boolean visit(TypeDeclaration node) {
+                       return false;
+               }
+
+               @Override
+               public boolean visit(EnumDeclaration node) {
+                       return false;
+               }
+
+               @Override
+               public boolean visit(AnnotationTypeDeclaration node) {
+                       return false;
+               }
+
+       }
+
+
+       public static void addMethodWithConstrNameProposals(IInvocationContext context, IProblemLocation problem, Collection<ICommandAccess> proposals) {
+               ICompilationUnit cu= context.getCompilationUnit();
+
+               ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot());
+               if (selectedNode instanceof MethodDeclaration) {
+                       MethodDeclaration declaration= (MethodDeclaration) selectedNode;
+
+                       ASTRewrite rewrite= ASTRewrite.create(declaration.getAST());
+                       rewrite.set(declaration, MethodDeclaration.CONSTRUCTOR_PROPERTY, Boolean.TRUE, null);
+
+                       String label= CorrectionMessages.ReturnTypeSubProcessor_constrnamemethod_description;
+                       Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
+                       ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, cu, rewrite, 5, image);
+                       proposals.add(proposal);
+               }
+
+       }
+
+       public static void addVoidMethodReturnsProposals(IInvocationContext context, IProblemLocation problem, Collection<ICommandAccess> proposals) {
+               ICompilationUnit cu= context.getCompilationUnit();
+
+               CompilationUnit astRoot= context.getASTRoot();
+               ASTNode selectedNode= problem.getCoveringNode(astRoot);
+               if (selectedNode == null) {
+                       return;
+               }
+
+               BodyDeclaration decl= ASTResolving.findParentBodyDeclaration(selectedNode);
+               if (decl instanceof MethodDeclaration && selectedNode.getNodeType() == ASTNode.RETURN_STATEMENT) {
+                       ReturnStatement returnStatement= (ReturnStatement) selectedNode;
+                       Expression expr= returnStatement.getExpression();
+                       if (expr != null) {
+                               AST ast= astRoot.getAST();
+
+                               ITypeBinding binding= Bindings.normalizeTypeBinding(expr.resolveTypeBinding());
+                               if (binding == null) {
+                                       binding= ast.resolveWellKnownType("java.lang.Object"); //$NON-NLS-1$
+                               }
+                               if (binding.isWildcardType()) {
+                                       binding= ASTResolving.normalizeWildcardType(binding, true, ast);
+                               }
+
+                               MethodDeclaration methodDeclaration= (MethodDeclaration) decl;
+
+                               ASTRewrite rewrite= ASTRewrite.create(ast);
+
+                               String label= Messages.format(CorrectionMessages.ReturnTypeSubProcessor_voidmethodreturns_description, BindingLabelProvider.getBindingLabel(binding, BindingLabelProvider.DEFAULT_TEXTFLAGS));
+                               Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
+                               LinkedCorrectionProposal proposal= new LinkedCorrectionProposal(label, cu, rewrite, 6, image);
+                               ImportRewrite imports= proposal.createImportRewrite(astRoot);
+                               ImportRewriteContext importRewriteContext= new ContextSensitiveImportRewriteContext(methodDeclaration, imports);
+                               Type newReturnType= imports.addImport(binding, ast, importRewriteContext);
+
+                               if (methodDeclaration.isConstructor()) {
+                                       rewrite.set(methodDeclaration, MethodDeclaration.CONSTRUCTOR_PROPERTY, Boolean.FALSE, null);
+                                       rewrite.set(methodDeclaration, MethodDeclaration.RETURN_TYPE2_PROPERTY, newReturnType, null);
+                               } else {
+                                       rewrite.replace(methodDeclaration.getReturnType2(), newReturnType, null);
+                               }
+                               String key= "return_type"; //$NON-NLS-1$
+                               proposal.addLinkedPosition(rewrite.track(newReturnType), true, key);
+                               ITypeBinding[] bindings= ASTResolving.getRelaxingTypes(ast, binding);
+                               for (int i= 0; i < bindings.length; i++) {
+                                       proposal.addLinkedPositionProposal(key, bindings[i]);
+                               }
+
+                               Javadoc javadoc= methodDeclaration.getJavadoc();
+                               if (javadoc != null) {
+                                       TagElement newTag= ast.newTagElement();
+                                       newTag.setTagName(TagElement.TAG_RETURN);
+                                       TextElement commentStart= ast.newTextElement();
+                                       newTag.fragments().add(commentStart);
+
+                                       JavadocTagsSubProcessor.insertTag(rewrite.getListRewrite(javadoc, Javadoc.TAGS_PROPERTY), newTag, null);
+                                       proposal.addLinkedPosition(rewrite.track(commentStart), false, "comment_start"); //$NON-NLS-1$
+
+                               }
+                               proposals.add(proposal);
+                       }
+                       ASTRewrite rewrite= ASTRewrite.create(decl.getAST());
+                       rewrite.remove(returnStatement.getExpression(), null);
+
+                       String label= CorrectionMessages.ReturnTypeSubProcessor_removereturn_description;
+                       Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
+                       ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, cu, rewrite, 5, image);
+                       proposals.add(proposal);
+               }
+       }
+
+
+
+       public static void addMissingReturnTypeProposals(IInvocationContext context, IProblemLocation problem, Collection<ICommandAccess> proposals) {
+               ICompilationUnit cu= context.getCompilationUnit();
+
+               CompilationUnit astRoot= context.getASTRoot();
+               ASTNode selectedNode= problem.getCoveringNode(astRoot);
+               if (selectedNode == null) {
+                       return;
+               }
+               BodyDeclaration decl= ASTResolving.findParentBodyDeclaration(selectedNode);
+               if (decl instanceof MethodDeclaration) {
+                       MethodDeclaration methodDeclaration= (MethodDeclaration) decl;
+
+                       ReturnStatementCollector eval= new ReturnStatementCollector();
+                       decl.accept(eval);
+
+                       AST ast= astRoot.getAST();
+
+                       ITypeBinding typeBinding= eval.getTypeBinding(decl.getAST());
+                       typeBinding= Bindings.normalizeTypeBinding(typeBinding);
+                       if (typeBinding == null) {
+                               typeBinding= ast.resolveWellKnownType("void"); //$NON-NLS-1$
+                       }
+                       if (typeBinding.isWildcardType()) {
+                               typeBinding= ASTResolving.normalizeWildcardType(typeBinding, true, ast);
+                       }
+
+                       ASTRewrite rewrite= ASTRewrite.create(ast);
+
+                       String label= Messages.format(CorrectionMessages.ReturnTypeSubProcessor_missingreturntype_description, BindingLabelProvider.getBindingLabel(typeBinding, BindingLabelProvider.DEFAULT_TEXTFLAGS));
+                       Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
+                       LinkedCorrectionProposal proposal= new LinkedCorrectionProposal(label, cu, rewrite, 6, image);
+
+                       ImportRewrite imports= proposal.createImportRewrite(astRoot);
+                       ImportRewriteContext importRewriteContext= new ContextSensitiveImportRewriteContext(decl, imports);
+                       Type type= imports.addImport(typeBinding, ast, importRewriteContext);
+
+                       rewrite.set(methodDeclaration, MethodDeclaration.RETURN_TYPE2_PROPERTY, type, null);
+                       rewrite.set(methodDeclaration, MethodDeclaration.CONSTRUCTOR_PROPERTY, Boolean.FALSE, null);
+
+                       Javadoc javadoc= methodDeclaration.getJavadoc();
+                       if (javadoc != null && typeBinding != null) {
+                               TagElement newTag= ast.newTagElement();
+                               newTag.setTagName(TagElement.TAG_RETURN);
+                               TextElement commentStart= ast.newTextElement();
+                               newTag.fragments().add(commentStart);
+
+                               JavadocTagsSubProcessor.insertTag(rewrite.getListRewrite(javadoc, Javadoc.TAGS_PROPERTY), newTag, null);
+                               proposal.addLinkedPosition(rewrite.track(commentStart), false, "comment_start"); //$NON-NLS-1$
+                       }
+
+                       String key= "return_type"; //$NON-NLS-1$
+                       proposal.addLinkedPosition(rewrite.track(type), true, key);
+                       if (typeBinding != null) {
+                               ITypeBinding[] bindings= ASTResolving.getRelaxingTypes(ast, typeBinding);
+                               for (int i= 0; i < bindings.length; i++) {
+                                       proposal.addLinkedPositionProposal(key, bindings[i]);
+                               }
+                       }
+
+                       proposals.add(proposal);
+
+                       // change to constructor
+                       ASTNode parentType= ASTResolving.findParentType(decl);
+                       if (parentType instanceof AbstractTypeDeclaration) {
+                               boolean isInterface= parentType instanceof TypeDeclaration && ((TypeDeclaration) parentType).isInterface();
+                               if (!isInterface) {
+                                       String constructorName= ((AbstractTypeDeclaration) parentType).getName().getIdentifier();
+                                       ASTNode nameNode= methodDeclaration.getName();
+                                       label= Messages.format(CorrectionMessages.ReturnTypeSubProcessor_wrongconstructorname_description, BasicElementLabels.getJavaElementName(constructorName));
+                                       proposals.add(new ReplaceCorrectionProposal(label, cu, nameNode.getStartPosition(), nameNode.getLength(), constructorName, 5));
+                               }
+                       }
+               }
+       }
+
+       public static void addMissingReturnStatementProposals(IInvocationContext context, IProblemLocation problem, Collection<ICommandAccess> proposals) {
+               ICompilationUnit cu= context.getCompilationUnit();
+
+               ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot());
+               if (selectedNode == null) {
+                       return;
+               }
+               BodyDeclaration decl= ASTResolving.findParentBodyDeclaration(selectedNode);
+               if (decl instanceof MethodDeclaration) {
+                       MethodDeclaration methodDecl= (MethodDeclaration) decl;
+                       Block block= methodDecl.getBody();
+                       if (block == null) {
+                               return;
+                       }
+                       ReturnStatement existingStatement= (selectedNode instanceof ReturnStatement) ? (ReturnStatement) selectedNode : null;
+                       proposals.add( new MissingReturnTypeCorrectionProposal(cu, methodDecl, existingStatement, 6));
+
+                       Type returnType= methodDecl.getReturnType2();
+                       if (returnType != null && !"void".equals(ASTNodes.asString(returnType))) { //$NON-NLS-1$
+                               AST ast= methodDecl.getAST();
+                               ASTRewrite rewrite= ASTRewrite.create(ast);
+                               rewrite.replace(returnType, ast.newPrimitiveType(PrimitiveType.VOID), null);
+                               Javadoc javadoc= methodDecl.getJavadoc();
+                               if (javadoc != null) {
+                                       TagElement tagElement= JavadocTagsSubProcessor.findTag(javadoc, TagElement.TAG_RETURN, null);
+                                       if (tagElement != null) {
+                                               rewrite.remove(tagElement, null);
+                                       }
+                               }
+
+                               String label= CorrectionMessages.ReturnTypeSubProcessor_changetovoid_description;
+                               Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
+                               ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, cu, rewrite, 5, image);
+                               proposals.add(proposal);
+                       }
+               }
+       }
+
+       public static void addMethodRetunsVoidProposals(IInvocationContext context, IProblemLocation problem, Collection<ICommandAccess> proposals) throws JavaModelException {
+               CompilationUnit astRoot= context.getASTRoot();
+               ASTNode selectedNode= problem.getCoveringNode(astRoot);
+               if (!(selectedNode instanceof ReturnStatement)) {
+                       return;
+               }
+               ReturnStatement returnStatement= (ReturnStatement) selectedNode;
+               Expression expression= returnStatement.getExpression();
+               if (expression == null) {
+                       return;
+               }
+               BodyDeclaration decl= ASTResolving.findParentBodyDeclaration(selectedNode);
+               if (decl instanceof MethodDeclaration) {
+                       MethodDeclaration methDecl= (MethodDeclaration) decl;
+                       Type retType= methDecl.getReturnType2();
+                       if (retType == null || retType.resolveBinding() == null) {
+                               return;
+                       }
+                       TypeMismatchSubProcessor.addChangeSenderTypeProposals(context, expression, retType.resolveBinding(), false, 4, proposals);
+               }
+       }
+}