1 /*******************************************************************************
2 * Copyright (c) 2000, 2011 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.jdt.internal.corext.refactoring.structure;
13 import java.util.HashSet;
16 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
18 import org.eclipse.jdt.core.dom.AST;
19 import org.eclipse.jdt.core.dom.ASTNode;
20 import org.eclipse.jdt.core.dom.ASTVisitor;
21 import org.eclipse.jdt.core.dom.Expression;
22 import org.eclipse.jdt.core.dom.FieldAccess;
23 import org.eclipse.jdt.core.dom.IBinding;
24 import org.eclipse.jdt.core.dom.IPackageBinding;
25 import org.eclipse.jdt.core.dom.ITypeBinding;
26 import org.eclipse.jdt.core.dom.MemberRef;
27 import org.eclipse.jdt.core.dom.MethodInvocation;
28 import org.eclipse.jdt.core.dom.MethodRef;
29 import org.eclipse.jdt.core.dom.Name;
30 import org.eclipse.jdt.core.dom.QualifiedName;
31 import org.eclipse.jdt.core.dom.SimpleName;
32 import org.eclipse.jdt.core.dom.Type;
33 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext;
35 import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext;
36 import org.eclipse.jdt.internal.corext.dom.ASTFlattener;
37 import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory;
38 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
39 import org.eclipse.jdt.internal.corext.dom.Bindings;
40 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
41 import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext;
43 /* package */ class MoveStaticMemberAnalyzer extends ASTVisitor {
45 protected RefactoringStatus fStatus;
47 protected ITypeBinding fSource;
48 protected ITypeBinding fTarget;
49 protected CompilationUnitRewrite fCuRewrite;
50 protected IBinding[] fMembers;
52 protected boolean fNeedsImport;
54 protected Set<SimpleName> fProcessed;
56 protected static final String REFERENCE_UPDATE= RefactoringCoreMessages.MoveMembersRefactoring_referenceUpdate;
58 public MoveStaticMemberAnalyzer(CompilationUnitRewrite cuRewrite, IBinding[] members, ITypeBinding source, ITypeBinding target) {
60 fStatus= new RefactoringStatus();
61 fCuRewrite= cuRewrite;
65 fProcessed= new HashSet<SimpleName>();
68 public RefactoringStatus getStatus() {
72 protected boolean isProcessed(ASTNode node) {
73 return fProcessed.contains(node);
76 protected void rewrite(SimpleName node, ITypeBinding type) {
77 AST ast= node.getAST();
78 ImportRewriteContext context= new ContextSensitiveImportRewriteContext(node, fCuRewrite.getImportRewrite());
79 Type result= fCuRewrite.getImportRewrite().addImport(type, fCuRewrite.getAST(), context);
80 fCuRewrite.getImportRemover().registerAddedImport(type.getQualifiedName());
81 Name dummy= ASTNodeFactory.newName(fCuRewrite.getAST(), ASTFlattener.asString(result));
82 QualifiedName name= ast.newQualifiedName(dummy, ast.newSimpleName(node.getIdentifier()));
83 fCuRewrite.getASTRewrite().replace(node, name, fCuRewrite.createGroupDescription(REFERENCE_UPDATE));
84 fCuRewrite.getImportRemover().registerRemovedNode(node);
89 protected void rewrite(QualifiedName node, ITypeBinding type) {
90 rewriteName(node.getQualifier(), type);
91 fProcessed.add(node.getName());
94 protected void rewrite(FieldAccess node, ITypeBinding type) {
95 Expression exp= node.getExpression();
97 ImportRewriteContext context= new ContextSensitiveImportRewriteContext(node, fCuRewrite.getImportRewrite());
98 Type result= fCuRewrite.getImportRewrite().addImport(type, fCuRewrite.getAST(), context);
99 fCuRewrite.getImportRemover().registerAddedImport(type.getQualifiedName());
100 exp= ASTNodeFactory.newName(fCuRewrite.getAST(), ASTFlattener.asString(result));
101 fCuRewrite.getASTRewrite().set(node, FieldAccess.EXPRESSION_PROPERTY, exp, fCuRewrite.createGroupDescription(REFERENCE_UPDATE));
103 } else if (exp instanceof Name) {
104 rewriteName((Name)exp, type);
106 rewriteExpression(node, exp, type);
108 fProcessed.add(node.getName());
111 protected void rewrite(MethodInvocation node, ITypeBinding type) {
112 Expression exp= node.getExpression();
114 ImportRewriteContext context= new ContextSensitiveImportRewriteContext(node, fCuRewrite.getImportRewrite());
115 Type result= fCuRewrite.getImportRewrite().addImport(type, fCuRewrite.getAST(), context);
116 fCuRewrite.getImportRemover().registerAddedImport(type.getQualifiedName());
117 exp= ASTNodeFactory.newName(fCuRewrite.getAST(), ASTFlattener.asString(result));
118 fCuRewrite.getASTRewrite().set(node, MethodInvocation.EXPRESSION_PROPERTY, exp, fCuRewrite.createGroupDescription(REFERENCE_UPDATE));
120 } else if (exp instanceof Name) {
121 rewriteName((Name)exp, type);
123 rewriteExpression(node, exp, type);
125 fProcessed.add(node.getName());
128 protected void rewrite(MemberRef node, ITypeBinding type) {
129 Name qualifier= node.getQualifier();
130 if (qualifier == null) {
131 ImportRewriteContext context= new ContextSensitiveImportRewriteContext(node, fCuRewrite.getImportRewrite());
132 Type result= fCuRewrite.getImportRewrite().addImport(type, fCuRewrite.getAST(), context);
133 fCuRewrite.getImportRemover().registerAddedImport(type.getQualifiedName());
134 qualifier= ASTNodeFactory.newName(fCuRewrite.getAST(), ASTFlattener.asString(result));
135 fCuRewrite.getASTRewrite().set(node, MemberRef.QUALIFIER_PROPERTY, qualifier, fCuRewrite.createGroupDescription(REFERENCE_UPDATE));
138 rewriteName(qualifier, type);
140 fProcessed.add(node.getName());
143 protected void rewrite(MethodRef node, ITypeBinding type) {
144 Name qualifier= node.getQualifier();
145 if (qualifier == null) {
146 ImportRewriteContext context= new ContextSensitiveImportRewriteContext(node, fCuRewrite.getImportRewrite());
147 Type result= fCuRewrite.getImportRewrite().addImport(type, fCuRewrite.getAST(), context);
148 fCuRewrite.getImportRemover().registerAddedImport(type.getQualifiedName());
149 qualifier= ASTNodeFactory.newName(fCuRewrite.getAST(), ASTFlattener.asString(result));
150 fCuRewrite.getASTRewrite().set(node, MethodRef.QUALIFIER_PROPERTY, qualifier, fCuRewrite.createGroupDescription(REFERENCE_UPDATE));
153 rewriteName(qualifier, type);
155 fProcessed.add(node.getName());
158 private void rewriteName(Name name, ITypeBinding type) {
159 AST creator= name.getAST();
160 boolean fullyQualified= false;
161 if (name instanceof QualifiedName) {
162 SimpleName left= ASTNodes.getLeftMostSimpleName(name);
163 if (left.resolveBinding() instanceof IPackageBinding)
164 fullyQualified= true;
166 if (fullyQualified) {
167 fCuRewrite.getASTRewrite().replace(
169 ASTNodeFactory.newName(creator, type.getQualifiedName()),
170 fCuRewrite.createGroupDescription(REFERENCE_UPDATE));
171 fCuRewrite.getImportRemover().registerRemovedNode(name);
173 ImportRewriteContext context= new ContextSensitiveImportRewriteContext(name, fCuRewrite.getImportRewrite());
174 Type result= fCuRewrite.getImportRewrite().addImport(type, fCuRewrite.getAST(), context);
175 fCuRewrite.getImportRemover().registerAddedImport(type.getQualifiedName());
176 Name n= ASTNodeFactory.newName(fCuRewrite.getAST(), ASTFlattener.asString(result));
177 fCuRewrite.getASTRewrite().replace(
180 fCuRewrite.createGroupDescription(REFERENCE_UPDATE));
181 fCuRewrite.getImportRemover().registerRemovedNode(name);
186 private void rewriteExpression(ASTNode node, Expression exp, ITypeBinding type) {
187 ImportRewriteContext context= new ContextSensitiveImportRewriteContext(exp, fCuRewrite.getImportRewrite());
188 Type typeNode= fCuRewrite.getImportRewrite().addImport(type, fCuRewrite.getAST(), context);
189 fCuRewrite.getASTRewrite().replace(exp, typeNode, fCuRewrite.createGroupDescription(REFERENCE_UPDATE));
190 fCuRewrite.getImportRemover().registerAddedImport(type.getQualifiedName());
191 fCuRewrite.getImportRemover().registerRemovedNode(exp);
193 nonStaticAccess(node);
196 protected void nonStaticAccess(ASTNode node) {
197 fStatus.addWarning(RefactoringCoreMessages.MoveStaticMemberAnalyzer_nonStatic,
198 JavaStatusContext.create(fCuRewrite.getCu(), node));
201 protected boolean isStaticAccess(Expression exp, ITypeBinding type) {
202 if (!(exp instanceof Name))
204 return Bindings.equals(type, ((Name)exp).resolveBinding());
207 protected boolean isMovedMember(IBinding binding) {
210 for (int i= 0; i < fMembers.length; i++) {
211 if (Bindings.equalDeclarations(fMembers[i], binding))