From e5c0166f6892d6c802be5f91b90e7ebd4c0eebe3 Mon Sep 17 00:00:00 2001 From: peter Date: Sun, 31 Jan 2010 12:38:06 +0000 Subject: [PATCH] yet another bug with compiling interdependent groovy classes, imports were not processed --- .../groovy/compiler/GroovyCompiler.java | 104 ++++++------------ 1 file changed, 36 insertions(+), 68 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompiler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompiler.java index 087684a4250f..49a0acd0fa8a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompiler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompiler.java @@ -35,7 +35,6 @@ import com.intellij.openapi.util.Computable; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.util.containers.FactoryMap; -import gnu.trove.THashMap; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.GroovyBundle; @@ -43,7 +42,9 @@ import org.jetbrains.plugins.groovy.GroovyFileType; import org.jetbrains.plugins.groovy.GroovyFileTypeLoader; import org.jetbrains.plugins.groovy.config.GroovyConfigUtils; 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.lang.psi.impl.synthetic.GroovyScriptClass; import org.jetbrains.plugins.groovy.util.LibrariesUtil; import java.util.*; @@ -75,14 +76,13 @@ public class GroovyCompiler extends GroovyCompilerBase { context.getProgressIndicator().checkCanceled(); context.getProgressIndicator().setText("Enumerating Groovy classes..."); - final Map moduleClasses = new THashMap(); - int groovyFiles = enumerateGroovyClasses(module, moduleClasses); + Set groovyFiles = enumerateGroovyFiles(module); - if (toCompile.size() < groovyFiles) { + if (toCompile.size() < groovyFiles.size()) { context.getProgressIndicator().checkCanceled(); context.getProgressIndicator().setText("Processing Groovy dependencies..."); - addIntermediateGroovyClasses(allToCompile, moduleClasses); + addIntermediateGroovyClasses(allToCompile, groovyFiles); } } @@ -92,81 +92,46 @@ public class GroovyCompiler extends GroovyCompilerBase { runGroovycCompiler(context, module, new ArrayList(allToCompile), false, getMainOutput(context, module, tests), sink, tests); } - private void addIntermediateGroovyClasses(Set allToCompile, final Map moduleClasses) { - final Set initialClasses = new THashSet(); - for (VirtualFile file : allToCompile) { - initialClasses.addAll(getAllClasses(file)); - } + private void addIntermediateGroovyClasses(Set allToCompile, final Set groovyFiles) { + final Set initialFiles = new THashSet(allToCompile); - final THashSet dirty = new THashSet(initialClasses); - - final THashSet visited = new THashSet(); - for (PsiClass aClass : initialClasses) { + final THashSet visited = new THashSet(); + for (VirtualFile aClass : initialFiles) { if (visited.add(aClass)) { - goForIntermediateClasses(aClass, dirty, new FactoryMap>() { + goForIntermediateFiles(aClass, allToCompile, new FactoryMap>() { @Override - protected Set create(final PsiClass key) { - return ApplicationManager.getApplication().runReadAction(new Computable>() { - public Set compute() { - return calcCodeReferenceDependencies(key, moduleClasses); + protected Set create(final VirtualFile key) { + return ApplicationManager.getApplication().runReadAction(new Computable>() { + public Set compute() { + return calcCodeReferenceDependencies(key, groovyFiles); } }); } }, visited); } } - for (PsiClass psiClass : dirty) { - allToCompile.add(moduleClasses.get(psiClass)); - } } - private int enumerateGroovyClasses(final Module module, final Map moduleClasses) { - final Set groovyFiles = new THashSet(); + private Set enumerateGroovyFiles(final Module module) { + final Set moduleClasses = new THashSet(); ModuleRootManager.getInstance(module).getFileIndex().iterateContent(new ContentIterator() { public boolean processFile(final VirtualFile vfile) { - if (!vfile.isDirectory() && GroovyFileType.GROOVY_FILE_TYPE.equals(vfile.getFileType())) { - final List classes = getAllClasses(vfile); - if (!classes.isEmpty()) { - groovyFiles.add(vfile); - for (PsiClass psiClass : classes) { - moduleClasses.put(psiClass, vfile); - } - } - + if (!vfile.isDirectory() && + GroovyFileType.GROOVY_FILE_TYPE.equals(vfile.getFileType()) && + PsiManager.getInstance(myProject).findFile(vfile) instanceof GroovyFile) { + moduleClasses.add(vfile); } return true; } }); - return groovyFiles.size(); + return moduleClasses; } - private List getAllClasses(final VirtualFile vfile) { - final ArrayList classes = new ArrayList(); - ApplicationManager.getApplication().runReadAction(new Runnable() { - public void run() { - final PsiFile file = PsiManager.getInstance(myProject).findFile(vfile); - if (file instanceof GroovyFile) { - addClassesFrom(((GroovyFile)file).getClasses(), classes); - } - } - - private void addClassesFrom(final PsiClass[] classes, List result) { - for (PsiClass aClass : classes) { - result.add(aClass); - addClassesFrom(aClass.getInnerClasses(), result); - } - } - - }); - return classes; - } - - - private static void goForIntermediateClasses(PsiClass from, Set dirty, FactoryMap> deps, Set visited) { - final Set set = deps.get(from); - for (PsiClass psiClass : set) { + private static void goForIntermediateFiles(VirtualFile from, Set dirty, FactoryMap> deps, Set visited) { + final Set set = deps.get(from); + for (VirtualFile psiClass : set) { if (visited.add(psiClass)) { - goForIntermediateClasses(psiClass, dirty, deps, visited); + goForIntermediateFiles(psiClass, dirty, deps, visited); } if (dirty.contains(psiClass)) { dirty.add(from); @@ -174,20 +139,23 @@ public class GroovyCompiler extends GroovyCompilerBase { } } - private Set calcCodeReferenceDependencies(PsiClass psiClass, final Map moduleClasses) { - final Set deps = new THashSet(); - psiClass.acceptChildren(new PsiElementVisitor() { + private Set calcCodeReferenceDependencies(VirtualFile vfile, final Set moduleFiles) { + final PsiFile psi = PsiManager.getInstance(myProject).findFile(vfile); + if (!(psi instanceof GroovyFile)) return Collections.emptySet(); + + final Set deps = new THashSet(); + psi.acceptChildren(new PsiElementVisitor() { @Override public void visitElement(PsiElement element) { - if (element instanceof PsiClass) { - return; - } if (element instanceof GrCodeReferenceElement) { GrCodeReferenceElement referenceElement = (GrCodeReferenceElement)element; try { final PsiElement target = referenceElement.resolve(); - if (target instanceof PsiClass && moduleClasses.containsKey(target)) { - deps.add((PsiClass)target); + if (target instanceof GrTypeDefinition || target instanceof GroovyScriptClass) { + final VirtualFile targetFile = target.getContainingFile().getViewProvider().getVirtualFile(); + if (moduleFiles.contains(targetFile)) { + deps.add(targetFile); + } } } catch (Exception e) {