Avoid exponential complexity in LexicalScope::findLocalVariable

There was an exponential complexity in case we have a chain
of nested LexicalScopeWrapper instances:
we were walking through the chain and on each step running
the algorithm recursively.

Such a case is possible in scripts where each line contains LexicalScopeWrapper

The fix looks safe to me because delegate was used there
for checking !is ImportingScope && !is LexicalChainedScope

In all other means, being recursively run the algorithm does the same job.

 #KT-22740 Fixed
This commit is contained in:
Denis Zharkov
2018-04-10 15:35:04 +03:00
parent a3c8afade5
commit 1442dd6c2b
2 changed files with 25 additions and 7 deletions
@@ -64,14 +64,19 @@ fun HierarchicalScope.collectDescriptorsFiltered(
@Deprecated("Use getContributedProperties instead")
fun LexicalScope.findLocalVariable(name: Name): VariableDescriptor? {
return findFirstFromMeAndParent {
when {
it is LexicalScopeWrapper -> it.delegate.findLocalVariable(name)
return findFirstFromMeAndParent { originalScope ->
// Unpacking LexicalScopeWrapper may be important to check that it is not ImportingScope
val possiblyUnpackedScope = when (originalScope) {
is LexicalScopeWrapper -> originalScope.delegate
else -> originalScope
}
it !is ImportingScope && it !is LexicalChainedScope -> it.getContributedVariables(
name,
NoLookupLocation.WHEN_GET_LOCAL_VARIABLE
).singleOrNull() /* todo check this*/
when {
possiblyUnpackedScope !is ImportingScope && possiblyUnpackedScope !is LexicalChainedScope ->
possiblyUnpackedScope.getContributedVariables(
name,
NoLookupLocation.WHEN_GET_LOCAL_VARIABLE
).singleOrNull() /* todo check this*/
else -> null
}