[JS IR] Add CLI argument to setup error tolerance policy

-  Make sure dev mode is enabled if code with errors is allowed
This commit is contained in:
Roman Artemev
2020-07-08 14:16:52 +03:00
parent 8a810e2a5e
commit a60782f3df
8 changed files with 67 additions and 19 deletions
@@ -175,6 +175,9 @@ class K2JSCompilerArguments : CommonCompilerArguments() {
@Argument(value = "-Xdisable-fake-override-validator", description = "Disable IR fake override validator") @Argument(value = "-Xdisable-fake-override-validator", description = "Disable IR fake override validator")
var disableFakeOverrideValidator: Boolean by FreezableVar(false) var disableFakeOverrideValidator: Boolean by FreezableVar(false)
@Argument(value = "-Xerror-tolerance-policy", description = "Set up error tolerance policy (NONE, SEMANTIC, SYNTAX, ALL)")
var errorTolerancePolicy: String? by NullableStringFreezableVar(null)
override fun checkIrSupport(languageVersionSettings: LanguageVersionSettings, collector: MessageCollector) { override fun checkIrSupport(languageVersionSettings: LanguageVersionSettings, collector: MessageCollector) {
if (!isIrBackendEnabled()) return if (!isIrBackendEnabled()) return
@@ -35,10 +35,7 @@ import org.jetbrains.kotlin.incremental.js.IncrementalNextRoundChecker
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer
import org.jetbrains.kotlin.ir.backend.js.* import org.jetbrains.kotlin.ir.backend.js.*
import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory
import org.jetbrains.kotlin.js.config.EcmaVersion import org.jetbrains.kotlin.js.config.*
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
import org.jetbrains.kotlin.js.config.JsConfig
import org.jetbrains.kotlin.js.config.SourceMapSourceEmbedding
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.serialization.js.ModuleKind import org.jetbrains.kotlin.serialization.js.ModuleKind
@@ -314,6 +311,13 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
configuration.putIfNotNull(CommonConfigurationKeys.LOOKUP_TRACKER, services[LookupTracker::class.java]) configuration.putIfNotNull(CommonConfigurationKeys.LOOKUP_TRACKER, services[LookupTracker::class.java])
configuration.putIfNotNull(CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER, services[ExpectActualTracker::class.java]) configuration.putIfNotNull(CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER, services[ExpectActualTracker::class.java])
val errorTolerancePolicy = arguments.errorTolerancePolicy?.let { ErrorTolerancePolicy.resolvePolicy(it) }
configuration.putIfNotNull(JSConfigurationKeys.ERROR_TOLERANCE_POLICY, errorTolerancePolicy)
if (errorTolerancePolicy?.allowErrors == true) {
configuration.put(JSConfigurationKeys.DEVELOPER_MODE, true)
}
val sourceMapEmbedContentString = arguments.sourceMapEmbedSources val sourceMapEmbedContentString = arguments.sourceMapEmbedSources
var sourceMapContentEmbedding: SourceMapSourceEmbedding? = if (sourceMapEmbedContentString != null) var sourceMapContentEmbedding: SourceMapSourceEmbedding? = if (sourceMapEmbedContentString != null)
sourceMapContentEmbeddingMap[sourceMapEmbedContentString] sourceMapContentEmbeddingMap[sourceMapEmbedContentString]
@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult
import org.jetbrains.kotlin.js.config.ErrorTolerancePolicy
import org.jetbrains.kotlin.js.config.JSConfigurationKeys import org.jetbrains.kotlin.js.config.JSConfigurationKeys
import org.jetbrains.kotlin.konan.properties.propertyList import org.jetbrains.kotlin.konan.properties.propertyList
import org.jetbrains.kotlin.konan.util.KlibMetadataFactories import org.jetbrains.kotlin.konan.util.KlibMetadataFactories
@@ -106,6 +107,7 @@ fun generateKLib(
nopack: Boolean nopack: Boolean
) { ) {
val incrementalDataProvider = configuration.get(JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER) val incrementalDataProvider = configuration.get(JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER)
val errorPolicy = configuration.get(JSConfigurationKeys.ERROR_TOLERANCE_POLICY) ?: ErrorTolerancePolicy.DEFAULT
val icData: List<KotlinFileSerializedData> val icData: List<KotlinFileSerializedData>
val serializedIrFiles: List<SerializedIrFile>? val serializedIrFiles: List<SerializedIrFile>?
@@ -140,7 +142,7 @@ fun generateKLib(
val depsDescriptors = val depsDescriptors =
ModulesStructure(project, MainModule.SourceFiles(files), analyzer, configuration, allDependencies, friendDependencies) ModulesStructure(project, MainModule.SourceFiles(files), analyzer, configuration, allDependencies, friendDependencies)
val psi2IrContext = runAnalysisAndPreparePsi2Ir(depsDescriptors, irFactory) val psi2IrContext = runAnalysisAndPreparePsi2Ir(depsDescriptors, irFactory, errorPolicy)
val irBuiltIns = psi2IrContext.irBuiltIns val irBuiltIns = psi2IrContext.irBuiltIns
val functionFactory = IrFunctionFactory(irBuiltIns, psi2IrContext.symbolTable) val functionFactory = IrFunctionFactory(irBuiltIns, psi2IrContext.symbolTable)
irBuiltIns.functionFactory = functionFactory irBuiltIns.functionFactory = functionFactory
@@ -222,10 +224,11 @@ fun loadIr(
): IrModuleInfo { ): IrModuleInfo {
val depsDescriptors = ModulesStructure(project, mainModule, analyzer, configuration, allDependencies, friendDependencies) val depsDescriptors = ModulesStructure(project, mainModule, analyzer, configuration, allDependencies, friendDependencies)
val deserializeFakeOverrides = configuration.getBoolean(CommonConfigurationKeys.DESERIALIZE_FAKE_OVERRIDES) val deserializeFakeOverrides = configuration.getBoolean(CommonConfigurationKeys.DESERIALIZE_FAKE_OVERRIDES)
val errorPolicy = configuration.get(JSConfigurationKeys.ERROR_TOLERANCE_POLICY) ?: ErrorTolerancePolicy.DEFAULT
when (mainModule) { when (mainModule) {
is MainModule.SourceFiles -> { is MainModule.SourceFiles -> {
val psi2IrContext: GeneratorContext = runAnalysisAndPreparePsi2Ir(depsDescriptors, irFactory) val psi2IrContext: GeneratorContext = runAnalysisAndPreparePsi2Ir(depsDescriptors, irFactory, errorPolicy)
val irBuiltIns = psi2IrContext.irBuiltIns val irBuiltIns = psi2IrContext.irBuiltIns
val symbolTable = psi2IrContext.symbolTable val symbolTable = psi2IrContext.symbolTable
val functionFactory = IrFunctionFactory(irBuiltIns, symbolTable) val functionFactory = IrFunctionFactory(irBuiltIns, symbolTable)
@@ -294,9 +297,9 @@ fun loadIr(
} }
} }
private fun runAnalysisAndPreparePsi2Ir(depsDescriptors: ModulesStructure, irFactory: IrFactory): GeneratorContext { private fun runAnalysisAndPreparePsi2Ir(depsDescriptors: ModulesStructure, irFactory: IrFactory, errorIgnorancePolicy: ErrorTolerancePolicy): GeneratorContext {
val (bindingContext, moduleDescriptor) = depsDescriptors.runAnalysis() val (bindingContext, moduleDescriptor) = depsDescriptors.runAnalysis(errorIgnorancePolicy)
val psi2Ir = Psi2IrTranslator(depsDescriptors.compilerConfiguration.languageVersionSettings, Psi2IrConfiguration()) val psi2Ir = Psi2IrTranslator(depsDescriptors.compilerConfiguration.languageVersionSettings, Psi2IrConfiguration(errorIgnorancePolicy.allowErrors))
val symbolTable = SymbolTable(IdSignatureDescriptor(JsManglerDesc), irFactory) val symbolTable = SymbolTable(IdSignatureDescriptor(JsManglerDesc), irFactory)
return psi2Ir.createGeneratorContext(moduleDescriptor, bindingContext, symbolTable) return psi2Ir.createGeneratorContext(moduleDescriptor, bindingContext, symbolTable)
} }
@@ -380,7 +383,7 @@ private class ModulesStructure(
val builtInsDep = allDependencies.getFullList().find { it.isBuiltIns } val builtInsDep = allDependencies.getFullList().find { it.isBuiltIns }
fun runAnalysis(): JsAnalysisResult { fun runAnalysis(errorPolicy: ErrorTolerancePolicy): JsAnalysisResult {
require(mainModule is MainModule.SourceFiles) require(mainModule is MainModule.SourceFiles)
val files = mainModule.files val files = mainModule.files
@@ -403,10 +406,11 @@ private class ModulesStructure(
/** can throw [IncrementalNextRoundException] */ /** can throw [IncrementalNextRoundException] */
compareMetadataAndGoToNextICRoundIfNeeded(analysisResult, compilerConfiguration, files) compareMetadataAndGoToNextICRoundIfNeeded(analysisResult, compilerConfiguration, files)
} }
if (analyzer.hasErrors() || analysisResult !is JsAnalysisResult)
if (!errorPolicy.allowErrors && analyzer.hasErrors() || analysisResult !is JsAnalysisResult)
throw JsIrCompilationError throw JsIrCompilationError
TopDownAnalyzerFacadeForJSIR.checkForErrors(files, analysisResult.bindingContext) TopDownAnalyzerFacadeForJSIR.checkForErrors(files, analysisResult.bindingContext, errorPolicy)
return analysisResult return analysisResult
} }
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider
import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult
import org.jetbrains.kotlin.js.config.ErrorTolerancePolicy
import org.jetbrains.kotlin.js.config.JSConfigurationKeys import org.jetbrains.kotlin.js.config.JSConfigurationKeys
import org.jetbrains.kotlin.js.config.JsConfig import org.jetbrains.kotlin.js.config.JsConfig
import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices
@@ -114,10 +115,14 @@ abstract class AbstractTopDownAnalyzerFacadeForJS {
return JsAnalysisResult.success(trace, moduleContext.module) return JsAnalysisResult.success(trace, moduleContext.module)
} }
fun checkForErrors(allFiles: Collection<KtFile>, bindingContext: BindingContext) { fun checkForErrors(allFiles: Collection<KtFile>, bindingContext: BindingContext, errorPolicy: ErrorTolerancePolicy) {
AnalyzingUtils.throwExceptionOnErrors(bindingContext) if (!errorPolicy.allowSemanticErrors) {
for (file in allFiles) { AnalyzingUtils.throwExceptionOnErrors(bindingContext)
AnalyzingUtils.checkForSyntacticErrors(file) }
if (!errorPolicy.allowSyntaxErrors) {
for (file in allFiles) {
AnalyzingUtils.checkForSyntacticErrors(file)
}
} }
} }
} }
@@ -0,0 +1,27 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.js.config
enum class ErrorTolerancePolicy(val allowSyntaxErrors: Boolean, val allowSemanticErrors: Boolean) {
NONE(false, false),
SEMANTIC(false, true),
ALL(true, true);
val allowErrors: Boolean get() = allowSyntaxErrors || allowSemanticErrors
companion object {
val DEFAULT = NONE
fun resolvePolicy(key: String): ErrorTolerancePolicy {
return when (key.toUpperCase()) {
"NONE" -> NONE
"SEMANTIC" -> SEMANTIC
"SYNTAX", "ALL" -> ALL
else -> error("Unknown error tolerance policy '$key'")
}
}
}
}
@@ -86,4 +86,7 @@ public class JSConfigurationKeys {
public static final CompilerConfigurationKey<Boolean> DISABLE_FAKE_OVERRIDE_VALIDATOR = public static final CompilerConfigurationKey<Boolean> DISABLE_FAKE_OVERRIDE_VALIDATOR =
CompilerConfigurationKey.create("disable IR fake override validator"); CompilerConfigurationKey.create("disable IR fake override validator");
public static final CompilerConfigurationKey<ErrorTolerancePolicy> ERROR_TOLERANCE_POLICY =
CompilerConfigurationKey.create("set up policy to ignore compilation errors");
} }
@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.descriptors.IrFunctionFactory import org.jetbrains.kotlin.ir.descriptors.IrFunctionFactory
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS
import org.jetbrains.kotlin.js.config.ErrorTolerancePolicy
import org.jetbrains.kotlin.js.config.JSConfigurationKeys import org.jetbrains.kotlin.js.config.JSConfigurationKeys
import org.jetbrains.kotlin.library.KotlinAbiVersion import org.jetbrains.kotlin.library.KotlinAbiVersion
import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.KotlinLibrary
@@ -441,7 +442,7 @@ class GenerateIrRuntime {
) )
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
TopDownAnalyzerFacadeForJS.checkForErrors(files, analysisResult.bindingContext) TopDownAnalyzerFacadeForJS.checkForErrors(files, analysisResult.bindingContext, ErrorTolerancePolicy.NONE)
return analysisResult return analysisResult
} }
@@ -46,6 +46,7 @@ import org.jetbrains.kotlin.js.backend.ast.JsBlock
import org.jetbrains.kotlin.js.backend.ast.JsName import org.jetbrains.kotlin.js.backend.ast.JsName
import org.jetbrains.kotlin.js.backend.ast.JsProgramFragment import org.jetbrains.kotlin.js.backend.ast.JsProgramFragment
import org.jetbrains.kotlin.js.backend.ast.JsStatement import org.jetbrains.kotlin.js.backend.ast.JsStatement
import org.jetbrains.kotlin.js.config.ErrorTolerancePolicy
import org.jetbrains.kotlin.js.coroutine.transformCoroutines import org.jetbrains.kotlin.js.coroutine.transformCoroutines
import org.jetbrains.kotlin.js.inline.util.collectDefinedNamesInAllScopes import org.jetbrains.kotlin.js.inline.util.collectDefinedNamesInAllScopes
import org.jetbrains.kotlin.js.translate.general.SourceFileTranslationResult import org.jetbrains.kotlin.js.translate.general.SourceFileTranslationResult
@@ -114,7 +115,7 @@ class K2JSTranslator @JvmOverloads constructor(
packageMetadata: MutableMap<FqName, ByteArray> packageMetadata: MutableMap<FqName, ByteArray>
): TranslationResult { ): TranslationResult {
val bindingTrace = analysisResult.bindingTrace val bindingTrace = analysisResult.bindingTrace
TopDownAnalyzerFacadeForJS.checkForErrors(files, bindingTrace.bindingContext) TopDownAnalyzerFacadeForJS.checkForErrors(files, bindingTrace.bindingContext, ErrorTolerancePolicy.NONE)
val moduleDescriptor = analysisResult.moduleDescriptor val moduleDescriptor = analysisResult.moduleDescriptor
val diagnostics = bindingTrace.bindingContext.diagnostics val diagnostics = bindingTrace.bindingContext.diagnostics
val pathResolver = SourceFilePathResolver.create(config) val pathResolver = SourceFilePathResolver.create(config)
@@ -154,7 +155,7 @@ class K2JSTranslator @JvmOverloads constructor(
packageMetadata: MutableMap<FqName, ByteArray> packageMetadata: MutableMap<FqName, ByteArray>
): TranslationResult { ): TranslationResult {
val bindingTrace = analysisResult.bindingTrace val bindingTrace = analysisResult.bindingTrace
TopDownAnalyzerFacadeForJS.checkForErrors(files, bindingTrace.bindingContext) TopDownAnalyzerFacadeForJS.checkForErrors(files, bindingTrace.bindingContext, ErrorTolerancePolicy.NONE)
val moduleDescriptor = analysisResult.moduleDescriptor val moduleDescriptor = analysisResult.moduleDescriptor
val diagnostics = bindingTrace.bindingContext.diagnostics val diagnostics = bindingTrace.bindingContext.diagnostics
val pathResolver = SourceFilePathResolver.create(config) val pathResolver = SourceFilePathResolver.create(config)