use of org.eclipse.jdt.core.dom.MethodReference in project eclipse.jdt.ls by eclipse.
the class ExceptionAnalyzer method perform.
public static ITypeBinding[] perform(ASTNode enclosingNode, Selection selection) {
ExceptionAnalyzer analyzer = new ExceptionAnalyzer(enclosingNode, selection);
enclosingNode.accept(analyzer);
List<ITypeBinding> exceptions = analyzer.getCurrentExceptions();
if (enclosingNode.getNodeType() == ASTNode.METHOD_DECLARATION) {
List<Type> thrownExceptions = ((MethodDeclaration) enclosingNode).thrownExceptionTypes();
for (Iterator<Type> thrown = thrownExceptions.iterator(); thrown.hasNext(); ) {
ITypeBinding thrownException = thrown.next().resolveBinding();
if (thrownException != null) {
updateExceptionsList(exceptions, thrownException);
}
}
} else {
ITypeBinding typeBinding = null;
if (enclosingNode.getLocationInParent() == LambdaExpression.BODY_PROPERTY) {
typeBinding = ((LambdaExpression) enclosingNode.getParent()).resolveTypeBinding();
} else if (enclosingNode instanceof MethodReference) {
typeBinding = ((MethodReference) enclosingNode).resolveTypeBinding();
}
if (typeBinding != null) {
IMethodBinding methodBinding = typeBinding.getFunctionalInterfaceMethod();
if (methodBinding != null) {
for (ITypeBinding thrownException : methodBinding.getExceptionTypes()) {
updateExceptionsList(exceptions, thrownException);
}
}
}
}
Collections.sort(exceptions, new ExceptionComparator());
return exceptions.toArray(new ITypeBinding[exceptions.size()]);
}
use of org.eclipse.jdt.core.dom.MethodReference in project eclipse.jdt.ls by eclipse.
the class SurroundWithAnalyzer method validSelectedNodes.
private boolean validSelectedNodes() {
ASTNode[] nodes = getSelectedNodes();
for (int i = 0; i < nodes.length; i++) {
ASTNode node = nodes[i];
boolean isValidNode = node instanceof Statement;
if (fSurroundWithTryCatch) {
// allow method reference and lambda's expression body also
isValidNode = isValidNode || node instanceof MethodReference || node.getLocationInParent() == LambdaExpression.BODY_PROPERTY;
}
if (!isValidNode) {
return false;
}
}
return true;
}
use of org.eclipse.jdt.core.dom.MethodReference in project eclipse.jdt.ls by eclipse.
the class SurroundWithTryCatchRefactoring method createTryCatchStatement.
private void createTryCatchStatement(org.eclipse.jdt.core.IBuffer buffer, String lineDelimiter) throws CoreException {
List<Statement> result = new ArrayList<>(1);
TryStatement tryStatement = getAST().newTryStatement();
ITypeBinding[] exceptions = fAnalyzer.getExceptions();
ImportRewriteContext context = new ContextSensitiveImportRewriteContext(fAnalyzer.getEnclosingBodyDeclaration(), fImportRewrite);
if (!fIsMultiCatch) {
for (int i = 0; i < exceptions.length; i++) {
ITypeBinding exception = exceptions[i];
CatchClause catchClause = getAST().newCatchClause();
tryStatement.catchClauses().add(catchClause);
SingleVariableDeclaration decl = getAST().newSingleVariableDeclaration();
String varName = StubUtility.getExceptionVariableName(fCUnit.getJavaProject());
String name = fScope.createName(varName, false);
decl.setName(getAST().newSimpleName(name));
Type type = fImportRewrite.addImport(exception, getAST(), context, TypeLocation.EXCEPTION);
decl.setType(type);
catchClause.setException(decl);
Statement st = getCatchBody(ASTNodes.getQualifiedTypeName(type), name, lineDelimiter);
if (st != null) {
catchClause.getBody().statements().add(st);
}
fLinkedProposalModel.getPositionGroup(GROUP_EXC_TYPE + i, true).addPosition(fRewriter.track(decl.getType()), i == 0);
fLinkedProposalModel.getPositionGroup(GROUP_EXC_NAME + i, true).addPosition(fRewriter.track(decl.getName()), false);
}
} else {
List<ITypeBinding> filteredExceptions = filterSubtypeExceptions(exceptions);
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));
UnionType unionType = getAST().newUnionType();
List<Type> types = unionType.types();
int i = 0;
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);
// $NON-NLS-1$
Statement st = getCatchBody("Exception", name, lineDelimiter);
if (st != null) {
catchClause.getBody().statements().add(st);
}
tryStatement.catchClauses().add(catchClause);
}
List<ASTNode> variableDeclarations = getSpecialVariableDeclarationStatements();
ListRewrite statements = fRewriter.getListRewrite(tryStatement.getBody(), Block.STATEMENTS_PROPERTY);
boolean selectedNodeRemoved = false;
ASTNode expressionStatement = null;
for (int i = 0; i < fSelectedNodes.length; i++) {
ASTNode node = fSelectedNodes[i];
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 (Iterator<VariableDeclarationFragment> iter = fragments.iterator(); iter.hasNext(); ) {
VariableDeclarationFragment fragment = iter.next();
fragment.setInitializer(null);
}
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 (Iterator<VariableDeclarationFragment> iter = fragments.iterator(); iter.hasNext(); ) {
VariableDeclarationFragment fragment = iter.next();
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);
ASTNode replacementNode;
if (result.size() == 1) {
replacementNode = result.get(0);
} else {
replacementNode = fRewriter.createGroupNode(result.toArray(new ASTNode[result.size()]));
}
if (fSelectedNodes.length == 1) {
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 {
ListRewrite source = fRewriter.getListRewrite(fSelectedNodes[0].getParent(), (ChildListPropertyDescriptor) fSelectedNodes[0].getLocationInParent());
ASTNode toMove = source.createMoveTarget(fSelectedNodes[0], fSelectedNodes[fSelectedNodes.length - 1], replacementNode, null);
statements.insertLast(toMove, null);
}
}
use of org.eclipse.jdt.core.dom.MethodReference in project AutoRefactor by JnRouvignac.
the class ObsoleteRedundantComparatorCleanUp method maybeRefactorTypedCode.
private boolean maybeRefactorTypedCode(final MethodInvocation visitedIfRefactoringNeeded, final Expression list, final Expression comparatorToRemove, final Expression comparatorToAnalyze, final ITypeBinding[] typeArguments, final boolean isForward, final Set<String> classesToUseWithImport, final Set<String> importsToAdd) {
NullLiteral nullLiteral = ASTNodes.as(comparatorToAnalyze, NullLiteral.class);
if (nullLiteral != null) {
return maybeRemoveComparator(visitedIfRefactoringNeeded, list, comparatorToRemove, isForward, classesToUseWithImport, importsToAdd);
}
ClassInstanceCreation classInstanceCreation = ASTNodes.as(comparatorToAnalyze, ClassInstanceCreation.class);
if (classInstanceCreation != null && isClassToRemove(classInstanceCreation, isForward)) {
return maybeRemoveComparator(visitedIfRefactoringNeeded, list, comparatorToRemove, true, classesToUseWithImport, importsToAdd);
}
MethodReference methodReference = ASTNodes.as(comparatorToAnalyze, MethodReference.class);
LambdaExpression lambdaExpression = ASTNodes.as(comparatorToAnalyze, LambdaExpression.class);
MethodInvocation methodInvocation = ASTNodes.as(comparatorToAnalyze, MethodInvocation.class);
if (methodReference != null) {
String elementClass = typeArguments[0].isWildcardType() ? Comparable.class.getCanonicalName() : typeArguments[0].getQualifiedName();
if (// $NON-NLS-1$
ASTNodes.usesGivenSignature(// $NON-NLS-1$
methodReference.resolveMethodBinding(), // $NON-NLS-1$
elementClass, // $NON-NLS-1$
"compareTo", Object.class.getCanonicalName())) {
return maybeRemoveComparator(visitedIfRefactoringNeeded, list, comparatorToRemove, isForward, classesToUseWithImport, importsToAdd);
}
} else if (methodInvocation != null) {
if (// $NON-NLS-1$
ASTNodes.usesGivenSignature(methodInvocation, Comparator.class.getCanonicalName(), "reversed") && methodInvocation.getExpression() != null) {
return maybeRefactorTypedCode(visitedIfRefactoringNeeded, list, comparatorToRemove, methodInvocation.getExpression(), typeArguments, !isForward, classesToUseWithImport, importsToAdd);
}
if (ASTNodes.usesGivenSignature(methodInvocation, Comparator.class.getCanonicalName(), "naturalOrder")) {
// $NON-NLS-1$
return maybeRemoveComparator(visitedIfRefactoringNeeded, list, comparatorToRemove, isForward, classesToUseWithImport, importsToAdd);
}
if (// $NON-NLS-1$
"comparing".equals(methodInvocation.getName().getIdentifier()) && methodInvocation.resolveMethodBinding() != null && methodInvocation.resolveMethodBinding().getParameterTypes().length == 1 && ASTNodes.hasType(methodInvocation.resolveMethodBinding().getDeclaringClass(), Comparator.class.getCanonicalName()) && ASTNodes.hasType(methodInvocation.resolveMethodBinding().getParameterTypes()[0], Function.class.getCanonicalName())) {
List<Expression> comparingMethodArgs = methodInvocation.arguments();
Expression criteria = comparingMethodArgs.get(0);
LambdaExpression comparingMethodLambdaExpression = ASTNodes.as(criteria, LambdaExpression.class);
MethodInvocation identityMethod = ASTNodes.as(criteria, MethodInvocation.class);
if (comparingMethodLambdaExpression != null) {
if (comparingMethodLambdaExpression.parameters().size() == 1) {
List<VariableDeclaration> parameters = comparingMethodLambdaExpression.parameters();
SimpleName variable = parameters.get(0).getName();
Expression bodyExpression = null;
if (comparingMethodLambdaExpression.getBody() instanceof Block) {
ReturnStatement returnStatement = ASTNodes.as((Block) comparingMethodLambdaExpression.getBody(), ReturnStatement.class);
if (returnStatement == null) {
return true;
}
bodyExpression = returnStatement.getExpression();
} else if (comparingMethodLambdaExpression.getBody() instanceof Expression) {
bodyExpression = (Expression) comparingMethodLambdaExpression.getBody();
} else {
return true;
}
if (ASTNodes.areSameVariables(variable, bodyExpression)) {
return maybeRemoveComparator(visitedIfRefactoringNeeded, list, comparatorToRemove, isForward, classesToUseWithImport, importsToAdd);
}
}
} else if (identityMethod != null && // $NON-NLS-1$
"identity".equals(identityMethod.getName().getIdentifier()) && identityMethod.resolveMethodBinding() != null && identityMethod.resolveMethodBinding().getParameterTypes().length == 0 && ASTNodes.hasType(identityMethod.resolveMethodBinding().getDeclaringClass(), Function.class.getCanonicalName())) {
return maybeRemoveComparator(visitedIfRefactoringNeeded, list, comparatorToRemove, isForward, classesToUseWithImport, importsToAdd);
}
}
} else if (lambdaExpression != null) {
if (lambdaExpression.parameters().size() == 2) {
List<ASTNode> parameters = lambdaExpression.parameters();
ASTNode parameter1 = parameters.get(0);
ASTNode parameter2 = parameters.get(1);
SimpleName variable1;
if (parameter1 instanceof SingleVariableDeclaration) {
variable1 = ((SingleVariableDeclaration) parameter1).getName();
} else if (parameter1 instanceof VariableDeclarationFragment) {
variable1 = ((VariableDeclarationFragment) parameter1).getName();
} else {
return true;
}
SimpleName variable2;
if (parameter2 instanceof SingleVariableDeclaration) {
variable2 = ((SingleVariableDeclaration) parameter2).getName();
} else if (parameter2 instanceof VariableDeclarationFragment) {
variable2 = ((VariableDeclarationFragment) parameter2).getName();
} else {
return true;
}
Expression bodyExpression = null;
if (lambdaExpression.getBody() instanceof Block) {
ReturnStatement returnStatement = ASTNodes.as((Block) lambdaExpression.getBody(), ReturnStatement.class);
if (returnStatement == null) {
return true;
}
bodyExpression = returnStatement.getExpression();
} else if (lambdaExpression.getBody() instanceof Expression) {
bodyExpression = (Expression) lambdaExpression.getBody();
} else {
return true;
}
if (isReturnedExpressionToRemove(variable1, variable2, bodyExpression, isForward)) {
return maybeRemoveComparator(visitedIfRefactoringNeeded, list, comparatorToRemove, true, classesToUseWithImport, importsToAdd);
}
}
}
return true;
}
use of org.eclipse.jdt.core.dom.MethodReference in project eclipse.jdt.ls by eclipse.
the class LocalCorrectionsSubProcessor method addUncaughtExceptionProposals.
public static void addUncaughtExceptionProposals(IInvocationContext context, IProblemLocation problem, Collection<CUCorrectionProposal> proposals) throws CoreException {
ICompilationUnit cu = context.getCompilationUnit();
CompilationUnit astRoot = context.getASTRoot();
ASTNode selectedNode = problem.getCoveringNode(astRoot);
if (selectedNode == null) {
return;
}
while (selectedNode != null && !(selectedNode instanceof Statement) && !(selectedNode instanceof VariableDeclarationExpression) && !(selectedNode.getLocationInParent() == LambdaExpression.BODY_PROPERTY) && !(selectedNode instanceof MethodReference)) {
selectedNode = selectedNode.getParent();
}
if (selectedNode == null) {
return;
}
int offset = selectedNode.getStartPosition();
int length = selectedNode.getLength();
int selectionEnd = context.getSelectionOffset() + context.getSelectionLength();
if (selectionEnd > offset + length) {
// extend the selection if more than one statement is selected (bug 72149)
length = selectionEnd - offset;
}
// Surround with proposals
SurroundWithTryCatchRefactoring refactoring = SurroundWithTryCatchRefactoring.create(cu, offset, length);
if (refactoring == null) {
return;
}
refactoring.setLeaveDirty(true);
if (refactoring.checkActivationBasics(astRoot).isOK()) {
String label = CorrectionMessages.LocalCorrectionsSubProcessor_surroundwith_trycatch_description;
RefactoringCorrectionProposal proposal = new RefactoringCorrectionProposal(label, cu, refactoring, IProposalRelevance.SURROUND_WITH_TRY_CATCH);
proposal.setLinkedProposalModel(refactoring.getLinkedProposalModel());
proposals.add(proposal);
}
if (JavaModelUtil.is17OrHigher(cu.getJavaProject())) {
refactoring = SurroundWithTryCatchRefactoring.create(cu, offset, length, true);
if (refactoring == null) {
return;
}
refactoring.setLeaveDirty(true);
if (refactoring.checkActivationBasics(astRoot).isOK()) {
String label = CorrectionMessages.LocalCorrectionsSubProcessor_surroundwith_trymulticatch_description;
RefactoringCorrectionProposal proposal = new RefactoringCorrectionProposal(label, cu, refactoring, IProposalRelevance.SURROUND_WITH_TRY_MULTICATCH);
proposal.setLinkedProposalModel(refactoring.getLinkedProposalModel());
proposals.add(proposal);
}
}
// Catch exception
BodyDeclaration decl = ASTResolving.findParentBodyDeclaration(selectedNode);
if (decl == null) {
return;
}
ASTNode enclosingNode = SurroundWithAnalyzer.getEnclosingNode(selectedNode);
if (enclosingNode == null) {
return;
}
ITypeBinding[] uncaughtExceptions = ExceptionAnalyzer.perform(enclosingNode, Selection.createFromStartLength(offset, length));
if (uncaughtExceptions.length == 0) {
return;
}
TryStatement surroundingTry = ASTResolving.findParentTryStatement(selectedNode);
AST ast = astRoot.getAST();
if (surroundingTry != null && (ASTNodes.isParent(selectedNode, surroundingTry.getBody()) || selectedNode.getLocationInParent() == TryStatement.RESOURCES_PROPERTY)) {
{
ASTRewrite rewrite = ASTRewrite.create(surroundingTry.getAST());
String label = CorrectionMessages.LocalCorrectionsSubProcessor_addadditionalcatch_description;
LinkedCorrectionProposal proposal = new LinkedCorrectionProposal(label, cu, rewrite, IProposalRelevance.ADD_ADDITIONAL_CATCH);
ImportRewrite imports = proposal.createImportRewrite(context.getASTRoot());
ImportRewriteContext importRewriteContext = new ContextSensitiveImportRewriteContext(decl, imports);
CodeScopeBuilder.Scope scope = CodeScopeBuilder.perform(decl, Selection.createFromStartLength(offset, length)).findScope(offset, length);
scope.setCursor(offset);
ListRewrite clausesRewrite = rewrite.getListRewrite(surroundingTry, TryStatement.CATCH_CLAUSES_PROPERTY);
for (int i = 0; i < uncaughtExceptions.length; i++) {
ITypeBinding excBinding = uncaughtExceptions[i];
String varName = StubUtility.getExceptionVariableName(cu.getJavaProject());
String name = scope.createName(varName, false);
SingleVariableDeclaration var = ast.newSingleVariableDeclaration();
var.setName(ast.newSimpleName(name));
var.setType(imports.addImport(excBinding, ast, importRewriteContext, TypeLocation.EXCEPTION));
CatchClause newClause = ast.newCatchClause();
newClause.setException(var);
String catchBody = StubUtility.getCatchBodyContent(cu, excBinding.getName(), name, selectedNode, String.valueOf('\n'));
if (catchBody != null) {
ASTNode node = rewrite.createStringPlaceholder(catchBody, ASTNode.RETURN_STATEMENT);
newClause.getBody().statements().add(node);
}
clausesRewrite.insertLast(newClause, null);
// $NON-NLS-1$
String typeKey = "type" + i;
// $NON-NLS-1$
String nameKey = "name" + i;
proposal.addLinkedPosition(rewrite.track(var.getType()), false, typeKey);
proposal.addLinkedPosition(rewrite.track(var.getName()), false, nameKey);
addExceptionTypeLinkProposals(proposal, excBinding, typeKey);
}
proposals.add(proposal);
}
if (JavaModelUtil.is17OrHigher(cu.getJavaProject())) {
List<CatchClause> catchClauses = surroundingTry.catchClauses();
if (catchClauses != null && catchClauses.size() == 1) {
List<ITypeBinding> filteredExceptions = SurroundWithTryCatchRefactoring.filterSubtypeExceptions(uncaughtExceptions);
String label = filteredExceptions.size() > 1 ? CorrectionMessages.LocalCorrectionsSubProcessor_addexceptionstoexistingcatch_description : CorrectionMessages.LocalCorrectionsSubProcessor_addexceptiontoexistingcatch_description;
ASTRewrite rewrite = ASTRewrite.create(ast);
LinkedCorrectionProposal proposal = new LinkedCorrectionProposal(label, cu, rewrite, IProposalRelevance.ADD_EXCEPTIONS_TO_EXISTING_CATCH);
ImportRewrite imports = proposal.createImportRewrite(context.getASTRoot());
ImportRewriteContext importRewriteContext = new ContextSensitiveImportRewriteContext(decl, imports);
CatchClause catchClause = catchClauses.get(0);
Type type = catchClause.getException().getType();
if (type instanceof UnionType) {
UnionType unionType = (UnionType) type;
ListRewrite listRewrite = rewrite.getListRewrite(unionType, UnionType.TYPES_PROPERTY);
for (int i = 0; i < filteredExceptions.size(); i++) {
ITypeBinding excBinding = filteredExceptions.get(i);
Type type2 = imports.addImport(excBinding, ast, importRewriteContext, TypeLocation.EXCEPTION);
listRewrite.insertLast(type2, null);
// $NON-NLS-1$
String typeKey = "type" + i;
proposal.addLinkedPosition(rewrite.track(type2), false, typeKey);
addExceptionTypeLinkProposals(proposal, excBinding, typeKey);
}
} else {
UnionType newUnionType = ast.newUnionType();
List<Type> types = newUnionType.types();
types.add((Type) rewrite.createCopyTarget(type));
for (int i = 0; i < filteredExceptions.size(); i++) {
ITypeBinding excBinding = filteredExceptions.get(i);
Type type2 = imports.addImport(excBinding, ast, importRewriteContext, TypeLocation.EXCEPTION);
types.add(type2);
// $NON-NLS-1$
String typeKey = "type" + i;
proposal.addLinkedPosition(rewrite.track(type2), false, typeKey);
addExceptionTypeLinkProposals(proposal, excBinding, typeKey);
}
rewrite.replace(type, newUnionType, null);
}
proposals.add(proposal);
} else if (catchClauses != null && catchClauses.size() == 0) {
List<ITypeBinding> filteredExceptions = SurroundWithTryCatchRefactoring.filterSubtypeExceptions(uncaughtExceptions);
if (filteredExceptions.size() > 1) {
String label = CorrectionMessages.LocalCorrectionsSubProcessor_addadditionalmulticatch_description;
ASTRewrite rewrite = ASTRewrite.create(ast);
LinkedCorrectionProposal proposal = new LinkedCorrectionProposal(label, cu, rewrite, IProposalRelevance.ADD_ADDITIONAL_MULTI_CATCH);
ImportRewrite imports = proposal.createImportRewrite(context.getASTRoot());
ImportRewriteContext importRewriteContext = new ContextSensitiveImportRewriteContext(decl, imports);
CodeScopeBuilder.Scope scope = CodeScopeBuilder.perform(decl, Selection.createFromStartLength(offset, length)).findScope(offset, length);
scope.setCursor(offset);
CatchClause newCatchClause = ast.newCatchClause();
String varName = StubUtility.getExceptionVariableName(cu.getJavaProject());
String name = scope.createName(varName, false);
SingleVariableDeclaration var = ast.newSingleVariableDeclaration();
var.setName(ast.newSimpleName(name));
UnionType newUnionType = ast.newUnionType();
List<Type> types = newUnionType.types();
for (int i = 0; i < filteredExceptions.size(); i++) {
ITypeBinding excBinding = filteredExceptions.get(i);
Type type2 = imports.addImport(excBinding, ast, importRewriteContext, TypeLocation.EXCEPTION);
types.add(type2);
// $NON-NLS-1$
String typeKey = "type" + i;
proposal.addLinkedPosition(rewrite.track(type2), false, typeKey);
addExceptionTypeLinkProposals(proposal, excBinding, typeKey);
}
// $NON-NLS-1$
String nameKey = "name";
proposal.addLinkedPosition(rewrite.track(var.getName()), false, nameKey);
var.setType(newUnionType);
newCatchClause.setException(var);
// $NON-NLS-1$
String catchBody = StubUtility.getCatchBodyContent(cu, "Exception", name, selectedNode, String.valueOf('\n'));
if (catchBody != null) {
ASTNode node = rewrite.createStringPlaceholder(catchBody, ASTNode.RETURN_STATEMENT);
newCatchClause.getBody().statements().add(node);
}
ListRewrite listRewrite = rewrite.getListRewrite(surroundingTry, TryStatement.CATCH_CLAUSES_PROPERTY);
listRewrite.insertFirst(newCatchClause, null);
proposals.add(proposal);
}
}
}
}
// Add throws declaration
if (enclosingNode instanceof MethodDeclaration) {
MethodDeclaration methodDecl = (MethodDeclaration) enclosingNode;
IMethodBinding binding = methodDecl.resolveBinding();
boolean isApplicable = (binding != null);
if (isApplicable) {
IMethodBinding overriddenMethod = Bindings.findOverriddenMethod(binding, true);
if (overriddenMethod != null) {
isApplicable = overriddenMethod.getDeclaringClass().isFromSource();
if (!isApplicable) {
// bug 349051
ITypeBinding[] exceptionTypes = overriddenMethod.getExceptionTypes();
ArrayList<ITypeBinding> unhandledExceptions = new ArrayList<>(uncaughtExceptions.length);
for (int i = 0; i < uncaughtExceptions.length; i++) {
ITypeBinding curr = uncaughtExceptions[i];
if (isSubtype(curr, exceptionTypes)) {
unhandledExceptions.add(curr);
}
}
uncaughtExceptions = unhandledExceptions.toArray(new ITypeBinding[unhandledExceptions.size()]);
isApplicable |= uncaughtExceptions.length > 0;
}
}
}
if (isApplicable) {
ITypeBinding[] methodExceptions = binding.getExceptionTypes();
ArrayList<ITypeBinding> unhandledExceptions = new ArrayList<>(uncaughtExceptions.length);
for (int i = 0; i < uncaughtExceptions.length; i++) {
ITypeBinding curr = uncaughtExceptions[i];
if (!isSubtype(curr, methodExceptions)) {
unhandledExceptions.add(curr);
}
}
uncaughtExceptions = unhandledExceptions.toArray(new ITypeBinding[unhandledExceptions.size()]);
List<Type> exceptions = methodDecl.thrownExceptionTypes();
int nExistingExceptions = exceptions.size();
ChangeDescription[] desc = new ChangeDescription[nExistingExceptions + uncaughtExceptions.length];
for (int i = 0; i < exceptions.size(); i++) {
Type elem = exceptions.get(i);
if (isSubtype(elem.resolveBinding(), uncaughtExceptions)) {
desc[i] = new RemoveDescription();
}
}
for (int i = 0; i < uncaughtExceptions.length; i++) {
// $NON-NLS-1$
desc[i + nExistingExceptions] = new InsertDescription(uncaughtExceptions[i], "");
}
String label = CorrectionMessages.LocalCorrectionsSubProcessor_addthrows_description;
ChangeMethodSignatureProposal proposal = new ChangeMethodSignatureProposal(label, cu, astRoot, binding, null, desc, IProposalRelevance.ADD_THROWS_DECLARATION);
for (int i = 0; i < uncaughtExceptions.length; i++) {
addExceptionTypeLinkProposals(proposal, uncaughtExceptions[i], proposal.getExceptionTypeGroupId(i + nExistingExceptions));
}
proposals.add(proposal);
}
}
}
Aggregations