Add lookup for every expression's type

This commit is contained in:
Alexey Tsvetkov
2016-01-21 18:33:57 +03:00
parent 1ef615e020
commit 310a995bb1
19 changed files with 248 additions and 155 deletions
@@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.builtins.ReflectionTypes;
import org.jetbrains.kotlin.context.GlobalContext;
import org.jetbrains.kotlin.incremental.components.LookupTracker;
import org.jetbrains.kotlin.platform.PlatformToKotlinClassMap;
import org.jetbrains.kotlin.resolve.*;
import org.jetbrains.kotlin.resolve.calls.CallExpressionResolver;
@@ -57,6 +58,7 @@ public class ExpressionTypingComponents {
/*package*/ IdentifierChecker identifierChecker;
/*package*/ DeclarationsCheckerBuilder declarationsCheckerBuilder;
/*package*/ LocalVariableResolver localVariableResolver;
/*package*/ LookupTracker lookupTracker;
@Inject
@@ -188,4 +190,9 @@ public class ExpressionTypingComponents {
public void setLocalVariableResolver(@NotNull LocalVariableResolver localVariableResolver) {
this.localVariableResolver = localVariableResolver;
}
@Inject
public void setLookupTracker(@NotNull LookupTracker lookupTracker) {
this.lookupTracker = lookupTracker;
}
}
@@ -23,6 +23,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
import org.jetbrains.kotlin.diagnostics.Errors;
import org.jetbrains.kotlin.incremental.components.LookupTracker;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.*;
import org.jetbrains.kotlin.resolve.bindingContextUtil.BindingContextUtilsKt;
@@ -33,6 +34,7 @@ import org.jetbrains.kotlin.types.DeferredType;
import org.jetbrains.kotlin.types.ErrorUtils;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryKt;
import org.jetbrains.kotlin.util.LookupTrackerUtilKt;
import org.jetbrains.kotlin.util.PerformanceCounter;
import org.jetbrains.kotlin.util.ReenteringLazyValueComputationException;
import org.jetbrains.kotlin.utils.KotlinFrontEndException;
@@ -158,7 +160,7 @@ public abstract class ExpressionTypingVisitorDispatcher extends KtVisitor<Kotlin
}
@NotNull
private static KotlinTypeInfo getTypeInfo(@NotNull final KtExpression expression, final ExpressionTypingContext context, final KtVisitor<KotlinTypeInfo, ExpressionTypingContext> visitor) {
private KotlinTypeInfo getTypeInfo(@NotNull final KtExpression expression, final ExpressionTypingContext context, final KtVisitor<KotlinTypeInfo, ExpressionTypingContext> visitor) {
return typeInfoPerfCounter.time(new Function0<KotlinTypeInfo>() {
@Override
public KotlinTypeInfo invoke() {
@@ -192,6 +194,7 @@ public abstract class ExpressionTypingVisitorDispatcher extends KtVisitor<Kotlin
// todo save scope before analyze and fix debugger: see CodeFragmentAnalyzer.correctContextForExpression
BindingContextUtilsKt.recordScope(context.trace, context.scope, expression);
BindingContextUtilsKt.recordDataFlowInfo(context.replaceDataFlowInfo(result.getDataFlowInfo()), expression);
recordTypeInfo(expression, result);
return result;
}
catch (ProcessCanceledException e) {
@@ -212,6 +215,15 @@ public abstract class ExpressionTypingVisitorDispatcher extends KtVisitor<Kotlin
});
}
private void recordTypeInfo(@NotNull KtExpression expression, @NotNull KotlinTypeInfo typeInfo) {
LookupTracker lookupTracker = getComponents().lookupTracker;
KotlinType resultType = typeInfo.getType();
if (resultType != null) {
LookupTrackerUtilKt.record(lookupTracker, expression, resultType);
}
}
private static void logOrThrowException(@NotNull KtExpression expression, Throwable e) {
try {
// This trows AssertionError in CLI and reports the error in the IDE
@@ -0,0 +1,29 @@
package org.jetbrains.kotlin.util
import org.jetbrains.kotlin.incremental.KotlinLookupLocation
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.record
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.resolve.DescriptorUtils.isLocal
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.isUnit
fun LookupTracker.record(expression: KtExpression, type: KotlinType) {
if (type.isError || type.isUnit()) return
val typeDescriptor = type.constructor.declarationDescriptor ?: return
val scopeDescriptor = typeDescriptor.containingDeclaration
// Scope descriptor is function descriptor only when type is local
// Lookups for local types are not needed since all usages are compiled with the type
if (!isLocal(typeDescriptor)) {
record(KotlinLookupLocation(expression), scopeDescriptor, typeDescriptor.name)
}
for (typeArgument in type.arguments) {
if (!typeArgument.isStarProjection) {
record(expression, typeArgument.type)
}
}
}