[JS Test] Support RECOMPILE directive in js box tests in new infrastructure

This commit is contained in:
Dmitriy Novozhilov
2021-10-20 13:04:19 +03:00
committed by Ivan Kylchik
parent 13d3b7c0b8
commit af0e40a0d2
20 changed files with 541 additions and 177 deletions
@@ -36,10 +36,6 @@ fun main(args: Array<String>) {
generateTestGroupSuite(args) {
testGroup("js/js.tests/tests-gen", "js/js.translator/testData", testRunnerMethodName = "runTest0") {
testClass<org.jetbrains.kotlin.js.test.semantics.AbstractBoxJsTest> {
model("box/incremental/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS)
}
testClass<AbstractIrBoxJsTest> {
model("box/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS_IR)
}
@@ -126,8 +122,8 @@ fun main(args: Array<String>) {
generateTestGroupSuiteWithJUnit5(args) {
testGroup("js/js.tests/tests-gen", "js/js.translator/testData", testRunnerMethodName = "runTest0") {
testClass<org.jetbrains.kotlin.js.testNew.AbstractBoxJsTest> {
model("box/", pattern = "^([^_](.+))\\.kt$", excludeDirs = listOf("incremental"))
testClass<AbstractBoxJsTest> {
model("box/", pattern = "^([^_](.+))\\.kt$")
}
testClass<AbstractSourceMapGenerationSmokeTest> {
@@ -1,16 +0,0 @@
/*
* 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.test.semantics
import org.jetbrains.kotlin.js.test.BasicBoxTest
abstract class AbstractBoxJsTest : BasicBoxTest(
TEST_DATA_DIR_PATH + "box/",
"box/"
) {
override val runMinifierByDefault: Boolean = true
}
@@ -5,10 +5,8 @@
package org.jetbrains.kotlin.js.testNew
import org.jetbrains.kotlin.js.testNew.handlers.JsArtifactsDumpHandler
import org.jetbrains.kotlin.js.testNew.handlers.JsBoxRunner
import org.jetbrains.kotlin.js.testNew.handlers.JsMinifierRunner
import org.jetbrains.kotlin.js.testNew.handlers.NodeJsGeneratorHandler
import org.jetbrains.kotlin.js.testNew.handlers.*
import org.jetbrains.kotlin.js.testNew.utils.JsIncrementalEnvironmentConfigurator
import org.jetbrains.kotlin.platform.js.JsPlatforms
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.TargetBackend
@@ -37,6 +35,7 @@ abstract class AbstractJsBlackBoxCodegenTestBase<R : ResultingArtifact.FrontendO
abstract val frontendFacade: Constructor<FrontendFacade<R>>
abstract val frontendToBackendConverter: Constructor<Frontend2BackendConverter<R, I>>
abstract val backendFacade: Constructor<BackendFacade<I, BinaryArtifacts.Js>>
abstract val recompileFacade: Constructor<AbstractTestFacade<BinaryArtifacts.Js, BinaryArtifacts.Js>>
override fun TestConfigurationBuilder.configuration() {
globalDefaults {
@@ -58,6 +57,7 @@ abstract class AbstractJsBlackBoxCodegenTestBase<R : ResultingArtifact.FrontendO
useConfigurators(
::CommonEnvironmentConfigurator,
::JsEnvironmentConfigurator,
::JsIncrementalEnvironmentConfigurator
)
useAdditionalSourceProviders(
@@ -80,12 +80,14 @@ abstract class AbstractJsBlackBoxCodegenTestBase<R : ResultingArtifact.FrontendO
irHandlersStep()
facadeStep(backendFacade)
facadeStep(recompileFacade)
jsArtifactsHandlersStep {
useHandlers(
::JsBoxRunner,
::NodeJsGeneratorHandler,
::JsMinifierRunner,
::JsArtifactsDumpHandler,
::JsRecompiledArtifactsIdentityHandler
)
}
}
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.js.testNew
import org.jetbrains.kotlin.js.testNew.converters.ClassicJsBackendFacade
import org.jetbrains.kotlin.js.testNew.converters.RecompileModuleJsBackendFacade
import org.jetbrains.kotlin.js.testNew.handlers.*
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.TargetBackend
@@ -34,6 +35,9 @@ abstract class AbstractJsTest(
override val backendFacade: Constructor<BackendFacade<ClassicBackendInput, BinaryArtifacts.Js>>
get() = ::ClassicJsBackendFacade
override val recompileFacade: Constructor<AbstractTestFacade<BinaryArtifacts.Js, BinaryArtifacts.Js>>
get() = { RecompileModuleJsBackendFacade(it, frontendFacade, frontendToBackendConverter) }
override fun configure(builder: TestConfigurationBuilder) {
super.configure(builder)
with(builder) {
@@ -7,15 +7,16 @@ package org.jetbrains.kotlin.js.testNew.converters
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector
import org.jetbrains.kotlin.cli.common.output.writeAllTo
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumerImpl
import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
import org.jetbrains.kotlin.js.facade.K2JSTranslator
import org.jetbrains.kotlin.js.facade.MainCallParameters
import org.jetbrains.kotlin.js.facade.TranslationResult
import org.jetbrains.kotlin.js.facade.TranslationUnit
import org.jetbrains.kotlin.js.testNew.utils.JsClassicIncrementalDataProvider
import org.jetbrains.kotlin.js.testNew.utils.jsClassicIncrementalDataProvider
import org.jetbrains.kotlin.serialization.js.ModuleKind
import org.jetbrains.kotlin.test.backend.classic.ClassicBackendFacade
import org.jetbrains.kotlin.test.backend.classic.ClassicBackendInput
@@ -23,21 +24,26 @@ import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives
import org.jetbrains.kotlin.test.model.ArtifactKinds
import org.jetbrains.kotlin.test.model.BinaryArtifacts
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.ServiceRegistrationData
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator
import java.io.ByteArrayOutputStream
import org.jetbrains.kotlin.test.services.service
import java.io.File
import java.io.PrintStream
import java.nio.charset.Charset
class ClassicJsBackendFacade(
testServices: TestServices
testServices: TestServices,
val incrementalCompilationEnabled: Boolean
) : ClassicBackendFacade<BinaryArtifacts.Js>(testServices, ArtifactKinds.Js) {
companion object {
const val KOTLIN_TEST_INTERNAL = "\$kotlin_test_internal\$"
}
constructor(testServices: TestServices) : this(testServices, incrementalCompilationEnabled = false)
override val additionalServices: List<ServiceRegistrationData>
get() = listOf(service(::JsClassicIncrementalDataProvider))
private fun wrapWithModuleEmulationMarkers(content: String, moduleKind: ModuleKind, moduleId: String): String {
val escapedModuleId = StringUtil.escapeStringCharacters(moduleId)
@@ -57,13 +63,25 @@ class ClassicJsBackendFacade(
}
}
override fun transform(module: TestModule, inputArtifact: ClassicBackendInput): BinaryArtifacts.Js? {
override fun transform(module: TestModule, inputArtifact: ClassicBackendInput): BinaryArtifacts.Js {
val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
val (psiFiles, analysisResult, project, _) = inputArtifact
// TODO how to reuse this config from frontend
val jsConfig = JsEnvironmentConfigurator.createJsConfig(project, configuration)
val units = psiFiles.map(TranslationUnit::SourceFile)
val unitsByPath: MutableMap<String, TranslationUnit> = psiFiles.associateTo(mutableMapOf()) {
(it.virtualFile.canonicalPath ?: "") to TranslationUnit.SourceFile(it)
}
if (incrementalCompilationEnabled) {
val incrementalData = testServices.jsClassicIncrementalDataProvider.getIncrementalData(module)
for ((file, data) in incrementalData.translatedFiles) {
unitsByPath[file.canonicalPath] = TranslationUnit.BinaryAst(data.binaryAst, data.inlineData)
}
}
val units = unitsByPath.entries.sortedBy { it.key }.map { it.value }
val mainCallParameters = when (JsEnvironmentConfigurationDirectives.CALL_MAIN) {
in module.directives -> MainCallParameters.mainWithArguments(listOf())
else -> MainCallParameters.noCall()
@@ -74,6 +92,22 @@ class ClassicJsBackendFacade(
JsEnvironmentConfigurator.Companion.ExceptionThrowingReporter, units, mainCallParameters, analysisResult as? JsAnalysisResult
)
if (!incrementalCompilationEnabled) {
jsConfig.configuration[JSConfigurationKeys.INCREMENTAL_RESULTS_CONSUMER]?.let {
val incrementalData = JsClassicIncrementalDataProvider.IncrementalData()
val incrementalService = it as IncrementalResultsConsumerImpl
for ((srcFile, data) in incrementalService.packageParts) {
incrementalData.translatedFiles[srcFile] = data
}
incrementalData.packageMetadata += incrementalService.packageMetadata
incrementalData.header = incrementalService.headerMetadata
testServices.jsClassicIncrementalDataProvider.recordIncrementalData(module, incrementalData)
}
}
val outputFile = File(JsEnvironmentConfigurator.getJsModuleArtifactPath(testServices, module.name) + ".js")
if (translationResult !is TranslationResult.Success) {
return BinaryArtifacts.Js.OldJsArtifact(outputFile, translationResult)
@@ -92,4 +126,4 @@ class ClassicJsBackendFacade(
return BinaryArtifacts.Js.OldJsArtifact(outputFile, translationResult)
}
}
}
@@ -0,0 +1,99 @@
/*
* Copyright 2010-2021 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.testNew.converters
import com.intellij.openapi.util.io.FileUtil
import org.jetbrains.kotlin.js.parser.sourcemaps.SourceMapParser
import org.jetbrains.kotlin.js.parser.sourcemaps.SourceMapSuccess
import org.jetbrains.kotlin.js.testNew.utils.jsClassicIncrementalDataProvider
import org.jetbrains.kotlin.test.*
import org.jetbrains.kotlin.test.backend.classic.ClassicBackendInput
import org.jetbrains.kotlin.test.builders.testConfiguration
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives.RECOMPILE
import org.jetbrains.kotlin.test.impl.testConfiguration
import org.jetbrains.kotlin.test.model.*
import org.jetbrains.kotlin.test.services.*
import org.jetbrains.kotlin.test.services.impl.TestModuleStructureImpl
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.PrintStream
import java.nio.charset.Charset
@Suppress("warnings")
class RecompileModuleJsBackendFacade<R : ResultingArtifact.FrontendOutput<R>>(
val testServices: TestServices,
private val frontendFacade: Constructor<FrontendFacade<R>>,
private val frontend2BackendConverter: Constructor<Frontend2BackendConverter<R, ClassicBackendInput>>
) : AbstractTestFacade<BinaryArtifacts.Js, BinaryArtifacts.Js>() {
override val inputKind: ArtifactKinds.Js
get() = ArtifactKinds.Js
override val outputKind: ArtifactKinds.Js
get() = ArtifactKinds.Js
@OptIn(TestInfrastructureInternals::class)
override fun transform(module: TestModule, inputArtifact: BinaryArtifacts.Js): BinaryArtifacts.Js {
val filesToRecompile = module.files.filter { RECOMPILE in it.directives }
if (filesToRecompile.isEmpty()) return inputArtifact
val builder = testServices.testConfiguration.originalBuilder
val incrementalConfiguration = testConfiguration(builder.testDataPath) {
assertions = builder.assertions
testInfo = builder.testInfo
startingArtifactFactory = builder.startingArtifactFactory
useSourcePreprocessor(*builder.sourcePreprocessors.toTypedArray())
useMetaInfoProcessors(*builder.additionalMetaInfoProcessors.toTypedArray())
useConfigurators(*builder.environmentConfigurators.toTypedArray())
useDirectives(*builder.directives.toTypedArray())
useAdditionalServices(*builder.additionalServices.toTypedArray())
builder.globalDefaultsConfigurators.forEach { globalDefaults(it) }
builder.defaultDirectiveConfigurators.forEach { defaultDirectives(it) }
builder.configurationsByPositiveTestDataCondition.forEach { (regex, init) -> forTestsMatching(regex, init) }
builder.configurationsByNegativeTestDataCondition.forEach { (regex, init) -> forTestsNotMatching(regex, init) }
facadeStep(frontendFacade)
facadeStep(frontend2BackendConverter)
facadeStep { ClassicJsBackendFacade(it, incrementalCompilationEnabled = true) }
}
val moduleStructure = testServices.moduleStructure
val incrementalModule = module.copy(files = filesToRecompile)
val incrementalModuleStructure = TestModuleStructureImpl(
moduleStructure.modules.map {
if (it != module) return@map it
else incrementalModule
},
moduleStructure.originalTestDataFiles
)
val incrementalRunner = TestRunner(incrementalConfiguration)
val incrementalDependencyProvider = testServices.dependencyProvider.copy().also {
it.unregisterAllArtifacts(module)
} as DependencyProviderImpl
val incrementalServices = incrementalConfiguration.testServices
incrementalServices.registerDependencyProvider(incrementalDependencyProvider)
incrementalServices.register(TestModuleStructure::class, incrementalModuleStructure)
incrementalServices.register(TemporaryDirectoryManager::class, testServices.temporaryDirectoryManager)
val incrementalData = testServices.jsClassicIncrementalDataProvider.getIncrementalData(module).copy()
for (testFile in filesToRecompile) {
incrementalData.translatedFiles.remove(File("/${testFile.relativePath}"))
}
incrementalServices.jsClassicIncrementalDataProvider.recordIncrementalData(
module,
incrementalData
)
incrementalRunner.processModule(incrementalModule, incrementalDependencyProvider)
incrementalRunner.reportFailures(incrementalServices)
val incrementalArtifact = incrementalDependencyProvider.getArtifact(incrementalModule, ArtifactKinds.Js)
return BinaryArtifacts.Js.IncrementalJsArtifact(inputArtifact, incrementalArtifact)
}
override fun shouldRunAnalysis(module: TestModule): Boolean {
return module.targetBackend == TargetBackend.JS && module.files.any { RECOMPILE in it.directives }
}
}
@@ -25,7 +25,7 @@ class JsAstHandler(testServices: TestServices) : JsBinaryArtifactHandler(testSer
override fun processModule(module: TestModule, info: BinaryArtifacts.Js) {
val ktFiles = module.files.filter { it.isKtFile }.map { it.originalContent }
val result = (info as? BinaryArtifacts.Js.OldJsArtifact)?.translationResult
val result = (info.unwrap() as? BinaryArtifacts.Js.OldJsArtifact)?.translationResult
?: throw IllegalArgumentException("JsBoxRunner suppose to work only with old js backend")
processJsProgram((result as TranslationResult.Success).program, ktFiles, module.targetBackend!!) {
testServices.assertions.fail { it }
@@ -59,4 +59,4 @@ class JsAstHandler(testServices: TestServices) : JsBinaryArtifactHandler(testSer
})
}
}
}
}
@@ -0,0 +1,70 @@
/*
* Copyright 2010-2021 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.testNew.handlers
import com.intellij.openapi.util.io.FileUtil
import org.jetbrains.kotlin.js.parser.sourcemaps.SourceMapParser
import org.jetbrains.kotlin.js.parser.sourcemaps.SourceMapSuccess
import org.jetbrains.kotlin.test.backend.handlers.JsBinaryArtifactHandler
import org.jetbrains.kotlin.test.model.BinaryArtifacts.Js
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.PrintStream
import java.nio.charset.Charset
class JsRecompiledArtifactsIdentityHandler(testServices: TestServices) : JsBinaryArtifactHandler(testServices) {
override fun processModule(module: TestModule, info: Js) {
if (info !is Js.IncrementalJsArtifact) return
val (originalArtifact, incrementalArtifact) = info
when {
originalArtifact is Js.OldJsArtifact && incrementalArtifact is Js.OldJsArtifact -> {
compareArtifacts(originalArtifact, incrementalArtifact)
}
else -> assertions.fail {
"""
Incompatible types of original and incremental artifacts:
original: ${originalArtifact::class}
incremental: ${incrementalArtifact::class}
""".trimIndent()
}
}
}
private fun compareArtifacts(originalArtifact: Js.OldJsArtifact, incrementalArtifact: Js.OldJsArtifact) {
val originalSourceMap = FileUtil.loadFile(File(originalArtifact.outputFile.parentFile, originalArtifact.outputFile.name + ".map"))
val recompiledSourceMap =
removeRecompiledSuffix(
FileUtil.loadFile(File(incrementalArtifact.outputFile.parentFile, incrementalArtifact.outputFile.name + ".map"))
)
if (originalSourceMap != recompiledSourceMap) {
val originalSourceMapParse = SourceMapParser.parse(originalSourceMap)
val recompiledSourceMapParse = SourceMapParser.parse(recompiledSourceMap)
if (originalSourceMapParse is SourceMapSuccess && recompiledSourceMapParse is SourceMapSuccess) {
testServices.assertions.assertEquals(
originalSourceMapParse.toDebugString(),
recompiledSourceMapParse.toDebugString(),
) { "Source map file changed after recompilation" }
}
testServices.assertions.assertEquals(originalSourceMap, recompiledSourceMap) { "Source map file changed after recompilation" }
}
}
private fun SourceMapSuccess.toDebugString(): String {
val out = ByteArrayOutputStream()
PrintStream(out).use { value.debug(it) }
return String(out.toByteArray(), Charset.forName("UTF-8"))
}
private fun removeRecompiledSuffix(text: String): String = text.replace("-recompiled.js", ".js")
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {}
}
@@ -34,7 +34,7 @@ class JsSourceMapHandler(testServices: TestServices) : JsBinaryArtifactHandler(t
override fun processModule(module: TestModule, info: BinaryArtifacts.Js) {
val outputFile = File(JsEnvironmentConfigurator.getJsModuleArtifactPath(testServices, module.name))
val result = (info as? BinaryArtifacts.Js.OldJsArtifact)?.translationResult
val result = (info.unwrap() as? BinaryArtifacts.Js.OldJsArtifact)?.translationResult
?: throw IllegalArgumentException("JsBoxRunner suppose to work only with old js backend")
val remap = JsEnvironmentConfigurationDirectives.SKIP_SOURCEMAP_REMAPPING !in module.directives
checkSourceMap(outputFile, (result as TranslationResult.Success).program, remap) { expected, actual ->
@@ -98,4 +98,4 @@ class JsSourceMapHandler(testServices: TestServices) : JsBinaryArtifactHandler(t
})
}
}
}
}
@@ -21,7 +21,7 @@ class JsTranslationResultHandler(testServices: TestServices) : JsBinaryArtifactH
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {}
override fun processModule(module: TestModule, info: BinaryArtifacts.Js) {
val result = (info as? BinaryArtifacts.Js.OldJsArtifact)?.translationResult
val result = (info.unwrap() as? BinaryArtifacts.Js.OldJsArtifact)?.translationResult
?: throw IllegalArgumentException("JsTranslationResultHandler suppose to work only with old js backend")
if (result !is TranslationResult.Success) {
@@ -32,4 +32,4 @@ class JsTranslationResultHandler(testServices: TestServices) : JsBinaryArtifactH
throw AssertionError("The following errors occurred compiling test:\n$messages")
}
}
}
}
@@ -0,0 +1,44 @@
/*
* Copyright 2010-2021 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.testNew.utils
import org.jetbrains.kotlin.incremental.js.TranslationResultValue
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestService
import org.jetbrains.kotlin.test.services.TestServices
import java.io.File
class JsClassicIncrementalDataProvider(private val testServices: TestServices) : TestService {
class IncrementalData(
var header: ByteArray? = null,
val translatedFiles: MutableMap<File, TranslationResultValue> = hashMapOf(),
val packageMetadata: MutableMap<String, ByteArray> = hashMapOf()
) {
fun copy(): IncrementalData {
return IncrementalData(
header?.clone(),
translatedFiles.toMutableMap(),
packageMetadata.toMutableMap()
)
}
}
private val cache: MutableMap<TestModule, IncrementalData> = mutableMapOf()
fun recordIncrementalData(module: TestModule, incrementalData: IncrementalData) {
cache[module] = incrementalData
}
fun getIncrementalData(module: TestModule): IncrementalData {
return cache.getValue(module)
}
fun getIncrementalDataIfAny(module: TestModule): IncrementalData? {
return cache[module]
}
}
val TestServices.jsClassicIncrementalDataProvider: JsClassicIncrementalDataProvider by TestServices.testServiceAccessor()
@@ -0,0 +1,39 @@
/*
* Copyright 2010-2021 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.testNew.utils
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.incremental.js.IncrementalDataProviderImpl
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumerImpl
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.EnvironmentConfigurator
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.utils.JsMetadataVersion
class JsIncrementalEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigurator(testServices) {
override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule) {
if (module.files.any { JsEnvironmentConfigurationDirectives.RECOMPILE in it.directives }) {
val incrementalData = testServices.jsClassicIncrementalDataProvider.getIncrementalDataIfAny(module)
val header = incrementalData?.header
if (header != null) {
configuration.put(
JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER,
IncrementalDataProviderImpl(
header,
incrementalData.translatedFiles,
JsMetadataVersion.INSTANCE.toArray(),
incrementalData.packageMetadata,
emptyMap()
)
)
}
configuration.put(JSConfigurationKeys.INCREMENTAL_RESULTS_CONSUMER, IncrementalResultsConsumerImpl())
}
}
}