Fix JS line number tests

This commit is contained in:
Alexey Andreev
2017-07-11 16:28:07 +03:00
parent df782eaadd
commit 61ba6e528a
14 changed files with 61 additions and 53 deletions
@@ -210,21 +210,22 @@ class FunctionReader(
FunctionWithWrapper(functionExpr, null)
}
val moduleReference = moduleNameMap[tag]?.deepCopy() ?: currentModuleName.makeRef()
val wrapperStatements = wrapper?.statements?.filter { it !is JsReturn }
val sourceMap = info.sourceMap
if (sourceMap != null) {
val remapper = SourceMapLocationRemapper(sourceMap)
remapper.remap(function)
wrapper?.let { remapper.remap(it) }
wrapperStatements?.forEach { remapper.remap(it) }
}
val replacements = hashMapOf(info.moduleVariable to moduleReference,
info.kotlinVariable to Namer.kotlinObject())
replaceExternalNames(function, replacements)
wrapper?.let { replaceExternalNames(it, replacements) }
wrapperStatements?.forEach { replaceExternalNames(it, replacements) }
function.markInlineArguments(descriptor)
val namesWithoutSizeEffects = wrapper?.statements.orEmpty().asSequence()
val namesWithoutSizeEffects = wrapperStatements.orEmpty().asSequence()
.flatMap { collectDefinedNames(it).asSequence() }
.toSet()
function.accept(object : RecursiveJsVisitor() {
@@ -23,8 +23,11 @@ class NameReplacingVisitor(private val replaceMap: Map<JsName, JsExpression>) :
override fun endVisit(x: JsNameRef, ctx: JsContext<JsNode>) {
if (x.qualifier != null) return
val replacement = replaceMap[x.name] ?: return
val replacementCopy = accept(replacement.deepCopy().source(x.source))
ctx.replaceMe(replacementCopy)
val replacementCopy = replacement.deepCopy()
if (x.source != null) {
replacementCopy.source = x.source
}
ctx.replaceMe(accept(replacementCopy))
}
override fun endVisit(x: JsVars.JsVar, ctx: JsContext<*>) = applyToNamedNode(x)
@@ -40,8 +40,6 @@ import org.jetbrains.kotlin.js.test.utils.LineCollector
import org.jetbrains.kotlin.js.test.utils.LineOutputToStringVisitor
import org.jetbrains.kotlin.js.util.TextOutputImpl
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.serialization.js.JsModuleDescriptor
import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil
import org.jetbrains.kotlin.serialization.js.ModuleKind
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.KotlinTestWithEnvironment
@@ -91,17 +89,13 @@ abstract class AbstractJsLineNumberTest : KotlinTestWithEnvironment() {
writeText(generatedCode)
}
File(baseOutputPath + ".js").writeText(translationResult.program.globalBlock.toString())
val moduleDescription = JsModuleDescriptor(
name = module.name,
data = translationResult.moduleDescriptor,
kind = ModuleKind.PLAIN,
imported = emptyList()
)
val metaFileContent = KotlinJavascriptSerializationUtil.metadataAsString(
translationResult.bindingContext, moduleDescription)
File(baseOutputPath + ".meta.js").writeText(metaFileContent)
val baseDir = File(baseOutputPath).parentFile
for (outputFile in translationResult.getOutputFiles(File(baseOutputPath + ".js"), null, null).asList()) {
with (File(baseDir, outputFile.relativePath)) {
parentFile.mkdirs()
writeBytes(outputFile.asByteArray())
}
}
val linesMatcher = module.files
.mapNotNull { LINES_PATTERN.find(File(it.fileName).readText()) }
@@ -118,15 +112,12 @@ abstract class AbstractJsLineNumberTest : KotlinTestWithEnvironment() {
}
}
private fun TestModule.outputFileName(file: File): String {
return outputPath(file) + "-" + name
}
private fun TestModule.outputFileName(file: File): String = outputPath(file) + "-" + name
private fun outputPath(file: File) = File(OUT_PATH, file.relativeTo(File(BASE_PATH)).path.removeSuffix(".kt")).path
override fun createEnvironment(): KotlinCoreEnvironment {
return KotlinCoreEnvironment.createForTests(testRootDisposable, CompilerConfiguration(), EnvironmentConfigFiles.JS_CONFIG_FILES)
}
override fun createEnvironment(): KotlinCoreEnvironment =
KotlinCoreEnvironment.createForTests(testRootDisposable, CompilerConfiguration(), EnvironmentConfigFiles.JS_CONFIG_FILES)
private fun createConfig(module: TestModule, inputFile: File, modules: Map<String, TestModule>): JsConfig {
val dependencies = module.dependencies
@@ -135,13 +126,14 @@ abstract class AbstractJsLineNumberTest : KotlinTestWithEnvironment() {
val configuration = environment.configuration.copy()
configuration.put(JSConfigurationKeys.LIBRARIES, JsConfig.JS_STDLIB + JsConfig.JS_KOTLIN_TEST + dependencies )
configuration.put(JSConfigurationKeys.LIBRARIES, JsConfig.JS_STDLIB + JsConfig.JS_KOTLIN_TEST + dependencies)
configuration.put(CommonConfigurationKeys.MODULE_NAME, module.name)
configuration.put(JSConfigurationKeys.MODULE_KIND, ModuleKind.PLAIN)
configuration.put(JSConfigurationKeys.TARGET, EcmaVersion.v5)
configuration.put(JSConfigurationKeys.SOURCE_MAP, true)
configuration.put(JSConfigurationKeys.META_INFO, true)
return JsConfig(project, configuration)
}
@@ -154,8 +146,8 @@ abstract class AbstractJsLineNumberTest : KotlinTestWithEnvironment() {
}
private inner class TestFileFactoryImpl : KotlinTestUtils.TestFileFactory<TestModule, TestFile>, Closeable {
val tmpDir = KotlinTestUtils.tmpDir("js-tests")
val defaultModule = TestModule(BasicBoxTest.TEST_MODULE, emptyList())
private val tmpDir = KotlinTestUtils.tmpDir("js-tests")
private val defaultModule = TestModule(BasicBoxTest.TEST_MODULE, emptyList())
override fun createFile(module: TestModule?, fileName: String, text: String, directives: Map<String, String>): TestFile? {
val currentModule = module ?: defaultModule
@@ -168,9 +160,7 @@ abstract class AbstractJsLineNumberTest : KotlinTestWithEnvironment() {
return TestFile(temporaryFile.absolutePath, currentModule)
}
override fun createModule(name: String, dependencies: List<String>, friends: List<String>): TestModule? {
return TestModule(name, dependencies)
}
override fun createModule(name: String, dependencies: List<String>, friends: List<String>) = TestModule(name, dependencies)
override fun close() {
FileUtil.delete(tmpDir)
@@ -500,7 +500,7 @@ abstract class BasicBoxTest(
configuration.put(JSConfigurationKeys.INCREMENTAL_RESULTS_CONSUMER, IncrementalResultsConsumerImpl())
}
configuration.put(JSConfigurationKeys.SOURCE_MAP, hasFilesToRecompile || generateSourceMap)
configuration.put(JSConfigurationKeys.SOURCE_MAP, true)
configuration.put(JSConfigurationKeys.SOURCE_MAP_SOURCE_ROOTS, sourceDirs)
configuration.put(JSConfigurationKeys.SOURCE_MAP_EMBED_SOURCES, module.sourceMapSourceEmbedding)
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyPublicApi
import org.jetbrains.kotlin.resolve.source.getPsi
import org.jetbrains.kotlin.resolve.source.PsiSourceFile
fun TranslationContext.translateAndAliasParameters(
@@ -101,9 +102,10 @@ fun TranslationContext.translateFunction(declaration: KtDeclarationWithBody, fun
}
fun TranslationContext.wrapWithInlineMetadata(function: JsFunction, descriptor: FunctionDescriptor): JsExpression {
val sourceInfo = descriptor.source.getPsi()
return if (descriptor.isInline && descriptor.isEffectivelyPublicApi) {
val metadata = InlineMetadata.compose(function, descriptor, this)
val functionWithMetadata = metadata.functionWithMetadata
val functionWithMetadata = metadata.functionWithMetadata(sourceInfo)
config.configuration[JSConfigurationKeys.INCREMENTAL_RESULTS_CONSUMER]?.apply {
val psiFile = (descriptor.source.containingFile as? PsiSourceFile)?.psiFile ?: return@apply
@@ -134,6 +136,6 @@ fun TranslationContext.wrapWithInlineMetadata(function: JsFunction, descriptor:
else {
null
}
if (block != null) InlineMetadata.wrapFunction(FunctionWithWrapper(function, block)) else function
if (block != null) InlineMetadata.wrapFunction(FunctionWithWrapper(function, block), sourceInfo) else function
}
}
@@ -78,15 +78,22 @@ class InlineMetadata(val tag: JsStringLiteral, val function: FunctionWithWrapper
}
@JvmStatic
fun wrapFunction(function: FunctionWithWrapper): JsExpression {
fun wrapFunction(function: FunctionWithWrapper, sourceInfo: Any?): JsExpression {
val wrapperBody = function.wrapperBody ?: JsBlock(JsReturn(function.function))
val wrapper = JsFunction(function.function.scope, wrapperBody, "")
return JsInvocation(Namer.wrapFunction(), wrapper)
function.wrapperBody?.statements?.forEach {
if (it is JsExpressionStatement) {
it.expression.source = sourceInfo
}
else {
it.source = sourceInfo
}
}
return JsInvocation(Namer.wrapFunction(), wrapper).source(sourceInfo)
}
}
val functionWithMetadata: JsExpression
get() {
return JsInvocation(Namer.createInlineFunction(), tag, wrapFunction(function))
}
fun functionWithMetadata(sourceInfo: Any?): JsExpression =
JsInvocation(Namer.createInlineFunction(), tag, wrapFunction(function, sourceInfo))
}
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.js.translate.utils.TranslationUtils.simpleReturnFunc
import org.jetbrains.kotlin.js.translate.utils.addFunctionButNotExport
import org.jetbrains.kotlin.js.translate.utils.fillCoroutineMetadata
import org.jetbrains.kotlin.js.translate.utils.finalElement
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtDeclarationWithBody
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
@@ -77,7 +78,7 @@ class LiteralFunctionTranslator(context: TranslationContext) : AbstractTranslato
name.staticRef = lambdaCreator
lambdaCreator.fillCoroutineMetadata(invokingContext, descriptor)
lambdaCreator.source = declaration
return lambdaCreator.withCapturedParameters(functionContext, name, invokingContext)
return lambdaCreator.withCapturedParameters(functionContext, name, invokingContext, declaration)
}
if (descriptor in tracker.capturedDescriptors) {
@@ -89,7 +90,7 @@ class LiteralFunctionTranslator(context: TranslationContext) : AbstractTranslato
lambda.isLocal = true
invokingContext.addFunctionDeclaration(name, lambda)
invokingContext.addFunctionDeclaration(name, lambda, declaration)
lambda.fillCoroutineMetadata(invokingContext, descriptor)
name.staticRef = lambda
return JsAstUtils.pureFqn(name, null)
@@ -111,9 +112,9 @@ class LiteralFunctionTranslator(context: TranslationContext) : AbstractTranslato
}
}
private fun TranslationContext.addFunctionDeclaration(name: JsName, function: JsFunction) {
private fun TranslationContext.addFunctionDeclaration(name: JsName, function: JsFunction, source: Any?) {
addFunctionButNotExport(name, if (isPublicInlineFunction) {
InlineMetadata.wrapFunction(FunctionWithWrapper(function, null))
InlineMetadata.wrapFunction(FunctionWithWrapper(function, null), source)
}
else {
function
@@ -123,9 +124,10 @@ private fun TranslationContext.addFunctionDeclaration(name: JsName, function: Js
fun JsFunction.withCapturedParameters(
context: TranslationContext,
functionName: JsName,
invokingContext: TranslationContext
invokingContext: TranslationContext,
source: KtDeclaration
): JsExpression {
context.addFunctionDeclaration(functionName, this)
context.addFunctionDeclaration(functionName, this, source)
val ref = JsAstUtils.pureFqn(functionName, null)
val invocation = JsInvocation(ref).apply { sideEffects = SideEffectKind.PURE }
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.js.translate.utils;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
@@ -39,6 +40,7 @@ import org.jetbrains.kotlin.resolve.BindingContextUtils;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.TypeUtils;
@@ -62,7 +64,8 @@ public final class TranslationUtils {
JsExpression functionExpression = function;
if (InlineUtil.isInline(descriptor)) {
InlineMetadata metadata = InlineMetadata.compose(function, descriptor, context);
functionExpression = metadata.getFunctionWithMetadata();
PsiElement sourceInfo = KotlinSourceElementKt.getPsi(descriptor.getSource());
functionExpression = metadata.functionWithMetadata(sourceInfo);
}
if (DescriptorUtils.isExtension(descriptor) ||
+1 -1
View File
@@ -17,4 +17,4 @@ fun bar(a: String, b: Char, x: Int) {
a.foo(b)
}
// LINES: 6 4 4 5 5 11 9 9 10 10 18 14 14 14 14 14 15 17 17 9 9 14 10 17 10 14 14 * 1 * 1
// LINES: 6 4 4 5 5 8 8 8 8 8 11 9 9 10 10 18 14 14 14 14 14 15 17 17 9 9 14 10 17 10 14 14 * 1 * 1
@@ -9,4 +9,4 @@ fun bar() {
foo(42)
}
// LINES: 6 2 2 3 3 4 4 10 2 2 9 2 3 3 4 4
// LINES: 1 1 1 1 1 6 2 2 3 3 4 4 10 2 2 9 2 3 3 4 4
@@ -8,7 +8,7 @@ inline fun foo(x: String) {
println("foo2($x);")
}
// LINES: 9 7 7 8 8
// LINES: 6 6 6 6 6 9 7 7 8 8
// MODULE: main(lib)
// FILE: main.kt
@@ -21,4 +21,4 @@ fun box() {
foo("42")
}
// LINES: 22 7 7 20 7 8 8 20 8 7 7 21 7 8 8 21 8
// LINES: 6 6 22 7 7 20 7 8 8 20 8 7 7 21 7 8 8 21 8
+1 -1
View File
@@ -21,4 +21,4 @@ fun bar(x: Int) {
println("%")
}
// LINES: 17 2 2 3 3 4 7 7 9 9 10 10 11 14 14 16 16 22 20 20 20 20 2 2 3 3 4 3 7 7 9 9 10 10 11 10 14 14 16 16 * 20 21 21
// LINES: 1 1 1 1 1 1 1 17 2 2 3 3 4 7 7 9 9 10 10 11 14 14 16 16 22 20 20 20 20 2 2 3 3 4 3 7 7 9 9 10 10 11 10 14 14 16 16 * 20 21 21
+1 -1
View File
@@ -11,4 +11,4 @@ inline fun bar() {
println("bar2")
}
// LINES: 7 2 2 10 10 11 11 4 4 10 10 11 11 6 6 12 10 10 11 11
// LINES: 7 2 2 10 10 11 11 4 4 10 10 11 11 6 6 9 9 9 9 9 12 10 10 11 11
@@ -16,4 +16,4 @@ inline fun foo(f: () -> Unit) {
println("after")
}
// LINES: 11 2 2 14 14 4 4 16 16 6 6 14 14 8 8 16 16 10 10 17 14 14 15 15 16 16
// LINES: 11 2 2 14 14 4 4 16 16 6 6 14 14 8 8 16 16 10 10 13 13 13 13 13 17 14 14 15 15 16 16