| /******************************************************************************* |
| * Copyright (c) 2000, 2006 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.Collection; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.core.runtime.CoreException; |
| |
| import org.eclipse.swt.graphics.Image; |
| |
| import org.eclipse.jdt.core.CorrectionEngine; |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.dom.AST; |
| import org.eclipse.jdt.core.dom.ASTNode; |
| import org.eclipse.jdt.core.dom.Annotation; |
| import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration; |
| import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration; |
| import org.eclipse.jdt.core.dom.ArrayInitializer; |
| import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor; |
| import org.eclipse.jdt.core.dom.EnumConstantDeclaration; |
| import org.eclipse.jdt.core.dom.EnumDeclaration; |
| import org.eclipse.jdt.core.dom.Expression; |
| import org.eclipse.jdt.core.dom.FieldDeclaration; |
| import org.eclipse.jdt.core.dom.Initializer; |
| import org.eclipse.jdt.core.dom.MemberValuePair; |
| import org.eclipse.jdt.core.dom.MethodDeclaration; |
| import org.eclipse.jdt.core.dom.NormalAnnotation; |
| import org.eclipse.jdt.core.dom.SingleMemberAnnotation; |
| import org.eclipse.jdt.core.dom.SingleVariableDeclaration; |
| import org.eclipse.jdt.core.dom.StringLiteral; |
| import org.eclipse.jdt.core.dom.TypeDeclaration; |
| import org.eclipse.jdt.core.dom.VariableDeclarationFragment; |
| import org.eclipse.jdt.core.dom.VariableDeclarationStatement; |
| import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; |
| import org.eclipse.jdt.core.dom.rewrite.ListRewrite; |
| |
| 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.internal.ui.JavaPlugin; |
| import org.eclipse.jdt.internal.ui.JavaPluginImages; |
| |
| /** |
| * |
| */ |
| public class SuppressWarningsSubProcessor { |
| |
| private static final String ADD_SUPPRESSWARNINGS_ID= "org.eclipse.jdt.ui.correction.addSuppressWarnings"; //$NON-NLS-1$ |
| |
| public static final boolean hasSuppressWarningsProposal(int problemId) { |
| return CorrectionEngine.getWarningToken(problemId) != null; // Suppress warning annotations |
| } |
| |
| |
| public static void addSuppressWarningsProposals(IInvocationContext context, IProblemLocation problem, Collection proposals) { |
| if (problem.isError()) { |
| return; |
| } |
| String warningToken= CorrectionEngine.getWarningToken(problem.getProblemId()); |
| if (warningToken == null) { |
| return; |
| } |
| for (Iterator iter= proposals.iterator(); iter.hasNext();) { |
| Object element= iter.next(); |
| if (element instanceof SuppressWarningsProposal && warningToken.equals(((SuppressWarningsProposal) element).getWarningToken())) { |
| return; // only one at a time |
| } |
| } |
| |
| ASTNode node= problem.getCoveringNode(context.getASTRoot()); |
| if (node == null) { |
| return; |
| } |
| if (node.getLocationInParent() == VariableDeclarationFragment.NAME_PROPERTY) { |
| ASTNode parent= node.getParent(); |
| if (parent.getLocationInParent() == VariableDeclarationStatement.FRAGMENTS_PROPERTY) { |
| addSuppressWarningsProposal(context.getCompilationUnit(), parent.getParent(), warningToken, -2, proposals); |
| return; |
| } |
| } else if (node.getLocationInParent() == SingleVariableDeclaration.NAME_PROPERTY) { |
| addSuppressWarningsProposal(context.getCompilationUnit(), node.getParent(), warningToken, -2, proposals); |
| return; |
| } else if (node.getLocationInParent() == VariableDeclarationFragment.INITIALIZER_PROPERTY) { |
| node= ASTResolving.findParentBodyDeclaration(node); |
| if (node instanceof FieldDeclaration) { |
| node= node.getParent(); |
| } |
| } |
| |
| ASTNode target= ASTResolving.findParentBodyDeclaration(node); |
| if (target instanceof Initializer) { |
| target= ASTResolving.findParentBodyDeclaration(target.getParent()); |
| } |
| if (target != null) { |
| addSuppressWarningsProposal(context.getCompilationUnit(), target, warningToken, -3, proposals); |
| } |
| } |
| |
| private static String getFirstFragmentName(List fragments) { |
| if (fragments.size() > 0) { |
| return ((VariableDeclarationFragment) fragments.get(0)).getName().getIdentifier(); |
| } |
| return new String(); |
| } |
| |
| |
| private static class SuppressWarningsProposal extends ASTRewriteCorrectionProposal { |
| |
| private final String fWarningToken; |
| private final ASTNode fNode; |
| private final ChildListPropertyDescriptor fProperty; |
| |
| public SuppressWarningsProposal(String warningToken, String label, ICompilationUnit cu, ASTNode node, ChildListPropertyDescriptor property, int relevance) { |
| super(label, cu, null, relevance, JavaPluginImages.get(JavaPluginImages.IMG_OBJS_ANNOTATION)); |
| fWarningToken= warningToken; |
| fNode= node; |
| fProperty= property; |
| setCommandId(ADD_SUPPRESSWARNINGS_ID); |
| } |
| |
| /** |
| * @return Returns the warningToken. |
| */ |
| public String getWarningToken() { |
| return fWarningToken; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.internal.ui.text.correction.ASTRewriteCorrectionProposal#getRewrite() |
| */ |
| protected ASTRewrite getRewrite() throws CoreException { |
| AST ast= fNode.getAST(); |
| ASTRewrite rewrite= ASTRewrite.create(ast); |
| |
| StringLiteral newStringLiteral= ast.newStringLiteral(); |
| newStringLiteral.setLiteralValue(fWarningToken); |
| |
| Annotation existing= findExistingAnnotation((List) fNode.getStructuralProperty(fProperty)); |
| if (existing == null) { |
| ListRewrite listRewrite= rewrite.getListRewrite(fNode, fProperty); |
| |
| SingleMemberAnnotation newAnnot= ast.newSingleMemberAnnotation(); |
| newAnnot.setTypeName(ast.newSimpleName("SuppressWarnings")); //$NON-NLS-1$ |
| |
| newAnnot.setValue(newStringLiteral); |
| |
| listRewrite.insertFirst(newAnnot, null); |
| } else if (existing instanceof SingleMemberAnnotation) { |
| SingleMemberAnnotation annotation= (SingleMemberAnnotation) existing; |
| Expression value= annotation.getValue(); |
| if (!addSuppressArgument(rewrite, value, newStringLiteral)) { |
| rewrite.set(existing, SingleMemberAnnotation.VALUE_PROPERTY, newStringLiteral, null); |
| } |
| } else if (existing instanceof NormalAnnotation) { |
| NormalAnnotation annotation= (NormalAnnotation) existing; |
| Expression value= findValue(annotation.values()); |
| if (!addSuppressArgument(rewrite, value, newStringLiteral)) { |
| ListRewrite listRewrite= rewrite.getListRewrite(annotation, NormalAnnotation.VALUES_PROPERTY); |
| MemberValuePair pair= ast.newMemberValuePair(); |
| pair.setName(ast.newSimpleName("value")); //$NON-NLS-1$ |
| pair.setValue(newStringLiteral); |
| listRewrite.insertFirst(pair, null); |
| } |
| } |
| return rewrite; |
| } |
| |
| private static boolean addSuppressArgument(ASTRewrite rewrite, Expression value, StringLiteral newStringLiteral) { |
| if (value instanceof ArrayInitializer) { |
| ListRewrite listRewrite= rewrite.getListRewrite(value, ArrayInitializer.EXPRESSIONS_PROPERTY); |
| listRewrite.insertLast(newStringLiteral, null); |
| } else if (value instanceof StringLiteral) { |
| ArrayInitializer newArr= rewrite.getAST().newArrayInitializer(); |
| newArr.expressions().add(rewrite.createMoveTarget(value)); |
| newArr.expressions().add(newStringLiteral); |
| rewrite.replace(value, newArr, null); |
| } else { |
| return false; |
| } |
| return true; |
| } |
| |
| private static Expression findValue(List keyValues) { |
| for (int i= 0, len= keyValues.size(); i < len; i++) { |
| MemberValuePair curr= (MemberValuePair) keyValues.get(i); |
| if ("value".equals(curr.getName().getIdentifier())) { //$NON-NLS-1$ |
| return curr.getValue(); |
| } |
| } |
| return null; |
| } |
| |
| private static Annotation findExistingAnnotation(List modifiers) { |
| for (int i= 0, len= modifiers.size(); i < len; i++) { |
| Object curr= modifiers.get(i); |
| if (curr instanceof NormalAnnotation || curr instanceof SingleMemberAnnotation) { |
| Annotation annotation= (Annotation) curr; |
| String fullyQualifiedName= annotation.getTypeName().getFullyQualifiedName(); |
| if ("SuppressWarnings".equals(fullyQualifiedName) || "java.lang.SuppressWarnings".equals(fullyQualifiedName)) { //$NON-NLS-1$ //$NON-NLS-2$ |
| return annotation; |
| } |
| } |
| } |
| return null; |
| } |
| } |
| |
| private static void addSuppressWarningsProposal(ICompilationUnit cu, ASTNode node, String warningToken, int relevance, Collection proposals) { |
| |
| ChildListPropertyDescriptor property= null; |
| String name; |
| switch (node.getNodeType()) { |
| case ASTNode.SINGLE_VARIABLE_DECLARATION: |
| property= SingleVariableDeclaration.MODIFIERS2_PROPERTY; |
| name= ((SingleVariableDeclaration) node).getName().getIdentifier(); |
| break; |
| case ASTNode.VARIABLE_DECLARATION_STATEMENT: |
| property= VariableDeclarationStatement.MODIFIERS2_PROPERTY; |
| name= getFirstFragmentName(((VariableDeclarationStatement) node).fragments()); |
| break; |
| case ASTNode.TYPE_DECLARATION: |
| property= TypeDeclaration.MODIFIERS2_PROPERTY; |
| name= ((TypeDeclaration) node).getName().getIdentifier(); |
| break; |
| case ASTNode.ANNOTATION_TYPE_DECLARATION: |
| property= AnnotationTypeDeclaration.MODIFIERS2_PROPERTY; |
| name= ((AnnotationTypeDeclaration) node).getName().getIdentifier(); |
| break; |
| case ASTNode.ENUM_DECLARATION: |
| property= EnumDeclaration.MODIFIERS2_PROPERTY; |
| name= ((EnumDeclaration) node).getName().getIdentifier(); |
| break; |
| case ASTNode.FIELD_DECLARATION: |
| property= FieldDeclaration.MODIFIERS2_PROPERTY; |
| name= getFirstFragmentName(((FieldDeclaration) node).fragments()); |
| break; |
| case ASTNode.INITIALIZER: |
| property= Initializer.MODIFIERS2_PROPERTY; |
| name= CorrectionMessages.SuppressWarningsSubProcessor_suppress_warnings_initializer_label; |
| break; |
| case ASTNode.METHOD_DECLARATION: |
| property= MethodDeclaration.MODIFIERS2_PROPERTY; |
| name= ((MethodDeclaration) node).getName().getIdentifier() + "()"; //$NON-NLS-1$ |
| break; |
| case ASTNode.ANNOTATION_TYPE_MEMBER_DECLARATION: |
| property= AnnotationTypeMemberDeclaration.MODIFIERS2_PROPERTY; |
| name= ((AnnotationTypeMemberDeclaration) node).getName().getIdentifier() + "()"; //$NON-NLS-1$ |
| break; |
| case ASTNode.ENUM_CONSTANT_DECLARATION: |
| property= EnumConstantDeclaration.MODIFIERS2_PROPERTY; |
| name= ((EnumConstantDeclaration) node).getName().getIdentifier(); |
| break; |
| default: |
| JavaPlugin.logErrorMessage("SuppressWarning quick fix: wrong node kind: " + node.getNodeType()); //$NON-NLS-1$ |
| return; |
| } |
| |
| String label= Messages.format(CorrectionMessages.SuppressWarningsSubProcessor_suppress_warnings_label, new String[] { warningToken, name }); |
| ASTRewriteCorrectionProposal proposal= new SuppressWarningsProposal(warningToken, label, cu, node, property, relevance); |
| |
| proposals.add(proposal); |
| } |
| |
| public static void addUnknownSuppressWarningProposals(IInvocationContext context, IProblemLocation problem, Collection proposals) { |
| |
| ASTNode coveringNode= context.getCoveringNode(); |
| if (!(coveringNode instanceof StringLiteral)) |
| return; |
| |
| AST ast= coveringNode.getAST(); |
| StringLiteral literal= (StringLiteral) coveringNode; |
| |
| String literalValue= literal.getLiteralValue(); |
| String[] allWarningTokens= CorrectionEngine.getAllWarningTokens(); |
| for (int i= 0; i < allWarningTokens.length; i++) { |
| String curr= allWarningTokens[i]; |
| if (NameMatcher.isSimilarName(literalValue, curr)) { |
| StringLiteral newLiteral= ast.newStringLiteral(); |
| newLiteral.setLiteralValue(curr); |
| ASTRewrite rewrite= ASTRewrite.create(ast); |
| rewrite.replace(literal, newLiteral, null); |
| String label= Messages.format(CorrectionMessages.SuppressWarningsSubProcessor_fix_suppress_token_label, new String[] { curr }); |
| Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); |
| ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 5, image); |
| proposals.add(proposal); |
| } |
| } |
| } |
| |
| } |