[uast] IDEA-332091 Use less memory for Java UAST elements

GitOrigin-RevId: c5230a90c90b0dcf70c4bf95261d37f877c0f0ad
This commit is contained in:
Yuriy Artamonov
2023-10-02 19:06:58 +02:00
committed by intellij-monorepo-bot
parent 809aeaadb5
commit c3ecb67628
47 changed files with 732 additions and 689 deletions

View File

@@ -0,0 +1,28 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast
import org.jetbrains.annotations.ApiStatus
val UNINITIALIZED_UAST_PART = Any()
@Suppress("unused")
class UastLazyPart<T> {
var value: Any? = UNINITIALIZED_UAST_PART
override fun toString(): String {
if (value == UNINITIALIZED_UAST_PART) return "UastLazyPart()"
return "UastLazyPart($value)"
}
}
@ApiStatus.Internal
@Suppress("UNCHECKED_CAST")
inline fun <T> UastLazyPart<T>.getOrBuild(crossinline initializer: () -> T): T {
var current: Any? = value
if (current != UNINITIALIZED_UAST_PART) return current as T
current = initializer.invoke()
value = current
return current
}

View File

@@ -45,12 +45,12 @@ open class UIdentifier(
}
open class LazyParentUIdentifier(psi: PsiElement?, givenParent: UElement?) : UIdentifier(psi, givenParent) {
private var uastParentValue: Any? = givenParent ?: NonInitializedLazyParentUIdentifierParent
private var uastParentValue: Any? = givenParent ?: UNINITIALIZED_UAST_PART
override val uastParent: UElement?
get() {
val currentValue = uastParentValue
if (currentValue != NonInitializedLazyParentUIdentifierParent) {
if (currentValue != UNINITIALIZED_UAST_PART) {
return currentValue as UElement?
}
@@ -63,8 +63,4 @@ open class LazyParentUIdentifier(psi: PsiElement?, givenParent: UElement?) : UId
protected open fun computeParent(): UElement? {
return sourcePsi?.parent?.toUElement()
}
private companion object {
val NonInitializedLazyParentUIdentifierParent = Any()
}
}

View File

@@ -1,38 +1,29 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java
import com.intellij.psi.PsiDoWhileStatement
import com.intellij.psi.impl.source.tree.ChildRole
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.uast.UDoWhileExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.UIdentifier
import org.jetbrains.uast.*
@ApiStatus.Internal
class JavaUDoWhileExpression(
override val sourcePsi: PsiDoWhileStatement,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UDoWhileExpression {
override val condition: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.condition, this) }
override val body: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.body, this) }
private val bodyPart = UastLazyPart<UExpression>()
private val conditionPart = UastLazyPart<UExpression>()
override val condition: UExpression
get() = conditionPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.condition, this) }
override val body: UExpression
get() = bodyPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.body, this) }
override val doIdentifier: UIdentifier
get() = UIdentifier(sourcePsi.getChildByRole(ChildRole.DO_KEYWORD), this)
override val whileIdentifier: UIdentifier
get() = UIdentifier(sourcePsi.getChildByRole(ChildRole.WHILE_KEYWORD), this)
}

View File

@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java
import com.intellij.psi.PsiForeachStatement
@@ -25,6 +11,10 @@ class JavaUForEachExpression(
override val sourcePsi: PsiForeachStatement,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UForEachExpression {
private val iteratedValuePart = UastLazyPart<UExpression>()
private val bodyPart = UastLazyPart<UExpression>()
@Deprecated("property may throw exception if foreach doesn't have variable", replaceWith = ReplaceWith("parameter"))
override val variable: UParameter
get() = JavaUParameter(sourcePsi.iterationParameter ?: error("Migrate code to $parameter"), this)
@@ -35,8 +25,11 @@ class JavaUForEachExpression(
return JavaUParameter(psiParameter, this)
}
override val iteratedValue: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.iteratedValue, this) }
override val body: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.body, this) }
override val iteratedValue: UExpression
get() = iteratedValuePart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.iteratedValue, this) }
override val body: UExpression
get() = bodyPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.body, this) }
override val forIdentifier: UIdentifier
get() = UIdentifier(sourcePsi.getChildByRole(ChildRole.FOR_KEYWORD), this)

View File

@@ -1,37 +1,35 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java
import com.intellij.psi.PsiForStatement
import com.intellij.psi.impl.source.tree.ChildRole
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.UForExpression
import org.jetbrains.uast.UIdentifier
import org.jetbrains.uast.*
@ApiStatus.Internal
class JavaUForExpression(
override val sourcePsi: PsiForStatement,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UForExpression {
override val declaration: UExpression? by lazyUnsafe { sourcePsi.initialization?.let { JavaConverter.convertStatement(it, this, UExpression::class.java) } }
override val condition: UExpression? by lazyUnsafe { sourcePsi.condition?.let { JavaConverter.convertExpression(it, this, UExpression::class.java) } }
override val update: UExpression? by lazyUnsafe { sourcePsi.update?.let { JavaConverter.convertStatement(it, this, UExpression::class.java) } }
override val body: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.body, this) }
private val declarationPart = UastLazyPart<UExpression?>()
private val conditionPart = UastLazyPart<UExpression?>()
private val updatePart = UastLazyPart<UExpression?>()
private val bodyPart = UastLazyPart<UExpression>()
override val declaration: UExpression?
get() = declarationPart.getOrBuild {
sourcePsi.initialization?.let { JavaConverter.convertStatement(it, this, UExpression::class.java) }
}
override val condition: UExpression?
get() = conditionPart.getOrBuild { sourcePsi.condition?.let { JavaConverter.convertExpression(it, this, UExpression::class.java) } }
override val update: UExpression?
get() = updatePart.getOrBuild { sourcePsi.update?.let { JavaConverter.convertStatement(it, this, UExpression::class.java) } }
override val body: UExpression
get() = bodyPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.body, this) }
override val forIdentifier: UIdentifier
get() = UIdentifier(sourcePsi.getChildByRole(ChildRole.FOR_KEYWORD), this)

View File

