Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 238485 Details for
Bug 423439
[1.8][clean up][quick assist] "Convert anonymous to lambda" needs to consider ambiguous target types
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Patch - Common infrastructure code
Bug-423439-1.8-targetType-common infra-.patch (text/plain), 14.50 KB, created by
Noopur Gupta
on 2013-12-19 08:28:57 EST
(
hide
)
Description:
Patch - Common infrastructure code
Filename:
MIME Type:
Creator:
Noopur Gupta
Created:
2013-12-19 08:28:57 EST
Size:
14.50 KB
patch
obsolete
>diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodes.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodes.java >index 1a2042d..d30d216 100644 >--- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodes.java >+++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodes.java >@@ -48,13 +48,18 @@ > import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; > import org.eclipse.jdt.core.dom.Annotation; > import org.eclipse.jdt.core.dom.AnonymousClassDeclaration; >+import org.eclipse.jdt.core.dom.ArrayCreation; >+import org.eclipse.jdt.core.dom.ArrayInitializer; > import org.eclipse.jdt.core.dom.ArrayType; > import org.eclipse.jdt.core.dom.Assignment; > import org.eclipse.jdt.core.dom.BodyDeclaration; >+import org.eclipse.jdt.core.dom.CastExpression; > import org.eclipse.jdt.core.dom.CharacterLiteral; > import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor; > import org.eclipse.jdt.core.dom.ClassInstanceCreation; > import org.eclipse.jdt.core.dom.CompilationUnit; >+import org.eclipse.jdt.core.dom.ConditionalExpression; >+import org.eclipse.jdt.core.dom.ConstructorInvocation; > import org.eclipse.jdt.core.dom.DoStatement; > import org.eclipse.jdt.core.dom.EnhancedForStatement; > import org.eclipse.jdt.core.dom.EnumConstantDeclaration; >@@ -69,6 +74,7 @@ > import org.eclipse.jdt.core.dom.IVariableBinding; > import org.eclipse.jdt.core.dom.IfStatement; > import org.eclipse.jdt.core.dom.InfixExpression; >+import org.eclipse.jdt.core.dom.LambdaExpression; > import org.eclipse.jdt.core.dom.MemberValuePair; > import org.eclipse.jdt.core.dom.Message; > import org.eclipse.jdt.core.dom.MethodDeclaration; >@@ -82,11 +88,15 @@ > import org.eclipse.jdt.core.dom.PrimitiveType; > import org.eclipse.jdt.core.dom.QualifiedName; > import org.eclipse.jdt.core.dom.QualifiedType; >+import org.eclipse.jdt.core.dom.ReturnStatement; > import org.eclipse.jdt.core.dom.SimpleName; > import org.eclipse.jdt.core.dom.SimpleType; > import org.eclipse.jdt.core.dom.SingleVariableDeclaration; > import org.eclipse.jdt.core.dom.StringLiteral; > import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor; >+import org.eclipse.jdt.core.dom.SuperConstructorInvocation; >+import org.eclipse.jdt.core.dom.SuperFieldAccess; >+import org.eclipse.jdt.core.dom.SuperMethodInvocation; > import org.eclipse.jdt.core.dom.Type; > import org.eclipse.jdt.core.dom.UnionType; > import org.eclipse.jdt.core.dom.VariableDeclaration; >@@ -571,6 +581,221 @@ > } > > /** >+ * Checks whether overloaded methods can result in ambiguous method call when the >+ * <code>expression</code> argument is replaced with a poly expression form of the functional >+ * interface instance. >+ * >+ * @param expression the method argument which is a functional interface instance >+ * @return <code>true</code> if overloaded methods can result in ambiguous method call, >+ * <code>false</code> otherwise >+ * >+ * @since 3.9 BETA_JAVA8 >+ */ >+ public static boolean isTargetAmbiguous(Expression expression) { >+ ASTNode parent= expression.getParent(); >+ StructuralPropertyDescriptor locationInParent= expression.getLocationInParent(); >+ IMethodBinding methodBinding; >+ int argumentIndex; >+ ITypeBinding enclosingTypeBinding; >+ >+ if (locationInParent == MethodInvocation.ARGUMENTS_PROPERTY) { >+ MethodInvocation methodInvocation= (MethodInvocation) parent; >+ methodBinding= methodInvocation.resolveMethodBinding(); >+ argumentIndex= methodInvocation.arguments().indexOf(expression); >+ } else if (locationInParent == SuperMethodInvocation.ARGUMENTS_PROPERTY) { >+ SuperMethodInvocation superMethodInvocation= (SuperMethodInvocation) parent; >+ methodBinding= superMethodInvocation.resolveMethodBinding(); >+ argumentIndex= superMethodInvocation.arguments().indexOf(expression); >+ } else if (locationInParent == ConstructorInvocation.ARGUMENTS_PROPERTY) { >+ ConstructorInvocation constructorInvocation= (ConstructorInvocation) parent; >+ methodBinding= constructorInvocation.resolveConstructorBinding(); >+ argumentIndex= constructorInvocation.arguments().indexOf(expression); >+ } else if (locationInParent == SuperConstructorInvocation.ARGUMENTS_PROPERTY) { >+ SuperConstructorInvocation superConstructorInvocation= (SuperConstructorInvocation) parent; >+ methodBinding= superConstructorInvocation.resolveConstructorBinding(); >+ argumentIndex= superConstructorInvocation.arguments().indexOf(expression); >+ } else if (locationInParent == ClassInstanceCreation.ARGUMENTS_PROPERTY) { >+ ClassInstanceCreation creation= (ClassInstanceCreation) parent; >+ methodBinding= creation.resolveConstructorBinding(); >+ argumentIndex= creation.arguments().indexOf(expression); >+ } else if (locationInParent == EnumConstantDeclaration.ARGUMENTS_PROPERTY) { >+ EnumConstantDeclaration enumConstantDecl= (EnumConstantDeclaration) parent; >+ methodBinding= enumConstantDecl.resolveConstructorBinding(); >+ argumentIndex= enumConstantDecl.arguments().indexOf(expression); >+ } else { >+ return false; >+ } >+ >+ enclosingTypeBinding= getEnclosingType(parent); >+ if (enclosingTypeBinding != null && methodBinding != null) { >+ TypeBindingVisitor visitor= new AmbiguousTargetMethodAnalyzer(enclosingTypeBinding, methodBinding, argumentIndex); >+ return !(visitor.visit(enclosingTypeBinding) && Bindings.visitHierarchy(enclosingTypeBinding, visitor)); >+ } >+ >+ return true; >+ } >+ >+ private static class AmbiguousTargetMethodAnalyzer implements TypeBindingVisitor { >+ private ITypeBinding fEnclosingType; >+ private IMethodBinding fOriginalMethod; >+ private int fArgIndex; >+ >+ /** >+ * @param enclosingType the type binding enclosing the method call >+ * @param originalMethod the method binding corresponding to the method call >+ * @param argumentIndex the index of the functional interface instance argument in the >+ * method call >+ */ >+ public AmbiguousTargetMethodAnalyzer(ITypeBinding enclosingType, IMethodBinding originalMethod, int argumentIndex) { >+ fEnclosingType= enclosingType; >+ fOriginalMethod= originalMethod; >+ fArgIndex= argumentIndex; >+ } >+ >+ public boolean visit(ITypeBinding node) { >+ IMethodBinding[] methods= node.getDeclaredMethods(); >+ for (int i= 0; i < methods.length; i++) { >+ IMethodBinding candidate= methods[i]; >+ if (candidate == fOriginalMethod) { >+ continue; >+ } >+ if (fEnclosingType != candidate.getDeclaringClass() && Modifier.isPrivate(candidate.getModifiers())) { >+ continue; >+ } >+ if (fOriginalMethod.getName().equals(candidate.getName()) >+ && fOriginalMethod.getParameterTypes().length == candidate.getParameterTypes().length >+ && candidate.getParameterTypes()[fArgIndex].isFunctionalInterface()) { >+ return false; >+ } >+ } >+ return true; >+ } >+ } >+ >+ /** >+ * Derives the target type defined at the location of the given expression if the target context >+ * supports poly expressions. >+ * >+ * @param expression the expression at whose location the target type is required >+ * @return the type binding of the target type defined at the location of the given expression >+ * if the target context supports poly expressions, or <code>null</code> if the target >+ * type could not be derived >+ * >+ * @since 3.9 BETA_JAVA8 >+ */ >+ public static ITypeBinding getTargetType(Expression expression) { >+ ASTNode parent= expression.getParent(); >+ StructuralPropertyDescriptor locationInParent= expression.getLocationInParent(); >+ >+ if (locationInParent == VariableDeclarationFragment.INITIALIZER_PROPERTY || locationInParent == SingleVariableDeclaration.INITIALIZER_PROPERTY) { >+ return ((VariableDeclaration) parent).getName().resolveTypeBinding(); >+ >+ } else if (locationInParent == Assignment.RIGHT_HAND_SIDE_PROPERTY) { >+ return ((Assignment) parent).getLeftHandSide().resolveTypeBinding(); >+ >+ } else if (locationInParent == ReturnStatement.EXPRESSION_PROPERTY) { >+ return getTargetTypeForReturnStmt((ReturnStatement) parent); >+ >+ } else if (locationInParent == ArrayInitializer.EXPRESSIONS_PROPERTY) { >+ return getTargetTypeForArrayInitializer((ArrayInitializer) parent); >+ >+ } else if (locationInParent == MethodInvocation.ARGUMENTS_PROPERTY) { >+ MethodInvocation methodInvocation= (MethodInvocation) parent; >+ IMethodBinding methodBinding= methodInvocation.resolveMethodBinding(); >+ if (methodBinding != null) { >+ return ASTResolving.getParameterTypeBinding(expression, methodInvocation.arguments(), methodBinding); >+ } >+ >+ } else if (locationInParent == SuperMethodInvocation.ARGUMENTS_PROPERTY) { >+ SuperMethodInvocation superMethodInvocation= (SuperMethodInvocation) parent; >+ IMethodBinding superMethodBinding= superMethodInvocation.resolveMethodBinding(); >+ if (superMethodBinding != null) { >+ return ASTResolving.getParameterTypeBinding(expression, superMethodInvocation.arguments(), superMethodBinding); >+ } >+ >+ } else if (locationInParent == ConstructorInvocation.ARGUMENTS_PROPERTY) { >+ ConstructorInvocation constructorInvocation= (ConstructorInvocation) parent; >+ IMethodBinding constructorBinding= constructorInvocation.resolveConstructorBinding(); >+ if (constructorBinding != null) { >+ return ASTResolving.getParameterTypeBinding(expression, constructorInvocation.arguments(), constructorBinding); >+ } >+ >+ } else if (locationInParent == SuperConstructorInvocation.ARGUMENTS_PROPERTY) { >+ SuperConstructorInvocation superConstructorInvocation= (SuperConstructorInvocation) parent; >+ IMethodBinding superConstructorBinding= superConstructorInvocation.resolveConstructorBinding(); >+ if (superConstructorBinding != null) { >+ return ASTResolving.getParameterTypeBinding(expression, superConstructorInvocation.arguments(), superConstructorBinding); >+ } >+ >+ } else if (locationInParent == ClassInstanceCreation.ARGUMENTS_PROPERTY) { >+ ClassInstanceCreation creation= (ClassInstanceCreation) parent; >+ IMethodBinding creationBinding= creation.resolveConstructorBinding(); >+ if (creationBinding != null) { >+ return ASTResolving.getParameterTypeBinding(expression, creation.arguments(), creationBinding); >+ } >+ >+ } else if (locationInParent == EnumConstantDeclaration.ARGUMENTS_PROPERTY) { >+ EnumConstantDeclaration enumConstantDecl= (EnumConstantDeclaration) parent; >+ IMethodBinding enumConstructorBinding= enumConstantDecl.resolveConstructorBinding(); >+ if (enumConstructorBinding != null) { >+ return ASTResolving.getParameterTypeBinding(expression, enumConstantDecl.arguments(), enumConstructorBinding); >+ } >+ >+ } else if (locationInParent == LambdaExpression.BODY_PROPERTY) { >+ IMethodBinding methodBinding= ((LambdaExpression) parent).resolveMethodBinding(); >+ if (methodBinding != null) { >+ return methodBinding.getReturnType(); >+ } >+ >+ } else if (locationInParent == ConditionalExpression.THEN_EXPRESSION_PROPERTY || locationInParent == ConditionalExpression.ELSE_EXPRESSION_PROPERTY) { >+ return getTargetType((ConditionalExpression) parent); >+ >+ } else if (locationInParent == CastExpression.EXPRESSION_PROPERTY) { >+ return ((CastExpression) parent).getType().resolveBinding(); >+ >+ } else if (locationInParent == FieldAccess.NAME_PROPERTY >+ || locationInParent == SuperFieldAccess.NAME_PROPERTY >+ || locationInParent == QualifiedName.NAME_PROPERTY) { >+ return getTargetType((Expression) parent); >+ >+ } else if (locationInParent == ParenthesizedExpression.EXPRESSION_PROPERTY) { >+ return getTargetType((ParenthesizedExpression) parent); >+ >+ } >+ return null; >+ } >+ >+ private static ITypeBinding getTargetTypeForArrayInitializer(ArrayInitializer arrayInitializer) { >+ ASTNode initializerParent= arrayInitializer.getParent(); >+ while (initializerParent instanceof ArrayInitializer) { >+ initializerParent= initializerParent.getParent(); >+ } >+ if (initializerParent instanceof ArrayCreation) { >+ return ((ArrayCreation) initializerParent).getType().getElementType().resolveBinding(); >+ } else if (initializerParent instanceof VariableDeclaration) { >+ ITypeBinding typeBinding= ((VariableDeclaration) initializerParent).getName().resolveTypeBinding(); >+ if (typeBinding != null) { >+ return typeBinding.getElementType(); >+ } >+ } >+ return null; >+ } >+ >+ private static ITypeBinding getTargetTypeForReturnStmt(ReturnStatement returnStmt) { >+ LambdaExpression enclosingLambdaExpr= ASTResolving.findEnclosingLambdaExpression(returnStmt); >+ if (enclosingLambdaExpr != null) { >+ IMethodBinding methodBinding= enclosingLambdaExpr.resolveMethodBinding(); >+ return methodBinding == null ? null : methodBinding.getReturnType(); >+ } >+ MethodDeclaration enclosingMethodDecl= ASTResolving.findParentMethodDeclaration(returnStmt); >+ if (enclosingMethodDecl != null) { >+ IMethodBinding methodBinding= enclosingMethodDecl.resolveBinding(); >+ return methodBinding == null ? null : methodBinding.getReturnType(); >+ } >+ return null; >+ } >+ >+ /** > * Returns whether an expression at the given location needs explicit boxing. > * > * @param expression the expression >diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/ASTResolving.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/ASTResolving.java >index 6e778a0..6511553 100644 >--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/ASTResolving.java >+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/ASTResolving.java >@@ -390,7 +390,7 @@ > return arrayBinding; > } > >- private static ITypeBinding getParameterTypeBinding(ASTNode node, List<Expression> args, IMethodBinding binding) { >+ public static ITypeBinding getParameterTypeBinding(ASTNode node, List<Expression> args, IMethodBinding binding) { > ITypeBinding[] paramTypes= binding.getParameterTypes(); > int index= args.indexOf(node); > if (binding.isVarargs() && index >= paramTypes.length - 1) { >@@ -698,6 +698,30 @@ > return null; > } > >+ /** >+ * Returns the lambda expression node which encloses the given <code>node</code>, or >+ * <code>null</code> if none. >+ * >+ * @param node the node >+ * @return the enclosing lambda expression node for the given <code>node</code>, or >+ * <code>null</code> if none >+ * >+ * @since 3.9 BETA_JAVA8 >+ */ >+ public static LambdaExpression findEnclosingLambdaExpression(ASTNode node) { >+ node= node.getParent(); >+ while (node != null) { >+ if (node instanceof LambdaExpression) { >+ return (LambdaExpression) node; >+ } >+ if (node instanceof BodyDeclaration || node instanceof AnonymousClassDeclaration) { >+ return null; >+ } >+ node= node.getParent(); >+ } >+ return null; >+ } >+ > public static ASTNode findAncestor(ASTNode node, int nodeType) { > while ((node != null) && (node.getNodeType() != nodeType)) { > node= node.getParent();
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 423439
:
238124
| 238485 |
238511
|
238540