From 14d1b9ce3506a98e4ab99944d8a92b747ac4933a Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Fri, 21 Nov 2014 15:28:31 +0300 Subject: [PATCH] Renamed StatementTree + moved utility functions into class object --- .../resolve/lazy/PartialBodyResolveFilter.kt | 130 +++++++++--------- 1 file changed, 63 insertions(+), 67 deletions(-) diff --git a/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/PartialBodyResolveFilter.kt b/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/PartialBodyResolveFilter.kt index af55ed8cd73..3af506b136d 100644 --- a/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/PartialBodyResolveFilter.kt +++ b/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/PartialBodyResolveFilter.kt @@ -37,12 +37,12 @@ class PartialBodyResolveFilter( probablyNothingCallableNames: ProbablyNothingCallableNames ) : org.jetbrains.jet.lang.resolve.PartialBodyResolveProvider() { - private val statementTree = StatementTree() + private val statementMarks = StatementMarks() private val nothingFunctionNames = HashSet(probablyNothingCallableNames.functionNames()) private val nothingPropertyNames = probablyNothingCallableNames.propertyNames() - override val filter: ((JetElement) -> Boolean)? = { it is JetExpression && statementTree.statementMark(it) != MarkLevel.SKIP } + override val filter: ((JetElement) -> Boolean)? = { it is JetExpression && statementMarks.statementMark(it) != MarkLevel.SKIP } ;{ assert(declaration.isAncestor(elementToResolve)) @@ -61,25 +61,23 @@ class PartialBodyResolveFilter( } }) - statementTree.mark(elementToResolve, MarkLevel.NEED_COMPLETION) - statementTree.blocks(declaration).forEach { - processBlock(it) - } + statementMarks.mark(elementToResolve, MarkLevel.NEED_COMPLETION) + declaration.blocks().forEach { processBlock(it) } } //TODO: do..while is special case private fun processBlock(block: JetBlockExpression): NameFilter { if (isValueNeeded(block)) { - block.lastStatement()?.let { statementTree.mark(it, MarkLevel.NEED_REFERENCE_RESOLVE) } + block.lastStatement()?.let { statementMarks.mark(it, MarkLevel.NEED_REFERENCE_RESOLVE) } } val nameFilter = NameFilter() - if (!statementTree.hasMarks(block, MarkLevel.NEED_REFERENCE_RESOLVE)) return nameFilter + if (!statementMarks.hasMarks(block, MarkLevel.NEED_REFERENCE_RESOLVE)) return nameFilter val startStatement = block.getLastChild().siblings(forward = false) .filterIsInstance() - .first { statementTree.statementMark(it) > MarkLevel.TAKE } + .first { statementMarks.statementMark(it) > MarkLevel.TAKE } for (statement in startStatement.siblings(forward = false)) { if (statement !is JetExpression) continue @@ -87,7 +85,7 @@ class PartialBodyResolveFilter( if (statement is JetNamedDeclaration) { val name = statement.getName() if (name != null && nameFilter.accepts(name)) { - statementTree.mark(statement, MarkLevel.NEED_REFERENCE_RESOLVE) + statementMarks.mark(statement, MarkLevel.NEED_REFERENCE_RESOLVE) } } else if (statement is JetMultiDeclaration) { @@ -95,12 +93,12 @@ class PartialBodyResolveFilter( val name = it.getName() name != null && nameFilter.accepts(name) }) { - statementTree.mark(statement, MarkLevel.NEED_REFERENCE_RESOLVE) + statementMarks.mark(statement, MarkLevel.NEED_REFERENCE_RESOLVE) } } fun updateNameFilter() { - val level = statementTree.statementMark(statement) + val level = statementMarks.statementMark(statement) when (level) { MarkLevel.NEED_REFERENCE_RESOLVE -> nameFilter.addUsedNames(statement) MarkLevel.NEED_COMPLETION -> nameFilter.addAllNames() @@ -115,14 +113,14 @@ class PartialBodyResolveFilter( //TODO: do we really need correct resolve for ALL smart cast places? smartCastPlaces.values() .flatMap { it } - .forEach { statementTree.mark(it, MarkLevel.NEED_REFERENCE_RESOLVE) } + .forEach { statementMarks.mark(it, MarkLevel.NEED_REFERENCE_RESOLVE) } updateNameFilter() } } - val level = statementTree.statementMark(statement) + val level = statementMarks.statementMark(statement) if (level > MarkLevel.TAKE) { - for (nestedBlock in statementTree.blocks(statement)) { + for (nestedBlock in statement.blocks()) { val childFilter = processBlock(nestedBlock) nameFilter.addNames(childFilter) } @@ -371,8 +369,6 @@ class PartialBodyResolveFilter( private fun JetElement.noControlFlowInside() = this is JetFunction || this is JetClass || this is JetClassBody } - private fun PsiElement.isStatement() = this is JetExpression && getParent() is JetBlockExpression - private data class SmartCastName(val receiverName: SmartCastName?, val selectorName: String) { override fun toString(): String = if (receiverName != null) receiverName.toString() + "." + selectorName else selectorName @@ -404,36 +400,6 @@ class PartialBodyResolveFilter( } } -// private fun JetExpression?.isNullLiteral() = this?.getNode()?.getElementType() == JetNodeTypes.NULL - - private fun JetExpression?.isTrueConstant() - = this != null && getNode()?.getElementType() == JetNodeTypes.BOOLEAN_CONSTANT && getText() == "true" - - //TODO: review logic - private fun isValueNeeded(expression: JetExpression): Boolean { - val parent = expression.getParent() - return when (parent) { - is JetBlockExpression -> expression == parent.lastStatement() && isValueNeeded(parent) - - is JetContainerNode -> { //TODO - not quite correct - val pparent = parent.getParent() as? JetExpression - pparent != null && isValueNeeded(pparent) - } - - is JetDeclarationWithBody -> { - if (expression == parent.getBodyExpression()) - !parent.hasBlockBody() && !parent.hasDeclaredReturnType() - else - true - } - - else -> true - } - } - - private fun JetBlockExpression.lastStatement(): JetExpression? - = getLastChild()?.siblings(forward = false)?.firstIsInstanceOrNull() - //TODO: declarations with special names (e.g. "get") private class NameFilter { private var names: MutableSet? = HashSet() @@ -484,29 +450,10 @@ class PartialBodyResolveFilter( NEED_COMPLETION } - private inner class StatementTree { + private inner class StatementMarks { private val statementMarks = HashMap() private val blockLevels = HashMap() - val topLevelBlocks: Collection = blocks(declaration) - - fun blocks(statement: JetExpression): Collection - = blocks(statement : JetElement) - - private fun blocks(element: JetElement): Collection { - val result = ArrayList(1) - element.accept(object : JetVisitorVoid() { - override fun visitBlockExpression(expression: JetBlockExpression) { - result.add(expression) - } - - override fun visitElement(element: PsiElement) { - element.acceptChildren(this) - } - }) - return result - } - fun mark(element: PsiElement, level: MarkLevel) { var e = element while (e != declaration) { @@ -538,5 +485,54 @@ class PartialBodyResolveFilter( return level >= minLevel } } + + class object { + private fun JetElement.blocks(): Collection { + val result = ArrayList(1) + this.accept(object : JetVisitorVoid() { + override fun visitBlockExpression(expression: JetBlockExpression) { + result.add(expression) + } + + override fun visitElement(element: PsiElement) { + element.acceptChildren(this) + } + }) + return result + } + + // private fun JetExpression?.isNullLiteral() = this?.getNode()?.getElementType() == JetNodeTypes.NULL + + private fun JetExpression?.isTrueConstant() + = this != null && getNode()?.getElementType() == JetNodeTypes.BOOLEAN_CONSTANT && getText() == "true" + + //TODO: review logic + private fun isValueNeeded(expression: JetExpression): Boolean { + val parent = expression.getParent() + return when (parent) { + is JetBlockExpression -> expression == parent.lastStatement() && isValueNeeded(parent) + + is JetContainerNode -> { //TODO - not quite correct + val pparent = parent.getParent() as? JetExpression + pparent != null && isValueNeeded(pparent) + } + + is JetDeclarationWithBody -> { + if (expression == parent.getBodyExpression()) + !parent.hasBlockBody() && !parent.hasDeclaredReturnType() + else + true + } + + else -> true + } + } + + private fun JetBlockExpression.lastStatement(): JetExpression? + = getLastChild()?.siblings(forward = false)?.firstIsInstanceOrNull() + + private fun PsiElement.isStatement() = this is JetExpression && getParent() is JetBlockExpression + + } }