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 9803b2231a2..b7f7bceed27 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaDescriptorResolver.java @@ -102,7 +102,7 @@ public class InjectorForJavaDescriptorResolver { this.javaDescriptorResolver = new JavaDescriptorResolver(lazyJavaPackageFragmentProvider, getModule()); this.globalSearchScope = com.intellij.psi.search.GlobalSearchScope.allScope(project); this.javaClassDataFinder = new JavaClassDataFinder(virtualFileFinder, deserializedDescriptorResolver); - this.annotationDescriptorLoader = new AnnotationDescriptorLoader(); + this.annotationDescriptorLoader = new AnnotationDescriptorLoader(getModule(), lockBasedStorageManager); this.constantDescriptorLoader = new ConstantDescriptorLoader(); this.deserializationGlobalContextForJava = new DeserializationGlobalContextForJava(lockBasedStorageManager, getModule(), javaClassDataFinder, annotationDescriptorLoader, constantDescriptorLoader, lazyJavaPackageFragmentProvider); this.descriptorLoadersStorage = new DescriptorLoadersStorage(lockBasedStorageManager); @@ -128,7 +128,6 @@ public class InjectorForJavaDescriptorResolver { annotationDescriptorLoader.setErrorReporter(traceBasedErrorReporter); annotationDescriptorLoader.setKotlinClassFinder(virtualFileFinder); - annotationDescriptorLoader.setModule(module); annotationDescriptorLoader.setStorage(descriptorLoadersStorage); descriptorLoadersStorage.setErrorReporter(traceBasedErrorReporter); 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 503e8de9a96..2ec347696da 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForLazyResolveWithJava.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForLazyResolveWithJava.java @@ -191,7 +191,7 @@ public class InjectorForLazyResolveWithJava { this.scopeProvider = new ScopeProvider(getResolveSession()); this.scriptBodyResolver = new ScriptBodyResolver(); this.javaClassDataFinder = new JavaClassDataFinder(virtualFileFinder, deserializedDescriptorResolver); - this.annotationDescriptorLoader = new AnnotationDescriptorLoader(); + this.annotationDescriptorLoader = new AnnotationDescriptorLoader(module, storageManager); this.constantDescriptorLoader = new ConstantDescriptorLoader(); this.deserializationGlobalContextForJava = new DeserializationGlobalContextForJava(storageManager, module, javaClassDataFinder, annotationDescriptorLoader, constantDescriptorLoader, lazyJavaPackageFragmentProvider); this.descriptorLoadersStorage = new DescriptorLoadersStorage(storageManager); @@ -277,7 +277,6 @@ public class InjectorForLazyResolveWithJava { annotationDescriptorLoader.setErrorReporter(traceBasedErrorReporter); annotationDescriptorLoader.setKotlinClassFinder(virtualFileFinder); - annotationDescriptorLoader.setModule(module); annotationDescriptorLoader.setStorage(descriptorLoadersStorage); descriptorLoadersStorage.setErrorReporter(traceBasedErrorReporter); 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 bcf7dc8e72c..8b309cd4987 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java @@ -185,7 +185,7 @@ public class InjectorForTopDownAnalyzerForJvm { this.lazyJavaPackageFragmentProvider = new LazyJavaPackageFragmentProvider(globalJavaResolverContext, getModuleDescriptor()); this.javaDescriptorResolver = new JavaDescriptorResolver(lazyJavaPackageFragmentProvider, getModuleDescriptor()); this.javaClassDataFinder = new JavaClassDataFinder(virtualFileFinder, deserializedDescriptorResolver); - this.annotationDescriptorLoader = new AnnotationDescriptorLoader(); + this.annotationDescriptorLoader = new AnnotationDescriptorLoader(getModuleDescriptor(), storageManager); this.constantDescriptorLoader = new ConstantDescriptorLoader(); this.deserializationGlobalContextForJava = new DeserializationGlobalContextForJava(storageManager, getModuleDescriptor(), javaClassDataFinder, annotationDescriptorLoader, constantDescriptorLoader, lazyJavaPackageFragmentProvider); this.additionalCheckerProvider = org.jetbrains.jet.lang.resolve.kotlin.JavaDeclarationCheckerProvider.INSTANCE$; @@ -361,7 +361,6 @@ public class InjectorForTopDownAnalyzerForJvm { annotationDescriptorLoader.setErrorReporter(traceBasedErrorReporter); annotationDescriptorLoader.setKotlinClassFinder(virtualFileFinder); - annotationDescriptorLoader.setModule(moduleDescriptor); annotationDescriptorLoader.setStorage(descriptorLoadersStorage); descriptorLoadersStorage.setErrorReporter(traceBasedErrorReporter); 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 5332f1dffef..816664d58c3 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 @@ -16,6 +16,7 @@ package org.jetbrains.jet.lang.resolve.kotlin; +import kotlin.Function0; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.descriptors.serialization.JavaProtoBuf; @@ -28,7 +29,6 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptorImpl; import org.jetbrains.jet.lang.descriptors.annotations.Annotations; -import org.jetbrains.jet.lang.descriptors.annotations.AnnotationsImpl; import org.jetbrains.jet.lang.resolve.constants.*; import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames; import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils; @@ -37,24 +37,21 @@ import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass.AnnotationArra import org.jetbrains.jet.lang.resolve.name.ClassId; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.types.ErrorUtils; +import org.jetbrains.jet.storage.StorageManager; import javax.inject.Inject; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import static org.jetbrains.jet.lang.resolve.kotlin.DescriptorLoadersStorage.MemberSignature; import static org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.javaClassIdToKotlinClassId; public class AnnotationDescriptorLoader extends BaseDescriptorLoader implements AnnotationLoader { + private final ModuleDescriptor module; + private final StorageManager storageManager; - private ModuleDescriptor module; - - @Inject - public void setModule(ModuleDescriptor module) { + public AnnotationDescriptorLoader(@NotNull ModuleDescriptor module, @NotNull StorageManager storageManager) { this.module = module; + this.storageManager = storageManager; } @Inject @@ -78,39 +75,34 @@ public class AnnotationDescriptorLoader extends BaseDescriptorLoader implements @NotNull @Override public Annotations loadClassAnnotations(@NotNull ClassDescriptor descriptor, @NotNull ProtoBuf.Class classProto) { - KotlinJvmBinaryClass kotlinClass = findKotlinClassByDescriptor(descriptor); + final KotlinJvmBinaryClass kotlinClass = findKotlinClassByDescriptor(descriptor); if (kotlinClass == null) { // This means that the resource we're constructing the descriptor from is no longer present: KotlinClassFinder had found the // class earlier, but it can't now errorReporter.reportLoadingError("Kotlin class for loading class annotations is not found: " + descriptor, null); return Annotations.EMPTY; } - try { - return loadClassAnnotationsFromClass(kotlinClass); - } - catch (IOException e) { - errorReporter.reportLoadingError("Error loading member annotations from Kotlin class: " + kotlinClass, e); - return Annotations.EMPTY; - } - } - @NotNull - private Annotations loadClassAnnotationsFromClass(@NotNull KotlinJvmBinaryClass kotlinClass) throws IOException { - final List result = new ArrayList(); - - kotlinClass.loadClassAnnotations(new KotlinJvmBinaryClass.AnnotationVisitor() { - @Nullable + return new DeserializedAnnotations(storageManager, new Function0>() { @Override - public KotlinJvmBinaryClass.AnnotationArgumentVisitor visitAnnotation(@NotNull ClassId classId) { - return resolveAnnotation(classId, result, module); - } + public List invoke() { + final List result = new ArrayList(1); - @Override - public void visitEnd() { + kotlinClass.loadClassAnnotations(new KotlinJvmBinaryClass.AnnotationVisitor() { + @Nullable + @Override + public KotlinJvmBinaryClass.AnnotationArgumentVisitor visitAnnotation(@NotNull ClassId classId) { + return resolveAnnotation(classId, result, module); + } + + @Override + public void visitEnd() { + } + }); + + return result; } }); - - return new AnnotationsImpl(result); } @Nullable @@ -227,16 +219,21 @@ public class AnnotationDescriptorLoader extends BaseDescriptorLoader implements @NotNull ProtoBuf.Callable proto, @NotNull NameResolver nameResolver, @NotNull AnnotatedCallableKind kind, - @NotNull MemberSignature signature + @NotNull final MemberSignature signature ) { - KotlinJvmBinaryClass kotlinClass = findClassWithAnnotationsAndInitializers(container, proto, nameResolver, kind); + final KotlinJvmBinaryClass kotlinClass = findClassWithAnnotationsAndInitializers(container, proto, nameResolver, kind); if (kotlinClass == null) { errorReporter.reportLoadingError("Kotlin class for loading member annotations is not found: " + container, null); return Annotations.EMPTY; } - List annotations = storage.getStorage().invoke(kotlinClass).getMemberAnnotations().get(signature); - return annotations == null ? Annotations.EMPTY : new AnnotationsImpl(annotations); + return new DeserializedAnnotations(storageManager, new Function0>() { + @Override + public List invoke() { + List descriptors = storage.getStorage().invoke(kotlinClass).getMemberAnnotations().get(signature); + return descriptors == null ? Collections.emptyList() : descriptors; + } + }); } @NotNull diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DeserializedAnnotations.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DeserializedAnnotations.kt new file mode 100644 index 00000000000..f7fbe4d39e9 --- /dev/null +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/kotlin/DeserializedAnnotations.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2010-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. + */ + +package org.jetbrains.jet.lang.resolve.kotlin + +import org.jetbrains.jet.lang.descriptors.annotations.Annotations +import org.jetbrains.jet.lang.resolve.name.FqName +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor +import org.jetbrains.jet.storage.StorageManager +import org.jetbrains.jet.lang.descriptors.ClassDescriptor +import org.jetbrains.jet.lang.resolve.DescriptorUtils +import org.jetbrains.jet.utils.toReadOnlyList + +class DeserializedAnnotations( + storageManager: StorageManager, + compute: () -> List +) : Annotations { + private val annotations = storageManager.createLazyValue { compute().toReadOnlyList() } + + override fun isEmpty(): Boolean = annotations().isEmpty() + + override fun findAnnotation(fqName: FqName): AnnotationDescriptor? = annotations().firstOrNull { + annotation -> + val descriptor = annotation.getType().getConstructor().getDeclarationDescriptor() + descriptor is ClassDescriptor && fqName.equalsTo(DescriptorUtils.getFqName(descriptor)) + } + + override fun iterator(): Iterator = annotations().iterator() +} diff --git a/idea/idea-analysis/src/org/jetbrains/jet/plugin/decompiler/textBuilder/DeserializerForDecompiler.kt b/idea/idea-analysis/src/org/jetbrains/jet/plugin/decompiler/textBuilder/DeserializerForDecompiler.kt index 811880e4882..7f40e8ecf85 100644 --- a/idea/idea-analysis/src/org/jetbrains/jet/plugin/decompiler/textBuilder/DeserializerForDecompiler.kt +++ b/idea/idea-analysis/src/org/jetbrains/jet/plugin/decompiler/textBuilder/DeserializerForDecompiler.kt @@ -95,9 +95,8 @@ public class DeserializerForDecompiler(val packageDirectory: VirtualFile, val di loadersStorage.setErrorReporter(LOGGING_REPORTER) } - private val annotationLoader = AnnotationDescriptorLoader(); + private val annotationLoader = AnnotationDescriptorLoader(moduleDescriptor, storageManager); { - annotationLoader.setModule(moduleDescriptor) annotationLoader.setKotlinClassFinder(localClassFinder) annotationLoader.setErrorReporter(LOGGING_REPORTER) annotationLoader.setStorage(loadersStorage)