mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
[groovy] support @BaseScript on package definition and import statements (IDEA-135602)
GitOrigin-RevId: 00ae8b515abd00032cef680fa012faaecfcbb138
This commit is contained in:
committed by
intellij-monorepo-bot
parent
91f264fe2c
commit
bedad949e5
+29
-19
@@ -1,32 +1,19 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.
|
||||
*/
|
||||
// Copyright 2000-2019 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.annotator.checkers;
|
||||
|
||||
import com.intellij.lang.annotation.AnnotationHolder;
|
||||
import com.intellij.psi.CommonClassNames;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.GroovyBundle;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.packaging.GrPackageDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrAnnotationUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
|
||||
|
||||
public class BaseScriptAnnotationChecker extends CustomAnnotationChecker {
|
||||
@@ -50,8 +37,31 @@ public class BaseScriptAnnotationChecker extends CustomAnnotationChecker {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (pparent instanceof GrPackageDefinition || pparent instanceof GrImportStatement) {
|
||||
PsiClass clazz = GrAnnotationUtil.inferClassAttribute(annotation, "value");
|
||||
if (!InheritanceUtil.isInheritor(clazz, GroovyCommonClassNames.GROOVY_LANG_SCRIPT)) {
|
||||
String typeText = getTypeText(clazz);
|
||||
holder.createErrorAnnotation(annotation, GroovyBundle.message("declared.type.0.have.to.extend.script", typeText));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getTypeText(@Nullable PsiClass clazz) {
|
||||
if (clazz == null) {
|
||||
return CommonClassNames.JAVA_LANG_OBJECT;
|
||||
}
|
||||
String fqn = clazz.getQualifiedName();
|
||||
if (fqn != null) {
|
||||
return fqn;
|
||||
}
|
||||
String name = clazz.getName();
|
||||
if (name != null) {
|
||||
return name;
|
||||
}
|
||||
return CommonClassNames.JAVA_LANG_OBJECT;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
// 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.
|
||||
// Copyright 2000-2019 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.lang.psi.impl;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
@@ -67,7 +67,7 @@ public class GrAnnotationUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiClass getPsiClass(@Nullable PsiAnnotationMemberValue targetValue) {
|
||||
public static PsiClass getPsiClass(@Nullable PsiAnnotationMemberValue targetValue) {
|
||||
if (targetValue instanceof PsiClassObjectAccessExpression) {
|
||||
PsiType type = ((PsiClassObjectAccessExpression)targetValue).getOperand().getType();
|
||||
if (type instanceof PsiClassType) {
|
||||
|
||||
+74
-12
@@ -1,10 +1,7 @@
|
||||
// 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.
|
||||
// Copyright 2000-2019 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.transformations.impl;
|
||||
|
||||
import com.intellij.psi.PsiArrayType;
|
||||
import com.intellij.psi.PsiClassType;
|
||||
import com.intellij.psi.PsiModifier;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.light.LightMethodBuilder;
|
||||
import com.intellij.psi.util.CachedValueProvider;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
@@ -13,8 +10,12 @@ 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.api.auxiliary.modifiers.GrModifierList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.packaging.GrPackageDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrAnnotationUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
|
||||
@@ -22,6 +23,8 @@ import org.jetbrains.plugins.groovy.transformations.AstTransformationSupport;
|
||||
import org.jetbrains.plugins.groovy.transformations.TransformationContext;
|
||||
|
||||
import static com.intellij.psi.impl.cache.impl.id.IdIndex.hasIdentifierInFile;
|
||||
import static org.jetbrains.plugins.groovy.lang.psi.impl.GrAnnotationUtilKt.findDeclaredDetachedValue;
|
||||
import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames.GROOVY_TRANSFORM_BASE_SCRIPT;
|
||||
|
||||
public class BaseScriptTransformationSupport implements AstTransformationSupport {
|
||||
|
||||
@@ -47,7 +50,9 @@ public class BaseScriptTransformationSupport implements AstTransformationSupport
|
||||
|
||||
@NotNull
|
||||
private static PsiClassType getBaseClassType(@NotNull GroovyScriptClass scriptClass) {
|
||||
PsiClassType type = getSuperClassTypeFromBaseScriptAnnotatedVariable(scriptClass);
|
||||
PsiClassType type = CachedValuesManager.getCachedValue(scriptClass, () -> CachedValueProvider.Result.create(
|
||||
getSuperClassTypeFromBaseScriptAnnotation(scriptClass), scriptClass.getContainingFile()
|
||||
));
|
||||
if (type != null) return type;
|
||||
|
||||
final PsiClassType superClassFromDSL = GroovyDslFileIndex.processScriptSuperClasses(scriptClass.getContainingFile());
|
||||
@@ -57,13 +62,70 @@ public class BaseScriptTransformationSupport implements AstTransformationSupport
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiClassType getSuperClassTypeFromBaseScriptAnnotatedVariable(GroovyScriptClass scriptClass) {
|
||||
return CachedValuesManager.getCachedValue(scriptClass, () -> CachedValueProvider.Result.create(
|
||||
doGetSuperClassType(scriptClass), scriptClass.getContainingFile()
|
||||
));
|
||||
private static PsiClassType getSuperClassTypeFromBaseScriptAnnotation(@NotNull GroovyScriptClass scriptClass) {
|
||||
//Groovy BaseScriptASTTransformation works exactly with this priorities
|
||||
PsiClassType fromVariable = getSuperClassTypeFromBaseScriptAnnotatedVariable(scriptClass);
|
||||
if (fromVariable != null) {
|
||||
return fromVariable;
|
||||
}
|
||||
|
||||
PsiClassType fromImport = getSuperClassTypeFromBaseScriptAnnotatedImportDefinition(scriptClass);
|
||||
if (fromImport != null) {
|
||||
return fromImport;
|
||||
}
|
||||
|
||||
return getSuperClassTypeFromBaseScriptAnnotatedPackageDefinition(scriptClass);
|
||||
}
|
||||
|
||||
private static PsiClassType doGetSuperClassType(GroovyScriptClass scriptClass) {
|
||||
@Nullable
|
||||
private static PsiClassType getSuperClassTypeFromBaseScriptAnnotatedImportDefinition(@NotNull GroovyScriptClass scriptClass) {
|
||||
GrImportStatement[] importStatements = scriptClass.getContainingFile().getImportStatements();
|
||||
for (GrImportStatement importStatement : importStatements) {
|
||||
GrModifierList annotations = importStatement.getAnnotationList();
|
||||
PsiAnnotation baseScriptAnnotation = annotations.findAnnotation(GROOVY_TRANSFORM_BASE_SCRIPT);
|
||||
if (baseScriptAnnotation == null) {
|
||||
continue;
|
||||
}
|
||||
PsiClassType superClassType = getSuperClassTypeFromAnnotationValue(scriptClass, baseScriptAnnotation);
|
||||
if (superClassType != null) {
|
||||
return superClassType;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiClassType getSuperClassTypeFromBaseScriptAnnotatedPackageDefinition(@NotNull GroovyScriptClass scriptClass) {
|
||||
GrPackageDefinition packageDefinition = scriptClass.getContainingFile().getPackageDefinition();
|
||||
if (packageDefinition == null) {
|
||||
return null;
|
||||
}
|
||||
PsiModifierList modifierList = packageDefinition.getModifierList();
|
||||
if (modifierList == null) {
|
||||
return null;
|
||||
}
|
||||
PsiAnnotation baseScriptAnnotation = modifierList.findAnnotation(GROOVY_TRANSFORM_BASE_SCRIPT);
|
||||
if (baseScriptAnnotation == null) {
|
||||
return null;
|
||||
}
|
||||
return getSuperClassTypeFromAnnotationValue(scriptClass, baseScriptAnnotation);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiClassType getSuperClassTypeFromAnnotationValue(GroovyScriptClass scriptClass, PsiAnnotation baseScriptAnnotation) {
|
||||
PsiClass clazz = GrAnnotationUtil.getPsiClass(findDeclaredDetachedValue(baseScriptAnnotation, "value"));
|
||||
if (clazz != null) {
|
||||
String className = clazz.getQualifiedName();
|
||||
if (className == null) clazz.getName();
|
||||
if (className != null) {
|
||||
return TypesUtil.createTypeByFQClassName(className, scriptClass);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiClassType getSuperClassTypeFromBaseScriptAnnotatedVariable(GroovyScriptClass scriptClass) {
|
||||
GrVariableDeclaration declaration = findDeclaration(scriptClass.getContainingFile());
|
||||
if (declaration != null) {
|
||||
GrTypeElement typeElement = declaration.getTypeElementGroovy();
|
||||
@@ -83,7 +145,7 @@ public class BaseScriptTransformationSupport implements AstTransformationSupport
|
||||
return null;
|
||||
}
|
||||
for (GrVariableDeclaration declaration : file.getScriptDeclarations(false)) {
|
||||
if (declaration.getModifierList().hasAnnotation(GroovyCommonClassNames.GROOVY_TRANSFORM_BASE_SCRIPT)) {
|
||||
if (declaration.getModifierList().hasAnnotation(GROOVY_TRANSFORM_BASE_SCRIPT)) {
|
||||
return declaration;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user