diff --git a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaDescriptorResolver.java index 42838337786..55a15e410fa 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaDescriptorResolver.java @@ -111,15 +111,14 @@ public class InjectorForJavaDescriptorResolver { deserializedDescriptorResolver.setContext(deserializationGlobalContextForJava); deserializedDescriptorResolver.setErrorReporter(traceBasedErrorReporter); - annotationDescriptorLoader.setClassResolver(javaDescriptorResolver); annotationDescriptorLoader.setErrorReporter(traceBasedErrorReporter); annotationDescriptorLoader.setKotlinClassFinder(virtualFileFinder); + annotationDescriptorLoader.setModule(module); annotationDescriptorLoader.setStorage(descriptorDeserializersStorage); - descriptorDeserializersStorage.setClassResolver(javaDescriptorResolver); descriptorDeserializersStorage.setErrorReporter(traceBasedErrorReporter); + descriptorDeserializersStorage.setModule(module); - constantDescriptorLoader.setClassResolver(javaDescriptorResolver); constantDescriptorLoader.setErrorReporter(traceBasedErrorReporter); constantDescriptorLoader.setKotlinClassFinder(virtualFileFinder); constantDescriptorLoader.setStorage(descriptorDeserializersStorage); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForLazyResolveWithJava.java b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForLazyResolveWithJava.java index a5ef9a12be3..3992c9a295a 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForLazyResolveWithJava.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForLazyResolveWithJava.java @@ -241,15 +241,14 @@ public class InjectorForLazyResolveWithJava { deserializedDescriptorResolver.setContext(deserializationGlobalContextForJava); deserializedDescriptorResolver.setErrorReporter(traceBasedErrorReporter); - annotationDescriptorLoader.setClassResolver(javaDescriptorResolver); annotationDescriptorLoader.setErrorReporter(traceBasedErrorReporter); annotationDescriptorLoader.setKotlinClassFinder(virtualFileFinder); + annotationDescriptorLoader.setModule(module); annotationDescriptorLoader.setStorage(descriptorDeserializersStorage); - descriptorDeserializersStorage.setClassResolver(javaDescriptorResolver); descriptorDeserializersStorage.setErrorReporter(traceBasedErrorReporter); + descriptorDeserializersStorage.setModule(module); - constantDescriptorLoader.setClassResolver(javaDescriptorResolver); constantDescriptorLoader.setErrorReporter(traceBasedErrorReporter); constantDescriptorLoader.setKotlinClassFinder(virtualFileFinder); constantDescriptorLoader.setStorage(descriptorDeserializersStorage); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java index 776f57ac0d2..5f39318c1b2 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java @@ -321,15 +321,14 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly deserializedDescriptorResolver.setContext(deserializationGlobalContextForJava); deserializedDescriptorResolver.setErrorReporter(traceBasedErrorReporter); - annotationDescriptorLoader.setClassResolver(javaDescriptorResolver); annotationDescriptorLoader.setErrorReporter(traceBasedErrorReporter); annotationDescriptorLoader.setKotlinClassFinder(virtualFileFinder); + annotationDescriptorLoader.setModule(moduleDescriptor); annotationDescriptorLoader.setStorage(descriptorDeserializersStorage); - descriptorDeserializersStorage.setClassResolver(javaDescriptorResolver); descriptorDeserializersStorage.setErrorReporter(traceBasedErrorReporter); + descriptorDeserializersStorage.setModule(moduleDescriptor); - constantDescriptorLoader.setClassResolver(javaDescriptorResolver); constantDescriptorLoader.setErrorReporter(traceBasedErrorReporter); constantDescriptorLoader.setKotlinClassFinder(virtualFileFinder); constantDescriptorLoader.setStorage(descriptorDeserializersStorage); diff --git a/compiler/testData/loadJava/compiledKotlin/annotations/classes/AnnotationInClassObject.kt b/compiler/testData/loadJava/compiledKotlin/annotations/classes/AnnotationInClassObject.kt new file mode 100644 index 00000000000..48dfd626fd4 --- /dev/null +++ b/compiler/testData/loadJava/compiledKotlin/annotations/classes/AnnotationInClassObject.kt @@ -0,0 +1,13 @@ +package test + +class A { + class object { + annotation class Anno1 + + class B { + annotation class Anno2 + } + } +} + +A.Anno1 A.B.Anno2 class C \ No newline at end of file diff --git a/compiler/testData/loadJava/compiledKotlin/annotations/classes/AnnotationInClassObject.txt b/compiler/testData/loadJava/compiledKotlin/annotations/classes/AnnotationInClassObject.txt new file mode 100644 index 00000000000..1340bee69b7 --- /dev/null +++ b/compiler/testData/loadJava/compiledKotlin/annotations/classes/AnnotationInClassObject.txt @@ -0,0 +1,25 @@ +package test + +internal final class A { + /*primary*/ public constructor A() + + internal class object { + /*primary*/ private constructor () + + internal final annotation class Anno1 : kotlin.Annotation { + /*primary*/ public constructor Anno1() + } + + internal final class B { + /*primary*/ public constructor B() + + internal final annotation class Anno2 : kotlin.Annotation { + /*primary*/ public constructor Anno2() + } + } + } +} + +test.A.Anno1() test.A.B.Anno2() internal final class C { + /*primary*/ public constructor C() +} \ No newline at end of file diff --git a/compiler/testData/loadJava/compiledKotlin/annotations/classes/DollarsInAnnotationName.kt b/compiler/testData/loadJava/compiledKotlin/annotations/classes/DollarsInAnnotationName.kt new file mode 100644 index 00000000000..a1208490787 --- /dev/null +++ b/compiler/testData/loadJava/compiledKotlin/annotations/classes/DollarsInAnnotationName.kt @@ -0,0 +1,6 @@ +package test + +//this test relies on particular heuristic implemntation, can become irrelevant should implementation change +annotation class `$$$$$$` + +`$$$$$$`class A \ No newline at end of file diff --git a/compiler/testData/loadJava/compiledKotlin/annotations/classes/DollarsInAnnotationName.txt b/compiler/testData/loadJava/compiledKotlin/annotations/classes/DollarsInAnnotationName.txt new file mode 100644 index 00000000000..5637bedc828 --- /dev/null +++ b/compiler/testData/loadJava/compiledKotlin/annotations/classes/DollarsInAnnotationName.txt @@ -0,0 +1,9 @@ +package test + +internal final annotation class $$$$$$ : kotlin.Annotation { + /*primary*/ public constructor $$$$$$() +} + +test.$$$$$$() internal final class A { + /*primary*/ public constructor A() +} \ No newline at end of file diff --git a/compiler/testData/loadJava/compiledKotlin/annotations/classes/NestedAnnotation.kt b/compiler/testData/loadJava/compiledKotlin/annotations/classes/NestedAnnotation.kt new file mode 100644 index 00000000000..94abc114c8c --- /dev/null +++ b/compiler/testData/loadJava/compiledKotlin/annotations/classes/NestedAnnotation.kt @@ -0,0 +1,9 @@ +package test + +class A { + annotation class Anno +} + +A.Anno class B { + A.Anno fun f() {} +} \ No newline at end of file diff --git a/compiler/testData/loadJava/compiledKotlin/annotations/classes/NestedAnnotation.txt b/compiler/testData/loadJava/compiledKotlin/annotations/classes/NestedAnnotation.txt new file mode 100644 index 00000000000..7be3109a7ac --- /dev/null +++ b/compiler/testData/loadJava/compiledKotlin/annotations/classes/NestedAnnotation.txt @@ -0,0 +1,14 @@ +package test + +internal final class A { + /*primary*/ public constructor A() + + internal final annotation class Anno : kotlin.Annotation { + /*primary*/ public constructor Anno() + } +} + +test.A.Anno() internal final class B { + /*primary*/ public constructor B() + test.A.Anno() internal final fun f(): kotlin.Unit +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java index a28d2b7d79f..1bd1fd17db0 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java @@ -1627,6 +1627,11 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/loadJava/compiledKotlin/annotations/classes"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("AnnotationInClassObject.kt") + public void testAnnotationInClassObject() throws Exception { + doTestCompiledKotlin("compiler/testData/loadJava/compiledKotlin/annotations/classes/AnnotationInClassObject.kt"); + } + @TestMetadata("ClassInClassObject.kt") public void testClassInClassObject() throws Exception { doTestCompiledKotlin("compiler/testData/loadJava/compiledKotlin/annotations/classes/ClassInClassObject.kt"); @@ -1647,6 +1652,11 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest { doTestCompiledKotlin("compiler/testData/loadJava/compiledKotlin/annotations/classes/Deprecated.kt"); } + @TestMetadata("DollarsInAnnotationName.kt") + public void testDollarsInAnnotationName() throws Exception { + doTestCompiledKotlin("compiler/testData/loadJava/compiledKotlin/annotations/classes/DollarsInAnnotationName.kt"); + } + @TestMetadata("EnumArgument.kt") public void testEnumArgument() throws Exception { doTestCompiledKotlin("compiler/testData/loadJava/compiledKotlin/annotations/classes/EnumArgument.kt"); @@ -1657,6 +1667,11 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest { doTestCompiledKotlin("compiler/testData/loadJava/compiledKotlin/annotations/classes/MultipleAnnotations.kt"); } + @TestMetadata("NestedAnnotation.kt") + public void testNestedAnnotation() throws Exception { + doTestCompiledKotlin("compiler/testData/loadJava/compiledKotlin/annotations/classes/NestedAnnotation.kt"); + } + @TestMetadata("NestedClass.kt") public void testNestedClass() throws Exception { doTestCompiledKotlin("compiler/testData/loadJava/compiledKotlin/annotations/classes/NestedClass.kt"); diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveRecursiveComparingTestGenerated.java b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveRecursiveComparingTestGenerated.java index 5ab9d342207..a7c2642e4a9 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveRecursiveComparingTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveRecursiveComparingTestGenerated.java @@ -95,6 +95,11 @@ public class LazyResolveRecursiveComparingTestGenerated extends AbstractLazyReso JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/loadJava/compiledKotlin/annotations/classes"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("AnnotationInClassObject.kt") + public void testAnnotationInClassObject() throws Exception { + doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadJava/compiledKotlin/annotations/classes/AnnotationInClassObject.kt"); + } + @TestMetadata("ClassInClassObject.kt") public void testClassInClassObject() throws Exception { doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadJava/compiledKotlin/annotations/classes/ClassInClassObject.kt"); @@ -115,6 +120,11 @@ public class LazyResolveRecursiveComparingTestGenerated extends AbstractLazyReso doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadJava/compiledKotlin/annotations/classes/Deprecated.kt"); } + @TestMetadata("DollarsInAnnotationName.kt") + public void testDollarsInAnnotationName() throws Exception { + doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadJava/compiledKotlin/annotations/classes/DollarsInAnnotationName.kt"); + } + @TestMetadata("EnumArgument.kt") public void testEnumArgument() throws Exception { doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadJava/compiledKotlin/annotations/classes/EnumArgument.kt"); @@ -125,6 +135,11 @@ public class LazyResolveRecursiveComparingTestGenerated extends AbstractLazyReso doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadJava/compiledKotlin/annotations/classes/MultipleAnnotations.kt"); } + @TestMetadata("NestedAnnotation.kt") + public void testNestedAnnotation() throws Exception { + doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadJava/compiledKotlin/annotations/classes/NestedAnnotation.kt"); + } + @TestMetadata("NestedClass.kt") public void testNestedClass() throws Exception { doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadJava/compiledKotlin/annotations/classes/NestedClass.kt"); diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/JvmClassName.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/JvmClassName.java index 68ff909c0d9..d6f11a54e98 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/JvmClassName.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/JvmClassName.java @@ -18,6 +18,11 @@ package org.jetbrains.jet.lang.resolve.java; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.resolve.name.FqName; +import org.jetbrains.jet.lang.resolve.name.Name; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; public class JvmClassName { @NotNull @@ -76,6 +81,28 @@ public class JvmClassName { return internalName; } + @NotNull + public FqName getPackageFqName() { + int packageNameEnd = internalName.lastIndexOf("/"); + if (packageNameEnd == -1) { + return FqName.ROOT; + } + return FqName.fromSegments(Arrays.asList(internalName.substring(0, packageNameEnd).split("/"))); + } + + @NotNull + public FqName getHeuristicClassFqName() { + String name = internalName.substring(internalName.lastIndexOf("/") + 1); + char[] chars = name.toCharArray(); + //treat all 'stand-alone' dollars as dots, except for last and first char of class name + for (int i = 1; i < chars.length - 1; ++i) { + if (name.charAt(i) == '$' && name.charAt(i - 1) != '$' && name.charAt(i + 1) != '$') { + chars[i] = '.'; + } + } + return new FqName(new String(chars)); + } + @Override public String toString() { return internalName; diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/AnnotationDescriptorLoader.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/AnnotationDescriptorLoader.java index bbdb2d45c07..812379ec690 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/AnnotationDescriptorLoader.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/AnnotationDescriptorLoader.java @@ -18,9 +18,8 @@ package org.jetbrains.jet.lang.resolve.kotlin; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.descriptors.serialization.JavaProtoBuf; -import org.jetbrains.jet.descriptors.serialization.NameResolver; -import org.jetbrains.jet.descriptors.serialization.ProtoBuf; +import org.jetbrains.jet.descriptors.serialization.*; +import org.jetbrains.jet.descriptors.serialization.descriptors.AnnotatedCallableKind; import org.jetbrains.jet.descriptors.serialization.descriptors.AnnotationLoader; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; @@ -35,8 +34,9 @@ import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames; import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils; import org.jetbrains.jet.lang.resolve.java.resolver.ErrorReporter; +import org.jetbrains.jet.lang.resolve.name.FqName; +import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe; import org.jetbrains.jet.lang.resolve.name.Name; -import org.jetbrains.jet.lang.types.DependencyClassByQualifiedNameResolver; import org.jetbrains.jet.lang.types.ErrorUtils; import javax.inject.Inject; @@ -46,20 +46,22 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.jetbrains.jet.descriptors.serialization.descriptors.AnnotatedCallableKind; import static org.jetbrains.jet.lang.resolve.kotlin.DescriptorDeserializersStorage.MemberSignature; +import static org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.javaFqNameToKotlinFqName; public class AnnotationDescriptorLoader extends BaseDescriptorLoader implements AnnotationLoader { + + private ModuleDescriptor module; + @Inject - @Override - public void setStorage(@NotNull DescriptorDeserializersStorage storage) { - this.storage = storage; + public void setModule(ModuleDescriptor module) { + this.module = module; } @Inject @Override - public void setClassResolver(@NotNull DependencyClassByQualifiedNameResolver classResolver) { - this.classResolver = classResolver; + public void setStorage(@NotNull DescriptorDeserializersStorage storage) { + this.storage = storage; } @Inject @@ -101,7 +103,7 @@ public class AnnotationDescriptorLoader extends BaseDescriptorLoader implements @Nullable @Override public KotlinJvmBinaryClass.AnnotationArgumentVisitor visitAnnotation(@NotNull JvmClassName className) { - return resolveAnnotation(className, result, classResolver); + return resolveAnnotation(className, result, module); } @Override @@ -116,11 +118,11 @@ public class AnnotationDescriptorLoader extends BaseDescriptorLoader implements public static KotlinJvmBinaryClass.AnnotationArgumentVisitor resolveAnnotation( @NotNull JvmClassName className, @NotNull final List result, - @NotNull final DependencyClassByQualifiedNameResolver classResolver + @NotNull final ModuleDescriptor moduleDescriptor ) { if (JvmAnnotationNames.isSpecialAnnotation(className)) return null; - final ClassDescriptor annotationClass = resolveClass(className, classResolver); + final ClassDescriptor annotationClass = resolveClass(className, moduleDescriptor); return new KotlinJvmBinaryClass.AnnotationArgumentVisitor() { private final Map> arguments = new HashMap>(); @@ -147,7 +149,7 @@ public class AnnotationDescriptorLoader extends BaseDescriptorLoader implements @NotNull private CompileTimeConstant enumEntryValue(@NotNull JvmClassName enumClassName, @NotNull Name name) { - ClassDescriptor enumClass = resolveClass(enumClassName, classResolver); + ClassDescriptor enumClass = resolveClass(enumClassName, moduleDescriptor); if (enumClass.getKind() == ClassKind.ENUM_CLASS) { ClassifierDescriptor classifier = enumClass.getUnsubstitutedInnerClassesScope().getClassifier(name); if (classifier instanceof ClassDescriptor) { @@ -175,8 +177,11 @@ public class AnnotationDescriptorLoader extends BaseDescriptorLoader implements } @NotNull - private static ClassDescriptor resolveClass(@NotNull JvmClassName className, DependencyClassByQualifiedNameResolver classResolver) { - ClassDescriptor annotationClass = classResolver.resolveClass(className.getFqNameForClassNameWithoutDollars()); + private static ClassDescriptor resolveClass(@NotNull JvmClassName className, @NotNull ModuleDescriptor moduleDescriptor) { + FqName packageFqName = className.getPackageFqName(); + FqNameUnsafe relativeClassName = javaFqNameToKotlinFqName(className.getHeuristicClassFqName()); + ClassId classId = new ClassId(packageFqName, relativeClassName); + ClassDescriptor annotationClass = SerializationPackage.findClassAcrossModuleDependencies(moduleDescriptor, classId); return annotationClass != null ? annotationClass : ErrorUtils.createErrorClass(className.getInternalName()); } diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/BaseDescriptorLoader.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/BaseDescriptorLoader.java index c0f2e5b332e..9b62c9b6dfb 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/BaseDescriptorLoader.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/BaseDescriptorLoader.java @@ -21,6 +21,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.descriptors.serialization.JavaProtoBuf; import org.jetbrains.jet.descriptors.serialization.NameResolver; import org.jetbrains.jet.descriptors.serialization.ProtoBuf; +import org.jetbrains.jet.descriptors.serialization.descriptors.AnnotatedCallableKind; import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedCallableMemberDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassOrPackageFragmentDescriptor; @@ -29,9 +30,7 @@ import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; import org.jetbrains.jet.lang.resolve.java.resolver.ErrorReporter; import org.jetbrains.jet.lang.resolve.name.Name; -import org.jetbrains.jet.lang.types.DependencyClassByQualifiedNameResolver; -import org.jetbrains.jet.descriptors.serialization.descriptors.AnnotatedCallableKind; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isClassObject; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isTrait; import static org.jetbrains.jet.lang.resolve.kotlin.DescriptorDeserializersStorage.MemberSignature; @@ -39,14 +38,11 @@ import static org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.ko import static org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.naiveKotlinFqName; public abstract class BaseDescriptorLoader { - protected DependencyClassByQualifiedNameResolver classResolver; protected KotlinClassFinder kotlinClassFinder; protected ErrorReporter errorReporter; protected DescriptorDeserializersStorage storage; - public abstract void setClassResolver(@NotNull DependencyClassByQualifiedNameResolver classResolver); - public abstract void setKotlinClassFinder(@NotNull KotlinClassFinder kotlinClassFinder); public abstract void setErrorReporter(@NotNull ErrorReporter errorReporter); diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/ConstantDescriptorLoader.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/ConstantDescriptorLoader.java index 22d203ba035..a69ab11d1cf 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/ConstantDescriptorLoader.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/ConstantDescriptorLoader.java @@ -20,15 +20,14 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.descriptors.serialization.NameResolver; import org.jetbrains.jet.descriptors.serialization.ProtoBuf; +import org.jetbrains.jet.descriptors.serialization.descriptors.AnnotatedCallableKind; import org.jetbrains.jet.descriptors.serialization.descriptors.ConstantLoader; import org.jetbrains.jet.lang.descriptors.ClassOrPackageFragmentDescriptor; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.java.resolver.ErrorReporter; -import org.jetbrains.jet.lang.types.DependencyClassByQualifiedNameResolver; import javax.inject.Inject; -import org.jetbrains.jet.descriptors.serialization.descriptors.AnnotatedCallableKind; import static org.jetbrains.jet.lang.resolve.kotlin.DescriptorDeserializersStorage.MemberSignature; public class ConstantDescriptorLoader extends BaseDescriptorLoader implements ConstantLoader { @@ -38,12 +37,6 @@ public class ConstantDescriptorLoader extends BaseDescriptorLoader implements Co this.storage = storage; } - @Inject - @Override - public void setClassResolver(@NotNull DependencyClassByQualifiedNameResolver classResolver) { - this.classResolver = classResolver; - } - @Inject @Override public void setKotlinClassFinder(@NotNull KotlinClassFinder kotlinClassFinder) { diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DescriptorDeserializersStorage.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DescriptorDeserializersStorage.java index 48b03d61877..5dcf8ec2020 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DescriptorDeserializersStorage.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DescriptorDeserializersStorage.java @@ -19,13 +19,13 @@ package org.jetbrains.jet.lang.resolve.kotlin; import kotlin.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.constants.ConstantsPackage; import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.java.resolver.ErrorReporter; import org.jetbrains.jet.lang.resolve.name.Name; -import org.jetbrains.jet.lang.types.DependencyClassByQualifiedNameResolver; import org.jetbrains.jet.storage.MemoizedFunctionToNotNull; import org.jetbrains.jet.storage.StorageManager; @@ -34,8 +34,8 @@ import java.io.IOException; import java.util.*; public class DescriptorDeserializersStorage { - private DependencyClassByQualifiedNameResolver classResolver; private ErrorReporter errorReporter; + private ModuleDescriptor module; private final MemoizedFunctionToNotNull storage; @@ -57,8 +57,8 @@ public class DescriptorDeserializersStorage { } @Inject - public void setClassResolver(DependencyClassByQualifiedNameResolver classResolver) { - this.classResolver = classResolver; + public void setModule(ModuleDescriptor module) { + this.module = module; } @Inject @@ -137,7 +137,7 @@ public class DescriptorDeserializersStorage { result = new ArrayList(); memberAnnotations.put(paramSignature, result); } - return AnnotationDescriptorLoader.resolveAnnotation(className, result, classResolver); + return AnnotationDescriptorLoader.resolveAnnotation(className, result, module); } } @@ -152,7 +152,7 @@ public class DescriptorDeserializersStorage { @Nullable @Override public KotlinJvmBinaryClass.AnnotationArgumentVisitor visitAnnotation(@NotNull JvmClassName className) { - return AnnotationDescriptorLoader.resolveAnnotation(className, result, classResolver); + return AnnotationDescriptorLoader.resolveAnnotation(className, result, module); } @Override diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DeserializedResolverUtils.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DeserializedResolverUtils.java index 4c150d9a3d0..f7c31371d37 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DeserializedResolverUtils.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DeserializedResolverUtils.java @@ -24,6 +24,7 @@ import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe; import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.lang.resolve.name.SpecialNames; import java.util.ArrayList; import java.util.List; @@ -44,6 +45,23 @@ public class DeserializedResolverUtils { return FqName.fromSegments(correctedSegments); } + @NotNull + public static FqNameUnsafe javaFqNameToKotlinFqName(@NotNull FqName javaFqName) { + if (javaFqName.isRoot()) { + return javaFqName.toUnsafe(); + } + List segments = javaFqName.pathSegments(); + List correctedSegments = new ArrayList(segments.size()); + correctedSegments.add(segments.get(0)); + for (int i = 1; i < segments.size(); i++) { + Name segment = segments.get(i); + boolean isClassObjectName = segment.asString().equals(JvmAbi.CLASS_OBJECT_CLASS_NAME); + Name correctedSegment = isClassObjectName ? SpecialNames.getClassObjectName(segments.get(i - 1)) : segment; + correctedSegments.add(correctedSegment); + } + return FqNameUnsafe.fromSegments(correctedSegments); + } + @NotNull public static FqNameUnsafe naiveKotlinFqName(@NotNull ClassDescriptor descriptor) { DeclarationDescriptor containing = descriptor.getContainingDeclaration(); diff --git a/core/serialization/src/org/jetbrains/jet/descriptors/serialization/findClassInModule.kt b/core/serialization/src/org/jetbrains/jet/descriptors/serialization/findClassInModule.kt index 5fd6ba38b65..8f1a03502cf 100644 --- a/core/serialization/src/org/jetbrains/jet/descriptors/serialization/findClassInModule.kt +++ b/core/serialization/src/org/jetbrains/jet/descriptors/serialization/findClassInModule.kt @@ -30,7 +30,7 @@ private fun findInnerClass(classDescriptor: ClassDescriptor, name: Name): ClassD } } -fun ModuleDescriptor.findClassAcrossModuleDependencies(classId: ClassId): ClassDescriptor? { +public fun ModuleDescriptor.findClassAcrossModuleDependencies(classId: ClassId): ClassDescriptor? { val packageViewDescriptor = getPackage(classId.getPackageFqName()) ?: return null val segments = classId.getRelativeClassName().pathSegments() val topLevelClass = packageViewDescriptor.getMemberScope().getClassifier(segments.first!!) as? ClassDescriptor ?: return null diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/DeserializerForDecompiler.kt b/idea/src/org/jetbrains/jet/plugin/libraries/DeserializerForDecompiler.kt index 462b4478fad..084fc784168 100644 --- a/idea/src/org/jetbrains/jet/plugin/libraries/DeserializerForDecompiler.kt +++ b/idea/src/org/jetbrains/jet/plugin/libraries/DeserializerForDecompiler.kt @@ -27,7 +27,6 @@ import org.jetbrains.jet.lang.resolve.name.FqName import org.jetbrains.jet.lang.resolve.name.Name import org.jetbrains.jet.storage.LockBasedStorageManager import java.util.Collections -import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils import com.intellij.openapi.vfs.VirtualFile import org.jetbrains.jet.lang.resolve.kotlin.KotlinBinaryClassCache import org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils @@ -56,6 +55,9 @@ public fun DeserializerForDecompiler(classFile: VirtualFile): DeserializerForDec public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val directoryPackageFqName: FqName) : ResolverForDecompiler { + private val moduleDescriptor = + ModuleDescriptorImpl(Name.special(""), listOf(), PlatformToKotlinClassMap.EMPTY) + override fun resolveTopLevelClass(classFqName: FqName) = classes(classFqName.toClassId()) override fun resolveDeclarationsInPackage(packageFqName: FqName): Collection { @@ -100,19 +102,13 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di private val deserializerStorage = DescriptorDeserializersStorage(storageManager); { - deserializerStorage.setClassResolver { - fqName -> - classes(fqName.toClassId()) - } + deserializerStorage.setModule(moduleDescriptor) deserializerStorage.setErrorReporter(LOGGING_REPORTER) } private val annotationLoader = AnnotationDescriptorLoader(); { - annotationLoader.setClassResolver { - fqName -> - classes(fqName.toClassId()) - } + annotationLoader.setModule(moduleDescriptor) annotationLoader.setKotlinClassFinder(localClassFinder) annotationLoader.setErrorReporter(LOGGING_REPORTER) annotationLoader.setStorage(deserializerStorage) @@ -120,10 +116,6 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di private val constantLoader = ConstantDescriptorLoader(); { - constantLoader.setClassResolver { - fqName -> - classes(fqName.toClassId()) - } constantLoader.setKotlinClassFinder(localClassFinder) constantLoader.setErrorReporter(LOGGING_REPORTER) constantLoader.setStorage(deserializerStorage) @@ -149,9 +141,6 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di } } - private val moduleDescriptor = - ModuleDescriptorImpl(Name.special(""), listOf(), PlatformToKotlinClassMap.EMPTY); - { moduleDescriptor.addFragmentProvider(DependencyKind.BUILT_INS, KotlinBuiltIns.getInstance().getBuiltInsModule().getPackageFragmentProvider()) @@ -166,13 +155,8 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di } private fun resolveClassByClassId(classId: ClassId): ClassDescriptor? { - val binaryClass = localClassFinder.findKotlinClass(classId) - if (binaryClass != null) { - return deserializeBinaryClass(binaryClass) - } - val fullFqName = classId.asSingleFqName() - assert(fullFqName.isSafe(), "Safe fq name expected here, got $fullFqName instead") - return MissingDependencyErrorClassDescriptor(ErrorUtils.getErrorModule(), fullFqName.toSafe()) + val binaryClass = localClassFinder.findKotlinClass(classId) ?: return null + return deserializeBinaryClass(binaryClass) } private fun deserializeBinaryClass(kotlinClass: KotlinJvmBinaryClass): ClassDescriptor { diff --git a/idea/tests/org/jetbrains/jet/plugin/stubs/LazyResolveByStubTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/stubs/LazyResolveByStubTestGenerated.java index 8febd6a824d..71fafd92a3c 100644 --- a/idea/tests/org/jetbrains/jet/plugin/stubs/LazyResolveByStubTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/stubs/LazyResolveByStubTestGenerated.java @@ -95,6 +95,11 @@ public class LazyResolveByStubTestGenerated extends AbstractLazyResolveByStubTes JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/loadJava/compiledKotlin/annotations/classes"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("AnnotationInClassObject.kt") + public void testAnnotationInClassObject() throws Exception { + doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadJava/compiledKotlin/annotations/classes/AnnotationInClassObject.kt"); + } + @TestMetadata("ClassInClassObject.kt") public void testClassInClassObject() throws Exception { doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadJava/compiledKotlin/annotations/classes/ClassInClassObject.kt"); @@ -115,6 +120,11 @@ public class LazyResolveByStubTestGenerated extends AbstractLazyResolveByStubTes doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadJava/compiledKotlin/annotations/classes/Deprecated.kt"); } + @TestMetadata("DollarsInAnnotationName.kt") + public void testDollarsInAnnotationName() throws Exception { + doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadJava/compiledKotlin/annotations/classes/DollarsInAnnotationName.kt"); + } + @TestMetadata("EnumArgument.kt") public void testEnumArgument() throws Exception { doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadJava/compiledKotlin/annotations/classes/EnumArgument.kt"); @@ -125,6 +135,11 @@ public class LazyResolveByStubTestGenerated extends AbstractLazyResolveByStubTes doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadJava/compiledKotlin/annotations/classes/MultipleAnnotations.kt"); } + @TestMetadata("NestedAnnotation.kt") + public void testNestedAnnotation() throws Exception { + doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadJava/compiledKotlin/annotations/classes/NestedAnnotation.kt"); + } + @TestMetadata("NestedClass.kt") public void testNestedClass() throws Exception { doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadJava/compiledKotlin/annotations/classes/NestedClass.kt");