Fix function lookup in modules with similar names [KT-23582]

This commit is contained in:
Roman Artemev
2018-04-06 16:07:44 +03:00
parent 96b6cec33f
commit 3bc323807f
5 changed files with 24 additions and 14 deletions
+1 -1
View File
@@ -1,2 +1,2 @@
warning: module "m" depends from module with the same name
warning: module "m" depends on module with the same name
OK
+1 -1
View File
@@ -1,2 +1,2 @@
warning: module "m" depends from module with the same name
warning: module "m" depends on module with the same name
OK
@@ -222,7 +222,7 @@ public class JsConfig {
}
if (modules.contains(getModuleId())) {
report.warning("Module \"" + getModuleId() + "\" depends from module with the same name");
report.warning("Module \"" + getModuleId() + "\" depends on module with the same name");
}
Set<String> friendLibsSet = new HashSet<>(getFriends());
@@ -178,24 +178,23 @@ class FunctionReader(
override fun toString() = text.substring(offset)
}
private val emptyFunctionWrapper = FunctionWithWrapper(JsFunction(object : JsScope("") {}, ""), null)
private val functionCache = object : SLRUCache<CallableDescriptor, FunctionWithWrapper>(50, 50) {
override fun createValue(descriptor: CallableDescriptor): FunctionWithWrapper =
readFunction(descriptor).sure { "Could not read function: $descriptor" }
readFunction(descriptor) ?: emptyFunctionWrapper
}
operator fun contains(descriptor: CallableDescriptor): Boolean {
val moduleName = getModuleName(descriptor)
val currentModuleName = config.moduleId
return currentModuleName != moduleName && moduleName in moduleNameToInfo.keys()
operator fun get(descriptor: CallableDescriptor): FunctionWithWrapper? {
val existed = functionCache.get(descriptor)
return if (existed == emptyFunctionWrapper) null else existed
}
operator fun get(descriptor: CallableDescriptor): FunctionWithWrapper = functionCache.get(descriptor)
private fun readFunction(descriptor: CallableDescriptor): FunctionWithWrapper? {
if (descriptor !in this) return null
val moduleName = getModuleName(descriptor)
if (moduleName !in moduleNameToInfo.keys()) return null
for (info in moduleNameToInfo[moduleName]) {
val function = readFunctionFromSource(descriptor, info)
if (function != null) return function
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.js.inline.context
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.js.backend.ast.*
import org.jetbrains.kotlin.js.backend.ast.metadata.isCallableReference
import org.jetbrains.kotlin.js.backend.ast.metadata.descriptor
@@ -23,6 +24,7 @@ import org.jetbrains.kotlin.js.config.JsConfig
import org.jetbrains.kotlin.js.inline.FunctionReader
import org.jetbrains.kotlin.js.inline.util.*
import org.jetbrains.kotlin.js.translate.context.Namer
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils.getModuleName
abstract class FunctionContext(private val functionReader: FunctionReader, private val config: JsConfig) {
protected abstract fun lookUpStaticFunction(functionName: JsName?): FunctionWithWrapper?
@@ -68,12 +70,16 @@ abstract class FunctionContext(private val functionReader: FunctionReader, priva
* in case of local function with closure.
*/
private fun getFunctionDefinitionImpl(call: JsInvocation): FunctionWithWrapper? {
val descriptor = call.descriptor
if (descriptor != null) {
if (descriptor in functionReader) return functionReader[descriptor]
lookUpStaticFunctionByTag(Namer.getFunctionTag(descriptor, config))?.let { return it }
return lookUpFunctionDirect(descriptor) ?: lookUpFunctionIndirect(call) ?: lookUpFunctionExternal(descriptor)
}
return lookUpFunctionIndirect(call)
}
private fun lookUpFunctionIndirect(call: JsInvocation): FunctionWithWrapper? {
/** remove ending `()` */
val callQualifier: JsExpression = if (isCallInvocation(call)) {
(call.qualifier as JsNameRef).qualifier!!
@@ -96,6 +102,11 @@ abstract class FunctionContext(private val functionReader: FunctionReader, priva
}
}
private fun lookUpFunctionDirect(descriptor: CallableDescriptor): FunctionWithWrapper? =
lookUpStaticFunctionByTag(Namer.getFunctionTag(descriptor, config))
private fun lookUpFunctionExternal(descriptor: CallableDescriptor): FunctionWithWrapper? = functionReader[descriptor]
private fun tryExtractCallableReference(invocation: JsInvocation): FunctionWithWrapper? {
if (invocation.isCallableReference) {
val arg = invocation.arguments[1]