Refactored PsiElement.parents() into 2 properties

This commit is contained in:
Valentin Kipyatkov
2015-05-28 22:49:07 +03:00
parent 55f70d7d48
commit 494d96bbc7
26 changed files with 52 additions and 56 deletions
@@ -192,7 +192,7 @@ public fun JetElement.getContainingPseudocode(context: BindingContext): Pseudoco
?: return null
val enclosingPseudocodeDeclaration = (pseudocodeDeclaration as? JetFunctionLiteral)?.let {
it.parents(withItself = false).firstOrNull { it is JetDeclaration && it !is JetFunctionLiteral } as? JetDeclaration
it.parents.firstOrNull { it is JetDeclaration && it !is JetFunctionLiteral } as? JetDeclaration
} ?: pseudocodeDeclaration
val enclosingPseudocode = PseudocodeUtil.generatePseudocode(enclosingPseudocodeDeclaration, context)
@@ -26,10 +26,7 @@ import com.intellij.psi.impl.source.codeStyle.CodeEditUtil
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.renderName
import org.jetbrains.kotlin.psi.psiUtil.PsiChildRange
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.psi.psiUtil.*
import java.util.ArrayList
import java.util.HashMap
import java.util.LinkedHashMap
@@ -124,7 +121,7 @@ public fun <TElement : JetElement> createByPattern(pattern: String, vararg args:
for ((range, text) in placeholders) {
val token = resultElement.findElementAt(range.getStartOffset())!!
for (element in token.parents()) {
for (element in token.parentsWithSelf) {
val elementRange = element.getTextRange().shiftRight(-start)
if (elementRange == range && expectedElementType.isInstance(element)) {
val pointer = pointerManager.createSmartPsiElementPointer(element)
@@ -38,10 +38,11 @@ public fun PsiElement.siblings(forward: Boolean = true, withItself: Boolean = tr
return if (withItself) sequence else sequence.drop(1)
}
public fun PsiElement.parents(withItself: Boolean = true): Sequence<PsiElement> {
val sequence = sequence(this) { if (it is PsiFile) null else it.getParent() }
return if (withItself) sequence else sequence.drop(1)
}
public val PsiElement.parentsWithSelf: Sequence<PsiElement>
get() = sequence(this) { if (it is PsiFile) null else it.getParent() }
public val PsiElement.parents: Sequence<PsiElement>
get() = parentsWithSelf.drop(1)
public fun PsiElement.prevLeaf(skipEmptyElements: Boolean = false): PsiElement?
= PsiTreeUtil.prevLeaf(this, skipEmptyElements)
@@ -216,7 +217,7 @@ public fun PsiFile.elementsInRange(range: TextRange): List<PsiElement> {
val leaf = findFirstLeafWhollyInRange(this, currentRange) ?: break
val element = leaf
.parents(withItself = true)
.parentsWithSelf
.first {
val parent = it.getParent()
it is PsiFile || parent.getTextRange() !in currentRange
@@ -26,6 +26,7 @@ import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.idea.JetBundle
import org.jetbrains.kotlin.psi.JetElement
import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
public abstract class JetSelfTargetingIntention<TElement : JetElement>(
public val elementType: Class<TElement>,
@@ -55,13 +56,13 @@ public abstract class JetSelfTargetingIntention<TElement : JetElement>(
var elementsToCheck: Sequence<PsiElement> = sequence { null }
if (leaf1 != null) {
elementsToCheck += leaf1.parents().takeWhile { it != commonParent }
elementsToCheck += leaf1.parentsWithSelf.takeWhile { it != commonParent }
}
if (leaf2 != null) {
elementsToCheck += leaf2.parents().takeWhile { it != commonParent }
elementsToCheck += leaf2.parentsWithSelf.takeWhile { it != commonParent }
}
if (commonParent != null) {
elementsToCheck += commonParent.parents()
elementsToCheck += commonParent.parentsWithSelf
}
val elementsOfType = elementsToCheck.filterIsInstance(elementType)
@@ -183,7 +183,7 @@ public class ShortenReferences(val options: (JetElement) -> Options = { Options.
val elementSet = elements.toSet()
val newElements = LinkedHashSet<JetElement>(elementSet.size())
for (element in elementSet) {
if (!element.parents(withItself = false).any { it in elementSet }) {
if (!element.parents.any { it in elementSet }) {
newElements.add(element)
}
}
@@ -43,10 +43,7 @@ import org.jetbrains.kotlin.idea.util.makeNotNullable
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptorKindExclude
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.psi.psiUtil.prevLeaf
import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo
import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
@@ -96,7 +93,7 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess
}
}
protected val bindingContext: BindingContext = resolutionFacade.analyze(position.parents().firstIsInstance<JetElement>(), BodyResolveMode.PARTIAL_FOR_COMPLETION)
protected val bindingContext: BindingContext = resolutionFacade.analyze(position.parentsWithSelf.firstIsInstance<JetElement>(), BodyResolveMode.PARTIAL_FOR_COMPLETION)
protected val inDescriptor: DeclarationDescriptor? = expression?.let { bindingContext.get(BindingContext.RESOLUTION_SCOPE, it)?.getContainingDeclaration() }
private val kotlinIdentifierStartPattern: ElementPattern<Char>
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.renderName
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
@@ -220,7 +221,7 @@ fun thisExpressionItems(bindingContext: BindingContext, position: JetExpression,
fun returnExpressionItems(bindingContext: BindingContext, position: JetElement): Collection<LookupElement> {
val result = ArrayList<LookupElement>()
for (parent in position.parents()) {
for (parent in position.parentsWithSelf) {
if (parent is JetDeclarationWithBody) {
val returnsUnit = returnsUnit(parent, bindingContext)
if (parent is JetFunctionLiteral) {
@@ -279,7 +280,7 @@ fun breakOrContinueExpressionItems(position: JetElement, breakOrContinue: String
val result = ArrayList<LookupElement>()
parentsLoop@
for (parent in position.parents()) {
for (parent in position.parentsWithSelf) {
when (parent) {
is JetLoopExpression -> {
if (result.isEmpty()) {
@@ -138,13 +138,13 @@ public class KotlinCompletionContributor : CompletionContributor() {
}
private fun isInFunctionLiteralParameterList(tokenBefore: PsiElement?): Boolean {
val parameterList = tokenBefore?.parents(false)?.firstOrNull { it is JetParameterList } ?: return false
val parameterList = tokenBefore?.parents?.firstOrNull { it is JetParameterList } ?: return false
val parent = parameterList.getParent()
return parent is JetFunctionLiteral && parent.getValueParameterList() == parameterList
}
private fun isInClassHeader(tokenBefore: PsiElement?): Boolean {
val classOrObject = tokenBefore?.parents(false)?.firstIsInstanceOrNull<JetClassOrObject>() ?: return false
val classOrObject = tokenBefore?.parents?.firstIsInstanceOrNull<JetClassOrObject>() ?: return false
val name = classOrObject.getNameIdentifier() ?: return false
val body = classOrObject.getBody() ?: return false
val offset = tokenBefore!!.startOffset
@@ -207,7 +207,7 @@ public class CommentSaver(originalElements: PsiChildRange, private val saveLineB
val token = original.findElementAt(element.getStartOffsetIn(createdElement) + rangeInOriginal.getStartOffset())
if (token != null) {
val elementLength = element.getTextLength()
for (originalElement in token.parents()) {
for (originalElement in token.parentsWithSelf) {
val length = originalElement.getTextLength()
if (length < elementLength) continue
if (length == elementLength) {
@@ -396,7 +396,7 @@ public class CommentSaver(originalElements: PsiChildRange, private val saveLineB
}
private fun PsiElement.anchorToAddCommentOrSpace(before: Boolean): PsiElement {
return parents()
return parentsWithSelf
.dropWhile { it.getParent() !is PsiFile && (if (before) it.getPrevSibling() else it.getNextSibling()) == null }
.first()
}
@@ -22,10 +22,7 @@ import com.intellij.openapi.util.TextRange
import com.intellij.psi.*
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
import org.jetbrains.kotlin.psi.psiUtil.allChildren
import org.jetbrains.kotlin.psi.psiUtil.elementsInRange
import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.psi.psiUtil.siblings
import org.jetbrains.kotlin.psi.psiUtil.*
import java.util.ArrayList
data class DataForConversion private(
@@ -132,8 +129,8 @@ data class DataForConversion private(
}
private fun PsiElement.maximalParentToClip(range: TextRange): PsiElement? {
val firstNotInRange = parents().takeWhile { it !is PsiDirectory }.firstOrNull { it.range !in range } ?: return null
return firstNotInRange.parents().lastOrNull { it.minimizedTextRange() in range }
val firstNotInRange = parentsWithSelf.takeWhile { it !is PsiDirectory }.firstOrNull { it.range !in range } ?: return null
return firstNotInRange.parentsWithSelf.lastOrNull { it.minimizedTextRange() in range }
}
private fun PsiElement.minimizedTextRange(): TextRange {
@@ -83,7 +83,7 @@ private fun JetExpression.getRelevantFunction(): JetFunction? {
if (this is JetReturnExpression) {
(this.getTargetLabel()?.getReference()?.resolve() as? JetFunction)?.let { return it }
}
for (parent in parents(false)) {
for (parent in parents) {
if (InlineUtil.canBeInlineArgument(parent) && !InlineUtil.isInlinedArgument(parent as JetFunction, parent.analyze(), false)) {
return parent as JetFunction
}
@@ -54,7 +54,7 @@ public class KotlinRecursiveCallLineMarkerProvider() : LineMarkerProvider {
}
private fun getEnclosingFunction(element: JetElement): JetNamedFunction? {
for (parent in element.parents(false)) {
for (parent in element.parents) {
when (parent) {
is JetFunctionLiteral -> if (!InlineUtil.isInlinedArgument(parent, parent.analyze(), false)) return null
is JetNamedFunction -> if (!InlineUtil.isInlinedArgument(parent, parent.analyze(), false)) return parent
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.psi.JetFile
import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
import kotlin.properties.Delegates
@@ -64,7 +65,7 @@ public class KotlinCleanupInspection(): LocalInspectionTool(), CleanupLocalInspe
val diagnostics = analysisResult.bindingContext.getDiagnostics()
class ProblemData(val problemDescriptor: ProblemDescriptor, elementToBeInvalidated: PsiElement) {
val depth = elementToBeInvalidated.parents(withItself = true).takeWhile { it !is PsiFile }.count()
val depth = elementToBeInvalidated.parentsWithSelf.takeWhile { it !is PsiFile }.count()
}
val problems = arrayListOf<ProblemData>()
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.psi.JetSimpleNameExpression
import com.intellij.psi.PsiWhiteSpace
import org.jetbrains.kotlin.lexer.JetTokens
import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
public class JoinDeclarationAndAssignmentHandler : JoinRawLinesHandlerDelegate {
@@ -39,7 +40,7 @@ public class JoinDeclarationAndAssignmentHandler : JoinRawLinesHandlerDelegate {
?.siblings(forward = false, withItself = false)
?.firstOrNull { !isToSkip(it) } ?: return -1
val pair = element.parents(withItself = true)
val pair = element.parentsWithSelf
.map { getPropertyAndAssignment(it) }
.filterNotNull()
.firstOrNull() ?: return -1
@@ -57,7 +57,7 @@ public class AddLoopLabelFix(loop: JetLoopExpression, val jumpExpression: JetEle
usedLabels.add(expression.getLabelName())
}
})
element.parents(false).forEach {
element.parents.forEach {
if (it is JetLabeledExpression) {
usedLabels.add(it.getLabelName())
}
@@ -531,7 +531,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
fun addNextToOriginalElementContainer(addBefore: Boolean): JetNamedDeclaration {
val actualContainer = (containingElement as? JetClassOrObject)?.getBody() ?: containingElement
val sibling = config.originalElement.parents().first { it.getParent() == actualContainer }
val sibling = config.originalElement.parentsWithSelf.first { it.getParent() == actualContainer }
return if (addBefore) {
actualContainer.addBefore(declaration, sibling)
}
@@ -43,7 +43,7 @@ object CreateLocalVariableActionFactory: JetSingleIntentionActionFactory() {
val propertyName = refExpr.getReferencedName()
val container = refExpr.parents(false)
val container = refExpr.parents
.filter { it is JetBlockExpression || it is JetDeclarationWithBody }
.firstOrNull() as? JetElement ?: return null
@@ -75,11 +75,11 @@ object CreateParameterActionFactory: JetSingleIntentionActionFactory() {
fun chooseContainingClass(it: PsiElement): JetClass? {
valOrVar = if (varExpected) JetValVar.Var else JetValVar.Val
return it.parents(false).firstIsInstanceOrNull<JetClassOrObject>() as? JetClass
return it.parents.firstIsInstanceOrNull<JetClassOrObject>() as? JetClass
}
// todo: skip lambdas for now because Change Signature doesn't apply to them yet
val container = refExpr.parents(false)
val container = refExpr.parents
.filter {
it is JetNamedFunction || it is JetPropertyAccessor || it is JetClassBody || it is JetClassInitializer ||
it is JetDelegationSpecifier
@@ -584,7 +584,7 @@ fun ExtractionGeneratorConfiguration.generateDeclaration(
// Ascend to the level of targetSibling
val targetParent = targetSibling.getParent()
marginalCandidate.parents().first { it.getParent() == targetParent }
marginalCandidate.parentsWithSelf.first { it.getParent() == targetParent }
}
val shouldInsert = !(generatorOptions.inTempFile || generatorOptions.target == ExtractionTarget.FAKE_LAMBDALIKE_FUNCTION)
@@ -49,10 +49,7 @@ import org.jetbrains.kotlin.idea.util.psi.patternMatching.JetPsiRange
import org.jetbrains.kotlin.idea.util.psi.patternMatching.JetPsiUnifier
import org.jetbrains.kotlin.idea.util.psi.patternMatching.toRange
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
import org.jetbrains.kotlin.psi.psiUtil.getValueParameterList
import org.jetbrains.kotlin.psi.psiUtil.getValueParameters
import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.scopes.JetScopeUtils
import java.util.Collections
@@ -90,7 +87,7 @@ public data class IntroduceParameterDescriptor(
}
}
if (occurrencesToReplace.all {
PsiTreeUtil.findCommonParent(it.elements)?.parents()?.any(modifierIsUnnecessary) ?: false
PsiTreeUtil.findCommonParent(it.elements)?.parentsWithSelf?.any(modifierIsUnnecessary) ?: false
}) JetValVar.None else JetValVar.Val
}
else JetValVar.None
@@ -154,12 +151,12 @@ fun selectNewParameterContext(
editor = editor,
file = file,
getContainers = { elements, parent ->
val parents = parent.parents(withItself = false)
val stopAt = (parent.parents(withItself = false) zip parent.parents(withItself = false).drop(1))
val parents = parent.parents
val stopAt = (parent.parents zip parent.parents.drop(1))
.firstOrNull { isObjectOrNonInnerClass(it.first) }
?.second
(if (stopAt != null) parent.parents(withItself = false).takeWhile { it != stopAt } else parents)
(if (stopAt != null) parent.parents.takeWhile { it != stopAt } else parents)
.filter {
((it is JetClass && !it.isInterface() && it !is JetEnumEntry) || it is JetNamedFunction || it is JetSecondaryConstructor) &&
((it as JetNamedDeclaration).getValueParameterList() != null || it.getNameIdentifier() != null)
@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.psi.JetFile
import org.jetbrains.kotlin.psi.JetProperty
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.types.JetType
import javax.swing.*
import javax.swing.event.PopupMenuEvent
@@ -164,7 +165,7 @@ public class KotlinInplacePropertyIntroducer(
}
override fun checkLocalScope(): PsiElement? {
return myElementToRename.parents().first { it is JetClassOrObject || it is JetFile }
return myElementToRename.parentsWithSelf.first { it is JetClassOrObject || it is JetFile }
}
override fun collectRefs(referencesSearchScope: SearchScope): MutableCollection<PsiReference>? {
@@ -151,7 +151,7 @@ public fun PsiElement.getAllExtractionContainers(strict: Boolean = true): List<J
public fun PsiElement.getExtractionContainers(strict: Boolean = true, includeAll: Boolean = false): List<JetElement> {
fun getEnclosingDeclaration(element: PsiElement, strict: Boolean): PsiElement? {
return element.parents(!strict)
return (if (strict) element.parents else element.parentsWithSelf)
.filter {
(it is JetDeclarationWithBody && it !is JetFunctionLiteral)
|| it is JetClassInitializer
@@ -104,7 +104,7 @@ public abstract class AbstractPartialBodyResolveTest : JetLightCodeInsightFixtur
builder.append("----------------------------------------------\n")
val skippedStatements = set
.filter { !it.parents(withItself = false).any { it in set } } // do not include skipped statements which are inside other skipped statement
.filter { !it.parents.any { it in set } } // do not include skipped statements which are inside other skipped statement
.sortBy { it.getTextOffset() }
myFixture.getProject().executeWriteCommand("") {
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.psi.JetTypeReference
import org.jetbrains.kotlin.psi.JetWhenCondition
import org.jetbrains.kotlin.idea.test.DirectiveBasedActionUtils
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
public abstract class AbstractJetPsiUnifierTest: JetLightCodeInsightFixtureTestCase() {
public fun doTest(filePath: String) {
@@ -38,7 +39,7 @@ public abstract class AbstractJetPsiUnifierTest: JetLightCodeInsightFixtureTestC
val start = selectionModel.getSelectionStart()
val end = selectionModel.getSelectionEnd()
val selectionRange = TextRange(start, end)
return file.findElementAt(start)?.parents()?.last {
return file.findElementAt(start)?.parentsWithSelf?.last {
(it is JetExpression || it is JetTypeReference || it is JetWhenCondition)
&& selectionRange.contains(it.getTextRange() ?: TextRange.EMPTY_RANGE)
} as JetElement
@@ -104,7 +104,7 @@ class ForConverter(
statement.isInSingleLine()).assignNoPrototype()
if (initializationConverted.isEmpty) return whileStatement
val kind = if (statement.parents(withItself = false).filter { it !is PsiLabeledStatement }.first() !is PsiCodeBlock) {
val kind = if (statement.parents.filter { it !is PsiLabeledStatement }.first() !is PsiCodeBlock) {
WhileWithInitializationPseudoStatement.Kind.WITH_BLOCK
}
else if (hasNameConflict())
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.resolve.BindingContext
import java.util.ArrayList
import java.util.Comparator
@@ -173,7 +174,7 @@ public class JavaToKotlinConverter(
val file: PsiFile,
val processings: Collection<UsageProcessing>
) {
val depth: Int by Delegates.lazy { target.parents(withItself = true).takeWhile { it !is PsiFile }.count() }
val depth: Int by Delegates.lazy { target.parentsWithSelf.takeWhile { it !is PsiFile }.count() }
}
private fun buildExternalCodeProcessing(