JS: restore names that can be changed by minifier
For example, Kotlin object can be renamed in stdlib, so when we inline stdlib function in context of other module renamed Kotlin object reference does not exitst.
This commit is contained in:
@@ -42,7 +42,19 @@ public class FunctionReader(private val context: TranslationContext) {
|
||||
* Maps module name to .js file content, that contains this module definition.
|
||||
* One file can contain more than one module definition.
|
||||
*/
|
||||
private val moduleJsDefinition = hashMapOf<String, String>();
|
||||
private val moduleJsDefinition = hashMapOf<String, String>()
|
||||
|
||||
/**
|
||||
* Maps module name to variable, that is used to call functions inside module.
|
||||
* The default variable is _, but it can be renamed by minifier.
|
||||
*/
|
||||
private val moduleRootVariable = hashMapOf<String, String>()
|
||||
|
||||
/**
|
||||
* Maps moduleName to kotlin object variable.
|
||||
* The default variable is Kotlin, but it can be renamed by minifier.
|
||||
*/
|
||||
private val moduleKotlinVariable = hashMapOf<String, String>();
|
||||
|
||||
{
|
||||
val config = context.getConfig() as LibrarySourcesConfig
|
||||
@@ -55,8 +67,12 @@ public class FunctionReader(private val context: TranslationContext) {
|
||||
|
||||
while (matcher.find()) {
|
||||
val moduleName = matcher.group(3)
|
||||
val moduleVariable = matcher.group(4)
|
||||
val kotlinVariable = matcher.group(1)
|
||||
assert(moduleName !in moduleJsDefinition) { "Module is defined in more, than one file" }
|
||||
moduleJsDefinition[moduleName] = file
|
||||
moduleRootVariable[moduleName] = moduleVariable
|
||||
moduleKotlinVariable[moduleName] = kotlinVariable
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,6 +109,13 @@ public class FunctionReader(private val context: TranslationContext) {
|
||||
}
|
||||
|
||||
val function = metadata.function
|
||||
val moduleName = getExternalModuleName(descriptor)!!
|
||||
val moduleNameLiteral = context.program().getStringLiteral(moduleName)
|
||||
val moduleReference = context.namer().getModuleReference(moduleNameLiteral)
|
||||
|
||||
val replacements = hashMapOf(moduleRootVariable[moduleName] to moduleReference,
|
||||
moduleKotlinVariable[moduleName] to Namer.KOTLIN_OBJECT_REF)
|
||||
replaceExternalNames(function, replacements)
|
||||
return function
|
||||
}
|
||||
|
||||
@@ -108,3 +131,21 @@ public class FunctionReader(private val context: TranslationContext) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun replaceExternalNames(function: JsFunction, externalReplacements: Map<String, JsExpression>) {
|
||||
val replacements = externalReplacements.filterKeys { !function.getScope().hasOwnName(it) }
|
||||
|
||||
if (replacements.isEmpty()) return
|
||||
|
||||
val visitor = object: JsVisitorWithContextImpl() {
|
||||
override fun endVisit(x: JsNameRef?, ctx: JsContext?) {
|
||||
if (x == null || x.getQualifier() != null) return
|
||||
|
||||
replacements[x.getIdent()]?.let {
|
||||
ctx?.replaceMe(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
visitor.accept(function)
|
||||
}
|
||||
|
||||
@@ -268,6 +268,9 @@ public final class Namer {
|
||||
@NotNull
|
||||
private final JsName isTypeName;
|
||||
|
||||
@NotNull
|
||||
private final JsExpression modulesMap;
|
||||
|
||||
private Namer(@NotNull JsScope rootScope) {
|
||||
kotlinName = rootScope.declareName(KOTLIN_NAME);
|
||||
kotlinScope = JsObjectScope(rootScope, "Kotlin standard object");
|
||||
@@ -290,6 +293,7 @@ public final class Namer {
|
||||
callableRefForExtensionProperty = kotlinScope.declareName(CALLABLE_REF_FOR_EXTENSION_PROPERTY);
|
||||
|
||||
isTypeName = kotlinScope.declareName("isType");
|
||||
modulesMap = kotlin("modules");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -421,4 +425,9 @@ public final class Namer {
|
||||
public JsExpression getCallSetProperty() {
|
||||
return callSetProperty;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsExpression getModuleReference(@NotNull JsStringLiteral moduleName) {
|
||||
return new JsArrayAccess(modulesMap, moduleName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -481,7 +481,7 @@ public final class StaticContext {
|
||||
}
|
||||
|
||||
return JsAstUtils.replaceRootReference(
|
||||
result, new JsArrayAccess(namer.kotlin("modules"), program.getStringLiteral(moduleName)));
|
||||
result, namer.getModuleReference(program.getStringLiteral(moduleName)));
|
||||
}
|
||||
};
|
||||
Rule<JsExpression> constructorOrDefaultObjectHasTheSameQualifierAsTheClass = new Rule<JsExpression>() {
|
||||
|
||||
Reference in New Issue
Block a user