Binding trace filtering: do not calculate diagnostics if no one is going to query them
This commit is contained in:
@@ -46,6 +46,7 @@ import org.jetbrains.kotlin.psi.KtFile
|
|||||||
import org.jetbrains.kotlin.psi.KtScript
|
import org.jetbrains.kotlin.psi.KtScript
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingTraceFilter
|
||||||
import org.jetbrains.kotlin.resolve.DelegatingBindingTrace
|
import org.jetbrains.kotlin.resolve.DelegatingBindingTrace
|
||||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||||
@@ -67,7 +68,8 @@ class GenerationState @JvmOverloads constructor(
|
|||||||
// partial compilation. Module chunks are treated as a single module.
|
// partial compilation. Module chunks are treated as a single module.
|
||||||
// TODO: get rid of it with the proper module infrastructure
|
// TODO: get rid of it with the proper module infrastructure
|
||||||
val outDirectory: File? = null,
|
val outDirectory: File? = null,
|
||||||
private val onIndependentPartCompilationEnd: GenerationStateEventCallback = GenerationStateEventCallback.DO_NOTHING
|
private val onIndependentPartCompilationEnd: GenerationStateEventCallback = GenerationStateEventCallback.DO_NOTHING,
|
||||||
|
wantsDiagnostics: Boolean = true
|
||||||
) {
|
) {
|
||||||
abstract class GenerateClassFilter {
|
abstract class GenerateClassFilter {
|
||||||
abstract fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject): Boolean
|
abstract fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject): Boolean
|
||||||
@@ -129,7 +131,8 @@ class GenerationState @JvmOverloads constructor(
|
|||||||
|
|
||||||
val moduleName: String = moduleName ?: JvmCodegenUtil.getModuleName(module)
|
val moduleName: String = moduleName ?: JvmCodegenUtil.getModuleName(module)
|
||||||
val classBuilderMode: ClassBuilderMode = builderFactory.classBuilderMode
|
val classBuilderMode: ClassBuilderMode = builderFactory.classBuilderMode
|
||||||
val bindingTrace: BindingTrace = DelegatingBindingTrace(bindingContext, "trace in GenerationState")
|
val bindingTrace: BindingTrace = DelegatingBindingTrace(bindingContext, "trace in GenerationState",
|
||||||
|
filter = if (wantsDiagnostics) BindingTraceFilter.ACCEPT_ALL else BindingTraceFilter.NO_DIAGNOSTICS)
|
||||||
val bindingContext: BindingContext = bindingTrace.bindingContext
|
val bindingContext: BindingContext = bindingTrace.bindingContext
|
||||||
val typeMapper: KotlinTypeMapper = KotlinTypeMapper(
|
val typeMapper: KotlinTypeMapper = KotlinTypeMapper(
|
||||||
this.bindingContext, classBuilderMode, fileClassesProvider, incrementalCacheForThisTarget,
|
this.bindingContext, classBuilderMode, fileClassesProvider, incrementalCacheForThisTarget,
|
||||||
|
|||||||
@@ -86,13 +86,17 @@ class ControlFlowInformationProvider private constructor(
|
|||||||
|
|
||||||
markUninitializedVariables()
|
markUninitializedVariables()
|
||||||
|
|
||||||
markUnusedVariables()
|
if (trace.wantsDiagnostics()) {
|
||||||
|
markUnusedVariables()
|
||||||
|
}
|
||||||
|
|
||||||
markStatements()
|
markStatements()
|
||||||
|
|
||||||
markUnusedExpressions()
|
markUnusedExpressions()
|
||||||
|
|
||||||
checkIfExpressions()
|
if (trace.wantsDiagnostics()) {
|
||||||
|
checkIfExpressions()
|
||||||
|
}
|
||||||
|
|
||||||
checkWhenExpressions()
|
checkWhenExpressions()
|
||||||
|
|
||||||
|
|||||||
@@ -82,6 +82,11 @@ public class PseudocodeUtil {
|
|||||||
@Override
|
@Override
|
||||||
public void report(@NotNull Diagnostic diagnostic) {
|
public void report(@NotNull Diagnostic diagnostic) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean wantsDiagnostics() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
return new ControlFlowProcessor(mockTrace).generatePseudocode(declaration);
|
return new ControlFlowProcessor(mockTrace).generatePseudocode(declaration);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,11 @@ public interface DiagnosticSink {
|
|||||||
@Override
|
@Override
|
||||||
public void report(@NotNull Diagnostic diagnostic) {
|
public void report(@NotNull Diagnostic diagnostic) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean wantsDiagnostics() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
DiagnosticSink THROW_EXCEPTION = new DiagnosticSink() {
|
DiagnosticSink THROW_EXCEPTION = new DiagnosticSink() {
|
||||||
@@ -42,7 +47,13 @@ public interface DiagnosticSink {
|
|||||||
throw new IllegalStateException(diagnostic.getFactory().getName() + ": " + diagnosticText + " " + DiagnosticUtils.atLocation(psiFile, textRanges.get(0)));
|
throw new IllegalStateException(diagnostic.getFactory().getName() + ": " + diagnosticText + " " + DiagnosticUtils.atLocation(psiFile, textRanges.get(0)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean wantsDiagnostics() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void report(@NotNull Diagnostic diagnostic);
|
void report(@NotNull Diagnostic diagnostic);
|
||||||
|
boolean wantsDiagnostics();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,14 +37,15 @@ public class BindingTraceContext implements BindingTrace {
|
|||||||
/* package */ final static boolean TRACK_WITH_STACK_TRACES = true;
|
/* package */ final static boolean TRACK_WITH_STACK_TRACES = true;
|
||||||
|
|
||||||
private final MutableSlicedMap map;
|
private final MutableSlicedMap map;
|
||||||
private final MutableDiagnosticsWithSuppression mutableDiagnostics;
|
@Nullable private final MutableDiagnosticsWithSuppression mutableDiagnostics;
|
||||||
|
@NotNull private final BindingTraceFilter filter;
|
||||||
|
|
||||||
private final BindingContext bindingContext = new BindingContext() {
|
private final BindingContext bindingContext = new BindingContext() {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Diagnostics getDiagnostics() {
|
public Diagnostics getDiagnostics() {
|
||||||
return mutableDiagnostics;
|
return mutableDiagnostics != null ? mutableDiagnostics : Diagnostics.Companion.getEMPTY();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -78,28 +79,45 @@ public class BindingTraceContext implements BindingTrace {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public BindingTraceContext() {
|
public BindingTraceContext() {
|
||||||
|
this(BindingTraceFilter.Companion.getACCEPT_ALL());
|
||||||
|
}
|
||||||
|
|
||||||
|
public BindingTraceContext(BindingTraceFilter filter) {
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
this(TRACK_REWRITES ? new TrackingSlicedMap(TRACK_WITH_STACK_TRACES) : SlicedMapImpl.create());
|
this(TRACK_REWRITES ? new TrackingSlicedMap(TRACK_WITH_STACK_TRACES) : SlicedMapImpl.create(), filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private BindingTraceContext(@NotNull MutableSlicedMap map) {
|
private BindingTraceContext(@NotNull MutableSlicedMap map, BindingTraceFilter filter) {
|
||||||
this.map = map;
|
this.map = map;
|
||||||
this.mutableDiagnostics = new MutableDiagnosticsWithSuppression(bindingContext, Diagnostics.Companion.getEMPTY());
|
this.mutableDiagnostics = !filter.getIgnoreDiagnostics()
|
||||||
|
? new MutableDiagnosticsWithSuppression(bindingContext, Diagnostics.Companion.getEMPTY())
|
||||||
|
: null;
|
||||||
|
this.filter = filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestOnly
|
@TestOnly
|
||||||
public static BindingTraceContext createTraceableBindingTrace() {
|
public static BindingTraceContext createTraceableBindingTrace() {
|
||||||
return new BindingTraceContext(new TrackingSlicedMap(TRACK_WITH_STACK_TRACES));
|
return new BindingTraceContext(new TrackingSlicedMap(TRACK_WITH_STACK_TRACES), BindingTraceFilter.Companion.getACCEPT_ALL());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void report(@NotNull Diagnostic diagnostic) {
|
public void report(@NotNull Diagnostic diagnostic) {
|
||||||
|
if (mutableDiagnostics == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
mutableDiagnostics.report(diagnostic);
|
mutableDiagnostics.report(diagnostic);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearDiagnostics() {
|
public void clearDiagnostics() {
|
||||||
mutableDiagnostics.clear();
|
if (mutableDiagnostics != null) {
|
||||||
|
mutableDiagnostics.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean wantsDiagnostics() {
|
||||||
|
return mutableDiagnostics != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 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
|
||||||
|
|
||||||
|
class BindingTraceFilter(val ignoreDiagnostics: Boolean) {
|
||||||
|
companion object {
|
||||||
|
val ACCEPT_ALL = BindingTraceFilter(false)
|
||||||
|
val NO_DIAGNOSTICS = BindingTraceFilter(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun includesEverythingIn(otherFilter: BindingTraceFilter): Boolean {
|
||||||
|
if (ignoreDiagnostics && !otherFilter.ignoreDiagnostics) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,12 +28,13 @@ import org.jetbrains.kotlin.util.slicedMap.*
|
|||||||
|
|
||||||
open class DelegatingBindingTrace(private val parentContext: BindingContext,
|
open class DelegatingBindingTrace(private val parentContext: BindingContext,
|
||||||
private val name: String,
|
private val name: String,
|
||||||
withParentDiagnostics: Boolean = true) : BindingTrace {
|
withParentDiagnostics: Boolean = true,
|
||||||
|
private val filter: BindingTraceFilter = BindingTraceFilter.ACCEPT_ALL) : BindingTrace {
|
||||||
private val map = if (BindingTraceContext.TRACK_REWRITES) TrackingSlicedMap(BindingTraceContext.TRACK_WITH_STACK_TRACES) else SlicedMapImpl.create()
|
private val map = if (BindingTraceContext.TRACK_REWRITES) TrackingSlicedMap(BindingTraceContext.TRACK_WITH_STACK_TRACES) else SlicedMapImpl.create()
|
||||||
private val mutableDiagnostics: MutableDiagnosticsWithSuppression
|
private val mutableDiagnostics: MutableDiagnosticsWithSuppression?
|
||||||
|
|
||||||
private inner class MyBindingContext : BindingContext {
|
private inner class MyBindingContext : BindingContext {
|
||||||
override fun getDiagnostics(): Diagnostics = mutableDiagnostics
|
override fun getDiagnostics(): Diagnostics = mutableDiagnostics ?: Diagnostics.EMPTY
|
||||||
|
|
||||||
override fun <K, V> get(slice: ReadOnlySlice<K, V>, key: K): V? {
|
override fun <K, V> get(slice: ReadOnlySlice<K, V>, key: K): V? {
|
||||||
return this@DelegatingBindingTrace.get(slice, key)
|
return this@DelegatingBindingTrace.get(slice, key)
|
||||||
@@ -60,7 +61,9 @@ open class DelegatingBindingTrace(private val parentContext: BindingContext,
|
|||||||
private val bindingContext = MyBindingContext()
|
private val bindingContext = MyBindingContext()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
this.mutableDiagnostics = if (withParentDiagnostics)
|
this.mutableDiagnostics = if (filter.ignoreDiagnostics)
|
||||||
|
null
|
||||||
|
else if (withParentDiagnostics)
|
||||||
MutableDiagnosticsWithSuppression(bindingContext, parentContext.diagnostics)
|
MutableDiagnosticsWithSuppression(bindingContext, parentContext.diagnostics)
|
||||||
else
|
else
|
||||||
MutableDiagnosticsWithSuppression(bindingContext)
|
MutableDiagnosticsWithSuppression(bindingContext)
|
||||||
@@ -68,7 +71,11 @@ open class DelegatingBindingTrace(private val parentContext: BindingContext,
|
|||||||
|
|
||||||
constructor(parentContext: BindingContext,
|
constructor(parentContext: BindingContext,
|
||||||
debugName: String,
|
debugName: String,
|
||||||
resolutionSubjectForMessage: Any?) : this(parentContext, AnalyzingUtils.formDebugNameForBindingTrace(debugName, resolutionSubjectForMessage)) {
|
resolutionSubjectForMessage: Any?,
|
||||||
|
filter: BindingTraceFilter = BindingTraceFilter.ACCEPT_ALL)
|
||||||
|
: this(parentContext,
|
||||||
|
AnalyzingUtils.formDebugNameForBindingTrace(debugName, resolutionSubjectForMessage),
|
||||||
|
filter = filter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getBindingContext(): BindingContext = bindingContext
|
override fun getBindingContext(): BindingContext = bindingContext
|
||||||
@@ -130,12 +137,17 @@ open class DelegatingBindingTrace(private val parentContext: BindingContext,
|
|||||||
|
|
||||||
fun clear() {
|
fun clear() {
|
||||||
map.clear()
|
map.clear()
|
||||||
mutableDiagnostics.clear()
|
mutableDiagnostics?.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun report(diagnostic: Diagnostic) {
|
override fun report(diagnostic: Diagnostic) {
|
||||||
|
if (mutableDiagnostics == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
mutableDiagnostics.report(diagnostic)
|
mutableDiagnostics.report(diagnostic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun wantsDiagnostics(): Boolean = mutableDiagnostics != null
|
||||||
|
|
||||||
override fun toString(): String = name
|
override fun toString(): String = name
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,4 +92,8 @@ public class ObservableBindingTrace implements BindingTrace {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean wantsDiagnostics() {
|
||||||
|
return originalTrace.wantsDiagnostics();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,12 @@ public class TemporaryBindingTrace extends DelegatingBindingTrace {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static TemporaryBindingTrace create(@NotNull BindingTrace trace, String debugName) {
|
public static TemporaryBindingTrace create(@NotNull BindingTrace trace, String debugName) {
|
||||||
return new TemporaryBindingTrace(trace, debugName);
|
return create(trace, debugName, BindingTraceFilter.Companion.getACCEPT_ALL());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static TemporaryBindingTrace create(@NotNull BindingTrace trace, String debugName, BindingTraceFilter filter) {
|
||||||
|
return new TemporaryBindingTrace(trace, debugName, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -33,8 +38,8 @@ public class TemporaryBindingTrace extends DelegatingBindingTrace {
|
|||||||
|
|
||||||
protected final BindingTrace trace;
|
protected final BindingTrace trace;
|
||||||
|
|
||||||
protected TemporaryBindingTrace(@NotNull BindingTrace trace, String debugName) {
|
protected TemporaryBindingTrace(@NotNull BindingTrace trace, String debugName, BindingTraceFilter filter) {
|
||||||
super(trace.getBindingContext(), debugName, true);
|
super(trace.getBindingContext(), debugName, true, filter);
|
||||||
this.trace = trace;
|
this.trace = trace;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,4 +52,9 @@ public class TemporaryBindingTrace extends DelegatingBindingTrace {
|
|||||||
addOwnDataTo(trace, filter, commitDiagnostics);
|
addOwnDataTo(trace, filter, commitDiagnostics);
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean wantsDiagnostics() {
|
||||||
|
return trace.wantsDiagnostics();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,9 +94,11 @@ class CallCompleter(
|
|||||||
if (calleeExpression != null && !calleeExpression.isFakeElement) calleeExpression
|
if (calleeExpression != null && !calleeExpression.isFakeElement) calleeExpression
|
||||||
else resolvedCall.call.callElement
|
else resolvedCall.call.callElement
|
||||||
|
|
||||||
val callCheckerContext = CallCheckerContext(context, languageVersionSettings)
|
if (context.trace.wantsDiagnostics()) {
|
||||||
for (callChecker in callCheckers) {
|
val callCheckerContext = CallCheckerContext(context, languageVersionSettings)
|
||||||
callChecker.check(resolvedCall, reportOn, callCheckerContext)
|
for (callChecker in callCheckers) {
|
||||||
|
callChecker.check(resolvedCall, reportOn, callCheckerContext)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resolveHandleResultCallForCoroutineLambdaExpressions(context, resolvedCall)
|
resolveHandleResultCallForCoroutineLambdaExpressions(context, resolvedCall)
|
||||||
|
|||||||
@@ -563,7 +563,7 @@ public class CallResolver {
|
|||||||
if (CallResolverUtilKt.isInvokeCallOnVariable(call)) return;
|
if (CallResolverUtilKt.isInvokeCallOnVariable(call)) return;
|
||||||
|
|
||||||
DelegatingBindingTrace deltasTraceToCacheResolve = new DelegatingBindingTrace(
|
DelegatingBindingTrace deltasTraceToCacheResolve = new DelegatingBindingTrace(
|
||||||
BindingContext.EMPTY, "delta trace for caching resolve of", context.call);
|
BindingContext.EMPTY, "delta trace for caching resolve of", context.call, BindingTraceFilter.Companion.getACCEPT_ALL());
|
||||||
traceToResolveCall.addOwnDataTo(deltasTraceToCacheResolve);
|
traceToResolveCall.addOwnDataTo(deltasTraceToCacheResolve);
|
||||||
|
|
||||||
context.resolutionResultsCache.record(call, results, context, tracing, deltasTraceToCacheResolve);
|
context.resolutionResultsCache.record(call, results, context, tracing, deltasTraceToCacheResolve);
|
||||||
|
|||||||
+4
-2
@@ -37,7 +37,7 @@ class MutableDiagnosticsWithSuppression @JvmOverloads constructor(
|
|||||||
CachedValueProvider.Result(DiagnosticsWithSuppression(bindingContext, allDiagnostics), modificationTracker)
|
CachedValueProvider.Result(DiagnosticsWithSuppression(bindingContext, allDiagnostics), modificationTracker)
|
||||||
})
|
})
|
||||||
|
|
||||||
private fun readonlyView() = cache.value!!
|
private fun readonlyView(): DiagnosticsWithSuppression = cache.value!!
|
||||||
|
|
||||||
override val modificationTracker = CompositeModificationTracker(delegateDiagnostics.modificationTracker)
|
override val modificationTracker = CompositeModificationTracker(delegateDiagnostics.modificationTracker)
|
||||||
|
|
||||||
@@ -46,7 +46,9 @@ class MutableDiagnosticsWithSuppression @JvmOverloads constructor(
|
|||||||
override fun noSuppression() = readonlyView().noSuppression()
|
override fun noSuppression() = readonlyView().noSuppression()
|
||||||
|
|
||||||
//essential that this list is readonly
|
//essential that this list is readonly
|
||||||
fun getOwnDiagnostics(): List<Diagnostic> = diagnosticList
|
fun getOwnDiagnostics(): List<Diagnostic> {
|
||||||
|
return diagnosticList
|
||||||
|
}
|
||||||
|
|
||||||
fun report(diagnostic: Diagnostic) {
|
fun report(diagnostic: Diagnostic) {
|
||||||
diagnosticList.add(diagnostic)
|
diagnosticList.add(diagnostic)
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class FileScopeFactory(
|
|||||||
|
|
||||||
fun createScopesForFile(file: KtFile, existingImports: ImportingScope? = null): FileScopes {
|
fun createScopesForFile(file: KtFile, existingImports: ImportingScope? = null): FileScopes {
|
||||||
val debugName = "LazyFileScope for file " + file.name
|
val debugName = "LazyFileScope for file " + file.name
|
||||||
val tempTrace = TemporaryBindingTrace.create(bindingTrace, "Transient trace for default imports lazy resolve")
|
val tempTrace = TemporaryBindingTrace.create(bindingTrace, "Transient trace for default imports lazy resolve", false)
|
||||||
|
|
||||||
infix fun <T> Collection<T>.concat(other: Collection<T>?) =
|
infix fun <T> Collection<T>.concat(other: Collection<T>?) =
|
||||||
if (other == null || other.isEmpty()) this else this + other
|
if (other == null || other.isEmpty()) this else this + other
|
||||||
|
|||||||
+2
@@ -81,5 +81,7 @@ class LockBasedLazyResolveStorageManager(private val storageManager: StorageMana
|
|||||||
override fun report(diagnostic: Diagnostic) {
|
override fun report(diagnostic: Diagnostic) {
|
||||||
storageManager.compute { trace.report(diagnostic) }
|
storageManager.compute { trace.report(diagnostic) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun wantsDiagnostics() = trace.wantsDiagnostics()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-7
@@ -609,9 +609,11 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
trace.record(RESOLVED_CALL, call, resolvedCall);
|
trace.record(RESOLVED_CALL, call, resolvedCall);
|
||||||
trace.record(CALL, expression, call);
|
trace.record(CALL, expression, call);
|
||||||
|
|
||||||
CallCheckerContext callCheckerContext = new CallCheckerContext(context, components.languageVersionSettings);
|
if (context.trace.wantsDiagnostics()) {
|
||||||
for (CallChecker checker : components.callCheckers) {
|
CallCheckerContext callCheckerContext = new CallCheckerContext(context, components.languageVersionSettings);
|
||||||
checker.check(resolvedCall, expression, callCheckerContext);
|
for (CallChecker checker : components.callCheckers) {
|
||||||
|
checker.check(resolvedCall, expression, callCheckerContext);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -910,7 +912,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
if (KtTokens.AUGMENTED_ASSIGNMENTS.contains(operationType)
|
if (KtTokens.AUGMENTED_ASSIGNMENTS.contains(operationType)
|
||||||
|| operationType == KtTokens.PLUSPLUS || operationType == KtTokens.MINUSMINUS) {
|
|| operationType == KtTokens.PLUSPLUS || operationType == KtTokens.MINUSMINUS) {
|
||||||
ResolvedCall<?> resolvedCall = ignoreReportsTrace.get(INDEXED_LVALUE_SET, expression);
|
ResolvedCall<?> resolvedCall = ignoreReportsTrace.get(INDEXED_LVALUE_SET, expression);
|
||||||
if (resolvedCall != null) {
|
if (resolvedCall != null && trace.wantsDiagnostics()) {
|
||||||
// Call must be validated with the actual, not temporary trace in order to report operator diagnostic
|
// Call must be validated with the actual, not temporary trace in order to report operator diagnostic
|
||||||
// Only unary assignment expressions (++, --) and +=/... must be checked, normal assignments have the proper trace
|
// Only unary assignment expressions (++, --) and +=/... must be checked, normal assignments have the proper trace
|
||||||
CallCheckerContext callCheckerContext = new CallCheckerContext(context, trace, components.languageVersionSettings);
|
CallCheckerContext callCheckerContext = new CallCheckerContext(context, trace, components.languageVersionSettings);
|
||||||
@@ -979,9 +981,11 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
);
|
);
|
||||||
resolvedCall.markCallAsCompleted();
|
resolvedCall.markCallAsCompleted();
|
||||||
|
|
||||||
CallCheckerContext callCheckerContext = new CallCheckerContext(context, components.languageVersionSettings);
|
if (context.trace.wantsDiagnostics()) {
|
||||||
for (CallChecker checker : components.callCheckers) {
|
CallCheckerContext callCheckerContext = new CallCheckerContext(context, components.languageVersionSettings);
|
||||||
checker.check(resolvedCall, expression, callCheckerContext);
|
for (CallChecker checker : components.callCheckers) {
|
||||||
|
checker.check(resolvedCall, expression, callCheckerContext);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -99,7 +99,8 @@ abstract class LightClassDataProvider<T : WithFileStubAndExtraDiagnostics>(
|
|||||||
context.bindingContext,
|
context.bindingContext,
|
||||||
files.toMutableList(),
|
files.toMutableList(),
|
||||||
CompilerConfiguration.EMPTY,
|
CompilerConfiguration.EMPTY,
|
||||||
generateClassFilter
|
generateClassFilter,
|
||||||
|
wantsDiagnostics = false
|
||||||
)
|
)
|
||||||
state.beforeCompile()
|
state.beforeCompile()
|
||||||
|
|
||||||
|
|||||||
@@ -196,6 +196,11 @@ public class KotlinTestUtils {
|
|||||||
throw new IllegalStateException("Unresolved: " + diagnostic.getPsiElement().getText());
|
throw new IllegalStateException("Unresolved: " + diagnostic.getPsiElement().getText());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean wantsDiagnostics() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static BindingTrace DUMMY_EXCEPTION_ON_ERROR_TRACE = new BindingTrace() {
|
public static BindingTrace DUMMY_EXCEPTION_ON_ERROR_TRACE = new BindingTrace() {
|
||||||
@@ -276,6 +281,11 @@ public class KotlinTestUtils {
|
|||||||
throw new IllegalStateException(DefaultErrorMessages.render(diagnostic));
|
throw new IllegalStateException(DefaultErrorMessages.render(diagnostic));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean wantsDiagnostics() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// We suspect sequences of eight consecutive hexadecimal digits to be a package part hash code
|
// We suspect sequences of eight consecutive hexadecimal digits to be a package part hash code
|
||||||
|
|||||||
@@ -16,8 +16,21 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.lazy
|
package org.jetbrains.kotlin.resolve.lazy
|
||||||
|
|
||||||
enum class BodyResolveMode {
|
import org.jetbrains.kotlin.resolve.BindingTraceFilter
|
||||||
FULL,
|
|
||||||
PARTIAL,
|
open class BodyResolveMode {
|
||||||
PARTIAL_FOR_COMPLETION
|
open val bindingTraceFilter: BindingTraceFilter = BindingTraceFilter.ACCEPT_ALL
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmField val FULL = BodyResolveMode()
|
||||||
|
|
||||||
|
@JvmField val PARTIAL = object : BodyResolveMode() {
|
||||||
|
override val bindingTraceFilter: BindingTraceFilter
|
||||||
|
get() = BindingTraceFilter.NO_DIAGNOSTICS
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmField val PARTIAL_WITH_DIAGNOSTICS = BodyResolveMode()
|
||||||
|
|
||||||
|
@JvmField val PARTIAL_FOR_COMPLETION = BodyResolveMode()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,10 +83,11 @@ class ResolveElementCache(
|
|||||||
},
|
},
|
||||||
false)
|
false)
|
||||||
|
|
||||||
private class CachedPartialResolve(val bindingContext: BindingContext, file: KtFile) {
|
private class CachedPartialResolve(val bindingContext: BindingContext, file: KtFile, val filter: BindingTraceFilter) {
|
||||||
private val modificationStamp: Long? = modificationStamp(file)
|
private val modificationStamp: Long? = modificationStamp(file)
|
||||||
|
|
||||||
fun isUpToDate(file: KtFile) = modificationStamp == modificationStamp(file)
|
fun isUpToDate(file: KtFile, newFilter: BindingTraceFilter) =
|
||||||
|
modificationStamp == modificationStamp(file) && filter.includesEverythingIn(newFilter)
|
||||||
|
|
||||||
private fun modificationStamp(file: KtFile): Long? {
|
private fun modificationStamp(file: KtFile): Long? {
|
||||||
return if (!file.isPhysical) // for non-physical file we don't get MODIFICATION_COUNT increased and must reset data on any modification of the file
|
return if (!file.isPhysical) // for non-physical file we don't get MODIFICATION_COUNT increased and must reset data on any modification of the file
|
||||||
@@ -117,7 +118,7 @@ class ResolveElementCache(
|
|||||||
= getElementsAdditionalResolve(function, null, BodyResolveMode.FULL)
|
= getElementsAdditionalResolve(function, null, BodyResolveMode.FULL)
|
||||||
|
|
||||||
fun resolvePrimaryConstructorParametersDefaultValues(ktClass: KtClass): BindingContext {
|
fun resolvePrimaryConstructorParametersDefaultValues(ktClass: KtClass): BindingContext {
|
||||||
return constructorAdditionalResolve(resolveSession, ktClass, ktClass.getContainingKtFile()).bindingContext
|
return constructorAdditionalResolve(resolveSession, ktClass, ktClass.getContainingKtFile(), BindingTraceFilter.NO_DIAGNOSTICS).bindingContext
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated("Use getElementsAdditionalResolve")
|
@Deprecated("Use getElementsAdditionalResolve")
|
||||||
@@ -149,7 +150,16 @@ class ResolveElementCache(
|
|||||||
return bindingContext
|
return bindingContext
|
||||||
}
|
}
|
||||||
|
|
||||||
BodyResolveMode.PARTIAL -> {
|
BodyResolveMode.PARTIAL_FOR_COMPLETION -> {
|
||||||
|
if (resolveElement !is KtDeclaration) {
|
||||||
|
return getElementsAdditionalResolve(resolveElement, null, BodyResolveMode.FULL)
|
||||||
|
}
|
||||||
|
|
||||||
|
// not cached
|
||||||
|
return performElementAdditionalResolve(resolveElement, contextElements, bodyResolveMode).first
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
if (resolveElement !is KtDeclaration) {
|
if (resolveElement !is KtDeclaration) {
|
||||||
return getElementsAdditionalResolve(resolveElement, null, BodyResolveMode.FULL)
|
return getElementsAdditionalResolve(resolveElement, null, BodyResolveMode.FULL)
|
||||||
}
|
}
|
||||||
@@ -158,18 +168,18 @@ class ResolveElementCache(
|
|||||||
val statementsToResolve = contextElements!!.map { PartialBodyResolveFilter.findStatementToResolve(it, resolveElement) }.distinct()
|
val statementsToResolve = contextElements!!.map { PartialBodyResolveFilter.findStatementToResolve(it, resolveElement) }.distinct()
|
||||||
val partialResolveMap = partialBodyResolveCache.value
|
val partialResolveMap = partialBodyResolveCache.value
|
||||||
val cachedResults = statementsToResolve.map { partialResolveMap[it ?: resolveElement] }
|
val cachedResults = statementsToResolve.map { partialResolveMap[it ?: resolveElement] }
|
||||||
if (cachedResults.all { it != null && it.isUpToDate(file) }) { // partial resolve is already cached for these statements
|
if (cachedResults.all { it != null && it.isUpToDate(file, bodyResolveMode.bindingTraceFilter) }) { // partial resolve is already cached for these statements
|
||||||
return CompositeBindingContext.create(cachedResults.map { it!!.bindingContext }.distinct())
|
return CompositeBindingContext.create(cachedResults.map { it!!.bindingContext }.distinct())
|
||||||
}
|
}
|
||||||
|
|
||||||
val (bindingContext, statementFilter) = performElementAdditionalResolve(resolveElement, contextElements, BodyResolveMode.PARTIAL)
|
val (bindingContext, statementFilter) = performElementAdditionalResolve(resolveElement, contextElements, bodyResolveMode)
|
||||||
|
|
||||||
if (statementFilter == StatementFilter.NONE) { // partial resolve is not supported for the given declaration - full resolve performed instead
|
if (statementFilter == StatementFilter.NONE) { // partial resolve is not supported for the given declaration - full resolve performed instead
|
||||||
fullResolveMap[resolveElement] = CachedFullResolve(bindingContext, resolveElement)
|
fullResolveMap[resolveElement] = CachedFullResolve(bindingContext, resolveElement)
|
||||||
return bindingContext
|
return bindingContext
|
||||||
}
|
}
|
||||||
|
|
||||||
val resolveToCache = CachedPartialResolve(bindingContext, file)
|
val resolveToCache = CachedPartialResolve(bindingContext, file, bodyResolveMode.bindingTraceFilter)
|
||||||
|
|
||||||
for (statement in (statementFilter as PartialBodyResolveFilter).allStatementsToResolve) {
|
for (statement in (statementFilter as PartialBodyResolveFilter).allStatementsToResolve) {
|
||||||
if (!partialResolveMap.containsKey(statement) && bindingContext[BindingContext.PROCESSED, statement] == true) {
|
if (!partialResolveMap.containsKey(statement) && bindingContext[BindingContext.PROCESSED, statement] == true) {
|
||||||
@@ -182,15 +192,6 @@ class ResolveElementCache(
|
|||||||
|
|
||||||
return bindingContext
|
return bindingContext
|
||||||
}
|
}
|
||||||
|
|
||||||
BodyResolveMode.PARTIAL_FOR_COMPLETION -> {
|
|
||||||
if (resolveElement !is KtDeclaration) {
|
|
||||||
return getElementsAdditionalResolve(resolveElement, null, BodyResolveMode.FULL)
|
|
||||||
}
|
|
||||||
|
|
||||||
// not cached
|
|
||||||
return performElementAdditionalResolve(resolveElement, contextElements, bodyResolveMode).first
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,17 +312,17 @@ class ResolveElementCache(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val trace: BindingTrace = when (resolveElement) {
|
val trace: BindingTrace = when (resolveElement) {
|
||||||
is KtNamedFunction -> functionAdditionalResolve(resolveSession, resolveElement, file, createStatementFilter())
|
is KtNamedFunction -> functionAdditionalResolve(resolveSession, resolveElement, file, createStatementFilter(), bodyResolveMode.bindingTraceFilter)
|
||||||
|
|
||||||
is KtAnonymousInitializer -> initializerAdditionalResolve(resolveSession, resolveElement, file, createStatementFilter())
|
is KtAnonymousInitializer -> initializerAdditionalResolve(resolveSession, resolveElement, file, createStatementFilter(), bodyResolveMode.bindingTraceFilter)
|
||||||
|
|
||||||
is KtSecondaryConstructor -> secondaryConstructorAdditionalResolve(resolveSession, resolveElement, file, createStatementFilter())
|
is KtSecondaryConstructor -> secondaryConstructorAdditionalResolve(resolveSession, resolveElement, file, createStatementFilter(), bodyResolveMode.bindingTraceFilter)
|
||||||
|
|
||||||
is KtProperty -> propertyAdditionalResolve(resolveSession, resolveElement, file, createStatementFilter())
|
is KtProperty -> propertyAdditionalResolve(resolveSession, resolveElement, file, createStatementFilter(), bodyResolveMode.bindingTraceFilter)
|
||||||
|
|
||||||
is KtSuperTypeList -> delegationSpecifierAdditionalResolve(resolveSession, resolveElement, resolveElement.getParent() as KtClassOrObject, file)
|
is KtSuperTypeList -> delegationSpecifierAdditionalResolve(resolveSession, resolveElement, resolveElement.getParent() as KtClassOrObject, file, bodyResolveMode.bindingTraceFilter)
|
||||||
|
|
||||||
is KtInitializerList -> delegationSpecifierAdditionalResolve(resolveSession, resolveElement, resolveElement.getParent() as KtEnumEntry, file)
|
is KtInitializerList -> delegationSpecifierAdditionalResolve(resolveSession, resolveElement, resolveElement.getParent() as KtEnumEntry, file, bodyResolveMode.bindingTraceFilter)
|
||||||
|
|
||||||
is KtImportList -> {
|
is KtImportList -> {
|
||||||
val resolver = resolveSession.fileScopeProvider.getImportResolver(resolveElement.getContainingKtFile())
|
val resolver = resolveSession.fileScopeProvider.getImportResolver(resolveElement.getContainingKtFile())
|
||||||
@@ -341,9 +342,9 @@ class ResolveElementCache(
|
|||||||
|
|
||||||
is KtAnnotationEntry -> annotationAdditionalResolve(resolveSession, resolveElement)
|
is KtAnnotationEntry -> annotationAdditionalResolve(resolveSession, resolveElement)
|
||||||
|
|
||||||
is KtClass -> constructorAdditionalResolve(resolveSession, resolveElement, file)
|
is KtClass -> constructorAdditionalResolve(resolveSession, resolveElement, file, bodyResolveMode.bindingTraceFilter)
|
||||||
|
|
||||||
is KtTypeAlias -> typealiasAdditionalResolve(resolveSession, resolveElement)
|
is KtTypeAlias -> typealiasAdditionalResolve(resolveSession, resolveElement, bodyResolveMode.bindingTraceFilter)
|
||||||
|
|
||||||
is KtTypeParameter -> typeParameterAdditionalResolve(resolveSession, resolveElement)
|
is KtTypeParameter -> typeParameterAdditionalResolve(resolveSession, resolveElement)
|
||||||
|
|
||||||
@@ -353,7 +354,7 @@ class ResolveElementCache(
|
|||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
if (resolveElement.getParentOfType<KtPackageDirective>(true) != null) {
|
if (resolveElement.getParentOfType<KtPackageDirective>(true) != null) {
|
||||||
packageRefAdditionalResolve(resolveSession, resolveElement)
|
packageRefAdditionalResolve(resolveSession, resolveElement, bodyResolveMode.bindingTraceFilter)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
error("Invalid type of the topmost parent: $resolveElement\n${resolveElement.getElementTextWithContext()}")
|
error("Invalid type of the topmost parent: $resolveElement\n${resolveElement.getElementTextWithContext()}")
|
||||||
@@ -368,8 +369,9 @@ class ResolveElementCache(
|
|||||||
return Pair(trace.bindingContext, statementFilterUsed)
|
return Pair(trace.bindingContext, statementFilterUsed)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun packageRefAdditionalResolve(resolveSession: ResolveSession, ktElement: KtElement): BindingTrace {
|
private fun packageRefAdditionalResolve(resolveSession: ResolveSession, ktElement: KtElement,
|
||||||
val trace = createDelegatingTrace(ktElement)
|
bindingTraceFilter: BindingTraceFilter): BindingTrace {
|
||||||
|
val trace = createDelegatingTrace(ktElement, bindingTraceFilter)
|
||||||
|
|
||||||
if (ktElement is KtSimpleNameExpression) {
|
if (ktElement is KtSimpleNameExpression) {
|
||||||
val header = ktElement.getParentOfType<KtPackageDirective>(true)!!
|
val header = ktElement.getParentOfType<KtPackageDirective>(true)!!
|
||||||
@@ -398,7 +400,7 @@ class ResolveElementCache(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun codeFragmentAdditionalResolve(codeFragment: KtCodeFragment, bodyResolveMode: BodyResolveMode): BindingTrace {
|
private fun codeFragmentAdditionalResolve(codeFragment: KtCodeFragment, bodyResolveMode: BodyResolveMode): BindingTrace {
|
||||||
val trace = createDelegatingTrace(codeFragment)
|
val trace = createDelegatingTrace(codeFragment, bodyResolveMode.bindingTraceFilter)
|
||||||
|
|
||||||
val contextResolveMode = if (bodyResolveMode == BodyResolveMode.PARTIAL)
|
val contextResolveMode = if (bodyResolveMode == BodyResolveMode.PARTIAL)
|
||||||
BodyResolveMode.PARTIAL_FOR_COMPLETION
|
BodyResolveMode.PARTIAL_FOR_COMPLETION
|
||||||
@@ -456,8 +458,9 @@ class ResolveElementCache(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun delegationSpecifierAdditionalResolve(resolveSession: ResolveSession, ktElement: KtElement,
|
private fun delegationSpecifierAdditionalResolve(resolveSession: ResolveSession, ktElement: KtElement,
|
||||||
classOrObject: KtClassOrObject, file: KtFile): BindingTrace {
|
classOrObject: KtClassOrObject, file: KtFile,
|
||||||
val trace = createDelegatingTrace(ktElement)
|
bindingTraceFilter: BindingTraceFilter): BindingTrace {
|
||||||
|
val trace = createDelegatingTrace(ktElement, bindingTraceFilter)
|
||||||
val descriptor = resolveSession.resolveToDescriptor(classOrObject) as LazyClassDescriptor
|
val descriptor = resolveSession.resolveToDescriptor(classOrObject) as LazyClassDescriptor
|
||||||
|
|
||||||
// Activate resolving of supertypes
|
// Activate resolving of supertypes
|
||||||
@@ -475,8 +478,10 @@ class ResolveElementCache(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun propertyAdditionalResolve(resolveSession: ResolveSession, property: KtProperty,
|
private fun propertyAdditionalResolve(resolveSession: ResolveSession, property: KtProperty,
|
||||||
file: KtFile, statementFilter: StatementFilter): BindingTrace {
|
file: KtFile,
|
||||||
val trace = createDelegatingTrace(property)
|
statementFilter: StatementFilter,
|
||||||
|
bindingTraceFilter: BindingTraceFilter): BindingTrace {
|
||||||
|
val trace = createDelegatingTrace(property, bindingTraceFilter)
|
||||||
|
|
||||||
val bodyResolver = createBodyResolver(resolveSession, trace, file, statementFilter)
|
val bodyResolver = createBodyResolver(resolveSession, trace, file, statementFilter)
|
||||||
val descriptor = resolveSession.resolveToDescriptor(property) as PropertyDescriptor
|
val descriptor = resolveSession.resolveToDescriptor(property) as PropertyDescriptor
|
||||||
@@ -501,8 +506,9 @@ class ResolveElementCache(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun functionAdditionalResolve(resolveSession: ResolveSession, namedFunction: KtNamedFunction, file: KtFile,
|
private fun functionAdditionalResolve(resolveSession: ResolveSession, namedFunction: KtNamedFunction, file: KtFile,
|
||||||
statementFilter: StatementFilter): BindingTrace {
|
statementFilter: StatementFilter,
|
||||||
val trace = createDelegatingTrace(namedFunction)
|
bindingTraceFilter: BindingTraceFilter): BindingTrace {
|
||||||
|
val trace = createDelegatingTrace(namedFunction, bindingTraceFilter)
|
||||||
|
|
||||||
val scope = resolveSession.declarationScopeProvider.getResolutionScopeForDeclaration(namedFunction)
|
val scope = resolveSession.declarationScopeProvider.getResolutionScopeForDeclaration(namedFunction)
|
||||||
val functionDescriptor = resolveSession.resolveToDescriptor(namedFunction) as FunctionDescriptor
|
val functionDescriptor = resolveSession.resolveToDescriptor(namedFunction) as FunctionDescriptor
|
||||||
@@ -517,8 +523,9 @@ class ResolveElementCache(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun secondaryConstructorAdditionalResolve(resolveSession: ResolveSession, constructor: KtSecondaryConstructor,
|
private fun secondaryConstructorAdditionalResolve(resolveSession: ResolveSession, constructor: KtSecondaryConstructor,
|
||||||
file: KtFile, statementFilter: StatementFilter): BindingTrace {
|
file: KtFile, statementFilter: StatementFilter,
|
||||||
val trace = createDelegatingTrace(constructor)
|
bindingTraceFilter: BindingTraceFilter): BindingTrace {
|
||||||
|
val trace = createDelegatingTrace(constructor, bindingTraceFilter)
|
||||||
|
|
||||||
val scope = resolveSession.declarationScopeProvider.getResolutionScopeForDeclaration(constructor)
|
val scope = resolveSession.declarationScopeProvider.getResolutionScopeForDeclaration(constructor)
|
||||||
val constructorDescriptor = resolveSession.resolveToDescriptor(constructor) as ClassConstructorDescriptor
|
val constructorDescriptor = resolveSession.resolveToDescriptor(constructor) as ClassConstructorDescriptor
|
||||||
@@ -532,8 +539,8 @@ class ResolveElementCache(
|
|||||||
return trace
|
return trace
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun constructorAdditionalResolve(resolveSession: ResolveSession, klass: KtClass, file: KtFile): BindingTrace {
|
private fun constructorAdditionalResolve(resolveSession: ResolveSession, klass: KtClass, file: KtFile, filter : BindingTraceFilter): BindingTrace {
|
||||||
val trace = createDelegatingTrace(klass)
|
val trace = createDelegatingTrace(klass, filter)
|
||||||
val scope = resolveSession.declarationScopeProvider.getResolutionScopeForDeclaration(klass)
|
val scope = resolveSession.declarationScopeProvider.getResolutionScopeForDeclaration(klass)
|
||||||
|
|
||||||
val classDescriptor = resolveSession.resolveToDescriptor(klass) as ClassDescriptor
|
val classDescriptor = resolveSession.resolveToDescriptor(klass) as ClassDescriptor
|
||||||
@@ -547,8 +554,9 @@ class ResolveElementCache(
|
|||||||
return trace
|
return trace
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun typealiasAdditionalResolve(resolveSession: ResolveSession, typeAlias: KtTypeAlias): BindingTrace {
|
private fun typealiasAdditionalResolve(resolveSession: ResolveSession, typeAlias: KtTypeAlias,
|
||||||
val trace = createDelegatingTrace(typeAlias)
|
bindingTraceFilter: BindingTraceFilter): BindingTrace {
|
||||||
|
val trace = createDelegatingTrace(typeAlias, bindingTraceFilter)
|
||||||
val typeAliasDescriptor = resolveSession.resolveToDescriptor(typeAlias)
|
val typeAliasDescriptor = resolveSession.resolveToDescriptor(typeAlias)
|
||||||
ForceResolveUtil.forceResolveAllContents(typeAliasDescriptor)
|
ForceResolveUtil.forceResolveAllContents(typeAliasDescriptor)
|
||||||
forceResolveAnnotationsInside(typeAlias)
|
forceResolveAnnotationsInside(typeAlias)
|
||||||
@@ -556,8 +564,9 @@ class ResolveElementCache(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun initializerAdditionalResolve(resolveSession: ResolveSession, anonymousInitializer: KtAnonymousInitializer,
|
private fun initializerAdditionalResolve(resolveSession: ResolveSession, anonymousInitializer: KtAnonymousInitializer,
|
||||||
file: KtFile, statementFilter: StatementFilter): BindingTrace {
|
file: KtFile, statementFilter: StatementFilter,
|
||||||
val trace = createDelegatingTrace(anonymousInitializer)
|
bindingTraceFilter: BindingTraceFilter): BindingTrace {
|
||||||
|
val trace = createDelegatingTrace(anonymousInitializer, bindingTraceFilter)
|
||||||
|
|
||||||
val classOrObjectDescriptor = resolveSession.resolveToDescriptor(anonymousInitializer.containingDeclaration) as LazyClassDescriptor
|
val classOrObjectDescriptor = resolveSession.resolveToDescriptor(anonymousInitializer.containingDeclaration) as LazyClassDescriptor
|
||||||
|
|
||||||
@@ -595,9 +604,9 @@ class ResolveElementCache(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// All additional resolve should be done to separate trace
|
// All additional resolve should be done to separate trace
|
||||||
private fun createDelegatingTrace(resolveElement: KtElement): BindingTrace {
|
private fun createDelegatingTrace(resolveElement: KtElement, filter: BindingTraceFilter): BindingTrace {
|
||||||
return resolveSession.storageManager.createSafeTrace(
|
return resolveSession.storageManager.createSafeTrace(
|
||||||
DelegatingBindingTrace(resolveSession.bindingContext, "trace to resolve element", resolveElement))
|
DelegatingBindingTrace(resolveSession.bindingContext, "trace to resolve element", resolveElement, filter))
|
||||||
}
|
}
|
||||||
|
|
||||||
private class BodyResolveContextForLazy(
|
private class BodyResolveContextForLazy(
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ abstract class AbstractKtReference<T : KtElement>(element: T)
|
|||||||
override fun isSoft(): Boolean = false
|
override fun isSoft(): Boolean = false
|
||||||
|
|
||||||
private fun resolveToPsiElements(): Collection<PsiElement> {
|
private fun resolveToPsiElements(): Collection<PsiElement> {
|
||||||
val bindingContext = expression.analyze(BodyResolveMode.PARTIAL)
|
val bindingContext = expression.analyze(BodyResolveMode.PARTIAL_WITH_DIAGNOSTICS)
|
||||||
return resolveToPsiElements(bindingContext, getTargetDescriptors(bindingContext))
|
return resolveToPsiElements(bindingContext, getTargetDescriptors(bindingContext))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -76,7 +76,7 @@ abstract class KotlinIntentionActionFactoryWithDelegate<E : KtElement, D : Any>
|
|||||||
if (!diagnosticElement.isValid || !element.isValid) return@factory null
|
if (!diagnosticElement.isValid || !element.isValid) return@factory null
|
||||||
|
|
||||||
val currentDiagnostic =
|
val currentDiagnostic =
|
||||||
element.analyze(BodyResolveMode.PARTIAL)
|
element.analyze(BodyResolveMode.PARTIAL_WITH_DIAGNOSTICS)
|
||||||
.diagnostics
|
.diagnostics
|
||||||
.forElement(diagnosticElement)
|
.forElement(diagnosticElement)
|
||||||
.firstOrNull { DefaultErrorMessages.render(it) == diagnosticMessage } ?: return@factory null
|
.firstOrNull { DefaultErrorMessages.render(it) == diagnosticMessage } ?: return@factory null
|
||||||
|
|||||||
+1
-1
@@ -111,7 +111,7 @@ class CreateTypeParameterFromUsageFix(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
is KtCallElement -> {
|
is KtCallElement -> {
|
||||||
if (it.analyze(BodyResolveMode.PARTIAL).diagnostics.forElement(it.calleeExpression!!).any {
|
if (it.analyze(BodyResolveMode.PARTIAL_WITH_DIAGNOSTICS).diagnostics.forElement(it.calleeExpression!!).any {
|
||||||
it.factory in Errors.TYPE_INFERENCE_ERRORS
|
it.factory in Errors.TYPE_INFERENCE_ERRORS
|
||||||
}) {
|
}) {
|
||||||
callsToExplicateArguments += it
|
callsToExplicateArguments += it
|
||||||
|
|||||||
@@ -303,7 +303,7 @@ class KotlinInlineValHandler : InlineActionHandler() {
|
|||||||
resolutionFacade: ResolutionFacade
|
resolutionFacade: ResolutionFacade
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val functionLiteral = lambdaExpression.functionLiteral
|
val functionLiteral = lambdaExpression.functionLiteral
|
||||||
val context = resolutionFacade.analyze(lambdaExpression, BodyResolveMode.PARTIAL)
|
val context = resolutionFacade.analyze(lambdaExpression, BodyResolveMode.PARTIAL_WITH_DIAGNOSTICS)
|
||||||
return context.diagnostics.any { diagnostic ->
|
return context.diagnostics.any { diagnostic ->
|
||||||
val factory = diagnostic.factory
|
val factory = diagnostic.factory
|
||||||
val element = diagnostic.psiElement
|
val element = diagnostic.psiElement
|
||||||
|
|||||||
@@ -784,7 +784,7 @@ fun getQualifiedTypeArgumentList(initializer: KtExpression): KtTypeArgumentList?
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun addTypeArgumentsIfNeeded(expression: KtExpression, typeArgumentList: KtTypeArgumentList) {
|
fun addTypeArgumentsIfNeeded(expression: KtExpression, typeArgumentList: KtTypeArgumentList) {
|
||||||
val context = expression.analyze(BodyResolveMode.PARTIAL)
|
val context = expression.analyze(BodyResolveMode.PARTIAL_WITH_DIAGNOSTICS)
|
||||||
val call = expression.getCallWithAssert(context)
|
val call = expression.getCallWithAssert(context)
|
||||||
val callElement = call.callElement as? KtCallExpression ?: return
|
val callElement = call.callElement as? KtCallExpression ?: return
|
||||||
if (call.typeArgumentList != null) return
|
if (call.typeArgumentList != null) return
|
||||||
|
|||||||
Reference in New Issue
Block a user