Boolean isScript = myScript;
if (isScript == null) {
final GrTopStatement[] topStatements = findChildrenByClass(GrTopStatement.class);
- isScript = topStatements.length == 0;
+ isScript = Boolean.FALSE;
for (GrTopStatement st : topStatements) {
if (!(st instanceof GrTypeDefinition || st instanceof GrImportStatement || st instanceof GrPackageDefinition)) {
isScript = Boolean.TRUE;
package org.jetbrains.plugins.groovy.refactoring.move;
-import com.intellij.psi.*;
-import com.intellij.psi.impl.source.tree.Factory;
-import com.intellij.psi.impl.source.tree.TreeElement;
-import com.intellij.psi.javadoc.PsiDocComment;
-import com.intellij.psi.search.LocalSearchScope;
-import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiFile;
import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassHandler;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.GroovyFileType;
-import org.jetbrains.plugins.groovy.actions.GroovyTemplatesFactory;
-import org.jetbrains.plugins.groovy.actions.NewGroovyActionBase;
-import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
-import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
-import org.jetbrains.plugins.groovy.refactoring.GroovyChangeContextUtil;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
/**
* @author Maxim.Medvedev
*/
public class MoveGroovyClassHandler implements MoveClassHandler {
public PsiClass doMoveClass(@NotNull PsiClass aClass, @NotNull PsiDirectory moveDestination) throws IncorrectOperationException {
- if (!aClass.getLanguage().equals(GroovyFileType.GROOVY_LANGUAGE)) return null;
- PsiFile file = aClass.getContainingFile();
- final PsiPackage newPackage = JavaDirectoryService.getInstance().getPackage(moveDestination);
-
- GroovyChangeContextUtil.encodeContextInfo(aClass);
-
- PsiClass newClass = null;
- if (file instanceof GroovyFile) {
- if (((GroovyFile)file).isScript() || ((GroovyFile)file).getClasses().length > 1) {
- correctSelfReferences(aClass, newPackage);
- final PsiClass created = ((GroovyFile)GroovyTemplatesFactory
- .createFromTemplate(moveDestination, aClass.getName(), aClass.getName() + NewGroovyActionBase.GROOVY_EXTENSION,
- "GroovyClass.groovy")).getClasses()[0];
- if (aClass.getDocComment() == null) {
- final PsiDocComment createdDocComment = created.getDocComment();
- if (createdDocComment != null) {
- aClass.addBefore(createdDocComment, null);
- }
- }
- newClass = (PsiClass)created.replace(aClass);
- correctOldClassReferences(newClass, aClass);
- aClass.delete();
- }
- else if (!moveDestination.equals(file.getContainingDirectory()) && moveDestination.findFile(file.getName()) != null) {
- // moving second of two classes which were in the same file to a different directory (IDEADEV-3089)
- correctSelfReferences(aClass, newPackage);
- PsiFile newFile = moveDestination.findFile(file.getName());
- TreeElement enter = Factory.createSingleLeafElement(GroovyTokenTypes.mNLS, "\n", 0, 1, null, aClass.getManager());
- newFile.getNode().addChild(enter);
- newClass = (PsiClass)newFile.add(aClass);
- aClass.delete();
- }
- else if (!moveDestination.equals(file.getContainingDirectory()) && moveDestination.findFile(file.getName()) == null) {
- if (!moveDestination.equals(file.getContainingDirectory())) {
- aClass.getManager().moveFile(file, moveDestination);
- newClass=((GroovyFile)file).getClasses()[0];
- if (newPackage != null) {
- ((PsiClassOwner)file).setPackageName(newPackage.getQualifiedName());
- }
- }
- }
- }
- if (newClass != null) GroovyChangeContextUtil.decodeContextInfo(newClass, null, null);
- return newClass;
- }
-
- private static void correctOldClassReferences(final PsiClass newClass, final PsiClass oldClass) {
- for (PsiReference reference : ReferencesSearch.search(oldClass, new LocalSearchScope(newClass)).findAll()) {
- reference.bindToElement(newClass);
- }
- }
-
- private static void correctSelfReferences(final PsiClass aClass, final PsiPackage newContainingPackage) {
- final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(aClass.getContainingFile().getContainingDirectory());
- if (aPackage == null) {
- return;
- }
-
- for (PsiReference reference : ReferencesSearch.search(aClass, new LocalSearchScope(aClass)).findAll()) {
- if (reference instanceof GrCodeReferenceElement) {
- final GrCodeReferenceElement qualifier = ((GrCodeReferenceElement)reference).getQualifier();
- if (qualifier != null) {
- qualifier.bindToElement(newContainingPackage);
- }
- }
- }
+ return MoveGroovyClassUtil.moveGroovyClass((GrTypeDefinition)aClass, moveDestination);
}
+ @Nullable
public String getName(PsiClass clazz) {
final PsiFile file = clazz.getContainingFile();
if (!(file instanceof GroovyFile)) return null;
--- /dev/null
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.refactoring.move;
+
+import com.intellij.psi.*;
+import com.intellij.psi.impl.source.tree.Factory;
+import com.intellij.psi.impl.source.tree.TreeElement;
+import com.intellij.psi.javadoc.PsiDocComment;
+import com.intellij.psi.search.LocalSearchScope;
+import com.intellij.psi.search.searches.ReferencesSearch;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.GroovyFileType;
+import org.jetbrains.plugins.groovy.actions.GroovyTemplatesFactory;
+import org.jetbrains.plugins.groovy.actions.NewGroovyActionBase;
+import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
+import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
+import org.jetbrains.plugins.groovy.refactoring.GroovyChangeContextUtil;
+
+/**
+ * @author Maxim.Medvedev
+ */
+public class MoveGroovyClassUtil {
+ private MoveGroovyClassUtil() {
+ }
+
+ @Nullable
+ public static PsiClass moveGroovyClass(@NotNull GrTypeDefinition aClass, @NotNull PsiDirectory moveDestination) {
+ if (!aClass.getLanguage().equals(GroovyFileType.GROOVY_LANGUAGE)) return null;
+ PsiFile file = aClass.getContainingFile();
+ final PsiPackage newPackage = JavaDirectoryService.getInstance().getPackage(moveDestination);
+
+ GroovyChangeContextUtil.encodeContextInfo(aClass);
+
+ PsiClass newClass = null;
+ if (file instanceof GroovyFile) {
+ if (((GroovyFile)file).isScript() || ((GroovyFile)file).getClasses().length > 1) {
+ correctSelfReferences(aClass, newPackage);
+ final PsiClass created = ((GroovyFile)GroovyTemplatesFactory
+ .createFromTemplate(moveDestination, aClass.getName(), aClass.getName() + NewGroovyActionBase.GROOVY_EXTENSION,
+ "GroovyClass.groovy")).getClasses()[0];
+ if (aClass.getDocComment() == null) {
+ final PsiDocComment createdDocComment = created.getDocComment();
+ if (createdDocComment != null) {
+ aClass.addBefore(createdDocComment, null);
+ }
+ }
+ newClass = (PsiClass)created.replace(aClass);
+ correctOldClassReferences(newClass, aClass);
+ aClass.delete();
+ }
+ else if (!moveDestination.equals(file.getContainingDirectory()) && moveDestination.findFile(file.getName()) != null) {
+ // moving second of two classes which were in the same file to a different directory (IDEADEV-3089)
+ correctSelfReferences(aClass, newPackage);
+ PsiFile newFile = moveDestination.findFile(file.getName());
+ TreeElement enter = Factory.createSingleLeafElement(GroovyTokenTypes.mNLS, "\n", 0, 1, null, aClass.getManager());
+ newFile.getNode().addChild(enter);
+ newClass = (GrTypeDefinition)newFile.add(aClass);
+ aClass.delete();
+ }
+ else if (!moveDestination.equals(file.getContainingDirectory()) && moveDestination.findFile(file.getName()) == null) {
+ if (!moveDestination.equals(file.getContainingDirectory())) {
+ aClass.getManager().moveFile(file, moveDestination);
+ newClass = ((GroovyFile)file).getClasses()[0];
+ if (newPackage != null) {
+ ((PsiClassOwner)file).setPackageName(newPackage.getQualifiedName());
+ }
+ }
+ }
+ }
+ if (newClass != null) GroovyChangeContextUtil.decodeContextInfo(newClass, null, null);
+ return newClass;
+ }
+
+ private static void correctOldClassReferences(final PsiClass newClass, final PsiClass oldClass) {
+ for (PsiReference reference : ReferencesSearch.search(oldClass, new LocalSearchScope(newClass)).findAll()) {
+ reference.bindToElement(newClass);
+ }
+ }
+
+ private static void correctSelfReferences(final PsiClass aClass, final PsiPackage newContainingPackage) {
+ final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(aClass.getContainingFile().getContainingDirectory());
+ if (aPackage == null) {
+ return;
+ }
+
+ for (PsiReference reference : ReferencesSearch.search(aClass, new LocalSearchScope(aClass)).findAll()) {
+ if (reference instanceof GrCodeReferenceElement) {
+ final GrCodeReferenceElement qualifier = ((GrCodeReferenceElement)reference).getQualifier();
+ if (qualifier != null) {
+ qualifier.bindToElement(newContainingPackage);
+ }
+ }
+ }
+ }
+}
import com.intellij.refactoring.HelpID;
import com.intellij.refactoring.JavaRefactoringSettings;
import com.intellij.refactoring.move.MoveCallback;
-import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesDialog;
import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesHandlerBase;
import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesImpl;
import com.intellij.refactoring.util.CommonRefactoringUtil;
for (PsiElement element : elements) {
if (!canMove(element)) return false;
}
- return super.canMove(elements, targetContainer);
+ return targetContainer == null || isValidTarget(targetContainer, elements);
}
private static boolean canMove(PsiElement element) {
}
final PsiClass[] classes = file.getClasses();
- return classes.length == 1 && classes[0] instanceof GroovyScriptClass;
+ return classes.length > 0 && classes[0] instanceof GroovyScriptClass;
}
@Override
PsiElement psiElement = elements[i];
searchTextOccurences = TextOccurrencesUtil.isSearchTextOccurencesEnabled(psiElement);
}
- final MoveClassesOrPackagesDialog moveDialog =
+ final MoveGroovyScriptDialog moveDialog =
new MoveGroovyScriptDialog(project, searchTextOccurences, elements, initialTargetElement, moveCallback);
boolean searchInComments = JavaRefactoringSettings.getInstance().MOVE_SEARCH_IN_COMMENTS;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
import org.jetbrains.plugins.groovy.refactoring.GroovyChangeContextUtil;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
/**
* @author Maxim.Medvedev
for (PsiElement element : elements) {
final GroovyFile groovyFile = (GroovyFile)element;
- final PsiClass scriptClass = groovyFile.getClasses()[0];
- String newName = getTargetPackage().getQualifiedName() + scriptClass.getName();
+ final PsiClass[] classes = groovyFile.getClasses();
+ for (PsiClass aClass : classes) {
+ String newName = getTargetPackage().getQualifiedName() + aClass.getName();
- final UsageInfo[] usages = MoveClassesOrPackagesUtil.findUsages(scriptClass, isSearchInComments(), isSearchInNonJavaFiles(), newName);
- allUsages.addAll(new ArrayList<UsageInfo>(Arrays.asList(usages)));
+ final UsageInfo[] usages = MoveClassesOrPackagesUtil.findUsages(aClass, isSearchInComments(), isSearchInNonJavaFiles(), newName);
+ allUsages.addAll(new ArrayList<UsageInfo>(Arrays.asList(usages)));
+ }
}
myMoveDestination
.analyzeModuleConflicts(elements, conflicts, allUsages.toArray(new UsageInfo[allUsages.size()]));
GroovyFile file = (GroovyFile)element;
final RefactoringElementListener elementListener = getTransaction().getElementListener(file);
- PsiClass oldScriptClass = file.getClasses()[0];
-
+ final PsiClass[] oldClasses = file.getClasses();
GroovyChangeContextUtil.encodeContextInfo(file);
PsiManager.getInstance(myProject).moveFile(file, myMoveDestination.getTargetDirectory(file));
file.setPackageName(getTargetPackage().getQualifiedName());
- PsiClass newScriptClass = file.getClasses()[0];
- oldToNewElementsMapping.put(oldScriptClass, newScriptClass);
+ PsiClass[] newClasses = file.getClasses();
+ for (int i = 0; i < oldClasses.length; i++) {
+ oldToNewElementsMapping.put(oldClasses[i], newClasses[i]);
+ }
elementListener.elementMoved(file);
}
doTest("multiMove", new String[]{"a/Script.groovy", "a/Script2.groovy"}, "b");
}
- private void performAction(String[] fileNames, String newDirName, String dir) throws Exception {
+ public void testScriptWithClasses() {
+ doTest("scriptWithClasses", new String[]{"a/Foo.groovy"}, "b");
+ }
+
+ private void performAction(String[] fileNames, String newDirName, String dir) {
final PsiFile[] files = new PsiFile[fileNames.length];
for (int i = 0; i < files.length; i++) {
String fileName = fileNames[i];
FileDocumentManager.getInstance().saveAllDocuments();
}
- private void doTest(String testName, String[] fileNames, String newDirName) throws Exception {
+ private void doTest(String testName, String[] fileNames, String newDirName) {
final VirtualFile actualRoot = myFixture.copyDirectoryToProject(testName + "/before", "");
performAction(fileNames, newDirName, VfsUtil.getRelativePath(actualRoot, myFixture.getTempDirFixture().getFile(""), '/'));
--- /dev/null
+package a
+import b.Foo
+
+class Y {
+ def foo
+
+ def a() {
+ Foo.main();
+ }
+}
\ No newline at end of file
--- /dev/null
+package a
+import a.Y
+
+class A {
+ def foo
+}
+
+print new A().foo
+print new X().foo
+print new Y().foo
\ No newline at end of file
--- /dev/null
+package b
+
+class X {
+ def foo
+
+ def a() {
+ A a = new A()
+ print a
+ }
+}
\ No newline at end of file
--- /dev/null
+package a
+import b.X
+
+class A {
+ def foo
+}
+
+print new A().foo
+print new X().foo
+print new Y().foo
\ No newline at end of file
--- /dev/null
+package a
+
+class Y {
+ def foo
+
+ def a() {
+ Foo.main();
+ }
+}
\ No newline at end of file
--- /dev/null
+package b
+import a.A
+
+class X {
+ def foo
+
+ def a() {
+ A a = new A()
+ print a
+ }
+}
\ No newline at end of file