Debugger: skip visibility check

This commit is contained in:
Natalia Ukhorskaya
2016-01-28 11:25:17 +03:00
parent bad8320038
commit d60a5e65c1
12 changed files with 72 additions and 31 deletions
@@ -18,12 +18,23 @@ package org.jetbrains.kotlin.psi.codeFragmentUtil
import com.intellij.openapi.util.Key
import org.jetbrains.kotlin.psi.KtCodeFragment
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtTypeReference
import org.jetbrains.kotlin.types.KotlinType
val SUPPRESS_DIAGNOSTICS_IN_DEBUG_MODE: Key<Boolean> = Key.create<Boolean>("SUPPRESS_DIAGNOSTICS_IN_DEBUG_MODE")
fun KtElement.suppressDiagnosticsInDebugMode(): Boolean {
return if (this is KtFile) {
this.suppressDiagnosticsInDebugMode
}
else {
val file = this.containingFile
file is KtFile && file.suppressDiagnosticsInDebugMode
}
}
var KtFile.suppressDiagnosticsInDebugMode: Boolean
get() = when (this) {
is KtCodeFragment -> true
@@ -78,7 +78,9 @@ class CandidateResolver(
return
}
checkVisibility()
if (!context.isDebuggerContext) {
checkVisibility()
}
when (checkArguments) {
CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS ->
@@ -42,11 +42,12 @@ public class BasicCallResolutionContext extends CallResolutionContext<BasicCallR
@NotNull CallChecker callChecker,
@NotNull StatementFilter statementFilter,
boolean isAnnotationContext,
boolean isDebuggerContext,
boolean collectAllCandidates,
@NotNull CallPosition callPosition
) {
super(trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments, resolutionResultsCache,
dataFlowInfoForArguments, callChecker, statementFilter, isAnnotationContext, collectAllCandidates, callPosition);
dataFlowInfoForArguments, callChecker, statementFilter, isAnnotationContext, isDebuggerContext, collectAllCandidates, callPosition);
}
@NotNull
@@ -63,7 +64,7 @@ public class BasicCallResolutionContext extends CallResolutionContext<BasicCallR
) {
return new BasicCallResolutionContext(trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments,
new ResolutionResultsCacheImpl(), null,
callChecker, StatementFilter.NONE, isAnnotationContext, false,
callChecker, StatementFilter.NONE, isAnnotationContext, false, false,
CallPosition.Unknown.INSTANCE);
}
@@ -76,7 +77,7 @@ public class BasicCallResolutionContext extends CallResolutionContext<BasicCallR
context.trace, context.scope, call, context.expectedType, context.dataFlowInfo, context.contextDependency, checkArguments,
context.resolutionResultsCache, dataFlowInfoForArguments,
context.callChecker,
context.statementFilter, context.isAnnotationContext, context.collectAllCandidates, context.callPosition);
context.statementFilter, context.isAnnotationContext, context.isDebuggerContext, context.collectAllCandidates, context.callPosition);
}
@NotNull
@@ -100,14 +101,14 @@ public class BasicCallResolutionContext extends CallResolutionContext<BasicCallR
) {
return new BasicCallResolutionContext(
trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments, resolutionResultsCache,
dataFlowInfoForArguments, callChecker, statementFilter, isAnnotationContext, collectAllCandidates, callPosition);
dataFlowInfoForArguments, callChecker, statementFilter, isAnnotationContext, isDebuggerContext, collectAllCandidates, callPosition);
}
@NotNull
public BasicCallResolutionContext replaceCall(@NotNull Call newCall) {
return new BasicCallResolutionContext(
trace, scope, newCall, expectedType, dataFlowInfo, contextDependency, checkArguments, resolutionResultsCache,
dataFlowInfoForArguments, callChecker, statementFilter, isAnnotationContext, collectAllCandidates, callPosition);
dataFlowInfoForArguments, callChecker, statementFilter, isAnnotationContext, isDebuggerContext, collectAllCandidates, callPosition);
}
public void performContextDependentCallChecks(@NotNull ResolvedCall<?> resolvedCall) {
@@ -58,11 +58,12 @@ public final class CallCandidateResolutionContext<D extends CallableDescriptor>
@Nullable Receiver explicitExtensionReceiverForInvoke,
@NotNull CandidateResolveMode candidateResolveMode,
boolean isAnnotationContext,
boolean isDebuggerContext,
boolean collectAllCandidates,
@NotNull CallPosition callPosition
) {
super(trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments, resolutionResultsCache,
dataFlowInfoForArguments, callChecker, statementFilter, isAnnotationContext,
dataFlowInfoForArguments, callChecker, statementFilter, isAnnotationContext, isDebuggerContext,
collectAllCandidates, callPosition);
this.candidateCall = candidateCall;
this.tracing = tracing;
@@ -80,7 +81,7 @@ public final class CallCandidateResolutionContext<D extends CallableDescriptor>
context.dataFlowInfo, context.contextDependency, context.checkArguments,
context.resolutionResultsCache, context.dataFlowInfoForArguments,
context.callChecker, context.statementFilter, explicitExtensionReceiverForInvoke,
candidateResolveMode, context.isAnnotationContext, context.collectAllCandidates, context.callPosition);
candidateResolveMode, context.isAnnotationContext, context.isDebuggerContext, context.collectAllCandidates, context.callPosition);
}
@NotNull
@@ -91,7 +92,7 @@ public final class CallCandidateResolutionContext<D extends CallableDescriptor>
candidateCall, tracing, context.trace, context.scope, context.call, context.expectedType,
context.dataFlowInfo, context.contextDependency, context.checkArguments, context.resolutionResultsCache,
context.dataFlowInfoForArguments, context.callChecker, context.statementFilter,
null, CandidateResolveMode.FULLY, context.isAnnotationContext, context.collectAllCandidates,
null, CandidateResolveMode.FULLY, context.isAnnotationContext, context.isDebuggerContext, context.collectAllCandidates,
context.callPosition);
}
@@ -110,6 +111,6 @@ public final class CallCandidateResolutionContext<D extends CallableDescriptor>
return new CallCandidateResolutionContext<D>(
candidateCall, tracing, trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments,
resolutionResultsCache, dataFlowInfoForArguments, callChecker, statementFilter,
explicitExtensionReceiverForInvoke, candidateResolveMode, isAnnotationContext, collectAllCandidates, callPosition);
explicitExtensionReceiverForInvoke, candidateResolveMode, isAnnotationContext, isDebuggerContext, collectAllCandidates, callPosition);
}
}
@@ -50,11 +50,12 @@ public abstract class CallResolutionContext<Context extends CallResolutionContex
@NotNull CallChecker callChecker,
@NotNull StatementFilter statementFilter,
boolean isAnnotationContext,
boolean isDebuggerContext,
boolean collectAllCandidates,
@NotNull CallPosition callPosition
) {
super(trace, scope, expectedType, dataFlowInfo, contextDependency, resolutionResultsCache, callChecker,
statementFilter, isAnnotationContext, collectAllCandidates, callPosition);
statementFilter, isAnnotationContext, isDebuggerContext, collectAllCandidates, callPosition);
this.call = call;
this.checkArguments = checkArguments;
if (dataFlowInfoForArguments != null) {
@@ -52,6 +52,8 @@ public abstract class ResolutionContext<Context extends ResolutionContext<Contex
public final boolean isAnnotationContext;
public final boolean isDebuggerContext;
public final boolean collectAllCandidates;
@NotNull
@@ -67,6 +69,7 @@ public abstract class ResolutionContext<Context extends ResolutionContext<Contex
@NotNull CallChecker callChecker,
@NotNull StatementFilter statementFilter,
boolean isAnnotationContext,
boolean isDebuggerContext,
boolean collectAllCandidates,
@NotNull CallPosition callPosition
) {
@@ -79,6 +82,7 @@ public abstract class ResolutionContext<Context extends ResolutionContext<Contex
this.callChecker = callChecker;
this.statementFilter = statementFilter;
this.isAnnotationContext = isAnnotationContext;
this.isDebuggerContext = isDebuggerContext;
this.collectAllCandidates = collectAllCandidates;
this.callPosition = callPosition;
}
@@ -58,11 +58,12 @@ public class ResolutionTask<D extends CallableDescriptor, F extends D> extends C
@NotNull StatementFilter statementFilter,
@NotNull Collection<MutableResolvedCall<F>> resolvedCalls,
boolean isAnnotationContext,
boolean isDebuggerContext,
boolean collectAllCandidates,
@NotNull CallPosition callPosition
) {
super(trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments, resolutionResultsCache,
dataFlowInfoForArguments, callChecker, statementFilter, isAnnotationContext, collectAllCandidates, callPosition);
dataFlowInfoForArguments, callChecker, statementFilter, isAnnotationContext, isDebuggerContext, collectAllCandidates, callPosition);
this.lazyCandidates = lazyCandidates;
this.resolvedCalls = resolvedCalls;
this.tracing = tracing;
@@ -79,7 +80,7 @@ public class ResolutionTask<D extends CallableDescriptor, F extends D> extends C
context.resolutionResultsCache, context.dataFlowInfoForArguments,
context.callChecker,
context.statementFilter, new SmartList<MutableResolvedCall<F>>(),
context.isAnnotationContext, context.collectAllCandidates, context.callPosition);
context.isAnnotationContext, context.isDebuggerContext, context.collectAllCandidates, context.callPosition);
}
@NotNull
@@ -113,7 +114,7 @@ public class ResolutionTask<D extends CallableDescriptor, F extends D> extends C
resolutionResultsCache, dataFlowInfoForArguments,
callChecker,
statementFilter, resolvedCalls,
isAnnotationContext, collectAllCandidates, callPosition);
isAnnotationContext, isDebuggerContext, collectAllCandidates, callPosition);
}
@Override
@@ -21,13 +21,11 @@ import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
import org.jetbrains.kotlin.resolve.scopes.ImportingScope
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.resolve.scopes.utils.getImplicitReceiversHierarchy
import org.jetbrains.kotlin.resolve.scopes.utils.parentsWithSelf
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.containsError
import org.jetbrains.kotlin.utils.addToStdlib.check
@@ -51,6 +49,8 @@ internal class ScopeTowerImpl(
override val implicitReceivers = resolutionContext.scope.getImplicitReceiversHierarchy().
mapNotNull { it.value.check { !it.type.containsError() } }
val isDebuggerContext = resolutionContext.isDebuggerContext
}
private class DataFlowDecoratorImpl(private val resolutionContext: ResolutionContext<*>): DataFlowDecorator {
@@ -62,10 +62,13 @@ internal abstract class AbstractScopeTowerLevel(
if (descriptor.isSynthesized) diagnostics.add(SynthesizedDescriptorDiagnostic)
if (dispatchReceiverSmartCastType != null) diagnostics.add(UsedSmartCastForDispatchReceiver(dispatchReceiverSmartCastType))
Visibilities.findInvisibleMember(
dispatchReceiver, descriptor,
scopeTower.lexicalScope.ownerDescriptor
)?.let { diagnostics.add(VisibilityError(it)) }
val shouldSkipVisibilityCheck = scopeTower is ScopeTowerImpl && scopeTower.isDebuggerContext
if (!shouldSkipVisibilityCheck) {
Visibilities.findInvisibleMember(
dispatchReceiver, descriptor,
scopeTower.lexicalScope.ownerDescriptor
)?.let { diagnostics.add(VisibilityError(it)) }
}
}
return CandidateWithBoundDispatchReceiverImpl(dispatchReceiver, descriptor, diagnostics)
}
@@ -58,7 +58,18 @@ public class ExpressionTypingContext extends ResolutionContext<ExpressionTypingC
context.contextDependency, context.resolutionResultsCache,
context.callChecker,
context.statementFilter,
context.isAnnotationContext, context.collectAllCandidates,
context.isAnnotationContext, context.isDebuggerContext, context.collectAllCandidates,
context.callPosition);
}
@NotNull
public static ExpressionTypingContext newContext(@NotNull ResolutionContext context, boolean isDebuggerContext) {
return new ExpressionTypingContext(
context.trace, context.scope, context.dataFlowInfo, context.expectedType,
context.contextDependency, context.resolutionResultsCache,
context.callChecker,
context.statementFilter,
context.isAnnotationContext, isDebuggerContext, context.collectAllCandidates,
context.callPosition);
}
@@ -76,7 +87,7 @@ public class ExpressionTypingContext extends ResolutionContext<ExpressionTypingC
) {
return new ExpressionTypingContext(
trace, scope, dataFlowInfo, expectedType, contextDependency, resolutionResultsCache, callChecker,
statementFilter, isAnnotationContext, false, CallPosition.Unknown.INSTANCE);
statementFilter, isAnnotationContext, false, false, CallPosition.Unknown.INSTANCE);
}
private ExpressionTypingContext(
@@ -89,12 +100,13 @@ public class ExpressionTypingContext extends ResolutionContext<ExpressionTypingC
@NotNull CallChecker callChecker,
@NotNull StatementFilter statementFilter,
boolean isAnnotationContext,
boolean isDebuggerContext,
boolean collectAllCandidates,
@NotNull CallPosition callPosition
) {
super(trace, scope, expectedType, dataFlowInfo, contextDependency, resolutionResultsCache,
callChecker,
statementFilter, isAnnotationContext, collectAllCandidates, callPosition);
statementFilter, isAnnotationContext, isDebuggerContext, collectAllCandidates, callPosition);
}
@Override
@@ -112,6 +124,6 @@ public class ExpressionTypingContext extends ResolutionContext<ExpressionTypingC
return new ExpressionTypingContext(trace, scope, dataFlowInfo,
expectedType, contextDependency, resolutionResultsCache,
callChecker,
statementFilter, isAnnotationContext, collectAllCandidates, callPosition);
statementFilter, isAnnotationContext, isDebuggerContext, collectAllCandidates, callPosition);
}
}
@@ -25,7 +25,11 @@ 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.psi.codeFragmentUtil.CodeFragmentUtilKt;
import org.jetbrains.kotlin.resolve.AnnotationChecker;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.BindingContextUtils;
import org.jetbrains.kotlin.resolve.DeclarationsCheckerBuilder;
import org.jetbrains.kotlin.resolve.bindingContextUtil.BindingContextUtilsKt;
import org.jetbrains.kotlin.resolve.calls.context.CallPosition;
import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind;
@@ -144,8 +148,12 @@ public abstract class ExpressionTypingVisitorDispatcher extends KtVisitor<Kotlin
@Override
@NotNull
public final KotlinTypeInfo getTypeInfo(@NotNull KtExpression expression, ExpressionTypingContext context, boolean isStatement) {
if (!isStatement) return getTypeInfo(expression, context);
return getTypeInfo(expression, context, getStatementVisitor(context));
ExpressionTypingContext newContext = context;
if (CodeFragmentUtilKt.suppressDiagnosticsInDebugMode(expression)) {
newContext = ExpressionTypingContext.newContext(context, true);
}
if (!isStatement) return getTypeInfo(expression, newContext);
return getTypeInfo(expression, newContext, getStatementVisitor(newContext));
}
protected ExpressionTypingVisitorForStatements createStatementVisitor(ExpressionTypingContext context) {
@@ -29,10 +29,7 @@ class DiagnosticSuppressorForDebugger : DiagnosticSuppressor {
if (containingFile is KtFile && containingFile.suppressDiagnosticsInDebugMode) {
val diagnosticFactory = diagnostic.factory
return diagnosticFactory == Errors.INVISIBLE_MEMBER ||
diagnosticFactory == Errors.INVISIBLE_REFERENCE ||
diagnosticFactory == Errors.INVISIBLE_SETTER ||
diagnosticFactory == Errors.UNSAFE_CALL
return diagnosticFactory == Errors.UNSAFE_CALL
}
return false