don't mention inaccessible class names in stubs, replace them with the first accessib...
authorpeter <peter.gromov@jetbrains.com>
Mon, 26 Apr 2010 14:23:03 +0000 (15:23 +0100)
committerpeter <peter.gromov@jetbrains.com>
Mon, 26 Apr 2010 14:37:29 +0000 (15:37 +0100)
plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovyToJavaGenerator.java
plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GeneratorTest.java
plugins/groovy/testdata/groovy/stubGenerator/inaccessiblePropertyType.test [new file with mode: 0644]

index 2a0cac487203e1a7705aed960b21d7401a6f4381..f3cf1cf50ea07090153199bb64cc0e158ff638aa 100644 (file)
@@ -26,7 +26,6 @@ import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.progress.ProgressIndicator;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.roots.ModuleRootManager;
 import com.intellij.openapi.util.Computable;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vfs.VfsUtil;
@@ -131,8 +130,6 @@ public class GroovyToJavaGenerator {
         continue;
       }
 
-      boolean isInTestSources = ModuleRootManager.getInstance(module).getFileIndex().isInTestSourceContent(file);
-
       final GroovyFileBase psiFile = findPsiFile(file);
       GrTopStatement[] statements = getTopStatementsInReadAction(psiFile);
 
@@ -145,7 +142,8 @@ public class GroovyToJavaGenerator {
 
       //top level class
       if (needCreateTopLevelClass) {
-        generationItems.add(new GenerationItem(prefix + file.getNameWithoutExtension() + "." + "java", module, new TimestampValidityState(file.getTimeStamp()), isInTestSources, file));
+        generationItems.add(new GenerationItem(prefix + file.getNameWithoutExtension() + "." + "java", module, new TimestampValidityState(file.getTimeStamp()),
+                                               file));
       }
 
       GrTypeDefinition[] typeDefinitions = ApplicationManager.getApplication().runReadAction(new Computable<GrTypeDefinition[]>() {
@@ -155,7 +153,8 @@ public class GroovyToJavaGenerator {
       });
 
       for (GrTypeDefinition typeDefinition : typeDefinitions) {
-        item = new GenerationItem(prefix + typeDefinition.getName() + "." + "java", module, new TimestampValidityState(file.getTimeStamp()), isInTestSources, file);
+        item = new GenerationItem(prefix + typeDefinition.getName() + "." + "java", module, new TimestampValidityState(file.getTimeStamp()),
+                                  file);
         generationItems.add(item);
       }
     }
@@ -380,7 +379,7 @@ public class GroovyToJavaGenerator {
       final PsiClassType[] extendsClassesTypes = typeDefinition.getExtendsListTypes();
 
       if (extendsClassesTypes.length > 0) {
-        text.append("extends ").append(computeTypeText(extendsClassesTypes[0], false)).append(" ");
+        text.append("extends ").append(getTypeText(extendsClassesTypes[0], typeDefinition, false)).append(" ");
       }
       PsiClassType[] implementsTypes = typeDefinition.getImplementsListTypes();
 
@@ -389,7 +388,7 @@ public class GroovyToJavaGenerator {
         int i = 0;
         while (i < implementsTypes.length) {
           if (i > 0) text.append(", ");
-          text.append(computeTypeText(implementsTypes[i], false)).append(" ");
+          text.append(getTypeText(implementsTypes[i], typeDefinition, false)).append(" ");
           i++;
         }
       }
@@ -480,7 +479,7 @@ public class GroovyToJavaGenerator {
           text.append(" extends ");
           for (int j = 0; j < extendsListTypes.length; j++) {
             if (j > 0) text.append(" & ");
-            text.append(computeTypeText(extendsListTypes[j], false));
+            text.append(getTypeText(extendsListTypes[j], typeParameterListOwner, false));
           }
         }
       }
@@ -518,7 +517,7 @@ public class GroovyToJavaGenerator {
     final PsiParameter[] superParams = constructor.getParameterList().getParameters();
     for (int j = 0; j < superParams.length; j++) {
       if (j > 0) text.append(", ");
-      String typeText = getTypeText(substitutor.substitute(superParams[j].getType()), false);
+      String typeText = getTypeText(substitutor.substitute(superParams[j].getType()), null, false);
       text.append("(").append(typeText).append(")").append(getDefaultValueText(typeText));
     }
   }
@@ -595,7 +594,7 @@ public class GroovyToJavaGenerator {
     assert chainedConstructor != null;
 
     for (PsiClassType type : chainedConstructor.getThrowsList().getReferencedTypes()) {
-      result.add(getTypeText(substitutor.substitute(type), false));
+      result.add(getTypeText(substitutor.substitute(type), null, false));
     }
 
     if (chainedConstructor instanceof GrConstructor) {
@@ -680,7 +679,7 @@ public class GroovyToJavaGenerator {
     PsiType retType = method.getReturnType();
     if (retType == null) retType = TypesUtil.getJavaLangObject(method);
 
-    text.append(getTypeText(retType, false));
+    text.append(getTypeText(retType, method, false));
     text.append(" ");
 
     //append method name
@@ -698,7 +697,7 @@ public class GroovyToJavaGenerator {
 
       if (i > 0) text.append(", ");  //append ','
 
-      text.append(getTypeText(parameter.getType(), i == parameters.length - 1));
+      text.append(getTypeText(parameter.getType(), parameter, i == parameters.length - 1));
       text.append(" ");
       text.append(parameter.getName());
 
@@ -712,7 +711,7 @@ public class GroovyToJavaGenerator {
       text.append("{\n");
       text.append("    return ");
 
-      text.append(getDefaultValueText(getTypeText(retType, false)));
+      text.append(getDefaultValueText(getTypeText(retType, method, false)));
 
       text.append(";");
 
@@ -769,21 +768,26 @@ public class GroovyToJavaGenerator {
   }
 
   private static String getTypeText(GrTypeElement typeElement) {
-    return getTypeText(typeElement == null ? null : typeElement.getType(), false);
+    if (typeElement == null) {
+      return CommonClassNames.JAVA_LANG_OBJECT;
+    }
+
+    return getTypeText(typeElement.getType(), typeElement, false);
   }
 
-  private static String getTypeText(PsiType type, boolean allowVarargs) {
-    if (type == null) {
-      return "java.lang.Object";
-    } else {
-      return computeTypeText(type, allowVarargs);
+  private static String getTypeText(PsiType type, @Nullable PsiElement context, boolean allowVarargs) {
+    if (context != null && type instanceof PsiClassType) {
+      final String accessible = findAccessibleSuperClass(context, ((PsiClassType)type).resolve());
+      if (accessible != null) {
+        return accessible;
+      }
     }
-  }
 
-  private static String computeTypeText(PsiType type, boolean allowVarargs) {
     if (type instanceof PsiArrayType) {
-      String componentText = computeTypeText(((PsiArrayType) type).getComponentType(), false);
-      if (allowVarargs && type instanceof PsiEllipsisType) return componentText + "...";
+      String componentText = getTypeText(((PsiArrayType)type).getComponentType(), context, false);
+      if (allowVarargs && type instanceof PsiEllipsisType) {
+        return componentText + "...";
+      }
       return componentText + "[]";
     }
 
@@ -791,20 +795,38 @@ public class GroovyToJavaGenerator {
     return canonicalText != null ? canonicalText : type.getPresentableText();
   }
 
+  @Nullable
+  private static String findAccessibleSuperClass(PsiElement context, @Nullable PsiClass initialClass) {
+    if (initialClass == null) {
+      return null;
+    }
+
+    PsiClass curClass = initialClass;
+    final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(context.getProject()).getResolveHelper();
+    while (curClass != null && !resolveHelper.isAccessible(curClass, context, null)) {
+      curClass = curClass.getSuperClass();
+    }
+    if (curClass != null && !initialClass.isEquivalentTo(curClass)) {
+      final String qname = curClass.getQualifiedName();
+      if (qname != null) {
+        return qname;
+      }
+    }
+    return null;
+  }
+
   CharTrie myTrie = new CharTrie();
 
   public class GenerationItem {
     ValidityState myState;
-    private final boolean myInTestSources;
     final Module myModule;
     public int myHashCode;
     private final VirtualFile myVFile;
 
-    public GenerationItem(String path, Module module, ValidityState state, boolean isInTestSources, VirtualFile vFile) {
+    public GenerationItem(String path, Module module, ValidityState state, VirtualFile vFile) {
       myVFile = vFile;
       myModule = module;
       myState = state;
-      myInTestSources = isInTestSources;
       myHashCode = myTrie.getHashCode(path);
     }
 
index 0a2b63a25f6a027566cf77f0cad2dc92ea154a41..b5848346b7428a6e42cfaedc7db242f8f7a8bdcd 100644 (file)
@@ -69,6 +69,12 @@ public void testArrayType1() throws Throwable { doTest(); }
     doTest();
   }
 
+  public void testInaccessiblePropertyType() throws Throwable {
+    myFixture.addClass("package foo;" +
+                       "class Hidden {}");
+    doTest();
+  }
+
   public void testImmutableAnno() throws Throwable {
     myFixture.addClass("package groovy.lang; public @interface Immutable {}");
     doTest();
diff --git a/plugins/groovy/testdata/groovy/stubGenerator/inaccessiblePropertyType.test b/plugins/groovy/testdata/groovy/stubGenerator/inaccessiblePropertyType.test
new file mode 100644 (file)
index 0000000..8b6c798
--- /dev/null
@@ -0,0 +1,37 @@
+class Foo {
+  foo.Hidden prop
+}
+
+-----
+public class Foo implements groovy.lang.GroovyObject {
+  public java.lang.Object getProp() {
+    return null;
+  }
+
+  public void setProp(java.lang.Object prop) {
+    return ;
+  }
+
+  public groovy.lang.MetaClass getMetaClass() {
+    return null;
+  }
+
+  public void setMetaClass(groovy.lang.MetaClass mc) {
+    return ;
+  }
+
+  public java.lang.Object invokeMethod(java.lang.String name, java.lang.Object args) {
+    return null;
+  }
+
+  public java.lang.Object getProperty(java.lang.String propertyName) {
+    return null;
+  }
+
+  public void setProperty(java.lang.String propertyName, java.lang.Object newValue) {
+    return ;
+  }
+
+  private java.lang.Object prop = null;
+}
+---
\ No newline at end of file