From 643aec6c9bf3b078657e89b621cfb3ad0d923a5e Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Thu, 24 Oct 2013 11:57:06 +0400 Subject: [PATCH] Added cached calculation of extensions --- .../jet/lang/resolve/BodyResolver.java | 2 +- .../jet/lang/resolve/calls/CallResolver.java | 14 +--- .../calls/CallResolverExtensionProvider.java | 76 +++++++++++++++++++ .../resolve/calls/CompositeExtension.java | 14 +++- .../expressions/ExpressionTypingContext.java | 2 +- .../expressions/ExpressionTypingServices.java | 17 +++-- 6 files changed, 99 insertions(+), 26 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverExtensionProvider.java diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index 9460271da47..2f60b65cb51 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -209,7 +209,7 @@ public class BodyResolver { if (type != null && supertype != null) { SimpleResolutionContext simpleResolutionContext = new SimpleResolutionContext( trace, scope, supertype, context.getOuterDataFlowInfo(), ExpressionPosition.FREE, ContextDependency.INDEPENDENT, - ResolutionResultsCacheImpl.create(), LabelResolver.create(), expressionTypingServices.getDefaultExtension()); + ResolutionResultsCacheImpl.create(), LabelResolver.create(), expressionTypingServices.createExtension(scope)); DataFlowUtils.checkType(type, delegateExpression, simpleResolutionContext); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java index 4faad684d5a..0136b76168c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java @@ -71,9 +71,6 @@ public class CallResolver { private CandidateResolver candidateResolver; @NotNull private ArgumentTypeResolver argumentTypeResolver; - @Nullable - private CallResolverExtension extension; - @Inject public void setExpressionTypingServices(@NotNull ExpressionTypingServices expressionTypingServices) { this.expressionTypingServices = expressionTypingServices; @@ -94,11 +91,6 @@ public class CallResolver { this.argumentTypeResolver = argumentTypeResolver; } - @Inject - public void setExtension(@NotNull CallResolverExtension extension) { - this.extension = extension; - } - @NotNull public OverloadResolutionResults resolveSimpleProperty(@NotNull BasicCallResolutionContext context) { JetExpression calleeExpression = context.call.getCalleeExpression(); @@ -141,7 +133,7 @@ public class CallResolver { ) { return resolveFunctionCall(BasicCallResolutionContext.create( trace, scope, call, expectedType, dataFlowInfo, ContextDependency.INDEPENDENT, CheckValueArgumentsMode.ENABLED, - ExpressionPosition.FREE, ResolutionResultsCacheImpl.create(), LabelResolver.create(), null, expressionTypingServices.getDefaultExtension())); + ExpressionPosition.FREE, ResolutionResultsCacheImpl.create(), LabelResolver.create(), null, expressionTypingServices.createExtension(scope))); } @NotNull @@ -322,9 +314,7 @@ public class CallResolver { results = completeTypeInferenceDependentOnExpectedType(context, results, tracing); } - if (extension != null) { - extension.run(results, context); - } + context.callResolverExtension.run(results, context); return results; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverExtensionProvider.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverExtensionProvider.java new file mode 100644 index 00000000000..2c03380f1f7 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverExtensionProvider.java @@ -0,0 +1,76 @@ +/* + * 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.calls; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; + +import java.lang.ref.WeakReference; +import java.util.*; + +public class CallResolverExtensionProvider { + + private final static CompositeExtension DEFAULT = + new CompositeExtension(Arrays.asList(new NeedSyntheticCallResolverExtension(), new TypeParameterAsReifiedCheck())); + + private WeakReference>> extensionsCache; + + @NotNull + public CallResolverExtension createExtension(@Nullable DeclarationDescriptor descriptor) { + if (descriptor == null) { + return DEFAULT; + } + return new CompositeExtension(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 void appendExtensionsFor(DeclarationDescriptor declarationDescriptor, List extensions) { + // add your extensions here + extensions.add(DEFAULT); + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CompositeExtension.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CompositeExtension.java index 02460bb4782..7c4e581d3fc 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CompositeExtension.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CompositeExtension.java @@ -5,17 +5,23 @@ import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.resolve.calls.context.BasicCallResolutionContext; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl; +import java.util.List; + public class CompositeExtension implements CallResolverExtension { - private final CallResolverExtension[] delegates = new CallResolverExtension[]{ - new NeedSyntheticCallResolverExtension(), new TypeParameterAsReifiedCheck()}; + + private final List extensions; + + public CompositeExtension(@NotNull List extensions) { + this.extensions = extensions; + } @Override public void run( @NotNull OverloadResolutionResultsImpl results, @NotNull BasicCallResolutionContext context ) { - for (CallResolverExtension delegate : delegates) { - delegate.run(results, context); + for (CallResolverExtension resolverExtension : extensions) { + resolverExtension.run(results, context); } } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java index ef036c2c8ef..6fc461e94ee 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java @@ -43,7 +43,7 @@ public class ExpressionTypingContext extends ResolutionContext