/*******************************************************************************
* Copyright (c) 2013, 2014 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.ui.text.correction.proposals;
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.CompilationUnit;
import org.eclipse.jdt.core.dom.Expression;
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.IVariableBinding;
import org.eclipse.jdt.core.dom.LambdaExpression;
import org.eclipse.jdt.core.dom.ReturnStatement;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory;
import org.eclipse.jdt.internal.corext.dom.Bindings;
import org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer;
import org.eclipse.jdt.internal.ui.text.correction.ASTResolving;
public class MissingReturnTypeInLambdaCorrectionProposal extends MissingReturnTypeCorrectionProposal {
private final LambdaExpression lambdaExpression;
public MissingReturnTypeInLambdaCorrectionProposal(ICompilationUnit cu, LambdaExpression lambda, ReturnStatement existingReturn, int relevance) {
super(cu, null, existingReturn, relevance);
lambdaExpression= lambda;
fExistingReturn= existingReturn;
}
@Override
protected AST getAST() {
return lambdaExpression.getAST();
}
@Override
public ITypeBinding getReturnTypeBinding() {
IMethodBinding methodBinding= lambdaExpression.resolveMethodBinding();
if (methodBinding != null && methodBinding.getReturnType() != null) {
return methodBinding.getReturnType();
}
return null;
}
@Override
protected CompilationUnit getCU() {
return (CompilationUnit) lambdaExpression.getRoot();
}
@Override
protected Expression createDefaultExpression(AST ast) {
return ASTNodeFactory.newDefaultExpression(ast, getReturnTypeBinding());
}
@Override
protected ASTNode getBody() {
return lambdaExpression.getBody();
}
@Override
protected int getModifiers() {
return 0;
}
@Override
protected Expression computeProposals(AST ast, ITypeBinding returnBinding, int returnOffset, CompilationUnit root, Expression result) {
ScopeAnalyzer analyzer= new ScopeAnalyzer(root);
IBinding[] bindings= analyzer.getDeclarationsInScope(returnOffset, ScopeAnalyzer.VARIABLES | ScopeAnalyzer.CHECK_VISIBILITY);
org.eclipse.jdt.core.dom.NodeFinder finder= new org.eclipse.jdt.core.dom.NodeFinder(root, returnOffset, 0);
ASTNode varDeclFrag= ASTResolving.findAncestor(finder.getCoveringNode(), ASTNode.VARIABLE_DECLARATION_FRAGMENT);
IVariableBinding varDeclFragBinding= null;
if (varDeclFrag != null)
varDeclFragBinding= ((VariableDeclarationFragment) varDeclFrag).resolveBinding();
for (int i= 0; i < bindings.length; i++) {
IVariableBinding curr= (IVariableBinding) bindings[i];
ITypeBinding type= curr.getType();
// Bindings are compared to make sure that a lambda does not return a variable which is yet to be initialised.
if (type != null && type.isAssignmentCompatible(returnBinding) && testModifier(curr) && !Bindings.equals(curr, varDeclFragBinding)) {
if (result == null) {
result= ast.newSimpleName(curr.getName());
}
addLinkedPositionProposal(RETURN_EXPRESSION_KEY, curr.getName(), null);
}
}
return result;
}
}