private void processAssignment(ASTNode node, ThisExpression thisExpression, ITypeBinding destinationInterfaceTypeBinding, Expression leftHandSide, Expression rightHandSide) { // if `this` appears on the LHS. if (leftHandSide == thisExpression) { // in this case, we need to check that the RHS can be // assigned to a variable of the destination type. if (!MigrateSkeletalImplementationToInterfaceRefactoringProcessor .isAssignmentCompatible(rightHandSide.resolveTypeBinding(), destinationInterfaceTypeBinding)) this.methodContainsTypeIncompatibleThisReference = true; } else if (rightHandSide == thisExpression) { // otherwise, if `this` appears on the RHS. Then, we // need to check that the LHS can receive a variable of // the destination type. if (!MigrateSkeletalImplementationToInterfaceRefactoringProcessor .isAssignmentCompatible(destinationInterfaceTypeBinding, leftHandSide.resolveTypeBinding())) this.methodContainsTypeIncompatibleThisReference = true; } else throw new IllegalStateException( "this: " + thisExpression + " must appear either on the LHS or RHS of the assignment: " + node); }
@Override public boolean visit(ThisExpression node) { // #153: Precondition missing for compile-time type of this // TODO: #153 There is actually a lot more checks we should add // here. /* * TODO: Actually need to examine every kind of expression where `this` * may appear. #149. Really, type constraints can (or should) be used * for this. Actually, similar to enum problem, especially with finding * the parameter from where the `this` expression came. Assignment is * only one kind of expression, we need to also look at comparison and * switches. */ if (node.getQualifier() != null) this.methodContainsQualifiedThisExpression = true; ASTNode parent = node.getParent(); process(parent, node); return super.visit(node); }
/** {@inheritDoc} */ @Override public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModel model) throws CoreException { ASTRewrite rewrite = cuRewrite.getASTRewrite(); TextEditGroup group = createTextEditGroup(getDescription(), cuRewrite); AST ast = rewrite.getAST(); FieldAccess fieldAccess = ast.newFieldAccess(); ThisExpression thisExpression = ast.newThisExpression(); if (fQualifier != null) thisExpression.setQualifier(ast.newName(fQualifier)); fieldAccess.setExpression(thisExpression); fieldAccess.setName((SimpleName) rewrite.createMoveTarget(fName)); rewrite.replace(fName, fieldAccess, group); }
private void checkMethodDeclaration(RefactoringStatus result, int severity) { MethodDeclaration methodDeclaration = fSourceProvider.getDeclaration(); // it is not allowed to inline constructor invocation only if it is used for class instance // creation // if constructor is invoked from another constructor then we can inline such invocation if (fInvocation.getNodeType() != ASTNode.CONSTRUCTOR_INVOCATION && methodDeclaration.isConstructor()) { result.addEntry( new RefactoringStatusEntry( severity, RefactoringCoreMessages.CallInliner_constructors, JavaStatusContext.create(fCUnit, fInvocation))); } if (fSourceProvider.hasSuperMethodInvocation() && fInvocation.getNodeType() == ASTNode.METHOD_INVOCATION) { Expression receiver = ((MethodInvocation) fInvocation).getExpression(); if (receiver instanceof ThisExpression) { result.addEntry( new RefactoringStatusEntry( severity, RefactoringCoreMessages.CallInliner_super_into_this_expression, JavaStatusContext.create(fCUnit, fInvocation))); } } }
@Override public boolean visit(final ThisExpression node) { Assert.isNotNull(node); Name name= node.getQualifier(); if (fCreateInstanceField && name != null) { ITypeBinding binding= node.resolveTypeBinding(); if (binding != null && Bindings.equals(binding, fTypeBinding.getDeclaringClass())) { AST ast= node.getAST(); Expression expression= null; if (fCodeGenerationSettings.useKeywordThis || fEnclosingInstanceFieldName.equals(fNameForEnclosingInstanceConstructorParameter)) { FieldAccess access= ast.newFieldAccess(); access.setExpression(ast.newThisExpression()); access.setName(ast.newSimpleName(fEnclosingInstanceFieldName)); expression= access; } else { expression= ast.newSimpleName(fEnclosingInstanceFieldName); } fSourceRewrite.getASTRewrite().replace(node, expression, null); } } return super.visit(node); }
private void modifyAccessToMethodsFromEnclosingInstance(CompilationUnitRewrite targetRewrite, MethodInvocation[] methodInvocations, AbstractTypeDeclaration declaration) { IMethodBinding binding= null; MethodInvocation invocation= null; for (int index= 0; index < methodInvocations.length; index++) { invocation= methodInvocations[index]; binding= invocation.resolveMethodBinding(); if (binding != null) { final Expression target= invocation.getExpression(); if (target == null) { final Expression expression= createAccessExpressionToEnclosingInstanceFieldText(invocation, binding, declaration); targetRewrite.getASTRewrite().set(invocation, MethodInvocation.EXPRESSION_PROPERTY, expression, null); } else { if (!(invocation.getExpression() instanceof ThisExpression) || !(((ThisExpression) invocation.getExpression()).getQualifier() != null)) continue; targetRewrite.getASTRewrite().replace(target, createAccessExpressionToEnclosingInstanceFieldText(invocation, binding, declaration), null); targetRewrite.getImportRemover().registerRemovedNode(target); } } } }
private void checkMethodDeclaration(RefactoringStatus result, int severity) { MethodDeclaration methodDeclaration= fSourceProvider.getDeclaration(); // it is not allowed to inline constructor invocation only if it is used for class instance creation // if constructor is invoked from another constructor then we can inline such invocation if (fInvocation.getNodeType() != ASTNode.CONSTRUCTOR_INVOCATION && methodDeclaration.isConstructor()) { result.addEntry(new RefactoringStatusEntry( severity, RefactoringCoreMessages.CallInliner_constructors, JavaStatusContext.create(fCUnit, fInvocation))); } if (fSourceProvider.hasSuperMethodInvocation() && fInvocation.getNodeType() == ASTNode.METHOD_INVOCATION) { Expression receiver= ((MethodInvocation)fInvocation).getExpression(); if (receiver instanceof ThisExpression) { result.addEntry(new RefactoringStatusEntry( severity, RefactoringCoreMessages.CallInliner_super_into_this_expression, JavaStatusContext.create(fCUnit, fInvocation))); } } }
private MethodDeclaration createGetOuterHelper() { String outerTypeName= fType.getDeclaringClass().getTypeDeclaration().getName(); MethodDeclaration helperMethod= fAst.newMethodDeclaration(); helperMethod.modifiers().addAll(ASTNodeFactory.newModifiers(fAst, Modifier.PRIVATE)); helperMethod.setName(fAst.newSimpleName(METHODNAME_OUTER_TYPE)); helperMethod.setConstructor(false); helperMethod.setReturnType2(fAst.newSimpleType(fAst.newSimpleName(outerTypeName))); Block body= fAst.newBlock(); helperMethod.setBody(body); ThisExpression thisExpression= fAst.newThisExpression(); thisExpression.setQualifier(fAst.newSimpleName(outerTypeName)); ReturnStatement endReturn= fAst.newReturnStatement(); endReturn.setExpression(thisExpression); body.statements().add(endReturn); return helperMethod; }
/** * {@inheritDoc} */ @Override public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModel model) throws CoreException { ASTRewrite rewrite= cuRewrite.getASTRewrite(); TextEditGroup group= createTextEditGroup(getDescription(), cuRewrite); AST ast= rewrite.getAST(); FieldAccess fieldAccess= ast.newFieldAccess(); ThisExpression thisExpression= ast.newThisExpression(); if (fQualifier != null) thisExpression.setQualifier(ast.newName(fQualifier)); fieldAccess.setExpression(thisExpression); fieldAccess.setName((SimpleName) rewrite.createMoveTarget(fName)); rewrite.replace(fName, fieldAccess, group); }
private void qualifyThisExpressions(ASTNode node, final ASTRewrite rewrite, final ImportRewrite importRewrite, final ImportRewriteContext importRewriteContext) { node.accept(new GenericVisitor() { /** * {@inheritDoc} */ @Override public boolean visit(ThisExpression thisExpr) { if (thisExpr.getQualifier() == null) { ITypeBinding typeBinding= thisExpr.resolveTypeBinding(); if (typeBinding != null) { String typeName= importRewrite.addImport(typeBinding.getTypeDeclaration(), importRewriteContext); SimpleName simpleName= thisExpr.getAST().newSimpleName(typeName); rewrite.set(thisExpr, ThisExpression.QUALIFIER_PROPERTY, simpleName, null); } } return super.visit(thisExpr); } }); }
@Override public boolean visit(final ThisExpression node) { Assert.isNotNull(node); final Name name= node.getQualifier(); if (name != null && name.isSimpleName()) { final AST ast= node.getAST(); Expression expression= null; if (fCodeGenerationSettings.useKeywordThis || fEnclosingInstanceFieldName.equals(fNameForEnclosingInstanceConstructorParameter)) { final FieldAccess access= ast.newFieldAccess(); access.setExpression(ast.newThisExpression()); access.setName(ast.newSimpleName(fEnclosingInstanceFieldName)); expression= access; } else expression= ast.newSimpleName(fEnclosingInstanceFieldName); fSourceRewrite.getASTRewrite().replace(node, expression, null); } return super.visit(node); }
/** * [ClassName '.'] this */ @Override public boolean visit(final ThisExpression node) { ASTNode enclosing = null; if (node.getQualifier() != null) { enclosing = ASTTools.enclosingTypeScope(node, node.getQualifier()); } else { enclosing = ASTTools.enclosingTypeScope(node); } if (enclosing instanceof AbstractTypeDeclaration) { uses.add(factory.newResolvedThisVariable(node, (AbstractTypeDeclaration) enclosing, qualifierOf, isLHS, isActual)); } else { uses.add(factory.newResolvedThisVariable(node, (AnonymousClassDeclaration) enclosing, qualifierOf, isLHS, isActual)); } // do not visit children return false; }
@Override public void endVisit(ThisExpression node) { if (skipNode(node)) { return; } assignFlowInfo(node, node.getQualifier()); }
private ASTNode[] createCallNodes(SnippetFinder.Match duplicate, int modifiers) { List<ASTNode> result = new ArrayList<>(2); IVariableBinding[] locals = fAnalyzer.getCallerLocals(); for (int i = 0; i < locals.length; i++) { result.add(createDeclaration(locals[i], null)); } MethodInvocation invocation = fAST.newMethodInvocation(); invocation.setName(fAST.newSimpleName(fMethodName)); ASTNode typeNode = ASTResolving.findParentType(fAnalyzer.getEnclosingBodyDeclaration()); RefactoringStatus status = new RefactoringStatus(); while (fDestination != typeNode) { fAnalyzer.checkInput(status, fMethodName, typeNode); if (!status.isOK()) { SimpleName destinationTypeName = fAST.newSimpleName(ASTNodes.getEnclosingType(fDestination).getName()); if ((modifiers & Modifier.STATIC) == 0) { ThisExpression thisExpression = fAST.newThisExpression(); thisExpression.setQualifier(destinationTypeName); invocation.setExpression(thisExpression); } else { invocation.setExpression(destinationTypeName); } break; } typeNode = typeNode.getParent(); } List<Expression> arguments = invocation.arguments(); for (int i = 0; i < fParameterInfos.size(); i++) { ParameterInfo parameter = fParameterInfos.get(i); arguments.add(ASTNodeFactory.newName(fAST, getMappedName(duplicate, parameter))); } if (fLinkedProposalModel != null) { LinkedProposalPositionGroup nameGroup = fLinkedProposalModel.getPositionGroup(KEY_NAME, true); nameGroup.addPosition(fRewriter.track(invocation.getName()), false); } ASTNode call; int returnKind = fAnalyzer.getReturnKind(); switch (returnKind) { case ExtractMethodAnalyzer.ACCESS_TO_LOCAL: IVariableBinding binding = fAnalyzer.getReturnLocal(); if (binding != null) { VariableDeclarationStatement decl = createDeclaration(getMappedBinding(duplicate, binding), invocation); call = decl; } else { Assignment assignment = fAST.newAssignment(); assignment.setLeftHandSide(ASTNodeFactory.newName(fAST, getMappedBinding(duplicate, fAnalyzer.getReturnValue()).getName())); assignment.setRightHandSide(invocation); call = assignment; } break; case ExtractMethodAnalyzer.RETURN_STATEMENT_VALUE: ReturnStatement rs = fAST.newReturnStatement(); rs.setExpression(invocation); call = rs; break; default: call = invocation; } if (call instanceof Expression && !fAnalyzer.isExpressionSelected()) { call = fAST.newExpressionStatement((Expression) call); } result.add(call); // We have a void return statement. The code looks like // extracted(); // return; if (returnKind == ExtractMethodAnalyzer.RETURN_STATEMENT_VOID && !fAnalyzer.isLastStatementSelected()) { result.add(fAST.newReturnStatement()); } return result.toArray(new ASTNode[result.size()]); }
private static void addQualifierToOuterProposal(IInvocationContext context, MethodInvocation invocationNode, IMethodBinding binding, Collection<CUCorrectionProposal> proposals) { ITypeBinding declaringType= binding.getDeclaringClass(); ITypeBinding parentType= Bindings.getBindingOfParentType(invocationNode); ITypeBinding currType= parentType; boolean isInstanceMethod= !Modifier.isStatic(binding.getModifiers()); while (currType != null && !Bindings.isSuperType(declaringType, currType)) { if (isInstanceMethod && Modifier.isStatic(currType.getModifiers())) { return; } currType= currType.getDeclaringClass(); } if (currType == null || currType == parentType) { return; } ASTRewrite rewrite= ASTRewrite.create(invocationNode.getAST()); String label = Messages.format(CorrectionMessages.UnresolvedElementsSubProcessor_changetoouter_description, ASTResolving.getTypeSignature(currType)); ASTRewriteCorrectionProposal proposal = new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, IProposalRelevance.QUALIFY_WITH_ENCLOSING_TYPE); ImportRewrite imports= proposal.createImportRewrite(context.getASTRoot()); ImportRewriteContext importRewriteContext= new ContextSensitiveImportRewriteContext(invocationNode, imports); AST ast= invocationNode.getAST(); String qualifier= imports.addImport(currType, importRewriteContext); Name name= ASTNodeFactory.newName(ast, qualifier); Expression newExpression; if (isInstanceMethod) { ThisExpression expr= ast.newThisExpression(); expr.setQualifier(name); newExpression= expr; } else { newExpression= name; } rewrite.set(invocationNode, MethodInvocation.EXPRESSION_PROPERTY, newExpression, null); proposals.add(proposal); }
/** {@inheritDoc} */ @Override public boolean visit(final MethodInvocation node) { if (!fRemoveMethodQualifiers) return true; Expression expression = node.getExpression(); if (!(expression instanceof ThisExpression)) return true; final SimpleName name = node.getName(); if (name.resolveBinding() == null) return true; if (hasConflict( expression.getStartPosition(), name, ScopeAnalyzer.METHODS | ScopeAnalyzer.CHECK_VISIBILITY)) return true; Name qualifier = ((ThisExpression) expression).getQualifier(); if (qualifier != null) { ITypeBinding declaringClass = ((IMethodBinding) name.resolveBinding()).getDeclaringClass(); if (declaringClass == null) return true; ITypeBinding caller = getDeclaringType(node); if (caller == null) return true; ITypeBinding callee = (ITypeBinding) qualifier.resolveBinding(); if (callee == null) return true; if (callee.isAssignmentCompatible(declaringClass) && caller.isAssignmentCompatible(declaringClass)) return true; } fOperations.add( new CompilationUnitRewriteOperation() { @Override public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModel model) throws CoreException { ASTRewrite rewrite = cuRewrite.getASTRewrite(); TextEditGroup group = createTextEditGroup( FixMessages.CodeStyleFix_removeThis_groupDescription, cuRewrite); rewrite.remove(node.getExpression(), group); } }); return super.visit(node); }
private Expression getSimpleNameReceiver(SimpleName node) { Expression receiver; if (node.getParent() instanceof QualifiedName && node.getLocationInParent() == QualifiedName.NAME_PROPERTY) { receiver = ((QualifiedName) node.getParent()).getQualifier(); } else if (node.getParent() instanceof FieldAccess && node.getLocationInParent() == FieldAccess.NAME_PROPERTY) { receiver = ((FieldAccess) node.getParent()).getExpression(); } else { // TODO other cases? (ThisExpression, SuperAccessExpression, ...) receiver = null; } if (receiver instanceof ThisExpression) return null; else return receiver; }
@Override public boolean visit(ThisExpression node) { if (node.getQualifier() != null) { status.addFatalError( RefactoringCoreMessages .InlineMethodRefactoring_SourceAnalyzer_qualified_this_expressions, JavaStatusContext.create(fTypeRoot, node)); return false; } return true; }
@Override public boolean visit(ThisExpression node) { if (fTypeCounter == 0) { fImplicitReceivers.add(node); } return true; }
private RefactoringStatus updateMethodInvocation( MethodInvocation originalInvocation, IMember enclosing, CompilationUnitRewrite unitRewriter) throws JavaModelException { RefactoringStatus status = new RefactoringStatus(); // If the method invocation utilizes type arguments, skip this // call as the new target method may have additional parameters if (originalInvocation.typeArguments().size() > 0) return createWarningAboutCall( enclosing, originalInvocation, RefactoringCoreMessages.IntroduceIndirectionRefactoring_call_warning_type_arguments); MethodInvocation newInvocation = unitRewriter.getAST().newMethodInvocation(); List<Expression> newInvocationArgs = newInvocation.arguments(); List<Expression> originalInvocationArgs = originalInvocation.arguments(); // static call => always use a qualifier String qualifier = unitRewriter.getImportRewrite().addImport(fIntermediaryTypeBinding); newInvocation.setExpression(ASTNodeFactory.newName(unitRewriter.getAST(), qualifier)); newInvocation.setName(unitRewriter.getAST().newSimpleName(getIntermediaryMethodName())); final Expression expression = originalInvocation.getExpression(); if (!isStaticTarget()) { // Add the expression as the first parameter if (expression == null) { // There is no expression for this call. Use a (possibly qualified) "this" expression. ThisExpression expr = unitRewriter.getAST().newThisExpression(); RefactoringStatus qualifierStatus = qualifyThisExpression(expr, originalInvocation, enclosing, unitRewriter); status.merge(qualifierStatus); if (qualifierStatus.hasEntries()) // warning means don't include this invocation return status; newInvocationArgs.add(expr); } else { Expression expressionAsParam = (Expression) unitRewriter.getASTRewrite().createMoveTarget(expression); newInvocationArgs.add(expressionAsParam); } } else { if (expression != null) { // Check if expression is the type name. If not, there may // be side effects (e.g. inside methods) -> don't update if (!(expression instanceof Name) || ASTNodes.getTypeBinding((Name) expression) == null) return createWarningAboutCall( enclosing, originalInvocation, RefactoringCoreMessages .IntroduceIndirectionRefactoring_call_warning_static_expression_access); } } for (int i = 0; i < originalInvocationArgs.size(); i++) { Expression originalInvocationArg = originalInvocationArgs.get(i); Expression movedArg = (Expression) unitRewriter.getASTRewrite().createMoveTarget(originalInvocationArg); newInvocationArgs.add(movedArg); } unitRewriter .getASTRewrite() .replace( originalInvocation, newInvocation, unitRewriter.createGroupDescription( RefactoringCoreMessages .IntroduceIndirectionRefactoring_group_description_replace_call)); return status; }
private void computeReceiver() throws BadLocationException { Expression receiver = Invocations.getExpression(fInvocation); if (receiver == null) return; final boolean isName = receiver instanceof Name; if (isName) fContext.receiverIsStatic = ((Name) receiver).resolveBinding() instanceof ITypeBinding; if (ASTNodes.isLiteral(receiver) || isName || receiver instanceof ThisExpression) { fContext.receiver = fBuffer.getDocument().get(receiver.getStartPosition(), receiver.getLength()); return; } switch (fSourceProvider.getReceiversToBeUpdated()) { case 0: // Make sure we evaluate the current receiver. Best is to assign to // local. fLocals.add( createLocalDeclaration( receiver.resolveTypeBinding(), fInvocationScope.createName("r", true), // $NON-NLS-1$ (Expression) fRewrite.createCopyTarget(receiver))); return; case 1: fContext.receiver = fBuffer.getDocument().get(receiver.getStartPosition(), receiver.getLength()); return; default: String local = fInvocationScope.createName("r", true); // $NON-NLS-1$ fLocals.add( createLocalDeclaration( receiver.resolveTypeBinding(), local, (Expression) fRewrite.createCopyTarget(receiver))); fContext.receiver = local; return; } }
private ASTNode[] createCallNodes(SnippetFinder.Match duplicate, int modifiers) { List<ASTNode> result = new ArrayList<ASTNode>(2); IVariableBinding[] locals = fAnalyzer.getCallerLocals(); for (int i = 0; i < locals.length; i++) { result.add(createDeclaration(locals[i], null)); } MethodInvocation invocation = fAST.newMethodInvocation(); invocation.setName(fAST.newSimpleName(fMethodName)); ASTNode typeNode = ASTResolving.findParentType(fAnalyzer.getEnclosingBodyDeclaration()); RefactoringStatus status = new RefactoringStatus(); while (fDestination != typeNode) { fAnalyzer.checkInput(status, fMethodName, typeNode); if (!status.isOK()) { SimpleName destinationTypeName = fAST.newSimpleName(ASTNodes.getEnclosingType(fDestination).getName()); if ((modifiers & Modifier.STATIC) == 0) { ThisExpression thisExpression = fAST.newThisExpression(); thisExpression.setQualifier(destinationTypeName); invocation.setExpression(thisExpression); } else { invocation.setExpression(destinationTypeName); } break; } typeNode = typeNode.getParent(); } List<Expression> arguments = invocation.arguments(); for (int i = 0; i < fParameterInfos.size(); i++) { ParameterInfo parameter = fParameterInfos.get(i); arguments.add(ASTNodeFactory.newName(fAST, getMappedName(duplicate, parameter))); } if (fLinkedProposalModel != null) { LinkedProposalPositionGroup nameGroup = fLinkedProposalModel.getPositionGroup(KEY_NAME, true); nameGroup.addPosition(fRewriter.track(invocation.getName()), false); } ASTNode call; int returnKind = fAnalyzer.getReturnKind(); switch (returnKind) { case ExtractMethodAnalyzer.ACCESS_TO_LOCAL: IVariableBinding binding = fAnalyzer.getReturnLocal(); if (binding != null) { VariableDeclarationStatement decl = createDeclaration(getMappedBinding(duplicate, binding), invocation); call = decl; } else { Assignment assignment = fAST.newAssignment(); assignment.setLeftHandSide( ASTNodeFactory.newName( fAST, getMappedBinding(duplicate, fAnalyzer.getReturnValue()).getName())); assignment.setRightHandSide(invocation); call = assignment; } break; case ExtractMethodAnalyzer.RETURN_STATEMENT_VALUE: ReturnStatement rs = fAST.newReturnStatement(); rs.setExpression(invocation); call = rs; break; default: call = invocation; } if (call instanceof Expression && !fAnalyzer.isExpressionSelected()) { call = fAST.newExpressionStatement((Expression) call); } result.add(call); // We have a void return statement. The code looks like // extracted(); // return; if (returnKind == ExtractMethodAnalyzer.RETURN_STATEMENT_VOID && !fAnalyzer.isLastStatementSelected()) { result.add(fAST.newReturnStatement()); } return result.toArray(new ASTNode[result.size()]); }
@Override public ITypeConstraint[] create(ThisExpression expression) { ConstraintVariable thisExpression = fConstraintVariableFactory.makeExpressionOrTypeVariable(expression, getContext()); ConstraintVariable declaringType = fConstraintVariableFactory.makeRawBindingVariable( expression .resolveTypeBinding()); // TODO fix this - can't use Decl(M) because 'this' can live // outside of methods return fTypeConstraintFactory.createDefinesConstraint(thisExpression, declaringType); }
private static void addQualifierToOuterProposal( IInvocationContext context, MethodInvocation invocationNode, IMethodBinding binding, Collection<ICommandAccess> proposals) { ITypeBinding declaringType = binding.getDeclaringClass(); ITypeBinding parentType = Bindings.getBindingOfParentType(invocationNode); ITypeBinding currType = parentType; boolean isInstanceMethod = !Modifier.isStatic(binding.getModifiers()); while (currType != null && !Bindings.isSuperType(declaringType, currType)) { if (isInstanceMethod && Modifier.isStatic(currType.getModifiers())) { return; } currType = currType.getDeclaringClass(); } if (currType == null || currType == parentType) { return; } ASTRewrite rewrite = ASTRewrite.create(invocationNode.getAST()); String label = Messages.format( CorrectionMessages.UnresolvedElementsSubProcessor_changetoouter_description, ASTResolving.getTypeSignature(currType)); Image image = JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE); ASTRewriteCorrectionProposal proposal = new ASTRewriteCorrectionProposal( label, context.getCompilationUnit(), rewrite, IProposalRelevance.QUALIFY_WITH_ENCLOSING_TYPE, image); ImportRewrite imports = proposal.createImportRewrite(context.getASTRoot()); ImportRewriteContext importRewriteContext = new ContextSensitiveImportRewriteContext(invocationNode, imports); AST ast = invocationNode.getAST(); String qualifier = imports.addImport(currType, importRewriteContext); Name name = ASTNodeFactory.newName(ast, qualifier); Expression newExpression; if (isInstanceMethod) { ThisExpression expr = ast.newThisExpression(); expr.setQualifier(name); newExpression = expr; } else { newExpression = name; } rewrite.set(invocationNode, MethodInvocation.EXPRESSION_PROPERTY, newExpression, null); proposals.add(proposal); }
@Override public boolean visit(ThisExpression node) { final Name qualifier= node.getQualifier(); if (qualifier != null) { final ITypeBinding binding= qualifier.resolveTypeBinding(); if (binding != null && binding != fCurrentType.getTypeDeclaration()) { fSimpleNames.add(qualifier); } } return super.visit(node); }
private Expression createEnclosingInstanceCreationString(final ASTNode node, final ICompilationUnit cu) throws JavaModelException { Assert.isTrue((node instanceof ClassInstanceCreation) || (node instanceof SuperConstructorInvocation)); Assert.isNotNull(cu); Expression expression= null; if (node instanceof ClassInstanceCreation) expression= ((ClassInstanceCreation) node).getExpression(); else expression= ((SuperConstructorInvocation) node).getExpression(); final AST ast= node.getAST(); if (expression != null) return expression; else if (JdtFlags.isStatic(fType)) return null; else if (isInsideSubclassOfDeclaringType(node)) return ast.newThisExpression(); else if ((node.getStartPosition() >= fType.getSourceRange().getOffset() && ASTNodes.getExclusiveEnd(node) <= fType.getSourceRange().getOffset() + fType.getSourceRange().getLength())) { if (fCodeGenerationSettings.useKeywordThis || fEnclosingInstanceFieldName.equals(fNameForEnclosingInstanceConstructorParameter)) { final FieldAccess access= ast.newFieldAccess(); access.setExpression(ast.newThisExpression()); access.setName(ast.newSimpleName(fEnclosingInstanceFieldName)); return access; } else return ast.newSimpleName(fEnclosingInstanceFieldName); } else if (isInsideTypeNestedInDeclaringType(node)) { final ThisExpression qualified= ast.newThisExpression(); qualified.setQualifier(ast.newSimpleName(fType.getDeclaringType().getElementName())); return qualified; } return null; }
private Expression createQualifiedReadAccessExpressionForEnclosingInstance(AST ast) { ThisExpression expression= ast.newThisExpression(); expression.setQualifier(ast.newName(new String[] { fType.getElementName()})); FieldAccess access= ast.newFieldAccess(); access.setExpression(expression); access.setName(ast.newSimpleName(fEnclosingInstanceFieldName)); return access; }
@Override public final boolean visit(final ThisExpression node) { Assert.isNotNull(node); if (node.getQualifier() != null) { fStatus.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_refers_enclosing_instances, JavaStatusContext.create(fMethod.getCompilationUnit(), node))); fResult.add(node); } return false; }
@Override public final boolean visit(final FieldAccess node) { Assert.isNotNull(node); final Expression expression= node.getExpression(); final IVariableBinding variable= node.resolveFieldBinding(); final AST ast= fRewrite.getAST(); if (expression instanceof ThisExpression) { if (Bindings.equals(fTarget, variable)) { if (fAnonymousClass > 0) { final ThisExpression target= ast.newThisExpression(); target.setQualifier(ast.newSimpleName(fTargetType.getElementName())); fRewrite.replace(node, target, null); } else fRewrite.replace(node, ast.newThisExpression(), null); return false; } else { expression.accept(this); return false; } } else if (expression instanceof FieldAccess) { final FieldAccess access= (FieldAccess) expression; final IBinding binding= access.getName().resolveBinding(); if (access.getExpression() instanceof ThisExpression && Bindings.equals(fTarget, binding)) { ASTNode newFieldAccess= getFieldReference(node.getName(), fRewrite); fRewrite.replace(node, newFieldAccess, null); return false; } } else if (expression != null) { expression.accept(this); return false; } return true; }
@Override public final boolean visit(final FieldAccess node) { Assert.isNotNull(node); if (node.getExpression() instanceof ThisExpression) { final IVariableBinding binding= (IVariableBinding) node.getName().resolveBinding(); if (binding != null) { final String key= binding.getKey(); if (!fFound.contains(key)) { fFound.add(key); fBindings.add(binding); } } } return true; }
@Override public final boolean visit(final MethodInvocation node) { Assert.isNotNull(node); final Expression expression= node.getExpression(); final IMethodBinding binding= node.resolveMethodBinding(); if (binding == null || !Modifier.isStatic(binding.getModifiers()) && Bindings.equals(binding, fBinding) && (expression == null || expression instanceof ThisExpression)) { fStatus.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_potentially_recursive, JavaStatusContext.create(fMethod.getCompilationUnit(), node))); fResult.add(node); return false; } return true; }
@Override public final boolean visit(final ThisExpression node) { Assert.isNotNull(node); fResult.add(node); fStatus.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_this_reference, JavaStatusContext.create(fMethod.getCompilationUnit(), node))); return false; }
@Override public final boolean visit(final SuperMethodInvocation node) { if (!fAnonymousClassDeclaration && !fTypeDeclarationStatement) { final IBinding superBinding= node.getName().resolveBinding(); if (superBinding instanceof IMethodBinding) { final IMethodBinding extended= (IMethodBinding) superBinding; if (fEnclosingMethod != null && fEnclosingMethod.overrides(extended)) return true; final ITypeBinding declaringBinding= extended.getDeclaringClass(); if (declaringBinding != null) { final IType type= (IType) declaringBinding.getJavaElement(); if (!fSuperReferenceType.equals(type)) return true; } } final AST ast= node.getAST(); final ThisExpression expression= ast.newThisExpression(); final MethodInvocation invocation= ast.newMethodInvocation(); final SimpleName simple= ast.newSimpleName(node.getName().getIdentifier()); invocation.setName(simple); invocation.setExpression(expression); final List<Expression> arguments= node.arguments(); if (arguments != null && arguments.size() > 0) { final ListRewrite rewriter= fRewrite.getListRewrite(invocation, MethodInvocation.ARGUMENTS_PROPERTY); ListRewrite superRewriter= fRewrite.getListRewrite(node, SuperMethodInvocation.ARGUMENTS_PROPERTY); ASTNode copyTarget= superRewriter.createCopyTarget(arguments.get(0), arguments.get(arguments.size() - 1)); rewriter.insertLast(copyTarget, null); } fRewrite.replace(node, invocation, null); if (!fSourceRewriter.getCu().equals(fTargetRewriter.getCu())) fSourceRewriter.getImportRemover().registerRemovedNode(node); return true; } return false; }
private Expression getSimpleNameReceiver(SimpleName node) { Expression receiver; if (node.getParent() instanceof QualifiedName && node.getLocationInParent() == QualifiedName.NAME_PROPERTY) { receiver= ((QualifiedName) node.getParent()).getQualifier(); } else if (node.getParent() instanceof FieldAccess && node.getLocationInParent() == FieldAccess.NAME_PROPERTY) { receiver= ((FieldAccess) node.getParent()).getExpression(); } else { //TODO other cases? (ThisExpression, SuperAccessExpression, ...) receiver= null; } if (receiver instanceof ThisExpression) return null; else return receiver; }
@Override public boolean visit(ThisExpression node) { if (node.getQualifier() != null) { status.addFatalError( RefactoringCoreMessages.InlineMethodRefactoring_SourceAnalyzer_qualified_this_expressions, JavaStatusContext.create(fTypeRoot, node)); return false; } return true; }