Support Class<?> as annotation arguments in java
This commit is contained in:
@@ -131,6 +131,7 @@ public class InjectorForJavaDescriptorResolver {
|
||||
|
||||
javaAnnotationArgumentResolver.setAnnotationResolver(javaAnnotationResolver);
|
||||
javaAnnotationArgumentResolver.setClassResolver(javaClassResolver);
|
||||
javaAnnotationArgumentResolver.setTypeTransformer(javaTypeTransformer);
|
||||
|
||||
javaClassResolver.setAnnotationResolver(javaAnnotationResolver);
|
||||
javaClassResolver.setCache(traceBasedJavaResolverCache);
|
||||
|
||||
+6
-5
@@ -59,12 +59,12 @@ import org.jetbrains.jet.lang.resolve.ScriptBodyResolver;
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.JavaClassResolver;
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationResolver;
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationArgumentResolver;
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.JavaTypeTransformer;
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.DeserializedDescriptorResolver;
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.AnnotationDescriptorDeserializer;
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.JavaNamespaceResolver;
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.JavaMemberResolver;
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.JavaConstructorResolver;
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.JavaTypeTransformer;
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.JavaValueParameterResolver;
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.JavaFunctionResolver;
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.JavaTypeParameterResolver;
|
||||
@@ -119,12 +119,12 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
|
||||
private final JavaClassResolver javaClassResolver;
|
||||
private final JavaAnnotationResolver javaAnnotationResolver;
|
||||
private final JavaAnnotationArgumentResolver javaAnnotationArgumentResolver;
|
||||
private final JavaTypeTransformer javaTypeTransformer;
|
||||
private final DeserializedDescriptorResolver deserializedDescriptorResolver;
|
||||
private final AnnotationDescriptorDeserializer annotationDescriptorDeserializer;
|
||||
private final JavaNamespaceResolver javaNamespaceResolver;
|
||||
private final JavaMemberResolver javaMemberResolver;
|
||||
private final JavaConstructorResolver javaConstructorResolver;
|
||||
private final JavaTypeTransformer javaTypeTransformer;
|
||||
private final JavaValueParameterResolver javaValueParameterResolver;
|
||||
private final JavaFunctionResolver javaFunctionResolver;
|
||||
private final JavaTypeParameterResolver javaTypeParameterResolver;
|
||||
@@ -180,12 +180,12 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
|
||||
this.javaClassResolver = new JavaClassResolver();
|
||||
this.javaAnnotationResolver = new JavaAnnotationResolver();
|
||||
this.javaAnnotationArgumentResolver = new JavaAnnotationArgumentResolver();
|
||||
this.javaTypeTransformer = new JavaTypeTransformer();
|
||||
this.deserializedDescriptorResolver = new DeserializedDescriptorResolver();
|
||||
this.annotationDescriptorDeserializer = new AnnotationDescriptorDeserializer();
|
||||
this.javaNamespaceResolver = new JavaNamespaceResolver();
|
||||
this.javaMemberResolver = new JavaMemberResolver();
|
||||
this.javaConstructorResolver = new JavaConstructorResolver();
|
||||
this.javaTypeTransformer = new JavaTypeTransformer();
|
||||
this.javaValueParameterResolver = new JavaValueParameterResolver();
|
||||
this.javaFunctionResolver = new JavaFunctionResolver();
|
||||
this.javaTypeParameterResolver = new JavaTypeParameterResolver();
|
||||
@@ -333,6 +333,9 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
|
||||
|
||||
javaAnnotationArgumentResolver.setAnnotationResolver(javaAnnotationResolver);
|
||||
javaAnnotationArgumentResolver.setClassResolver(javaClassResolver);
|
||||
javaAnnotationArgumentResolver.setTypeTransformer(javaTypeTransformer);
|
||||
|
||||
javaTypeTransformer.setClassResolver(javaClassResolver);
|
||||
|
||||
deserializedDescriptorResolver.setAnnotationDeserializer(annotationDescriptorDeserializer);
|
||||
deserializedDescriptorResolver.setErrorReporter(traceBasedErrorReporter);
|
||||
@@ -359,8 +362,6 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
|
||||
javaConstructorResolver.setTypeTransformer(javaTypeTransformer);
|
||||
javaConstructorResolver.setValueParameterResolver(javaValueParameterResolver);
|
||||
|
||||
javaTypeTransformer.setClassResolver(javaClassResolver);
|
||||
|
||||
javaValueParameterResolver.setAnnotationResolver(javaAnnotationResolver);
|
||||
javaValueParameterResolver.setTypeTransformer(javaTypeTransformer);
|
||||
|
||||
|
||||
+3
@@ -47,6 +47,9 @@ public abstract class JavaAnnotationArgumentImpl<Psi extends PsiAnnotationMember
|
||||
else if (argument instanceof PsiAnnotation) {
|
||||
return new JavaAnnotationAsAnnotationArgumentImpl((PsiAnnotation) argument, name);
|
||||
}
|
||||
else if (argument instanceof PsiClassObjectAccessExpression) {
|
||||
return new JavaClassObjectAnnotationArgumentImpl((PsiClassObjectAccessExpression) argument, name);
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("Unsupported annotation argument type: " + argument);
|
||||
}
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2010-2013 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.jet.lang.resolve.java.structure.impl;
|
||||
|
||||
import com.intellij.psi.PsiClassObjectAccessExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaClassObjectAnnotationArgument;
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaType;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
|
||||
public class JavaClassObjectAnnotationArgumentImpl extends JavaAnnotationArgumentImpl<PsiClassObjectAccessExpression>
|
||||
implements JavaClassObjectAnnotationArgument {
|
||||
public JavaClassObjectAnnotationArgumentImpl(@NotNull PsiClassObjectAccessExpression expression, @Nullable Name name) {
|
||||
super(expression, name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JavaType getReferencedType() {
|
||||
return JavaTypeImpl.create(getPsi().getOperand().getType());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package test;
|
||||
|
||||
public class ClassObjectArrayInParam {
|
||||
public @interface Anno {
|
||||
Class<?>[] value();
|
||||
}
|
||||
|
||||
@Anno({ClassObjectArrayInParam.class, Nested.class, String.class})
|
||||
public static class Nested {}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package test
|
||||
|
||||
public open class ClassObjectArrayInParam : java.lang.Object {
|
||||
public constructor ClassObjectArrayInParam()
|
||||
|
||||
public final annotation class Anno : jet.Annotation {
|
||||
public constructor Anno(/*0*/ vararg value: java.lang.Class<out jet.Any?>? /*jet.Array<java.lang.Class<out jet.Any?>>?*/)
|
||||
public abstract fun value(): jet.Array<java.lang.Class<out jet.Any?>>?
|
||||
}
|
||||
|
||||
test.ClassObjectArrayInParam.Anno(value = [ClassObjectArrayInParam?.class, Nested?.class, String?.class]: jet.Array<java.lang.Class<out jet.Any?>>?) public open class Nested : java.lang.Object {
|
||||
public constructor Nested()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package test;
|
||||
|
||||
public class ClassObjectInParam {
|
||||
public @interface Anno {
|
||||
Class<?> value();
|
||||
}
|
||||
|
||||
@Anno(ClassObjectInParam.class)
|
||||
public static class Nested {}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package test
|
||||
|
||||
public open class ClassObjectInParam : java.lang.Object {
|
||||
public constructor ClassObjectInParam()
|
||||
|
||||
public final annotation class Anno : jet.Annotation {
|
||||
public constructor Anno(/*0*/ value: java.lang.Class<out jet.Any?>?)
|
||||
public abstract fun value(): java.lang.Class<out jet.Any?>?
|
||||
}
|
||||
|
||||
test.ClassObjectInParam.Anno(value = ClassObjectInParam?.class: java.lang.Class<test.ClassObjectInParam?>) public open class Nested : java.lang.Object {
|
||||
public constructor Nested()
|
||||
}
|
||||
}
|
||||
@@ -3,13 +3,13 @@ package test
|
||||
public trait ErrorTypes : java.lang.Object {
|
||||
|
||||
public trait Sub : test.ErrorTypes.Super {
|
||||
public abstract fun errorTypeInParameter(/*0*/ list: jet.List<jet.Array<[ERROR : Unresolved java class: T]>?>?): jet.Unit
|
||||
public abstract override /*1*/ /*fake_override*/ fun errorTypeInParameter(/*0*/ list: jet.List<jet.Array<[ERROR : Unresolved java class: T]>?>?): jet.Unit
|
||||
public abstract override /*1*/ fun returnErrorType(): [ERROR : Unresolved java class: T]
|
||||
public abstract fun errorTypeInParameter(/*0*/ list: jet.List<jet.Array<[ERROR : Unresolved java classifier: T]>?>?): jet.Unit
|
||||
public abstract override /*1*/ /*fake_override*/ fun errorTypeInParameter(/*0*/ list: jet.List<jet.Array<[ERROR : Unresolved java classifier: T]>?>?): jet.Unit
|
||||
public abstract override /*1*/ fun returnErrorType(): [ERROR : Unresolved java classifier: T]
|
||||
}
|
||||
|
||||
public trait Super : java.lang.Object {
|
||||
public abstract fun errorTypeInParameter(/*0*/ list: jet.List<jet.Array<[ERROR : Unresolved java class: T]>?>?): jet.Unit
|
||||
public abstract fun returnErrorType(): [ERROR : Unresolved java class: T]
|
||||
public abstract fun errorTypeInParameter(/*0*/ list: jet.List<jet.Array<[ERROR : Unresolved java classifier: T]>?>?): jet.Unit
|
||||
public abstract fun returnErrorType(): [ERROR : Unresolved java classifier: T]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1080,6 +1080,16 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
|
||||
doTestCompiledJava("compiler/testData/loadJava/compiledJava/annotations/ArrayOfStringInParam.java");
|
||||
}
|
||||
|
||||
@TestMetadata("ClassObjectArrayInParam.java")
|
||||
public void testClassObjectArrayInParam() throws Exception {
|
||||
doTestCompiledJava("compiler/testData/loadJava/compiledJava/annotations/ClassObjectArrayInParam.java");
|
||||
}
|
||||
|
||||
@TestMetadata("ClassObjectInParam.java")
|
||||
public void testClassObjectInParam() throws Exception {
|
||||
doTestCompiledJava("compiler/testData/loadJava/compiledJava/annotations/ClassObjectInParam.java");
|
||||
}
|
||||
|
||||
@TestMetadata("CustomAnnotation.java")
|
||||
public void testCustomAnnotation() throws Exception {
|
||||
doTestCompiledJava("compiler/testData/loadJava/compiledJava/annotations/CustomAnnotation.java");
|
||||
|
||||
+1
-1
@@ -168,7 +168,7 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer
|
||||
annotation.setAnnotationType(annotationClass.getDefaultType());
|
||||
|
||||
return new AnnotationVisitor(Opcodes.ASM4) {
|
||||
// TODO: arrays, annotations
|
||||
// TODO: arrays, annotations, java.lang.Class
|
||||
@Override
|
||||
public void visit(String name, Object value) {
|
||||
CompileTimeConstant<?> argument = JavaAnnotationArgumentResolver.resolveCompileTimeConstantValue(value, null);
|
||||
|
||||
+35
@@ -29,19 +29,26 @@ import org.jetbrains.jet.lang.resolve.java.structure.*;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.JetTypeImpl;
|
||||
import org.jetbrains.jet.lang.types.TypeProjection;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getEnumEntriesScope;
|
||||
import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.IGNORE_KOTLIN_SOURCES;
|
||||
import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.INCLUDE_KOTLIN_SOURCES;
|
||||
|
||||
public final class JavaAnnotationArgumentResolver {
|
||||
public static final FqName JL_CLASS_FQ_NAME = new FqName("java.lang.Class");
|
||||
|
||||
private JavaAnnotationResolver annotationResolver;
|
||||
private JavaClassResolver classResolver;
|
||||
private JavaTypeTransformer typeTransformer;
|
||||
|
||||
@Inject
|
||||
public void setAnnotationResolver(JavaAnnotationResolver annotationResolver) {
|
||||
@@ -53,6 +60,11 @@ public final class JavaAnnotationArgumentResolver {
|
||||
this.classResolver = classResolver;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setTypeTransformer(JavaTypeTransformer typeTransformer) {
|
||||
this.typeTransformer = typeTransformer;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CompileTimeConstant<?> resolveAnnotationArgument(
|
||||
@NotNull FqName annotationFqName,
|
||||
@@ -80,6 +92,10 @@ public final class JavaAnnotationArgumentResolver {
|
||||
else if (argument instanceof JavaAnnotationAsAnnotationArgument) {
|
||||
return resolveFromAnnotation(((JavaAnnotationAsAnnotationArgument) argument).getAnnotation(), postponedTasks);
|
||||
}
|
||||
// Class<?>
|
||||
else if (argument instanceof JavaClassObjectAnnotationArgument) {
|
||||
return resolveFromJavaClassObjectType(((JavaClassObjectAnnotationArgument) argument).getReferencedType());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -135,6 +151,25 @@ public final class JavaAnnotationArgumentResolver {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private CompileTimeConstant<?> resolveFromJavaClassObjectType(@NotNull JavaType javaType) {
|
||||
JetType type = typeTransformer.transformToType(javaType, TypeVariableResolver.EMPTY);
|
||||
|
||||
ClassDescriptor jlClass = classResolver.resolveClass(JL_CLASS_FQ_NAME, IGNORE_KOTLIN_SOURCES);
|
||||
if (jlClass == null) return null;
|
||||
|
||||
List<TypeProjection> arguments = Collections.singletonList(new TypeProjection(type));
|
||||
JetTypeImpl javaClassType = new JetTypeImpl(
|
||||
jlClass.getAnnotations(),
|
||||
jlClass.getTypeConstructor(),
|
||||
false,
|
||||
arguments,
|
||||
jlClass.getMemberScope(arguments)
|
||||
);
|
||||
|
||||
return new JavaClassValue(javaClassType);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static CompileTimeConstant<?> resolveCompileTimeConstantValue(@Nullable Object value, @Nullable JetType expectedType) {
|
||||
if (value instanceof String) {
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2010-2013 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.jet.lang.resolve.java.structure;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface JavaClassObjectAnnotationArgument extends JavaAnnotationArgument {
|
||||
@NotNull
|
||||
JavaType getReferencedType();
|
||||
}
|
||||
Reference in New Issue
Block a user