Bug 576431 - Refactor SurroundWithTryWithResouresRefactoring
- create new SurroundWithTryWithResourcesRefactoringCore and
have SurroundWithTryWithResourcesRefactoring extend it
- move AbstractExceptionAnalyzer, ExceptionAnalyzer, and
SurroundWithTryWithResourcesAnalyzer to jdt.core.manipulation
- move a number of static methods from QuickAssistProcessor to
new QuickAssistProcessorUtil class in jdt.core.manipulation and
modify users appropriately
- add a new package org.eclipse.jdt.internal.corext.refactoring.surround
to jdt.core.manipulation and expose it in MANIFEST.MF
- fix TestWithThrows3.java expected output and add
SurroundWithResourcesTests1d8 to AllTests
- add TestTry1 and TestTry2 tests
Change-Id: I244b7d7802bf1b751f7ca507107b08335810347f
Reviewed-on: https://git.eclipse.org/r/c/jdt/eclipse.jdt.ui/+/186117
Tested-by: JDT Bot <jdt-bot@eclipse.org>
Tested-by: Jeff Johnston <jjohnstn@redhat.com>
Reviewed-by: Jeff Johnston <jjohnstn@redhat.com>
diff --git a/org.eclipse.jdt.core.manipulation/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.manipulation/META-INF/MANIFEST.MF
index 3323eec..bf430e7 100644
--- a/org.eclipse.jdt.core.manipulation/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core.manipulation/META-INF/MANIFEST.MF
@@ -45,6 +45,7 @@
org.eclipse.jdt.internal.corext.refactoring.rename;x-friends:="org.eclipse.jdt.ui",
org.eclipse.jdt.internal.corext.refactoring.reorg;x-friends:="org.eclipse.jdt.ui",
org.eclipse.jdt.internal.corext.refactoring.structure;x-friends:="org.eclipse.jdt.ui",
+ org.eclipse.jdt.internal.corext.refactoring.surround;x-friends:="org.eclipse.jdt.ui",
org.eclipse.jdt.internal.corext.refactoring.tagging;x-friends:="org.eclipse.jdt.ui",
org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types;manipulation=split;mandatory:=manipulation;x-friends:="org.eclipse.jdt.ui",
org.eclipse.jdt.internal.corext.refactoring.util;manipulation=split;mandatory:=manipulation;x-friends:="org.eclipse.jdt.ui",
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
new file mode 100644
index 0000000..c54919f
--- /dev/null
+++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessorUtil.java
@@ -0,0 +1,388 @@
+/*******************************************************************************
+ * Copyright (c) 2021 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ * Red Hat Inc. - moved static methods from QuickAssistProcessor to here
+ *******************************************************************************/
+package org.eclipse.jdt.internal.ui.text.correction;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.jface.text.link.LinkedPositionGroup;
+
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ArrayCreation;
+import org.eclipse.jdt.core.dom.ArrayType;
+import org.eclipse.jdt.core.dom.Block;
+import org.eclipse.jdt.core.dom.ClassInstanceCreation;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.CreationReference;
+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.IBinding;
+import org.eclipse.jdt.core.dom.IMethodBinding;
+import org.eclipse.jdt.core.dom.ITypeBinding;
+import org.eclipse.jdt.core.dom.LambdaExpression;
+import org.eclipse.jdt.core.dom.MethodInvocation;
+import org.eclipse.jdt.core.dom.MethodReference;
+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.ReturnStatement;
+import org.eclipse.jdt.core.dom.SimpleName;
+import org.eclipse.jdt.core.dom.Statement;
+import org.eclipse.jdt.core.dom.SuperMethodInvocation;
+import org.eclipse.jdt.core.dom.SuperMethodReference;
+import org.eclipse.jdt.core.dom.ThisExpression;
+import org.eclipse.jdt.core.dom.Type;
+import org.eclipse.jdt.core.dom.TypeMethodReference;
+import org.eclipse.jdt.core.dom.VariableDeclaration;
+import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
+
+import org.eclipse.jdt.internal.core.manipulation.StubUtility;
+import org.eclipse.jdt.internal.corext.dom.ASTNodes;
+import org.eclipse.jdt.internal.corext.dom.Bindings;
+import org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer;
+import org.eclipse.jdt.internal.corext.fix.LinkedProposalModelCore;
+
+public class QuickAssistProcessorUtil {
+
+ /**
+ * Returns the functional interface method being implemented by the given method reference.
+ *
+ * @param methodReference the method reference to get the functional method
+ * @return the functional interface method being implemented by <code>methodReference</code> or
+ * <code>null</code> if it could not be derived
+ */
+ public static IMethodBinding getFunctionalMethodForMethodReference(MethodReference methodReference) {
+ ITypeBinding targetTypeBinding= ASTNodes.getTargetType(methodReference);
+ if (targetTypeBinding == null)
+ return null;
+
+ IMethodBinding functionalMethod= targetTypeBinding.getFunctionalInterfaceMethod();
+ if (functionalMethod != null && functionalMethod.isSynthetic()) {
+ functionalMethod= Bindings.findOverriddenMethodInType(functionalMethod.getDeclaringClass(), functionalMethod);
+ }
+ return functionalMethod;
+ }
+
+ /**
+ * Converts and replaces the given method reference with corresponding lambda expression in the
+ * given ASTRewrite.
+ *
+ * @param methodReference the method reference to convert
+ * @param functionalMethod the non-generic functional interface method to be implemented by the
+ * lambda expression
+ * @param astRoot the AST root
+ * @param rewrite the ASTRewrite
+ * @param linkedProposalModel to create linked proposals for lambda's parameters or
+ * <code>null</code> if linked proposals are not required
+ * @param createBlockBody <code>true</code> if lambda expression's body should be a block
+ *
+ * @return lambda expression used to replace the method reference in the given ASTRewrite
+ * @throws JavaModelException if an exception occurs while accessing the Java element
+ * corresponding to the <code>functionalMethod</code>
+ */
+ public static LambdaExpression convertMethodRefernceToLambda(MethodReference methodReference, IMethodBinding functionalMethod, CompilationUnit astRoot,
+ ASTRewrite rewrite, LinkedProposalModelCore linkedProposalModel, boolean createBlockBody) throws JavaModelException {
+
+ AST ast= astRoot.getAST();
+ LambdaExpression lambda= ast.newLambdaExpression();
+
+ String[] lambdaParamNames= QuickAssistProcessorUtil.getUniqueParameterNames(methodReference, functionalMethod);
+ List<VariableDeclaration> lambdaParameters= lambda.parameters();
+ for (int i= 0; i < lambdaParamNames.length; i++) {
+ String paramName= lambdaParamNames[i];
+ VariableDeclarationFragment lambdaParameter= ast.newVariableDeclarationFragment();
+ SimpleName name= ast.newSimpleName(paramName);
+ lambdaParameter.setName(name);
+ lambdaParameters.add(lambdaParameter);
+ if (linkedProposalModel != null) {
+ linkedProposalModel.getPositionGroup(name.getIdentifier(), true).addPosition(rewrite.track(name), i == 0);
+ }
+ }
+
+ int noOfLambdaParameters= lambdaParamNames.length;
+ lambda.setParentheses(noOfLambdaParameters != 1);
+
+ ITypeBinding returnTypeBinding= functionalMethod.getReturnType();
+ IMethodBinding referredMethodBinding= methodReference.resolveMethodBinding(); // too often null, see bug 440000, bug 440344, bug 333665
+
+ if (methodReference instanceof CreationReference) {
+ CreationReference creationRef= (CreationReference) methodReference;
+ Type type= creationRef.getType();
+ if (type instanceof ArrayType) {
+ ArrayCreation arrayCreation= ast.newArrayCreation();
+ if (createBlockBody) {
+ Block blockBody= QuickAssistProcessorUtil.getBlockBodyForLambda(arrayCreation, returnTypeBinding, ast);
+ lambda.setBody(blockBody);
+ } else {
+ lambda.setBody(arrayCreation);
+ }
+
+ ArrayType arrayType= (ArrayType) type;
+ Type copiedElementType= (Type) rewrite.createCopyTarget(arrayType.getElementType());
+ arrayCreation.setType(ast.newArrayType(copiedElementType, arrayType.getDimensions()));
+ SimpleName name= ast.newSimpleName(lambdaParamNames[0]);
+ arrayCreation.dimensions().add(name);
+ if (linkedProposalModel != null) {
+ linkedProposalModel.getPositionGroup(name.getIdentifier(), false).addPosition(rewrite.track(name), LinkedPositionGroup.NO_STOP);
+ }
+ } else {
+ ClassInstanceCreation cic= ast.newClassInstanceCreation();
+ if (createBlockBody) {
+ Block blockBody= QuickAssistProcessorUtil.getBlockBodyForLambda(cic, returnTypeBinding, ast);
+ lambda.setBody(blockBody);
+ } else {
+ lambda.setBody(cic);
+ }
+
+ ITypeBinding typeBinding= type.resolveBinding();
+ if (!(type instanceof ParameterizedType) && typeBinding != null && typeBinding.getTypeDeclaration().isGenericType()) {
+ cic.setType(ast.newParameterizedType((Type) rewrite.createCopyTarget(type)));
+ } else {
+ cic.setType((Type) rewrite.createCopyTarget(type));
+ }
+ List<SimpleName> invocationArgs= QuickAssistProcessorUtil.getInvocationArguments(ast, 0, noOfLambdaParameters, lambdaParamNames);
+ cic.arguments().addAll(invocationArgs);
+ if (linkedProposalModel != null) {
+ for (SimpleName name : invocationArgs) {
+ linkedProposalModel.getPositionGroup(name.getIdentifier(), false).addPosition(rewrite.track(name), LinkedPositionGroup.NO_STOP);
+ }
+ }
+ cic.typeArguments().addAll(QuickAssistProcessorUtil.getCopiedTypeArguments(rewrite, methodReference.typeArguments()));
+ }
+
+ } else if (referredMethodBinding != null && Modifier.isStatic(referredMethodBinding.getModifiers())) {
+ MethodInvocation methodInvocation= ast.newMethodInvocation();
+ if (createBlockBody) {
+ Block blockBody= QuickAssistProcessorUtil.getBlockBodyForLambda(methodInvocation, returnTypeBinding, ast);
+ lambda.setBody(blockBody);
+ } else {
+ lambda.setBody(methodInvocation);
+ }
+
+ Expression expr= null;
+ boolean hasConflict= QuickAssistProcessorUtil.hasConflict(methodReference.getStartPosition(), referredMethodBinding, ScopeAnalyzer.METHODS | ScopeAnalyzer.CHECK_VISIBILITY, astRoot);
+ if (hasConflict || !Bindings.isSuperType(referredMethodBinding.getDeclaringClass(), ASTNodes.getEnclosingType(methodReference)) || methodReference.typeArguments().size() != 0) {
+ if (methodReference instanceof ExpressionMethodReference) {
+ ExpressionMethodReference expressionMethodReference= (ExpressionMethodReference) methodReference;
+ expr= (Expression) rewrite.createCopyTarget(expressionMethodReference.getExpression());
+ } else if (methodReference instanceof TypeMethodReference) {
+ Type type= ((TypeMethodReference) methodReference).getType();
+ ITypeBinding typeBinding= type.resolveBinding();
+ if (typeBinding != null) {
+ ImportRewrite importRewrite= StubUtility.createImportRewrite(astRoot, true);
+ expr= ast.newName(importRewrite.addImport(typeBinding));
+ }
+ }
+ }
+ methodInvocation.setExpression(expr);
+ SimpleName methodName= QuickAssistProcessorUtil.getMethodInvocationName(methodReference);
+ methodInvocation.setName((SimpleName) rewrite.createCopyTarget(methodName));
+ List<SimpleName> invocationArgs= QuickAssistProcessorUtil.getInvocationArguments(ast, 0, noOfLambdaParameters, lambdaParamNames);
+ methodInvocation.arguments().addAll(invocationArgs);
+ if (linkedProposalModel != null) {
+ for (SimpleName name : invocationArgs) {
+ linkedProposalModel.getPositionGroup(name.getIdentifier(), false).addPosition(rewrite.track(name), LinkedPositionGroup.NO_STOP);
+ }
+ }
+ methodInvocation.typeArguments().addAll(QuickAssistProcessorUtil.getCopiedTypeArguments(rewrite, methodReference.typeArguments()));
+
+ } else if (methodReference instanceof SuperMethodReference) {
+ SuperMethodInvocation superMethodInvocation= ast.newSuperMethodInvocation();
+ if (createBlockBody) {
+ Block blockBody= QuickAssistProcessorUtil.getBlockBodyForLambda(superMethodInvocation, returnTypeBinding, ast);
+ lambda.setBody(blockBody);
+ } else {
+ lambda.setBody(superMethodInvocation);
+ }
+
+ Name superQualifier= ((SuperMethodReference) methodReference).getQualifier();
+ if (superQualifier != null) {
+ superMethodInvocation.setQualifier((Name) rewrite.createCopyTarget(superQualifier));
+ }
+ SimpleName methodName= QuickAssistProcessorUtil.getMethodInvocationName(methodReference);
+ superMethodInvocation.setName((SimpleName) rewrite.createCopyTarget(methodName));
+ List<SimpleName> invocationArgs= QuickAssistProcessorUtil.getInvocationArguments(ast, 0, noOfLambdaParameters, lambdaParamNames);
+ superMethodInvocation.arguments().addAll(invocationArgs);
+ if (linkedProposalModel != null) {
+ for (SimpleName name : invocationArgs) {
+ linkedProposalModel.getPositionGroup(name.getIdentifier(), false).addPosition(rewrite.track(name), LinkedPositionGroup.NO_STOP);
+ }
+ }
+ superMethodInvocation.typeArguments().addAll(QuickAssistProcessorUtil.getCopiedTypeArguments(rewrite, methodReference.typeArguments()));
+
+ } else {
+ MethodInvocation methodInvocation= ast.newMethodInvocation();
+ if (createBlockBody) {
+ Block blockBody= QuickAssistProcessorUtil.getBlockBodyForLambda(methodInvocation, returnTypeBinding, ast);
+ lambda.setBody(blockBody);
+ } else {
+ lambda.setBody(methodInvocation);
+ }
+
+ boolean isTypeReference= QuickAssistProcessorUtil.isTypeReferenceToInstanceMethod(methodReference);
+ if (isTypeReference) {
+ SimpleName name= ast.newSimpleName(lambdaParamNames[0]);
+ methodInvocation.setExpression(name);
+ if (linkedProposalModel != null) {
+ linkedProposalModel.getPositionGroup(name.getIdentifier(), false).addPosition(rewrite.track(name), LinkedPositionGroup.NO_STOP);
+ }
+ } else {
+ Expression expr= ((ExpressionMethodReference) methodReference).getExpression();
+ if (!(expr instanceof ThisExpression) || (methodReference.typeArguments().size() != 0)) {
+ methodInvocation.setExpression((Expression) rewrite.createCopyTarget(expr));
+ }
+ }
+ SimpleName methodName= QuickAssistProcessorUtil.getMethodInvocationName(methodReference);
+ methodInvocation.setName((SimpleName) rewrite.createCopyTarget(methodName));
+ List<SimpleName> invocationArgs= QuickAssistProcessorUtil.getInvocationArguments(ast, isTypeReference ? 1 : 0, noOfLambdaParameters, lambdaParamNames);
+ methodInvocation.arguments().addAll(invocationArgs);
+ if (linkedProposalModel != null) {
+ for (SimpleName name : invocationArgs) {
+ linkedProposalModel.getPositionGroup(name.getIdentifier(), false).addPosition(rewrite.track(name), LinkedPositionGroup.NO_STOP);
+ }
+ }
+ methodInvocation.typeArguments().addAll(QuickAssistProcessorUtil.getCopiedTypeArguments(rewrite, methodReference.typeArguments()));
+ }
+
+ rewrite.replace(methodReference, lambda, null);
+ return lambda;
+ }
+
+ public static Block getBlockBodyForLambda(Expression bodyExpr, ITypeBinding returnTypeBinding, AST ast) {
+ Statement statementInBlockBody;
+ if (ast.resolveWellKnownType("void").isEqualTo(returnTypeBinding)) { //$NON-NLS-1$
+ ExpressionStatement expressionStatement= ast.newExpressionStatement(bodyExpr);
+ statementInBlockBody= expressionStatement;
+ } else {
+ ReturnStatement returnStatement= ast.newReturnStatement();
+ returnStatement.setExpression(bodyExpr);
+ statementInBlockBody= returnStatement;
+ }
+ Block blockBody= ast.newBlock();
+ blockBody.statements().add(statementInBlockBody);
+ return blockBody;
+ }
+
+ public static List<Type> getCopiedTypeArguments(ASTRewrite rewrite, List<Type> typeArguments) {
+ List<Type> copiedTypeArgs= new ArrayList<>();
+ for (Type typeArg : typeArguments) {
+ copiedTypeArgs.add((Type) rewrite.createCopyTarget(typeArg));
+ }
+ return copiedTypeArgs;
+ }
+
+ private static SimpleName getMethodInvocationName(MethodReference methodReference) {
+ SimpleName name= null;
+ if (methodReference instanceof ExpressionMethodReference) {
+ name= ((ExpressionMethodReference) methodReference).getName();
+ } else if (methodReference instanceof TypeMethodReference) {
+ name= ((TypeMethodReference) methodReference).getName();
+ } else if (methodReference instanceof SuperMethodReference) {
+ name= ((SuperMethodReference) methodReference).getName();
+ }
+ return name;
+ }
+
+ public static String[] getUniqueParameterNames(MethodReference methodReference, IMethodBinding functionalMethod) throws JavaModelException {
+ String[] originalParameterNames= ((IMethod) functionalMethod.getJavaElement()).getParameterNames();
+ String[] newNames= new String[originalParameterNames.length];
+ Set<String> excludedNames= new HashSet<>(ASTNodes.getVisibleLocalVariablesInScope(methodReference));
+
+ for (int i= 0; i < originalParameterNames.length; i++) {
+ String paramName= originalParameterNames[i];
+
+ if (excludedNames.contains(paramName)) {
+ Set<String> allNamesToExclude= new HashSet<>(excludedNames);
+ Collections.addAll(allNamesToExclude, originalParameterNames);
+
+ String newParamName= QuickAssistProcessorUtil.createName(paramName, allNamesToExclude);
+
+ excludedNames.add(newParamName);
+ newNames[i]= newParamName;
+ } else {
+ newNames[i]= paramName;
+ }
+ }
+
+ return newNames;
+ }
+
+ private static String createName(final String nameRoot, final Set<String> excludedNames) {
+ int i= 1;
+ String candidate;
+
+ do {
+ candidate= nameRoot + i++;
+ } while (excludedNames.remove(candidate));
+
+ return candidate;
+ }
+
+ private static List<SimpleName> getInvocationArguments(AST ast, int begIndex, int noOfLambdaParameters, String[] lambdaParamNames) {
+ List<SimpleName> args= new ArrayList<>();
+ for (int i= begIndex; i < noOfLambdaParameters; i++) {
+ args.add(ast.newSimpleName(lambdaParamNames[i]));
+ }
+ return args;
+ }
+
+ private static boolean hasConflict(int startPosition, IMethodBinding referredMethodBinding, int flags, CompilationUnit cu) {
+ ScopeAnalyzer analyzer= new ScopeAnalyzer(cu);
+ for (IBinding decl : analyzer.getDeclarationsInScope(startPosition, flags)) {
+ if (decl.getName().equals(referredMethodBinding.getName()) && !referredMethodBinding.getMethodDeclaration().isEqualTo(decl))
+ return true;
+ }
+ return false;
+ }
+
+ public static boolean isTypeReferenceToInstanceMethod(MethodReference methodReference) {
+ if (methodReference instanceof TypeMethodReference)
+ return true;
+ if (methodReference instanceof ExpressionMethodReference) {
+ Expression expression= ((ExpressionMethodReference) methodReference).getExpression();
+ if (expression instanceof Name) {
+ IBinding nameBinding= ((Name) expression).resolveBinding();
+ if (nameBinding instanceof ITypeBinding) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Changes the expression body of the given lambda expression to block form.
+ * {@link LambdaExpression#resolveMethodBinding()} should not be <code>null</code> for the given
+ * lambda expression.
+ *
+ * @param lambda the lambda expression to convert the body form
+ * @param ast the AST to create new nodes
+ * @param rewrite the ASTRewrite
+ */
+ public static void changeLambdaBodyToBlock(LambdaExpression lambda, AST ast, ASTRewrite rewrite) {
+ Expression bodyExpr= (Expression) rewrite.createMoveTarget(lambda.getBody());
+ Block blockBody= getBlockBodyForLambda(bodyExpr, lambda.resolveMethodBinding().getReturnType(), ast);
+ rewrite.set(lambda, LambdaExpression.BODY_PROPERTY, blockBody, null);
+ }
+
+}
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/ExceptionAnalyzer.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/surround/ExceptionAnalyzer.java
similarity index 96%
rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/ExceptionAnalyzer.java
rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/surround/ExceptionAnalyzer.java
index 90c0e93..10b5a43 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/ExceptionAnalyzer.java
+++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/surround/ExceptionAnalyzer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2021 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -10,6 +10,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Red Hat Inc. - refactored to jdt.core.manipulation
*******************************************************************************/
package org.eclipse.jdt.internal.corext.refactoring.surround;
@@ -43,8 +44,11 @@
import org.eclipse.jdt.internal.corext.dom.Selection;
import org.eclipse.jdt.internal.corext.refactoring.util.AbstractExceptionAnalyzer;
-import org.eclipse.jdt.internal.ui.text.correction.QuickAssistProcessor;
+import org.eclipse.jdt.internal.ui.text.correction.QuickAssistProcessorUtil;
+/**
+ * @since 1.16
+ */
public class ExceptionAnalyzer extends AbstractExceptionAnalyzer {
private Selection fSelection;
@@ -207,7 +211,7 @@
IMethodBinding referredMethodBinding= node.resolveMethodBinding();
if (referredMethodBinding == null)
return false;
- IMethodBinding functionalMethod= QuickAssistProcessor.getFunctionalMethodForMethodReference(node);
+ IMethodBinding functionalMethod= QuickAssistProcessorUtil.getFunctionalMethodForMethodReference(node);
if (functionalMethod == null || functionalMethod.isGenericMethod()) { // generic lambda expressions are not allowed
return false;
}
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesAnalyzer.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesAnalyzer.java
similarity index 100%
rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesAnalyzer.java
rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesAnalyzer.java
diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesRefactoringCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesRefactoringCore.java
new file mode 100644
index 0000000..1869228
--- /dev/null
+++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesRefactoringCore.java
@@ -0,0 +1,697 @@
+/*******************************************************************************
+ * Copyright (c) 2021 IBM Corporation 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 code based on SurroundWithTryCatchRefactoring
+ *******************************************************************************/
+package org.eclipse.jdt.internal.corext.refactoring.surround;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+
+import org.eclipse.text.edits.MultiTextEdit;
+import org.eclipse.text.edits.TextEdit;
+import org.eclipse.text.edits.TextEditGroup;
+
+import org.eclipse.ltk.core.refactoring.Change;
+import org.eclipse.ltk.core.refactoring.Refactoring;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.ltk.core.refactoring.TextFileChange;
+
+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.ASTVisitor;
+import org.eclipse.jdt.core.dom.Assignment;
+import org.eclipse.jdt.core.dom.Block;
+import org.eclipse.jdt.core.dom.CatchClause;
+import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.Expression;
+import org.eclipse.jdt.core.dom.ExpressionStatement;
+import org.eclipse.jdt.core.dom.IExtendedModifier;
+import org.eclipse.jdt.core.dom.IMethodBinding;
+import org.eclipse.jdt.core.dom.ITypeBinding;
+import org.eclipse.jdt.core.dom.IVariableBinding;
+import org.eclipse.jdt.core.dom.LambdaExpression;
+import org.eclipse.jdt.core.dom.MethodReference;
+import org.eclipse.jdt.core.dom.Modifier;
+import org.eclipse.jdt.core.dom.SimpleName;
+import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
+import org.eclipse.jdt.core.dom.Statement;
+import org.eclipse.jdt.core.dom.ThrowStatement;
+import org.eclipse.jdt.core.dom.TryStatement;
+import org.eclipse.jdt.core.dom.Type;
+import org.eclipse.jdt.core.dom.UnionType;
+import org.eclipse.jdt.core.dom.VariableDeclaration;
+import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
+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.ImportRewrite;
+import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext;
+import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.TypeLocation;
+import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
+import org.eclipse.jdt.core.refactoring.CompilationUnitChange;
+
+import org.eclipse.jdt.internal.core.manipulation.StubUtility;
+import org.eclipse.jdt.internal.core.manipulation.dom.ASTResolving;
+import org.eclipse.jdt.internal.core.manipulation.util.Strings;
+import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext;
+import org.eclipse.jdt.internal.corext.dom.ASTNodes;
+import org.eclipse.jdt.internal.corext.dom.CodeScopeBuilder;
+import org.eclipse.jdt.internal.corext.dom.IASTSharedValues;
+import org.eclipse.jdt.internal.corext.dom.LinkedNodeFinder;
+import org.eclipse.jdt.internal.corext.dom.Selection;
+import org.eclipse.jdt.internal.corext.fix.LinkedProposalModelCore;
+import org.eclipse.jdt.internal.corext.refactoring.Checks;
+import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
+import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
+import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil;
+
+import org.eclipse.jdt.internal.ui.text.correction.QuickAssistProcessorUtil;
+
+/**
+ * Surround a set of statements with a try-with-resources block.
+ *
+ * Special case:
+ *
+ * URL url= file.toURL();
+ *
+ * In this case the variable declaration statement gets convert into a
+ * declaration without initializer. So the body of the try/catch block
+ * only consists of new assignments. In this case we can't move the
+ * selected nodes (e.g. the declaration) into the try block.
+ */
+public class SurroundWithTryWithResourcesRefactoringCore extends Refactoring {
+
+ public final String GROUP_EXC_TYPE= "exc_type"; //$NON-NLS-1$
+ public final String GROUP_EXC_NAME= "exc_name"; //$NON-NLS-1$
+ public final String GROUP_TRY_STATEMENT= "try_stmt"; //$NON-NLS-1$
+
+ private Selection fSelection;
+ private SurroundWithTryWithResourcesAnalyzer fAnalyzer;
+ private boolean fLeaveDirty;
+
+ private ICompilationUnit fCUnit;
+ private CompilationUnit fRootNode;
+ private ASTRewrite fRewriter;
+ private ImportRewrite fImportRewrite;
+ private CodeScopeBuilder.Scope fScope;
+ private ASTNode[] fSelectedNodes;
+ private List<ASTNode> fAutoClosableNodes;
+
+ private LinkedProposalModelCore fLinkedProposalModel;
+
+ protected SurroundWithTryWithResourcesRefactoringCore(ICompilationUnit cu, Selection selection) {
+ fCUnit= cu;
+ fSelection= selection;
+ fLeaveDirty= false;
+ }
+
+ public static SurroundWithTryWithResourcesRefactoringCore create(ICompilationUnit cu, int offset, int length) {
+ return new SurroundWithTryWithResourcesRefactoringCore(cu, Selection.createFromStartLength(offset, length));
+ }
+
+ public static SurroundWithTryWithResourcesRefactoringCore create(ICompilationUnit cu, Selection selection) {
+ return new SurroundWithTryWithResourcesRefactoringCore(cu, selection);
+ }
+
+ public LinkedProposalModelCore getLinkedProposalModelCore() {
+ return fLinkedProposalModel;
+ }
+
+ public void setLeaveDirty(boolean leaveDirty) {
+ fLeaveDirty= leaveDirty;
+ }
+
+ public boolean stopExecution() {
+ if (fAnalyzer == null)
+ return true;
+ ITypeBinding[] exceptions= fAnalyzer.getExceptions(fAnalyzer.getSelection());
+ List<ASTNode> autoClosableNodes= fAnalyzer.getCoveredAutoClosableNodes();
+ return (exceptions == null || exceptions.length == 0) && (autoClosableNodes == null || autoClosableNodes.isEmpty());
+ }
+
+ /* non Java-doc
+ * @see IRefactoring#getName()
+ */
+ @Override
+ public String getName() {
+ return RefactoringCoreMessages.SurroundWithTryWithResourcesRefactoring_name;
+ }
+
+ public RefactoringStatus checkActivationBasics(CompilationUnit rootNode) throws CoreException {
+ RefactoringStatus result= new RefactoringStatus();
+ fRootNode= rootNode;
+
+ fAnalyzer= new SurroundWithTryWithResourcesAnalyzer(fCUnit, fSelection);
+ fRootNode.accept(fAnalyzer);
+ result.merge(fAnalyzer.getStatus());
+ fAutoClosableNodes= fAnalyzer.getCoveredAutoClosableNodes();
+ if (fAutoClosableNodes == null || fAutoClosableNodes.isEmpty()) {
+ result.merge(RefactoringStatus.createWarningStatus(RefactoringCoreMessages.SurroundWithTryWithResourcesRefactoring_notAutoclosable));
+ }
+ return result;
+ }
+
+
+ /*
+ * @see Refactoring#checkActivation(IProgressMonitor)
+ */
+ @Override
+ public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException {
+ CompilationUnit rootNode= new RefactoringASTParser(IASTSharedValues.SHARED_AST_LEVEL).parse(fCUnit, true, pm);
+ return checkActivationBasics(rootNode);
+ }
+
+ /*
+ * @see Refactoring#checkInput(IProgressMonitor)
+ */
+ @Override
+ public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException {
+ return Checks.validateModifiesFiles(
+ ResourceUtil.getFiles(new ICompilationUnit[]{fCUnit}),
+ getValidationContext(), pm);
+ }
+
+ protected LinkedProposalModelCore createLinkedProposalModel() {
+ return new LinkedProposalModelCore();
+ }
+
+ /* non Java-doc
+ * @see IRefactoring#createChange(IProgressMonitor)
+ */
+ @Override
+ public Change createChange(IProgressMonitor pm) throws CoreException {
+ final String NN= ""; //$NON-NLS-1$
+ if (pm == null) pm= new NullProgressMonitor();
+ pm.beginTask(NN, 2);
+ try {
+ final CompilationUnitChange result= new CompilationUnitChange(getName(), fCUnit);
+ if (fLeaveDirty)
+ result.setSaveMode(TextFileChange.LEAVE_DIRTY);
+ MultiTextEdit root= new MultiTextEdit();
+ result.setEdit(root);
+ fRewriter= ASTRewrite.create(fAnalyzer.getEnclosingBodyDeclaration().getAST());
+ fImportRewrite= StubUtility.createImportRewrite(fRootNode, true);
+
+ fLinkedProposalModel= createLinkedProposalModel();
+
+ fScope= CodeScopeBuilder.perform(fAnalyzer.getEnclosingBodyDeclaration(), fSelection).
+ findScope(fSelection.getOffset(), fSelection.getLength());
+ fScope.setCursor(fSelection.getOffset());
+
+ fSelectedNodes= fAnalyzer.getSelectedNodes();
+
+ createTryWithResourcesStatement(fCUnit.getBuffer(), fCUnit.findRecommendedLineSeparator());
+
+ if (fImportRewrite.hasRecordedChanges()) {
+ TextEdit edit= fImportRewrite.rewriteImports(null);
+ root.addChild(edit);
+ result.addTextEditGroup(new TextEditGroup(NN, new TextEdit[] {edit} ));
+ }
+ TextEdit change= fRewriter.rewriteAST();
+ root.addChild(change);
+ result.addTextEditGroup(new TextEditGroup(NN, new TextEdit[] {change} ));
+ return result;
+ } finally {
+ pm.done();
+ }
+ }
+
+ private AST getAST() {
+ return fRootNode.getAST();
+ }
+
+ @SuppressWarnings("null")
+ private void createTryWithResourcesStatement(org.eclipse.jdt.core.IBuffer buffer, String lineDelimiter) throws CoreException {
+ List<Statement> result= new ArrayList<>(1);
+ boolean modifyExistingTry= false;
+ TryStatement tryStatement= null;
+ ITypeBinding[] exceptions= fAnalyzer.getExceptions(fAnalyzer.getSelection());
+ ImportRewriteContext context= new ContextSensitiveImportRewriteContext(fAnalyzer.getEnclosingBodyDeclaration(), fImportRewrite);
+
+ TryStatement enclosingTry= (TryStatement)ASTResolving.findAncestor(fSelectedNodes[0], ASTNode.TRY_STATEMENT);
+ ListRewrite resourcesRewriter= null;
+ ListRewrite clausesRewriter= null;
+ ListRewrite statements= null;
+ if (enclosingTry == null || enclosingTry.getBody() == null || enclosingTry.getBody().statements().get(0) != fSelectedNodes[0]) {
+ tryStatement= getAST().newTryStatement();
+ statements= fRewriter.getListRewrite(tryStatement.getBody(), Block.STATEMENTS_PROPERTY);
+ } else {
+ modifyExistingTry= true;
+ resourcesRewriter= fRewriter.getListRewrite(enclosingTry, TryStatement.RESOURCES2_PROPERTY);
+ clausesRewriter= fRewriter.getListRewrite(enclosingTry, TryStatement.CATCH_CLAUSES_PROPERTY);
+ }
+
+ CatchClause catchClause= getAST().newCatchClause();
+ SingleVariableDeclaration decl= getAST().newSingleVariableDeclaration();
+ String varName= StubUtility.getExceptionVariableName(fCUnit.getJavaProject());
+ String name= fScope.createName(varName, false);
+ decl.setName(getAST().newSimpleName(name));
+
+
+ boolean selectedNodeRemoved= false;
+ ASTNode expressionStatement= null;
+ ASTNode replacementNode= null;
+ List<ASTNode> nodesInRange= new ArrayList<>();
+
+ if (!modifyExistingTry) {
+ List<ASTNode> variableDeclarations= getSpecialVariableDeclarationStatements();
+ for (ASTNode node : fSelectedNodes) {
+ if (fAutoClosableNodes.contains(node)) {
+ continue;
+ }
+ if (node instanceof VariableDeclarationStatement && variableDeclarations.contains(node)) {
+ AST ast= getAST();
+ VariableDeclarationStatement statement= (VariableDeclarationStatement)node;
+ // Create a copy and remove the initializer
+ VariableDeclarationStatement copy= (VariableDeclarationStatement)ASTNode.copySubtree(ast, statement);
+ List<IExtendedModifier> modifiers= copy.modifiers();
+ for (Iterator<IExtendedModifier> iter= modifiers.iterator(); iter.hasNext();) {
+ IExtendedModifier modifier= iter.next();
+ if (modifier.isModifier() && Modifier.isFinal(((Modifier)modifier).getKeyword().toFlagValue())) {
+ iter.remove();
+ }
+ }
+ List<VariableDeclarationFragment> fragments= copy.fragments();
+ for (VariableDeclarationFragment fragment : fragments) {
+ fragment.setInitializer(null);
+ }
+
+ // "var" type cannot have null initializer, so change to inferred type
+ if (ASTNodes.isVarType(statement, fRootNode)) {
+ ITypeBinding binding= statement.getType().resolveBinding();
+ if (binding != null) {
+ Type varType= fImportRewrite.addImport(binding, getAST(), context, TypeLocation.LOCAL_VARIABLE);
+ copy.setType(varType);
+ }
+ }
+
+ CompilationUnit root= (CompilationUnit)statement.getRoot();
+ int extendedStart= root.getExtendedStartPosition(statement);
+ // we have a leading comment and the comment is covered by the selection
+ if (extendedStart != statement.getStartPosition() && extendedStart >= fSelection.getOffset()) {
+ String commentToken= buffer.getText(extendedStart, statement.getStartPosition() - extendedStart);
+ commentToken= Strings.trimTrailingTabsAndSpaces(commentToken);
+ Type type= statement.getType();
+ String typeName= buffer.getText(type.getStartPosition(), type.getLength());
+ copy.setType((Type)fRewriter.createStringPlaceholder(commentToken + typeName, type.getNodeType()));
+ }
+ result.add(copy);
+ // convert the fragments into expression statements
+ fragments= statement.fragments();
+ if (!fragments.isEmpty()) {
+ List<ExpressionStatement> newExpressionStatements= new ArrayList<>();
+ for (VariableDeclarationFragment fragment : fragments) {
+ Expression initializer= fragment.getInitializer();
+ if (initializer != null) {
+ Assignment assignment= ast.newAssignment();
+ assignment.setLeftHandSide((Expression)fRewriter.createCopyTarget(fragment.getName()));
+ assignment.setRightHandSide((Expression)fRewriter.createCopyTarget(initializer));
+ newExpressionStatements.add(ast.newExpressionStatement(assignment));
+ }
+ }
+ if (!newExpressionStatements.isEmpty()) {
+ if (fSelectedNodes.length == 1) {
+ expressionStatement= fRewriter.createGroupNode(newExpressionStatements.toArray(new ASTNode[newExpressionStatements.size()]));
+ } else {
+ fRewriter.replace(
+ statement,
+ fRewriter.createGroupNode(newExpressionStatements.toArray(new ASTNode[newExpressionStatements.size()])),
+ null);
+ }
+ } else {
+ fRewriter.remove(statement, null);
+ selectedNodeRemoved= true;
+ }
+ } else {
+ fRewriter.remove(statement, null);
+ selectedNodeRemoved= true;
+ }
+ }
+ }
+ result.add(tryStatement);
+ if (result.size() == 1) {
+ replacementNode= result.get(0);
+ } else {
+ replacementNode= fRewriter.createGroupNode(result.toArray(new ASTNode[result.size()]));
+ }
+
+ ASTNode node= fSelectedNodes[0];
+ List<ASTNode> coveredStatements= new ArrayList<>();
+ for (ASTNode coveredNode : fSelectedNodes) {
+ Statement statement= ASTResolving.findParentStatement(coveredNode);
+ if (statement == null) {
+ continue;
+ }
+ if (!coveredStatements.contains(statement)) {
+ coveredStatements.add(statement);
+ }
+ }
+
+ Selection nodesInRangeSelection= fAnalyzer.getSelection();
+ if (!fAutoClosableNodes.isEmpty()) {
+ ASTNode parentBodyDeclaration= ASTResolving.findParentBodyDeclaration(node);
+ int start= fAutoClosableNodes.get(0).getStartPosition();
+ ASTNode lastSelectedNode= fSelectedNodes[fSelectedNodes.length - 1];
+ int end= lastSelectedNode.getStartPosition() + lastSelectedNode.getLength();
+
+ for (ASTNode astNode : fAutoClosableNodes) {
+ int endPosition= findEndPosition(astNode);
+ end= Math.max(end, endPosition);
+ }
+
+ // recursive loop to find all nodes affected by wrapping in try block
+ nodesInRange= findNodesInRange(parentBodyDeclaration, start, end);
+ int oldEnd= end;
+ int newEnd= end;
+ while (true) {
+ newEnd= oldEnd;
+ for (ASTNode astNode : nodesInRange) {
+ int endPosition= findEndPosition(astNode);
+ newEnd= Math.max(newEnd, endPosition);
+ }
+ if (newEnd > oldEnd) {
+ oldEnd= newEnd;
+ nodesInRange= findNodesInRange(parentBodyDeclaration, start, newEnd);
+ continue;
+ }
+ break;
+ }
+ if (nodesInRange.size() > 0) {
+ // must recalculate exceptions as additional lines are now in try statement
+ ASTNode lastNode= nodesInRange.get(nodesInRange.size() - 1);
+ nodesInRangeSelection= Selection.createFromStartEnd(start, lastNode.getStartPosition() + lastNode.getLength());
+ exceptions= fAnalyzer.getExceptions(nodesInRangeSelection);
+ }
+ nodesInRange.removeAll(fAutoClosableNodes);
+ nodesInRange.removeAll(Arrays.asList(fSelectedNodes));
+ }
+ }
+
+ // add required resource statements
+ CompilationUnit cu= (CompilationUnit)fSelectedNodes[0].getRoot();
+ AST ast= fSelectedNodes[0].getAST();
+ Set<String> resourceNameList= new HashSet<>();
+ List<ITypeBinding> allExceptions= new ArrayList<>(Arrays.asList(exceptions));
+ for (ASTNode coveredNode : fAutoClosableNodes) {
+ ASTNode findAncestor= ASTResolving.findAncestor(coveredNode, ASTNode.VARIABLE_DECLARATION_STATEMENT);
+ if (findAncestor == null) {
+ findAncestor= ASTResolving.findAncestor(coveredNode, ASTNode.ASSIGNMENT);
+ }
+ if (findAncestor instanceof VariableDeclarationStatement) {
+ VariableDeclarationStatement vds= (VariableDeclarationStatement) findAncestor;
+ String commentToken= null;
+ int extendedStatementStart= cu.getExtendedStartPosition(vds);
+ if(vds.getStartPosition() > extendedStatementStart) {
+ commentToken= buffer.getText(extendedStatementStart, vds.getStartPosition() - extendedStatementStart);
+ }
+ Type type= vds.getType();
+ ITypeBinding typeBinding= type.resolveBinding();
+ if (typeBinding != null) {
+ IMethodBinding close= findAutocloseMethod(typeBinding);
+ if (close != null) {
+ for (ITypeBinding exceptionType : close.getExceptionTypes()) {
+ if (!allExceptions.contains(exceptionType)) {
+ allExceptions.add(exceptionType);
+ }
+ }
+ }
+ }
+ String typeName= buffer.getText(type.getStartPosition(), type.getLength());
+
+ for (Object object : vds.fragments()) {
+ VariableDeclarationFragment variableDeclarationFragment= (VariableDeclarationFragment) object;
+ VariableDeclarationFragment newVariableDeclarationFragment= ast.newVariableDeclarationFragment();
+ SimpleName vdsName= variableDeclarationFragment.getName();
+
+ if(commentToken == null) {
+ int extendedStart= cu.getExtendedStartPosition(variableDeclarationFragment);
+ commentToken= buffer.getText(extendedStart, variableDeclarationFragment.getStartPosition() - extendedStart);
+ }
+ commentToken= Strings.trimTrailingTabsAndSpaces(commentToken);
+ commentToken += commentToken.isEmpty() ? "" : " "; //$NON-NLS-1$ //$NON-NLS-2$
+
+ newVariableDeclarationFragment.setName(ast.newSimpleName(vdsName.getIdentifier()));
+ Expression newExpression= null;
+ Expression initializer= variableDeclarationFragment.getInitializer();
+ if (initializer == null) {
+ fRewriter.remove(coveredNode, null);
+ continue;
+ } else {
+ newExpression= (Expression) fRewriter.createMoveTarget(initializer);
+ }
+ resourceNameList.add(vdsName.getIdentifier());
+ newVariableDeclarationFragment.setInitializer(newExpression);
+ VariableDeclarationExpression newVariableDeclarationExpression= ast.newVariableDeclarationExpression(newVariableDeclarationFragment);
+ newVariableDeclarationExpression.setType(
+ (Type) fRewriter.createStringPlaceholder(commentToken + typeName, type.getNodeType()));
+ if (modifyExistingTry) {
+ if (enclosingTry.resources().isEmpty()) {
+ resourcesRewriter.insertFirst(newVariableDeclarationExpression, null);
+ } else {
+ resourcesRewriter.insertLast(newVariableDeclarationExpression, null);
+ }
+ } else {
+ tryStatement.resources().add(newVariableDeclarationExpression);
+ }
+ commentToken= null;
+ }
+// String commentToken2= ""; //$NON-NLS-1$
+// int extendedStart= cu.getExtendedStartPosition(vds);
+// int extendedLength= cu.getExtendedLength(vds);
+// int endCommentLength= extendedLength - (vds.getStartPosition() - extendedStart) - vds.getLength();
+// if (endCommentLength > 0) {
+// commentToken2= buffer.getText(vds.getStartPosition() + vds.getLength(),
+// endCommentLength);
+// commentToken2= Strings.trimLeadingTabsAndSpaces(commentToken2);
+// }
+ }
+ }
+
+ List<ITypeBinding> mustRethrowList= new ArrayList<>();
+ List<ITypeBinding> catchExceptions= fAnalyzer.calculateCatchesAndRethrows(ASTNodes.filterSubtypes(allExceptions), mustRethrowList);
+ List<ITypeBinding> filteredExceptions= ASTNodes.filterSubtypes(catchExceptions);
+ if (catchExceptions.size() > 0) {
+ LinkedProposalModelCore linkedProposalModel= new LinkedProposalModelCore();
+ int i= 0;
+ if (!modifyExistingTry) {
+ for (ITypeBinding mustThrow : mustRethrowList) {
+ CatchClause newClause= ast.newCatchClause();
+ SingleVariableDeclaration newDecl= ast.newSingleVariableDeclaration();
+ newDecl.setName(ast.newSimpleName(name));
+ Type importType= fImportRewrite.addImport(mustThrow, ast, context, TypeLocation.EXCEPTION);
+ newDecl.setType(importType);
+ newClause.setException(newDecl);
+ ThrowStatement newThrowStatement= ast.newThrowStatement();
+ newThrowStatement.setExpression(ast.newSimpleName(name));
+ linkedProposalModel.getPositionGroup(GROUP_EXC_NAME + i, true).addPosition(fRewriter.track(decl.getName()), false);
+ newClause.getBody().statements().add(newThrowStatement);
+ tryStatement.catchClauses().add(newClause);
+ ++i;
+ }
+ }
+ UnionType unionType= getAST().newUnionType();
+ List<Type> types= unionType.types();
+ for (ITypeBinding exception : filteredExceptions) {
+ Type type= fImportRewrite.addImport(exception, getAST(), context, TypeLocation.EXCEPTION);
+ types.add(type);
+ fLinkedProposalModel.getPositionGroup(GROUP_EXC_TYPE + i, true).addPosition(fRewriter.track(type), i == 0);
+ i++;
+ }
+
+ decl.setType(unionType);
+ catchClause.setException(decl);
+ fLinkedProposalModel.getPositionGroup(GROUP_EXC_NAME + 0, true).addPosition(fRewriter.track(decl.getName()), false);
+ Statement st= getCatchBody("Exception", name, lineDelimiter); //$NON-NLS-1$
+ if (st != null) {
+ catchClause.getBody().statements().add(st);
+ }
+ if (modifyExistingTry) {
+ clausesRewriter.insertLast(catchClause, null);
+ } else {
+ tryStatement.catchClauses().add(catchClause);
+ }
+ }
+
+
+ if (fSelectedNodes.length == 1 && fAutoClosableNodes.isEmpty()) {
+ ASTNode selectedNode= fSelectedNodes[0];
+
+ if (selectedNode instanceof MethodReference) {
+ MethodReference methodReference= (MethodReference) selectedNode;
+ IMethodBinding functionalMethod= QuickAssistProcessorUtil.getFunctionalMethodForMethodReference(methodReference);
+ // functionalMethod is non-null and non-generic. See ExceptionAnalyzer.handleMethodReference(MethodReference node).
+ Assert.isTrue(functionalMethod != null && !functionalMethod.isGenericMethod());
+ LambdaExpression lambda= QuickAssistProcessorUtil.convertMethodRefernceToLambda(methodReference, functionalMethod, fRootNode, fRewriter, null, true);
+ ASTNode statementInBlock= (ASTNode) ((Block) lambda.getBody()).statements().get(0);
+ fRewriter.replace(statementInBlock, replacementNode, null);
+ statements.insertLast(statementInBlock, null);
+ return;
+ }
+
+ LambdaExpression enclosingLambda= ASTResolving.findEnclosingLambdaExpression(selectedNode);
+ if (enclosingLambda != null && selectedNode.getLocationInParent() == LambdaExpression.BODY_PROPERTY && enclosingLambda.resolveMethodBinding() != null) {
+ QuickAssistProcessorUtil.changeLambdaBodyToBlock(enclosingLambda, getAST(), fRewriter);
+ Block blockBody= (Block) fRewriter.get(enclosingLambda, LambdaExpression.BODY_PROPERTY);
+ ASTNode statementInBlock= (ASTNode) blockBody.statements().get(0);
+ fRewriter.replace(statementInBlock, replacementNode, null);
+ statements.insertLast(statementInBlock, null);
+ return;
+ }
+
+ if (expressionStatement != null) {
+ statements.insertLast(expressionStatement, null);
+ } else {
+ if (!selectedNodeRemoved)
+ statements.insertLast(fRewriter.createMoveTarget(selectedNode), null);
+ }
+ fRewriter.replace(selectedNode, replacementNode, null);
+ } else if (modifyExistingTry) {
+ ListRewrite source= fRewriter.getListRewrite(enclosingTry.getBody(), Block.STATEMENTS_PROPERTY);
+ for (ASTNode node : fAutoClosableNodes) {
+ source.remove(node, null);
+ }
+ } else {
+ ListRewrite source= fRewriter.getListRewrite(
+ fSelectedNodes[0].getParent(),
+ (ChildListPropertyDescriptor)fSelectedNodes[0].getLocationInParent());
+ List<ASTNode> nodes= new ArrayList<>(Arrays.asList(fSelectedNodes));
+ if (!nodesInRange.isEmpty()) {
+ nodes.addAll(nodesInRange);
+ }
+ int index= fAutoClosableNodes.size();
+ if (index < nodes.size()) {
+ ASTNode toMove= source.createMoveTarget(nodes.get(index), nodes.get(nodes.size() - 1),
+ index == 0 ? replacementNode : null, null);
+ statements.insertLast(toMove, null);
+ }
+ if (index > 0) {
+ source.replace(fAutoClosableNodes.get(0), replacementNode, null);
+ for (int i= 1; i < index; ++i) {
+ source.remove(fAutoClosableNodes.get(i), null);
+ }
+ }
+ }
+
+ }
+
+ public static IMethodBinding findAutocloseMethod(ITypeBinding type) {
+ while (type != null) {
+ IMethodBinding[] methods= type.getDeclaredMethods();
+ for (IMethodBinding method : methods) {
+ if ("close".equals(method.getName()) && method.getParameterTypes().length == 0) { //$NON-NLS-1$
+ return method;
+ }
+ }
+ type= type.getSuperclass();
+ }
+ return null;
+ }
+
+ private int findEndPosition(ASTNode node) {
+ int end= node.getStartPosition() + node.getLength();
+ Map<SimpleName, IVariableBinding> nodeSimpleNameBindings= fAnalyzer.getVariableStatementBinding(node);
+ List<SimpleName> nodeNames= new ArrayList<>(nodeSimpleNameBindings.keySet());
+ if (nodeNames.isEmpty()) {
+ return -1;
+ }
+ SimpleName nodeSimpleName= nodeNames.get(0);
+ SimpleName[] coveredNodeBindings= LinkedNodeFinder.findByNode(node.getRoot(), nodeSimpleName);
+ if (coveredNodeBindings.length == 0) {
+ return -1;
+ }
+ for (ASTNode astNode : coveredNodeBindings) {
+ end= Math.max(end, (astNode.getStartPosition() + astNode.getLength()));
+ }
+ return end;
+ }
+
+ // find all nodes (statements) that are within the start/end positions
+ public static List<ASTNode> findNodesInRange(ASTNode astNode, final int start, final int end) {
+ List<ASTNode> nodesInRange= new ArrayList<>();
+ astNode.accept(new ASTVisitor() {
+ int pre= start;
+
+ @Override
+ public void preVisit(ASTNode preNode) {
+ pre= preNode.getStartPosition();
+ super.preVisit(preNode);
+ }
+
+ @Override
+ public void postVisit(ASTNode postNode) {
+ int post= postNode.getStartPosition() + postNode.getLength();
+ if (pre >= start && post <= end) {
+ Statement statement= ASTResolving.findParentStatement(postNode);
+ loop: while (statement != null) {
+ if (statement.getParent() instanceof Statement) {
+ Statement pStatement= (Statement) statement.getParent();
+ switch (pStatement.getNodeType()) {
+ case ASTNode.BLOCK:
+ if (pStatement.getParent().getNodeType() != ASTNode.METHOD_DECLARATION &&
+ pStatement.getParent().getNodeType() != ASTNode.TRY_STATEMENT) {
+ statement= pStatement;
+ continue;
+ } else {
+ break loop;
+ }
+ case ASTNode.METHOD_DECLARATION:
+ break loop;
+ default:
+ break;
+ }
+ statement= pStatement;
+ } else {
+ break;
+ }
+ }
+ if (statement != null && !nodesInRange.contains(statement)) {
+ nodesInRange.add(statement);
+ }
+ }
+ super.postVisit(postNode);
+ }
+ });
+ return nodesInRange;
+ }
+
+ private List<ASTNode> getSpecialVariableDeclarationStatements() {
+ List<ASTNode> result= new ArrayList<>(3);
+ for (VariableDeclaration local : fAnalyzer.getAffectedLocals()) {
+ ASTNode parent= local.getParent();
+ if (parent instanceof VariableDeclarationStatement && !result.contains(parent))
+ result.add(parent);
+ }
+ return result;
+
+ }
+
+ private Statement getCatchBody(String type, String name, String lineSeparator) throws CoreException {
+ String s= StubUtility.getCatchBodyContent(fCUnit, type, name, fSelectedNodes[0], lineSeparator);
+ if (s == null) {
+ return null;
+ } else {
+ return (Statement)fRewriter.createStringPlaceholder(s, ASTNode.RETURN_STATEMENT);
+ }
+ }
+}
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/util/AbstractExceptionAnalyzer.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/util/AbstractExceptionAnalyzer.java
similarity index 100%
rename from org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/util/AbstractExceptionAnalyzer.java
rename to org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/refactoring/util/AbstractExceptionAnalyzer.java
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_in/TestTry1.java b/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_in/TestTry1.java
new file mode 100644
index 0000000..7352ca1
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_in/TestTry1.java
@@ -0,0 +1,16 @@
+package trycatch18_in;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+
+class TestTry1 {
+ FileInputStream foo() {
+ try {
+ /*[*/FileInputStream f = new FileInputStream("a.b");
+ return f;/*]*/
+ } catch (FileNotFoundException e) {
+ // do nothing
+ }
+ return null;
+ }
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_in/TestTry2.java b/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_in/TestTry2.java
new file mode 100644
index 0000000..bc4d4f3
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_in/TestTry2.java
@@ -0,0 +1,17 @@
+package trycatch18_in;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+
+class TestTry1 {
+ FileInputStream foo() {
+ try {
+ String name = "a.b";
+ /*[*/FileInputStream f = new FileInputStream(name);
+ return f;/*]*/
+ } catch (FileNotFoundException e) {
+ // do nothing
+ }
+ return null;
+ }
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_out/TestTry1.java b/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_out/TestTry1.java
new file mode 100644
index 0000000..a2764af
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_out/TestTry1.java
@@ -0,0 +1,17 @@
+package trycatch18_out;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+class TestTry1 {
+ FileInputStream foo() {
+ try (/*[*/ FileInputStream f = new FileInputStream("a.b")) {
+ return f;/*]*/
+ } catch (FileNotFoundException e) {
+ // do nothing
+ } catch (IOException e) {
+ }
+ return null;
+ }
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_out/TestTry2.java b/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_out/TestTry2.java
new file mode 100644
index 0000000..d32e746
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_out/TestTry2.java
@@ -0,0 +1,22 @@
+package trycatch18_out;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+class TestTry1 {
+ FileInputStream foo() {
+ try {
+ String name = "a.b";
+ try (/*[*/ FileInputStream f = new FileInputStream(name)) {
+ return f;/*]*/
+ } catch (FileNotFoundException e) {
+ throw e;
+ } catch (IOException e) {
+ }
+ } catch (FileNotFoundException e) {
+ // do nothing
+ }
+ return null;
+ }
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_out/TestWithThrows3.java b/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_out/TestWithThrows3.java
index 3c4c1d7..fe0e0d0 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_out/TestWithThrows3.java
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/tryresources18_out/TestWithThrows3.java
@@ -6,15 +6,11 @@
class TestWithThrows3 {
public FileInputStream foo(int a) throws FileNotFoundException {
- try {
- try (/*[*/ FileInputStream f = new FileInputStream("a.b")) {
- return f;/*]*/
- } catch (FileNotFoundException e) {
- throw e;
- } catch (IOException e) {
- }
+ try (/*[*/ FileInputStream f = new FileInputStream("a.b")) {
+ return f;/*]*/
} catch (FileNotFoundException e) {
// do nothing
+ } catch (IOException e) {
}
return null;
}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/AllTests.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/AllTests.java
index 694794b..cc26ae5 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/AllTests.java
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/AllTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2020 IBM Corporation and others.
+ * Copyright (c) 2000, 2021 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -26,6 +26,7 @@
SurroundWithTests.class,
SurroundWithTests1d7.class,
SurroundWithTests1d8.class,
+ SurroundWithResourcesTests1d8.class,
})
public class AllTests {
}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryCatchRefactoring.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryCatchRefactoring.java
index e8ef5c1..e96439e 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryCatchRefactoring.java
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryCatchRefactoring.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2020 IBM Corporation and others.
+ * Copyright (c) 2000, 2021 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -80,7 +80,7 @@
import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil;
import org.eclipse.jdt.internal.corext.refactoring.util.SelectionAwareSourceRangeComputer;
-import org.eclipse.jdt.internal.ui.text.correction.QuickAssistProcessor;
+import org.eclipse.jdt.internal.ui.text.correction.QuickAssistProcessorUtil;
/**
* Surround a set of statements with a try/catch block or a try/multi-catch block.
@@ -380,10 +380,10 @@
if (selectedNode instanceof MethodReference) {
MethodReference methodReference= (MethodReference) selectedNode;
- IMethodBinding functionalMethod= QuickAssistProcessor.getFunctionalMethodForMethodReference(methodReference);
+ IMethodBinding functionalMethod= QuickAssistProcessorUtil.getFunctionalMethodForMethodReference(methodReference);
// functionalMethod is non-null and non-generic. See ExceptionAnalyzer.handleMethodReference(MethodReference node).
Assert.isTrue(functionalMethod != null && !functionalMethod.isGenericMethod());
- LambdaExpression lambda= QuickAssistProcessor.convertMethodRefernceToLambda(methodReference, functionalMethod, fRootNode, fRewriter, null, true);
+ LambdaExpression lambda= QuickAssistProcessorUtil.convertMethodRefernceToLambda(methodReference, functionalMethod, fRootNode, fRewriter, null, true);
ASTNode statementInBlock= (ASTNode) ((Block) lambda.getBody()).statements().get(0);
fRewriter.replace(statementInBlock, replacementNode, null);
statements.insertLast(statementInBlock, null);
@@ -392,7 +392,7 @@
LambdaExpression enclosingLambda= ASTResolving.findEnclosingLambdaExpression(selectedNode);
if (enclosingLambda != null && selectedNode.getLocationInParent() == LambdaExpression.BODY_PROPERTY && enclosingLambda.resolveMethodBinding() != null) {
- QuickAssistProcessor.changeLambdaBodyToBlock(enclosingLambda, getAST(), fRewriter);
+ QuickAssistProcessorUtil.changeLambdaBodyToBlock(enclosingLambda, getAST(), fRewriter);
Block blockBody= (Block) fRewriter.get(enclosingLambda, LambdaExpression.BODY_PROPERTY);
ASTNode statementInBlock= (ASTNode) blockBody.statements().get(0);
fRewriter.replace(statementInBlock, replacementNode, null);
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesRefactoring.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesRefactoring.java
index 4209ae5..010461d 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesRefactoring.java
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryWithResourcesRefactoring.java
@@ -13,82 +13,13 @@
*******************************************************************************/
package org.eclipse.jdt.internal.corext.refactoring.surround;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.eclipse.core.runtime.Assert;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-
-import org.eclipse.text.edits.MultiTextEdit;
-import org.eclipse.text.edits.TextEdit;
-import org.eclipse.text.edits.TextEditGroup;
-
import org.eclipse.jface.text.ITextSelection;
-import org.eclipse.ltk.core.refactoring.Change;
-import org.eclipse.ltk.core.refactoring.Refactoring;
-import org.eclipse.ltk.core.refactoring.RefactoringStatus;
-import org.eclipse.ltk.core.refactoring.TextFileChange;
-
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.ASTVisitor;
-import org.eclipse.jdt.core.dom.Assignment;
-import org.eclipse.jdt.core.dom.Block;
-import org.eclipse.jdt.core.dom.CatchClause;
-import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;
-import org.eclipse.jdt.core.dom.CompilationUnit;
-import org.eclipse.jdt.core.dom.Expression;
-import org.eclipse.jdt.core.dom.ExpressionStatement;
-import org.eclipse.jdt.core.dom.IExtendedModifier;
-import org.eclipse.jdt.core.dom.IMethodBinding;
-import org.eclipse.jdt.core.dom.ITypeBinding;
-import org.eclipse.jdt.core.dom.IVariableBinding;
-import org.eclipse.jdt.core.dom.LambdaExpression;
-import org.eclipse.jdt.core.dom.MethodReference;
-import org.eclipse.jdt.core.dom.Modifier;
-import org.eclipse.jdt.core.dom.SimpleName;
-import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
-import org.eclipse.jdt.core.dom.Statement;
-import org.eclipse.jdt.core.dom.ThrowStatement;
-import org.eclipse.jdt.core.dom.TryStatement;
-import org.eclipse.jdt.core.dom.Type;
-import org.eclipse.jdt.core.dom.UnionType;
-import org.eclipse.jdt.core.dom.VariableDeclaration;
-import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
-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.ImportRewrite;
-import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext;
-import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.TypeLocation;
-import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
-import org.eclipse.jdt.core.refactoring.CompilationUnitChange;
-import org.eclipse.jdt.internal.core.manipulation.StubUtility;
-import org.eclipse.jdt.internal.core.manipulation.dom.ASTResolving;
-import org.eclipse.jdt.internal.core.manipulation.util.Strings;
-import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext;
-import org.eclipse.jdt.internal.corext.dom.ASTNodes;
-import org.eclipse.jdt.internal.corext.dom.CodeScopeBuilder;
-import org.eclipse.jdt.internal.corext.dom.IASTSharedValues;
-import org.eclipse.jdt.internal.corext.dom.LinkedNodeFinder;
import org.eclipse.jdt.internal.corext.dom.Selection;
import org.eclipse.jdt.internal.corext.fix.LinkedProposalModel;
-import org.eclipse.jdt.internal.corext.refactoring.Checks;
-import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
-import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringASTParser;
-import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil;
-
-import org.eclipse.jdt.internal.ui.text.correction.QuickAssistProcessor;
+import org.eclipse.jdt.internal.corext.fix.LinkedProposalModelCore;
/**
* Surround a set of statements with a try-with-resources block.
@@ -102,30 +33,10 @@
* only consists of new assignments. In this case we can't move the
* selected nodes (e.g. the declaration) into the try block.
*/
-public class SurroundWithTryWithResourcesRefactoring extends Refactoring {
-
- public final String GROUP_EXC_TYPE= "exc_type"; //$NON-NLS-1$
- public final String GROUP_EXC_NAME= "exc_name"; //$NON-NLS-1$
- public final String GROUP_TRY_STATEMENT= "try_stmt"; //$NON-NLS-1$
-
- private Selection fSelection;
- private SurroundWithTryWithResourcesAnalyzer fAnalyzer;
- private boolean fLeaveDirty;
-
- private ICompilationUnit fCUnit;
- private CompilationUnit fRootNode;
- private ASTRewrite fRewriter;
- private ImportRewrite fImportRewrite;
- private CodeScopeBuilder.Scope fScope;
- private ASTNode[] fSelectedNodes;
- private List<ASTNode> fAutoClosableNodes;
-
- private LinkedProposalModel fLinkedProposalModel;
+public class SurroundWithTryWithResourcesRefactoring extends SurroundWithTryWithResourcesRefactoringCore {
private SurroundWithTryWithResourcesRefactoring(ICompilationUnit cu, Selection selection) {
- fCUnit= cu;
- fSelection= selection;
- fLeaveDirty= false;
+ super(cu, selection);
}
public static SurroundWithTryWithResourcesRefactoring create(ICompilationUnit cu, int offset, int length) {
@@ -136,560 +47,13 @@
return new SurroundWithTryWithResourcesRefactoring(cu, Selection.createFromStartLength(selection.getOffset(), selection.getLength()));
}
+ @Override
+ protected LinkedProposalModelCore createLinkedProposalModel() {
+ return new LinkedProposalModel();
+ }
+
public LinkedProposalModel getLinkedProposalModel() {
- return fLinkedProposalModel;
+ return (LinkedProposalModel)getLinkedProposalModelCore();
}
- public void setLeaveDirty(boolean leaveDirty) {
- fLeaveDirty= leaveDirty;
- }
-
- public boolean stopExecution() {
- if (fAnalyzer == null)
- return true;
- ITypeBinding[] exceptions= fAnalyzer.getExceptions(fAnalyzer.getSelection());
- List<ASTNode> autoClosableNodes= fAnalyzer.getCoveredAutoClosableNodes();
- return (exceptions == null || exceptions.length == 0) && (autoClosableNodes == null || autoClosableNodes.isEmpty());
- }
-
- /* non Java-doc
- * @see IRefactoring#getName()
- */
- @Override
- public String getName() {
- return RefactoringCoreMessages.SurroundWithTryWithResourcesRefactoring_name;
- }
-
- public RefactoringStatus checkActivationBasics(CompilationUnit rootNode) throws CoreException {
- RefactoringStatus result= new RefactoringStatus();
- fRootNode= rootNode;
-
- fAnalyzer= new SurroundWithTryWithResourcesAnalyzer(fCUnit, fSelection);
- fRootNode.accept(fAnalyzer);
- result.merge(fAnalyzer.getStatus());
- fAutoClosableNodes= fAnalyzer.getCoveredAutoClosableNodes();
- if (fAutoClosableNodes == null || fAutoClosableNodes.isEmpty()) {
- result.merge(RefactoringStatus.createWarningStatus(RefactoringCoreMessages.SurroundWithTryWithResourcesRefactoring_notAutoclosable));
- }
- return result;
- }
-
-
- /*
- * @see Refactoring#checkActivation(IProgressMonitor)
- */
- @Override
- public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException {
- CompilationUnit rootNode= new RefactoringASTParser(IASTSharedValues.SHARED_AST_LEVEL).parse(fCUnit, true, pm);
- return checkActivationBasics(rootNode);
- }
-
- /*
- * @see Refactoring#checkInput(IProgressMonitor)
- */
- @Override
- public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException {
- return Checks.validateModifiesFiles(
- ResourceUtil.getFiles(new ICompilationUnit[]{fCUnit}),
- getValidationContext(), pm);
- }
-
- /* non Java-doc
- * @see IRefactoring#createChange(IProgressMonitor)
- */
- @Override
- public Change createChange(IProgressMonitor pm) throws CoreException {
- final String NN= ""; //$NON-NLS-1$
- if (pm == null) pm= new NullProgressMonitor();
- pm.beginTask(NN, 2);
- try {
- final CompilationUnitChange result= new CompilationUnitChange(getName(), fCUnit);
- if (fLeaveDirty)
- result.setSaveMode(TextFileChange.LEAVE_DIRTY);
- MultiTextEdit root= new MultiTextEdit();
- result.setEdit(root);
- fRewriter= ASTRewrite.create(fAnalyzer.getEnclosingBodyDeclaration().getAST());
- fImportRewrite= StubUtility.createImportRewrite(fRootNode, true);
-
- fLinkedProposalModel= new LinkedProposalModel();
-
- fScope= CodeScopeBuilder.perform(fAnalyzer.getEnclosingBodyDeclaration(), fSelection).
- findScope(fSelection.getOffset(), fSelection.getLength());
- fScope.setCursor(fSelection.getOffset());
-
- fSelectedNodes= fAnalyzer.getSelectedNodes();
-
- createTryWithResourcesStatement(fCUnit.getBuffer(), fCUnit.findRecommendedLineSeparator());
-
- if (fImportRewrite.hasRecordedChanges()) {
- TextEdit edit= fImportRewrite.rewriteImports(null);
- root.addChild(edit);
- result.addTextEditGroup(new TextEditGroup(NN, new TextEdit[] {edit} ));
- }
- TextEdit change= fRewriter.rewriteAST();
- root.addChild(change);
- result.addTextEditGroup(new TextEditGroup(NN, new TextEdit[] {change} ));
- return result;
- } finally {
- pm.done();
- }
- }
-
- private AST getAST() {
- return fRootNode.getAST();
- }
-
- @SuppressWarnings("null")
- private void createTryWithResourcesStatement(org.eclipse.jdt.core.IBuffer buffer, String lineDelimiter) throws CoreException {
- List<Statement> result= new ArrayList<>(1);
- boolean modifyExistingTry= false;
- TryStatement tryStatement= null;
- ITypeBinding[] exceptions= fAnalyzer.getExceptions(fAnalyzer.getSelection());
- ImportRewriteContext context= new ContextSensitiveImportRewriteContext(fAnalyzer.getEnclosingBodyDeclaration(), fImportRewrite);
-
- TryStatement enclosingTry= (TryStatement)ASTResolving.findAncestor(fSelectedNodes[0], ASTNode.TRY_STATEMENT);
- ListRewrite resourcesRewriter= null;
- ListRewrite clausesRewriter= null;
- ListRewrite statements= null;
- if (enclosingTry == null || enclosingTry.getBody() == null || enclosingTry.getBody().statements().get(0) != fSelectedNodes[0]) {
- tryStatement= getAST().newTryStatement();
- statements= fRewriter.getListRewrite(tryStatement.getBody(), Block.STATEMENTS_PROPERTY);
- } else {
- modifyExistingTry= true;
- resourcesRewriter= fRewriter.getListRewrite(enclosingTry, TryStatement.RESOURCES2_PROPERTY);
- clausesRewriter= fRewriter.getListRewrite(enclosingTry, TryStatement.CATCH_CLAUSES_PROPERTY);
- }
-
- CatchClause catchClause= getAST().newCatchClause();
- SingleVariableDeclaration decl= getAST().newSingleVariableDeclaration();
- String varName= StubUtility.getExceptionVariableName(fCUnit.getJavaProject());
- String name= fScope.createName(varName, false);
- decl.setName(getAST().newSimpleName(name));
-
-
- boolean selectedNodeRemoved= false;
- ASTNode expressionStatement= null;
- ASTNode replacementNode= null;
- List<ASTNode> nodesInRange= new ArrayList<>();
-
- if (!modifyExistingTry) {
- List<ASTNode> variableDeclarations= getSpecialVariableDeclarationStatements();
- for (ASTNode node : fSelectedNodes) {
- if (fAutoClosableNodes.contains(node)) {
- continue;
- }
- if (node instanceof VariableDeclarationStatement && variableDeclarations.contains(node)) {
- AST ast= getAST();
- VariableDeclarationStatement statement= (VariableDeclarationStatement)node;
- // Create a copy and remove the initializer
- VariableDeclarationStatement copy= (VariableDeclarationStatement)ASTNode.copySubtree(ast, statement);
- List<IExtendedModifier> modifiers= copy.modifiers();
- for (Iterator<IExtendedModifier> iter= modifiers.iterator(); iter.hasNext();) {
- IExtendedModifier modifier= iter.next();
- if (modifier.isModifier() && Modifier.isFinal(((Modifier)modifier).getKeyword().toFlagValue())) {
- iter.remove();
- }
- }
- List<VariableDeclarationFragment> fragments= copy.fragments();
- for (VariableDeclarationFragment fragment : fragments) {
- fragment.setInitializer(null);
- }
-
- // "var" type cannot have null initializer, so change to inferred type
- if (ASTNodes.isVarType(statement, fRootNode)) {
- ITypeBinding binding= statement.getType().resolveBinding();
- if (binding != null) {
- Type varType= fImportRewrite.addImport(binding, getAST(), context, TypeLocation.LOCAL_VARIABLE);
- copy.setType(varType);
- }
- }
-
- CompilationUnit root= (CompilationUnit)statement.getRoot();
- int extendedStart= root.getExtendedStartPosition(statement);
- // we have a leading comment and the comment is covered by the selection
- if (extendedStart != statement.getStartPosition() && extendedStart >= fSelection.getOffset()) {
- String commentToken= buffer.getText(extendedStart, statement.getStartPosition() - extendedStart);
- commentToken= Strings.trimTrailingTabsAndSpaces(commentToken);
- Type type= statement.getType();
- String typeName= buffer.getText(type.getStartPosition(), type.getLength());
- copy.setType((Type)fRewriter.createStringPlaceholder(commentToken + typeName, type.getNodeType()));
- }
- result.add(copy);
- // convert the fragments into expression statements
- fragments= statement.fragments();
- if (!fragments.isEmpty()) {
- List<ExpressionStatement> newExpressionStatements= new ArrayList<>();
- for (VariableDeclarationFragment fragment : fragments) {
- Expression initializer= fragment.getInitializer();
- if (initializer != null) {
- Assignment assignment= ast.newAssignment();
- assignment.setLeftHandSide((Expression)fRewriter.createCopyTarget(fragment.getName()));
- assignment.setRightHandSide((Expression)fRewriter.createCopyTarget(initializer));
- newExpressionStatements.add(ast.newExpressionStatement(assignment));
- }
- }
- if (!newExpressionStatements.isEmpty()) {
- if (fSelectedNodes.length == 1) {
- expressionStatement= fRewriter.createGroupNode(newExpressionStatements.toArray(new ASTNode[newExpressionStatements.size()]));
- } else {
- fRewriter.replace(
- statement,
- fRewriter.createGroupNode(newExpressionStatements.toArray(new ASTNode[newExpressionStatements.size()])),
- null);
- }
- } else {
- fRewriter.remove(statement, null);
- selectedNodeRemoved= true;
- }
- } else {
- fRewriter.remove(statement, null);
- selectedNodeRemoved= true;
- }
- }
- }
- result.add(tryStatement);
- if (result.size() == 1) {
- replacementNode= result.get(0);
- } else {
- replacementNode= fRewriter.createGroupNode(result.toArray(new ASTNode[result.size()]));
- }
-
- ASTNode node= fSelectedNodes[0];
- List<ASTNode> coveredStatements= new ArrayList<>();
- for (ASTNode coveredNode : fSelectedNodes) {
- Statement statement= ASTResolving.findParentStatement(coveredNode);
- if (statement == null) {
- continue;
- }
- if (!coveredStatements.contains(statement)) {
- coveredStatements.add(statement);
- }
- }
-
- Selection nodesInRangeSelection= fAnalyzer.getSelection();
- if (!fAutoClosableNodes.isEmpty()) {
- ASTNode parentBodyDeclaration= ASTResolving.findParentBodyDeclaration(node);
- int start= fAutoClosableNodes.get(0).getStartPosition();
- ASTNode lastSelectedNode= fSelectedNodes[fSelectedNodes.length - 1];
- int end= lastSelectedNode.getStartPosition() + lastSelectedNode.getLength();
-
- for (ASTNode astNode : fAutoClosableNodes) {
- int endPosition= findEndPosition(astNode);
- end= Math.max(end, endPosition);
- }
-
- // recursive loop to find all nodes affected by wrapping in try block
- nodesInRange= findNodesInRange(parentBodyDeclaration, start, end);
- int oldEnd= end;
- int newEnd= end;
- while (true) {
- newEnd= oldEnd;
- for (ASTNode astNode : nodesInRange) {
- int endPosition= findEndPosition(astNode);
- newEnd= Math.max(newEnd, endPosition);
- }
- if (newEnd > oldEnd) {
- oldEnd= newEnd;
- nodesInRange= findNodesInRange(parentBodyDeclaration, start, newEnd);
- continue;
- }
- break;
- }
- if (nodesInRange.size() > 0) {
- // must recalculate exceptions as additional lines are now in try statement
- ASTNode lastNode= nodesInRange.get(nodesInRange.size() - 1);
- nodesInRangeSelection= Selection.createFromStartEnd(start, lastNode.getStartPosition() + lastNode.getLength());
- exceptions= fAnalyzer.getExceptions(nodesInRangeSelection);
- }
- nodesInRange.removeAll(fAutoClosableNodes);
- nodesInRange.removeAll(Arrays.asList(fSelectedNodes));
- }
- }
-
- // add required resource statements
- CompilationUnit cu= (CompilationUnit)fSelectedNodes[0].getRoot();
- AST ast= fSelectedNodes[0].getAST();
- Set<String> resourceNameList= new HashSet<>();
- List<ITypeBinding> allExceptions= new ArrayList<>(Arrays.asList(exceptions));
- for (ASTNode coveredNode : fAutoClosableNodes) {
- ASTNode findAncestor= ASTResolving.findAncestor(coveredNode, ASTNode.VARIABLE_DECLARATION_STATEMENT);
- if (findAncestor == null) {
- findAncestor= ASTResolving.findAncestor(coveredNode, ASTNode.ASSIGNMENT);
- }
- if (findAncestor instanceof VariableDeclarationStatement) {
- VariableDeclarationStatement vds= (VariableDeclarationStatement) findAncestor;
- String commentToken= null;
- int extendedStatementStart= cu.getExtendedStartPosition(vds);
- if(vds.getStartPosition() > extendedStatementStart) {
- commentToken= buffer.getText(extendedStatementStart, vds.getStartPosition() - extendedStatementStart);
- }
- Type type= vds.getType();
- ITypeBinding typeBinding= type.resolveBinding();
- if (typeBinding != null) {
- IMethodBinding close= findAutocloseMethod(typeBinding);
- if (close != null) {
- for (ITypeBinding exceptionType : close.getExceptionTypes()) {
- if (!allExceptions.contains(exceptionType)) {
- allExceptions.add(exceptionType);
- }
- }
- }
- }
- String typeName= buffer.getText(type.getStartPosition(), type.getLength());
-
- for (Object object : vds.fragments()) {
- VariableDeclarationFragment variableDeclarationFragment= (VariableDeclarationFragment) object;
- VariableDeclarationFragment newVariableDeclarationFragment= ast.newVariableDeclarationFragment();
- SimpleName vdsName= variableDeclarationFragment.getName();
-
- if(commentToken == null) {
- int extendedStart= cu.getExtendedStartPosition(variableDeclarationFragment);
- commentToken= buffer.getText(extendedStart, variableDeclarationFragment.getStartPosition() - extendedStart);
- }
- commentToken= Strings.trimTrailingTabsAndSpaces(commentToken);
- commentToken += commentToken.isEmpty() ? "" : " "; //$NON-NLS-1$ //$NON-NLS-2$
-
- newVariableDeclarationFragment.setName(ast.newSimpleName(vdsName.getIdentifier()));
- Expression newExpression= null;
- Expression initializer= variableDeclarationFragment.getInitializer();
- if (initializer == null) {
- fRewriter.remove(coveredNode, null);
- continue;
- } else {
- newExpression= (Expression) fRewriter.createMoveTarget(initializer);
- }
- resourceNameList.add(vdsName.getIdentifier());
- newVariableDeclarationFragment.setInitializer(newExpression);
- VariableDeclarationExpression newVariableDeclarationExpression= ast.newVariableDeclarationExpression(newVariableDeclarationFragment);
- newVariableDeclarationExpression.setType(
- (Type) fRewriter.createStringPlaceholder(commentToken + typeName, type.getNodeType()));
- if (modifyExistingTry) {
- if (enclosingTry.resources().isEmpty()) {
- resourcesRewriter.insertFirst(newVariableDeclarationExpression, null);
- } else {
- resourcesRewriter.insertLast(newVariableDeclarationExpression, null);
- }
- } else {
- tryStatement.resources().add(newVariableDeclarationExpression);
- }
- commentToken= null;
- }
-// String commentToken2= ""; //$NON-NLS-1$
-// int extendedStart= cu.getExtendedStartPosition(vds);
-// int extendedLength= cu.getExtendedLength(vds);
-// int endCommentLength= extendedLength - (vds.getStartPosition() - extendedStart) - vds.getLength();
-// if (endCommentLength > 0) {
-// commentToken2= buffer.getText(vds.getStartPosition() + vds.getLength(),
-// endCommentLength);
-// commentToken2= Strings.trimLeadingTabsAndSpaces(commentToken2);
-// }
- }
- }
-
- List<ITypeBinding> mustRethrowList= new ArrayList<>();
- List<ITypeBinding> catchExceptions= fAnalyzer.calculateCatchesAndRethrows(ASTNodes.filterSubtypes(allExceptions), mustRethrowList);
- List<ITypeBinding> filteredExceptions= ASTNodes.filterSubtypes(catchExceptions);
- if (catchExceptions.size() > 0) {
- LinkedProposalModel linkedProposalModel= new LinkedProposalModel();
- int i= 0;
- if (!modifyExistingTry) {
- for (ITypeBinding mustThrow : mustRethrowList) {
- CatchClause newClause= ast.newCatchClause();
- SingleVariableDeclaration newDecl= ast.newSingleVariableDeclaration();
- newDecl.setName(ast.newSimpleName(name));
- Type importType= fImportRewrite.addImport(mustThrow, ast, context, TypeLocation.EXCEPTION);
- newDecl.setType(importType);
- newClause.setException(newDecl);
- ThrowStatement newThrowStatement= ast.newThrowStatement();
- newThrowStatement.setExpression(ast.newSimpleName(name));
- linkedProposalModel.getPositionGroup(GROUP_EXC_NAME + i, true).addPosition(fRewriter.track(decl.getName()), false);
- newClause.getBody().statements().add(newThrowStatement);
- tryStatement.catchClauses().add(newClause);
- ++i;
- }
- }
- UnionType unionType= getAST().newUnionType();
- List<Type> types= unionType.types();
- for (ITypeBinding exception : filteredExceptions) {
- Type type= fImportRewrite.addImport(exception, getAST(), context, TypeLocation.EXCEPTION);
- types.add(type);
- fLinkedProposalModel.getPositionGroup(GROUP_EXC_TYPE + i, true).addPosition(fRewriter.track(type), i == 0);
- i++;
- }
-
- decl.setType(unionType);
- catchClause.setException(decl);
- fLinkedProposalModel.getPositionGroup(GROUP_EXC_NAME + 0, true).addPosition(fRewriter.track(decl.getName()), false);
- Statement st= getCatchBody("Exception", name, lineDelimiter); //$NON-NLS-1$
- if (st != null) {
- catchClause.getBody().statements().add(st);
- }
- if (modifyExistingTry) {
- clausesRewriter.insertLast(catchClause, null);
- } else {
- tryStatement.catchClauses().add(catchClause);
- }
- }
-
-
- if (fSelectedNodes.length == 1 && fAutoClosableNodes.isEmpty()) {
- ASTNode selectedNode= fSelectedNodes[0];
-
- if (selectedNode instanceof MethodReference) {
- MethodReference methodReference= (MethodReference) selectedNode;
- IMethodBinding functionalMethod= QuickAssistProcessor.getFunctionalMethodForMethodReference(methodReference);
- // functionalMethod is non-null and non-generic. See ExceptionAnalyzer.handleMethodReference(MethodReference node).
- Assert.isTrue(functionalMethod != null && !functionalMethod.isGenericMethod());
- LambdaExpression lambda= QuickAssistProcessor.convertMethodRefernceToLambda(methodReference, functionalMethod, fRootNode, fRewriter, null, true);
- ASTNode statementInBlock= (ASTNode) ((Block) lambda.getBody()).statements().get(0);
- fRewriter.replace(statementInBlock, replacementNode, null);
- statements.insertLast(statementInBlock, null);
- return;
- }
-
- LambdaExpression enclosingLambda= ASTResolving.findEnclosingLambdaExpression(selectedNode);
- if (enclosingLambda != null && selectedNode.getLocationInParent() == LambdaExpression.BODY_PROPERTY && enclosingLambda.resolveMethodBinding() != null) {
- QuickAssistProcessor.changeLambdaBodyToBlock(enclosingLambda, getAST(), fRewriter);
- Block blockBody= (Block) fRewriter.get(enclosingLambda, LambdaExpression.BODY_PROPERTY);
- ASTNode statementInBlock= (ASTNode) blockBody.statements().get(0);
- fRewriter.replace(statementInBlock, replacementNode, null);
- statements.insertLast(statementInBlock, null);
- return;
- }
-
- if (expressionStatement != null) {
- statements.insertLast(expressionStatement, null);
- } else {
- if (!selectedNodeRemoved)
- statements.insertLast(fRewriter.createMoveTarget(selectedNode), null);
- }
- fRewriter.replace(selectedNode, replacementNode, null);
- } else if (modifyExistingTry) {
- ListRewrite source= fRewriter.getListRewrite(enclosingTry.getBody(), Block.STATEMENTS_PROPERTY);
- for (ASTNode node : fAutoClosableNodes) {
- source.remove(node, null);
- }
- } else {
- ListRewrite source= fRewriter.getListRewrite(
- fSelectedNodes[0].getParent(),
- (ChildListPropertyDescriptor)fSelectedNodes[0].getLocationInParent());
- List<ASTNode> nodes= new ArrayList<>(Arrays.asList(fSelectedNodes));
- if (!nodesInRange.isEmpty()) {
- nodes.addAll(nodesInRange);
- }
- int index= fAutoClosableNodes.size();
- if (index < nodes.size()) {
- ASTNode toMove= source.createMoveTarget(nodes.get(index), nodes.get(nodes.size() - 1),
- index == 0 ? replacementNode : null, null);
- statements.insertLast(toMove, null);
- }
- if (index > 0) {
- source.replace(fAutoClosableNodes.get(0), replacementNode, null);
- for (int i= 1; i < index; ++i) {
- source.remove(fAutoClosableNodes.get(i), null);
- }
- }
- }
-
- }
-
- public static IMethodBinding findAutocloseMethod(ITypeBinding type) {
- while (type != null) {
- IMethodBinding[] methods= type.getDeclaredMethods();
- for (IMethodBinding method : methods) {
- if ("close".equals(method.getName()) && method.getParameterTypes().length == 0) { //$NON-NLS-1$
- return method;
- }
- }
- type= type.getSuperclass();
- }
- return null;
- }
-
- private int findEndPosition(ASTNode node) {
- int end= node.getStartPosition() + node.getLength();
- Map<SimpleName, IVariableBinding> nodeSimpleNameBindings= fAnalyzer.getVariableStatementBinding(node);
- List<SimpleName> nodeNames= new ArrayList<>(nodeSimpleNameBindings.keySet());
- if (nodeNames.isEmpty()) {
- return -1;
- }
- SimpleName nodeSimpleName= nodeNames.get(0);
- SimpleName[] coveredNodeBindings= LinkedNodeFinder.findByNode(node.getRoot(), nodeSimpleName);
- if (coveredNodeBindings.length == 0) {
- return -1;
- }
- for (ASTNode astNode : coveredNodeBindings) {
- end= Math.max(end, (astNode.getStartPosition() + astNode.getLength()));
- }
- return end;
- }
-
- // find all nodes (statements) that are within the start/end positions
- public static List<ASTNode> findNodesInRange(ASTNode astNode, final int start, final int end) {
- List<ASTNode> nodesInRange= new ArrayList<>();
- astNode.accept(new ASTVisitor() {
- int pre= start;
-
- @Override
- public void preVisit(ASTNode preNode) {
- pre= preNode.getStartPosition();
- super.preVisit(preNode);
- }
-
- @Override
- public void postVisit(ASTNode postNode) {
- int post= postNode.getStartPosition() + postNode.getLength();
- if (pre >= start && post <= end) {
- Statement statement= ASTResolving.findParentStatement(postNode);
- loop: while (statement != null) {
- if (statement.getParent() instanceof Statement) {
- Statement pStatement= (Statement) statement.getParent();
- switch (pStatement.getNodeType()) {
- case ASTNode.BLOCK:
- if (pStatement.getParent().getNodeType() != ASTNode.METHOD_DECLARATION &&
- pStatement.getParent().getNodeType() != ASTNode.TRY_STATEMENT) {
- statement= pStatement;
- continue;
- } else {
- break loop;
- }
- case ASTNode.METHOD_DECLARATION:
- break loop;
- default:
- break;
- }
- statement= pStatement;
- } else {
- break;
- }
- }
- if (statement != null && !nodesInRange.contains(statement)) {
- nodesInRange.add(statement);
- }
- }
- super.postVisit(postNode);
- }
- });
- return nodesInRange;
- }
-
- private List<ASTNode> getSpecialVariableDeclarationStatements() {
- List<ASTNode> result= new ArrayList<>(3);
- for (VariableDeclaration local : fAnalyzer.getAffectedLocals()) {
- ASTNode parent= local.getParent();
- if (parent instanceof VariableDeclarationStatement && !result.contains(parent))
- result.add(parent);
- }
- return result;
-
- }
-
- private Statement getCatchBody(String type, String name, String lineSeparator) throws CoreException {
- String s= StubUtility.getCatchBodyContent(fCUnit, type, name, fSelectedNodes[0], lineSeparator);
- if (s == null) {
- return null;
- } else {
- return (Statement)fRewriter.createStringPlaceholder(s, ASTNode.RETURN_STATEMENT);
- }
- }
-}
+}
\ No newline at end of file
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 04e35ef..dbd72e7 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
@@ -19,20 +19,18 @@
* Jeremie Bresson <dev@jmini.fr> - Bug 439912: [1.8][quick assist] Add quick assists to add and remove parentheses around single lambda parameter - https://bugs.eclipse.org/439912
* Jens Reimann <jens.reimann@ibh-systems.com>, Fabian Pfaff <fabian.pfaff@vogella.com> - Bug 197850: [quick assist] Add import static field/method - https://bugs.eclipse.org/bugs/show_bug.cgi?id=197850
* Pierre-Yves B. <pyvesdev@gmail.com> - [inline] Allow inlining of local variable initialized to null. - https://bugs.eclipse.org/93850
+ * Red Hat Inc. - refactor some static methods to QuickAssistProcessorUtil class in jdt.core.manipulation
*******************************************************************************/
package org.eclipse.jdt.internal.ui.text.correction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.Set;
import org.eclipse.swt.graphics.Image;
@@ -53,7 +51,6 @@
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaModelMarker;
import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
@@ -159,7 +156,6 @@
import org.eclipse.jdt.internal.corext.dom.JdtASTMatcher;
import org.eclipse.jdt.internal.corext.dom.LinkedNodeFinder;
import org.eclipse.jdt.internal.corext.dom.ModifierRewrite;
-import org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer;
import org.eclipse.jdt.internal.corext.dom.Selection;
import org.eclipse.jdt.internal.corext.dom.SelectionAnalyzer;
import org.eclipse.jdt.internal.corext.dom.TokenScanner;
@@ -185,7 +181,7 @@
import org.eclipse.jdt.internal.corext.refactoring.code.PromoteTempToFieldRefactoring;
import org.eclipse.jdt.internal.corext.refactoring.structure.ImportRemover;
import org.eclipse.jdt.internal.corext.refactoring.surround.SurroundWithTryWithResourcesAnalyzer;
-import org.eclipse.jdt.internal.corext.refactoring.surround.SurroundWithTryWithResourcesRefactoring;
+import org.eclipse.jdt.internal.corext.refactoring.surround.SurroundWithTryWithResourcesRefactoringCore;
import org.eclipse.jdt.internal.corext.refactoring.util.TightSourceRangeComputer;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.corext.util.Messages;
@@ -711,7 +707,7 @@
return false;
}
- IMethodBinding functionalMethod= getFunctionalMethodForMethodReference(methodReference);
+ IMethodBinding functionalMethod= QuickAssistProcessorUtil.getFunctionalMethodForMethodReference(methodReference);
if (functionalMethod == null || functionalMethod.isGenericMethod()) { // generic lambda expressions are not allowed
return false;
}
@@ -722,7 +718,7 @@
ASTRewrite rewrite= ASTRewrite.create(methodReference.getAST());
LinkedProposalModel linkedProposalModel= new LinkedProposalModel();
- LambdaExpression lambda= convertMethodRefernceToLambda(methodReference, functionalMethod, context.getASTRoot(), rewrite, linkedProposalModel, false);
+ LambdaExpression lambda= QuickAssistProcessorUtil.convertMethodRefernceToLambda(methodReference, functionalMethod, context.getASTRoot(), rewrite, linkedProposalModel, false);
// add proposal
String label= CorrectionMessages.QuickAssistProcessor_convert_to_lambda_expression;
@@ -772,297 +768,6 @@
return true;
}
- /**
- * Returns the functional interface method being implemented by the given method reference.
- *
- * @param methodReference the method reference to get the functional method
- * @return the functional interface method being implemented by <code>methodReference</code> or
- * <code>null</code> if it could not be derived
- */
- public static IMethodBinding getFunctionalMethodForMethodReference(MethodReference methodReference) {
- ITypeBinding targetTypeBinding= ASTNodes.getTargetType(methodReference);
- if (targetTypeBinding == null)
- return null;
-
- IMethodBinding functionalMethod= targetTypeBinding.getFunctionalInterfaceMethod();
- if (functionalMethod != null && functionalMethod.isSynthetic()) {
- functionalMethod= Bindings.findOverriddenMethodInType(functionalMethod.getDeclaringClass(), functionalMethod);
- }
- return functionalMethod;
- }
-
- /**
- * Converts and replaces the given method reference with corresponding lambda expression in the
- * given ASTRewrite.
- *
- * @param methodReference the method reference to convert
- * @param functionalMethod the non-generic functional interface method to be implemented by the
- * lambda expression
- * @param astRoot the AST root
- * @param rewrite the ASTRewrite
- * @param linkedProposalModel to create linked proposals for lambda's parameters or
- * <code>null</code> if linked proposals are not required
- * @param createBlockBody <code>true</code> if lambda expression's body should be a block
- *
- * @return lambda expression used to replace the method reference in the given ASTRewrite
- * @throws JavaModelException if an exception occurs while accessing the Java element
- * corresponding to the <code>functionalMethod</code>
- */
- public static LambdaExpression convertMethodRefernceToLambda(MethodReference methodReference, IMethodBinding functionalMethod, CompilationUnit astRoot,
- ASTRewrite rewrite, LinkedProposalModel linkedProposalModel, boolean createBlockBody) throws JavaModelException {
-
- AST ast= astRoot.getAST();
- LambdaExpression lambda= ast.newLambdaExpression();
-
- String[] lambdaParamNames= getUniqueParameterNames(methodReference, functionalMethod);
- List<VariableDeclaration> lambdaParameters= lambda.parameters();
- for (int i= 0; i < lambdaParamNames.length; i++) {
- String paramName= lambdaParamNames[i];
- VariableDeclarationFragment lambdaParameter= ast.newVariableDeclarationFragment();
- SimpleName name= ast.newSimpleName(paramName);
- lambdaParameter.setName(name);
- lambdaParameters.add(lambdaParameter);
- if (linkedProposalModel != null) {
- linkedProposalModel.getPositionGroup(name.getIdentifier(), true).addPosition(rewrite.track(name), i == 0);
- }
- }
-
- int noOfLambdaParameters= lambdaParamNames.length;
- lambda.setParentheses(noOfLambdaParameters != 1);
-
- ITypeBinding returnTypeBinding= functionalMethod.getReturnType();
- IMethodBinding referredMethodBinding= methodReference.resolveMethodBinding(); // too often null, see bug 440000, bug 440344, bug 333665
-
- if (methodReference instanceof CreationReference) {
- CreationReference creationRef= (CreationReference) methodReference;
- Type type= creationRef.getType();
- if (type instanceof ArrayType) {
- ArrayCreation arrayCreation= ast.newArrayCreation();
- if (createBlockBody) {
- Block blockBody= getBlockBodyForLambda(arrayCreation, returnTypeBinding, ast);
- lambda.setBody(blockBody);
- } else {
- lambda.setBody(arrayCreation);
- }
-
- ArrayType arrayType= (ArrayType) type;
- Type copiedElementType= (Type) rewrite.createCopyTarget(arrayType.getElementType());
- arrayCreation.setType(ast.newArrayType(copiedElementType, arrayType.getDimensions()));
- SimpleName name= ast.newSimpleName(lambdaParamNames[0]);
- arrayCreation.dimensions().add(name);
- if (linkedProposalModel != null) {
- linkedProposalModel.getPositionGroup(name.getIdentifier(), false).addPosition(rewrite.track(name), LinkedPositionGroup.NO_STOP);
- }
- } else {
- ClassInstanceCreation cic= ast.newClassInstanceCreation();
- if (createBlockBody) {
- Block blockBody= getBlockBodyForLambda(cic, returnTypeBinding, ast);
- lambda.setBody(blockBody);
- } else {
- lambda.setBody(cic);
- }
-
- ITypeBinding typeBinding= type.resolveBinding();
- if (!(type instanceof ParameterizedType) && typeBinding != null && typeBinding.getTypeDeclaration().isGenericType()) {
- cic.setType(ast.newParameterizedType((Type) rewrite.createCopyTarget(type)));
- } else {
- cic.setType((Type) rewrite.createCopyTarget(type));
- }
- List<SimpleName> invocationArgs= getInvocationArguments(ast, 0, noOfLambdaParameters, lambdaParamNames);
- cic.arguments().addAll(invocationArgs);
- if (linkedProposalModel != null) {
- for (SimpleName name : invocationArgs) {
- linkedProposalModel.getPositionGroup(name.getIdentifier(), false).addPosition(rewrite.track(name), LinkedPositionGroup.NO_STOP);
- }
- }
- cic.typeArguments().addAll(getCopiedTypeArguments(rewrite, methodReference.typeArguments()));
- }
-
- } else if (referredMethodBinding != null && Modifier.isStatic(referredMethodBinding.getModifiers())) {
- MethodInvocation methodInvocation= ast.newMethodInvocation();
- if (createBlockBody) {
- Block blockBody= getBlockBodyForLambda(methodInvocation, returnTypeBinding, ast);
- lambda.setBody(blockBody);
- } else {
- lambda.setBody(methodInvocation);
- }
-
- Expression expr= null;
- boolean hasConflict= hasConflict(methodReference.getStartPosition(), referredMethodBinding, ScopeAnalyzer.METHODS | ScopeAnalyzer.CHECK_VISIBILITY, astRoot);
- if (hasConflict || !Bindings.isSuperType(referredMethodBinding.getDeclaringClass(), ASTNodes.getEnclosingType(methodReference)) || methodReference.typeArguments().size() != 0) {
- if (methodReference instanceof ExpressionMethodReference) {
- ExpressionMethodReference expressionMethodReference= (ExpressionMethodReference) methodReference;
- expr= (Expression) rewrite.createCopyTarget(expressionMethodReference.getExpression());
- } else if (methodReference instanceof TypeMethodReference) {
- Type type= ((TypeMethodReference) methodReference).getType();
- ITypeBinding typeBinding= type.resolveBinding();
- if (typeBinding != null) {
- ImportRewrite importRewrite= StubUtility.createImportRewrite(astRoot, true);
- expr= ast.newName(importRewrite.addImport(typeBinding));
- }
- }
- }
- methodInvocation.setExpression(expr);
- SimpleName methodName= getMethodInvocationName(methodReference);
- methodInvocation.setName((SimpleName) rewrite.createCopyTarget(methodName));
- List<SimpleName> invocationArgs= getInvocationArguments(ast, 0, noOfLambdaParameters, lambdaParamNames);
- methodInvocation.arguments().addAll(invocationArgs);
- if (linkedProposalModel != null) {
- for (SimpleName name : invocationArgs) {
- linkedProposalModel.getPositionGroup(name.getIdentifier(), false).addPosition(rewrite.track(name), LinkedPositionGroup.NO_STOP);
- }
- }
- methodInvocation.typeArguments().addAll(getCopiedTypeArguments(rewrite, methodReference.typeArguments()));
-
- } else if (methodReference instanceof SuperMethodReference) {
- SuperMethodInvocation superMethodInvocation= ast.newSuperMethodInvocation();
- if (createBlockBody) {
- Block blockBody= getBlockBodyForLambda(superMethodInvocation, returnTypeBinding, ast);
- lambda.setBody(blockBody);
- } else {
- lambda.setBody(superMethodInvocation);
- }
-
- Name superQualifier= ((SuperMethodReference) methodReference).getQualifier();
- if (superQualifier != null) {
- superMethodInvocation.setQualifier((Name) rewrite.createCopyTarget(superQualifier));
- }
- SimpleName methodName= getMethodInvocationName(methodReference);
- superMethodInvocation.setName((SimpleName) rewrite.createCopyTarget(methodName));
- List<SimpleName> invocationArgs= getInvocationArguments(ast, 0, noOfLambdaParameters, lambdaParamNames);
- superMethodInvocation.arguments().addAll(invocationArgs);
- if (linkedProposalModel != null) {
- for (SimpleName name : invocationArgs) {
- linkedProposalModel.getPositionGroup(name.getIdentifier(), false).addPosition(rewrite.track(name), LinkedPositionGroup.NO_STOP);
- }
- }
- superMethodInvocation.typeArguments().addAll(getCopiedTypeArguments(rewrite, methodReference.typeArguments()));
-
- } else {
- MethodInvocation methodInvocation= ast.newMethodInvocation();
- if (createBlockBody) {
- Block blockBody= getBlockBodyForLambda(methodInvocation, returnTypeBinding, ast);
- lambda.setBody(blockBody);
- } else {
- lambda.setBody(methodInvocation);
- }
-
- boolean isTypeReference= isTypeReferenceToInstanceMethod(methodReference);
- if (isTypeReference) {
- SimpleName name= ast.newSimpleName(lambdaParamNames[0]);
- methodInvocation.setExpression(name);
- if (linkedProposalModel != null) {
- linkedProposalModel.getPositionGroup(name.getIdentifier(), false).addPosition(rewrite.track(name), LinkedPositionGroup.NO_STOP);
- }
- } else {
- Expression expr= ((ExpressionMethodReference) methodReference).getExpression();
- if (!(expr instanceof ThisExpression) || (methodReference.typeArguments().size() != 0)) {
- methodInvocation.setExpression((Expression) rewrite.createCopyTarget(expr));
- }
- }
- SimpleName methodName= getMethodInvocationName(methodReference);
- methodInvocation.setName((SimpleName) rewrite.createCopyTarget(methodName));
- List<SimpleName> invocationArgs= getInvocationArguments(ast, isTypeReference ? 1 : 0, noOfLambdaParameters, lambdaParamNames);
- methodInvocation.arguments().addAll(invocationArgs);
- if (linkedProposalModel != null) {
- for (SimpleName name : invocationArgs) {
- linkedProposalModel.getPositionGroup(name.getIdentifier(), false).addPosition(rewrite.track(name), LinkedPositionGroup.NO_STOP);
- }
- }
- methodInvocation.typeArguments().addAll(getCopiedTypeArguments(rewrite, methodReference.typeArguments()));
- }
-
- rewrite.replace(methodReference, lambda, null);
- return lambda;
- }
-
- private static boolean hasConflict(int startPosition, IMethodBinding referredMethodBinding, int flags, CompilationUnit cu) {
- ScopeAnalyzer analyzer= new ScopeAnalyzer(cu);
- for (IBinding decl : analyzer.getDeclarationsInScope(startPosition, flags)) {
- if (decl.getName().equals(referredMethodBinding.getName()) && !referredMethodBinding.getMethodDeclaration().isEqualTo(decl))
- return true;
- }
- return false;
- }
-
- private static String[] getUniqueParameterNames(MethodReference methodReference, IMethodBinding functionalMethod) throws JavaModelException {
- String[] originalParameterNames= ((IMethod) functionalMethod.getJavaElement()).getParameterNames();
- String[] newNames= new String[originalParameterNames.length];
- Set<String> excludedNames= new HashSet<>(ASTNodes.getVisibleLocalVariablesInScope(methodReference));
-
- for (int i= 0; i < originalParameterNames.length; i++) {
- String paramName= originalParameterNames[i];
-
- if (excludedNames.contains(paramName)) {
- Set<String> allNamesToExclude= new HashSet<>(excludedNames);
- Collections.addAll(allNamesToExclude, originalParameterNames);
-
- String newParamName= createName(paramName, allNamesToExclude);
-
- excludedNames.add(newParamName);
- newNames[i]= newParamName;
- } else {
- newNames[i]= paramName;
- }
- }
-
- return newNames;
- }
-
- private static String createName(final String nameRoot, final Set<String> excludedNames) {
- int i= 1;
- String candidate;
-
- do {
- candidate= nameRoot + i++;
- } while (excludedNames.remove(candidate));
-
- return candidate;
- }
-
- private static boolean isTypeReferenceToInstanceMethod(MethodReference methodReference) {
- if (methodReference instanceof TypeMethodReference)
- return true;
- if (methodReference instanceof ExpressionMethodReference) {
- Expression expression= ((ExpressionMethodReference) methodReference).getExpression();
- if (expression instanceof Name) {
- IBinding nameBinding= ((Name) expression).resolveBinding();
- if (nameBinding instanceof ITypeBinding) {
- return true;
- }
- }
- }
- return false;
- }
-
- private static List<SimpleName> getInvocationArguments(AST ast, int begIndex, int noOfLambdaParameters, String[] lambdaParamNames) {
- List<SimpleName> args= new ArrayList<>();
- for (int i= begIndex; i < noOfLambdaParameters; i++) {
- args.add(ast.newSimpleName(lambdaParamNames[i]));
- }
- return args;
- }
-
- private static List<Type> getCopiedTypeArguments(ASTRewrite rewrite, List<Type> typeArguments) {
- List<Type> copiedTypeArgs= new ArrayList<>();
- for (Type typeArg : typeArguments) {
- copiedTypeArgs.add((Type) rewrite.createCopyTarget(typeArg));
- }
- return copiedTypeArgs;
- }
-
- private static SimpleName getMethodInvocationName(MethodReference methodReference) {
- SimpleName name= null;
- if (methodReference instanceof ExpressionMethodReference) {
- name= ((ExpressionMethodReference) methodReference).getName();
- } else if (methodReference instanceof TypeMethodReference) {
- name= ((TypeMethodReference) methodReference).getName();
- } else if (methodReference instanceof SuperMethodReference) {
- name= ((SuperMethodReference) methodReference).getName();
- }
- return name;
- }
-
private static boolean getChangeLambdaBodyToBlockProposal(IInvocationContext context, ASTNode covering, Collection<ICommandAccess> resultingCollections) {
LambdaExpression lambda;
if (covering instanceof LambdaExpression) {
@@ -1084,7 +789,7 @@
AST ast= lambda.getAST();
ASTRewrite rewrite= ASTRewrite.create(ast);
- changeLambdaBodyToBlock(lambda, ast, rewrite);
+ QuickAssistProcessorUtil.changeLambdaBodyToBlock(lambda, ast, rewrite);
// add proposal
String label= CorrectionMessages.QuickAssistProcessor_change_lambda_body_to_block;
@@ -1094,36 +799,6 @@
return true;
}
- /**
- * Changes the expression body of the given lambda expression to block form.
- * {@link LambdaExpression#resolveMethodBinding()} should not be <code>null</code> for the given
- * lambda expression.
- *
- * @param lambda the lambda expression to convert the body form
- * @param ast the AST to create new nodes
- * @param rewrite the ASTRewrite
- */
- public static void changeLambdaBodyToBlock(LambdaExpression lambda, AST ast, ASTRewrite rewrite) {
- Expression bodyExpr= (Expression) rewrite.createMoveTarget(lambda.getBody());
- Block blockBody= getBlockBodyForLambda(bodyExpr, lambda.resolveMethodBinding().getReturnType(), ast);
- rewrite.set(lambda, LambdaExpression.BODY_PROPERTY, blockBody, null);
- }
-
- private static Block getBlockBodyForLambda(Expression bodyExpr, ITypeBinding returnTypeBinding, AST ast) {
- Statement statementInBlockBody;
- if (ast.resolveWellKnownType("void").isEqualTo(returnTypeBinding)) { //$NON-NLS-1$
- ExpressionStatement expressionStatement= ast.newExpressionStatement(bodyExpr);
- statementInBlockBody= expressionStatement;
- } else {
- ReturnStatement returnStatement= ast.newReturnStatement();
- returnStatement.setExpression(bodyExpr);
- statementInBlockBody= returnStatement;
- }
- Block blockBody= ast.newBlock();
- blockBody.statements().add(statementInBlockBody);
- return blockBody;
- }
-
private static boolean getChangeLambdaBodyToExpressionProposal(IInvocationContext context, ASTNode covering, Collection<ICommandAccess> resultingCollections) {
LambdaExpression lambda;
if (covering instanceof LambdaExpression) {
@@ -1299,7 +974,7 @@
type= ((ParameterizedType) type).getType();
}
creationReference.setType((Type) rewrite.createCopyTarget(type));
- creationReference.typeArguments().addAll(getCopiedTypeArguments(rewrite, cic.typeArguments()));
+ creationReference.typeArguments().addAll(QuickAssistProcessorUtil.getCopiedTypeArguments(rewrite, cic.typeArguments()));
} else if (exprBody instanceof ArrayCreation) {
CreationReference creationReference= ast.newCreationReference();
replacement= creationReference;
@@ -1320,7 +995,7 @@
importRewrite= StubUtility.createImportRewrite(context.getASTRoot(), true);
ITypeBinding invocationTypeBinding= ASTNodes.getInvocationType(superMethodInvocation, methodBinding, superQualifier);
typeMethodReference.setType(importRewrite.addImport(invocationTypeBinding.getTypeDeclaration(), ast));
- typeMethodReference.typeArguments().addAll(getCopiedTypeArguments(rewrite, superMethodInvocation.typeArguments()));
+ typeMethodReference.typeArguments().addAll(QuickAssistProcessorUtil.getCopiedTypeArguments(rewrite, superMethodInvocation.typeArguments()));
} else {
SuperMethodReference superMethodReference= ast.newSuperMethodReference();
replacement= superMethodReference;
@@ -1329,7 +1004,7 @@
superMethodReference.setQualifier((Name) rewrite.createCopyTarget(superQualifier));
}
superMethodReference.setName((SimpleName) rewrite.createCopyTarget(superMethodInvocation.getName()));
- superMethodReference.typeArguments().addAll(getCopiedTypeArguments(rewrite, superMethodInvocation.typeArguments()));
+ superMethodReference.typeArguments().addAll(QuickAssistProcessorUtil.getCopiedTypeArguments(rewrite, superMethodInvocation.typeArguments()));
}
} else { // MethodInvocation
MethodInvocation methodInvocation= (MethodInvocation) exprBody;
@@ -1349,7 +1024,7 @@
invocationTypeBinding= StubUtility2Core.replaceWildcardsAndCaptures(invocationTypeBinding);
ImportRewriteContext importRewriteContext= new ContextSensitiveImportRewriteContext(lambda, importRewrite);
typeMethodReference.setType(importRewrite.addImport(invocationTypeBinding, ast, importRewriteContext, TypeLocation.OTHER));
- typeMethodReference.typeArguments().addAll(getCopiedTypeArguments(rewrite, methodInvocation.typeArguments()));
+ typeMethodReference.typeArguments().addAll(QuickAssistProcessorUtil.getCopiedTypeArguments(rewrite, methodInvocation.typeArguments()));
} else {
ExpressionMethodReference exprMethodReference= ast.newExpressionMethodReference();
@@ -1393,7 +1068,7 @@
}
exprMethodReference.setExpression(newThisExpression);
}
- exprMethodReference.typeArguments().addAll(getCopiedTypeArguments(rewrite, methodInvocation.typeArguments()));
+ exprMethodReference.typeArguments().addAll(QuickAssistProcessorUtil.getCopiedTypeArguments(rewrite, methodInvocation.typeArguments()));
}
}
@@ -1876,7 +1551,7 @@
boolean addStaticModifier= false;
TypeDeclaration typeDeclaration= ASTNodes.getParent(methodReferenceNode, TypeDeclaration.class);
- if (isTypeReferenceToInstanceMethod(methodReferenceNode)) {
+ if (QuickAssistProcessorUtil.isTypeReferenceToInstanceMethod(methodReferenceNode)) {
String methodReferenceQualifiedName= ((Name) methodReferenceNode.getExpression()).getFullyQualifiedName();
String typeDeclarationName= astRoot.getPackage().getName().getFullyQualifiedName() + '.' + typeDeclaration.getName().getFullyQualifiedName();
if (!methodReferenceQualifiedName.equals(typeDeclarationName)
@@ -3418,7 +3093,7 @@
}
// recursive loop to find all nodes affected by wrapping in try block
- List<ASTNode> nodesInRange= SurroundWithTryWithResourcesRefactoring.findNodesInRange(parentBodyDeclaration, start, end);
+ List<ASTNode> nodesInRange= SurroundWithTryWithResourcesRefactoringCore.findNodesInRange(parentBodyDeclaration, start, end);
int oldEnd= end;
while (true) {
int newEnd= oldEnd;
@@ -3428,7 +3103,7 @@
}
if (newEnd > oldEnd) {
oldEnd= newEnd;
- nodesInRange= SurroundWithTryWithResourcesRefactoring.findNodesInRange(parentBodyDeclaration, start, newEnd);
+ nodesInRange= SurroundWithTryWithResourcesRefactoringCore.findNodesInRange(parentBodyDeclaration, start, newEnd);
continue;
}
break;
@@ -3478,7 +3153,7 @@
Type type= vds.getType();
ITypeBinding typeBinding= type.resolveBinding();
if (typeBinding != null) {
- IMethodBinding close= SurroundWithTryWithResourcesRefactoring.findAutocloseMethod(typeBinding);
+ IMethodBinding close= SurroundWithTryWithResourcesRefactoringCore.findAutocloseMethod(typeBinding);
if (close != null) {
for (ITypeBinding exceptionType : close.getExceptionTypes()) {
if (!allExceptions.contains(exceptionType)) {
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/proposals/AssignToVariableAssistProposal.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/proposals/AssignToVariableAssistProposal.java
index 0e4ed20..b8a3148 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/proposals/AssignToVariableAssistProposal.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/proposals/AssignToVariableAssistProposal.java
@@ -86,7 +86,7 @@
import org.eclipse.jdt.internal.corext.fix.LinkedProposalModel;
import org.eclipse.jdt.internal.corext.refactoring.surround.ExceptionAnalyzer;
import org.eclipse.jdt.internal.corext.refactoring.surround.SurroundWithTryWithResourcesAnalyzer;
-import org.eclipse.jdt.internal.corext.refactoring.surround.SurroundWithTryWithResourcesRefactoring;
+import org.eclipse.jdt.internal.corext.refactoring.surround.SurroundWithTryWithResourcesRefactoringCore;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.corext.util.Messages;
@@ -291,7 +291,7 @@
List<ITypeBinding> mustRethrowList= new ArrayList<>();
if (fTypeBinding != null) {
- IMethodBinding close= SurroundWithTryWithResourcesRefactoring.findAutocloseMethod(fTypeBinding);
+ IMethodBinding close= SurroundWithTryWithResourcesRefactoringCore.findAutocloseMethod(fTypeBinding);
if (close != null) {
for (ITypeBinding exceptionType : close.getExceptionTypes()) {
if (!allExceptions.contains(exceptionType)) {