@@ -1,36 +1,29 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java
import com.intellij.psi.PsiIfStatement
import com.intellij.psi.impl.source.tree.ChildRole
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.UIdentifier
import org.jetbrains.uast.UIfExpression
import org.jetbrains.uast.*
@ApiStatus.Internal
class JavaUIfExpression(
override val sourcePsi: PsiIfStatement,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UIfExpression {
override val condition: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.condition, this) }
override val thenExpression: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.thenBranch, this) }
override val elseExpression: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.elseBranch, this) }
private val conditionPart = UastLazyPart<UExpression>()
private val thenExpressionPart = UastLazyPart<UExpression>()
private val elseExpressionPart = UastLazyPart<UExpression>()
override val condition: UExpression
get() = conditionPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.condition, this) }
override val thenExpression: UExpression
get() = thenExpressionPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.thenBranch, this) }
override val elseExpression: UExpression
get() = elseExpressionPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.elseBranch, this) }
override val isTernary: Boolean
get() = false

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java
import com.intellij.psi.*
@@ -13,9 +13,15 @@ class JavaUSwitchExpression(
override val sourcePsi: PsiSwitchBlock,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), USwitchExpression {
override val expression: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.expression, this) }
override val body: JavaUSwitchEntryList by lazyUnsafe { JavaUSwitchEntryList(sourcePsi, this) }
private val expressionPart = UastLazyPart<UExpression>()
private val bodyPart = UastLazyPart<JavaUSwitchEntryList>()
override val expression: UExpression
get() = expressionPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.expression, this) }
override val body: JavaUSwitchEntryList
get() = bodyPart.getOrBuild { JavaUSwitchEntryList(sourcePsi, this) }
override val switchIdentifier: UIdentifier
get() = UIdentifier(sourcePsi.getChildByRole(ChildRole.SWITCH_KEYWORD), this)
@@ -35,8 +41,8 @@ class JavaUSwitchEntryList(
it.asRenderString().withMargin
}
private val switchEntries: Lazy<List<JavaUSwitchEntry>> = lazyUnsafe {
val statements = sourcePsi.body?.statements ?: return@lazyUnsafe emptyList<JavaUSwitchEntry>()
private val switchEntries: Lazy<List<JavaUSwitchEntry>> = lazy(LazyThreadSafetyMode.NONE) {
val statements = sourcePsi.body?.statements ?: return@lazy emptyList<JavaUSwitchEntry>()
var currentLabels = listOf<PsiSwitchLabelStatementBase>()
var currentBody = listOf<PsiStatement>()
val result = mutableListOf<JavaUSwitchEntry>()
@@ -69,11 +75,10 @@ class JavaUSwitchEntryList(
result += JavaUSwitchEntry(currentLabels, currentBody, this)
}
result
}
override val expressions: List<UExpression>
get() = switchEntries.value
get() = switchEntries.value
internal fun findUSwitchEntryForLabel(switchLabelStatement: PsiSwitchLabelStatementBase): JavaUSwitchEntry? {
if (switchEntries.isInitialized()) return switchEntries.value.find { it.labels.contains(switchLabelStatement) }
@@ -98,7 +103,6 @@ class JavaUSwitchEntryList(
val psiSwitchLabelStatement = statement.prevSiblings.filterIsInstance<PsiSwitchLabelStatement>().firstOrNull() ?: return null
return findUSwitchEntryForLabel(psiSwitchLabelStatement)
}
}
private val PsiElement.nextSiblings: Sequence<PsiElement> get() = generateSequence(this) { it.nextSibling }
@@ -111,49 +115,55 @@ class JavaUSwitchEntry(
givenParent: UElement?,
private val addDummyBreak: Boolean = false
) : JavaAbstractUExpression(givenParent), USwitchClauseExpressionWithBody {
override val sourcePsi: PsiSwitchLabelStatementBase = labels.first()
override val caseValues: List<UExpression> by lazyUnsafe {
labels.flatMap {
if (it.isDefaultCase) {
listOf(JavaUDefaultCaseExpression(it, this))
}
else {
it.caseLabelElementList?.elements.orEmpty().map { element ->
if (element is PsiExpression) JavaConverter.convertOrEmpty(element, this)
else UnknownJavaExpression(element, this)
private val caseValuesPart = UastLazyPart<List<UExpression>>()
private val bodyPart = UastLazyPart<UExpressionList>()
override val sourcePsi: PsiSwitchLabelStatementBase
get() = labels.first()
override val caseValues: List<UExpression>
get() = caseValuesPart.getOrBuild {
labels.flatMap {
if (it.isDefaultCase) {
listOf(JavaUDefaultCaseExpression(it, this))
}
else {
it.caseLabelElementList?.elements.orEmpty().map { element ->
if (element is PsiExpression) JavaConverter.convertOrEmpty(element, this)
else UnknownJavaExpression(element, this)
}
}
}
}
}
override val body: UExpressionList by lazyUnsafe {
object : JavaUExpressionList(sourcePsi, JavaSpecialExpressionKinds.SWITCH_ENTRY, this) {
override val body: UExpressionList
get() = bodyPart.getOrBuild {
object : JavaUExpressionList(sourcePsi, JavaSpecialExpressionKinds.SWITCH_ENTRY, this) {
override val expressions: List<UExpression>
override val expressions: List<UExpression>
init {
val expressions = ArrayList<UExpression>(this@JavaUSwitchEntry.statements.size)
for (statement in this@JavaUSwitchEntry.statements) {
expressions.add(JavaConverter.convertOrEmpty(statement, this))
}
if (addDummyBreak) {
val lastValueExpressionPsi = expressions.lastOrNull()?.sourcePsi as? PsiExpression
if (lastValueExpressionPsi != null)
expressions[expressions.size - 1] = DummyYieldExpression(lastValueExpressionPsi, this,
this@JavaUSwitchEntry.sourcePsi.enclosingSwitchBlock)
}
init {
val expressions = ArrayList<UExpression>(this@JavaUSwitchEntry.statements.size)
for (statement in this@JavaUSwitchEntry.statements) {
expressions.add(JavaConverter.convertOrEmpty(statement, this))
}
if (addDummyBreak) {
val lastValueExpressionPsi = expressions.lastOrNull()?.sourcePsi as? PsiExpression
if (lastValueExpressionPsi != null)
expressions[expressions.size - 1] = DummyYieldExpression(lastValueExpressionPsi, this,
this@JavaUSwitchEntry.sourcePsi.enclosingSwitchBlock)
this.expressions = expressions
}
this.expressions = expressions
}
override fun asRenderString() = buildString {
appendLine("{")
expressions.forEach { appendLine(it.asRenderString().withMargin) }
appendLine("}")
override fun asRenderString() = buildString {
appendLine("{")
expressions.forEach { appendLine(it.asRenderString().withMargin) }
appendLine("}")
}
}
}
}
}
internal class DummyYieldExpression(
@@ -161,6 +171,9 @@ internal class DummyYieldExpression(
override val uastParent: UElement?,
private val enclosingSwitchBlock: PsiSwitchBlock?
) : UYieldExpression {
private val expressionPart = UastLazyPart<UExpression?>()
override val javaPsi: PsiElement? = null
override val sourcePsi: PsiElement? = null
override val psi: PsiElement?
@@ -170,7 +183,8 @@ internal class DummyYieldExpression(
override val uAnnotations: List<UAnnotation>
get() = emptyList()
override val expression: UExpression? by lazyUnsafe { JavaConverter.convertExpression(expressionPsi, this, UExpression::class.java) }
override val expression: UExpression?
get() = expressionPart.getOrBuild { JavaConverter.convertExpression(expressionPsi, this, UExpression::class.java) }
override fun equals(other: Any?): Boolean {
if (this === other) return true

View File

@@ -3,19 +3,26 @@ package org.jetbrains.uast.java
import com.intellij.psi.PsiConditionalExpression
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.UIdentifier
import org.jetbrains.uast.UIfExpression
import org.jetbrains.uast.*
@ApiStatus.Internal
class JavaUTernaryIfExpression(
override val sourcePsi: PsiConditionalExpression,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UIfExpression {
override val condition: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.condition, this) }
override val thenExpression: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.thenExpression, this) }
override val elseExpression: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.elseExpression, this) }
private val conditionPart = UastLazyPart<UExpression>()
private val thenExpressionPart = UastLazyPart<UExpression>()
private val elseExpressionPart = UastLazyPart<UExpression>()
override val condition: UExpression
get() = conditionPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.condition, this) }
override val thenExpression: UExpression
get() = thenExpressionPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.thenExpression, this) }
override val elseExpression: UExpression
get() = elseExpressionPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.elseExpression, this) }
override val isTernary: Boolean
get() = true

View File

@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java
import com.intellij.psi.*
@@ -25,16 +11,28 @@ class JavaUTryExpression(
override val sourcePsi: PsiTryStatement,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UTryExpression {
override val tryClause: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.tryBlock, this) }
override val catchClauses: List<UCatchClause> by lazyUnsafe { sourcePsi.catchSections.map { JavaUCatchClause(it, this) } }
override val finallyClause: UBlockExpression? by lazyUnsafe { sourcePsi.finallyBlock?.let { JavaConverter.convertBlock(it, this) } }
override val resourceVariables: List<UVariable> by lazyUnsafe {
sourcePsi.resourceList
?.filterIsInstance<PsiResourceVariable>()
?.map { JavaUVariable.create(it, this) }
?: emptyList()
}
private val tryClausePart = UastLazyPart<UExpression>()
private val catchClausesPart = UastLazyPart<List<UCatchClause>>()
private val finallyClausePart = UastLazyPart<UBlockExpression?>()
private val resourceVariablesPart = UastLazyPart<List<UVariable>>()
override val tryClause: UExpression
get() = tryClausePart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.tryBlock, this) }
override val catchClauses: List<UCatchClause>
get() = catchClausesPart.getOrBuild { sourcePsi.catchSections.map { JavaUCatchClause(it, this) } }
override val finallyClause: UBlockExpression?
get() = finallyClausePart.getOrBuild { sourcePsi.finallyBlock?.let { JavaConverter.convertBlock(it, this) } }
override val resourceVariables: List<UVariable>
get() = resourceVariablesPart.getOrBuild {
sourcePsi.resourceList
?.filterIsInstance<PsiResourceVariable>()
?.map { JavaUVariable.create(it, this) }
?: emptyList()
}
override val hasResources: Boolean
get() = sourcePsi.resourceList != null
@@ -51,19 +49,28 @@ class JavaUCatchClause(
override val sourcePsi: PsiCatchSection,
givenParent: UElement?
) : JavaAbstractUElement(givenParent), UCatchClause {
override val body: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.catchBlock, this) }
override val parameters: List<UParameter> by lazyUnsafe {
(sourcePsi.parameter?.let { listOf(it) } ?: emptyList()).map { JavaUParameter(it, this) }
}
private val bodyPart = UastLazyPart<UExpression>()
private val parametersPart = UastLazyPart<List<UParameter>>()
private val typeReferencesPart = UastLazyPart<List<UTypeReferenceExpression>>()
override val typeReferences: List<UTypeReferenceExpression> by lazyUnsafe {
val typeElement = sourcePsi.parameter?.typeElement ?: return@lazyUnsafe emptyList<UTypeReferenceExpression>()
if (typeElement.type is PsiDisjunctionType) {
typeElement.children.filterIsInstance<PsiTypeElement>().map { JavaUTypeReferenceExpression(it, this) }
override val body: UExpression
get() = bodyPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.catchBlock, this) }
override val parameters: List<UParameter>
get() = parametersPart.getOrBuild {
(sourcePsi.parameter?.let { listOf(it) } ?: emptyList())
.map { JavaUParameter(it, this) }
}
else {
listOf(JavaUTypeReferenceExpression(typeElement, this))
override val typeReferences: List<UTypeReferenceExpression>
get() = typeReferencesPart.getOrBuild {
val typeElement = sourcePsi.parameter?.typeElement ?: return@getOrBuild emptyList<UTypeReferenceExpression>()
if (typeElement.type is PsiDisjunctionType) {
typeElement.children.filterIsInstance<PsiTypeElement>().map { JavaUTypeReferenceExpression(it, this) }
}
else {
listOf(JavaUTypeReferenceExpression(typeElement, this))
}
}
}
}

View File

@@ -1,35 +1,25 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java
import com.intellij.psi.PsiWhileStatement
import com.intellij.psi.impl.source.tree.ChildRole
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.UIdentifier
import org.jetbrains.uast.UWhileExpression
import org.jetbrains.uast.*
@ApiStatus.Internal
class JavaUWhileExpression(
override val sourcePsi: PsiWhileStatement,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UWhileExpression {
override val condition: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.condition, this) }
override val body: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.body, this) }
private val conditionPart = UastLazyPart<UExpression>()
private val bodyPart = UastLazyPart<UExpression>()
override val condition: UExpression
get() = conditionPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.condition, this) }
override val body: UExpression
get() = bodyPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.body, this) }
override val whileIdentifier: UIdentifier
get() = UIdentifier(sourcePsi.getChildByRole(ChildRole.WHILE_KEYWORD), this)

View File

