下面列出了org.eclipse.jdt.core.dom.CreationReference#org.eclipse.jdt.core.dom.LambdaExpression 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private Expression convert(LambdaExpression expression) {
MethodDescriptor functionalMethodDescriptor =
JdtUtils.createMethodDescriptor(expression.resolveMethodBinding());
return FunctionExpression.newBuilder()
.setTypeDescriptor(JdtUtils.createTypeDescriptor(expression.resolveTypeBinding()))
.setParameters(
JdtUtils.<VariableDeclaration>asTypedList(expression.parameters()).stream()
.map(this::convert)
.collect(toImmutableList()))
.setStatements(
processEnclosedBy(
functionalMethodDescriptor,
() -> convertLambdaBody(expression.getBody()).getStatements()))
.setSourcePosition(getSourcePosition(expression))
.build();
}
@Override
public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException {
initAST();
if (fTempDeclarationNode == null || fTempDeclarationNode.resolveBinding() == null) {
return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.RenameTempRefactoring_must_select_local);
}
if (!Checks.isDeclaredIn(fTempDeclarationNode, MethodDeclaration.class)
&& !Checks.isDeclaredIn(fTempDeclarationNode, Initializer.class)
&& !Checks.isDeclaredIn(fTempDeclarationNode, LambdaExpression.class)) {
if (JavaModelUtil.is18OrHigher(fCu.getJavaProject())) {
return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.RenameTempRefactoring_only_in_methods_initializers_and_lambda);
}
return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.RenameTempRefactoring_only_in_methods_and_initializers);
}
initNames();
return new RefactoringStatus();
}
private ASTNode getEnclosingBodyNode() throws JavaModelException {
ASTNode node = getSelectedExpression().getAssociatedNode();
// expression must be in a method, lambda or initializer body
// make sure it is not in method or parameter annotation
StructuralPropertyDescriptor location = null;
while (node != null && !(node instanceof BodyDeclaration)) {
location = node.getLocationInParent();
node = node.getParent();
if (node instanceof LambdaExpression) {
break;
}
}
if (location == MethodDeclaration.BODY_PROPERTY || location == Initializer.BODY_PROPERTY || (location == LambdaExpression.BODY_PROPERTY && ((LambdaExpression) node).resolveMethodBinding() != null)) {
return (ASTNode) node.getStructuralProperty(location);
}
return null;
}
private boolean isVoidMethod() {
ITypeBinding binding = null;
LambdaExpression enclosingLambdaExpr = ASTResolving.findEnclosingLambdaExpression(getFirstSelectedNode());
if (enclosingLambdaExpr != null) {
IMethodBinding methodBinding = enclosingLambdaExpr.resolveMethodBinding();
if (methodBinding != null) {
binding = methodBinding.getReturnType();
}
} else {
// if we have an initializer
if (fEnclosingMethodBinding == null) {
return true;
}
binding = fEnclosingMethodBinding.getReturnType();
}
if (fEnclosingBodyDeclaration.getAST().resolveWellKnownType("void").equals(binding)) {
return true;
}
return false;
}
private ASTNode getEnclosingBodyNode() throws JavaModelException {
ASTNode node = getSelectedExpression().getAssociatedNode();
// expression must be in a method, lambda or initializer body.
// make sure it is not in method or parameter annotation
StructuralPropertyDescriptor location = null;
while (node != null && !(node instanceof BodyDeclaration)) {
location = node.getLocationInParent();
node = node.getParent();
if (node instanceof LambdaExpression) {
break;
}
}
if (location == MethodDeclaration.BODY_PROPERTY || location == Initializer.BODY_PROPERTY || (location == LambdaExpression.BODY_PROPERTY && ((LambdaExpression) node).resolveMethodBinding() != null)) {
return (ASTNode) node.getStructuralProperty(location);
}
return null;
}
@SuppressWarnings("unchecked")
@Override
public boolean preNext(MethodInvocation curElement) {
List<LambdaExpression> params = (List<LambdaExpression>) curElement.arguments();
compiler.println("par");
boolean isFirst = true;
for (LambdaExpression interaction : params) {
if (isFirst) {
isFirst = false;
} else {
compiler.println("else");
}
interaction.getBody().accept(compiler);
}
return false;
}
private OccurrenceUpdate<? extends ASTNode> createOccurrenceUpdate(ASTNode node, CompilationUnitRewrite cuRewrite, RefactoringStatus result) {
if (BUG_89686 && node instanceof SimpleName && node.getParent() instanceof EnumConstantDeclaration)
node= node.getParent();
if (Invocations.isInvocationWithArguments(node))
return new ReferenceUpdate(node, cuRewrite, result);
else if (node instanceof SimpleName && node.getParent() instanceof MethodDeclaration)
return new DeclarationUpdate((MethodDeclaration) node.getParent(), cuRewrite, result);
else if (node instanceof MemberRef || node instanceof MethodRef)
return new DocReferenceUpdate(node, cuRewrite, result);
else if (ASTNodes.getParent(node, ImportDeclaration.class) != null)
return new StaticImportUpdate((ImportDeclaration) ASTNodes.getParent(node, ImportDeclaration.class), cuRewrite, result);
else if (node instanceof LambdaExpression)
return new LambdaExpressionUpdate((LambdaExpression) node, cuRewrite, result);
else if (node.getLocationInParent() == ExpressionMethodReference.NAME_PROPERTY)
return new ExpressionMethodRefUpdate((ExpressionMethodReference) node.getParent(), cuRewrite, result);
else
return new NullOccurrenceUpdate(node, cuRewrite, result);
}
protected String getFullTypeName() {
ASTNode node= getNode();
while (true) {
node= node.getParent();
if (node instanceof AbstractTypeDeclaration) {
String typeName= ((AbstractTypeDeclaration) node).getName().getIdentifier();
if (getNode() instanceof LambdaExpression) {
return Messages.format(RefactoringCoreMessages.ChangeSignatureRefactoring_lambda_expression, typeName);
}
return typeName;
} else if (node instanceof ClassInstanceCreation) {
ClassInstanceCreation cic= (ClassInstanceCreation) node;
return Messages.format(RefactoringCoreMessages.ChangeSignatureRefactoring_anonymous_subclass, BasicElementLabels.getJavaElementName(ASTNodes.asString(cic.getType())));
} else if (node instanceof EnumConstantDeclaration) {
EnumDeclaration ed= (EnumDeclaration) node.getParent();
return Messages.format(RefactoringCoreMessages.ChangeSignatureRefactoring_anonymous_subclass, BasicElementLabels.getJavaElementName(ASTNodes.asString(ed.getName())));
}
}
}
@Override
public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException {
initAST();
if (fTempDeclarationNode == null || fTempDeclarationNode.resolveBinding() == null)
return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.RenameTempRefactoring_must_select_local);
if (!Checks.isDeclaredIn(fTempDeclarationNode, MethodDeclaration.class)
&& !Checks.isDeclaredIn(fTempDeclarationNode, Initializer.class)
&& !Checks.isDeclaredIn(fTempDeclarationNode, LambdaExpression.class)) {
if (JavaModelUtil.is18OrHigher(fCu.getJavaProject()))
return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.RenameTempRefactoring_only_in_methods_initializers_and_lambda);
return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.RenameTempRefactoring_only_in_methods_and_initializers);
}
initNames();
return new RefactoringStatus();
}
private boolean isVoidMethod() {
ITypeBinding binding= null;
LambdaExpression enclosingLambdaExpr= ASTResolving.findEnclosingLambdaExpression(getFirstSelectedNode());
if (enclosingLambdaExpr != null) {
IMethodBinding methodBinding= enclosingLambdaExpr.resolveMethodBinding();
if (methodBinding != null) {
binding= methodBinding.getReturnType();
}
} else {
// if we have an initializer
if (fEnclosingMethodBinding == null)
return true;
binding= fEnclosingMethodBinding.getReturnType();
}
if (fEnclosingBodyDeclaration.getAST().resolveWellKnownType("void").equals(binding)) //$NON-NLS-1$
return true;
return false;
}
/**
* Returns the type node for the given declaration.
*
* @param declaration the declaration
* @return the type node or <code>null</code> if the given declaration represents a type
* inferred parameter in lambda expression
*/
public static Type getType(VariableDeclaration declaration) {
if (declaration instanceof SingleVariableDeclaration) {
return ((SingleVariableDeclaration)declaration).getType();
} else if (declaration instanceof VariableDeclarationFragment) {
ASTNode parent= ((VariableDeclarationFragment)declaration).getParent();
if (parent instanceof VariableDeclarationExpression)
return ((VariableDeclarationExpression)parent).getType();
else if (parent instanceof VariableDeclarationStatement)
return ((VariableDeclarationStatement)parent).getType();
else if (parent instanceof FieldDeclaration)
return ((FieldDeclaration)parent).getType();
else if (parent instanceof LambdaExpression)
return null;
}
Assert.isTrue(false, "Unknown VariableDeclaration"); //$NON-NLS-1$
return null;
}
public static int getDimensions(VariableDeclaration declaration) {
int dim= declaration.getExtraDimensions();
if (declaration instanceof VariableDeclarationFragment && declaration.getParent() instanceof LambdaExpression) {
LambdaExpression lambda= (LambdaExpression) declaration.getParent();
IMethodBinding methodBinding= lambda.resolveMethodBinding();
if (methodBinding != null) {
ITypeBinding[] parameterTypes= methodBinding.getParameterTypes();
int index= lambda.parameters().indexOf(declaration);
ITypeBinding typeBinding= parameterTypes[index];
return typeBinding.getDimensions();
}
} else {
Type type= getType(declaration);
if (type instanceof ArrayType) {
dim+= ((ArrayType) type).getDimensions();
}
}
return dim;
}
private static Type newType(LambdaExpression lambdaExpression, VariableDeclarationFragment declaration, AST ast, ImportRewrite importRewrite, ImportRewriteContext context) {
IMethodBinding method= lambdaExpression.resolveMethodBinding();
if (method != null) {
ITypeBinding[] parameterTypes= method.getParameterTypes();
int index= lambdaExpression.parameters().indexOf(declaration);
ITypeBinding typeBinding= parameterTypes[index];
if (importRewrite != null) {
return importRewrite.addImport(typeBinding, ast, context);
} else {
String qualifiedName= typeBinding.getQualifiedName();
if (qualifiedName.length() > 0) {
return newType(ast, qualifiedName);
}
}
}
// fall-back
return ast.newSimpleType(ast.newSimpleName("Object")); //$NON-NLS-1$
}
/**
* Returns the new type node representing the return type of <code>lambdaExpression</code>
* including the extra dimensions.
*
* @param lambdaExpression the lambda expression
* @param ast the AST to create the return type with
* @param importRewrite the import rewrite to use, or <code>null</code>
* @param context the import rewrite context, or <code>null</code>
* @return a new type node created with the given AST representing the return type of
* <code>lambdaExpression</code>
*
* @since 3.10
*/
public static Type newReturnType(LambdaExpression lambdaExpression, AST ast, ImportRewrite importRewrite, ImportRewriteContext context) {
IMethodBinding method= lambdaExpression.resolveMethodBinding();
if (method != null) {
ITypeBinding returnTypeBinding= method.getReturnType();
if (importRewrite != null) {
return importRewrite.addImport(returnTypeBinding, ast);
} else {
String qualifiedName= returnTypeBinding.getQualifiedName();
if (qualifiedName.length() > 0) {
return newType(ast, qualifiedName);
}
}
}
// fall-back
return ast.newSimpleType(ast.newSimpleName("Object")); //$NON-NLS-1$
}
private static boolean isLastStatementInEnclosingMethodOrLambda(Statement statement) {
ASTNode currentStructure= statement;
ASTNode currentParent= statement.getParent();
while (!(currentParent instanceof MethodDeclaration || currentParent instanceof LambdaExpression)) {
// should not be in a loop
if (currentParent instanceof ForStatement || currentParent instanceof EnhancedForStatement
|| currentParent instanceof WhileStatement || currentParent instanceof DoStatement) {
return false;
}
if (currentParent instanceof Block) {
Block parentBlock= (Block) currentParent;
if (parentBlock.statements().indexOf(currentStructure) != parentBlock.statements().size() - 1) { // not last statement in the block
return false;
}
}
currentStructure= currentParent;
currentParent= currentParent.getParent();
}
return true;
}
private static IBinding resolveBinding(ASTNode node) {
if (node instanceof SimpleName) {
SimpleName simpleName = (SimpleName) node;
// workaround for https://bugs.eclipse.org/62605 (constructor name resolves to type, not method)
ASTNode normalized = ASTNodes.getNormalizedNode(simpleName);
if (normalized.getLocationInParent() == ClassInstanceCreation.TYPE_PROPERTY) {
ClassInstanceCreation cic = (ClassInstanceCreation) normalized.getParent();
IMethodBinding constructorBinding = cic.resolveConstructorBinding();
if (constructorBinding == null) {
return null;
}
ITypeBinding declaringClass = constructorBinding.getDeclaringClass();
if (!declaringClass.isAnonymous()) {
return constructorBinding;
}
ITypeBinding superTypeDeclaration = declaringClass.getSuperclass().getTypeDeclaration();
return resolveSuperclassConstructor(superTypeDeclaration, constructorBinding);
}
return simpleName.resolveBinding();
} else if (node instanceof SuperConstructorInvocation) {
return ((SuperConstructorInvocation) node).resolveConstructorBinding();
} else if (node instanceof ConstructorInvocation) {
return ((ConstructorInvocation) node).resolveConstructorBinding();
} else if (node instanceof LambdaExpression) {
return ((LambdaExpression) node).resolveMethodBinding();
} else {
return null;
}
}
@Override
public void endVisit(LambdaExpression node) {
if (skipNode(node)) {
return;
}
GenericSequentialFlowInfo info = createSequential(node);
process(info, node.parameters());
process(info, node.getBody());
info.setNoReturn();
}
private static boolean canReplace(IASTFragment fragment) {
ASTNode node = fragment.getAssociatedNode();
ASTNode parent = node.getParent();
if (parent instanceof VariableDeclarationFragment) {
VariableDeclarationFragment vdf = (VariableDeclarationFragment) parent;
if (node.equals(vdf.getName())) {
return false;
}
}
if (isMethodParameter(node)) {
return false;
}
if (isThrowableInCatchBlock(node)) {
return false;
}
if (parent instanceof ExpressionStatement) {
return false;
}
if (parent instanceof LambdaExpression) {
return false;
}
if (isLeftValue(node)) {
return false;
}
if (isReferringToLocalVariableFromFor((Expression) node)) {
return false;
}
if (isUsedInForInitializerOrUpdater((Expression) node)) {
return false;
}
if (parent instanceof SwitchCase) {
return false;
}
return true;
}
private void replaceSelectedExpressionWithTempDeclaration() throws CoreException {
ASTRewrite rewrite = fCURewrite.getASTRewrite();
Expression selectedExpression = getSelectedExpression().getAssociatedExpression(); // whole expression selected
Expression initializer = (Expression) rewrite.createMoveTarget(selectedExpression);
VariableDeclarationStatement tempDeclaration = createTempDeclaration(initializer);
ASTNode replacement;
ASTNode parent = selectedExpression.getParent();
boolean isParentLambda = parent instanceof LambdaExpression;
AST ast = rewrite.getAST();
if (isParentLambda) {
Block blockBody = ast.newBlock();
blockBody.statements().add(tempDeclaration);
if (!Bindings.isVoidType(((LambdaExpression) parent).resolveMethodBinding().getReturnType())) {
List<VariableDeclarationFragment> fragments = tempDeclaration.fragments();
SimpleName varName = fragments.get(0).getName();
ReturnStatement returnStatement = ast.newReturnStatement();
returnStatement.setExpression(ast.newSimpleName(varName.getIdentifier()));
blockBody.statements().add(returnStatement);
}
replacement = blockBody;
} else if (ASTNodes.isControlStatementBody(parent.getLocationInParent())) {
Block block = ast.newBlock();
block.statements().add(tempDeclaration);
replacement = block;
} else {
replacement = tempDeclaration;
}
ASTNode replacee = isParentLambda || !ASTNodes.hasSemicolon((ExpressionStatement) parent, fCu) ? selectedExpression : parent;
rewrite.replace(replacee, replacement, fCURewrite.createGroupDescription(RefactoringCoreMessages.ExtractTempRefactoring_declare_local_variable));
}
private boolean shouldReplaceSelectedExpressionWithTempDeclaration() throws JavaModelException {
IExpressionFragment selectedFragment = getSelectedExpression();
IExpressionFragment firstExpression = getFirstReplacedExpression();
if (firstExpression.getStartPosition() < selectedFragment.getStartPosition()) {
return false;
}
ASTNode associatedNode = selectedFragment.getAssociatedNode();
return (associatedNode.getParent() instanceof ExpressionStatement || associatedNode.getParent() instanceof LambdaExpression) && selectedFragment.matches(ASTFragmentFactory.createFragmentForFullSubtree(associatedNode));
}
@Override
public boolean visit(LambdaExpression node) {
Selection selection = getSelection();
int selectionStart = selection.getOffset();
int selectionExclusiveEnd = selection.getExclusiveEnd();
int lambdaStart = node.getStartPosition();
int lambdaExclusiveEnd = lambdaStart + node.getLength();
ASTNode body = node.getBody();
int bodyStart = body.getStartPosition();
int bodyExclusiveEnd = bodyStart + body.getLength();
boolean isValidSelection = false;
if ((body instanceof Block) && (bodyStart < selectionStart && selectionExclusiveEnd <= bodyExclusiveEnd)) {
// if selection is inside lambda body's block
isValidSelection = true;
} else if (body instanceof Expression) {
try {
TokenScanner scanner = new TokenScanner(fCUnit);
int arrowExclusiveEnd = scanner.getTokenEndOffset(ITerminalSymbols.TokenNameARROW, lambdaStart);
if (selectionStart >= arrowExclusiveEnd) {
isValidSelection = true;
}
} catch (CoreException e) {
// ignore
}
}
if (selectionStart <= lambdaStart && selectionExclusiveEnd >= lambdaExclusiveEnd) {
// if selection covers the lambda node
isValidSelection = true;
}
if (!isValidSelection) {
return false;
}
return super.visit(node);
}
private boolean isDeclaredInLambdaExpression() throws JavaModelException {
ASTNode node = getSelectedExpression().getAssociatedNode();
while (node != null && !(node instanceof BodyDeclaration)) {
node = node.getParent();
if (node instanceof LambdaExpression) {
return true;
}
}
return false;
}
private static boolean canReplace(IASTFragment fragment) {
ASTNode node = fragment.getAssociatedNode();
ASTNode parent = node.getParent();
if (parent instanceof VariableDeclarationFragment) {
VariableDeclarationFragment vdf = (VariableDeclarationFragment) parent;
if (node.equals(vdf.getName())) {
return false;
}
}
if (isMethodParameter(node)) {
return false;
}
if (isThrowableInCatchBlock(node)) {
return false;
}
if (parent instanceof ExpressionStatement) {
return false;
}
if (parent instanceof LambdaExpression) {
return false;
}
if (isLeftValue(node)) {
return false;
}
if (isReferringToLocalVariableFromFor((Expression) node)) {
return false;
}
if (isUsedInForInitializerOrUpdater((Expression) node)) {
return false;
}
if (parent instanceof SwitchCase) {
return false;
}
return true;
}
public boolean visit(VariableDeclarationFragment node) {
if(!(node.getParent() instanceof LambdaExpression)) {
VariableDeclaration variableDeclaration = new VariableDeclaration(cu, filePath, node);
variableDeclarations.add(variableDeclaration);
if(current.getUserObject() != null) {
AnonymousClassDeclarationObject anonymous = (AnonymousClassDeclarationObject)current.getUserObject();
anonymous.getVariableDeclarations().add(variableDeclaration);
}
}
return super.visit(node);
}
public boolean visit(LambdaExpression node) {
LambdaExpressionObject lambda = new LambdaExpressionObject(cu, filePath, node);
lambdas.add(lambda);
if(current.getUserObject() != null) {
AnonymousClassDeclarationObject anonymous = (AnonymousClassDeclarationObject)current.getUserObject();
anonymous.getLambdas().add(lambda);
}
return false;
}
public LambdaExpressionObject(CompilationUnit cu, String filePath, LambdaExpression lambda) {
this.locationInfo = new LocationInfo(cu, filePath, lambda, CodeElementType.LAMBDA_EXPRESSION);
if(lambda.getBody() instanceof Block) {
this.body = new OperationBody(cu, filePath, (Block)lambda.getBody());
}
else if(lambda.getBody() instanceof Expression) {
this.expression = new AbstractExpression(cu, filePath, (Expression)lambda.getBody(), CodeElementType.LAMBDA_EXPRESSION_BODY);
}
}
@Override
public void endVisit(LambdaExpression node) {
if (skipNode(node))
return;
GenericSequentialFlowInfo info= createSequential(node);
process(info, node.parameters());
process(info, node.getBody());
info.setNoReturn();
}
@Override
public boolean visit(LambdaExpression node) {
Selection selection= getSelection();
int selectionStart= selection.getOffset();
int selectionExclusiveEnd= selection.getExclusiveEnd();
int lambdaStart= node.getStartPosition();
int lambdaExclusiveEnd= lambdaStart + node.getLength();
ASTNode body= node.getBody();
int bodyStart= body.getStartPosition();
int bodyExclusiveEnd= bodyStart + body.getLength();
boolean isValidSelection= false;
if ((body instanceof Block) && (bodyStart < selectionStart && selectionExclusiveEnd <= bodyExclusiveEnd)) {
// if selection is inside lambda body's block
isValidSelection= true;
} else if (body instanceof Expression) {
try {
TokenScanner scanner= new TokenScanner(fCUnit);
int arrowExclusiveEnd= scanner.getTokenEndOffset(ITerminalSymbols.TokenNameARROW, lambdaStart);
if (selectionStart >= arrowExclusiveEnd) {
isValidSelection= true;
}
} catch (CoreException e) {
// ignore
}
}
if (selectionStart <= lambdaStart && selectionExclusiveEnd >= lambdaExclusiveEnd) {
// if selection covers the lambda node
isValidSelection= true;
}
if (!isValidSelection) {
return false;
}
return super.visit(node);
}
@Override
public boolean visit(LambdaExpression node) {
/*
* FIXME: Remove this method. It's just a workaround for bug 433426.
* ExceptionAnalyzer forces clients to on the wrong enclosing node (BodyDeclaration instead of LambdaExpression's body).
*/
return true;
}
private static boolean isExplicitlyTypedLambda(Expression expression) {
if (!(expression instanceof LambdaExpression))
return false;
LambdaExpression lambda= (LambdaExpression) expression;
List<VariableDeclaration> parameters= lambda.parameters();
if (parameters.isEmpty())
return true;
return parameters.get(0) instanceof SingleVariableDeclaration;
}