Added cached calculation of extensions

This commit is contained in:
Mikhael Bogdanov
2013-10-24 11:57:06 +04:00
parent 592c26e840
commit 643aec6c9b
6 changed files with 99 additions and 26 deletions
@@ -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);
}
}
@@ -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<VariableDescriptor> 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;
}
@@ -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<Map<DeclarationDescriptor, List<CallResolverExtension>>> 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<CallResolverExtension> createExtensions(@NotNull DeclarationDescriptor declaration) {
Map<DeclarationDescriptor, List<CallResolverExtension>> map;
if (extensionsCache == null || (map = extensionsCache.get()) == null) {
map = new HashMap<DeclarationDescriptor, List<CallResolverExtension>>();
extensionsCache = new WeakReference<Map<DeclarationDescriptor, List<CallResolverExtension>>>(map);
}
List<CallResolverExtension> extensions = map.get(declaration);
if (extensions != null) {
return extensions;
}
extensions = new ArrayList<CallResolverExtension>();
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<CallResolverExtension> immutableResult = Collections.unmodifiableList(extensions);
map.put(declaration, immutableResult);
return immutableResult;
}
// with default one at the end
private void appendExtensionsFor(DeclarationDescriptor declarationDescriptor, List<CallResolverExtension> extensions) {
// add your extensions here
extensions.add(DEFAULT);
}
}
@@ -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<CallResolverExtension> extensions;
public CompositeExtension(@NotNull List<CallResolverExtension> extensions) {
this.extensions = extensions;
}
@Override
public <F extends CallableDescriptor> void run(
@NotNull OverloadResolutionResultsImpl<F> results,
@NotNull BasicCallResolutionContext context
) {
for (CallResolverExtension delegate : delegates) {
delegate.run(results, context);
for (CallResolverExtension resolverExtension : extensions) {
resolverExtension.run(results, context);
}
}
}
@@ -43,7 +43,7 @@ public class ExpressionTypingContext extends ResolutionContext<ExpressionTypingC
) {
return newContext(expressionTypingServices, trace, scope, dataFlowInfo, expectedType, expressionPosition,
ContextDependency.INDEPENDENT, ResolutionResultsCacheImpl.create(), LabelResolver.create(),
expressionTypingServices.getDefaultExtension());
expressionTypingServices.createExtension(scope));
}
@NotNull
@@ -31,6 +31,7 @@ import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.CallResolverExtension;
import org.jetbrains.jet.lang.resolve.calls.CallResolverExtensionProvider;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.context.ContextDependency;
import org.jetbrains.jet.lang.resolve.calls.context.ExpressionPosition;
@@ -72,7 +73,7 @@ public class ExpressionTypingServices {
@NotNull
private PlatformToKotlinClassMap platformToKotlinClassMap;
@NotNull
private CallResolverExtension defaultExtension;
private CallResolverExtensionProvider extensionProvider;
@NotNull
public Project getProject() {
@@ -146,13 +147,8 @@ public class ExpressionTypingServices {
}
@Inject
public void setDefaultExtension(@NotNull CallResolverExtension extension) {
this.defaultExtension = extension;
}
@NotNull
public CallResolverExtension getDefaultExtension() {
return defaultExtension;
public void setExtensionProvider(@NotNull CallResolverExtensionProvider extensionProvider) {
this.extensionProvider = extensionProvider;
}
@NotNull
@@ -412,4 +408,9 @@ public class ExpressionTypingServices {
}
}
}
@NotNull
public CallResolverExtension createExtension(@NotNull JetScope scope) {
return extensionProvider.createExtension(scope == JetScope.EMPTY ? null : scope.getContainingDeclaration());
}
}