diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.java index ea67dd8f41e..6bfd02d6246 100644 --- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.java +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.java @@ -159,6 +159,7 @@ private MultiFixMessages() { public static String RedundantModifiersCleanup_description; public static String SubstringCleanUp_description; public static String InlineDeprecatedMethodCleanUp_description; + public static String ReplaceDeprecatedFieldsCleanUp_description; public static String JoinCleanup_description; public static String ArraysFillCleanUp_description; public static String EvaluateNullableCleanUp_description; diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.properties b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.properties index 48c1a7f2e5a..d5880d15c1c 100644 --- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.properties +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/MultiFixMessages.properties @@ -140,6 +140,7 @@ HashCleanup_description=Use Objects.hash() RedundantModifiersCleanup_description=Remove redundant modifiers SubstringCleanUp_description=Remove redundant String.substring() parameter InlineDeprecatedMethodCleanUp_description=Replace deprecated calls with inlined content where possible +ReplaceDeprecatedFieldsCleanUp_description=Replace deprecated fields where possible JoinCleanup_description=Use String.join() ArraysFillCleanUp_description=Use Arrays.fill() when possible EvaluateNullableCleanUp_description=Evaluate without null check diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/ReplaceDeprecatedFieldCleanUpCore.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/ReplaceDeprecatedFieldCleanUpCore.java new file mode 100644 index 00000000000..4be17e6868d --- /dev/null +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/ReplaceDeprecatedFieldCleanUpCore.java @@ -0,0 +1,184 @@ +/******************************************************************************* + * Copyright (c) 2025 Red Hat Inc. and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.ui.fix; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.ASTVisitor; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.FieldAccess; +import org.eclipse.jdt.core.dom.QualifiedName; +import org.eclipse.jdt.core.dom.SimpleName; +import org.eclipse.jdt.core.dom.SuperFieldAccess; +import org.eclipse.jdt.core.dom.VariableDeclarationFragment; + +import org.eclipse.jdt.internal.corext.fix.CleanUpConstants; +import org.eclipse.jdt.internal.corext.fix.CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation; +import org.eclipse.jdt.internal.corext.fix.ReplaceDeprecatedFieldFixCore; + +import org.eclipse.jdt.ui.cleanup.CleanUpRequirements; +import org.eclipse.jdt.ui.cleanup.ICleanUpFix; +import org.eclipse.jdt.ui.text.java.IProblemLocation; + +import org.eclipse.jdt.internal.ui.text.correction.QuickAssistProcessorUtil; + +public class ReplaceDeprecatedFieldCleanUpCore extends AbstractMultiFix { + + public ReplaceDeprecatedFieldCleanUpCore() { + this(Collections.emptyMap()); + } + + public ReplaceDeprecatedFieldCleanUpCore(final Map options) { + super(options); + } + + @Override + public CleanUpRequirements getRequirements() { + boolean requireAST= isEnabled(CleanUpConstants.REPLACE_DEPRECATED_FIELDS); + return new CleanUpRequirements(requireAST, false, false, null); + } + + @Override + public String[] getStepDescriptions() { + if (isEnabled(CleanUpConstants.REPLACE_DEPRECATED_FIELDS)) { + return new String[] { MultiFixMessages.ReplaceDeprecatedFieldsCleanUp_description }; + } + return new String[0]; + } + + @Override + public String getPreview() { + StringBuilder bld= new StringBuilder(); + bld.append("Class E {\n"); //$NON-NLS-1$ + bld.append(" /**\n"); //$NON-NLS-1$ + bld.append(" * @deprecated use {@link K#field2} instead\n"); //$NON-NLS-1$ + bld.append(" */\n"); //$NON-NLS-1$ + bld.append(" @Deprecated\n"); //$NON-NLS-1$ + bld.append(" public int field1;\n"); //$NON-NLS-1$ + bld.append("}\n\n"); //$NON-NLS-1$ + if (isEnabled(CleanUpConstants.REPLACE_DEPRECATED_FIELDS)) { + bld.append("return K.field2;\n"); //$NON-NLS-1$ + } else { + bld.append("return E.field1;\n"); //$NON-NLS-1$ + } + return bld.toString(); + } + + @Override + public boolean canFix(ICompilationUnit compilationUnit, IProblemLocation problem) { + return false; + } + + @Override + protected ICleanUpFix createFix(CompilationUnit compilationUnit) throws CoreException { + if (!isEnabled(CleanUpConstants.REPLACE_DEPRECATED_FIELDS)) { + return null; + } + if (compilationUnit == null) + return null; + + final List deprecatedFields= new ArrayList<>(); + ASTVisitor visitor= new ASTVisitor() { + @Override + public boolean visit(QualifiedName node) { + String replacement= QuickAssistProcessorUtil.getDeprecatedFieldReplacement(node); + if (replacement != null) { + deprecatedFields.add(new ReplaceDeprecatedFieldFixCore.ReplaceDeprecatedFieldProposalOperation(node, replacement)); + } + return false; + } + @Override + public boolean visit(SimpleName node) { + if (node.getLocationInParent() == VariableDeclarationFragment.NAME_PROPERTY) { + return true; + } + String replacement= QuickAssistProcessorUtil.getDeprecatedFieldReplacement(node); + if (replacement != null) { + deprecatedFields.add(new ReplaceDeprecatedFieldFixCore.ReplaceDeprecatedFieldProposalOperation(node, replacement)); + } + return false; + } + @Override + public boolean visit(FieldAccess node) { + String replacement= QuickAssistProcessorUtil.getDeprecatedFieldReplacement(node); + if (replacement != null) { + deprecatedFields.add(new ReplaceDeprecatedFieldFixCore.ReplaceDeprecatedFieldProposalOperation(node, replacement)); + } + return false; + } + @Override + public boolean visit(SuperFieldAccess node) { + String replacement= QuickAssistProcessorUtil.getDeprecatedFieldReplacement(node); + if (replacement != null) { + deprecatedFields.add(new ReplaceDeprecatedFieldFixCore.ReplaceDeprecatedFieldProposalOperation(node, replacement)); + } + return false; + } + }; + compilationUnit.accept(visitor); + if (deprecatedFields.isEmpty()) { + return null; + } + return new ReplaceDeprecatedFieldFixCore(getPreview(), compilationUnit, deprecatedFields.toArray(new CompilationUnitRewriteOperation[0])); + } + + @Override + public int computeNumberOfFixes(CompilationUnit compilationUnit) { + if (!isEnabled(CleanUpConstants.REPLACE_DEPRECATED_FIELDS)) { + return 0; + } + if (compilationUnit == null) + return 0; + + final List deprecatedFields= new ArrayList<>(); + ASTVisitor visitor= new ASTVisitor() { + @Override + public boolean visit(QualifiedName node) { + if (QuickAssistProcessorUtil.getDeprecatedFieldReplacement(node) != null) { + deprecatedFields.add(node); + } + return true; + } + @Override + public boolean visit(FieldAccess node) { + if (QuickAssistProcessorUtil.getDeprecatedFieldReplacement(node) != null) { + deprecatedFields.add(node); + } + return true; + } + @Override + public boolean visit(SuperFieldAccess node) { + if (QuickAssistProcessorUtil.getDeprecatedFieldReplacement(node) != null) { + deprecatedFields.add(node); + } + return true; + } + }; + compilationUnit.accept(visitor); + return deprecatedFields.size(); + } + + @Override + protected ICleanUpFix createFix(CompilationUnit unit, IProblemLocation[] problems) throws CoreException { + return null; + } + +} diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/IProposalRelevance.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/IProposalRelevance.java index 12599dfa0ed..7cab39985f4 100644 --- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/IProposalRelevance.java +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/IProposalRelevance.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012, 2024 IBM Corporation and others. + * Copyright (c) 2012, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -58,6 +58,7 @@ public interface IProposalRelevance { int CREATE_OPTIONAL= 9; int CREATE_OPTIONAL_OF_NULLABLE= 9; int INLINE_DEPRECATED_METHOD= 9; + int REPLACE_DEPRECATED_FIELD= 9; int ADD_ABSTRACT_MODIFIER= 8; int ADD_STATIC_MODIFIER= 8; diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessorUtil.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessorUtil.java index 4b7c62b4989..70d634b272f 100644 --- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessorUtil.java +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessorUtil.java @@ -27,6 +27,7 @@ import org.eclipse.jdt.core.IBuffer; import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IField; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.dom.AST; @@ -41,6 +42,8 @@ import org.eclipse.jdt.core.dom.Expression; import org.eclipse.jdt.core.dom.ExpressionMethodReference; import org.eclipse.jdt.core.dom.ExpressionStatement; +import org.eclipse.jdt.core.dom.FieldAccess; +import org.eclipse.jdt.core.dom.FieldDeclaration; import org.eclipse.jdt.core.dom.IAnnotationBinding; import org.eclipse.jdt.core.dom.IBinding; import org.eclipse.jdt.core.dom.IDocElement; @@ -49,6 +52,7 @@ import org.eclipse.jdt.core.dom.IVariableBinding; import org.eclipse.jdt.core.dom.Javadoc; import org.eclipse.jdt.core.dom.LambdaExpression; +import org.eclipse.jdt.core.dom.MemberRef; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.MethodInvocation; import org.eclipse.jdt.core.dom.MethodRef; @@ -56,9 +60,11 @@ import org.eclipse.jdt.core.dom.Modifier; import org.eclipse.jdt.core.dom.Name; import org.eclipse.jdt.core.dom.ParameterizedType; +import org.eclipse.jdt.core.dom.QualifiedName; import org.eclipse.jdt.core.dom.ReturnStatement; import org.eclipse.jdt.core.dom.SimpleName; import org.eclipse.jdt.core.dom.Statement; +import org.eclipse.jdt.core.dom.SuperFieldAccess; import org.eclipse.jdt.core.dom.SuperMethodInvocation; import org.eclipse.jdt.core.dom.SuperMethodReference; import org.eclipse.jdt.core.dom.TagElement; @@ -743,6 +749,108 @@ public static CompilationUnit findCUForMethod(CompilationUnit compilationUnit, I return compilationUnit; } + public static String getDeprecatedFieldReplacement(ASTNode node) { + IBinding binding= null; + switch (node) { + case QualifiedName q: + binding= q.resolveBinding(); + break; + case SimpleName s: + if (s.getLocationInParent() == QualifiedName.NAME_PROPERTY) { + node= s.getParent(); + binding= ((QualifiedName)node).resolveBinding(); + } else { + binding= s.resolveBinding(); + } + break; + case FieldAccess f: +// if (f.getExpression() instanceof MethodInvocation) { +// return null; +// } + binding= f.resolveFieldBinding(); + break; + case SuperFieldAccess sf: + binding= sf.resolveFieldBinding(); + break; + default: + return null; + } + if (binding instanceof IVariableBinding varBinding && varBinding.isField()) { + IField field= (IField)varBinding.getJavaElement(); + if (field == null) { + return null; + } + IAnnotationBinding[] annotations= varBinding.getAnnotations(); + for (IAnnotationBinding annotation : annotations) { + if (annotation.getAnnotationType().getQualifiedName().equals("java.lang.Deprecated")) { //$NON-NLS-1$ + CompilationUnit sourceCu= (CompilationUnit)node.getRoot(); + CompilationUnit cu= findCUForField(sourceCu, (ICompilationUnit)sourceCu.getJavaElement(), varBinding); + if (cu == null) { + return null; + } + try { + FieldDeclaration fieldDeclaration= ASTNodeSearchUtil.getFieldDeclarationNode(field, cu); + Javadoc javadoc= fieldDeclaration.getJavadoc(); + if (javadoc == null) { + return null; + } + List tags= javadoc.tags(); + for (TagElement tag : tags) { + if ("@deprecated".equals(tag.getTagName())) { //$NON-NLS-1$ + List fragments= tag.fragments(); + if (fragments.size() < 2) { + return null; + } + if (fragments.get(0) instanceof TextElement textElement) { + String text= textElement.getText().toLowerCase().trim(); + if (text.endsWith("use") || text.endsWith("replace by")) { //$NON-NLS-1$ //$NON-NLS-2$ + if (fragments.get(1) instanceof TagElement tagElement) { + if ("@link".equals(tagElement.getTagName())) { //$NON-NLS-1$ + List linkFragments= tagElement.fragments(); + if (linkFragments.size() == 1) { + IDocElement linkFragment= linkFragments.get(0); + if (linkFragment instanceof MemberRef methodRef) { + IBinding refBinding= methodRef.resolveBinding(); + if (refBinding instanceof IVariableBinding replaceBinding && replaceBinding.isField()) { + return replaceBinding.getDeclaringClass().getQualifiedName() + "." + replaceBinding.getName(); //$NON-NLS-1$ + } + } + } + } + } + } + } + } + } + } catch (JavaModelException e) { + // ignore + } + } + } + } + return null; + } + + public static CompilationUnit findCUForField(CompilationUnit compilationUnit, ICompilationUnit cu, IVariableBinding fieldBinding) { + ASTNode fieldDecl= compilationUnit.findDeclaringNode(fieldBinding.getVariableDeclaration()); + if (fieldDecl == null) { + // is field defined in another CU? + ITypeBinding declaringTypeDecl= fieldBinding.getDeclaringClass().getTypeDeclaration(); + if (declaringTypeDecl.isFromSource()) { + ICompilationUnit targetCU= null; + try { + targetCU= ASTResolving.findCompilationUnitForBinding(cu, compilationUnit, declaringTypeDecl); + } catch (JavaModelException e) { /* can't do better */ + } + if (targetCU != null) { + return ASTResolving.createQuickFixAST(targetCU, null); + } + } + return null; + } + return compilationUnit; + } + public static ASTNode getCopyOfInner(ASTRewrite rewrite, ASTNode statement, boolean toControlStatementBody) { if (statement.getNodeType() == ASTNode.BLOCK) { Block block= (Block) statement; diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstants.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstants.java index c26e333552b..2ecfe839255 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstants.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstants.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2023 IBM Corporation and others. + * Copyright (c) 2000, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -1301,10 +1301,21 @@ public class CleanUpConstants { * * @see CleanUpOptions#TRUE * @see CleanUpOptions#FALSE - * @since 4.30 + * @since 4.37 */ public static final String REPLACE_DEPRECATED_CALLS= "cleanup.replace_deprecated_calls"; //$NON-NLS-1$ + /** + * Replace deprecated fields with specified replacement fields if possible. + *

