[Frontend] Make DiagnosticSuppressor a project-level extension

Originally it was an application-level component, which caused non-trivial
  logic and cognitive load to carefully handle those extensions to avoid
  memory leaks.

6740a596 introduced a way to easily register `DiagnosticSuppressor` to
  project, and this commit continues this work, making it a proper
  project-level extension

A lot of changes caused by the fact, that this extension is needed to be
  obtained from `BindingContext` (see `BindingContextSuppressCache` and
  its usages), so almost all changes are introducing `Project` to
  `BindingContext`

^KT-66449 Fixed
This commit is contained in:
Dmitriy Novozhilov
2024-03-08 08:52:28 +02:00
committed by Space Team
parent a552238874
commit d352cc9d96
45 changed files with 165 additions and 127 deletions
@@ -186,7 +186,7 @@ internal class KtFirCompilerFacility(
ProgressManager.checkCanceled()
targetFir2IrResult.pluginContext.applyIrGenerationExtensions(targetFir2IrResult.irModuleFragment, irGeneratorExtensions)
val bindingContext = NoScopeRecordCliBindingTrace().bindingContext
val bindingContext = NoScopeRecordCliBindingTrace(project).bindingContext
val codegenFactory = createJvmIrCodegenFactory(targetConfiguration, file is KtCodeFragment, targetFir2IrResult.irModuleFragment)
val generateClassFilter = SingleFileGenerateClassFilter(file, compilationPeerData.inlinedClasses)
@@ -140,7 +140,7 @@ abstract class AbstractSimpleFileBenchmark {
val result = TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
moduleContext.project,
listOf(file),
NoScopeRecordCliBindingTrace(),
NoScopeRecordCliBindingTrace(env.project),
env.configuration,
{ scope -> JvmPackagePartProvider(LANGUAGE_FEATURE_SETTINGS, scope) }
)
@@ -175,7 +175,7 @@ private fun <D : FunctionDescriptor> ResolvedCall<D>.replaceAssertWithAssertInne
call,
newCandidateDescriptor,
dispatchReceiver, extensionReceiver, explicitReceiverKind,
null, DelegatingBindingTrace(BindingTraceContext().bindingContext, "Temporary trace for assertInner"),
null, DelegatingBindingTrace(BindingTraceContext(null).bindingContext, "Temporary trace for assertInner"),
TracingStrategy.EMPTY, MutableDataFlowInfoForArguments.WithoutArgumentsCheck(DataFlowInfo.EMPTY)
)
valueArguments.forEach {
@@ -127,7 +127,7 @@ fun ResolvedCall<*>.replaceSuspensionFunctionWithRealDescriptor(
call,
newCandidateDescriptor,
dispatchReceiver, extensionReceiver, explicitReceiverKind,
null, DelegatingBindingTrace(BindingTraceContext().bindingContext, "Temporary trace for unwrapped suspension function"),
null, DelegatingBindingTrace(BindingTraceContext(null).bindingContext, "Temporary trace for unwrapped suspension function"),
TracingStrategy.EMPTY, MutableDataFlowInfoForArguments.WithoutArgumentsCheck(DataFlowInfo.EMPTY)
)
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.cli.jvm.compiler
import com.intellij.openapi.project.Project
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.LanguageVersionSettings
@@ -19,7 +20,7 @@ import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer
import org.jetbrains.kotlin.util.slicedMap.ReadOnlySlice
import org.jetbrains.kotlin.util.slicedMap.WritableSlice
class CliTraceHolder : JvmCodeAnalyzerInitializer() {
class CliTraceHolder(val project: Project) : JvmCodeAnalyzerInitializer() {
lateinit var bindingContext: BindingContext
private set
lateinit var module: ModuleDescriptor
@@ -34,7 +35,7 @@ class CliTraceHolder : JvmCodeAnalyzerInitializer() {
module: ModuleDescriptor,
codeAnalyzer: KotlinCodeAnalyzer,
languageVersionSettings: LanguageVersionSettings,
jvmTarget: JvmTarget
jvmTarget: JvmTarget,
) {
this.bindingContext = trace.bindingContext
this.module = module
@@ -49,13 +50,13 @@ class CliTraceHolder : JvmCodeAnalyzerInitializer() {
}
override fun createTrace(): BindingTraceContext {
return NoScopeRecordCliBindingTrace()
return NoScopeRecordCliBindingTrace(project)
}
}
// TODO: needs better name + list of keys to skip somewhere
class NoScopeRecordCliBindingTrace : CliBindingTrace() {
class NoScopeRecordCliBindingTrace(project: Project) : CliBindingTrace(project) {
override fun <K, V> record(slice: WritableSlice<K, V>, key: K, value: V) {
if (slice == BindingContext.LEXICAL_SCOPE || slice == BindingContext.DATA_FLOW_INFO_BEFORE) {
// In the compiler there's no need to keep scopes
@@ -69,7 +70,7 @@ class NoScopeRecordCliBindingTrace : CliBindingTrace() {
}
}
open class CliBindingTrace @TestOnly constructor() : BindingTraceContext() {
open class CliBindingTrace @TestOnly constructor(project: Project) : BindingTraceContext(project) {
private var kotlinCodeAnalyzer: KotlinCodeAnalyzer? = null
override fun toString(): String {
@@ -90,6 +90,7 @@ import org.jetbrains.kotlin.parsing.KotlinParserDefinition
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer
import org.jetbrains.kotlin.resolve.ModuleAnnotationsResolver
import org.jetbrains.kotlin.resolve.diagnostics.DiagnosticSuppressor
import org.jetbrains.kotlin.resolve.extensions.AssignResolutionAltererExtension
import org.jetbrains.kotlin.resolve.extensions.ExtraImportsProviderExtension
import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension
@@ -726,6 +727,7 @@ class KotlinCoreEnvironment private constructor(
TypeAttributeTranslatorExtension.registerExtensionPoint(project)
AssignResolutionAltererExtension.registerExtensionPoint(project)
FirAnalysisHandlerExtension.registerExtensionPoint(project)
DiagnosticSuppressor.registerExtensionPoint(project)
}
internal fun registerExtensionsFromPlugins(project: MockProject, configuration: CompilerConfiguration) {
@@ -820,7 +822,7 @@ class KotlinCoreEnvironment private constructor(
@JvmStatic
fun registerKotlinLightClassSupport(project: MockProject) {
with(project) {
val traceHolder = CliTraceHolder()
val traceHolder = CliTraceHolder(project)
val cliLightClassGenerationSupport = CliLightClassGenerationSupport(traceHolder, project)
val kotlinAsJavaSupport = CliKotlinAsJavaSupport(project, traceHolder)
registerService(LightClassGenerationSupport::class.java, cliLightClassGenerationSupport)
@@ -16,7 +16,7 @@
area="IDEA_PROJECT"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.diagnosticSuppressor"
interface="org.jetbrains.kotlin.resolve.diagnostics.DiagnosticSuppressor"
dynamic="true"/>
area="IDEA_PROJECT" dynamic="true"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.expressionCodegenExtension"
interface="org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension"
area="IDEA_PROJECT" dynamic="true"/>
@@ -186,7 +186,7 @@ object KotlinToJVMBytecodeCompiler {
factory,
input,
fir2IrAndIrActualizerResult.irModuleFragment.descriptor,
NoScopeRecordCliBindingTrace().bindingContext,
NoScopeRecordCliBindingTrace(project).bindingContext,
FirJvmBackendClassResolver(fir2IrAndIrActualizerResult.components),
FirJvmBackendExtension(
fir2IrAndIrActualizerResult.components,
@@ -383,7 +383,7 @@ object KotlinToJVMBytecodeCompiler {
TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
project,
sourceFiles,
NoScopeRecordCliBindingTrace(),
NoScopeRecordCliBindingTrace(project),
environment.configuration,
environment::createPackagePartProvider,
sourceModuleSearchScope = scope,
@@ -209,10 +209,12 @@ fun generateCodeFromIr(
input.configuration,
input.configuration.get(CLIConfigurationKeys.PHASE_CONFIG),
)
val dummyBindingContext = NoScopeRecordCliBindingTrace().bindingContext
val project = (environment.projectEnvironment as VfsBasedProjectEnvironment).project
val dummyBindingContext = NoScopeRecordCliBindingTrace(project).bindingContext
val generationState = GenerationState.Builder(
(environment.projectEnvironment as VfsBasedProjectEnvironment).project, ClassBuilderFactories.BINARIES,
project, ClassBuilderFactories.BINARIES,
input.irModuleFragment.descriptor, dummyBindingContext, input.configuration
).targetId(
input.targetId
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.cfg.pseudocode;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.cfg.ControlFlowProcessor;
@@ -95,6 +96,12 @@ public class PseudocodeUtil {
public boolean wantsDiagnostics() {
return false;
}
@Nullable
@Override
public Project getProject() {
return bindingContext.getProject();
}
};
return new ControlFlowProcessor(mockTrace, languageVersionSettings).generatePseudocode(declaration);
}
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.resolve;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Multimap;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiElement;
import kotlin.Pair;
@@ -89,8 +90,17 @@ public interface BindingContext {
public void addOwnDataTo(@NotNull BindingTrace trace, boolean commitDiagnostics) {
// Do nothing
}
@Nullable
@Override
public Project getProject() {
return null;
}
};
@Nullable
Project getProject();
WritableSlice<KtAnnotationEntry, AnnotationDescriptor> ANNOTATION = Slices.createSimpleSlice();
WritableSlice<KtExpression, CompileTimeConstant<?>> COMPILE_TIME_VALUE = new BasicWritableSlice<>(COMPILE_TIME_VALUE_REWRITE_POLICY);
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.resolve;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.diagnostics.DiagnosticSink;
@@ -30,6 +31,9 @@ public interface BindingTrace extends DiagnosticSink {
@NotNull
BindingContext getBindingContext();
@Nullable
Project getProject();
<K, V> void record(WritableSlice<K, V> slice, K key, V value);
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.resolve;
import com.google.common.collect.ImmutableMap;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
@@ -42,6 +43,7 @@ public class BindingTraceContext implements BindingTrace {
private final MutableSlicedMap map;
private final MutableDiagnosticsWithSuppression mutableDiagnostics;
private final Project project;
private final boolean isValidationEnabled;
@@ -85,36 +87,43 @@ public class BindingTraceContext implements BindingTrace {
public void clear() {
map.clear();
}
@Nullable
@Override
public Project getProject() {
return project;
}
};
public BindingTraceContext() {
this(false);
public BindingTraceContext(Project project) {
this(false, project);
}
public BindingTraceContext(boolean allowSliceRewrite) {
this(BindingTraceFilter.Companion.getACCEPT_ALL(), allowSliceRewrite);
public BindingTraceContext(boolean allowSliceRewrite, Project project) {
this(BindingTraceFilter.Companion.getACCEPT_ALL(), allowSliceRewrite, project);
}
public BindingTraceContext(BindingTraceFilter filter, boolean allowSliceRewrite) {
this(filter, allowSliceRewrite, VALIDATION);
public BindingTraceContext(BindingTraceFilter filter, boolean allowSliceRewrite, Project project) {
this(filter, allowSliceRewrite, VALIDATION, project);
}
public BindingTraceContext(BindingTraceFilter filter, boolean allowSliceRewrite, boolean isValidationEnabled) {
this(TRACK_REWRITES && !allowSliceRewrite ? new TrackingSlicedMap(TRACK_WITH_STACK_TRACES) : new SlicedMapImpl(allowSliceRewrite), filter, isValidationEnabled);
public BindingTraceContext(BindingTraceFilter filter, boolean allowSliceRewrite, boolean isValidationEnabled, Project project) {
this(TRACK_REWRITES && !allowSliceRewrite ? new TrackingSlicedMap(TRACK_WITH_STACK_TRACES) : new SlicedMapImpl(allowSliceRewrite), filter, isValidationEnabled, project);
}
private BindingTraceContext(@NotNull MutableSlicedMap map, BindingTraceFilter filter, boolean isValidationEnabled) {
private BindingTraceContext(@NotNull MutableSlicedMap map, BindingTraceFilter filter, boolean isValidationEnabled, Project project) {
this.map = map;
this.mutableDiagnostics =
filter.getIgnoreDiagnostics()
? null
: new MutableDiagnosticsWithSuppression(new BindingContextSuppressCache(bindingContext), Diagnostics.Companion.getEMPTY());
this.isValidationEnabled = isValidationEnabled;
this.project = project;
}
@TestOnly
public static BindingTraceContext createTraceableBindingTrace() {
return new BindingTraceContext(new TrackingSlicedMap(TRACK_WITH_STACK_TRACES), BindingTraceFilter.Companion.getACCEPT_ALL(), VALIDATION);
public static BindingTraceContext createTraceableBindingTrace(Project project) {
return new BindingTraceContext(new TrackingSlicedMap(TRACK_WITH_STACK_TRACES), BindingTraceFilter.Companion.getACCEPT_ALL(), VALIDATION, project);
}
@Override
@@ -125,6 +134,11 @@ public class BindingTraceContext implements BindingTrace {
mutableDiagnostics.report(diagnostic);
}
@Override
public Project getProject() {
return project;
}
public void clearDiagnostics() {
if (mutableDiagnostics != null) {
mutableDiagnostics.clear();
@@ -27,6 +27,6 @@ interface CodeAnalyzerInitializer {
}
}
class DummyCodeAnalyzerInitializer : CodeAnalyzerInitializer {
override fun createTrace(): BindingTrace = BindingTraceContext(true)
class DummyCodeAnalyzerInitializer(val project: Project) : CodeAnalyzerInitializer {
override fun createTrace(): BindingTrace = BindingTraceContext(/* allowSliceRewrite = */ true, project)
}
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve
import org.jetbrains.kotlin.util.slicedMap.ReadOnlySlice
import org.jetbrains.kotlin.util.slicedMap.WritableSlice
import com.google.common.collect.ImmutableMap
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.diagnostics.Diagnostic
import com.intellij.psi.PsiElement
import com.intellij.openapi.util.ModificationTracker
@@ -66,6 +67,10 @@ class CompositeBindingContext private constructor(
// Do nothing
}
override fun getProject(): Project? {
return delegates.firstOrNull()?.project
}
private class CompositeDiagnostics(
private val delegates: List<Diagnostics>
) : Diagnostics {
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.resolve
import com.google.common.collect.ImmutableMap
import com.intellij.openapi.project.Project
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
@@ -66,6 +67,10 @@ open class DelegatingBindingTrace(
override fun <K, V> getSliceContents(slice: ReadOnlySlice<K, V>): ImmutableMap<K, V> {
return ImmutableMap.copyOf(parentContext.getSliceContents(slice) + map.getSliceContents(slice))
}
override fun getProject(): Project? {
return this@DelegatingBindingTrace.getProject()
}
}
private val bindingContext = MyBindingContext()
@@ -176,4 +181,8 @@ open class DelegatingBindingTrace(
override fun wantsDiagnostics(): Boolean = mutableDiagnostics != null
override fun toString(): String = name
override fun getProject(): Project? {
return parentContext.project
}
}
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.resolve;
import com.intellij.openapi.project.Project;
import com.intellij.util.SmartFMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -102,4 +103,10 @@ public class ObservableBindingTrace implements BindingTrace {
public String toString() {
return "ObservableTrace over " + originalTrace.toString();
}
@Nullable
@Override
public Project getProject() {
return originalTrace.getProject();
}
}
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.resolve.diagnostics
import com.google.common.collect.ImmutableSet
import com.intellij.openapi.extensions.ExtensionPointName
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
@@ -30,7 +31,6 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.constants.ArrayValue
import org.jetbrains.kotlin.resolve.constants.StringValue
import org.jetbrains.kotlin.util.ExtensionProvider
interface DiagnosticSuppressor {
fun isSuppressed(diagnostic: Diagnostic): Boolean
@@ -48,9 +48,9 @@ interface DiagnosticSuppressor {
}
}
abstract class KotlinSuppressCache : AbstractKotlinSuppressCache<PsiElement>() {
abstract class KotlinSuppressCache(project: Project?) : AbstractKotlinSuppressCache<PsiElement>() {
private val diagnosticSuppressors = ExtensionProvider.create(DiagnosticSuppressor.extensionPointName)
private val diagnosticSuppressors: List<DiagnosticSuppressor> = project?.let { DiagnosticSuppressor.getInstances(it) } ?: emptyList()
val filter: (Diagnostic) -> Boolean = { diagnostic: Diagnostic ->
!isSuppressed(DiagnosticSuppressRequest(diagnostic))
@@ -99,7 +99,7 @@ abstract class KotlinSuppressCache : AbstractKotlinSuppressCache<PsiElement>() {
}
if (request is DiagnosticSuppressRequest) {
for (suppressor in diagnosticSuppressors.get()) {
for (suppressor in diagnosticSuppressors) {
if (isSuppressedByExtension(suppressor, request.diagnostic)) return true
}
}
@@ -122,7 +122,7 @@ abstract class KotlinSuppressCache : AbstractKotlinSuppressCache<PsiElement>() {
}
}
class BindingContextSuppressCache(val context: BindingContext) : KotlinSuppressCache() {
class BindingContextSuppressCache(val context: BindingContext) : KotlinSuppressCache(context.project) {
override fun getSuppressionAnnotations(annotated: PsiElement): List<AnnotationDescriptor> {
val descriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, annotated)
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtTreeVisitorVoid
import org.jetbrains.kotlin.resolve.BindingContext
class OnDemandSuppressCache(private val context: BindingContext) : KotlinSuppressCache() {
class OnDemandSuppressCache(private val context: BindingContext) : KotlinSuppressCache(context.project) {
private val processedRoots = mutableSetOf<KtFile>()
private val storage = mutableMapOf<PsiElement, List<AnnotationDescriptor>>()
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.storage
import com.intellij.openapi.project.Project
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.resolve.BindingContext
@@ -53,6 +54,10 @@ class LockBasedLazyResolveStorageManager(private val storageManager: StorageMana
@TestOnly
override fun <K, V> getSliceContents(slice: ReadOnlySlice<K, V>) = storageManager.compute { context.getSliceContents<K, V>(slice) }
override fun getProject(): Project? {
return context.project
}
}
private class LockProtectedTrace(private val storageManager: StorageManager, private val trace: BindingTrace) : BindingTrace {
@@ -87,5 +92,9 @@ class LockBasedLazyResolveStorageManager(private val storageManager: StorageMana
override fun toString(): String {
return "Lock-protected trace of LockBasedLazyResolveStorageManager $storageManager"
}
override fun getProject(): Project? {
return trace.project
}
}
}
@@ -1,55 +0,0 @@
/*
* Copyright 2010-2015 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.util
import com.intellij.openapi.application.Application
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.extensions.ExtensionPointName
import java.lang.ref.WeakReference
open class MappedExtensionProvider<T : Any, out R>
protected constructor(
private val epName: ExtensionPointName<T>,
private val map: (List<T>) -> R
) {
private var cached = WeakReference<Pair<Application, R>>(null)
fun get(): R {
val cached = cached.get() ?: return update()
val (app, extensions) = cached
return if (app == ApplicationManager.getApplication()) {
extensions
} else {
update()
}
}
private fun update(): R {
val newVal = ApplicationManager.getApplication().let { app ->
Pair(app, map(app.extensionArea.getExtensionPoint(epName).extensionList))
}
cached = WeakReference(newVal)
return newVal.second
}
}
class ExtensionProvider<T : Any>(epName: ExtensionPointName<T>) : MappedExtensionProvider<T, List<T>>(epName, { it }) {
companion object {
@JvmStatic
fun <T : Any> create(epName: ExtensionPointName<T>): ExtensionProvider<T> = ExtensionProvider(epName)
}
}
@@ -182,7 +182,6 @@ class ClassicFrontendFacade(
}
}
@OptIn(ExperimentalStdlibApi::class)
private fun performJvmModuleResolve(
module: TestModule,
project: Project,
@@ -197,7 +196,7 @@ class ClassicFrontendFacade(
val moduleVisibilityManager = ModuleVisibilityManager.SERVICE.getInstance(project)
configuration.getList(JVMConfigurationKeys.FRIEND_PATHS).forEach { moduleVisibilityManager.addFriendPath(it) }
val moduleTrace = NoScopeRecordCliBindingTrace()
val moduleTrace = NoScopeRecordCliBindingTrace(project)
if (module.dependsOnDependencies.isEmpty()) {
return TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
project,
@@ -253,7 +252,6 @@ class ClassicFrontendFacade(
return AnalysisResult.success(moduleTrace.bindingContext, moduleDescriptor)
}
@OptIn(ExperimentalStdlibApi::class)
private fun performJsModuleResolve(
project: Project,
configuration: CompilerConfiguration,
@@ -310,7 +308,6 @@ class ClassicFrontendFacade(
}
}
@OptIn(ExperimentalStdlibApi::class)
private fun performJsIrModuleResolve(
module: TestModule,
project: Project,
@@ -393,7 +390,7 @@ class ClassicFrontendFacade(
friendsDescriptors: List<ModuleDescriptorImpl>,
dependsOnDescriptors: List<ModuleDescriptorImpl>,
): AnalysisResult {
val moduleTrace = NoScopeRecordCliBindingTrace()
val moduleTrace = NoScopeRecordCliBindingTrace(project)
val runtimeKlibsNames = NativeEnvironmentConfigurator.getRuntimePathsForModule(module, testServices)
val nativeFactories = KlibMetadataFactories(::KonanBuiltIns, NullFlexibleTypeDeserializer)
val runtimeKlibs = loadKlib(nativeFactories, runtimeKlibsNames, configuration).mapNotNull { it as? ModuleDescriptorImpl }
@@ -477,7 +474,6 @@ class ClassicFrontendFacade(
override val refinesModuleInfos: List<ModuleInfo> = _moduleInfos.filter { it.module in module.allExpectedByModules }
}
@OptIn(ExperimentalStdlibApi::class)
private fun createModuleContext(
module: TestModule,
project: Project,
@@ -106,7 +106,7 @@ class Fir2IrJvmResultsConverter(
val codegenFactory = JvmIrCodegenFactory(configuration, phaseConfig)
val generationState = GenerationState.Builder(
project, ClassBuilderFactories.TEST,
fir2irResult.irModuleFragment.descriptor, NoScopeRecordCliBindingTrace().bindingContext, configuration
fir2irResult.irModuleFragment.descriptor, NoScopeRecordCliBindingTrace(project).bindingContext, configuration
).isIrBackend(
true
).jvmBackendClassResolver(
@@ -133,7 +133,7 @@ abstract class AbstractDiagnosticsTest : BaseDiagnosticsTest() {
val separateModules = groupedByModule.size == 1 && groupedByModule.keys.single() == null
val result = analyzeModuleContents(
moduleContext, ktFiles, NoScopeRecordCliBindingTrace(),
moduleContext, ktFiles, NoScopeRecordCliBindingTrace(project),
languageVersionSettings, separateModules, loadJvmTarget(testFilesInModule)
)
if (oldModule != result.moduleDescriptor) {
@@ -304,7 +304,7 @@ public abstract class CodegenTestCase extends KotlinBaseTest<KotlinBaseTest.Test
try {
GenerationState generationState = GenerationUtils.compileFiles(
myFiles.getPsiFiles(), myEnvironment, getClassBuilderFactory(),
new NoScopeRecordCliBindingTrace()
new NoScopeRecordCliBindingTrace(myEnvironment.getProject())
);
classFileFactory = generationState.getFactory();
@@ -244,7 +244,7 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir {
registerJavacIfNeeded(environment);
configureEnvironment(environment);
AnalysisResult result = TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
environment.getProject(), environment.getSourceFiles(), new NoScopeRecordCliBindingTrace(),
environment.getProject(), environment.getSourceFiles(), new NoScopeRecordCliBindingTrace(environment.getProject()),
configuration, environment::createPackagePartProvider
);
@@ -153,7 +153,7 @@ public class ExpectedResolveDataUtil {
LanguageVersionSettings languageVersionSettings = CommonConfigurationKeysKt.getLanguageVersionSettings(environment.getConfiguration());
ExpressionTypingContext context = ExpressionTypingContext.newContext(
new BindingTraceContext(), lexicalScope,
new BindingTraceContext(project), lexicalScope,
DataFlowInfoFactory.EMPTY, TypeUtils.NO_EXPECTED_TYPE, languageVersionSettings, container.getDataFlowValueFactory());
KtExpression callElement = new KtPsiFactory(project).createExpression(name);
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.test;
import com.google.common.collect.ImmutableMap;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
@@ -67,9 +68,21 @@ public class DummyTraces {
public void addOwnDataTo(@NotNull BindingTrace trace, boolean commitDiagnostics) {
// do nothing
}
@Nullable
@Override
public Project getProject() {
return null;
}
};
}
@Nullable
@Override
public Project getProject() {
return null;
}
@Override
public <K, V> void record(WritableSlice<K, V> slice, K key, V value) {
}
@@ -121,6 +134,12 @@ public class DummyTraces {
@Override
public BindingContext getBindingContext() {
return new BindingContext() {
@Nullable
@Override
public Project getProject() {
return null;
}
@NotNull
@Override
public Diagnostics getDiagnostics() {
@@ -158,6 +177,12 @@ public class DummyTraces {
};
}
@Nullable
@Override
public Project getProject() {
return null;
}
@Override
public <K, V> void record(WritableSlice<K, V> slice, K key, V value) {
}
@@ -41,7 +41,7 @@ fun createContainerForTests(project: Project, module: ModuleDescriptor): Contain
ModuleContext(module, project, "container for tests"),
JvmPlatforms.defaultJvmPlatform,
JvmPlatformAnalyzerServices,
BindingTraceContext(),
BindingTraceContext(project),
LanguageVersionSettingsImpl.DEFAULT,
optimizingOptions = null,
absentDescriptorHandlerClass = BasicAbsentDescriptorHandler::class.java
@@ -59,7 +59,7 @@ object GenerationUtils {
files: List<KtFile>,
environment: KotlinCoreEnvironment,
classBuilderFactory: ClassBuilderFactory = ClassBuilderFactories.TEST,
trace: BindingTrace = NoScopeRecordCliBindingTrace()
trace: BindingTrace = NoScopeRecordCliBindingTrace(environment.project)
): GenerationState =
compileFiles(files, environment.configuration, classBuilderFactory, environment::createPackagePartProvider, trace)
@@ -70,7 +70,7 @@ object GenerationUtils {
configuration: CompilerConfiguration,
classBuilderFactory: ClassBuilderFactory,
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
trace: BindingTrace = NoScopeRecordCliBindingTrace()
trace: BindingTrace = NoScopeRecordCliBindingTrace(files.first().project)
): GenerationState {
val project = files.first().project
val state = if (configuration.getBoolean(CommonConfigurationKeys.USE_FIR)) {
@@ -128,7 +128,7 @@ object GenerationUtils {
irGeneratorExtensions = emptyList()
)
val dummyBindingContext = NoScopeRecordCliBindingTrace().bindingContext
val dummyBindingContext = NoScopeRecordCliBindingTrace(project).bindingContext
val codegenFactory = JvmIrCodegenFactory(
configuration,
@@ -33,7 +33,7 @@ object JvmResolveUtil {
targetEnvironment: TargetEnvironment = CompilerEnvironment
): ComponentProvider =
TopDownAnalyzerFacadeForJVM.createContainer(
environment.project, files, NoScopeRecordCliBindingTrace(),
environment.project, files, NoScopeRecordCliBindingTrace(environment.project),
environment.configuration, { PackagePartProvider.Empty }, ::FileBasedDeclarationProviderFactory,
targetEnvironment
)
@@ -52,7 +52,7 @@ object JvmResolveUtil {
files: Collection<KtFile>,
configuration: CompilerConfiguration,
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
trace: BindingTrace = CliBindingTrace(),
trace: BindingTrace = CliBindingTrace(project),
klibList: List<KotlinLibrary> = emptyList()
): AnalysisResult {
for (file in files) {
@@ -93,7 +93,7 @@ object JvmResolveUtil {
files: Collection<KtFile>,
configuration: CompilerConfiguration,
packagePartProviderFactory: (GlobalSearchScope) -> PackagePartProvider,
trace: BindingTrace = CliBindingTrace(),
trace: BindingTrace = CliBindingTrace(project),
klibList: List<KotlinLibrary> = emptyList()
): AnalysisResult {
return TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
@@ -40,9 +40,10 @@ class MutableDiagnosticsTest : KotlinTestWithEnvironment() {
get() = bindingContext.diagnostics
fun testPropagatingModification() {
val base = BindingTraceContext()
val middle = DelegatingBindingTrace(base.bindingContext, "middle")
val derived = DelegatingBindingTrace(middle.bindingContext, "derived")
val project = environment.project
val base = BindingTraceContext(project)
val middle = DelegatingBindingTrace(base.bindingContext, "middle", project)
val derived = DelegatingBindingTrace(middle.bindingContext, "derived", project)
Assert.assertTrue(base.diagnostics.isEmpty())
Assert.assertTrue(middle.diagnostics.isEmpty())
@@ -83,9 +84,10 @@ class MutableDiagnosticsTest : KotlinTestWithEnvironment() {
}
fun testCaching() {
val base = BindingTraceContext()
val middle = DelegatingBindingTrace(base.bindingContext, "middle")
val derived = DelegatingBindingTrace(middle.bindingContext, "derived")
val project = environment.project
val base = BindingTraceContext(project)
val middle = DelegatingBindingTrace(base.bindingContext, "middle", project)
val derived = DelegatingBindingTrace(middle.bindingContext, "derived", project)
base.reportDiagnostic()
middle.reportDiagnostic()
@@ -73,7 +73,7 @@ class JsVersionRequirementTest : AbstractVersionRequirementTest() {
override fun loadModule(directory: File): ModuleDescriptor {
val environment = createEnvironment(extraDependencies = listOf(File(directory, "lib.meta.js")))
return TopDownAnalyzerFacadeForJS.analyzeFilesWithGivenTrace(
emptyList(), BindingTraceContext(), createModule(environment), environment.configuration, CompilerEnvironment, environment.project
emptyList(), BindingTraceContext(environment.project), createModule(environment), environment.configuration, CompilerEnvironment, environment.project
).moduleDescriptor
}
@@ -115,7 +115,7 @@ public class DefaultModalityModifiersTest extends KotlinTestWithEnvironment {
StorageComponentContainer container = createContainerForLazyResolve(
moduleContext,
new FileBasedDeclarationProviderFactory(moduleContext.getStorageManager(), files),
new BindingTraceContext(),
new BindingTraceContext(getProject()),
CommonPlatforms.INSTANCE.getDefaultCommonPlatform(),
CommonPlatformAnalyzerServices.INSTANCE,
CompilerEnvironment.INSTANCE,
@@ -563,7 +563,7 @@ public class KotlinTypeCheckerTest extends KotlinTestWithEnvironment {
KotlinType type = expressionTypingServices.getType(
scope, ktExpression, TypeUtils.NO_EXPECTED_TYPE,
DataFlowInfoFactory.EMPTY, InferenceSession.Companion.getDefault(),
new BindingTraceContext()
new BindingTraceContext(project)
);
KotlinType expectedType = expectedTypeStr == null ? null : makeType(expectedTypeStr);
assertEquals(expectedType, type);
@@ -147,7 +147,7 @@ public class TypeSubstitutorTest extends KotlinTestWithEnvironment {
private KotlinType resolveType(String typeStr) {
KtTypeReference ktTypeReference = new KtPsiFactory(getProject()).createType(typeStr);
AnalyzingUtils.checkForSyntacticErrors(ktTypeReference);
BindingTrace trace = new BindingTraceContext();
BindingTrace trace = new BindingTraceContext(getProject());
KotlinType type = container.getTypeResolver().resolveType(scope, ktTypeReference, trace, true);
if (!trace.getBindingContext().getDiagnostics().isEmpty()) {
fail("Errors:\n" + StringUtil.join(trace.getBindingContext().getDiagnostics(), DefaultErrorMessages::render, "\n"));
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.resolve.BindingTraceContext;
public class TrackingSliceMapTest extends TestCase {
public void testSimpleSlice() {
WritableSlice<String, Integer> SUPER_COMPUTER = Slices.<String, Integer>sliceBuilder().setDebugName("SUPER_COMPUTER").build();
BindingTraceContext traceContext = BindingTraceContext.createTraceableBindingTrace();
BindingTraceContext traceContext = BindingTraceContext.createTraceableBindingTrace(null);
traceContext.record(SUPER_COMPUTER, "Answer", 42);
Integer answer = traceContext.get(SUPER_COMPUTER, "Answer");
@@ -39,7 +39,7 @@ public class TrackingSliceMapTest extends TestCase {
.setFurtherLookupSlices(new ReadOnlySlice[] {NAME_COLOR})
.setDebugName("NAME_OBJECT").build();
BindingTraceContext traceContext = BindingTraceContext.createTraceableBindingTrace();
BindingTraceContext traceContext = BindingTraceContext.createTraceableBindingTrace(null);
traceContext.record(NAME_COLOR, "RED", 0xff0000);
Object object = traceContext.get(NAME_OBJECT, "RED");
@@ -89,7 +89,7 @@ abstract class AbstractTopDownAnalyzerFacadeForWeb {
val moduleKind = configuration.get(JSConfigurationKeys.MODULE_KIND, ModuleKind.PLAIN)
val trace = BindingTraceContext()
val trace = BindingTraceContext(project)
trace.record(MODULE_KIND, context.module, moduleKind)
return analyzeFilesWithGivenTrace(files, trace, context, configuration, targetEnvironment, project, additionalPackages)
}
@@ -62,7 +62,7 @@ internal object TopDownAnalyzerFacadeForKonan {
additionalPackages += functionInterfacePackageFragmentProvider(projectContext.storageManager, module)
}
return analyzeFilesWithGivenTrace(files, BindingTraceContext(), moduleContext, context, projectContext, additionalPackages)
return analyzeFilesWithGivenTrace(files, BindingTraceContext(projectContext.project), moduleContext, context, projectContext, additionalPackages)
}
fun analyzeFilesWithGivenTrace(
@@ -244,7 +244,7 @@ class ObjCExportLazyImpl(
val receiverType = topLevelDeclaration.receiverTypeReference ?: return null
val fileScope = fileScopeProvider.getFileResolutionScope(topLevelDeclaration.containingKtFile)
val trace = BindingTraceContext() // TODO: revise.
val trace = BindingTraceContext(topLevelDeclaration.project) // TODO: revise.
val kotlinReceiverType = typeResolver.resolveType(
createHeaderScope(topLevelDeclaration, fileScope, trace),
@@ -101,7 +101,7 @@ fun createModuleDescriptor(
return FakeTopDownAnalyzerFacadeForNative.analyzeFilesWithGivenTrace(
files = kotlinPsiFiles,
trace = NoScopeRecordCliBindingTrace(),
trace = NoScopeRecordCliBindingTrace(environment.project),
languageVersionSettings = createLanguageVersionSettings(),
moduleContext = projectContext.withModule(moduleDescriptor)
).moduleDescriptor
@@ -49,7 +49,7 @@ internal fun constructAnnotation(psi: KtAnnotationEntry, targetClass: KClass<out
DefaultBuiltIns.Instance
)
val evaluator = ConstantExpressionEvaluator(module, LanguageVersionSettingsImpl.DEFAULT, project)
val trace = BindingTraceContext()
val trace = BindingTraceContext(project)
val valueArguments = psi.valueArguments.map { arg ->
val expression = arg.getArgumentExpression()!!
@@ -267,7 +267,7 @@ private fun analyze(sourceFiles: Collection<KtFile>, environment: KotlinCoreEnvi
TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
project,
sourceFiles,
NoScopeRecordCliBindingTrace(),
NoScopeRecordCliBindingTrace(project),
environment.configuration,
environment::createPackagePartProvider
)
@@ -43,7 +43,7 @@ import kotlin.script.experimental.jvm.util.SnippetsHistory
open class ReplCodeAnalyzerBase(
environment: KotlinCoreEnvironment,
val trace: BindingTraceContext = NoScopeRecordCliBindingTrace(),
val trace: BindingTraceContext = NoScopeRecordCliBindingTrace(environment.project),
implicitsResolutionFilter: ImplicitsExtensionsResolutionFilter? = null
) {
protected val scriptDeclarationFactory: ScriptMutableDeclarationProviderFactory
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.scripting.compiler.plugin.repl.ReplCodeAnalyzerBase
class IdeLikeReplCodeAnalyzer(
private val environment: KotlinCoreEnvironment,
implicitsResolutionFilter: ImplicitsExtensionsResolutionFilter
) : ReplCodeAnalyzerBase(environment, CliBindingTrace(), implicitsResolutionFilter) {
) : ReplCodeAnalyzerBase(environment, CliBindingTrace(environment.project), implicitsResolutionFilter) {
interface ReplLineAnalysisResultWithStateless : ReplLineAnalysisResult {
// Result of stateless analyse, which may be used for reporting errors
// without code generation