JS: FunctionReader cleanup

This commit is contained in:
Anton Bannykh
2018-12-18 18:32:57 +03:00
parent 6d5ef2d324
commit 13844bd08e
4 changed files with 8 additions and 35 deletions
@@ -83,8 +83,8 @@ class FunctionReader(
val offsetToSourceMapping by lazy(offsetToSourceMappingProvider)
val wrapFunctionRegex = specialFunctions.entries
.filter { (_, v) -> v == SpecialFunction.WRAP_FUNCTION } // TODO This is a hack! Investigate duplicates!
.map { Regex("\\s*${it.key}\\s*\\(\\s*").toPattern() }
.singleOrNull { (_, v) -> v == SpecialFunction.WRAP_FUNCTION }?.key
?.let { Regex("\\s*$it\\s*\\(\\s*").toPattern() }
}
private val moduleNameToInfo by lazy {
@@ -224,11 +224,9 @@ class FunctionReader(
return null
}
// TODO move renamings to a proper place
private fun readFunctionFromSource(descriptor: CallableDescriptor, info: ModuleInfo): FunctionWithWrapper? {
val source = info.fileContent
var tag = Namer.getFunctionTag(descriptor, config)
// val tagForModule = tag
var index = source.indexOf(tag)
// Hack for compatibility with old versions of stdlib
@@ -247,30 +245,21 @@ class FunctionReader(
}
val sourcePart = ShallowSubSequence(source, offset, source.length)
var isWrapped = false
for (regex in info.wrapFunctionRegex) {
val wrapFunctionMatcher = regex.matcher(sourcePart)
isWrapped = wrapFunctionMatcher.lookingAt() == true
if (isWrapped) {
offset += wrapFunctionMatcher!!.end()
break
}
val wrapFunctionMatcher = info.wrapFunctionRegex?.matcher(sourcePart)
val isWrapped = wrapFunctionMatcher?.lookingAt() == true
if (isWrapped) {
offset += wrapFunctionMatcher!!.end()
}
val position = info.offsetToSourceMapping[offset]
val jsScope = JsRootScope(JsProgram())
val functionExpr = try {
parseFunction(source, info.filePath, position, offset, ThrowExceptionOnErrorReporter, jsScope) ?: return null
} catch (t: Throwable) {
throw Error("Exception while reading function '$tag' from ${info.filePath}", t)
}
val functionExpr = parseFunction(source, info.filePath, position, offset, ThrowExceptionOnErrorReporter, jsScope) ?: return null
functionExpr.fixForwardNameReferences()
val (function, wrapper) = if (isWrapped) {
InlineMetadata.decomposeWrapper(functionExpr) ?: return null
} else {
FunctionWithWrapper(functionExpr, null)
}
// val moduleReference = moduleNameMap[tagForModule]?.deepCopy() ?: currentModuleName.makeRef()
val wrapperStatements = wrapper?.statements?.filter { it !is JsReturn }
val sourceMap = info.sourceMap
@@ -283,14 +272,9 @@ class FunctionReader(
}
val allDefinedNames = collectDefinedNamesInAllScopes(function)
// val replacements = hashMapOf(info.moduleVariable to moduleReference,
// info.kotlinVariable to Namer.kotlinObject())
// replaceExternalNames(function, replacements, allDefinedNames)
// wrapperStatements?.forEach { replaceExternalNames(it, replacements, allDefinedNames) }
function.markInlineArguments(descriptor)
markDefaultParams(function)
// TODO maybe move elsewhere?
markSpecialFunctions(function, allDefinedNames, info, jsScope)
val namesWithoutSideEffects = wrapperStatements.orEmpty().asSequence()
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.js.inline.util.refreshLabelNames
import org.jetbrains.kotlin.js.translate.expression.InlineMetadata
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
// TODO stateless?
class InlinerImpl(
val jsInliner: JsInliner,
val scope: InliningScope
@@ -89,8 +88,6 @@ class InlinerImpl(
}
}
// TODO This could be extracted into a separate pass.
// TODO Don't forget to run it on the freshly inlined code!
override fun doAcceptStatementList(statements: MutableList<JsStatement>) {
var i = 0
@@ -114,7 +111,6 @@ class InlinerImpl(
private fun patchReturnsFromSecondaryConstructor(function: JsFunction) {
// Support non-local return from secondary constructor
// Returns from secondary constructors should return `$this` object.
// TODO This seems brittle
function.forcedReturnVariable?.let { returnVariable ->
function.body.accept(object : RecursiveJsVisitor() {
override fun visitReturn(x: JsReturn) {
@@ -45,8 +45,6 @@ sealed class InliningScope {
fun importFunctionDefinition(definition: InlineFunctionDefinition): JsFunction {
// Apparently we should avoid this trick when we implement fair support for crossinline
// That's because crossinline lambdas inline into the declaration block and specialize those.
// TODO cache the function itself instead
val result = computeIfAbsent(definition.tag, definition.fn.function) {
val newReplacements = HashMap<JsName, JsNameRef>()
@@ -146,9 +144,7 @@ class ProgramFragmentInliningScope(
private val additionalDeclarations = mutableListOf<JsStatement>()
override fun update() {
// TODO fix the order
// TODO this probably will be replaced with a special tag -> block map for the imported stuff, so that we can merge same imports.
// TODO in that case this method will become obsolete
// TODO fix the order?
fragment.declarationBlock.statements.addAll(0, additionalDeclarations)
// post-processing
@@ -161,7 +157,6 @@ class ProgramFragmentInliningScope(
removeUnusedImports(fragment)
}
// TODO !!!!! This localAlias thing will get copied, inlined, and lost during IC =(
override fun hasImport(name: JsName, tag: String): JsName? {
return name.localAlias?.let {(name, tag) ->
if (tag != null) {
@@ -217,7 +212,6 @@ class ProgramFragmentInliningScope(
private fun addInlinedModule(module: JsImportedModule): JsName {
return existingModules.computeIfAbsent(module.key) {
// Copy so that the Merger.kt doesn't operate on the same instance in different fragments.
// TODO What about nameBindings?
JsImportedModule(module.externalName, module.internalName, module.plainReference).also {
fragment.importedModules.add(it)
}
@@ -82,7 +82,6 @@ class JsInliner(
InlinerImpl(this@JsInliner, this).accept(node)
}
// TODO a lot of code... Probably a bad sign
fun inline(scope: InliningScope, call: JsInvocation, currentStatement: JsStatement?): InlineableResult {
val definition = functionContext.getFunctionDefinition(call, scope)