001: /*******************************************************************************
002: * Copyright (c) 2000, 2005 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.corext.refactoring.code;
011:
012: import java.util.ArrayList;
013: import java.util.Iterator;
014: import java.util.List;
015:
016: import org.eclipse.jdt.core.dom.ASTVisitor;
017: import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
018: import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
019: import org.eclipse.jdt.core.dom.BodyDeclaration;
020: import org.eclipse.jdt.core.dom.EnumDeclaration;
021: import org.eclipse.jdt.core.dom.IBinding;
022: import org.eclipse.jdt.core.dom.ITypeBinding;
023: import org.eclipse.jdt.core.dom.SimpleName;
024: import org.eclipse.jdt.core.dom.TypeDeclaration;
025:
026: import org.eclipse.jdt.internal.corext.dom.Selection;
027: import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
028: import org.eclipse.ltk.core.refactoring.RefactoringStatus;
029:
030: public class LocalTypeAnalyzer extends ASTVisitor {
031:
032: private Selection fSelection;
033: private List fTypeDeclarationsBefore = new ArrayList(2);
034: private List fTypeDeclarationsSelected = new ArrayList(2);
035: private String fBeforeTypeReferenced;
036: private String fSelectedTypeReferenced;
037:
038: //---- Analyzing statements ----------------------------------------------------------------
039:
040: public static RefactoringStatus perform(
041: BodyDeclaration declaration, Selection selection) {
042: LocalTypeAnalyzer analyzer = new LocalTypeAnalyzer(selection);
043: declaration.accept(analyzer);
044: RefactoringStatus result = new RefactoringStatus();
045: analyzer.check(result);
046: return result;
047: }
048:
049: private LocalTypeAnalyzer(Selection selection) {
050: fSelection = selection;
051: }
052:
053: public boolean visit(SimpleName node) {
054: if (node.isDeclaration())
055: return true;
056: IBinding binding = node.resolveBinding();
057: if (binding instanceof ITypeBinding)
058: processLocalTypeBinding((ITypeBinding) binding, fSelection
059: .getVisitSelectionMode(node));
060:
061: return true;
062: }
063:
064: public boolean visit(TypeDeclaration node) {
065: return visitType(node);
066: }
067:
068: public boolean visit(AnnotationTypeDeclaration node) {
069: return visitType(node);
070: }
071:
072: public boolean visit(EnumDeclaration node) {
073: return visitType(node);
074: }
075:
076: private boolean visitType(AbstractTypeDeclaration node) {
077: int mode = fSelection.getVisitSelectionMode(node);
078: switch (mode) {
079: case Selection.BEFORE:
080: fTypeDeclarationsBefore.add(node);
081: break;
082: case Selection.SELECTED:
083: fTypeDeclarationsSelected.add(node);
084: break;
085: }
086: return true;
087: }
088:
089: private void processLocalTypeBinding(ITypeBinding binding, int mode) {
090: switch (mode) {
091: case Selection.SELECTED:
092: if (fBeforeTypeReferenced != null)
093: break;
094: if (checkBinding(fTypeDeclarationsBefore, binding))
095: fBeforeTypeReferenced = RefactoringCoreMessages.LocalTypeAnalyzer_local_type_from_outside;
096: break;
097: case Selection.AFTER:
098: if (fSelectedTypeReferenced != null)
099: break;
100: if (checkBinding(fTypeDeclarationsSelected, binding))
101: fSelectedTypeReferenced = RefactoringCoreMessages.LocalTypeAnalyzer_local_type_referenced_outside;
102: break;
103: }
104: }
105:
106: private boolean checkBinding(List declarations, ITypeBinding binding) {
107: for (Iterator iter = declarations.iterator(); iter.hasNext();) {
108: AbstractTypeDeclaration declaration = (AbstractTypeDeclaration) iter
109: .next();
110: if (declaration.resolveBinding() == binding) {
111: return true;
112: }
113: }
114: return false;
115: }
116:
117: private void check(RefactoringStatus status) {
118: if (fBeforeTypeReferenced != null)
119: status.addFatalError(fBeforeTypeReferenced);
120: if (fSelectedTypeReferenced != null)
121: status.addFatalError(fSelectedTypeReferenced);
122: }
123: }
|