mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Add "Convert to @CompileStatic" to groovy scripts
This commit is contained in:
+33
-33
@@ -1,6 +1,6 @@
|
||||
// Copyright 2000-2017 JetBrains s.r.o.
|
||||
// Use of this source code is governed by the Apache 2.0 license that can be
|
||||
// found in the LICENSE file.
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.refactoring.convertToStatic;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -15,9 +15,11 @@ import com.intellij.refactoring.ui.UsageViewDescriptorAdapter;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.usageView.UsageViewDescriptor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.annotator.VisitorCallback;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementVisitor;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
@@ -77,7 +79,6 @@ public class ConvertToStaticProcessor extends BaseRefactoringProcessor {
|
||||
for (GroovyFile file : myFiles) {
|
||||
counter++;
|
||||
commitFile(file);
|
||||
if (file.isScript()) continue;
|
||||
progressIndicator.setText2(file.getName());
|
||||
progressIndicator.setFraction(counter / (double)myFiles.length);
|
||||
try {
|
||||
@@ -111,12 +112,6 @@ public class ConvertToStaticProcessor extends BaseRefactoringProcessor {
|
||||
}
|
||||
|
||||
private void putCompileAnnotations(@NotNull GroovyFile file) {
|
||||
GrTypeDefinition[] classes = file.getTypeDefinitions();
|
||||
|
||||
for (GrTypeDefinition typeDef : classes) {
|
||||
addAnnotation(typeDef, true);
|
||||
}
|
||||
|
||||
Set<GrTypeDefinition> classesWithUnresolvedRef = new HashSet<>();
|
||||
Set<GrMethod> methodsWithUnresolvedRef = new HashSet<>();
|
||||
|
||||
@@ -129,18 +124,37 @@ public class ConvertToStaticProcessor extends BaseRefactoringProcessor {
|
||||
GrTypeDefinition containingClass = PsiTreeUtil.getParentOfType(element, GrTypeDefinition.class);
|
||||
if (containingClass != null) classesWithUnresolvedRef.add(containingClass);
|
||||
};
|
||||
|
||||
file.accept(new DynamicFeaturesVisitor(file, myProject, callback));
|
||||
|
||||
|
||||
for (GrTypeDefinition typeDef : classes) {
|
||||
processDefinitions(typeDef, classesWithUnresolvedRef, methodsWithUnresolvedRef, false);
|
||||
file.accept(new GroovyRecursiveElementVisitor() {
|
||||
@Override
|
||||
public void visitTypeDefinition(@NotNull GrTypeDefinition typeDef) {
|
||||
processDefinitions(typeDef, classesWithUnresolvedRef);
|
||||
super.visitTypeDefinition(typeDef);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethod(@NotNull GrMethod method) {
|
||||
processMethods(method, methodsWithUnresolvedRef);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void processMethods(@NotNull GrMethod method, Set<GrMethod> dynamicMethods) {
|
||||
boolean isOuterStatic = PsiUtil.isCompileStatic(method.getContainingClass());
|
||||
boolean isStatic = dynamicMethods.stream().noneMatch(method::isEquivalentTo);
|
||||
|
||||
if (isOuterStatic != isStatic) {
|
||||
addAnnotation(method, isStatic);
|
||||
}
|
||||
}
|
||||
|
||||
private void processDefinitions(GrTypeDefinition typeDef,
|
||||
Set<GrTypeDefinition> dynamicClasses,
|
||||
Set<GrMethod> dynamicMethods,
|
||||
boolean isOuterStatic) {
|
||||
Set<GrTypeDefinition> dynamicClasses) {
|
||||
boolean isOuterStatic = PsiUtil.isCompileStatic(typeDef.getContainingClass());
|
||||
|
||||
boolean isStatic = !dynamicClasses.contains(typeDef);
|
||||
if (isOuterStatic && !isStatic) {
|
||||
addAnnotation(typeDef, false);
|
||||
@@ -148,19 +162,6 @@ public class ConvertToStaticProcessor extends BaseRefactoringProcessor {
|
||||
if (!isOuterStatic && isStatic) {
|
||||
addAnnotation(typeDef, true);
|
||||
}
|
||||
if (!isOuterStatic && !isStatic) {
|
||||
removeAnnotation(typeDef);
|
||||
}
|
||||
|
||||
for (GrMethod method : typeDef.getCodeMethods()) {
|
||||
if (dynamicMethods.stream().anyMatch(method::isEquivalentTo) == isStatic) {
|
||||
addAnnotation(method, !isStatic);
|
||||
}
|
||||
}
|
||||
|
||||
for (GrTypeDefinition definition : typeDef.getCodeInnerClasses()) {
|
||||
processDefinitions(definition, dynamicClasses, dynamicMethods, isStatic);
|
||||
}
|
||||
}
|
||||
|
||||
private static void applyErrorFixes(@NotNull GroovyFile file) {
|
||||
@@ -195,11 +196,10 @@ public class ConvertToStaticProcessor extends BaseRefactoringProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
void removeAnnotation(@NotNull PsiModifierListOwner owner) {
|
||||
@Nullable
|
||||
PsiAnnotation findAnnotation(@Nullable PsiModifierListOwner owner, @NotNull String annotation) {
|
||||
if (owner == null) return null;
|
||||
PsiModifierList modifierList = owner.getModifierList();
|
||||
if (modifierList != null) {
|
||||
PsiAnnotation psiAnnotation = modifierList.findAnnotation(GROOVY_TRANSFORM_COMPILE_STATIC);
|
||||
if (psiAnnotation != null) psiAnnotation.delete();
|
||||
}
|
||||
return modifierList != null ? modifierList.findAnnotation(annotation) : null;
|
||||
}
|
||||
}
|
||||
|
||||
+15
-3
@@ -1,6 +1,6 @@
|
||||
// Copyright 2000-2017 JetBrains s.r.o.
|
||||
// Use of this source code is governed by the Apache 2.0 license that can be
|
||||
// found in the LICENSE file.
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.refactoring.covertToStatic
|
||||
|
||||
import org.jetbrains.plugins.groovy.LightGroovyTestCase
|
||||
@@ -37,4 +37,16 @@ class ConvertTest extends LightGroovyTestCase {
|
||||
void testMultiAssignment() {
|
||||
doTest()
|
||||
}
|
||||
|
||||
void testMarkupPrintScript() {
|
||||
doTest()
|
||||
}
|
||||
|
||||
void testCompileDynamicClass() {
|
||||
doTest()
|
||||
}
|
||||
|
||||
void testNestedClasses() {
|
||||
doTest()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class Foo {
|
||||
private field1 = ""
|
||||
private field1 = bar1()
|
||||
|
||||
static def bar1() {
|
||||
""
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ import groovy.transform.CompileStatic
|
||||
|
||||
@CompileStatic
|
||||
class Foo {
|
||||
private String field1 = ""
|
||||
private String field1 = bar1()
|
||||
|
||||
static String bar1() {
|
||||
""
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
class Foo {
|
||||
private field1 = new Object().unresolvedMethod()
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
class Foo {
|
||||
private field1 = new Object().unresolvedMethod()
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import groovy.xml.MarkupBuilder
|
||||
|
||||
class DynamicFeaturesExample {
|
||||
final ConfigObject config
|
||||
|
||||
DynamicFeaturesExample(ConfigObject config) {
|
||||
this.config = config
|
||||
}
|
||||
|
||||
def printXML() {
|
||||
new MarkupBuilder().records {
|
||||
persons.each { p ->
|
||||
person {
|
||||
name(p.name)
|
||||
age(p.age)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List getPersons() {
|
||||
config.persons
|
||||
}
|
||||
}
|
||||
|
||||
static def getConfig() {
|
||||
def c = new ConfigObject()
|
||||
c.putAll(persons:[[name:'Alex', age: 30]])
|
||||
return c
|
||||
}
|
||||
|
||||
static def addPerson(ConfigObject o) {
|
||||
o.persons.add([name:"Margaret", age:0])
|
||||
}
|
||||
|
||||
def c = getConfig()
|
||||
addPerson(c)
|
||||
|
||||
new DynamicFeaturesExample(c).printXML()
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
import groovy.transform.CompileDynamic
|
||||
import groovy.transform.CompileStatic
|
||||
import groovy.xml.MarkupBuilder
|
||||
|
||||
@CompileStatic
|
||||
class DynamicFeaturesExample {
|
||||
final ConfigObject config
|
||||
|
||||
DynamicFeaturesExample(ConfigObject config) {
|
||||
this.config = config
|
||||
}
|
||||
|
||||
@CompileDynamic
|
||||
String printXML() {
|
||||
new MarkupBuilder().records {
|
||||
persons.each { p ->
|
||||
person {
|
||||
name(p.name)
|
||||
age(p.age)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@CompileDynamic
|
||||
List getPersons() {
|
||||
config.persons
|
||||
}
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
static ConfigObject getConfig() {
|
||||
def c = new ConfigObject()
|
||||
c.putAll(persons:[[name:'Alex', age: 30]])
|
||||
return c
|
||||
}
|
||||
|
||||
static Object addPerson(ConfigObject o) {
|
||||
o.persons.add([name:"Margaret", age:0])
|
||||
}
|
||||
|
||||
def c = getConfig()
|
||||
addPerson(c)
|
||||
|
||||
new DynamicFeaturesExample(c).printXML()
|
||||
@@ -0,0 +1,15 @@
|
||||
class UpClass {
|
||||
class InClass{
|
||||
def c = UpClass.unresolved
|
||||
|
||||
def method() {
|
||||
new I() {
|
||||
def m() {
|
||||
InClass.unresolved
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface I{}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import groovy.transform.CompileDynamic
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@CompileStatic
|
||||
class UpClass {
|
||||
@CompileDynamic
|
||||
class InClass{
|
||||
def c = UpClass.unresolved
|
||||
|
||||
@CompileStatic
|
||||
def method() {
|
||||
new I() {
|
||||
def m() {
|
||||
InClass.unresolved
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
interface I{}
|
||||
Reference in New Issue
Block a user