@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java
import com.intellij.psi.PsiAnnotation
@@ -28,16 +14,19 @@ class JavaUAnnotation(
givenParent: UElement?
) : JavaAbstractUElement(givenParent), UAnnotationEx, UAnchorOwner, UMultiResolvable {
private val attributeValuesPart = UastLazyPart<List<UNamedExpression>>()
override val javaPsi: PsiAnnotation = sourcePsi
override val qualifiedName: String?
get() = sourcePsi.qualifiedName
override val attributeValues: List<UNamedExpression> by lazyUnsafe {
val attributes = sourcePsi.parameterList.attributes
override val attributeValues: List<UNamedExpression>
get() = attributeValuesPart.getOrBuild {
val attributes = sourcePsi.parameterList.attributes
attributes.map { attribute -> JavaUNamedExpression(attribute, this) }
}
attributes.map { attribute -> JavaUNamedExpression(attribute, this) }
}
override val uastAnchor: UIdentifier?
get() = sourcePsi.nameReferenceElement?.referenceNameElement?.let { UIdentifier(it, this) }

View File

@@ -15,19 +15,22 @@ abstract class AbstractJavaUClass(
givenParent: UElement?
) : JavaAbstractUElement(givenParent), UClass, JavaUElementWithComments, UAnchorOwner, UDeclarationEx {
private val uastDeclarationsPart = UastLazyPart<List<UDeclaration>>()
abstract override val javaPsi: PsiClass
@Suppress("OverridingDeprecatedMember")
override val psi: PsiClass get() = javaPsi
override val uastDeclarations: List<UDeclaration> by lazyUnsafe {
mutableListOf<UDeclaration>().apply {
addAll(fields)
addAll(initializers)
addAll(methods)
addAll(innerClasses)
override val uastDeclarations: List<UDeclaration>
get() = uastDeclarationsPart.getOrBuild {
mutableListOf<UDeclaration>().apply {
addAll(fields)
addAll(initializers)
addAll(methods)
addAll(innerClasses)
}
}
}
protected fun createJavaUTypeReferenceExpression(referenceElement: PsiJavaCodeReferenceElement): LazyJavaUTypeReferenceExpression =
LazyJavaUTypeReferenceExpression(referenceElement, this) {
@@ -87,6 +90,9 @@ class JavaUAnonymousClass(
uastParent: UElement?
) : AbstractJavaUClass(uastParent), UAnonymousClass, UAnchorOwner, PsiAnonymousClass by sourcePsi {
private val uastAnchorPart = UastLazyPart<UIdentifier?>()
private val fakeConstructorPart = UastLazyPart<JavaUMethod?>()
@Suppress("OverridingDeprecatedMember")
override val psi: PsiAnonymousClass get() = sourcePsi
@@ -106,39 +112,42 @@ class JavaUAnonymousClass(
override fun convertParent(): UElement? = sourcePsi.parent.toUElementOfType<UObjectLiteralExpression>() ?: super.convertParent()
override val uastAnchor: UIdentifier? by lazyUnsafe {
when (javaPsi) {
is PsiEnumConstantInitializer ->
(javaPsi.parent as? PsiEnumConstant)?.let { UIdentifier(it.nameIdentifier, this) }
else -> UIdentifier(sourcePsi.baseClassReference.referenceNameElement, this)
override val uastAnchor: UIdentifier?
get() = uastAnchorPart.getOrBuild {
when (javaPsi) {
is PsiEnumConstantInitializer ->
(javaPsi.parent as? PsiEnumConstant)?.let { UIdentifier(it.nameIdentifier, this) }
else -> UIdentifier(sourcePsi.baseClassReference.referenceNameElement, this)
}
}
}
override fun getSuperClass(): UClass? = super<AbstractJavaUClass>.getSuperClass()
override fun getFields(): Array<UField> = super<AbstractJavaUClass>.getFields()
override fun getInitializers(): Array<UClassInitializer> = super<AbstractJavaUClass>.getInitializers()
private val fakeConstructor: JavaUMethod? by lazyUnsafe {
val psiClass = this.javaPsi
val physicalNewExpression = psiClass.parent.asSafely<PsiNewExpression>() ?: return@lazyUnsafe null
val superConstructor = physicalNewExpression.resolveMethod()
val lightMethodBuilder = object : LightMethodBuilder(psiClass.manager, psiClass.language, "<anon-init>") {
init {
containingClass = psiClass
isConstructor = true
private val fakeConstructor: JavaUMethod?
get() = fakeConstructorPart.getOrBuild {
val psiClass = this.javaPsi
val physicalNewExpression = psiClass.parent.asSafely<PsiNewExpression>() ?: return@getOrBuild null
val superConstructor = physicalNewExpression.resolveMethod()
val lightMethodBuilder = object : LightMethodBuilder(psiClass.manager, psiClass.language, "<anon-init>") {
init {
containingClass = psiClass
isConstructor = true
}
override fun getNavigationElement(): PsiElement =
superConstructor?.navigationElement ?: psiClass.superClass?.navigationElement ?: super.getNavigationElement()
override fun getParent(): PsiElement = psiClass
override fun getModifierList(): PsiModifierList = superConstructor?.modifierList ?: super.getModifierList()
override fun getParameterList(): PsiParameterList = superConstructor?.parameterList ?: super.getParameterList()
override fun getDocComment(): PsiDocComment? = superConstructor?.docComment ?: super.getDocComment()
}
override fun getNavigationElement(): PsiElement =
superConstructor?.navigationElement ?: psiClass.superClass?.navigationElement ?: super.getNavigationElement()
override fun getParent(): PsiElement = psiClass
override fun getModifierList(): PsiModifierList = superConstructor?.modifierList ?: super.getModifierList()
override fun getParameterList(): PsiParameterList = superConstructor?.parameterList ?: super.getParameterList()
override fun getDocComment(): PsiDocComment? = superConstructor?.docComment ?: super.getDocComment()
JavaUMethod(lightMethodBuilder, this@JavaUAnonymousClass)
}
JavaUMethod(lightMethodBuilder, this@JavaUAnonymousClass)
}
override fun getMethods(): Array<UMethod> {
val constructor = fakeConstructor ?: return super<AbstractJavaUClass>.getMethods()
val uMethods = SmartList<UMethod>()

View File

@@ -14,6 +14,9 @@ class JavaUClassInitializer(
uastParent: UElement?
) : JavaAbstractUElement(uastParent), UClassInitializerEx, JavaUElementWithComments, UAnchorOwner, PsiClassInitializer by sourcePsi {
private val uAnnotationsPart = UastLazyPart<List<UAnnotation>>()
private val uastBodyPart = UastLazyPart<UExpression>()
@Suppress("OverridingDeprecatedMember")
override val psi: PsiClassInitializer get() = sourcePsi
@@ -22,11 +25,13 @@ class JavaUClassInitializer(
override val uastAnchor: UIdentifier?
get() = null
override val uastBody: UExpression by lazyUnsafe {
UastFacade.findPlugin(sourcePsi.body)?.convertElement(sourcePsi.body, this, null) as? UExpression ?: UastEmptyExpression(this)
}
override val uastBody: UExpression
get() = uastBodyPart.getOrBuild {
UastFacade.findPlugin(sourcePsi.body)?.convertElement(sourcePsi.body, this, null) as? UExpression ?: UastEmptyExpression(this)
}
override val uAnnotations: List<UAnnotation> by lazyUnsafe { sourcePsi.annotations.map { JavaUAnnotation(it, this) } }
override val uAnnotations: List<UAnnotation>
get() = uAnnotationsPart.getOrBuild { sourcePsi.annotations.map { JavaUAnnotation(it, this) } }
override fun equals(other: Any?): Boolean = this === other
override fun hashCode(): Int = sourcePsi.hashCode()

View File

@@ -14,12 +14,17 @@ class JavaUFile(
override val languagePlugin: UastLanguagePlugin
) : UFile, UElement, JavaUElementWithComments {
private val importsPart = UastLazyPart<List<UImportStatement>>()
private val classesPart = UastLazyPart<List<UClass>>()
private val allCommentsInFilePart = UastLazyPart<List<UComment>>()
override val packageName: String
get() = sourcePsi.packageName
override val imports: List<UImportStatement> by lazyUnsafe {
sourcePsi.importList?.allImportStatements?.map { JavaUImportStatement(it, this) } ?: listOf()
}
override val imports: List<UImportStatement>
get() = importsPart.getOrBuild {
sourcePsi.importList?.allImportStatements?.map { JavaUImportStatement(it, this) } ?: listOf()
}
override val implicitImports: List<String>
get() = sourcePsi.implicitlyImportedPackages.toList()
@@ -27,20 +32,24 @@ class JavaUFile(
override val uAnnotations: List<UAnnotation>
get() = sourcePsi.packageStatement?.annotationList?.annotations?.map { JavaUAnnotation(it, this) } ?: emptyList()
override val classes: List<UClass> by lazyUnsafe { sourcePsi.classes.map { JavaUClass.create(it, this) } }
override val classes: List<UClass>
get() = classesPart.getOrBuild { sourcePsi.classes.map { JavaUClass.create(it, this) } }
override val allCommentsInFile: ArrayList<UComment> by lazyUnsafe {
val comments = ArrayList<UComment>(0)
sourcePsi.accept(object : PsiRecursiveElementWalkingVisitor() {
override fun visitComment(comment: PsiComment) {
comments += UComment(comment, this@JavaUFile)
}
})
comments
}
override val allCommentsInFile: List<UComment>
get() = allCommentsInFilePart.getOrBuild {
val comments = ArrayList<UComment>(0)
sourcePsi.accept(object : PsiRecursiveElementWalkingVisitor() {
override fun visitComment(comment: PsiComment) {
comments += UComment(comment, this@JavaUFile)
}
})
comments
}
override fun equals(other: Any?): Boolean = (other as? JavaUFile)?.sourcePsi == sourcePsi
override fun hashCode(): Int = sourcePsi.hashCode()
@Suppress("OverridingDeprecatedMember")
override val psi: PsiJavaFile
get() = sourcePsi

View File

@@ -1,36 +1,25 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiImportStatementBase
import com.intellij.psi.ResolveResult
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UImportStatement
import org.jetbrains.uast.UMultiResolvable
import org.jetbrains.uast.*
@ApiStatus.Internal
class JavaUImportStatement(
override val sourcePsi: PsiImportStatementBase,
uastParent: UElement?
) : JavaAbstractUElement(uastParent), UImportStatement, UMultiResolvable {
private val importReferencePart = UastLazyPart<UElement?>()
override val isOnDemand: Boolean
get() = sourcePsi.isOnDemand
override val importReference: UElement? by lazyUnsafe { sourcePsi.importReference?.let { JavaDumbUElement(it, this, it.qualifiedName) } }
override val importReference: UElement?
get() = importReferencePart.getOrBuild { sourcePsi.importReference?.let { JavaDumbUElement(it, this, it.qualifiedName) } }
override fun resolve(): PsiElement? = sourcePsi.resolve()
override fun multiResolve(): Iterable<ResolveResult> =
sourcePsi.importReference?.multiResolve(false)?.asIterable() ?: emptyList()

View File

@@ -16,6 +16,11 @@ open class JavaUMethod(
uastParent: UElement?
) : JavaAbstractUElement(uastParent), UMethod, JavaUElementWithComments, UAnchorOwner, PsiMethod by javaPsi {
private val uastBodyPart = UastLazyPart<UExpression?>()
private val returnTypeReferencePart = UastLazyPart<UTypeReferenceExpression?>()
private val uAnnotationsPart = UastLazyPart<List<UAnnotation>>()
private val uastParametersPart = UastLazyPart<List<UParameter>>()
@Suppress("OverridingDeprecatedMember")
override val psi: PsiMethod
get() = javaPsi
@@ -25,16 +30,19 @@ open class JavaUMethod(
// hah, there is a Lombok and Enums and also Records, so we have fake PsiElements even in Java (IDEA-216248)
javaPsi.takeIf { it !is LightElement }
override val uastBody: UExpression? by lazyUnsafe {
val body = sourcePsi.asSafely<PsiMethod>()?.body ?: return@lazyUnsafe null
UastFacade.findPlugin(body)?.convertElement(body, this) as? UExpression
}
override val uastBody: UExpression?
get() = uastBodyPart.getOrBuild {
val body = sourcePsi.asSafely<PsiMethod>()?.body ?: return@getOrBuild null
UastFacade.findPlugin(body)?.convertElement(body, this) as? UExpression
}
override val uAnnotations: List<UAnnotation> by lazyUnsafe { javaPsi.annotations.map { JavaUAnnotation(it, this) } }
override val uAnnotations: List<UAnnotation>
get() = uAnnotationsPart.getOrBuild { javaPsi.annotations.map { JavaUAnnotation(it, this) } }
override val uastParameters: List<UParameter> by lazyUnsafe {
javaPsi.parameterList.parameters.mapNotNull { convertOrReport(it, this) }
}
override val uastParameters: List<UParameter>
get() = uastParametersPart.getOrBuild {
javaPsi.parameterList.parameters.mapNotNull { convertOrReport(it, this) }
}
override fun getPsiParentForLazyConversion(): PsiElement? = super.getPsiParentForLazyConversion() ?: javaPsi.containingClass
@@ -69,9 +77,10 @@ open class JavaUMethod(
}
}
override val returnTypeReference: UTypeReferenceExpression? by lazyUnsafe {
javaPsi.returnTypeElement?.let { JavaUTypeReferenceExpression(it, this) }
}
override val returnTypeReference: UTypeReferenceExpression?
get() = returnTypeReferencePart.getOrBuild {
javaPsi.returnTypeElement?.let { JavaUTypeReferenceExpression(it, this) }
}
override fun getOriginalElement(): PsiElement? = javaPsi.originalElement
}
@@ -92,16 +101,19 @@ private class JavaRecordConstructorUMethod(
@ApiStatus.Internal
class JavaUAnnotationMethod(
override val javaPsi: PsiAnnotationMethod,
languagePlugin: UastLanguagePlugin,
private val languagePlugin: UastLanguagePlugin,
containingElement: UElement?
) : JavaUMethod(javaPsi, containingElement), UAnnotationMethod, UDeclarationEx {
private val uastDefaultValuePart = UastLazyPart<UExpression?>()
@Suppress("OverridingDeprecatedMember")
override val psi: PsiAnnotationMethod
get() = javaPsi
override val uastDefaultValue: UExpression? by lazyUnsafe {
val defaultValue = javaPsi.defaultValue ?: return@lazyUnsafe null
languagePlugin.convertElement(defaultValue, this, null) as? UExpression
}
override val uastDefaultValue: UExpression?
get() = uastDefaultValuePart.getOrBuild {
val defaultValue = javaPsi.defaultValue ?: return@getOrBuild null
languagePlugin.convertElement(defaultValue, this, null) as? UExpression
}
}

View File

@@ -21,21 +21,29 @@ abstract class AbstractJavaUVariable(
givenParent: UElement?
) : JavaAbstractUElement(givenParent), PsiVariable, UVariableEx, JavaUElementWithComments, UAnchorOwner {
private val uastInitializerPart = UastLazyPart<UExpression?>()
private val uAnnotationsPart = UastLazyPart<List<UAnnotation>>()
private val typeReferencePart = UastLazyPart<UTypeReferenceExpression?>()
abstract override val javaPsi: PsiVariable
@Suppress("OverridingDeprecatedMember")
override val psi: PsiVariable
get() = javaPsi
override val uastInitializer: UExpression? by lazyUnsafe {
val initializer = javaPsi.initializer ?: return@lazyUnsafe null
UastFacade.findPlugin(initializer)?.convertElement(initializer, this) as? UExpression
}
override val uastInitializer: UExpression?
get() = uastInitializerPart.getOrBuild {
val initializer = javaPsi.initializer ?: return@getOrBuild null
UastFacade.findPlugin(initializer)?.convertElement(initializer, this) as? UExpression
}
override val uAnnotations: List<UAnnotation> by lazyUnsafe { javaPsi.annotations.map { JavaUAnnotation(it, this) } }
override val typeReference: UTypeReferenceExpression? by lazyUnsafe {
javaPsi.typeElement?.let { UastFacade.findPlugin(it)?.convertOpt<UTypeReferenceExpression>(javaPsi.typeElement, this) }
}
override val uAnnotations: List<UAnnotation>
get() = uAnnotationsPart.getOrBuild { javaPsi.annotations.map { JavaUAnnotation(it, this) } }
override val typeReference: UTypeReferenceExpression?
get() = typeReferencePart.getOrBuild {
javaPsi.typeElement?.let { UastFacade.findPlugin(it)?.convertOpt<UTypeReferenceExpression>(javaPsi.typeElement, this) }
}
abstract override val sourcePsi: PsiVariable?
@@ -223,7 +231,12 @@ class JavaUEnumConstant(
override val sourcePsi: PsiEnumConstant,
givenParent: UElement?
) : AbstractJavaUVariable(givenParent), UEnumConstantEx, UCallExpression, PsiEnumConstant by sourcePsi, UMultiResolvable {
override val initializingClass: UClass? by lazyUnsafe { UastFacade.findPlugin(sourcePsi)?.convertOpt(sourcePsi.initializingClass, this) }
private val initializingClassPart = UastLazyPart<UClass?>()
private val valueArgumentsPart = UastLazyPart<List<UExpression>>()
override val initializingClass: UClass?
get() = initializingClassPart.getOrBuild { UastFacade.findPlugin(sourcePsi)?.convertOpt(sourcePsi.initializingClass, this) }
@Suppress("OverridingDeprecatedMember")
override val psi: PsiEnumConstant
@@ -248,11 +261,12 @@ class JavaUEnumConstant(
override val valueArgumentCount: Int
get() = sourcePsi.argumentList?.expressions?.size ?: 0
override val valueArguments: List<UExpression> by lazyUnsafe {
sourcePsi.argumentList?.expressions?.map {
UastFacade.findPlugin(it)?.convertElement(it, this) as? UExpression ?: UastEmptyExpression(this)
} ?: emptyList()
}
override val valueArguments: List<UExpression>
get() = valueArgumentsPart.getOrBuild {
sourcePsi.argumentList?.expressions?.map {
UastFacade.findPlugin(it)?.convertElement(it, this) as? UExpression ?: UastEmptyExpression(this)
} ?: emptyList()
}
override fun getArgumentForParameter(i: Int): UExpression? = valueArguments.getOrNull(i)

View File

@@ -1,6 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java.expressions
import com.intellij.psi.PsiAnnotation
@@ -12,7 +10,6 @@ import org.jetbrains.uast.*
import org.jetbrains.uast.java.JavaAbstractUExpression
import org.jetbrains.uast.java.JavaConverter
import org.jetbrains.uast.java.JavaUAnnotation
import org.jetbrains.uast.java.lazyUnsafe
import org.jetbrains.uast.visitor.UastVisitor
@ApiStatus.Internal
@@ -21,11 +18,16 @@ class JavaUAnnotationCallExpression(
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UCallExpression, UMultiResolvable {
private val uAnnotationPart = UastLazyPart<JavaUAnnotation>()
private val classReferencePart = UastLazyPart<UReferenceExpression?>()
private val valueArgumentsPart = UastLazyPart<List<UNamedExpression>>()
// TODO: once there is no more external usage, this property can be `private`.
@get:ApiStatus.Internal
val uAnnotation: JavaUAnnotation by lazyUnsafe {
JavaUAnnotation(sourcePsi, this)
}
val uAnnotation: JavaUAnnotation
get() = uAnnotationPart.getOrBuild {
JavaUAnnotation(sourcePsi, this)
}
override val returnType: PsiType?
get() = uAnnotation.qualifiedName?.let { PsiType.getTypeByName(it, sourcePsi.project, sourcePsi.resolveScope) }
@@ -44,18 +46,18 @@ class JavaUAnnotationCallExpression(
override val methodIdentifier: UIdentifier?
get() = null
override val classReference: UReferenceExpression? by lazyUnsafe {
sourcePsi.nameReferenceElement?.let { ref ->
JavaConverter.convertReference(ref, this, UElement::class.java) as? UReferenceExpression
override val classReference: UReferenceExpression?
get() = classReferencePart.getOrBuild {
sourcePsi.nameReferenceElement?.let { ref ->
JavaConverter.convertReference(ref, this, UElement::class.java) as? UReferenceExpression
}
}
}
override val valueArgumentCount: Int
get() = sourcePsi.parameterList.attributes.size
override val valueArguments: List<UNamedExpression> by lazyUnsafe {
uAnnotation.attributeValues
}
override val valueArguments: List<UNamedExpression>
get() = valueArgumentsPart.getOrBuild { uAnnotation.attributeValues }
override fun getArgumentForParameter(i: Int): UExpression? = valueArguments.getOrNull(i)

View File

@@ -18,17 +18,24 @@ package org.jetbrains.uast.java
import com.intellij.psi.PsiArrayAccessExpression
import com.intellij.psi.PsiElement
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.uast.UArrayAccessExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.*
@ApiStatus.Internal
class JavaUArrayAccessExpression(
override val sourcePsi: PsiArrayAccessExpression,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UArrayAccessExpression {
override val receiver: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.arrayExpression, this) }
override val indices: List<UExpression> by lazyUnsafe { singletonListOrEmpty(JavaConverter.convertOrNull(sourcePsi.indexExpression, this)) }
private val receiverPart = UastLazyPart<UExpression>()
private val indicesPart = UastLazyPart<List<UExpression>>()
override val receiver: UExpression
get() = receiverPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.arrayExpression, this) }
override val indices: List<UExpression>
get() = indicesPart.getOrBuild {
singletonListOrEmpty(JavaConverter.convertOrNull(sourcePsi.indexExpression, this))
}
// No operator overloading in Java (yet?)
override fun resolve(): PsiElement? = null

View File

@@ -28,8 +28,15 @@ class JavaUAssertExpression(
override val sourcePsi: PsiAssertStatement,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UCallExpression, UMultiResolvable {
val condition: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.assertCondition, this) }
val message: UExpression? by lazyUnsafe { JavaConverter.convertOrNull(sourcePsi.assertDescription, this) }
private val conditionPart = UastLazyPart<UExpression>()
private val messagePart = UastLazyPart<UExpression?>()
private val valueArgumentsPart = UastLazyPart<List<UExpression>>()
val condition: UExpression
get() = conditionPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.assertCondition, this) }
val message: UExpression?
get() = messagePart.getOrBuild { JavaConverter.convertOrNull(sourcePsi.assertDescription, this) }
@Suppress("OverridingDeprecatedMember")
override val psi: PsiAssertStatement
@@ -53,10 +60,11 @@ class JavaUAssertExpression(
override val valueArgumentCount: Int
get() = if (message != null) 2 else 1
override val valueArguments: List<UExpression> by lazyUnsafe {
val message = this.message
if (message != null) listOf(condition, message) else listOf(condition)
}
override val valueArguments: List<UExpression>
get() = valueArgumentsPart.getOrBuild {
val message = this.message
if (message != null) listOf(condition, message) else listOf(condition)
}
override fun getArgumentForParameter(i: Int): UExpression? = valueArguments.getOrNull(i)

View File

@@ -24,9 +24,19 @@ class JavaUAssignmentExpression(
override val sourcePsi: PsiAssignmentExpression,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UBinaryExpression {
override val leftOperand: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.lExpression, this) }
override val rightOperand: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.rExpression, this) }
override val operator: UastBinaryOperator by lazyUnsafe { sourcePsi.operationTokenType.getOperatorType() }
private val leftOperandPart = UastLazyPart<UExpression>()
private val rightOperandPart = UastLazyPart<UExpression>()
private val operatorPart = UastLazyPart<UastBinaryOperator>()
override val leftOperand: UExpression
get() = leftOperandPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.lExpression, this) }
override val rightOperand: UExpression
get() = rightOperandPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.rExpression, this) }
override val operator: UastBinaryOperator
get() = operatorPart.getOrBuild { sourcePsi.operationTokenType.getOperatorType() }
override fun resolveOperator(): Nothing? = null

View File

@@ -24,9 +24,19 @@ class JavaUBinaryExpression(
override val sourcePsi: PsiBinaryExpression,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UBinaryExpression {
override val leftOperand: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.lOperand, this) }
override val rightOperand: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.rOperand, this) }
override val operator: UastBinaryOperator by lazyUnsafe { sourcePsi.operationTokenType.getOperatorType() }
private val leftOperandPart = UastLazyPart<UExpression>()
private val rightOperandPart = UastLazyPart<UExpression>()
private val operatorPart = UastLazyPart<UastBinaryOperator>()
override val leftOperand: UExpression
get() = leftOperandPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.lOperand, this) }
override val rightOperand: UExpression
get() = rightOperandPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.rOperand, this) }
override val operator: UastBinaryOperator
get() = operatorPart.getOrBuild { sourcePsi.operationTokenType.getOperatorType() }
override val operatorIdentifier: UIdentifier
get() = UIdentifier(sourcePsi.operationSign, this)

View File

@@ -17,14 +17,16 @@ package org.jetbrains.uast.java
import com.intellij.psi.PsiBlockStatement
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.uast.UBlockExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.*
@ApiStatus.Internal
class JavaUBlockExpression(
override val sourcePsi: PsiBlockStatement,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UBlockExpression {
override val expressions: List<UExpression> by lazyUnsafe { sourcePsi.codeBlock.statements.map { JavaConverter.convertOrEmpty(it, this) } }
private val expressionsPart = UastLazyPart<List<UExpression>>()
override val expressions: List<UExpression>
get() = expressionsPart.getOrBuild { sourcePsi.codeBlock.statements.map { JavaConverter.convertOrEmpty(it, this) } }
}

View File

@@ -3,19 +3,21 @@ package org.jetbrains.uast.java
import com.intellij.psi.PsiBreakStatement
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.uast.UBreakExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.*
@ApiStatus.Internal
class JavaUBreakExpression(
override val sourcePsi: PsiBreakStatement,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UBreakExpression {
private val jumpTargetPart = UastLazyPart<UElement?>()
override val label: String?
get() = sourcePsi.labelIdentifier?.text
override val jumpTarget: UElement? by lazyUnsafe {
sourcePsi.findExitedStatement().takeIf { it !== sourcePsi }?.let { JavaConverter.convertStatement(it, null, UExpression::class.java) }
}
override val jumpTarget: UElement?
get() = jumpTargetPart.getOrBuild {
sourcePsi.findExitedStatement().takeIf { it !== sourcePsi }?.let { JavaConverter.convertStatement(it, null, UExpression::class.java) }
}
}

View File

@@ -17,17 +17,19 @@ package org.jetbrains.uast.java
import com.intellij.psi.*
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.uast.UCallableReferenceExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.UMultiResolvable
import org.jetbrains.uast.*
@ApiStatus.Internal
class JavaUCallableReferenceExpression(
override val sourcePsi: PsiMethodReferenceExpression,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UCallableReferenceExpression, UMultiResolvable {
override val qualifierExpression: UExpression? by lazyUnsafe { JavaConverter.convertOrNull(sourcePsi.qualifierExpression, this) }
private val qualifierExpressionPart = UastLazyPart<UExpression?>()
private val referenceNameElementPart = UastLazyPart<UElement?>()
override val qualifierExpression: UExpression?
get() = qualifierExpressionPart.getOrBuild { JavaConverter.convertOrNull(sourcePsi.qualifierExpression, this) }
override val qualifierType: PsiType?
get() = sourcePsi.qualifierType?.type
@@ -42,7 +44,8 @@ class JavaUCallableReferenceExpression(
override val resolvedName: String?
get() = (sourcePsi.resolve() as? PsiNamedElement)?.name
override val referenceNameElement: UElement? by lazyUnsafe {
sourcePsi.referenceNameElement?.let { JavaUSimpleNameReferenceExpression(it, callableName, this, it.reference) }
}
override val referenceNameElement: UElement?
get() = referenceNameElementPart.getOrBuild {
sourcePsi.referenceNameElement?.let { JavaUSimpleNameReferenceExpression(it, callableName, this, it.reference) }
}
}

View File

@@ -20,18 +20,24 @@ import com.intellij.psi.PsiType
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.uast.UClassLiteralExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UastLazyPart
import org.jetbrains.uast.getOrBuild
@ApiStatus.Internal
class JavaUClassLiteralExpression(
override val sourcePsi: PsiClassObjectAccessExpression,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UClassLiteralExpression {
private val expressionPart = UastLazyPart<JavaUTypeReferenceExpression>()
override val type: PsiType
get() = sourcePsi.operand.type
// TODO: return type JavaUTypeReferenceExpression doesn't have anything special,
// so UTypeReferenceExpression should be good enough (or checking if the underlying sourcePsi is from Java).
override val expression: JavaUTypeReferenceExpression by lazyUnsafe {
JavaUTypeReferenceExpression(sourcePsi.operand, this)
}
override val expression: JavaUTypeReferenceExpression
get() = expressionPart.getOrBuild {
JavaUTypeReferenceExpression(sourcePsi.operand, this)
}
}

View File

@@ -17,14 +17,16 @@ package org.jetbrains.uast.java
import com.intellij.psi.PsiCodeBlock
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.uast.UBlockExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.*
@ApiStatus.Internal
class JavaUCodeBlockExpression(
override val sourcePsi: PsiCodeBlock,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UBlockExpression {
override val expressions: List<UExpression> by lazyUnsafe { sourcePsi.statements.map { JavaConverter.convertOrEmpty(it, this) } }
private val expressionsPart = UastLazyPart<List<UExpression>>()
override val expressions: List<UExpression>
get() = expressionsPart.getOrBuild { sourcePsi.statements.map { JavaConverter.convertOrEmpty(it, this) } }
}

View File

@@ -18,19 +18,23 @@ package org.jetbrains.uast.java
import com.intellij.psi.PsiContinueStatement
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.uast.UContinueExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.*
@ApiStatus.Internal
class JavaUContinueExpression(
override val sourcePsi: PsiContinueStatement,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UContinueExpression {
private val jumpTargetPart = UastLazyPart<UElement?>()
override val label: String?
get() = sourcePsi.labelIdentifier?.text
override val jumpTarget: UElement? by lazyUnsafe {
sourcePsi.findContinuedStatement().takeIf { it !== sourcePsi }?.let { JavaConverter.convertStatement(it, null, UExpression::class.java) }
}
override val jumpTarget: UElement?
get() = jumpTargetPart.getOrBuild {
sourcePsi.findContinuedStatement().takeIf { it !== sourcePsi }?.let {
JavaConverter.convertStatement(it, null, UExpression::class.java)
}
}
}

View File

@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java
import com.intellij.psi.PsiInstanceOfExpression
@@ -25,8 +11,17 @@ class JavaUInstanceCheckExpression(
override val sourcePsi: PsiInstanceOfExpression,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UBinaryExpressionWithType {
override val operand: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.operand, this) }
override val typeReference: JavaUTypeReferenceExpression? by lazyUnsafe { sourcePsi.checkType?.let { JavaUTypeReferenceExpression(it, this) } }
private val operandPart = UastLazyPart<UExpression>()
private val typeReferencePart = UastLazyPart<JavaUTypeReferenceExpression?>()
override val operand: UExpression
get() = operandPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.operand, this) }
override val typeReference: JavaUTypeReferenceExpression?
get() = typeReferencePart.getOrBuild {
sourcePsi.checkType?.let { JavaUTypeReferenceExpression(it, this) }
}
override val type: PsiType
get() = sourcePsi.checkType?.type ?: UastErrorType

View File

@@ -1,25 +1,26 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java
import com.intellij.psi.PsiLabeledStatement
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.UIdentifier
import org.jetbrains.uast.ULabeledExpression
import org.jetbrains.uast.*
@ApiStatus.Internal
class JavaULabeledExpression(
override val sourcePsi: PsiLabeledStatement,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), ULabeledExpression {
private val expressionPart = UastLazyPart<UExpression>()
override val label: String
get() = sourcePsi.labelIdentifier.text
override val labelIdentifier: UIdentifier
get() = UIdentifier(sourcePsi.labelIdentifier, this)
override val expression: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.statement, this) }
override val expression: UExpression
get() = expressionPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.statement, this) }
override fun evaluate(): Any? = expression.evaluate()
}

View File

@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java
import com.intellij.psi.*
@@ -25,23 +11,28 @@ class JavaULambdaExpression(
override val sourcePsi: PsiLambdaExpression,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), ULambdaExpression {
private val bodyPart = UastLazyPart<UExpression>()
private val valueParametersPart = UastLazyPart<List<UParameter>>()
override val functionalInterfaceType: PsiType?
get() = sourcePsi.functionalInterfaceType
override val valueParameters: List<UParameter> by lazyUnsafe {
sourcePsi.parameterList.parameters.map { JavaUParameter(it, this) }
}
override val body: UExpression by lazyUnsafe {
when (val b = sourcePsi.body) {
is PsiCodeBlock -> JavaConverter.convertBlock(b, this)
is PsiExpression -> wrapLambdaBody(this, b)
else -> UastEmptyExpression(this)
override val valueParameters: List<UParameter>
get() = valueParametersPart.getOrBuild {
sourcePsi.parameterList.parameters.map { JavaUParameter(it, this) }
}
override val body: UExpression
get() = bodyPart.getOrBuild {
when (val b = sourcePsi.body) {
is PsiCodeBlock -> JavaConverter.convertBlock(b, this)
is PsiExpression -> wrapLambdaBody(this, b)
else -> UastEmptyExpression(this)
}
}
}
companion object {
@Internal
fun unwrapImplicitBody(uExpression: UExpression): PsiExpression? =
uExpression
@@ -85,12 +76,12 @@ private class JavaImplicitUReturnExpression(givenParent: UElement?) : JavaAbstra
}
override fun hashCode(): Int = 31 + returnExpression.hashCode()
}
private class JavaImplicitUBlockExpression(givenParent: UElement?) : JavaAbstractUExpression(givenParent), UBlockExpression {
override val sourcePsi: PsiElement?
get() = null
override lateinit var expressions: List<UExpression>
internal set
@@ -102,5 +93,4 @@ private class JavaImplicitUBlockExpression(givenParent: UElement?) : JavaAbstrac
}
override fun hashCode(): Int = 31 + expressions.hashCode()
}

View File

@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java
import com.intellij.psi.PsiLanguageInjectionHost
@@ -26,8 +12,17 @@ class JavaULiteralExpression(
override val sourcePsi: PsiLiteralExpressionImpl,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), ULiteralExpression, UInjectionHost {
private var lazyValue: Any? = UNINITIALIZED_UAST_PART
override fun evaluate(): Any? = sourcePsi.value
override val value: Any? by lazyUnsafe { evaluate() }
override val value: Any?
get() {
if (lazyValue == UNINITIALIZED_UAST_PART) {
lazyValue = evaluate()
}
return lazyValue
}
override val isString: Boolean
get() = super<UInjectionHost>.isString

View File

@@ -1,41 +1,28 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java.expressions
import com.intellij.psi.PsiNameValuePair
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.UNamedExpression
import org.jetbrains.uast.UastEmptyExpression
import org.jetbrains.uast.*
import org.jetbrains.uast.java.JavaAbstractUExpression
import org.jetbrains.uast.java.JavaConverter
import org.jetbrains.uast.java.lazyUnsafe
@ApiStatus.Internal
class JavaUNamedExpression(
override val sourcePsi: PsiNameValuePair,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UNamedExpression {
private val expressionPart = UastLazyPart<UExpression>()
override fun evaluate(): Any? = expression.evaluate()
override val name: String?
get() = sourcePsi.name
override val expression: UExpression by lazyUnsafe {
sourcePsi.value?.let { value -> JavaConverter.convertPsiElement(value, this, UElement::class.java) } as? UExpression ?: UastEmptyExpression(this)
}
override val expression: UExpression
get() = expressionPart.getOrBuild {
sourcePsi.value
?.let { value -> JavaConverter.convertPsiElement(value, this, UElement::class.java) } as? UExpression
?: UastEmptyExpression(this)
}
}

View File

@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java
import com.intellij.psi.PsiMethod
@@ -27,24 +13,38 @@ class JavaUObjectLiteralExpression(
override val sourcePsi: PsiNewExpression,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UObjectLiteralExpression, UCallExpression, UMultiResolvable {
override val declaration: UClass by lazyUnsafe { JavaUClass.create(sourcePsi.anonymousClass!!, this) }
private val declarationPart = UastLazyPart<UClass>()
private val classReferencePart = UastLazyPart<UReferenceExpression?>()
private val valueArgumentsPart = UastLazyPart<List<UExpression>>()
private var typeArgumentCountLazy = Int.MIN_VALUE
override val classReference: UReferenceExpression? by lazyUnsafe {
sourcePsi.classReference?.let { ref ->
JavaConverter.convertReference(ref, this, UElement::class.java) as? UReferenceExpression
override val declaration: UClass
get() = declarationPart.getOrBuild { JavaUClass.create(sourcePsi.anonymousClass!!, this) }
override val classReference: UReferenceExpression?
get() = classReferencePart.getOrBuild {
sourcePsi.classReference?.let { ref ->
JavaConverter.convertReference(ref, this, UElement::class.java) as? UReferenceExpression
}
}
}
override val valueArgumentCount: Int
get() = sourcePsi.argumentList?.expressions?.size ?: 0
override val valueArguments: List<UExpression> by lazyUnsafe {
sourcePsi.argumentList?.expressions?.map { JavaConverter.convertOrEmpty(it, this) } ?: emptyList()
}
override val valueArguments: List<UExpression>
get() = valueArgumentsPart.getOrBuild {
sourcePsi.argumentList?.expressions?.map { JavaConverter.convertOrEmpty(it, this) } ?: emptyList()
}
override fun getArgumentForParameter(i: Int): UExpression? = valueArguments.getOrNull(i)
override val typeArgumentCount: Int by lazyUnsafe { sourcePsi.classReference?.typeParameters?.size ?: 0 }
override val typeArgumentCount: Int
get() {
if (typeArgumentCountLazy == Int.MIN_VALUE) {
typeArgumentCountLazy = sourcePsi.classReference?.typeParameters?.size ?: 0
}
return typeArgumentCountLazy
}
override val typeArguments: List<PsiType>
get() = sourcePsi.classReference?.typeParameters?.toList() ?: emptyList()

View File

@@ -1,31 +1,19 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java
import com.intellij.psi.PsiParenthesizedExpression
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.UParenthesizedExpression
import org.jetbrains.uast.*
@ApiStatus.Internal
class JavaUParenthesizedExpression(
override val sourcePsi: PsiParenthesizedExpression,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UParenthesizedExpression {
override val expression: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.expression, this) }
private val expressionPart = UastLazyPart<UExpression>()
override val expression: UExpression
get() = expressionPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.expression, this) }
override fun evaluate(): Any? = expression.evaluate()
}

View File

@@ -1,26 +1,9 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java
import com.intellij.psi.PsiPolyadicExpression
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.UPolyadicExpression
import org.jetbrains.uast.UastBinaryOperator
import org.jetbrains.uast.*
import org.jetbrains.uast.java.internal.PsiArrayToUElementListMappingView
@ApiStatus.Internal
@@ -28,8 +11,12 @@ class JavaUPolyadicExpression(
override val sourcePsi: PsiPolyadicExpression,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UPolyadicExpression {
private val operatorPart = UastLazyPart<UastBinaryOperator>()
override val operands: List<UExpression> = PsiArrayToUElementListMappingView(sourcePsi.operands) { JavaConverter.convertOrEmpty(it, this) }
override val operands: List<UExpression> = PsiArrayToUElementListMappingView(sourcePsi.operands) {
JavaConverter.convertOrEmpty(it, this)
}
override val operator: UastBinaryOperator by lazyUnsafe { sourcePsi.operationTokenType.getOperatorType() }
override val operator: UastBinaryOperator
get() = operatorPart.getOrBuild { sourcePsi.operationTokenType.getOperatorType() }
}

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java
import com.intellij.psi.JavaTokenType
@@ -11,7 +11,10 @@ class JavaUPostfixExpression(
override val sourcePsi: PsiPostfixExpression,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UPostfixExpression {
override val operand: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.operand, this) }
private val operandPart = UastLazyPart<UExpression>()
override val operand: UExpression
get() = operandPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.operand, this) }
override val operatorIdentifier: UIdentifier
get() = UIdentifier(sourcePsi.operationSign, this)

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java
import com.intellij.psi.JavaTokenType
@@ -11,7 +11,10 @@ class JavaUPrefixExpression(
override val sourcePsi: PsiPrefixExpression,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UPrefixExpression {
override val operand: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.operand, this) }
private val operandPart = UastLazyPart<UExpression>()
override val operand: UExpression
get() = operandPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.operand, this) }
override val operatorIdentifier: UIdentifier
get() = UIdentifier(sourcePsi.operationSign, this)

View File

@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java
import com.intellij.psi.PsiElement
@@ -27,13 +13,20 @@ class JavaUQualifiedReferenceExpression(
override val sourcePsi: PsiJavaCodeReferenceElement,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UQualifiedReferenceExpression, UMultiResolvable {
override val receiver: UExpression by lazyUnsafe {
sourcePsi.qualifier?.let { JavaConverter.convertPsiElement(it, this, UElement::class.java) as? UExpression } ?: UastEmptyExpression(this)
}
private val receiverPart = UastLazyPart<UExpression>()
private val selectorPart = UastLazyPart<USimpleNameReferenceExpression>()
override val selector: USimpleNameReferenceExpression by lazyUnsafe {
JavaUSimpleNameReferenceExpression(sourcePsi.referenceNameElement, sourcePsi.referenceName ?: "<error>", this, sourcePsi)
}
override val receiver: UExpression
get() = receiverPart.getOrBuild {
sourcePsi.qualifier
?.let { JavaConverter.convertPsiElement(it, this, UElement::class.java) as? UExpression }
?: UastEmptyExpression(this)
}
override val selector: USimpleNameReferenceExpression
get() = selectorPart.getOrBuild {
JavaUSimpleNameReferenceExpression(sourcePsi.referenceNameElement, sourcePsi.referenceName ?: "<error>", this, sourcePsi)
}
override val accessType: UastQualifiedExpressionAccessType
get() = UastQualifiedExpressionAccessType.SIMPLE
@@ -44,7 +37,6 @@ class JavaUQualifiedReferenceExpression(
override fun resolve(): PsiElement? = sourcePsi.resolve()
override fun multiResolve(): Iterable<ResolveResult> = sourcePsi.multiResolve(false).asIterable()
}
internal fun UElement.unwrapCompositeQualifiedReference(uParent: UElement?): UElement? = when (uParent) {

View File

@@ -1,34 +1,21 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java
import com.intellij.psi.PsiReturnStatement
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.UReturnExpression
import org.jetbrains.uast.*
@ApiStatus.Internal
class JavaUReturnExpression(
override val sourcePsi: PsiReturnStatement,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UReturnExpression {
private val returnExpressionPart = UastLazyPart<UExpression?>()
override val label: String?
get() = null
override val returnExpression: UExpression? by lazyUnsafe { JavaConverter.convertOrNull(sourcePsi.returnValue, this) }
override val returnExpression: UExpression?
get() = returnExpressionPart.getOrBuild { JavaConverter.convertOrNull(sourcePsi.returnValue, this) }
}

View File

@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java
import com.intellij.psi.*
@@ -42,7 +28,7 @@ class JavaUSimpleNameReferenceExpression(
if (parent is PsiReferenceExpression && parent.parent is PsiMethodCallExpression) {
return parent.parent
}
else if (parent is PsiAnonymousClass){
else if (parent is PsiAnonymousClass) {
return parent.parent
}
return parent
@@ -74,5 +60,8 @@ class LazyJavaUTypeReferenceExpression(
givenParent: UElement?,
private val typeSupplier: () -> PsiType
) : JavaAbstractUExpression(givenParent), UTypeReferenceExpression {
override val type: PsiType by lazyUnsafe { typeSupplier() }
private val typePart = UastLazyPart<PsiType>()
override val type: PsiType
get() = typePart.getOrBuild(typeSupplier)
}

View File

@@ -1,30 +1,13 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java.expressions
import com.intellij.psi.PsiSynchronizedStatement
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.uast.UBlockExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.*
import org.jetbrains.uast.internal.acceptList
import org.jetbrains.uast.java.JavaAbstractUExpression
import org.jetbrains.uast.java.JavaConverter
import org.jetbrains.uast.java.lazyUnsafe
import org.jetbrains.uast.visitor.UastVisitor
@ApiStatus.Internal
@@ -32,11 +15,16 @@ class JavaUSynchronizedExpression(
override val sourcePsi: PsiSynchronizedStatement,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UBlockExpression {
override val expressions: List<UExpression> by lazyUnsafe {
sourcePsi.body?.statements?.map { JavaConverter.convertOrEmpty(it, this) } ?: listOf()
}
private val expressionsPart = UastLazyPart<List<UExpression>>()
private val lockExpressionPart = UastLazyPart<UExpression>()
private val lockExpression: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.lockExpression, this) }
override val expressions: List<UExpression>
get() = expressionsPart.getOrBuild {
sourcePsi.body?.statements?.map { JavaConverter.convertOrEmpty(it, this) } ?: listOf()
}
private val lockExpression: UExpression
get() = lockExpressionPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.lockExpression, this) }
override fun accept(visitor: UastVisitor) {
if (visitor.visitBlockExpression(this)) return

View File

@@ -1,31 +1,18 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java
import com.intellij.psi.PsiThrowStatement
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.UThrowExpression
import org.jetbrains.uast.*
@ApiStatus.Internal
class JavaUThrowExpression(
override val sourcePsi: PsiThrowStatement,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UThrowExpression {
override val thrownExpression: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.exception, this) }
private val thrownExpressionPart = UastLazyPart<UExpression>()
override val thrownExpression: UExpression
get() = thrownExpressionPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.exception, this) }
}

View File

@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java
import com.intellij.psi.PsiType
@@ -25,12 +11,17 @@ class JavaUTypeCastExpression(
override val sourcePsi: PsiTypeCastExpression,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UBinaryExpressionWithType {
override val operand: UExpression by lazyUnsafe { JavaConverter.convertOrEmpty(sourcePsi.operand, this) }
private val operandPart = UastLazyPart<UExpression>()
private val typeReferencePart = UastLazyPart<UTypeReferenceExpression?>()
override val operand: UExpression
get() = operandPart.getOrBuild { JavaConverter.convertOrEmpty(sourcePsi.operand, this) }
override val type: PsiType
get() = sourcePsi.castType?.type ?: UastErrorType
override val typeReference: UTypeReferenceExpression? by lazyUnsafe { sourcePsi.castType?.let { JavaUTypeReferenceExpression(it, this) } }
override val typeReference: UTypeReferenceExpression?
get() = typeReferencePart.getOrBuild { sourcePsi.castType?.let { JavaUTypeReferenceExpression(it, this) } }
override val operationKind: UastBinaryExpressionWithTypeKind
get() = UastBinaryExpressionWithTypeKind.TypeCast.INSTANCE

View File

@@ -1,25 +1,30 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.uast.java
import com.intellij.psi.PsiYieldStatement
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.UYieldExpression
import org.jetbrains.uast.*
@ApiStatus.Internal
class JavaUYieldExpression(
override val sourcePsi: PsiYieldStatement,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UYieldExpression {
override val expression: UExpression? by lazyUnsafe {
JavaConverter.convertOrEmpty(sourcePsi.expression, this)
}
private val expressionPart = UastLazyPart<UExpression?>()
private val jumpTargetPart = UastLazyPart<UElement?>()
override val expression: UExpression?
get() = expressionPart.getOrBuild {
JavaConverter.convertOrEmpty(sourcePsi.expression, this)
}
override val label: String?
get() = null
override val jumpTarget: UElement? by lazyUnsafe {
sourcePsi.findEnclosingExpression().takeIf { sourcePsi !== it }?.let { JavaConverter.convertExpression(it, null, UExpression::class.java) }
}
override val jumpTarget: UElement?
get() = jumpTargetPart.getOrBuild {
sourcePsi.findEnclosingExpression().takeIf { sourcePsi !== it }?.let {
JavaConverter.convertExpression(it, null, UExpression::class.java)
}
}
}

View File

@@ -29,6 +29,11 @@ class JavaUCallExpression(
override val sourcePsi: PsiMethodCallExpression,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UCallExpression, UElementWithLocation, UMultiResolvable {
private val valueArgumentsPart = UastLazyPart<List<UExpression>>()
private val methodIdentifierPart = UastLazyPart<UIdentifier?>()
private var typeArgumentCountLazy = Int.MIN_VALUE
override val kind: UastCallKind
get() {
val element = nameReferenceElement
@@ -38,9 +43,10 @@ class JavaUCallExpression(
return UastCallKind.METHOD_CALL
}
override val methodIdentifier: UIdentifier? by lazyUnsafe {
nameReferenceElement?.let { UIdentifier(it, this) }
}
override val methodIdentifier: UIdentifier?
get() = methodIdentifierPart.getOrBuild {
nameReferenceElement?.let { UIdentifier(it, this) }
}
private val nameReferenceElement: PsiElement?
get() = sourcePsi.methodExpression.referenceNameElement
@@ -51,9 +57,10 @@ class JavaUCallExpression(
override val valueArgumentCount: Int
get() = sourcePsi.argumentList.expressionCount
override val valueArguments: List<UExpression> by lazyUnsafe {
PsiArrayToUElementListMappingView(sourcePsi.argumentList.expressions) { JavaConverter.convertOrEmpty(it, this@JavaUCallExpression) }
}
override val valueArguments: List<UExpression>
get() = valueArgumentsPart.getOrBuild {
PsiArrayToUElementListMappingView(sourcePsi.argumentList.expressions) { JavaConverter.convertOrEmpty(it, this@JavaUCallExpression) }
}
override fun getArgumentForParameter(i: Int): UExpression? {
val resolved = multiResolve().mapNotNull { it.element as? PsiMethod }
@@ -69,7 +76,14 @@ class JavaUCallExpression(
return null
}
override val typeArgumentCount: Int by lazyUnsafe { sourcePsi.typeArguments.size }
override val typeArgumentCount: Int
get() {
if (typeArgumentCountLazy == Int.MIN_VALUE) {
typeArgumentCountLazy = sourcePsi.typeArguments.size
}
return typeArgumentCountLazy
}
override val typeArguments: List<PsiType>
get() = sourcePsi.typeArguments.toList()
@@ -134,13 +148,25 @@ class JavaConstructorUCallExpression(
override val sourcePsi: PsiNewExpression,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UCallExpression, UMultiResolvable {
override val kind: UastCallKind by lazyUnsafe {
when {
sourcePsi.arrayInitializer != null -> UastCallKind.NEW_ARRAY_WITH_INITIALIZER
sourcePsi.arrayDimensions.isNotEmpty() -> UastCallKind.NEW_ARRAY_WITH_DIMENSIONS
else -> UastCallKind.CONSTRUCTOR_CALL
private val classReferencePart = UastLazyPart<UReferenceExpression?>()
private val valueArgumentsPart = UastLazyPart<List<UExpression>>()
private var kindLazy: UastCallKind? = null
private var typeArgumentCountLazy = Int.MIN_VALUE
override val kind: UastCallKind
get() {
if (kindLazy == null) {
kindLazy = when {
sourcePsi.arrayInitializer != null -> UastCallKind.NEW_ARRAY_WITH_INITIALIZER
sourcePsi.arrayDimensions.isNotEmpty() -> UastCallKind.NEW_ARRAY_WITH_DIMENSIONS
else -> UastCallKind.CONSTRUCTOR_CALL
}
}
return kindLazy!!
}
}
override val receiver: UExpression?
get() = null
@@ -151,11 +177,12 @@ class JavaConstructorUCallExpression(
override val methodIdentifier: UIdentifier?
get() = null
override val classReference: UReferenceExpression? by lazyUnsafe {
sourcePsi.classReference?.let { ref ->
JavaConverter.convertReference(ref, this, UElement::class.java) as? UReferenceExpression
override val classReference: UReferenceExpression?
get() = classReferencePart.getOrBuild {
sourcePsi.classReference?.let { ref ->
JavaConverter.convertReference(ref, this, UElement::class.java) as? UReferenceExpression
}
}
}
override val valueArgumentCount: Int
get() {
@@ -167,18 +194,26 @@ class JavaConstructorUCallExpression(
}
}
override val valueArguments: List<UExpression> by lazyUnsafe {
val initializer = sourcePsi.arrayInitializer
when {
initializer != null -> initializer.initializers.map { JavaConverter.convertOrEmpty(it, this) }
sourcePsi.arrayDimensions.isNotEmpty() -> sourcePsi.arrayDimensions.map { JavaConverter.convertOrEmpty(it, this) }
else -> sourcePsi.argumentList?.expressions?.map { JavaConverter.convertOrEmpty(it, this) } ?: emptyList()
override val valueArguments: List<UExpression>
get() = valueArgumentsPart.getOrBuild {
val initializer = sourcePsi.arrayInitializer
when {
initializer != null -> initializer.initializers.map { JavaConverter.convertOrEmpty(it, this) }
sourcePsi.arrayDimensions.isNotEmpty() -> sourcePsi.arrayDimensions.map { JavaConverter.convertOrEmpty(it, this) }
else -> sourcePsi.argumentList?.expressions?.map { JavaConverter.convertOrEmpty(it, this) } ?: emptyList()
}
}
}
override fun getArgumentForParameter(i: Int): UExpression? = valueArguments.getOrNull(i)
override val typeArgumentCount: Int by lazyUnsafe { sourcePsi.classReference?.typeParameters?.size ?: 0 }
override val typeArgumentCount: Int
get() {
if (typeArgumentCountLazy == Int.MIN_VALUE) {
typeArgumentCountLazy = sourcePsi.classReference?.typeParameters?.size ?: 0
}
return typeArgumentCountLazy
}
override val typeArguments: List<PsiType>
get() = sourcePsi.classReference?.typeParameters?.toList() ?: emptyList()
@@ -207,6 +242,9 @@ class JavaArrayInitializerUCallExpression(
override val sourcePsi: PsiArrayInitializerExpression,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UCallExpression, UMultiResolvable {
private var valueArgumentCountLazy = Int.MIN_VALUE
private val valueArgumentsPart = UastLazyPart<List<UExpression>>()
override val methodIdentifier: UIdentifier?
get() = null
@@ -216,8 +254,17 @@ class JavaArrayInitializerUCallExpression(
override val methodName: String?
get() = null
override val valueArgumentCount: Int by lazyUnsafe { sourcePsi.initializers.size }
override val valueArguments: List<UExpression> by lazyUnsafe { sourcePsi.initializers.map { JavaConverter.convertOrEmpty(it, this) } }
override val valueArgumentCount: Int
get() {
if (valueArgumentCountLazy == Int.MIN_VALUE) {
valueArgumentCountLazy = sourcePsi.initializers.size
}
return valueArgumentCountLazy
}
override val valueArguments: List<UExpression>
get() = valueArgumentsPart.getOrBuild { sourcePsi.initializers.map { JavaConverter.convertOrEmpty(it, this) } }
override fun getArgumentForParameter(i: Int): UExpression? = valueArguments.getOrNull(i)
@@ -248,6 +295,7 @@ class JavaAnnotationArrayInitializerUCallExpression(
override val sourcePsi: PsiArrayInitializerMemberValue,
givenParent: UElement?
) : JavaAbstractUExpression(givenParent), UCallExpression, UMultiResolvable {
private val valueArgumentsPart = UastLazyPart<List<UExpression>>()
override fun getArgumentForParameter(i: Int): UExpression? = valueArguments.getOrNull(i)
@@ -263,13 +311,22 @@ class JavaAnnotationArrayInitializerUCallExpression(
override val methodName: String?
get() = null
override val valueArgumentCount: Int by lazyUnsafe { sourcePsi.initializers.size }
private var valueArgumentCountLazy = Int.MIN_VALUE
override val valueArguments: List<UExpression> by lazyUnsafe {
sourcePsi.initializers.map {
JavaConverter.convertPsiElement(it, this, UElement::class.java) as? UExpression ?: UnknownJavaExpression(it, this)
override val valueArgumentCount: Int
get() {
if (valueArgumentCountLazy == Int.MIN_VALUE) {
valueArgumentCountLazy = sourcePsi.initializers.size
}
return valueArgumentCountLazy
}
override val valueArguments: List<UExpression>
get() = valueArgumentsPart.getOrBuild {
sourcePsi.initializers.map {
JavaConverter.convertPsiElement(it, this, UElement::class.java) as? UExpression ?: UnknownJavaExpression(it, this)
}
}
}
override val typeArgumentCount: Int
get() = 0

View File

@@ -87,8 +87,6 @@ fun isJava(language: Language?): Boolean {
return language == JavaLanguage.INSTANCE
}
internal fun <T> lazyUnsafe(initializer: () -> T): Lazy<T> = lazy(LazyThreadSafetyMode.NONE, initializer)
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
internal inline fun <reified T : Any> Any?.asSafely(): @kotlin.internal.NoInfer T? = this as? T