]> git.uio.no Git - ifi-stolz-refaktor.git/blobdiff - case-study/jdt-after/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/LocalTypeAnalyzer.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-after / core refactoring / org / eclipse / jdt / internal / corext / refactoring / code / LocalTypeAnalyzer.java
diff --git a/case-study/jdt-after/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/LocalTypeAnalyzer.java b/case-study/jdt-after/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/LocalTypeAnalyzer.java
new file mode 100644 (file)
index 0000000..a384f6e
--- /dev/null
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.corext.refactoring.code;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+
+import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
+import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
+import org.eclipse.jdt.core.dom.BodyDeclaration;
+import org.eclipse.jdt.core.dom.EnumDeclaration;
+import org.eclipse.jdt.core.dom.IBinding;
+import org.eclipse.jdt.core.dom.ITypeBinding;
+import org.eclipse.jdt.core.dom.SimpleName;
+import org.eclipse.jdt.core.dom.TypeDeclaration;
+
+import org.eclipse.jdt.internal.corext.dom.Selection;
+import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
+
+public class LocalTypeAnalyzer extends ASTVisitor {
+
+       private Selection fSelection;
+       private List<AbstractTypeDeclaration> fTypeDeclarationsBefore= new ArrayList<AbstractTypeDeclaration>(2);
+       private List<AbstractTypeDeclaration> fTypeDeclarationsSelected= new ArrayList<AbstractTypeDeclaration>(2);
+       private String fBeforeTypeReferenced;
+       private String fSelectedTypeReferenced;
+
+       //---- Analyzing statements ----------------------------------------------------------------
+
+       public static RefactoringStatus perform(BodyDeclaration declaration, Selection selection) {
+               LocalTypeAnalyzer analyzer= new LocalTypeAnalyzer(selection);
+               declaration.accept(analyzer);
+               RefactoringStatus result= new RefactoringStatus();
+               analyzer.check(result);
+               return result;
+       }
+
+       private LocalTypeAnalyzer(Selection selection) {
+               fSelection= selection;
+       }
+
+       @Override
+       public boolean visit(SimpleName node) {
+               if (node.isDeclaration())
+                       return true;
+               IBinding binding= node.resolveBinding();
+               if (binding instanceof ITypeBinding)
+                       processLocalTypeBinding((ITypeBinding) binding, fSelection.getVisitSelectionMode(node));
+
+               return true;
+       }
+
+       @Override
+       public boolean visit(TypeDeclaration node) {
+               return visitType(node);
+       }
+
+       @Override
+       public boolean visit(AnnotationTypeDeclaration node) {
+               return visitType(node);
+       }
+
+       @Override
+       public boolean visit(EnumDeclaration node) {
+               return visitType(node);
+       }
+
+       private boolean visitType(AbstractTypeDeclaration node) {
+               int mode= fSelection.getVisitSelectionMode(node);
+               switch (mode) {
+                       case Selection.BEFORE:
+                               fTypeDeclarationsBefore.add(node);
+                               break;
+                       case Selection.SELECTED:
+                               fTypeDeclarationsSelected.add(node);
+                               break;
+               }
+               return true;
+       }
+
+       private void processLocalTypeBinding(ITypeBinding binding, int mode) {
+               switch (mode) {
+                       case Selection.SELECTED:
+                               if (fBeforeTypeReferenced != null)
+                                       break;
+                               if (checkBinding(fTypeDeclarationsBefore, binding))
+                                       fBeforeTypeReferenced= RefactoringCoreMessages.LocalTypeAnalyzer_local_type_from_outside;
+                               break;
+                       case Selection.AFTER:
+                               if (fSelectedTypeReferenced != null)
+                                       break;
+                               if (checkBinding(fTypeDeclarationsSelected, binding))
+                                       fSelectedTypeReferenced= RefactoringCoreMessages.LocalTypeAnalyzer_local_type_referenced_outside;
+                               break;
+               }
+       }
+
+       private boolean checkBinding(List<AbstractTypeDeclaration> declarations, ITypeBinding binding) {
+               for (Iterator<AbstractTypeDeclaration> iter= declarations.iterator(); iter.hasNext();) {
+                       AbstractTypeDeclaration declaration= iter.next();
+                       if (declaration.resolveBinding() == binding) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       private void check(RefactoringStatus status) {
+               if (fBeforeTypeReferenced != null)
+                       status.addFatalError(fBeforeTypeReferenced);
+               if (fSelectedTypeReferenced != null)
+                       status.addFatalError(fSelectedTypeReferenced);
+       }
+}