~ubuntu-branches/ubuntu/trusty/netbeans/trusty

« back to all changes in this revision

Viewing changes to refactoring/java/src/org/netbeans/modules/refactoring/java/plugins/VarUsageVisitor.java

  • Committer: Bazaar Package Importer
  • Author(s): Marek Slama
  • Date: 2008-01-29 14:11:22 UTC
  • Revision ID: james.westby@ubuntu.com-20080129141122-fnzjbo11ntghxfu7
Tags: upstream-6.0.1
ImportĀ upstreamĀ versionĀ 6.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *                 Sun Public License Notice
 
3
 *
 
4
 * The contents of this file are subject to the Sun Public License
 
5
 * Version 1.0 (the "License"). You may not use this file except in
 
6
 * compliance with the License. A copy of the License is available at
 
7
 * http://www.sun.com/
 
8
 *
 
9
 * The Original Code is NetBeans. The Initial Developer of the Original
 
10
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun
 
11
 * Microsystems, Inc. All Rights Reserved.
 
12
 
 
13
If you wish your version of this file to be governed by only the CDDL
 
14
or only the GPL Version 2, indicate your decision by adding
 
15
"[Contributor] elects to include this software in this distribution
 
16
under the [CDDL or GPL Version 2] license." If you do not indicate a
 
17
single choice of license, a recipient has the option to distribute
 
18
your version of this file under either the CDDL, the GPL Version 2 or
 
19
to extend the choice of license to its licensees as provided above.
 
20
However, if you add GPL Version 2 code and therefore, elected the GPL
 
21
Version 2 license, then the option applies only if the new code is
 
22
made subject to such option by the copyright holder.
 
23
 */
 
24
 
 
25
package org.netbeans.modules.refactoring.java.plugins;
 
26
 
 
27
import org.netbeans.modules.refactoring.java.api.*;
 
28
import com.sun.source.tree.AssignmentTree;
 
29
import com.sun.source.tree.ExpressionTree;
 
30
import com.sun.source.tree.MemberSelectTree;
 
31
import com.sun.source.tree.Tree;
 
32
import com.sun.source.tree.VariableTree;
 
33
import com.sun.source.util.TreePath;
 
34
import com.sun.source.util.Trees;
 
35
import java.util.List;
 
36
import java.util.Set;
 
37
import javax.lang.model.element.Element;
 
38
import javax.lang.model.element.ElementKind;
 
39
import javax.lang.model.element.ExecutableElement;
 
40
import javax.lang.model.element.Modifier;
 
41
import javax.lang.model.element.TypeElement;
 
42
import javax.lang.model.element.VariableElement;
 
43
import javax.lang.model.type.DeclaredType;
 
44
import javax.lang.model.type.TypeKind;
 
45
import javax.lang.model.type.TypeMirror;
 
46
import javax.lang.model.util.Elements;
 
47
import javax.lang.model.util.Types;
 
48
import org.netbeans.api.java.source.WorkingCopy;
 
49
import org.netbeans.modules.refactoring.java.spi.RefactoringVisitor;
 
50
import org.netbeans.modules.refactoring.java.spi.ToPhaseException;
 
51
import org.openide.util.Exceptions;
 
52
 
 
53
/**
 
54
 * @author Jan Becicka, Bharath Ravi Kumar
 
55
 */
 