+ * Possible values: {TRUE, FALSE} + * + * @see CleanUpOptions#TRUE + * @see CleanUpOptions#FALSE + * @since 4.30 + */ + public static final String REPLACE_DEPRECATED_FIELDS= "cleanup.replace_deprecated_fields"; //$NON-NLS-1$ + /** * Replaces {@code String.replaceAll()} by {@code String.replace()}. *

diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.java index 4496a49ff5d..b0aea5676a6 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.java +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.java @@ -186,6 +186,7 @@ private FixMessages() { public static String StringConcatToTextBlockFix_convert_msg; public static String LambdaExpressionAndMethodRefFix_clean_up_expression_msg; public static String InlineDeprecatedMethod_msg; + public static String ReplaceDeprecatedField_msg; static { // initialize resource bundle diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.properties b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.properties index cc1d6d16824..866357c68d1 100644 --- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.properties +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/FixMessages.properties @@ -165,6 +165,7 @@ StringBufferToStringBuilderFix_convert_msg=Convert StringBuffer to StringBuilder StringConcatToTextBlockFix_convert_msg=Convert String concatenation to Text Block LambdaExpressionAndMethodRefFix_clean_up_expression_msg=Clean up lambda expression InlineDeprecatedMethod_msg=Replace with inlined method +ReplaceDeprecatedField_msg=Replace deprecated field OneIfRatherThanDuplicateBlocksThatFallThroughFix_description=Single 'if' statement rather than duplicate blocks that fall through PullOutIfFromIfElseFix_description=Pull out a duplicate 'if' from an if/else diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/ReplaceDeprecatedFieldFixCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/ReplaceDeprecatedFieldFixCore.java new file mode 100644 index 00000000000..5e0274468ed --- /dev/null +++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/ReplaceDeprecatedFieldFixCore.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * Copyright (c) 2025 Red Hat Inc. and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.corext.fix; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.jdt.core.IImportDeclaration; +import org.eclipse.jdt.core.IPackageDeclaration; +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.CompilationUnit; +import org.eclipse.jdt.core.dom.FieldAccess; +import org.eclipse.jdt.core.dom.ITypeBinding; +import org.eclipse.jdt.core.dom.IVariableBinding; +import org.eclipse.jdt.core.dom.Name; +import org.eclipse.jdt.core.dom.QualifiedName; +import org.eclipse.jdt.core.dom.SimpleName; +import org.eclipse.jdt.core.dom.SuperFieldAccess; +import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; +import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; + +import org.eclipse.jdt.internal.corext.refactoring.structure.CompilationUnitRewrite; +import org.eclipse.jdt.internal.corext.refactoring.structure.ImportRemover; + +public class ReplaceDeprecatedFieldFixCore extends CompilationUnitRewriteOperationsFixCore { + + public ReplaceDeprecatedFieldFixCore(String name, CompilationUnit compilationUnit, CompilationUnitRewriteOperation operation) { + super(name, compilationUnit, operation); + } + + public ReplaceDeprecatedFieldFixCore(String name, CompilationUnit compilationUnit, CompilationUnitRewriteOperation operations[]) { + super(name, compilationUnit, operations); + } + + public static ReplaceDeprecatedFieldFixCore create(String name, String replacement, CompilationUnit compilationUnit, ASTNode node) { + return new ReplaceDeprecatedFieldFixCore(name, compilationUnit, new ReplaceDeprecatedFieldProposalOperation(node, replacement)); + } + + public static class ReplaceDeprecatedFieldProposalOperation extends CompilationUnitRewriteOperation { + + private final ASTNode fNode; + private final String fReplacement; + + public ReplaceDeprecatedFieldProposalOperation(ASTNode node, String name) { + this.fNode= node; + this.fReplacement= name; + } + + @Override + public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModelCore linkedModel) throws CoreException { + AST ast= cuRewrite.getAST(); + ASTRewrite rewrite= cuRewrite.getASTRewrite(); + ImportRewrite importRewrite= cuRewrite.getImportRewrite(); + ImportRemover importRemover= cuRewrite.getImportRemover(); + IPackageDeclaration[] packageDecls= cuRewrite.getCu().getPackageDeclarations(); + + IVariableBinding fieldBinding= null; + switch (fNode.getNodeType()) { + case ASTNode.QUALIFIED_NAME: + fieldBinding= (IVariableBinding) ((QualifiedName)fNode).resolveBinding(); + break; + case ASTNode.SIMPLE_NAME: + fieldBinding= (IVariableBinding) ((SimpleName)fNode).resolveBinding(); + break; + case ASTNode.FIELD_ACCESS: + fieldBinding= ((FieldAccess)fNode).resolveFieldBinding(); + break; + case ASTNode.SUPER_FIELD_ACCESS: + fieldBinding= ((SuperFieldAccess)fNode).resolveFieldBinding(); + break; + default: + break; + } + + boolean sameClass= false; + boolean mustQualify= false; + int simpleNameQualifierIndex= -1; + String simpleNameQualifier= ""; //$NON-NLS-1$ + int lastDot= fReplacement.lastIndexOf('.'); + if (lastDot > 0) { + int startIndex= lastDot - 1; + while (startIndex >= 0 && Character.isJavaIdentifierPart(fReplacement.charAt(startIndex))) { + --startIndex; + } + simpleNameQualifierIndex= startIndex + 1; + simpleNameQualifier= fReplacement.substring(simpleNameQualifierIndex, lastDot); + if (fieldBinding != null) { + ITypeBinding classBinding= fieldBinding.getDeclaringClass(); + String className= classBinding.getQualifiedName(); + if (className != null && className.equals(fReplacement.substring(0, lastDot))) { + sameClass= true; + } + } + IImportDeclaration[] importDecls= cuRewrite.getCu().getImports(); + for (IImportDeclaration importDecl : importDecls) { + String elementName= importDecl.getElementName(); + if (!importDecl.isOnDemand()) { + int elementLastDot= elementName.lastIndexOf('.'); + if (elementLastDot > 0) { + String importName= elementName.substring(elementLastDot + 1); + if (importName.equals(simpleNameQualifier) && !elementName.equals(fReplacement.substring(0, lastDot)) + && !fReplacement.substring(0, lastDot).equals(packageDecls[0].getElementName())) { + mustQualify= !sameClass; + break; + } + } + } + } + } + + if (mustQualify) { + Name newName= ast.newName(fReplacement); + rewrite.replace(fNode, newName, null); + } else if (sameClass) { + class GetSimpleNameVisitor extends ASTVisitor { + private SimpleName nameToReplace= fNode instanceof SimpleName simpleName ? simpleName : null; + @Override + public boolean visit(SimpleName node) { + if (node.getLocationInParent() == FieldAccess.NAME_PROPERTY + || node.getLocationInParent() == SuperFieldAccess.NAME_PROPERTY + || node.getLocationInParent() == QualifiedName.NAME_PROPERTY) { + nameToReplace= node; + } + return true; + } + public SimpleName getNameToReplace() { + return nameToReplace; + } + } + GetSimpleNameVisitor visitor= new GetSimpleNameVisitor(); + fNode.accept(visitor); + SimpleName nameToReplace= visitor.getNameToReplace(); + SimpleName newName= ast.newSimpleName(fReplacement.substring(lastDot + 1)); + rewrite.replace(nameToReplace, newName, null); + } else { + importRewrite.addImport(fReplacement.substring(0, lastDot)); + Name newName= ast.newName(fReplacement.substring(simpleNameQualifierIndex)); + rewrite.replace(fNode, newName, null); + } + importRemover.registerRemovedNode(fNode); + } + } + +} diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d8.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d8.java index dd2f93d074e..4ee09829fd2 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d8.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest1d8.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020, 2024 IBM Corporation and others. + * Copyright (c) 2020, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -6578,6 +6578,189 @@ public static void depfunc2(String x, String y, Object z) { new HashSet<>(Arrays.asList(FixMessages.InlineDeprecatedMethod_msg))); } + @Test + public void testDeprecatedFieldCleanup1() throws Exception { + IPackageFragment pack2= fSourceFolder.createPackageFragment("test2", false, null); + String sample2= """ + package test2; + + public interface K { + String field1= "abc"; + String field2= "def"; + } + """; + ICompilationUnit cu2= pack2.createCompilationUnit("K.java", sample2, false, null); + + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample1= """ + package test1; + + import test2.K; + + public interface E1 { + + /** + * field to use + * + * @deprecated use {@link K#field2} instead + */ + @Deprecated String field= "blah"; + } + """; // + ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", sample1, false, null); + + String sample= """ + package test1; + + import test1.E1; + + public class E { + + /** + * @deprecated use {@link #localField2} instead + */ + @Deprecated + public String localField1= "abc"; + + public String localField2= "def"; + + public void foo() { + String x = E1.field; + } + + public E getThis() { + return this; + } + + public void foo2() { + String y = E1.field; + } + + public void foo3() { + String z = this.localField1; + String z2= localField1; + String z3= getThis().localField1; + } + + } + """; + ICompilationUnit cu= pack1.createCompilationUnit("E.java", sample, false, null); + enable(CleanUpConstants.REPLACE_DEPRECATED_FIELDS); + + sample= """ + package test1; + + import test2.K; + + public class E { + + /** + * @deprecated use {@link #localField2} instead + */ + @Deprecated + public String localField1= "abc"; + + public String localField2= "def"; + + public void foo() { + String x = K.field2; + } + + public E getThis() { + return this; + } + + public void foo2() { + String y = K.field2; + } + + public void foo3() { + String z = this.localField2; + String z2= localField2; + String z3= getThis().localField2; + } + + } + """; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] {cu, cu1, cu2}, new String[] {sample1, sample2, expected1}, + new HashSet<>(Arrays.asList(FixMessages.ReplaceDeprecatedField_msg))); + } + + @Test + public void testDeprecatedFieldCleanup2() throws Exception { + IPackageFragment pack2= fSourceFolder.createPackageFragment("test2", false, null); + String sample2= """ + package test2; + + public interface K { + String field1= "abc"; + String field2= "def"; + } + """; + ICompilationUnit cu2= pack2.createCompilationUnit("K.java", sample2, false, null); + + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample1= """ + package test1; + + import test2.K; + + public interface E1 { + + /** + * field to use + * + * @deprecated use {@link K#field2} instead + */ + @Deprecated String field= "blah"; + } + """; // + ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", sample1, false, null); + + String sample= """ + package test1; + + import test1.E1; + + public class E { + + private class Z implements E1 { + } + + public void foo() { + String x = new E1().field; + } + + } + """; + ICompilationUnit cu= pack1.createCompilationUnit("E.java", sample, false, null); + enable(CleanUpConstants.REPLACE_DEPRECATED_FIELDS); + + sample= """ + package test1; + + import test1.E1; + import test2.K; + + public class E { + + private class Z implements E1 { + } + + public void foo() { + String x = K.field2; + } + + } + """; + String expected1= sample; + + assertRefactoringResultAsExpected(new ICompilationUnit[] {cu, cu1, cu2}, new String[] {sample1, sample2, expected1}, + new HashSet<>(Arrays.asList(FixMessages.ReplaceDeprecatedField_msg))); + } + @Test public void testDoNotDoDeprecatedCleanup1() throws Exception { // https://github.com/eclipse-jdt/eclipse.jdt.ui/issues/722 IPackageFragment pack1= fSourceFolder.createPackageFragment("test", false, null); diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTest1d8.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTest1d8.java index b8a2bdbcfa1..c33d8438825 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTest1d8.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTest1d8.java @@ -3372,4 +3372,144 @@ public void foo(Object x, String string) { assertExpectedExistInProposals(proposals, new String[] {expected1}); } + @Test + public void testIssue2242_fixDeprecatedField1() throws Exception { + Hashtable options = JavaCore.getOptions(); + options.put(JavaCore.COMPILER_PB_DEPRECATION, CompilerOptions.WARNING); + JavaCore.setOptions(options); + IPackageFragment pack2= fSourceFolder.createPackageFragment("test2", false, null); + + String str2= """ + package test2; + + public interface K { + String field1= "abc"; + String field2= "def"; + } + """; + pack2.createCompilationUnit("K.java", str2, false, null); + + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String str1= """ + package test1; + + import test2.K; + + public interface B { + + /** + * field to use + * + * @deprecated use {@link K#field2} instead + */ + @Deprecated String field= "blah"; + } + """; + pack1.createCompilationUnit("B.java", str1, false, null); + + String str= """ + package test1; + + class E { + public void foo() { + String x = B.field; + System.out.println(x); + } + } + """; + ICompilationUnit cu= pack1.createCompilationUnit("E.java", str, false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot, 1, null); + assertCorrectLabels(proposals); + + String expected1= """ + package test1; + + import test2.K; + + class E { + public void foo() { + String x = K.field2; + System.out.println(x); + } + } + """; + + assertExpectedExistInProposals(proposals, new String[] {expected1}); + } + + @Test + public void testIssue2242_fixDeprecatedField2() throws Exception { + Hashtable options = JavaCore.getOptions(); + options.put(JavaCore.COMPILER_PB_DEPRECATION, CompilerOptions.WARNING); + JavaCore.setOptions(options); + IPackageFragment pack2= fSourceFolder.createPackageFragment("test2", false, null); + + String str2= """ + package test2; + + public interface K { + String field1= "abc"; + String field2= "def"; + } + """; + pack2.createCompilationUnit("K.java", str2, false, null); + + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String str1= """ + package test1; + + import test2.K; + + public interface B { + + /** + * field to use + * + * @deprecated use {@link K#field2} instead + */ + @Deprecated String field= "blah"; + } + """; + pack1.createCompilationUnit("B.java", str1, false, null); + + String str= """ + package test1; + + class E { + private class Z implements B { + } + + public void foo() { + String x = new Z().field; + System.out.println(x); + } + } + """; + ICompilationUnit cu= pack1.createCompilationUnit("E.java", str, false, null); + + CompilationUnit astRoot= getASTRoot(cu); + ArrayList proposals= collectCorrections(cu, astRoot, 2, null); + assertCorrectLabels(proposals); + + String expected1= """ + package test1; + + import test2.K; + + class E { + private class Z implements B { + } + + public void foo() { + String x = K.field2; + System.out.println(x); + } + } + """; + + assertExpectedExistInProposals(proposals, new String[] {expected1}); + } + } diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstantsOptions.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstantsOptions.java index a2e56ec523a..100d60565ef 100644 --- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstantsOptions.java +++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/fix/CleanUpConstantsOptions.java @@ -171,6 +171,7 @@ private static void setEclipseDefaultSettings(CleanUpOptions options) { options.setOption(STANDARD_COMPARISON, CleanUpOptions.FALSE); options.setOption(CHECK_SIGN_OF_BITWISE_OPERATION, CleanUpOptions.FALSE); options.setOption(REPLACE_DEPRECATED_CALLS, CleanUpOptions.FALSE); + options.setOption(REPLACE_DEPRECATED_FIELDS, CleanUpOptions.FALSE); // Duplicate Code options.setOption(OPERAND_FACTORIZATION, CleanUpOptions.FALSE); @@ -361,6 +362,7 @@ private static void setSaveParticipantSettings(CleanUpOptions options) { options.setOption(STANDARD_COMPARISON, CleanUpOptions.FALSE); options.setOption(CHECK_SIGN_OF_BITWISE_OPERATION, CleanUpOptions.FALSE); options.setOption(REPLACE_DEPRECATED_CALLS, CleanUpOptions.FALSE); + options.setOption(REPLACE_DEPRECATED_FIELDS, CleanUpOptions.FALSE); // Duplicate Code options.setOption(OPERAND_FACTORIZATION, CleanUpOptions.FALSE); diff --git a/org.eclipse.jdt.ui/plugin.xml b/org.eclipse.jdt.ui/plugin.xml index 8233bc86989..dbbd831f0fc 100644 --- a/org.eclipse.jdt.ui/plugin.xml +++ b/org.eclipse.jdt.ui/plugin.xml @@ -7133,11 +7133,16 @@ class="org.eclipse.jdt.internal.ui.fix.InlineDeprecatedMethodCleanUpCore" id="org.eclipse.jdt.ui.cleanup.replace_deprecated_calls" runAfter="org.eclipse.jdt.ui.cleanup.add_all"> + + + runAfter="org.eclipse.jdt.ui.cleanup.replace_deprecated_fields"> valu new InvertEqualsCleanUpCore(values), new StandardComparisonCleanUpCore(values), new BitwiseConditionalExpressionCleanup(values), - new InlineDeprecatedMethodCleanUpCore(values) + new InlineDeprecatedMethodCleanUpCore(values), + new ReplaceDeprecatedFieldCleanUpCore(values) }; } @@ -66,5 +68,8 @@ protected void doCreatePreferences(final Composite composite, final int numColum final CheckboxPreference inlineDeprecatedMethodCallPref= createCheckboxPref(deprecatedCodeGroup, numColumns, CleanUpMessages.SourceFixingTabPage_CheckboxName_ReplaceDeprecatedMethodCall, CleanUpConstants.REPLACE_DEPRECATED_CALLS, CleanUpModifyDialog.FALSE_TRUE); registerPreference(inlineDeprecatedMethodCallPref); + + final CheckboxPreference replaceDeprecatedFieldsPref= createCheckboxPref(deprecatedCodeGroup, numColumns, CleanUpMessages.SourceFixingTabPage_CheckboxName_ReplaceDeprecatedField, CleanUpConstants.REPLACE_DEPRECATED_FIELDS, CleanUpModifyDialog.FALSE_TRUE); + registerPreference(replaceDeprecatedFieldsPref); } } diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java index ecd4ffeee1e..30724aa1a0b 100644 --- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java +++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java @@ -115,6 +115,7 @@ import org.eclipse.jdt.core.dom.SingleVariableDeclaration; import org.eclipse.jdt.core.dom.Statement; import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor; +import org.eclipse.jdt.core.dom.SuperFieldAccess; import org.eclipse.jdt.core.dom.SuperMethodInvocation; import org.eclipse.jdt.core.dom.SwitchCase; import org.eclipse.jdt.core.dom.SwitchExpression; @@ -170,6 +171,7 @@ import org.eclipse.jdt.internal.corext.fix.LinkedProposalModelCore; import org.eclipse.jdt.internal.corext.fix.PatternInstanceofToSwitchFixCore; import org.eclipse.jdt.internal.corext.fix.RemoveVarOrInferredLambdaParameterTypesFixCore; +import org.eclipse.jdt.internal.corext.fix.ReplaceDeprecatedFieldFixCore; import org.eclipse.jdt.internal.corext.fix.SplitTryResourceFixCore; import org.eclipse.jdt.internal.corext.fix.SplitVariableFixCore; import org.eclipse.jdt.internal.corext.fix.StringConcatToTextBlockFixCore; @@ -347,6 +349,7 @@ public boolean hasAssists(IInvocationContext context) throws CoreException { || getSplitSwitchLabelProposal(context, coveringNode, null) || getSplitTryResourceProposal(context, coveringNode, null) || getConvertPatternInstanceofIfStmtToSwitchProposals(context, coveringNode, null) + || getDeprecatedFieldProposal(context, coveringNode, null, null) || getDeprecatedProposal(context, coveringNode, null, null); } return false; @@ -374,6 +377,7 @@ public IJavaCompletionProposal[] getAssists(IInvocationContext context, IProblem getSplitSwitchLabelProposal(context, coveringNode, resultingCollections); getAddMethodDeclaration(context, coveringNode, resultingCollections); getDeprecatedProposal(context, coveringNode, locations, resultingCollections); + getDeprecatedFieldProposal(context, coveringNode, locations, resultingCollections); if (noErrorsAtLocation) { boolean problemsAtLocation= locations.length != 0; @@ -727,6 +731,38 @@ private static boolean getDeprecatedProposal(IInvocationContext context, ASTNode return true; } + private static boolean getDeprecatedFieldProposal(IInvocationContext context, ASTNode node, IProblemLocation[] locations, Collection proposals) { + // don't add if already added as quick fix + if (containsMatchingProblem(locations, IProblem.UsingDeprecatedField)) + return false; + + if (node != null && !(node instanceof QualifiedName) + && !(node instanceof FieldAccess) + && !(node instanceof SuperFieldAccess)) { + ASTNode originalNode= node; + node= ASTNodes.getFirstAncestorOrNull(node, QualifiedName.class, + FieldAccess.class, SuperFieldAccess.class); + if (node == null && originalNode instanceof SimpleName) { + node= originalNode; + } + } + if (node != null) { + String replacement= QuickAssistProcessorUtil.getDeprecatedFieldReplacement(node); + if (replacement != null) { + if (proposals != null) { + IProposableFix fix= ReplaceDeprecatedFieldFixCore.create(FixMessages.ReplaceDeprecatedField_msg, + replacement, (CompilationUnit)node.getRoot(), node); + if (fix != null) { + Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); + proposals.add(new FixCorrectionProposal(fix, null, IProposalRelevance.REPLACE_DEPRECATED_FIELD, image, context)); + } + } + return true; + } + } + return false; + } + private static boolean getConvertAnonymousToNestedProposal(IInvocationContext context, final ASTNode node, Collection proposals) throws CoreException { if (!(node instanceof Name)) return false; diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickFixProcessor.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickFixProcessor.java index 77969a0505b..73f4ec8c573 100644 --- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickFixProcessor.java +++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickFixProcessor.java @@ -24,6 +24,8 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; +import java.util.Hashtable; +import java.util.Map; import org.eclipse.swt.graphics.Image; @@ -37,19 +39,26 @@ import org.eclipse.jdt.core.compiler.IProblem; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.FieldAccess; import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.MemberValuePair; import org.eclipse.jdt.core.dom.MethodInvocation; import org.eclipse.jdt.core.dom.Name; import org.eclipse.jdt.core.dom.QualifiedName; +import org.eclipse.jdt.core.dom.SimpleName; import org.eclipse.jdt.core.dom.SingleMemberAnnotation; +import org.eclipse.jdt.core.dom.SuperFieldAccess; +import org.eclipse.jdt.internal.corext.dom.ASTNodes; import org.eclipse.jdt.internal.corext.dom.Bindings; +import org.eclipse.jdt.internal.corext.fix.CleanUpConstants; import org.eclipse.jdt.internal.corext.fix.FixMessages; import org.eclipse.jdt.internal.corext.fix.IProposableFix; import org.eclipse.jdt.internal.corext.fix.InlineMethodFixCore; import org.eclipse.jdt.internal.corext.fix.NullAnnotationsRewriteOperations.ChangeKind; +import org.eclipse.jdt.internal.corext.fix.ReplaceDeprecatedFieldFixCore; +import org.eclipse.jdt.ui.cleanup.CleanUpOptions; import org.eclipse.jdt.ui.text.java.IInvocationContext; import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal; import org.eclipse.jdt.ui.text.java.IProblemLocation; @@ -57,6 +66,7 @@ import org.eclipse.jdt.ui.text.java.correction.ICommandAccess; import org.eclipse.jdt.internal.ui.JavaPluginImages; +import org.eclipse.jdt.internal.ui.fix.ReplaceDeprecatedFieldCleanUpCore; import org.eclipse.jdt.internal.ui.text.correction.proposals.FixCorrectionProposal; import org.eclipse.jdt.internal.ui.text.correction.proposals.ReplaceCorrectionProposal; import org.eclipse.jdt.internal.ui.text.correction.proposals.TaskMarkerProposal; @@ -233,6 +243,7 @@ public boolean hasCorrections(ICompilationUnit cu, int problemId) { case IProblem.MethodMissingDeprecatedAnnotation: case IProblem.TypeMissingDeprecatedAnnotation: case IProblem.UsingDeprecatedMethod: + case IProblem.UsingDeprecatedField: case IProblem.MissingOverrideAnnotation: case IProblem.MissingOverrideAnnotationForInterfaceMethodImplementation: case IProblem.MethodMustOverride: @@ -740,6 +751,32 @@ private void process(IInvocationContext context, IProblemLocation problem, Colle } } break; + case IProblem.UsingDeprecatedField: + ASTNode deprecatedFieldNode= context.getCoveredNode(); + if (deprecatedFieldNode != null && !(deprecatedFieldNode instanceof QualifiedName) + && !(deprecatedFieldNode instanceof FieldAccess) + && !(deprecatedFieldNode instanceof SuperFieldAccess)) { + ASTNode originalNode= deprecatedFieldNode; + deprecatedFieldNode= ASTNodes.getFirstAncestorOrNull(deprecatedFieldNode, QualifiedName.class, + FieldAccess.class, SuperFieldAccess.class); + if (deprecatedFieldNode == null && originalNode instanceof SimpleName) { + deprecatedFieldNode= originalNode; + } + } + if (deprecatedFieldNode != null) { + String replacement= QuickAssistProcessorUtil.getDeprecatedFieldReplacement(deprecatedFieldNode); + if (replacement != null) { + IProposableFix fix= ReplaceDeprecatedFieldFixCore.create(FixMessages.ReplaceDeprecatedField_msg, + replacement, (CompilationUnit)deprecatedFieldNode.getRoot(), deprecatedFieldNode); + if (fix != null) { + Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); + Map options= new Hashtable<>(); + options.put(CleanUpConstants.REPLACE_DEPRECATED_FIELDS, CleanUpOptions.TRUE); + proposals.add(new FixCorrectionProposal(fix, new ReplaceDeprecatedFieldCleanUpCore(options), IProposalRelevance.REPLACE_DEPRECATED_FIELD, image, context)); + } + } + } + break; case IProblem.IsClassPathCorrect: case IProblem.IsClassPathCorrectWithReferencingType: ReorgCorrectionsSubProcessor.getIncorrectBuildPathProposals(context, problem, proposals);