diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt index 0309a15bdb4..a9e2c90a927 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt @@ -175,6 +175,9 @@ class K2JSCompilerArguments : CommonCompilerArguments() { @Argument(value = "-Xdisable-fake-override-validator", description = "Disable IR fake override validator") 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) { if (!isIrBackendEnabled()) return diff --git a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt index 012c1dd2221..c170f53124d 100644 --- a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt +++ b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt @@ -35,10 +35,7 @@ import org.jetbrains.kotlin.incremental.js.IncrementalNextRoundChecker import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer import org.jetbrains.kotlin.ir.backend.js.* import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory -import org.jetbrains.kotlin.js.config.EcmaVersion -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.js.config.* import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.serialization.js.ModuleKind @@ -314,6 +311,13 @@ class K2JsIrCompiler : CLICompiler() { configuration.putIfNotNull(CommonConfigurationKeys.LOOKUP_TRACKER, services[LookupTracker::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 var sourceMapContentEmbedding: SourceMapSourceEmbedding? = if (sourceMapEmbedContentString != null) sourceMapContentEmbeddingMap[sourceMapEmbedContentString] diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt index 2132a116acd..05bc49a0205 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt @@ -42,6 +42,7 @@ import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.acceptVoid 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.konan.properties.propertyList import org.jetbrains.kotlin.konan.util.KlibMetadataFactories @@ -106,6 +107,7 @@ fun generateKLib( nopack: Boolean ) { val incrementalDataProvider = configuration.get(JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER) + val errorPolicy = configuration.get(JSConfigurationKeys.ERROR_TOLERANCE_POLICY) ?: ErrorTolerancePolicy.DEFAULT val icData: List val serializedIrFiles: List? @@ -140,7 +142,7 @@ fun generateKLib( val depsDescriptors = 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 functionFactory = IrFunctionFactory(irBuiltIns, psi2IrContext.symbolTable) irBuiltIns.functionFactory = functionFactory @@ -222,10 +224,11 @@ fun loadIr( ): IrModuleInfo { val depsDescriptors = ModulesStructure(project, mainModule, analyzer, configuration, allDependencies, friendDependencies) val deserializeFakeOverrides = configuration.getBoolean(CommonConfigurationKeys.DESERIALIZE_FAKE_OVERRIDES) + val errorPolicy = configuration.get(JSConfigurationKeys.ERROR_TOLERANCE_POLICY) ?: ErrorTolerancePolicy.DEFAULT when (mainModule) { is MainModule.SourceFiles -> { - val psi2IrContext: GeneratorContext = runAnalysisAndPreparePsi2Ir(depsDescriptors, irFactory) + val psi2IrContext: GeneratorContext = runAnalysisAndPreparePsi2Ir(depsDescriptors, irFactory, errorPolicy) val irBuiltIns = psi2IrContext.irBuiltIns val symbolTable = psi2IrContext.symbolTable val functionFactory = IrFunctionFactory(irBuiltIns, symbolTable) @@ -294,9 +297,9 @@ fun loadIr( } } -private fun runAnalysisAndPreparePsi2Ir(depsDescriptors: ModulesStructure, irFactory: IrFactory): GeneratorContext { - val (bindingContext, moduleDescriptor) = depsDescriptors.runAnalysis() - val psi2Ir = Psi2IrTranslator(depsDescriptors.compilerConfiguration.languageVersionSettings, Psi2IrConfiguration()) +private fun runAnalysisAndPreparePsi2Ir(depsDescriptors: ModulesStructure, irFactory: IrFactory, errorIgnorancePolicy: ErrorTolerancePolicy): GeneratorContext { + val (bindingContext, moduleDescriptor) = depsDescriptors.runAnalysis(errorIgnorancePolicy) + val psi2Ir = Psi2IrTranslator(depsDescriptors.compilerConfiguration.languageVersionSettings, Psi2IrConfiguration(errorIgnorancePolicy.allowErrors)) val symbolTable = SymbolTable(IdSignatureDescriptor(JsManglerDesc), irFactory) return psi2Ir.createGeneratorContext(moduleDescriptor, bindingContext, symbolTable) } @@ -380,7 +383,7 @@ private class ModulesStructure( val builtInsDep = allDependencies.getFullList().find { it.isBuiltIns } - fun runAnalysis(): JsAnalysisResult { + fun runAnalysis(errorPolicy: ErrorTolerancePolicy): JsAnalysisResult { require(mainModule is MainModule.SourceFiles) val files = mainModule.files @@ -403,10 +406,11 @@ private class ModulesStructure( /** can throw [IncrementalNextRoundException] */ compareMetadataAndGoToNextICRoundIfNeeded(analysisResult, compilerConfiguration, files) } - if (analyzer.hasErrors() || analysisResult !is JsAnalysisResult) + + if (!errorPolicy.allowErrors && analyzer.hasErrors() || analysisResult !is JsAnalysisResult) throw JsIrCompilationError - TopDownAnalyzerFacadeForJSIR.checkForErrors(files, analysisResult.bindingContext) + TopDownAnalyzerFacadeForJSIR.checkForErrors(files, analysisResult.bindingContext, errorPolicy) return analysisResult } diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.kt index d12674da10b..a8b49a3050b 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider 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.JsConfig import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices @@ -114,10 +115,14 @@ abstract class AbstractTopDownAnalyzerFacadeForJS { return JsAnalysisResult.success(trace, moduleContext.module) } - fun checkForErrors(allFiles: Collection, bindingContext: BindingContext) { - AnalyzingUtils.throwExceptionOnErrors(bindingContext) - for (file in allFiles) { - AnalyzingUtils.checkForSyntacticErrors(file) + fun checkForErrors(allFiles: Collection, bindingContext: BindingContext, errorPolicy: ErrorTolerancePolicy) { + if (!errorPolicy.allowSemanticErrors) { + AnalyzingUtils.throwExceptionOnErrors(bindingContext) + } + if (!errorPolicy.allowSyntaxErrors) { + for (file in allFiles) { + AnalyzingUtils.checkForSyntacticErrors(file) + } } } } diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/config/ErrorTolerancePolicy.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/config/ErrorTolerancePolicy.kt new file mode 100644 index 00000000000..2b6f18a5d12 --- /dev/null +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/config/ErrorTolerancePolicy.kt @@ -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'") + } + } + } +} \ No newline at end of file diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/config/JSConfigurationKeys.java b/js/js.frontend/src/org/jetbrains/kotlin/js/config/JSConfigurationKeys.java index 72529543c7f..dba90aaf3e6 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/config/JSConfigurationKeys.java +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/config/JSConfigurationKeys.java @@ -86,4 +86,7 @@ public class JSConfigurationKeys { public static final CompilerConfigurationKey DISABLE_FAKE_OVERRIDE_VALIDATOR = CompilerConfigurationKey.create("disable IR fake override validator"); + + public static final CompilerConfigurationKey ERROR_TOLERANCE_POLICY = + CompilerConfigurationKey.create("set up policy to ignore compilation errors"); } diff --git a/js/js.tests/test/org/jetbrains/kotlin/benchmarks/GenerateIrRuntime.kt b/js/js.tests/test/org/jetbrains/kotlin/benchmarks/GenerateIrRuntime.kt index 04360aa7833..57852d2c133 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/benchmarks/GenerateIrRuntime.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/benchmarks/GenerateIrRuntime.kt @@ -42,6 +42,7 @@ import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.descriptors.IrFunctionFactory import org.jetbrains.kotlin.ir.util.* 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.library.KotlinAbiVersion import org.jetbrains.kotlin.library.KotlinLibrary @@ -441,7 +442,7 @@ class GenerateIrRuntime { ) ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() - TopDownAnalyzerFacadeForJS.checkForErrors(files, analysisResult.bindingContext) + TopDownAnalyzerFacadeForJS.checkForErrors(files, analysisResult.bindingContext, ErrorTolerancePolicy.NONE) return analysisResult } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.kt index a5e64f6c357..5263705b93c 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.kt @@ -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.JsProgramFragment 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.inline.util.collectDefinedNamesInAllScopes import org.jetbrains.kotlin.js.translate.general.SourceFileTranslationResult @@ -114,7 +115,7 @@ class K2JSTranslator @JvmOverloads constructor( packageMetadata: MutableMap ): TranslationResult { val bindingTrace = analysisResult.bindingTrace - TopDownAnalyzerFacadeForJS.checkForErrors(files, bindingTrace.bindingContext) + TopDownAnalyzerFacadeForJS.checkForErrors(files, bindingTrace.bindingContext, ErrorTolerancePolicy.NONE) val moduleDescriptor = analysisResult.moduleDescriptor val diagnostics = bindingTrace.bindingContext.diagnostics val pathResolver = SourceFilePathResolver.create(config) @@ -154,7 +155,7 @@ class K2JSTranslator @JvmOverloads constructor( packageMetadata: MutableMap ): TranslationResult { val bindingTrace = analysisResult.bindingTrace - TopDownAnalyzerFacadeForJS.checkForErrors(files, bindingTrace.bindingContext) + TopDownAnalyzerFacadeForJS.checkForErrors(files, bindingTrace.bindingContext, ErrorTolerancePolicy.NONE) val moduleDescriptor = analysisResult.moduleDescriptor val diagnostics = bindingTrace.bindingContext.diagnostics val pathResolver = SourceFilePathResolver.create(config)