Lines 34-42
Link Here
|
34 |
import org.eclipse.jdt.core.dom.IBinding; |
34 |
import org.eclipse.jdt.core.dom.IBinding; |
35 |
import org.eclipse.jdt.core.dom.IMethodBinding; |
35 |
import org.eclipse.jdt.core.dom.IMethodBinding; |
36 |
import org.eclipse.jdt.core.dom.ITypeBinding; |
36 |
import org.eclipse.jdt.core.dom.ITypeBinding; |
|
|
37 |
import org.eclipse.jdt.core.dom.IVariableBinding; |
37 |
import org.eclipse.jdt.core.dom.LambdaExpression; |
38 |
import org.eclipse.jdt.core.dom.LambdaExpression; |
38 |
import org.eclipse.jdt.core.dom.MethodDeclaration; |
39 |
import org.eclipse.jdt.core.dom.MethodDeclaration; |
39 |
import org.eclipse.jdt.core.dom.MethodInvocation; |
40 |
import org.eclipse.jdt.core.dom.MethodInvocation; |
|
|
41 |
import org.eclipse.jdt.core.dom.Name; |
42 |
import org.eclipse.jdt.core.dom.QualifiedName; |
40 |
import org.eclipse.jdt.core.dom.ReturnStatement; |
43 |
import org.eclipse.jdt.core.dom.ReturnStatement; |
41 |
import org.eclipse.jdt.core.dom.SimpleName; |
44 |
import org.eclipse.jdt.core.dom.SimpleName; |
42 |
import org.eclipse.jdt.core.dom.SingleVariableDeclaration; |
45 |
import org.eclipse.jdt.core.dom.SingleVariableDeclaration; |
Lines 69-74
Link Here
|
69 |
import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings; |
72 |
import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings; |
70 |
|
73 |
|
71 |
public class LambdaExpressionsFix extends CompilationUnitRewriteOperationsFix { |
74 |
public class LambdaExpressionsFix extends CompilationUnitRewriteOperationsFix { |
|
|
75 |
|
76 |
private static final class InterfaceAccessQualifier extends HierarchicalASTVisitor { |
77 |
|
78 |
List<Name> nameNodes; |
79 |
|
80 |
private ITypeBinding typeBinding; |
81 |
|
82 |
public InterfaceAccessQualifier(ITypeBinding typeBinding) { |
83 |
this.typeBinding= typeBinding; |
84 |
nameNodes= new ArrayList<Name>(); |
85 |
} |
86 |
|
87 |
@Override |
88 |
public boolean visit(SimpleName node) { |
89 |
IBinding resolveBinding= node.resolveBinding(); |
90 |
ITypeBinding declaringClass= null; |
91 |
if (resolveBinding instanceof IVariableBinding) { |
92 |
declaringClass= ((IVariableBinding) resolveBinding).getDeclaringClass(); |
93 |
} else if (resolveBinding instanceof ITypeBinding) { |
94 |
declaringClass= ((ITypeBinding) resolveBinding).getDeclaringClass(); |
95 |
} |
96 |
if (declaringClass != null && Bindings.equals(typeBinding, declaringClass)) { |
97 |
nameNodes.add(node); |
98 |
} |
99 |
return true; |
100 |
} |
101 |
|
102 |
@Override |
103 |
public boolean visit(QualifiedName node) { |
104 |
Name qualifier= node.getQualifier(); |
105 |
String fullyQualifiedName= qualifier.getFullyQualifiedName(); |
106 |
// Ignore if already qualified with the functional interface |
107 |
if (fullyQualifiedName.startsWith(typeBinding.getQualifiedName()) || fullyQualifiedName.startsWith(typeBinding.getName())) { |
108 |
return false; |
109 |
} |
110 |
IBinding resolveBinding= node.resolveBinding(); |
111 |
ITypeBinding declaringClass= null; |
112 |
if (resolveBinding instanceof IVariableBinding) { |
113 |
declaringClass= ((IVariableBinding) resolveBinding).getDeclaringClass(); |
114 |
} else if (resolveBinding instanceof ITypeBinding) { |
115 |
declaringClass= ((ITypeBinding) resolveBinding).getDeclaringClass(); |
116 |
} |
117 |
while (declaringClass != null) { |
118 |
if (Bindings.equals(typeBinding, declaringClass)) { |
119 |
nameNodes.add(qualifier); |
120 |
return false; |
121 |
} |
122 |
declaringClass= declaringClass.getDeclaringClass(); |
123 |
} |
124 |
return false; |
125 |
} |
126 |
} |
72 |
|
127 |
|
73 |
private static final class FunctionalAnonymousClassesFinder extends ASTVisitor { |
128 |
private static final class FunctionalAnonymousClassesFinder extends ASTVisitor { |
74 |
|
129 |
|
Lines 177-182
Link Here
|
177 |
if (binding != null && !JdtFlags.isStatic(binding) && node.getExpression() == null |
232 |
if (binding != null && !JdtFlags.isStatic(binding) && node.getExpression() == null |
178 |
&& Bindings.isSuperType(binding.getDeclaringClass(), fFunctionalInterface, false)) |
233 |
&& Bindings.isSuperType(binding.getDeclaringClass(), fFunctionalInterface, false)) |
179 |
throw new AbortSearchException(); |
234 |
throw new AbortSearchException(); |
|
|
235 |
if (Bindings.equals(binding, fMethodDeclaration.resolveBinding())) { |
236 |
throw new AbortSearchException(); |
237 |
} |
180 |
return true; |
238 |
return true; |
181 |
} |
239 |
} |
182 |
} |
240 |
} |
Lines 238-245
Link Here
|
238 |
} |
296 |
} |
239 |
} |
297 |
} |
240 |
} |
298 |
} |
241 |
//TODO: Bug 421479: [1.8][clean up][quick assist] convert anonymous to lambda must consider lost scope of interface |
299 |
|
242 |
// lambdaBody.accept(new InterfaceAccessQualifier(rewrite, classInstanceCreation.getType().resolveBinding())); //TODO: maybe need a separate ASTRewrite and string placeholder |
300 |
ITypeBinding typeBinding= classInstanceCreation.getType().resolveBinding(); |
|
|
301 |
InterfaceAccessQualifier visitor= new InterfaceAccessQualifier(typeBinding); |
302 |
lambdaBody.accept(visitor); |
303 |
qualifyNameNodes(rewrite, typeBinding, visitor.nameNodes, group); |
243 |
|
304 |
|
244 |
lambdaExpression.setBody(rewrite.createCopyTarget(lambdaBody)); |
305 |
lambdaExpression.setBody(rewrite.createCopyTarget(lambdaBody)); |
245 |
Expression replacement= lambdaExpression; |
306 |
Expression replacement= lambdaExpression; |
Lines 248-254
Link Here
|
248 |
cast.setExpression(lambdaExpression); |
309 |
cast.setExpression(lambdaExpression); |
249 |
ImportRewrite importRewrite= cuRewrite.getImportRewrite(); |
310 |
ImportRewrite importRewrite= cuRewrite.getImportRewrite(); |
250 |
ImportRewriteContext importRewriteContext= new ContextSensitiveImportRewriteContext(classInstanceCreation, importRewrite); |
311 |
ImportRewriteContext importRewriteContext= new ContextSensitiveImportRewriteContext(classInstanceCreation, importRewrite); |
251 |
Type castType= importRewrite.addImport(classInstanceCreation.getType().resolveBinding(), ast, importRewriteContext); |
312 |
Type castType= importRewrite.addImport(typeBinding, ast, importRewriteContext); |
252 |
cast.setType(castType); |
313 |
cast.setType(castType); |
253 |
importRemover.registerAddedImports(castType); |
314 |
importRemover.registerAddedImports(castType); |
254 |
replacement= cast; |
315 |
replacement= cast; |
Lines 257-262
Link Here
|
257 |
|
318 |
|
258 |
importRemover.registerRemovedNode(classInstanceCreation); |
319 |
importRemover.registerRemovedNode(classInstanceCreation); |
259 |
importRemover.registerRetainedNode(lambdaBody); |
320 |
importRemover.registerRetainedNode(lambdaBody); |
|
|
321 |
} |
322 |
} |
323 |
|
324 |
private void qualifyNameNodes(ASTRewrite rewrite, ITypeBinding typeBinding, List<Name> nameNodes, TextEditGroup group) { |
325 |
for (Name name : nameNodes) { |
326 |
AST ast= name.getAST(); |
327 |
SimpleName simpleName= null; |
328 |
String qualifier= typeBinding.getName(); |
329 |
if (name instanceof SimpleName) { |
330 |
simpleName= ast.newSimpleName(((SimpleName) name).getIdentifier()); |
331 |
rewrite.set(name, SimpleName.IDENTIFIER_PROPERTY, ast.newQualifiedName(ast.newName(qualifier), simpleName).getFullyQualifiedName(), group); |
332 |
} else if (name instanceof QualifiedName) { |
333 |
qualifier= qualifier + '.' + ((QualifiedName) name).getQualifier().getFullyQualifiedName(); |
334 |
rewrite.set(name, QualifiedName.QUALIFIER_PROPERTY, ast.newName(qualifier), group); |
335 |
} |
260 |
} |
336 |
} |
261 |
} |
337 |
} |
262 |
|
338 |
|
Lines 531-537
Link Here
|
531 |
return methodBinding.getReturnType().getFunctionalInterfaceMethod() != null; |
607 |
return methodBinding.getReturnType().getFunctionalInterfaceMethod() != null; |
532 |
} |
608 |
} |
533 |
|
609 |
|
534 |
//TODO: should also check whether variable is of a functional type |
610 |
//TODO: should also check whether variable is of a functional type |
535 |
return locationInParent == SingleVariableDeclaration.INITIALIZER_PROPERTY |
611 |
return locationInParent == SingleVariableDeclaration.INITIALIZER_PROPERTY |
536 |
|| locationInParent == VariableDeclarationFragment.INITIALIZER_PROPERTY |
612 |
|| locationInParent == VariableDeclarationFragment.INITIALIZER_PROPERTY |
537 |
|| locationInParent == Assignment.RIGHT_HAND_SIDE_PROPERTY |
613 |
|| locationInParent == Assignment.RIGHT_HAND_SIDE_PROPERTY |