JS: change the way how DCE resolves input paths

This commit is contained in:
Alexey Andreev
2017-11-17 18:05:08 +03:00
parent 8514a7706f
commit ffdebfab45
13 changed files with 156 additions and 99 deletions
@@ -19,7 +19,10 @@ package org.jetbrains.kotlin.js.dce
import com.google.gwt.dev.js.rhino.CodePosition
import com.google.gwt.dev.js.rhino.ErrorReporter
import org.jetbrains.kotlin.js.backend.JsToStringGenerationVisitor
import org.jetbrains.kotlin.js.backend.ast.*
import org.jetbrains.kotlin.js.backend.ast.JsBlock
import org.jetbrains.kotlin.js.backend.ast.JsGlobalBlock
import org.jetbrains.kotlin.js.backend.ast.JsNode
import org.jetbrains.kotlin.js.backend.ast.JsProgram
import org.jetbrains.kotlin.js.dce.Context.Node
import org.jetbrains.kotlin.js.facade.SourceMapBuilderConsumer
import org.jetbrains.kotlin.js.inline.util.collectDefinedNames
@@ -33,7 +36,6 @@ import org.jetbrains.kotlin.js.sourceMap.SourceFilePathResolver
import org.jetbrains.kotlin.js.sourceMap.SourceMap3Builder
import org.jetbrains.kotlin.js.util.TextOutputImpl
import java.io.File
import java.io.FileInputStream
import java.io.InputStreamReader
class DeadCodeElimination(private val logConsumer: (DCELogLevel, String) -> Unit) {
@@ -41,7 +43,6 @@ class DeadCodeElimination(private val logConsumer: (DCELogLevel, String) -> Unit
private val reachableNames = mutableSetOf<String>()
var reachableNodes = setOf<Node>()
get
private set
fun apply(root: JsNode) {
@@ -82,19 +83,19 @@ class DeadCodeElimination(private val logConsumer: (DCELogLevel, String) -> Unit
var hasErrors = false
val blocks = inputFiles.map { file ->
val block = JsGlobalBlock()
val code = File(file.path).readText()
val statements = parse(code, Reporter(file.path, logConsumer), program.scope, file.path) ?: run {
val code = file.resource.reader().let { InputStreamReader(it, "UTF-8") }.use { it.readText() }
val statements = parse(code, Reporter(file.resource.name, logConsumer), program.scope, file.resource.name) ?: run {
hasErrors = true
return@map block
}
val sourceMapParse = file.pathToSourceMap
?.let { InputStreamReader(FileInputStream(it), "UTF-8") }
val sourceMapParse = file.sourceMapResource
?.let { InputStreamReader(it.reader(), "UTF-8") }
?.use { SourceMapParser.parse(it) }
when (sourceMapParse) {
is SourceMapError -> {
logConsumer(
DCELogLevel.WARN,
"Error parsing source map file ${file.pathToSourceMap}: ${sourceMapParse.message}")
"Error parsing source map file ${file.sourceMapResource}: ${sourceMapParse.message}")
}
is SourceMapSuccess -> {
val sourceMap = sourceMapParse.value
@@ -130,7 +131,7 @@ class DeadCodeElimination(private val logConsumer: (DCELogLevel, String) -> Unit
writeText(textOutput.toString())
}
if (file.pathToSourceMap != null) {
if (file.sourceMapResource != null) {
sourceMapFile.writeText(sourceMapContent)
}
}
@@ -16,4 +16,4 @@
package org.jetbrains.kotlin.js.dce
class InputFile(val path: String, val pathToSourceMap: String?, val outputPath: String, val moduleName: String? = null)
class InputFile(val resource: InputResource, val sourceMapResource: InputResource?, val outputPath: String, val moduleName: String? = null)
@@ -0,0 +1,33 @@
/*
* Copyright 2010-2017 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.js.dce
import java.io.File
import java.io.FileInputStream
import java.io.InputStream
import java.util.zip.ZipFile
class InputResource(val name: String, val reader: () -> InputStream) {
companion object {
fun file(path: String): InputResource = InputResource(path) { FileInputStream(File(path)) }
fun zipFile(path: String, entryPath: String): InputResource = InputResource("$path!$entryPath") {
val zipFile = ZipFile(path)
zipFile.getInputStream(zipFile.getEntry(entryPath))
}
}
}
@@ -19,13 +19,15 @@ package org.jetbrains.kotlin.js.test
import junit.framework.TestCase
import org.jetbrains.kotlin.js.dce.DeadCodeElimination
import org.jetbrains.kotlin.js.dce.InputFile
import org.jetbrains.kotlin.js.dce.InputResource
import java.io.File
abstract class AbstractDceTest : TestCase() {
fun doTest(filePath: String) {
val file = File(filePath)
val fileContents = file.readText()
val inputFile = InputFile(filePath, null, File(pathToOutputDir, file.relativeTo(File(pathToTestDir)).path).path, "main")
val inputFile = InputFile(InputResource.file(filePath), null,
File(pathToOutputDir, file.relativeTo(File(pathToTestDir)).path).path, "main")
val dceResult = DeadCodeElimination.run(setOf(inputFile), extractDeclarations(REQUEST_REACHABLE_PATTERN, fileContents)) { _, _ -> }
val reachableNodeStrings = dceResult.reachableNodes.map { it.toString().removePrefix("<unknown>.") }.toSet()
@@ -43,6 +43,7 @@ import org.jetbrains.kotlin.js.config.JsConfig
import org.jetbrains.kotlin.js.config.SourceMapSourceEmbedding
import org.jetbrains.kotlin.js.dce.DeadCodeElimination
import org.jetbrains.kotlin.js.dce.InputFile
import org.jetbrains.kotlin.js.dce.InputResource
import org.jetbrains.kotlin.js.facade.*
import org.jetbrains.kotlin.js.parser.parse
import org.jetbrains.kotlin.js.parser.sourcemaps.SourceMapError
@@ -549,12 +550,12 @@ abstract class BasicBoxTest(
val kotlinJsLibOutput = File(workDir, "kotlin.min.js").path
val kotlinTestJsLibOutput = File(workDir, "kotlin-test.min.js").path
val kotlinJsInputFile = InputFile(kotlinJsLib, null, kotlinJsLibOutput, "kotlin")
val kotlinTestJsInputFile = InputFile(kotlinTestJsLib, null, kotlinTestJsLibOutput, "kotlin-test")
val kotlinJsInputFile = InputFile(InputResource.file(kotlinJsLib), null, kotlinJsLibOutput, "kotlin")
val kotlinTestJsInputFile = InputFile(InputResource.file(kotlinTestJsLib), null, kotlinTestJsLibOutput, "kotlin-test")
val filesToMinify = generatedJsFiles.associate { (fileName, module) ->
val inputFileName = File(fileName).nameWithoutExtension
fileName to InputFile(fileName, null, File(workDir, inputFileName + ".min.js").absolutePath, module.name)
fileName to InputFile(InputResource.file(fileName), null, File(workDir, inputFileName + ".min.js").absolutePath, module.name)
}
val testFunctionFqn = testModuleName + (if (testPackage.isNullOrEmpty()) "" else ".$testPackage") + ".$testFunction"