From bb17adc8d736a6f9ff5681486dd635cfabfe9e03 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Fri, 21 Mar 2014 16:19:06 +0400 Subject: [PATCH] LazyAnnotations implementation --- .../jet/lang/resolve/AnnotationResolver.java | 4 +- .../lang/resolve/lazy/ForceResolveUtil.java | 4 + .../lazy/descriptors/LazyAnnotations.kt | 131 ++++++++++++++++++ .../descriptors/annotations/Annotations.java | 50 ------- .../descriptors/annotations/Annotations.kt | 38 +++++ 5 files changed, 175 insertions(+), 52 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyAnnotations.kt delete mode 100644 core/descriptors/src/org/jetbrains/jet/lang/descriptors/annotations/Annotations.java create mode 100644 core/descriptors/src/org/jetbrains/jet/lang/descriptors/annotations/Annotations.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java index 8b303d10852..f9e65ffd168 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java @@ -126,7 +126,7 @@ public class AnnotationResolver { } @NotNull - public JetType resolveAnnotationType( + private JetType resolveAnnotationType( JetScope scope, JetAnnotationEntry entryElement, BindingTrace trace @@ -230,7 +230,7 @@ public class AnnotationResolver { } @Nullable - private static CompileTimeConstant getAnnotationArgumentValue( + public static CompileTimeConstant getAnnotationArgumentValue( BindingTrace trace, ValueParameterDescriptor parameterDescriptor, ResolvedValueArgument resolvedArgument diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ForceResolveUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ForceResolveUtil.java index 1d141fbb533..e6a84014efe 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ForceResolveUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ForceResolveUtil.java @@ -21,6 +21,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.Annotations; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.JetType; @@ -65,6 +66,9 @@ public class ForceResolveUtil { public static void forceResolveAllContents(@NotNull Annotations annotations) { doForceResolveAllContents(annotations); + for (AnnotationDescriptor annotation : annotations) { + doForceResolveAllContents(annotation); + } } private static void doForceResolveAllContents(Object object) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyAnnotations.kt b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyAnnotations.kt new file mode 100644 index 00000000000..2a6f346f7c9 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyAnnotations.kt @@ -0,0 +1,131 @@ +/* + * 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.lazy.descriptors + +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor +import org.jetbrains.jet.lang.resolve.name.FqName +import org.jetbrains.jet.lang.descriptors.annotations.Annotations +import org.jetbrains.jet.lang.resolve.lazy.LazyEntity +import org.jetbrains.jet.lang.psi.JetAnnotated +import org.jetbrains.jet.lang.psi.JetAnnotationEntry +import org.jetbrains.jet.lang.resolve.DescriptorUtils +import org.jetbrains.jet.lang.resolve.AnnotationResolver +import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor +import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant +import org.jetbrains.jet.lang.resolve.lazy.ForceResolveUtil +import org.jetbrains.jet.storage.StorageManager +import org.jetbrains.jet.lang.resolve.scopes.JetScope +import org.jetbrains.jet.lang.resolve.BindingTrace +import org.jetbrains.jet.utils.keysToMapExceptNulls + +class LazyAnnotationsContext( + val annotationResolver: AnnotationResolver, + val storageManager: StorageManager, + val scope: JetScope, + val trace: BindingTrace + ) + +public class LazyAnnotations( + val c: LazyAnnotationsContext, + val annotatedElement: JetAnnotated +) : Annotations, LazyEntity { + override fun isEmpty() = annotatedElement.getAnnotationEntries().isEmpty() + + val _annotation = c.storageManager.createMemoizedFunction { + (entry: JetAnnotationEntry) -> + LazyAnnotationDescriptor(c, entry) + } + + override fun findAnnotation(fqName: FqName): AnnotationDescriptor? { + // We can not efficiently check short names here: + // an annotation class may be renamed on import + for (annotationDescriptor in iterator()) { + val annotationType = annotationDescriptor.getType() + if (annotationType.isError()) continue + + val descriptor = annotationType.getConstructor().getDeclarationDescriptor() + if (descriptor == null) continue + + if (DescriptorUtils.getFqNameSafe(descriptor) == fqName) { + return annotationDescriptor + } + } + + return null + } + + override fun iterator(): Iterator { + return annotatedElement.getAnnotationEntries().stream().map(_annotation).iterator() + } + + override fun forceResolveAllContents() { + // To resolve all entries + this.toList() + } +} + +public class LazyAnnotationDescriptor( + val c: LazyAnnotationsContext, + val annotationEntry: JetAnnotationEntry +) : AnnotationDescriptor, LazyEntity { + + private val _resolutionResults = c.storageManager.createLazyValue { + val results = c.annotationResolver.resolveAnnotationCall( + annotationEntry, + c.scope, + c.trace + ) + AnnotationResolver.checkAnnotationType(annotationEntry, c.trace, results) + results + } + + private val _type = c.storageManager.createLazyValue { + c.annotationResolver.resolveAnnotationType( + c.scope, + annotationEntry + ) + } + + override fun getType() = _type() + + private val _valueArguments = c.storageManager.createMemoizedFunctionWithNullableValues @f { + (valueParameterDescriptor: ValueParameterDescriptor): CompileTimeConstant<*>? -> + if (!_resolutionResults().isSingleResult()) return@f null + + val resolvedValueArgument = _resolutionResults().getResultingCall().getValueArguments()[valueParameterDescriptor] + if (resolvedValueArgument == null) return@f null + + AnnotationResolver.getAnnotationArgumentValue(c.trace, valueParameterDescriptor, resolvedValueArgument) + } + + override fun getValueArgument(valueParameterDescriptor: ValueParameterDescriptor): CompileTimeConstant? { + return _valueArguments(valueParameterDescriptor) + } + + override fun getAllValueArguments(): Map> { + if (!_resolutionResults().isSingleResult()) return mapOf() + + return _resolutionResults().getResultingCall().getValueArguments().keySet().keysToMapExceptNulls { + getValueArgument(it) + } + } + + override fun forceResolveAllContents() { + ForceResolveUtil.forceResolveAllContents(getType()) + getAllValueArguments() + } +} \ No newline at end of file diff --git a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/annotations/Annotations.java b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/annotations/Annotations.java deleted file mode 100644 index 76ee856044c..00000000000 --- a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/annotations/Annotations.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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.descriptors.annotations; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.resolve.name.FqName; - -import java.util.Collections; -import java.util.Iterator; - -public interface Annotations extends Iterable { - Annotations EMPTY = new Annotations() { - @Override - public boolean isEmpty() { - return true; - } - - @Nullable - @Override - public AnnotationDescriptor findAnnotation(@NotNull FqName fqName) { - return null; - } - - @NotNull - @Override - public Iterator iterator() { - return Collections.emptyList().iterator(); - } - }; - - boolean isEmpty(); - - @Nullable - AnnotationDescriptor findAnnotation(@NotNull FqName fqName); -} diff --git a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/annotations/Annotations.kt b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/annotations/Annotations.kt new file mode 100644 index 00000000000..be1a7f930f4 --- /dev/null +++ b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/annotations/Annotations.kt @@ -0,0 +1,38 @@ +/* + * 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.descriptors.annotations + +import org.jetbrains.annotations.Nullable +import org.jetbrains.jet.lang.resolve.name.FqName +import java.util.Collections + +public trait Annotations : Iterable { + + fun isEmpty(): Boolean + + fun findAnnotation(fqName: FqName): AnnotationDescriptor? + + class object { + val EMPTY: Annotations = object : Annotations { + override fun isEmpty() = true + + override fun findAnnotation(fqName: FqName) = null + + override fun iterator() = Collections.emptyList().iterator() + } + } +}