From 597a191c84eeb7e7d8b62ac73ef111f7e9ca5453 Mon Sep 17 00:00:00 2001 From: Alexey Tsvetkov Date: Tue, 30 Dec 2014 20:46:12 +0300 Subject: [PATCH] Frontend: extracted InlineCallCheckerWrapper to create InlineCallCheckers during run --- .../CallResolverExtensionProvider.java | 52 ++----------------- .../resolve/calls/checkers/InlineChecker.java | 2 +- .../calls/checkers/InlineCheckerWrapper.kt | 51 ++++++++++++++++++ 3 files changed, 55 insertions(+), 50 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineCheckerWrapper.kt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CallResolverExtensionProvider.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CallResolverExtensionProvider.java index e46f53dfac9..afae2516576 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CallResolverExtensionProvider.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CallResolverExtensionProvider.java @@ -30,58 +30,12 @@ public class CallResolverExtensionProvider { new CompositeChecker(Arrays.asList( new NeedSyntheticChecker(), new ReifiedTypeParameterSubstitutionChecker(), - new CapturingInClosureChecker() + new CapturingInClosureChecker(), + new InlineCheckerWrapper() )); - private WeakReference>> extensionsCache; - @NotNull public CallChecker createExtension(@Nullable DeclarationDescriptor descriptor, boolean isAnnotationContext) { - if (descriptor == null || isAnnotationContext) { - return DEFAULT; - } - return new CompositeChecker(createExtensions(descriptor)); - } - - // create extension list with default one at the end - @NotNull - private List createExtensions(@NotNull DeclarationDescriptor declaration) { - Map> map; - if (extensionsCache == null || (map = extensionsCache.get()) == null) { - map = new HashMap>(); - extensionsCache = new WeakReference>>(map); - } - - List extensions = map.get(declaration); - if (extensions != null) { - return extensions; - } - - extensions = new ArrayList(); - - DeclarationDescriptor parent = declaration.getContainingDeclaration(); - if (parent != null) { - extensions.addAll(createExtensions(parent)); - extensions.remove(extensions.size() - 1);//remove default from parent list - } - - appendExtensionsFor(declaration, extensions); - - List immutableResult = Collections.unmodifiableList(extensions); - map.put(declaration, immutableResult); - - return immutableResult; - } - - // with default one at the end - private static void appendExtensionsFor(DeclarationDescriptor declarationDescriptor, List extensions) { - if (declarationDescriptor instanceof SimpleFunctionDescriptor) { - SimpleFunctionDescriptor descriptor = (SimpleFunctionDescriptor) declarationDescriptor; - if (descriptor.getInlineStrategy().isInline()) { - extensions.add(new InlineChecker(descriptor)); - } - } - // add your checkers here - extensions.add(DEFAULT); + return DEFAULT; } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineChecker.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineChecker.java index 9633d4de715..1b39387532b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineChecker.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineChecker.java @@ -46,7 +46,7 @@ import java.util.Set; import static org.jetbrains.kotlin.resolve.InlineDescriptorUtils.allowsNonLocalReturns; import static org.jetbrains.kotlin.resolve.InlineDescriptorUtils.checkNonLocalReturnUsage; -public class InlineChecker implements CallChecker { +class InlineChecker implements CallChecker { private final SimpleFunctionDescriptor descriptor; diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineCheckerWrapper.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineCheckerWrapper.kt new file mode 100644 index 00000000000..7ac15052441 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineCheckerWrapper.kt @@ -0,0 +1,51 @@ +/* + * Copyright 2010-2015 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.kotlin.resolve.calls.checkers + +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall +import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor +import java.lang.ref.WeakReference + +public class InlineCheckerWrapper : CallChecker { + private var checkersCache: WeakReference>? = null + + override fun check(resolvedCall: ResolvedCall, context: BasicCallResolutionContext) { + if (context.isAnnotationContext) return + + var parentDescriptor: DeclarationDescriptor? = context.scope.getContainingDeclaration() + + while (parentDescriptor != null) { + val descriptor = parentDescriptor!! + + if (descriptor is SimpleFunctionDescriptor && descriptor.getInlineStrategy().isInline()) { + val checker = getChecker(descriptor) + checker.check(resolvedCall, context) + } + + parentDescriptor = parentDescriptor?.getContainingDeclaration() + } + } + + private fun getChecker(descriptor: SimpleFunctionDescriptor): CallChecker { + val map = checkersCache?.get() ?: hashMapOf() + checkersCache = checkersCache ?: WeakReference(map) + return map.getOrPut(descriptor) { InlineChecker(descriptor) } + } +} \ No newline at end of file