56
class VarUsageVisitor extends RefactoringVisitor {
 
57
 
 
58
    private final TypeElement superTypeElement;
 
59
    private final TypeElement subTypeElement;
 
60
    private boolean isReplCandidate = true;
 
61
 
 
62
    VarUsageVisitor(TypeElement subTypeElement, WorkingCopy workingCopy, 
 
63
            TypeElement superTypeElem) {
 
64
        try {
 
65
            setWorkingCopy(workingCopy);
 
66
        } catch (ToPhaseException ex) {
 
67
            Exceptions.printStackTrace(ex);
 
68
        }
 
69
        this.superTypeElement = superTypeElem;
 
70
        this.subTypeElement = subTypeElement;
 
71
    }
 
72
 
 
73
    @Override
 
74
    public Tree visitMemberSelect(MemberSelectTree memSelectTree, Element refVarElem) {
 
75
 
 
76
        Element methodElement = this.asElement(memSelectTree);
 
77
        Element varElement = asElement(memSelectTree.getExpression());
 
78
        if (!refVarElem.equals(varElement)) {
 
79
            return super.visitMemberSelect(memSelectTree, refVarElem);
 
80
        }
 
81
 
 
82
        boolean isAssgCmptble = isMemberAvailable(subTypeElement, methodElement, 
 
83
                superTypeElement);
 
84
        if (!isAssgCmptble) {
 
85
            isReplCandidate = false;
 
86
        }
 
87
        return super.visitMemberSelect(memSelectTree, refVarElem);
 
88
    }
 
89
 
 
90
    @Override
 
91
    public Tree visitAssignment(AssignmentTree assgnTree, Element refVarElem) {
 
92
 
 
93
        ExpressionTree exprnTree = assgnTree.getExpression();
 
94
        Element exprElement = asElement(exprnTree);
 
95
        if (!refVarElem.equals(exprElement)) {
 
96
            return super.visitAssignment(assgnTree, refVarElem);
 
97
        }
 
98
        ExpressionTree varExprTree = assgnTree.getVariable();
 
99
 
 
100
        VariableElement varElement = (VariableElement) asElement(varExprTree);
 
101
        isReplCandidate = isReplacableAssgnmt(varElement) && isReplCandidate;
 
102
        return super.visitAssignment(assgnTree, refVarElem);
 
103
    }
 
104
 
 
105
    @Override
 
106
    public Tree visitVariable(VariableTree varTree, Element refVarElem) {
 
107
        ExpressionTree initTree = varTree.getInitializer();
 
108
        if (null == initTree) {
 
109
            return super.visitVariable(varTree, refVarElem);
 
110
        }
 
111
        Element exprElement = asElement(initTree);
 
112
        if (!refVarElem.equals(exprElement)) {
 
113
            return super.visitVariable(varTree, refVarElem);
 
114
        }
 
115
        VariableElement varElement = (VariableElement) asElement(varTree);
 
116
        isReplCandidate = isReplacableAssgnmt(varElement) && isReplCandidate;
 
117
        return super.visitVariable(varTree, refVarElem);
 
118
    }
 
119
 
 
120
    private boolean isMemberAvailable(TypeElement subTypeElement, Element methodElement, 
 
121
            TypeElement superTypeElement) {
 
122
        ElementKind memberKind = methodElement.getKind();
 
123
        if(ElementKind.METHOD.equals(memberKind)){
 
124
            return isMethodAvailable(subTypeElement, (ExecutableElement)methodElement, 
 
125
                    superTypeElement);
 
126
        }else{
 
127
            return isHidingMember(subTypeElement, methodElement, superTypeElement);
 
128
        }
 
129
    }
 
130
 
 
131
    private boolean isMethodAvailable(TypeElement subTypeElement, 
 
132
            ExecutableElement execElem, TypeElement superTypeElement) {
 
133
        Elements elements = workingCopy.getElements();
 
134
        List<? extends Element> memberElements = elements.getAllMembers(superTypeElement);
 
135
        for (Element elem : memberElements) {
 
136
            if(ElementKind.METHOD.equals(elem.getKind())){
 
137
                if(isStatic(execElem) && elements.hides(execElem, elem)){
 
138
                    return true;
 
139
                }else{
 
140
                    if(execElem.equals(elem) || elements.overrides(execElem, (ExecutableElement)elem, 
 
141
                            subTypeElement)){
 
142
                        return true;
 
143
                    }
 
144
                }
 
145
            }
 
146
        }
 
147
 
 
148
        return false;
 
149
    }
 
150
 
 
151
    private boolean isHidingMember(TypeElement subTypeElement, Element variableElement, 
 
152
            TypeElement superTypeElement) {
 
153
        //TODO: We do not handle nested types yet (includes enums)
 
154
        Elements elements = workingCopy.getElements();
 
155
        List<? extends Element> memberElements = elements.getAllMembers(superTypeElement);
 
156
        for (Element elem : memberElements) {
 
157
            if(variableElement.equals(elem) || elements.hides(variableElement, elem)){
 
158
                return true;
 
159
            }
 
160
        }
 
161
        return false;
 
162
    }
 
163
 
 
164
    private boolean isReplacableAssgnmt(VariableElement varElement) {
 
165
        if (isDeclaredType(varElement.asType())) {
 
166
            DeclaredType declType = (DeclaredType) varElement.asType();
 
167
            TypeElement varType = (TypeElement) declType.asElement();
 
168
            if (isAssignable(superTypeElement, varType)) {
 
169
                return true;
 
170
            }
 
171
        }
 
172
        return false;
 
173
    }
 
174
 
 
175
    boolean isReplaceCandidate() {
 
176
        return isReplCandidate;
 
177
    }
 
178
 
 
179
    private boolean isAssignable(TypeElement typeFrom, TypeElement typeTo) {
 
180
        Types types = workingCopy.getTypes();
 
181
        return types.isAssignable(typeFrom.asType(), typeTo.asType());
 
182
    }
 
183
 
 
184
    private Element asElement(Tree tree) {
 
185
        Trees treeUtil = workingCopy.getTrees();
 
186
        TreePath treePath = treeUtil.getPath(workingCopy.getCompilationUnit(), tree);
 
187
        Element element = treeUtil.getElement(treePath);
 
188
        return element;
 
189
    }
 
190
 
 
191
    private boolean isDeclaredType(TypeMirror type) {
 
192
        return TypeKind.DECLARED.equals(type.getKind());
 
193
    }
 
194
    //TODO: This method can be shared. Copied from UseSuperTypeRefactoringPlugin.
 
195
    private boolean isStatic(Element element) {
 
196
        Set<Modifier> modifiers = element.getModifiers();
 
197
        return modifiers.contains(Modifier.STATIC);
 
198
    }
 
199
 
 
200
}