diff --git a/js/js.dce/src/org/jetbrains/kotlin/js/dce/Analyzer.kt b/js/js.dce/src/org/jetbrains/kotlin/js/dce/Analyzer.kt index bedeee8ef0b..6ffef6e3ee1 100644 --- a/js/js.dce/src/org/jetbrains/kotlin/js/dce/Analyzer.kt +++ b/js/js.dce/src/org/jetbrains/kotlin/js/dce/Analyzer.kt @@ -278,7 +278,7 @@ class Analyzer(private val context: Context) : JsVisitor() { leftNode.addFunction(rhs) return leftNode } - leftNode.qualifier?.memberName == Namer.METADATA -> { + leftNode.memberName == Namer.METADATA -> { // lhs.$metadata$ = expression // During reachability tracking phase: eliminate it if lhs is unreachable, traverse expression // It's commonly used to supply class's metadata diff --git a/js/js.dce/src/org/jetbrains/kotlin/js/dce/Context.kt b/js/js.dce/src/org/jetbrains/kotlin/js/dce/Context.kt index 43b9961f147..4fa27f5e0e6 100644 --- a/js/js.dce/src/org/jetbrains/kotlin/js/dce/Context.kt +++ b/js/js.dce/src/org/jetbrains/kotlin/js/dce/Context.kt @@ -76,7 +76,7 @@ class Context { fun extractNode(expression: JsExpression): Node? { val node = extractNodeImpl(expression)?.original - return if (node != null && moduleExportsNode in generateSequence(node) { it.qualifier?.parent }) { + return if (node != null && moduleExportsNode in generateSequence(node) { it.parent }) { val path = node.pathFromRoot().drop(2) path.fold(currentModule.original) { n, memberName -> n.member(memberName) } } @@ -134,7 +134,7 @@ class Context { fun visit(n: Node) = n.visit(currentColor) - class Node private constructor(val localName: JsName?, qualifier: Qualifier?) { + class Node private constructor(val localName: JsName?, parent: Node?, val memberName: String?) { private var _dependenciesImpl: MutableSet? = null private var _expressionsImpl: MutableSet? = null private var _functionsImpl: MutableSet? = null @@ -183,7 +183,7 @@ class Context { original.declarationReachableImpl = value } - var qualifier: Qualifier? = qualifier + var parent: Node? = parent private set private var color: Byte = 0 @@ -196,7 +196,7 @@ class Context { val memberNames: Set get() = original._membersImpl?.keys ?: emptySet() - constructor(localName: JsName? = null) : this(localName, null) + constructor(localName: JsName? = null) : this(localName, null, null) var original: Node = this get() { @@ -225,20 +225,20 @@ class Context { original.usedByAstNodesImpl += node } - fun member(name: String): Node = original.membersImpl.getOrPut(name) { Node(null, Qualifier(this, name)) }.original + fun member(name: String): Node = original.membersImpl.getOrPut(name) { Node(null, this, name) }.original fun alias(other: Node) { val a = original val b = other.original if (a == b) return - if (a.qualifier == null && b.qualifier == null) { + if (a.parent == null && b.parent == null) { a.merge(b) } - else if (a.qualifier == null) { + else if (a.parent == null) { if (b.root() == a) a.makeDependencies(b) else b.evacuateFrom(a) } - else if (b.qualifier == null) { + else if (b.parent == null) { if (a.root() == b) a.makeDependencies(b) else a.evacuateFrom(b) } else { @@ -257,12 +257,12 @@ class Context { for ((name, member) in newMembers) { membersImpl[name] = member - member.original.qualifier = Qualifier(this, member.original.qualifier!!.memberName) + member.original.parent = this } for ((name, member) in existingMembers) { membersImpl[name]!!.original.merge(member.original) membersImpl[name] = member.original - member.original.qualifier = Qualifier(this, member.original.qualifier!!.memberName) + member.original.parent = this } other.membersImpl.clear() @@ -301,14 +301,12 @@ class Context { } } - fun root(): Node = generateSequence(original) { it.qualifier?.parent?.original }.last() + fun root(): Node = generateSequence(original) { it.parent?.original }.last() fun pathFromRoot(): List = - generateSequence(original) { it.qualifier?.parent?.original }.mapNotNull { it.qualifier?.memberName } + generateSequence(original) { it.parent?.original }.mapNotNull { it.memberName } .toList().asReversed() override fun toString(): String = (root().localName?.ident ?: "") + pathFromRoot().joinToString("") { ".$it" } } - - class Qualifier(val parent: Node, val memberName: String) -} \ No newline at end of file +} diff --git a/js/js.dce/src/org/jetbrains/kotlin/js/dce/ReachabilityTracker.kt b/js/js.dce/src/org/jetbrains/kotlin/js/dce/ReachabilityTracker.kt index 4f062f6b1c7..c432638e86b 100644 --- a/js/js.dce/src/org/jetbrains/kotlin/js/dce/ReachabilityTracker.kt +++ b/js/js.dce/src/org/jetbrains/kotlin/js/dce/ReachabilityTracker.kt @@ -102,8 +102,8 @@ class ReachabilityTracker( invocation in analysisResult.invocationsToSkip -> {} else -> { val node = context.extractNode(invocation.qualifier) - if (node != null && node.qualifier?.memberName in CALL_FUNCTIONS) { - val parent = node.qualifier!!.parent + if (node != null && node.memberName in CALL_FUNCTIONS) { + val parent = node.parent!! reach(parent) currentNodeWithLocation?.let { parent.addUsedByAstNode(it) } } @@ -178,15 +178,14 @@ class ReachabilityTracker( var current = node while (true) { for (ancestorDependency in current.dependencies) { - if (current in generateSequence(ancestorDependency) { it.qualifier?.parent }) continue + if (current in generateSequence(ancestorDependency) { it.parent }) continue val dependency = path.asReversed().fold(ancestorDependency) { n, memberName -> n.member(memberName) } if (!dependency.reachable) { reportAndNest("reach: dependency $dependency", null) { reach(dependency) } } } - val qualifier = current.qualifier ?: break - path += qualifier.memberName - current = qualifier.parent + path += current.memberName ?: break + current = current.parent!! // memberName != null => parent != null } } @@ -202,7 +201,7 @@ class ReachabilityTracker( reachableNodesImpl += node } - node.original.qualifier?.parent?.let { + node.original.parent?.let { reportAndNest("reach-decl: parent $it", null) { reachDeclaration(it) } diff --git a/js/js.dce/src/org/jetbrains/kotlin/js/dce/printTree.kt b/js/js.dce/src/org/jetbrains/kotlin/js/dce/printTree.kt index 7da25da5839..08509f8a728 100644 --- a/js/js.dce/src/org/jetbrains/kotlin/js/dce/printTree.kt +++ b/js/js.dce/src/org/jetbrains/kotlin/js/dce/printTree.kt @@ -24,7 +24,7 @@ fun printTree(root: Node, consumer: (String) -> Unit, printNestedMembers: Boolea private fun printTree(node: Node, consumer: (String) -> Unit, depth: Int, settings: Settings) { val sb = StringBuilder() - sb.append(" ".repeat(depth)).append(node.qualifier?.memberName ?: node.toString()) + sb.append(" ".repeat(depth)).append(node.memberName ?: node.toString()) if (node.reachable) { sb.append(" (reachable") diff --git a/js/js.dce/src/org/jetbrains/kotlin/js/dce/util.kt b/js/js.dce/src/org/jetbrains/kotlin/js/dce/util.kt index abb3c6e9545..020c5281c2a 100644 --- a/js/js.dce/src/org/jetbrains/kotlin/js/dce/util.kt +++ b/js/js.dce/src/org/jetbrains/kotlin/js/dce/util.kt @@ -83,11 +83,11 @@ fun Iterable.extractReachableRoots(context: Context): Iterable { private fun Node.extractRootsImpl(target: MutableList, context: Context) { if (!context.visit(original)) return - val qualifier = original.qualifier - if (qualifier == null) { + val parent = original.parent + if (parent == null) { target += original } else { - qualifier.parent.extractRootsImpl(target, context) + parent.extractRootsImpl(target, context) } }