下面列出了org.eclipse.jdt.core.dom.ASTNode#getNodeType ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public boolean consumes(SemanticToken token) {
// 1: match types
SimpleName name = token.getNode();
ASTNode node = name.getParent();
int nodeType = node.getNodeType();
if (nodeType != ASTNode.SIMPLE_TYPE && nodeType != ASTNode.THIS_EXPRESSION && nodeType != ASTNode.QUALIFIED_TYPE && nodeType != ASTNode.QUALIFIED_NAME && nodeType != ASTNode.TYPE_DECLARATION
&& nodeType != ASTNode.METHOD_INVOCATION) {
return false;
}
while (nodeType == ASTNode.QUALIFIED_NAME) {
node = node.getParent();
nodeType = node.getNodeType();
if (nodeType == ASTNode.IMPORT_DECLARATION) {
return false;
}
}
// 2: match classes
IBinding binding = token.getBinding();
return binding instanceof ITypeBinding && ((ITypeBinding) binding).isClass();
}
public static Expression getExpression(ASTNode invocation) {
switch (invocation.getNodeType()) {
case ASTNode.METHOD_INVOCATION:
return ((MethodInvocation)invocation).getExpression();
case ASTNode.SUPER_METHOD_INVOCATION:
return null;
case ASTNode.CONSTRUCTOR_INVOCATION:
return null;
case ASTNode.SUPER_CONSTRUCTOR_INVOCATION:
return ((SuperConstructorInvocation)invocation).getExpression();
case ASTNode.CLASS_INSTANCE_CREATION:
return ((ClassInstanceCreation)invocation).getExpression();
case ASTNode.ENUM_CONSTANT_DECLARATION:
return null;
default:
throw new IllegalArgumentException(invocation.toString());
}
}
private static void insertToCu(ASTRewrite rewrite, ASTNode node, CompilationUnit cuNode) {
switch (node.getNodeType()) {
case ASTNode.TYPE_DECLARATION:
case ASTNode.ENUM_DECLARATION:
case ASTNode.ANNOTATION_TYPE_DECLARATION:
rewrite.getListRewrite(cuNode, CompilationUnit.TYPES_PROPERTY).insertAt(node, ASTNodes.getInsertionIndex((AbstractTypeDeclaration) node, cuNode.types()), null);
break;
case ASTNode.IMPORT_DECLARATION:
rewrite.getListRewrite(cuNode, CompilationUnit.IMPORTS_PROPERTY).insertLast(node, null);
break;
case ASTNode.PACKAGE_DECLARATION:
// only insert if none exists
if (cuNode.getPackage() == null)
rewrite.set(cuNode, CompilationUnit.PACKAGE_PROPERTY, node, null);
break;
default:
Assert.isTrue(false, String.valueOf(node.getNodeType()));
}
}
@Override
public boolean consumes(SemanticToken token) {
// 1: match types in type parameter lists
SimpleName name = token.getNode();
ASTNode node = name.getParent();
if (node.getNodeType() != ASTNode.SIMPLE_TYPE && node.getNodeType() != ASTNode.TYPE_PARAMETER) {
return false;
}
// 2: match generic type variable references
IBinding binding = token.getBinding();
return binding instanceof ITypeBinding && ((ITypeBinding) binding).isTypeVariable();
}
@Override
public void preVisit(final ASTNode node) {
// If node is a foldableType add node to foldableStack and
// add fold to allFolds
if (foldableTypes.contains(node.getNodeType())) {
final FoldableNode fn = tree.new FoldableNode(node);
// If node is also a javadoc, add its range to javadocFolds
// along with first line of javadoc comment
if (node.getNodeType() == ASTNode.JAVADOC) {
final Javadoc jdoc = (Javadoc) node;
String firstTagLine = "";
if (!jdoc.tags().isEmpty()) { // Handle empty comment
final String firstTag = ((TagElement) jdoc.tags().get(0)).toString();
firstTagLine = firstTag.split("\n")[1].substring(2);
// If tokenizing comments add javadoc tokens to tree
if (tokenizeComments)
fn.addTerms(tokenizeCommentString(firstTag));
}
javadocFolds.put(fn.getRange(), firstTagLine);
}
foldableStack.push(fn);
allFolds.add(fn.getRange());
}
}
public boolean hasCorrectNesting(ASTNode node) {
if (fNodes.size() == 0)
return true;
ASTNode parent= node.getParent();
if(fNodes.get(0).getParent() != parent)
return false;
// Here we know that we have two elements. In this case the
// parent must be a block or a switch statement. Otherwise a
// snippet like "if (true) foo(); else foo();" would match
// the pattern "foo(); foo();"
int nodeType= parent.getNodeType();
return nodeType == ASTNode.BLOCK || nodeType == ASTNode.SWITCH_STATEMENT;
}
@Override
public boolean visit(final SingleVariableDeclaration node) {
final ASTNode parent = node.getParent();
if (parent.getNodeType() == ASTNode.METHOD_DECLARATION) {
variableScopes.put(parent, new Variable(node.getName()
.getIdentifier(), node.getType().toString(),
ScopeType.SCOPE_METHOD));
} else {
variableScopes.put(parent, new Variable(node.getName()
.getIdentifier(), node.getType().toString(),
ScopeType.SCOPE_LOCAL));
}
return false;
}
private static boolean hasSideEffect(SimpleName reference) {
ASTNode parent= reference.getParent();
while (parent instanceof QualifiedName) {
parent= parent.getParent();
}
if (parent instanceof FieldAccess) {
parent= parent.getParent();
}
ASTNode node= null;
int nameParentType= parent.getNodeType();
if (nameParentType == ASTNode.ASSIGNMENT) {
Assignment assignment= (Assignment) parent;
node= assignment.getRightHandSide();
} else if (nameParentType == ASTNode.SINGLE_VARIABLE_DECLARATION) {
SingleVariableDeclaration decl= (SingleVariableDeclaration)parent;
node= decl.getInitializer();
if (node == null)
return false;
} else if (nameParentType == ASTNode.VARIABLE_DECLARATION_FRAGMENT) {
node= parent;
} else {
return false;
}
ArrayList<Expression> sideEffects= new ArrayList<Expression>();
node.accept(new SideEffectFinder(sideEffects));
return sideEffects.size() > 0;
}
private static boolean isMultiDeclarationFragment(ASTNode node) {
int nodeType= node.getNodeType();
if (nodeType == ASTNode.VARIABLE_DECLARATION_FRAGMENT) {
node= node.getParent();
if (node.getNodeType() == ASTNode.VARIABLE_DECLARATION_STATEMENT) {
VariableDeclarationStatement vs= (VariableDeclarationStatement)node;
return vs.fragments().size() > 1;
}
}
return false;
}
private RefactoringStatus replaceReferences(ParameterObjectFactory pof, SearchResultGroup group, CompilationUnitRewrite cuRewrite) {
TextEditGroup writeGroup= cuRewrite.createGroupDescription(RefactoringCoreMessages.ExtractClassRefactoring_group_replace_write);
TextEditGroup readGroup= cuRewrite.createGroupDescription(RefactoringCoreMessages.ExtractClassRefactoring_group_replace_read);
ITypeRoot typeRoot= cuRewrite.getCu();
IJavaProject javaProject= typeRoot.getJavaProject();
AST ast= cuRewrite.getAST();
RefactoringStatus status= new RefactoringStatus();
String parameterName= fDescriptor.getFieldName();
SearchMatch[] searchResults= group.getSearchResults();
for (int j= 0; j < searchResults.length; j++) {
SearchMatch searchMatch= searchResults[j];
ASTNode node= NodeFinder.perform(cuRewrite.getRoot(), searchMatch.getOffset(), searchMatch.getLength());
ASTNode parent= node.getParent();
boolean isDeclaration= parent instanceof VariableDeclaration && ((VariableDeclaration)parent).getInitializer() != node;
if (!isDeclaration && node instanceof SimpleName) {
ASTRewrite rewrite= cuRewrite.getASTRewrite();
if (parent.getNodeType() == ASTNode.SWITCH_CASE)
status.addError(RefactoringCoreMessages.ExtractClassRefactoring_error_switch, JavaStatusContext.create(typeRoot, node));
SimpleName name= (SimpleName) node;
ParameterInfo pi= getFieldInfo(name.getIdentifier()).pi;
boolean writeAccess= ASTResolving.isWriteAccess(name);
if (writeAccess && fDescriptor.isCreateGetterSetter()) {
boolean useSuper= parent.getNodeType() == ASTNode.SUPER_FIELD_ACCESS;
Expression qualifier= getQualifier(parent);
ASTNode replaceNode= getReplacementNode(parent, useSuper, qualifier);
Expression assignedValue= getAssignedValue(pof, parameterName, javaProject, status, rewrite, pi, useSuper, name.resolveTypeBinding(), qualifier, replaceNode, typeRoot);
if (assignedValue == null) {
status.addError(RefactoringCoreMessages.ExtractClassRefactoring_error_unable_to_convert_node, JavaStatusContext.create(typeRoot, replaceNode));
} else {
NullLiteral marker= qualifier == null ? null : ast.newNullLiteral();
Expression access= pof.createFieldWriteAccess(pi, parameterName, ast, javaProject, assignedValue, useSuper, marker);
replaceMarker(rewrite, qualifier, access, marker);
rewrite.replace(replaceNode, access, writeGroup);
}
} else {
Expression fieldReadAccess= pof.createFieldReadAccess(pi, parameterName, ast, javaProject, false, null); //qualifier is already there
rewrite.replace(name, fieldReadAccess, readGroup);
}
}
}
return status;
}
private boolean isControlStatement(ASTNode node) {
int type= node.getNodeType();
return type == ASTNode.IF_STATEMENT || type == ASTNode.FOR_STATEMENT || type == ASTNode.ENHANCED_FOR_STATEMENT ||
type == ASTNode.WHILE_STATEMENT || type == ASTNode.DO_STATEMENT;
}
@Override
protected FoldableNode getBestNode(final HashMap<FoldableNode, Option> options, final double budget,
final boolean debug) {
int maxScore = Integer.MIN_VALUE;
FoldableNode bestNode = null;
// For every *folded* FoldableNode
for (final FoldableNode fn : options.keySet()) {
if (!fn.isUnfolded()) {
// Get cost
final int cost = options.get(fn).cost;
// Get parent node
final ASTNode parentNode = fn.node.getParent();
// Get score (2 - javadoc, 0 - method, 1 - o/w)
int score = Integer.MIN_VALUE;
if (cost <= budget) {
if (fn.node.getNodeType() == ASTNode.JAVADOC)
score = 2;
else if (parentNode == null) // parent is root node
score = 1;
else if (parentNode.getNodeType() == ASTNode.METHOD_DECLARATION)
score = 0;
else
score = 1;
}
// Set profit (for counting ties)
// options.get(fn).profit = score;
// Print node cost stats
if (debug)
System.out.println(
"\n+++++ Node: " + fn + "Cost: " + cost + " Budget: " + budget + " score: " + score);
// Set bestNode as node with max score
if (score > maxScore) {
maxScore = score;
bestNode = fn;
}
}
}
// countRandomlyBrokenTies(options, bestNode, maxScore);
// Print out bestNode and stats
if (debug && bestNode != null)
System.out.println("\n+=+=+ bestNode " + bestNode.printRange() + ", cost: " + options.get(bestNode).cost
+ " score: " + maxScore);
return bestNode;
}
public static List<CUCorrectionProposal> getMoveRefactoringProposals(CodeActionParams params, IInvocationContext context) {
String label = ActionMessages.MoveRefactoringAction_label;
int relevance = IProposalRelevance.MOVE_REFACTORING;
ASTNode node = context.getCoveredNode();
if (node == null) {
node = context.getCoveringNode();
}
while (node != null && !(node instanceof BodyDeclaration)) {
node = node.getParent();
}
ICompilationUnit cu = context.getCompilationUnit();
String uri = JDTUtils.toURI(cu);
if (cu != null && node != null) {
try {
if (node instanceof MethodDeclaration || node instanceof FieldDeclaration || node instanceof AbstractTypeDeclaration) {
String displayName = getDisplayName(node);
int memberType = node.getNodeType();
String enclosingTypeName = getEnclosingType(node);
String projectName = cu.getJavaProject().getProject().getName();
if (node instanceof AbstractTypeDeclaration) {
MoveTypeInfo moveTypeInfo = new MoveTypeInfo(displayName, enclosingTypeName, projectName);
if (isMoveInnerAvailable((AbstractTypeDeclaration) node)) {
moveTypeInfo.addDestinationKind("newFile");
}
if (isMoveStaticMemberAvailable(node)) {
moveTypeInfo.addDestinationKind("class");
}
// move inner type.
if (moveTypeInfo.isMoveAvaiable()) {
return Collections.singletonList(
new CUCorrectionCommandProposal(label, JavaCodeActionKind.REFACTOR_MOVE, cu, relevance, APPLY_REFACTORING_COMMAND_ID,
Arrays.asList(MOVE_TYPE_COMMAND, params, moveTypeInfo)));
}
// move ICompilationUnit.
return Collections.singletonList((new CUCorrectionCommandProposal(label, JavaCodeActionKind.REFACTOR_MOVE, cu, relevance, RefactorProposalUtility.APPLY_REFACTORING_COMMAND_ID,
Arrays.asList(MOVE_FILE_COMMAND, params, new MoveFileInfo(uri)))));
} else if (JdtFlags.isStatic((BodyDeclaration) node)) {
// move static member.
if (isMoveStaticMemberAvailable(node)) {
return Collections.singletonList(new CUCorrectionCommandProposal(label, JavaCodeActionKind.REFACTOR_MOVE, cu, relevance, APPLY_REFACTORING_COMMAND_ID,
Arrays.asList(MOVE_STATIC_MEMBER_COMMAND, params, new MoveMemberInfo(displayName, memberType, enclosingTypeName, projectName))));
}
} else if (node instanceof MethodDeclaration) {
// move instance method.
if (isMoveMethodAvailable((MethodDeclaration) node)) {
return Collections.singletonList(new CUCorrectionCommandProposal(label, JavaCodeActionKind.REFACTOR_MOVE, cu, relevance, APPLY_REFACTORING_COMMAND_ID,
Arrays.asList(MOVE_INSTANCE_METHOD_COMMAND, params, new MoveMemberInfo(displayName))));
}
}
}
} catch (JavaModelException e) {
// do nothing.
}
return Collections.emptyList();
}
return Collections.singletonList(
(new CUCorrectionCommandProposal(label, JavaCodeActionKind.REFACTOR_MOVE, cu, relevance, RefactorProposalUtility.APPLY_REFACTORING_COMMAND_ID, Arrays.asList(MOVE_FILE_COMMAND, params, new MoveFileInfo(uri)))));
}
protected ASTNode generateElementAST(ASTRewrite rewriter, ICompilationUnit cu) throws JavaModelException {
ASTNode node = super.generateElementAST(rewriter, cu);
if (node.getNodeType() != ASTNode.FIELD_DECLARATION)
throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_CONTENTS));
return node;
}
/**
* Converts an assignment, postfix expression or prefix expression into an assignable equivalent expression using the getter.
*
* @param node the assignment/prefix/postfix node
* @param astRewrite the astRewrite to use
* @param getterExpression the expression to insert for read accesses or <code>null</code> if such an expression does not exist
* @param variableType the type of the variable that the result will be assigned to
* @param is50OrHigher <code>true</code> if a 5.0 or higher environment can be used
* @return an expression that can be assigned to the type variableType with node being replaced by a equivalent expression using the getter
*/
public static Expression getAssignedValue(ASTNode node, ASTRewrite astRewrite, Expression getterExpression, ITypeBinding variableType, boolean is50OrHigher) {
InfixExpression.Operator op= null;
AST ast= astRewrite.getAST();
if (isNotInBlock(node))
return null;
if (node.getNodeType() == ASTNode.ASSIGNMENT) {
Assignment assignment= ((Assignment) node);
Expression rightHandSide= assignment.getRightHandSide();
Expression copiedRightOp= (Expression) astRewrite.createCopyTarget(rightHandSide);
if (assignment.getOperator() == Operator.ASSIGN) {
ITypeBinding rightHandSideType= rightHandSide.resolveTypeBinding();
copiedRightOp= createNarrowCastIfNessecary(copiedRightOp, rightHandSideType, ast, variableType, is50OrHigher);
return copiedRightOp;
}
if (getterExpression != null) {
InfixExpression infix= ast.newInfixExpression();
infix.setLeftOperand(getterExpression);
infix.setOperator(ASTNodes.convertToInfixOperator(assignment.getOperator()));
ITypeBinding infixType= infix.resolveTypeBinding();
if (NecessaryParenthesesChecker.needsParenthesesForRightOperand(rightHandSide, infix, variableType)) {
ParenthesizedExpression p= ast.newParenthesizedExpression();
p.setExpression(copiedRightOp);
copiedRightOp= p;
}
infix.setRightOperand(copiedRightOp);
return createNarrowCastIfNessecary(infix, infixType, ast, variableType, is50OrHigher);
}
} else if (node.getNodeType() == ASTNode.POSTFIX_EXPRESSION) {
PostfixExpression po= (PostfixExpression) node;
if (po.getOperator() == PostfixExpression.Operator.INCREMENT)
op= InfixExpression.Operator.PLUS;
if (po.getOperator() == PostfixExpression.Operator.DECREMENT)
op= InfixExpression.Operator.MINUS;
} else if (node.getNodeType() == ASTNode.PREFIX_EXPRESSION) {
PrefixExpression pe= (PrefixExpression) node;
if (pe.getOperator() == PrefixExpression.Operator.INCREMENT)
op= InfixExpression.Operator.PLUS;
if (pe.getOperator() == PrefixExpression.Operator.DECREMENT)
op= InfixExpression.Operator.MINUS;
}
if (op != null && getterExpression != null) {
return createInfixInvocationFromPostPrefixExpression(op, getterExpression, ast, variableType, is50OrHigher);
}
return null;
}
@Override
protected ASTRewrite getRewrite() throws CoreException {
CompilationUnit astRoot= ASTResolving.findParentCompilationUnit(fNode);
ASTNode boundNode= astRoot.findDeclaringNode(fBinding);
ASTNode declNode= null;
if (boundNode != null) {
declNode= boundNode; // is same CU
} else {
//setSelectionDescription(selectionDescription);
CompilationUnit newRoot= ASTResolving.createQuickFixAST(getCompilationUnit(), null);
declNode= newRoot.findDeclaringNode(fBinding.getKey());
}
if (declNode != null) {
AST ast= declNode.getAST();
ASTRewrite rewrite= ASTRewrite.create(ast);
if (declNode.getNodeType() == ASTNode.VARIABLE_DECLARATION_FRAGMENT) {
VariableDeclarationFragment fragment= (VariableDeclarationFragment)declNode;
ASTNode parent= declNode.getParent();
if (parent instanceof FieldDeclaration) {
FieldDeclaration fieldDecl= (FieldDeclaration) parent;
if (fieldDecl.fragments().size() > 1 && (fieldDecl.getParent() instanceof AbstractTypeDeclaration)) { // split
VariableDeclarationRewrite.rewriteModifiers(fieldDecl, new VariableDeclarationFragment[] {fragment}, fIncludedModifiers, fExcludedModifiers, rewrite, null);
return rewrite;
}
} else if (parent instanceof VariableDeclarationStatement) {
VariableDeclarationStatement varDecl= (VariableDeclarationStatement) parent;
if (varDecl.fragments().size() > 1 && (varDecl.getParent() instanceof Block)) { // split
VariableDeclarationRewrite.rewriteModifiers(varDecl, new VariableDeclarationFragment[] {fragment}, fIncludedModifiers, fExcludedModifiers, rewrite, null);
return rewrite;
}
} else if (parent instanceof VariableDeclarationExpression) {
// can't separate
}
declNode= parent;
} else if (declNode.getNodeType() == ASTNode.METHOD_DECLARATION) {
MethodDeclaration methodDecl= (MethodDeclaration) declNode;
if (!methodDecl.isConstructor()) {
IMethodBinding methodBinding= methodDecl.resolveBinding();
if (methodDecl.getBody() == null && methodBinding != null && Modifier.isAbstract(methodBinding.getModifiers()) && Modifier.isStatic(fIncludedModifiers)) {
// add body
ICompilationUnit unit= getCompilationUnit();
String delimiter= unit.findRecommendedLineSeparator();
String bodyStatement= ""; //$NON-NLS-1$
Block body= ast.newBlock();
rewrite.set(methodDecl, MethodDeclaration.BODY_PROPERTY, body, null);
Type returnType= methodDecl.getReturnType2();
if (returnType != null) {
Expression expression= ASTNodeFactory.newDefaultExpression(ast, returnType, methodDecl.getExtraDimensions());
if (expression != null) {
ReturnStatement returnStatement= ast.newReturnStatement();
returnStatement.setExpression(expression);
bodyStatement= ASTNodes.asFormattedString(returnStatement, 0, delimiter, unit.getJavaProject().getOptions(true));
}
}
String placeHolder= CodeGeneration.getMethodBodyContent(unit, methodBinding.getDeclaringClass().getName(), methodBinding.getName(), false, bodyStatement, delimiter);
if (placeHolder != null) {
ReturnStatement todoNode= (ReturnStatement) rewrite.createStringPlaceholder(placeHolder, ASTNode.RETURN_STATEMENT);
body.statements().add(todoNode);
}
}
}
}
ModifierRewrite listRewrite= ModifierRewrite.create(rewrite, declNode);
PositionInformation trackedDeclNode= listRewrite.setModifiers(fIncludedModifiers, fExcludedModifiers, null);
LinkedProposalPositionGroup positionGroup= new LinkedProposalPositionGroup("group"); //$NON-NLS-1$
positionGroup.addPosition(trackedDeclNode);
getLinkedProposalModel().addPositionGroup(positionGroup);
if (boundNode != null) {
// only set end position if in same CU
setEndPosition(rewrite.track(fNode));
}
return rewrite;
}
return null;
}
@Override
public boolean validElement(ASTNode curElement) {
return (curElement.getNodeType() == ASTNode.TYPE_DECLARATION)
&& (((TypeDeclaration) curElement).getName().toString().equals(compiler.getSeqDiagramName()));
}
/**
* Determines what kind of ASTNode has been selected.
* @param node the node
* @return A non-null String containing an error message
* is returned if the ChangeTypeRefactoring refactoring cannot be applied to the selected ASTNode.
* A return value of null indicates a valid selection.
*/
private String determineSelection(ASTNode node) {
if (node == null) {
return RefactoringCoreMessages.ChangeTypeRefactoring_invalidSelection;
} else {
if (DEBUG) System.out.println("node nodeType= " + node.getClass().getName()); //$NON-NLS-1$
if (DEBUG) System.out.println("parent nodeType= " + node.getParent().getClass().getName()); //$NON-NLS-1$
if (DEBUG) System.out.println("GrandParent nodeType= " + node.getParent().getParent().getClass().getName()); //$NON-NLS-1$
ASTNode parent= node.getParent();
ASTNode grandParent= parent.getParent();
if (grandParent == null)
return nodeTypeNotSupported();
// adjustment needed if part of a parameterized type is selected
if (grandParent.getNodeType() == ASTNode.PARAMETERIZED_TYPE){
node= grandParent;
}
// adjustment needed if part of a qualified name is selected
ASTNode current= null;
if (node.getNodeType() == ASTNode.QUALIFIED_NAME){
current= node;
while (current.getNodeType() == ASTNode.QUALIFIED_NAME){
current= current.getParent();
}
if (current.getNodeType() != ASTNode.SIMPLE_TYPE){
return nodeTypeNotSupported();
}
node= current.getParent();
} else if (parent.getNodeType() == ASTNode.QUALIFIED_NAME){
current= parent;
while (current.getNodeType() == ASTNode.QUALIFIED_NAME){
current= current.getParent();
}
if (current.getNodeType() != ASTNode.SIMPLE_TYPE){
return nodeTypeNotSupported();
}
node= current.getParent();
}
fObject= node.getAST().resolveWellKnownType("java.lang.Object"); //$NON-NLS-1$
switch (node.getNodeType()) {
case ASTNode.SIMPLE_NAME :
return simpleNameSelected((SimpleName)node);
case ASTNode.VARIABLE_DECLARATION_STATEMENT :
return variableDeclarationStatementSelected((VariableDeclarationStatement) node);
case ASTNode.FIELD_DECLARATION :
return fieldDeclarationSelected((FieldDeclaration) node);
case ASTNode.SINGLE_VARIABLE_DECLARATION :
return singleVariableDeclarationSelected((SingleVariableDeclaration) node);
case ASTNode.PARAMETERIZED_TYPE:
return parameterizedTypeSelected((ParameterizedType) node);
default :
return nodeTypeNotSupported();
}
}
}
@Override
protected ASTRewrite getRewrite() throws CoreException {
CompilationUnit astRoot = ASTResolving.findParentCompilationUnit(fNode);
ASTNode boundNode = astRoot.findDeclaringNode(fBinding);
ASTNode declNode = null;
if (boundNode != null) {
declNode = boundNode; // is same CU
} else {
//setSelectionDescription(selectionDescription);
CompilationUnit newRoot = ASTResolving.createQuickFixAST(getCompilationUnit(), null);
declNode = newRoot.findDeclaringNode(fBinding.getKey());
}
if (declNode != null) {
AST ast = declNode.getAST();
ASTRewrite rewrite = ASTRewrite.create(ast);
if (declNode.getNodeType() == ASTNode.VARIABLE_DECLARATION_FRAGMENT) {
VariableDeclarationFragment fragment = (VariableDeclarationFragment) declNode;
ASTNode parent = declNode.getParent();
if (parent instanceof FieldDeclaration) {
FieldDeclaration fieldDecl = (FieldDeclaration) parent;
if (fieldDecl.fragments().size() > 1 && (fieldDecl.getParent() instanceof AbstractTypeDeclaration)) { // split
VariableDeclarationRewrite.rewriteModifiers(fieldDecl, new VariableDeclarationFragment[] { fragment }, fIncludedModifiers, fExcludedModifiers, rewrite, null);
return rewrite;
}
} else if (parent instanceof VariableDeclarationStatement) {
VariableDeclarationStatement varDecl = (VariableDeclarationStatement) parent;
if (varDecl.fragments().size() > 1 && (varDecl.getParent() instanceof Block)) { // split
VariableDeclarationRewrite.rewriteModifiers(varDecl, new VariableDeclarationFragment[] { fragment }, fIncludedModifiers, fExcludedModifiers, rewrite, null);
return rewrite;
}
} else if (parent instanceof VariableDeclarationExpression) {
// can't separate
}
declNode = parent;
} else if (declNode.getNodeType() == ASTNode.METHOD_DECLARATION) {
MethodDeclaration methodDecl = (MethodDeclaration) declNode;
if (!methodDecl.isConstructor()) {
IMethodBinding methodBinding = methodDecl.resolveBinding();
if (methodDecl.getBody() == null && methodBinding != null && Modifier.isAbstract(methodBinding.getModifiers()) && Modifier.isStatic(fIncludedModifiers)) {
// add body
ICompilationUnit unit = getCompilationUnit();
String delimiter = unit.findRecommendedLineSeparator();
String bodyStatement = ""; //$NON-NLS-1$
Block body = ast.newBlock();
rewrite.set(methodDecl, MethodDeclaration.BODY_PROPERTY, body, null);
Type returnType = methodDecl.getReturnType2();
if (returnType != null) {
Expression expression = ASTNodeFactory.newDefaultExpression(ast, returnType, methodDecl.getExtraDimensions());
if (expression != null) {
ReturnStatement returnStatement = ast.newReturnStatement();
returnStatement.setExpression(expression);
bodyStatement = ASTNodes.asFormattedString(returnStatement, 0, delimiter, unit.getJavaProject().getOptions(true));
}
}
String placeHolder = CodeGeneration.getMethodBodyContent(unit, methodBinding.getDeclaringClass().getName(), methodBinding.getName(), false, bodyStatement, delimiter);
if (placeHolder != null) {
ReturnStatement todoNode = (ReturnStatement) rewrite.createStringPlaceholder(placeHolder, ASTNode.RETURN_STATEMENT);
body.statements().add(todoNode);
}
}
}
}
ModifierRewrite listRewrite = ModifierRewrite.create(rewrite, declNode);
PositionInformation trackedDeclNode = listRewrite.setModifiers(fIncludedModifiers, fExcludedModifiers, null);
LinkedProposalPositionGroupCore positionGroup = new LinkedProposalPositionGroupCore("group"); //$NON-NLS-1$
positionGroup.addPosition(trackedDeclNode);
getLinkedProposalModel().addPositionGroup(positionGroup);
if (boundNode != null) {
// only set end position if in same CU
setEndPosition(rewrite.track(fNode));
}
return rewrite;
}
return null;
}
/**
* Returns the closest ancestor of <code>node</code> whose type is <code>nodeType</code>, or <code>null</code> if none.
* <p>
* <b>Warning:</b> This method does not stop at any boundaries like parentheses, statements, body declarations, etc.
* The resulting node may be in a totally different scope than the given node.
* Consider using one of the {@link ASTResolving}<code>.find(..)</code> methods instead.
* </p>
* @param node the node
* @param nodeType the node type constant from {@link ASTNode}
* @return the closest ancestor of <code>node</code> whose type is <code>nodeType</code>, or <code>null</code> if none
*/
public static ASTNode getParent(ASTNode node, int nodeType) {
do {
node= node.getParent();
} while (node != null && node.getNodeType() != nodeType);
return node;
}