001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.refactoring.java.plugins;
042:
043: import com.sun.source.tree.CompilationUnitTree;
044: import com.sun.source.tree.Scope;
045: import com.sun.source.tree.Tree;
046: import com.sun.source.util.TreePath;
047: import java.io.IOException;
048: import java.text.MessageFormat;
049: import java.util.*;
050: import javax.lang.model.element.*;
051: import javax.lang.model.type.ExecutableType;
052: import javax.lang.model.util.ElementFilter;
053: import javax.lang.model.util.Elements;
054: import org.netbeans.api.java.classpath.ClassPath;
055: import org.netbeans.api.java.source.*;
056: import org.netbeans.modules.refactoring.api.*;
057: import org.netbeans.modules.refactoring.java.RetoucheUtils;
058: import org.netbeans.modules.refactoring.java.spi.JavaRefactoringPlugin;
059: import org.openide.filesystems.FileObject;
060: import org.netbeans.modules.refactoring.spi.RefactoringElementsBag;
061: import org.openide.filesystems.FileUtil;
062: import org.openide.util.NbBundle;
063: import org.openide.util.Utilities;
064:
065: /**
066: * @author Jan Becicka
067: * @author Martin Matula
068: * @author Pavel Flaska
069: * @author Daniel Prusa
070: */
071: public class RenameRefactoringPlugin extends JavaRefactoringPlugin {
072:
073: private TreePathHandle treePathHandle = null;
074: private Collection<ExecutableElement> overriddenByMethods = null; // methods that override the method to be renamed
075: private Collection<ExecutableElement> overridesMethods = null; // methods that are overridden by the method to be renamed
076: private boolean doCheckName = true;
077:
078: private RenameRefactoring refactoring;
079:
080: /** Creates a new instance of RenameRefactoring */
081: public RenameRefactoringPlugin(RenameRefactoring rename) {
082: this .refactoring = rename;
083: TreePathHandle tph = rename.getRefactoringSource().lookup(
084: TreePathHandle.class);
085: if (tph != null) {
086: treePathHandle = tph;
087: } else {
088: JavaSource source = JavaSource.forFileObject(rename
089: .getRefactoringSource().lookup(FileObject.class));
090: try {
091: source.runUserActionTask(
092: new CancellableTask<CompilationController>() {
093: public void cancel() {
094: }
095:
096: public void run(CompilationController co)
097: throws Exception {
098: co.toPhase(JavaSource.Phase.RESOLVED);
099: CompilationUnitTree cut = co
100: .getCompilationUnit();
101: for (Tree t : cut.getTypeDecls()) {
102: Element e = co.getTrees()
103: .getElement(
104: TreePath.getPath(
105: cut, t));
106: if (e != null
107: && e
108: .getSimpleName()
109: .toString()
110: .equals(
111: co
112: .getFileObject()
113: .getName())) {
114: treePathHandle = TreePathHandle
115: .create(
116: TreePath
117: .getPath(
118: cut,
119: t),
120: co);
121: refactoring.getContext()
122: .add(co);
123: break;
124: }
125: }
126: }
127: }, false);
128: } catch (IllegalArgumentException ex) {
129: ex.printStackTrace();
130: } catch (IOException ex) {
131: ex.printStackTrace();
132: }
133: }
134: }
135:
136: protected JavaSource getJavaSource(Phase p) {
137: if (treePathHandle == null) {
138: return null;
139: }
140: switch (p) {
141: case PRECHECK:
142: case FASTCHECKPARAMETERS:
143: return JavaSource.forFileObject(treePathHandle
144: .getFileObject());
145: case CHECKPARAMETERS:
146: if (treePathHandle == null) {
147: return null;
148: }
149: ClasspathInfo cpInfo = getClasspathInfo(refactoring);
150: JavaSource source = JavaSource.create(cpInfo,
151: treePathHandle.getFileObject());
152: return source;
153:
154: }
155: throw new IllegalStateException();
156: }
157:
158: @Override
159: protected Problem preCheck(CompilationController info)
160: throws IOException {
161: Problem preCheckProblem = null;
162: fireProgressListenerStart(refactoring.PRE_CHECK, 4);
163: info.toPhase(JavaSource.Phase.RESOLVED);
164: Element el = treePathHandle.resolveElement(info);
165: preCheckProblem = isElementAvail(treePathHandle, info);
166: if (preCheckProblem != null) {
167: return preCheckProblem;
168: }
169: FileObject file = SourceUtils.getFile(el, info
170: .getClasspathInfo());
171: if (file != null && FileUtil.getArchiveFile(file) != null) { //NOI18N
172: preCheckProblem = createProblem(preCheckProblem, true,
173: getCannotRename(file));
174: return preCheckProblem;
175: }
176:
177: if (file == null || !RetoucheUtils.isElementInOpenProject(file)) {
178: preCheckProblem = new Problem(true, NbBundle.getMessage(
179: RenameRefactoringPlugin.class,
180: "ERR_ProjectNotOpened"));
181: return preCheckProblem;
182: }
183:
184: switch (el.getKind()) {
185: case METHOD:
186: fireProgressListenerStep();
187: fireProgressListenerStep();
188: overriddenByMethods = RetoucheUtils.getOverridingMethods(
189: (ExecutableElement) el, info);
190: fireProgressListenerStep();
191: if (el.getModifiers().contains(Modifier.NATIVE)) {
192: preCheckProblem = createProblem(preCheckProblem, false,
193: NbBundle.getMessage(
194: RenameRefactoringPlugin.class,
195: "ERR_RenameNative", el));
196: }
197: if (!overriddenByMethods.isEmpty()) {
198: String msg = new MessageFormat(
199: getString("ERR_IsOverridden"))
200: .format(new Object[] { SourceUtils
201: .getEnclosingTypeElement(el)
202: .getSimpleName().toString() });
203: preCheckProblem = createProblem(preCheckProblem, false,
204: msg);
205: }
206: for (ExecutableElement e : overriddenByMethods) {
207: if (e.getModifiers().contains(Modifier.NATIVE)) {
208: preCheckProblem = createProblem(preCheckProblem,
209: false, NbBundle.getMessage(
210: RenameRefactoringPlugin.class,
211: "ERR_RenameNative", e));
212: }
213: }
214: overridesMethods = RetoucheUtils.getOverridenMethods(
215: (ExecutableElement) el, info);
216: fireProgressListenerStep();
217: if (!overridesMethods.isEmpty()) {
218: boolean fatal = false;
219: for (Iterator iter = overridesMethods.iterator(); iter
220: .hasNext();) {
221: ExecutableElement method = (ExecutableElement) iter
222: .next();
223: if (method.getModifiers().contains(Modifier.NATIVE)) {
224: preCheckProblem = createProblem(
225: preCheckProblem, false,
226: NbBundle.getMessage(
227: RenameRefactoringPlugin.class,
228: "ERR_RenameNative", method));
229: }
230: if (RetoucheUtils.isFromLibrary(method, info
231: .getClasspathInfo())) {
232: fatal = true;
233: break;
234: }
235: }
236: String msg = fatal ? getString("ERR_Overrides_Fatal")
237: : getString("ERR_Overrides");
238: preCheckProblem = createProblem(preCheckProblem, fatal,
239: msg);
240: }
241: break;
242: case FIELD:
243: case ENUM_CONSTANT:
244: fireProgressListenerStep();
245: fireProgressListenerStep();
246: Element hiddenField = hides(el, el.getSimpleName()
247: .toString(), info);
248: fireProgressListenerStep();
249: fireProgressListenerStep();
250: if (hiddenField != null) {
251: String msg = new MessageFormat(getString("ERR_Hides"))
252: .format(new Object[] { SourceUtils
253: .getEnclosingTypeElement(hiddenField) });
254: preCheckProblem = createProblem(preCheckProblem, false,
255: msg);
256: }
257: break;
258: case PACKAGE:
259: //TODO: any prechecks?
260: break;
261: case LOCAL_VARIABLE:
262: //TODO: any prechecks for formal parametr or local variable?
263: break;
264: case CLASS:
265: case INTERFACE:
266: case ANNOTATION_TYPE:
267: case ENUM:
268: //TODO: any prechecks for JavaClass?
269: break;
270: default:
271: // if (!((jmiObject instanceof Resource) && ((Resource)jmiObject).getClassifiers().isEmpty()))
272: // result = createProblem(result, true, NbBundle.getMessage(RenameRefactoring.class, "ERR_RenameWrongType"));
273: }
274: fireProgressListenerStop();
275: return preCheckProblem;
276: }
277:
278: private static final String getCannotRename(FileObject r) {
279: return new MessageFormat(NbBundle.getMessage(
280: RenameRefactoringPlugin.class, "ERR_CannotRenameFile"))
281: .format(new Object[] { r.getNameExt() });
282: }
283:
284: @Override
285: protected Problem fastCheckParameters(CompilationController info)
286: throws IOException {
287: Problem fastCheckProblem = null;
288: info.toPhase(JavaSource.Phase.RESOLVED);
289: TreePath treePath = treePathHandle.resolve(info);
290: Element element = treePathHandle.resolveElement(info);
291: ElementKind kind = element.getKind();
292:
293: String newName = refactoring.getNewName();
294: String oldName = element.getSimpleName().toString();
295:
296: if (oldName.equals(newName)) {
297: boolean nameNotChanged = true;
298: if (kind.isClass()) {
299: if (!((TypeElement) element).getNestingKind()
300: .isNested()) {
301: nameNotChanged = info.getFileObject().getName()
302: .equals(element);
303: }
304: }
305: if (nameNotChanged) {
306: fastCheckProblem = createProblem(fastCheckProblem,
307: true, getString("ERR_NameNotChanged"));
308: return fastCheckProblem;
309: }
310:
311: }
312:
313: if (!Utilities.isJavaIdentifier(newName)) {
314: String s = kind == ElementKind.PACKAGE ? getString("ERR_InvalidPackage")
315: : getString("ERR_InvalidIdentifier"); //NOI18N
316: String msg = new MessageFormat(s)
317: .format(new Object[] { newName });
318: fastCheckProblem = createProblem(fastCheckProblem, true,
319: msg);
320: return fastCheckProblem;
321: }
322:
323: if (kind.isClass()
324: && !((TypeElement) element).getNestingKind().isNested()) {
325: if (doCheckName) {
326: String oldfqn = RetoucheUtils
327: .getQualifiedName(treePathHandle);
328: String newFqn = oldfqn.substring(0, oldfqn
329: .lastIndexOf(oldName));
330:
331: String pkgname = oldfqn;
332: int i = pkgname.indexOf('.');
333: if (i >= 0)
334: pkgname = pkgname.substring(0, i);
335: else
336: pkgname = "";
337:
338: String fqn = "".equals(pkgname) ? newName : pkgname
339: + '.' + newName;
340: FileObject fo = treePathHandle.getFileObject();
341: ClassPath cp = ClassPath.getClassPath(fo,
342: ClassPath.SOURCE);
343: if (RetoucheUtils.typeExist(treePathHandle, newFqn)) {
344: String msg = new MessageFormat(
345: getString("ERR_ClassClash"))
346: .format(new Object[] { newName, pkgname });
347: fastCheckProblem = createProblem(fastCheckProblem,
348: true, msg);
349: return fastCheckProblem;
350: }
351: }
352: FileObject primFile = treePathHandle.getFileObject();
353: FileObject folder = primFile.getParent();
354: FileObject[] children = folder.getChildren();
355: for (int x = 0; x < children.length; x++) {
356: if (children[x] != primFile && !children[x].isVirtual()
357: && children[x].getName().equals(newName)
358: && "java".equals(children[x].getExt())) { //NOI18N
359: String msg = new MessageFormat(
360: getString("ERR_ClassClash"))
361: .format(new Object[] { newName,
362: folder.getPath() });
363: fastCheckProblem = createProblem(fastCheckProblem,
364: true, msg);
365: break;
366: }
367: } // for
368: } else if (kind == ElementKind.LOCAL_VARIABLE
369: || kind == ElementKind.PARAMETER) {
370: String msg = variableClashes(newName, treePath, info);
371: if (msg != null) {
372: fastCheckProblem = createProblem(fastCheckProblem,
373: true, msg);
374: return fastCheckProblem;
375: }
376: } else {
377: String msg = clashes(element, newName, info);
378: if (msg != null) {
379: fastCheckProblem = createProblem(fastCheckProblem,
380: true, msg);
381: return fastCheckProblem;
382: }
383: }
384: return fastCheckProblem;
385: }
386:
387: @Override
388: protected Problem checkParameters(CompilationController info)
389: throws IOException {
390:
391: Problem checkProblem = null;
392: int steps = 0;
393: if (overriddenByMethods != null)
394: steps += overriddenByMethods.size();
395: if (overridesMethods != null)
396: steps += overridesMethods.size();
397:
398: fireProgressListenerStart(refactoring.PARAMETERS_CHECK,
399: 8 + 3 * steps);
400:
401: info.toPhase(JavaSource.Phase.RESOLVED);
402: Element element = treePathHandle.resolveElement(info);
403:
404: fireProgressListenerStep();
405: fireProgressListenerStep();
406: String msg;
407: if (element.getKind() == ElementKind.METHOD) {
408: checkProblem = checkMethodForOverriding(
409: (ExecutableElement) element, refactoring
410: .getNewName(), checkProblem, info);
411: fireProgressListenerStep();
412: fireProgressListenerStep();
413: } else if (element.getKind().isField()) {
414: fireProgressListenerStep();
415: fireProgressListenerStep();
416: Element hiddenField = hides(element, refactoring
417: .getNewName(), info);
418: fireProgressListenerStep();
419: fireProgressListenerStep();
420: fireProgressListenerStep();
421: if (hiddenField != null) {
422: msg = new MessageFormat(getString("ERR_WillHide"))
423: .format(new Object[] { SourceUtils
424: .getEnclosingTypeElement(hiddenField)
425: .toString() });
426: checkProblem = createProblem(checkProblem, false, msg);
427: }
428: }
429: fireProgressListenerStop();
430: return checkProblem;
431: }
432:
433: private Problem checkMethodForOverriding(ExecutableElement m,
434: String newName, Problem problem, CompilationInfo info) {
435: ElementUtilities ut = info.getElementUtilities();
436: //problem = willBeOverridden(m, newName, argTypes, problem);
437: fireProgressListenerStep();
438: problem = willOverride(m, newName, problem, info);
439: fireProgressListenerStep();
440: return problem;
441: }
442:
443: private Set<ElementHandle<ExecutableElement>> allMethods;
444:
445: private Set<FileObject> getRelevantFiles() {
446: ClasspathInfo cpInfo = getClasspathInfo(refactoring);
447: final Set<FileObject> set = new HashSet<FileObject>();
448: JavaSource source = JavaSource.create(cpInfo, treePathHandle
449: .getFileObject());
450:
451: try {
452: source.runUserActionTask(
453: new CancellableTask<CompilationController>() {
454:
455: public void cancel() {
456: throw new UnsupportedOperationException(
457: "Not supported yet."); // NOI18N
458: }
459:
460: public void run(CompilationController info)
461: throws Exception {
462: final ClassIndex idx = info
463: .getClasspathInfo().getClassIndex();
464: info.toPhase(JavaSource.Phase.RESOLVED);
465: Element el = treePathHandle
466: .resolveElement(info);
467: ElementKind kind = el.getKind();
468: ElementHandle<TypeElement> enclosingType;
469: if (el instanceof TypeElement) {
470: enclosingType = ElementHandle
471: .create((TypeElement) el);
472: } else {
473: enclosingType = ElementHandle
474: .create(SourceUtils
475: .getEnclosingTypeElement(el));
476: }
477: set.add(SourceUtils.getFile(el, info
478: .getClasspathInfo()));
479: if (el.getModifiers().contains(
480: Modifier.PRIVATE)) {
481: if (kind == ElementKind.METHOD) {
482: //add all references of overriding methods
483: allMethods = new HashSet<ElementHandle<ExecutableElement>>();
484: allMethods
485: .add(ElementHandle
486: .create((ExecutableElement) el));
487: }
488: } else {
489: if (kind.isField()) {
490: set
491: .addAll(idx
492: .getResources(
493: enclosingType,
494: EnumSet
495: .of(ClassIndex.SearchKind.FIELD_REFERENCES),
496: EnumSet
497: .of(ClassIndex.SearchScope.SOURCE)));
498: } else if (el instanceof TypeElement) {
499: set
500: .addAll(idx
501: .getResources(
502: enclosingType,
503: EnumSet
504: .of(
505: ClassIndex.SearchKind.TYPE_REFERENCES,
506: ClassIndex.SearchKind.IMPLEMENTORS),
507: EnumSet
508: .of(ClassIndex.SearchScope.SOURCE)));
509: } else if (kind == ElementKind.METHOD) {
510: //add all references of overriding methods
511: allMethods = new HashSet<ElementHandle<ExecutableElement>>();
512: allMethods
513: .add(ElementHandle
514: .create((ExecutableElement) el));
515: for (ExecutableElement e : RetoucheUtils
516: .getOverridingMethods(
517: (ExecutableElement) el,
518: info)) {
519: addMethods(e, set, info, idx);
520: }
521: //add all references of overriden methods
522: for (ExecutableElement ov : RetoucheUtils
523: .getOverridenMethods(
524: (ExecutableElement) el,
525: info)) {
526: addMethods(ov, set, info, idx);
527: for (ExecutableElement e : RetoucheUtils
528: .getOverridingMethods(
529: ov, info)) {
530: addMethods(e, set, info,
531: idx);
532: }
533: }
534: set
535: .addAll(idx
536: .getResources(
537: enclosingType,
538: EnumSet
539: .of(ClassIndex.SearchKind.METHOD_REFERENCES),
540: EnumSet
541: .of(ClassIndex.SearchScope.SOURCE))); //?????
542: }
543: }
544: }
545: }, true);
546: } catch (IOException ioe) {
547: throw (RuntimeException) new RuntimeException()
548: .initCause(ioe);
549: }
550: return set;
551: }
552:
553: private void addMethods(ExecutableElement e, Set set,
554: CompilationInfo info, ClassIndex idx) {
555: set.add(SourceUtils.getFile(e, info.getClasspathInfo()));
556: ElementHandle<TypeElement> encl = ElementHandle
557: .create(SourceUtils.getEnclosingTypeElement(e));
558: set.addAll(idx.getResources(encl, EnumSet
559: .of(ClassIndex.SearchKind.METHOD_REFERENCES), EnumSet
560: .of(ClassIndex.SearchScope.SOURCE)));
561: allMethods.add(ElementHandle.create(e));
562: }
563:
564: public Problem prepare(RefactoringElementsBag elements) {
565: if (treePathHandle == null)
566: return null;
567: Set<FileObject> a = getRelevantFiles();
568: fireProgressListenerStart(ProgressEvent.START, a.size());
569: TransformTask transform = new TransformTask(
570: new RenameTransformer(refactoring.getNewName(),
571: allMethods, refactoring.isSearchInComments()),
572: treePathHandle);
573: createAndAddElements(a, transform, elements, refactoring);
574: fireProgressListenerStop();
575: return null;
576: }
577:
578: private static int getAccessLevel(Element e) {
579: Set<Modifier> access = e.getModifiers();
580: if (access.contains(Modifier.PUBLIC)) {
581: return 3;
582: } else if (access.contains(Modifier.PROTECTED)) {
583: return 2;
584: } else if (!access.contains(Modifier.PRIVATE)) {
585: return 1;
586: } else {
587: return 0;
588: }
589: }
590:
591: private Problem willOverride(ExecutableElement method, String name,
592: Problem problem, CompilationInfo info) {
593: boolean isStatic = method.getModifiers().contains(
594: Modifier.STATIC);
595: TypeElement jc = (TypeElement) method.getEnclosingElement();
596: LinkedList super types = new LinkedList();
597:
598: ElementUtilities ut = info.getElementUtilities();
599: //TODO:
600: //ExecutableElement m = ut.getOverriddenMethod(method, name);
601: ExecutableElement m = null;
602: if (m != null) {
603: if (m.getModifiers().contains(Modifier.FINAL)) {
604: String msg = new MessageFormat(
605: getString("ERR_WillOverride_final"))
606: .format(new Object[] {
607: method.getSimpleName(),
608: method.getEnclosingElement()
609: .getSimpleName(),
610: m.getSimpleName(),
611: m.getEnclosingElement().getSimpleName() });
612: return createProblem(problem, true, msg);
613: } else if (getAccessLevel(m) > getAccessLevel(method)) {
614: String msg = new MessageFormat(
615: getString("ERR_WillOverride_access"))
616: .format(new Object[] {
617: method.getSimpleName(),
618: method.getEnclosingElement()
619: .getSimpleName(),
620: m.getSimpleName(),
621: m.getEnclosingElement().getSimpleName() });
622: return createProblem(problem, true, msg);
623: } else if (m.getModifiers().contains(Modifier.STATIC) != method
624: .getModifiers().contains(Modifier.STATIC)) {
625: String msg = new MessageFormat(
626: getString("ERR_WillOverride_static"))
627: .format(new Object[] {
628: isStatic ? getString("LBL_static")
629: : getString("LBL_instance"),
630: method.getSimpleName(),
631: method.getEnclosingElement()
632: .getSimpleName(),
633: m.getModifiers().contains(
634: Modifier.STATIC) ? getString("LBL_static")
635: : getString("LBL_instance"),
636: m.getSimpleName(),
637: m.getEnclosingElement().getSimpleName() });
638: return createProblem(problem, true, msg);
639: } else {
640: String msg = new MessageFormat(
641: getString("ERR_WillOverride"))
642: .format(new Object[] {
643: method.getSimpleName(),
644: method.getEnclosingElement()
645: .getSimpleName(),
646: m.getSimpleName(),
647: m.getEnclosingElement().getSimpleName() });
648: return createProblem(problem, false, msg);
649: }
650: } else {
651: return problem;
652: }
653: }
654:
655: private Element hides(Element field, String name,
656: CompilationInfo info) {
657: TypeElement jc = SourceUtils.getEnclosingTypeElement(field);
658: Elements elements = info.getElements();
659: ElementUtilities utils = info.getElementUtilities();
660: for (Element el : elements.getAllMembers(jc)) {
661: //TODO:
662: // if (utils.willHide(el, field, name)) {
663: // return el;
664: // }
665: if (el.getKind().isField()) {
666: if (el.getSimpleName().toString().equals(name)) {
667: if (!el.getEnclosingElement().equals(
668: field.getEnclosingElement())) {
669: return el;
670: }
671: }
672: }
673: }
674: return null;
675: }
676:
677: private String variableClashes(String newName, TreePath tp,
678: CompilationInfo info) {
679: LocalVarScanner lookup = new LocalVarScanner(info, newName);
680: TreePath scopeBlok = tp;
681: EnumSet set = EnumSet.of(Tree.Kind.BLOCK, Tree.Kind.FOR_LOOP,
682: Tree.Kind.METHOD);
683: while (!set.contains(scopeBlok.getLeaf().getKind())) {
684: scopeBlok = scopeBlok.getParentPath();
685: }
686: Element var = info.getTrees().getElement(tp);
687: lookup.scan(scopeBlok, var);
688:
689: if (lookup.hasRefernces())
690: return new MessageFormat(getString("ERR_LocVariableClash"))
691: .format(new Object[] { newName });
692:
693: TreePath temp = tp;
694: while (temp.getLeaf().getKind() != Tree.Kind.METHOD) {
695: Scope scope = info.getTrees().getScope(temp);
696: for (Element el : scope.getLocalElements()) {
697: if (el.getSimpleName().toString().equals(newName)) {
698: return new MessageFormat(
699: getString("ERR_LocVariableClash"))
700: .format(new Object[] { newName });
701: }
702: }
703: temp = temp.getParentPath();
704: }
705: return null;
706: }
707:
708: private String clashes(Element feature, String newName,
709: CompilationInfo info) {
710: ElementUtilities utils = info.getElementUtilities();
711: Element dc = feature.getEnclosingElement();
712: ElementKind kind = feature.getKind();
713: if (kind.isClass() || kind.isInterface()) {
714: for (Element current : ElementFilter.typesIn(dc
715: .getEnclosedElements())) {
716: if (current.getSimpleName().toString().equals(newName)) {
717: return new MessageFormat(
718: getString("ERR_InnerClassClash"))
719: .format(new Object[] { newName,
720: dc.getSimpleName() });
721: }
722: }
723: } else if (kind == ElementKind.METHOD) {
724: if (utils
725: .alreadyDefinedIn((CharSequence) newName,
726: (ExecutableType) feature.asType(),
727: (TypeElement) dc)) {
728: return new MessageFormat(getString("ERR_MethodClash"))
729: .format(new Object[] { newName,
730: dc.getSimpleName() });
731: }
732: } else if (kind.isField()) {
733: for (Element current : ElementFilter.fieldsIn(dc
734: .getEnclosedElements())) {
735: if (current.getSimpleName().toString().equals(newName)) {
736: return new MessageFormat(
737: getString("ERR_FieldClash"))
738: .format(new Object[] { newName,
739: dc.getSimpleName() });
740: }
741: }
742: }
743: return null;
744: }
745:
746: private static final String getString(String key) {
747: return NbBundle.getMessage(RenameRefactoringPlugin.class, key);
748: }
749: }
|