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 |
if (resolveBinding instanceof IVariableBinding) { |
91 |
ITypeBinding declaringClass= ((IVariableBinding) resolveBinding).getDeclaringClass(); |
92 |
if (declaringClass != null && Bindings.equals(typeBinding, declaringClass)) { |
93 |
nameNodes.add(node); |
94 |
} |
95 |
} |
96 |
return true; |
97 |
} |
98 |
|
99 |
@Override |
100 |
public boolean visit(QualifiedName node) { |
101 |
IBinding resolveBinding= node.resolveBinding(); |
102 |
Name qualifier= node.getQualifier(); |
103 |
if (!(qualifier instanceof SimpleName)) { |
104 |
qualifier= ASTNodes.getLeftMostSimpleName(qualifier); |
105 |
} |
106 |
IBinding qualifierBinding= qualifier.resolveBinding(); |
107 |
if (Bindings.equals(typeBinding, qualifierBinding)) { |
108 |
return false; |
109 |
} |
110 |
if (resolveBinding instanceof IVariableBinding) { |
111 |
ITypeBinding declaringClass= ((IVariableBinding) resolveBinding).getDeclaringClass(); |
112 |
while (declaringClass != null && declaringClass.isEnum()) { |
113 |
declaringClass= declaringClass.getDeclaringClass(); |
114 |
} |
115 |
if (declaringClass != null && Bindings.equals(typeBinding, declaringClass)) { |
116 |
nameNodes.add(qualifier); |
117 |
} |
118 |
} |
119 |
return false; |
120 |
} |
121 |
} |
72 |
|
122 |
|
73 |
private static final class FunctionalAnonymousClassesFinder extends ASTVisitor { |
123 |
private static final class FunctionalAnonymousClassesFinder extends ASTVisitor { |
74 |
|
124 |
|
Lines 177-182
Link Here
|
177 |
if (binding != null && !JdtFlags.isStatic(binding) && node.getExpression() == null |
227 |
if (binding != null && !JdtFlags.isStatic(binding) && node.getExpression() == null |
178 |
&& Bindings.isSuperType(binding.getDeclaringClass(), fFunctionalInterface, false)) |
228 |
&& Bindings.isSuperType(binding.getDeclaringClass(), fFunctionalInterface, false)) |
179 |
throw new AbortSearchException(); |
229 |
throw new AbortSearchException(); |
|
|
230 |
if (Bindings.equals(fMethodDeclaration.resolveBinding(), binding)) { |
231 |
throw new AbortSearchException(); |
232 |
} |
180 |
return true; |
233 |
return true; |
181 |
} |
234 |
} |
182 |
} |
235 |
} |
Lines 238-245
Link Here
|
238 |
} |
291 |
} |
239 |
} |
292 |
} |
240 |
} |
293 |
} |
241 |
//TODO: Bug 421479: [1.8][clean up][quick assist] convert anonymous to lambda must consider lost scope of interface |
294 |
|
242 |
// lambdaBody.accept(new InterfaceAccessQualifier(rewrite, classInstanceCreation.getType().resolveBinding())); //TODO: maybe need a separate ASTRewrite and string placeholder |
295 |
ITypeBinding typeBinding= classInstanceCreation.getType().resolveBinding(); |
|
|
296 |
InterfaceAccessQualifier visitor= new InterfaceAccessQualifier(typeBinding); |
297 |
lambdaBody.accept(visitor); |
298 |
qualifyNameNodes(rewrite, typeBinding, visitor.nameNodes, group); |
243 |
|
299 |
|
244 |
lambdaExpression.setBody(rewrite.createCopyTarget(lambdaBody)); |
300 |
lambdaExpression.setBody(rewrite.createCopyTarget(lambdaBody)); |
245 |
Expression replacement= lambdaExpression; |
301 |
Expression replacement= lambdaExpression; |
Lines 248-254
Link Here
|
248 |
cast.setExpression(lambdaExpression); |
304 |
cast.setExpression(lambdaExpression); |
249 |
ImportRewrite importRewrite= cuRewrite.getImportRewrite(); |
305 |
ImportRewrite importRewrite= cuRewrite.getImportRewrite(); |
250 |
ImportRewriteContext importRewriteContext= new ContextSensitiveImportRewriteContext(classInstanceCreation, importRewrite); |
306 |
ImportRewriteContext importRewriteContext= new ContextSensitiveImportRewriteContext(classInstanceCreation, importRewrite); |
251 |
Type castType= importRewrite.addImport(classInstanceCreation.getType().resolveBinding(), ast, importRewriteContext); |
307 |
Type castType= importRewrite.addImport(typeBinding, ast, importRewriteContext); |
252 |
cast.setType(castType); |
308 |
cast.setType(castType); |
253 |
importRemover.registerAddedImports(castType); |
309 |
importRemover.registerAddedImports(castType); |
254 |
replacement= cast; |
310 |
replacement= cast; |
Lines 257-262
Link Here
|
257 |
|
313 |
|
258 |
importRemover.registerRemovedNode(classInstanceCreation); |
314 |
importRemover.registerRemovedNode(classInstanceCreation); |
259 |
importRemover.registerRetainedNode(lambdaBody); |
315 |
importRemover.registerRetainedNode(lambdaBody); |
|
|
316 |
} |
317 |
} |
318 |
|
319 |
private void qualifyNameNodes(ASTRewrite rewrite, ITypeBinding typeBinding, List<Name> nameNodes, TextEditGroup group) { |
320 |
for (Name name : nameNodes) { |
321 |
AST ast= name.getAST(); |
322 |
SimpleName simpleName= null; |
323 |
String qualifier= typeBinding.getName(); |
324 |
if (name instanceof SimpleName) { |
325 |
simpleName= ast.newSimpleName(((SimpleName) name).getIdentifier()); |
326 |
rewrite.set(name, SimpleName.IDENTIFIER_PROPERTY, ast.newQualifiedName(ast.newName(qualifier), simpleName).getFullyQualifiedName(), group); |
327 |
} else if (name instanceof QualifiedName) { |
328 |
qualifier= qualifier + '.' + ((QualifiedName) name).getQualifier().getFullyQualifiedName(); |
329 |
rewrite.set(name, QualifiedName.QUALIFIER_PROPERTY, ast.newName(qualifier), group); |
330 |
} |
260 |
} |
331 |
} |
261 |
} |
332 |
} |
262 |
|
333 |
|
Lines 531-537
Link Here
|
531 |
return methodBinding.getReturnType().getFunctionalInterfaceMethod() != null; |
602 |
return methodBinding.getReturnType().getFunctionalInterfaceMethod() != null; |
532 |
} |
603 |
} |
533 |
|
604 |
|
534 |
//TODO: should also check whether variable is of a functional type |
605 |
//TODO: should also check whether variable is of a functional type |
535 |
return locationInParent == SingleVariableDeclaration.INITIALIZER_PROPERTY |
606 |
return locationInParent == SingleVariableDeclaration.INITIALIZER_PROPERTY |
536 |
|| locationInParent == VariableDeclarationFragment.INITIALIZER_PROPERTY |
607 |
|| locationInParent == VariableDeclarationFragment.INITIALIZER_PROPERTY |
537 |
|| locationInParent == Assignment.RIGHT_HAND_SIDE_PROPERTY |
608 |
|| locationInParent == Assignment.RIGHT_HAND_SIDE_PROPERTY |