[groovy] @BaseScript support: use stubs
authorDaniil Ovchinnikov <daniil.ovchinnikov@jetbrains.com>
Tue, 1 Nov 2016 16:32:45 +0000 (19:32 +0300)
committerDaniil Ovchinnikov <daniil.ovchinnikov@jetbrains.com>
Tue, 1 Nov 2016 16:35:04 +0000 (19:35 +0300)
plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/impl/BaseScriptTransformationSupport.java
plugins/groovy/test/org/jetbrains/plugins/groovy/transformations/BaseScriptTransformationSupportTest.groovy [new file with mode: 0644]

index a449d988b6b94eb0831d0cf3b13887697ca98507..189e1f213a38194defe70373ec0ec19c1569eb19 100644 (file)
@@ -15,7 +15,6 @@
  */
 package org.jetbrains.plugins.groovy.transformations.impl;
 
-import com.intellij.openapi.util.Ref;
 import com.intellij.psi.PsiArrayType;
 import com.intellij.psi.PsiClassType;
 import com.intellij.psi.PsiModifier;
@@ -28,9 +27,6 @@ import org.jetbrains.annotations.Nullable;
 import org.jetbrains.plugins.groovy.GroovyLanguage;
 import org.jetbrains.plugins.groovy.dsl.GroovyDslFileIndex;
 import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
-import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
-import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
-import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList;
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration;
 import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
 import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
@@ -84,16 +80,11 @@ public class BaseScriptTransformationSupport implements AstTransformationSupport
   private static PsiClassType doGetSuperClassType(GroovyScriptClass scriptClass) {
     GrVariableDeclaration declaration = findDeclaration(scriptClass.getContainingFile());
     if (declaration != null) {
-
-
-      GrModifierList modifierList = declaration.getModifierList();
-      if (modifierList.findAnnotation(GroovyCommonClassNames.GROOVY_TRANSFORM_BASE_SCRIPT) != null) {
-        GrTypeElement typeElement = declaration.getTypeElementGroovy();
-        if (typeElement != null) {
-          PsiType type = typeElement.getType();
-          if (type instanceof PsiClassType) {
-            return (PsiClassType)type;
-          }
+      GrTypeElement typeElement = declaration.getTypeElementGroovy();
+      if (typeElement != null) {
+        PsiType type = typeElement.getType();
+        if (type instanceof PsiClassType) {
+          return (PsiClassType)type;
         }
       }
     }
@@ -105,24 +96,11 @@ public class BaseScriptTransformationSupport implements AstTransformationSupport
     if (!hasNameInFile(file, "BaseScript")) {
       return null;
     }
-    final Ref<GrVariableDeclaration> ref = Ref.create();
-    file.accept(new GroovyRecursiveElementVisitor() {
-      @Override
-      public void visitVariableDeclaration(@NotNull GrVariableDeclaration variableDeclaration) {
-        super.visitVariableDeclaration(variableDeclaration);
-        if (variableDeclaration.getModifierList().findAnnotation(GroovyCommonClassNames.GROOVY_TRANSFORM_BASE_SCRIPT) != null) {
-          ref.set(variableDeclaration);
-        }
+    for (GrVariableDeclaration declaration : file.getScriptDeclarations(false)) {
+      if (declaration.getModifierList().findAnnotation(GroovyCommonClassNames.GROOVY_TRANSFORM_BASE_SCRIPT) != null) {
+        return declaration;
       }
-
-      @Override
-      public void visitElement(@NotNull GroovyPsiElement element) {
-        if (ref.isNull()) {
-          super.visitElement(element);
-        }
-      }
-    });
-
-    return ref.get();
+    }
+    return null;
   }
 }
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/transformations/BaseScriptTransformationSupportTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/transformations/BaseScriptTransformationSupportTest.groovy
new file mode 100644 (file)
index 0000000..4e2f57a
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2000-2016 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.transformations
+
+import com.intellij.psi.PsiClass
+import com.intellij.psi.util.InheritanceUtil
+import com.intellij.testFramework.LightProjectDescriptor
+import groovy.transform.CompileStatic
+import org.jetbrains.plugins.groovy.GroovyLightProjectDescriptor
+import org.jetbrains.plugins.groovy.LightGroovyTestCase
+import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyFileImpl
+import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass
+
+@CompileStatic
+class BaseScriptTransformationSupportTest extends LightGroovyTestCase {
+
+  LightProjectDescriptor projectDescriptor = GroovyLightProjectDescriptor.GROOVY_LATEST
+
+  @Override
+  void setUp() throws Exception {
+    super.setUp()
+    fixture.addFileToProject 'base.groovy', 'abstract class MyBaseScript extends Script {}'
+  }
+
+  private void doTest(String text) {
+    def file = fixture.addFileToProject('Zzz.groovy', """\
+import groovy.transform.BaseScript
+
+$text
+""") as GroovyFileImpl
+    def clazz = fixture.findClass('Zzz')
+    assert clazz instanceof GroovyScriptClass
+    assert InheritanceUtil.isInheritor(clazz as PsiClass, 'MyBaseScript')
+    assert !file.contentsLoaded
+  }
+
+  void 'test top level'() {
+    doTest '@BaseScript MyBaseScript hello'
+  }
+
+  void 'test script block level'() {
+    doTest 'if (true) @BaseScript MyBaseScript hello'
+  }
+
+  void 'test within method'() {
+    doTest '''\
+def foo() {
+  @BaseScript MyBaseScript hello  
+}
+'''
+  }
+}