FIR/UAST: commonize binary expression with type
This commit is contained in:
committed by
teamcityserver
parent
b2e644b485
commit
9a539aac7d
+37
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.uast.kotlin
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
|
import org.jetbrains.kotlin.psi.KtBinaryExpressionWithTypeRHS
|
||||||
|
import org.jetbrains.uast.*
|
||||||
|
|
||||||
|
class KotlinUBinaryExpressionWithType(
|
||||||
|
override val sourcePsi: KtBinaryExpressionWithTypeRHS,
|
||||||
|
givenParent: UElement?
|
||||||
|
) : KotlinAbstractUExpression(givenParent), UBinaryExpressionWithType, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||||
|
override val operand by lz {
|
||||||
|
baseResolveProviderService.baseKotlinConverter.convertOrEmpty(sourcePsi.left, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val type by lz {
|
||||||
|
sourcePsi.right?.let {
|
||||||
|
baseResolveProviderService.resolveToType(it, this)
|
||||||
|
} ?: UastErrorType
|
||||||
|
}
|
||||||
|
|
||||||
|
override val typeReference by lz {
|
||||||
|
sourcePsi.right?.let {
|
||||||
|
KotlinUTypeReferenceExpression(it, this) { type }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val operationKind = when (sourcePsi.operationReference.getReferencedNameElementType()) {
|
||||||
|
KtTokens.AS_KEYWORD -> UastBinaryExpressionWithTypeKind.TYPE_CAST
|
||||||
|
KtTokens.AS_SAFE -> KotlinBinaryExpressionWithTypeKinds.SAFE_TYPE_CAST
|
||||||
|
else -> UastBinaryExpressionWithTypeKind.UNKNOWN
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -291,6 +291,7 @@ internal object FirKotlinConverter : BaseKotlinConverter {
|
|||||||
|
|
||||||
is KtIfExpression -> expr<UIfExpression>(build(::KotlinUIfExpression))
|
is KtIfExpression -> expr<UIfExpression>(build(::KotlinUIfExpression))
|
||||||
|
|
||||||
|
is KtBinaryExpressionWithTypeRHS -> expr<UBinaryExpressionWithType>(build(::KotlinUBinaryExpressionWithType))
|
||||||
is KtIsExpression -> expr<UBinaryExpressionWithType>(build(::KotlinUTypeCheckExpression))
|
is KtIsExpression -> expr<UBinaryExpressionWithType>(build(::KotlinUTypeCheckExpression))
|
||||||
|
|
||||||
else -> expr<UExpression>(build(::UnknownKotlinExpression))
|
else -> expr<UExpression>(build(::UnknownKotlinExpression))
|
||||||
|
|||||||
+3
-1
@@ -1,7 +1,9 @@
|
|||||||
UFile (package = )
|
UFile (package = )
|
||||||
UClass (name = CycleInTypeParametersKt)
|
UClass (name = CycleInTypeParametersKt)
|
||||||
UField (name = a)
|
UField (name = a)
|
||||||
[!] UnknownKotlinExpression (BINARY_WITH_TYPE)
|
UBinaryExpressionWithType
|
||||||
|
ULiteralExpression (value = "not-yet-compile-time-constant")
|
||||||
|
UTypeReferenceExpression (name = Device<?>)
|
||||||
UMethod (name = getA)
|
UMethod (name = getA)
|
||||||
UClass (name = Device)
|
UClass (name = Device)
|
||||||
UMethod (name = Device)
|
UMethod (name = Device)
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
public final class CycleInTypeParametersKt {
|
public final class CycleInTypeParametersKt {
|
||||||
private static final var a: Device<?> = [!] UnknownKotlinExpression (BINARY_WITH_TYPE)
|
private static final var a: Device<?> = "not-yet-compile-time-constant" as? Device<?>
|
||||||
public static final fun getA() : Device<?> = UastEmptyExpression
|
public static final fun getA() : Device<?> = UastEmptyExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-2
@@ -1,7 +1,9 @@
|
|||||||
UFile (package = ) [public final class CycleInTypeParametersKt {...]
|
UFile (package = ) [public final class CycleInTypeParametersKt {...]
|
||||||
UClass (name = CycleInTypeParametersKt) [public final class CycleInTypeParametersKt {...}]
|
UClass (name = CycleInTypeParametersKt) [public final class CycleInTypeParametersKt {...}]
|
||||||
UField (name = a) [private static final var a: Device<?> = [!] UnknownKotlinExpression (BINARY_WITH_TYPE)]
|
UField (name = a) [private static final var a: Device<?> = "not-yet-compile-time-constant" as? Device<?>]
|
||||||
[!] UnknownKotlinExpression (BINARY_WITH_TYPE) [[!] UnknownKotlinExpression (BINARY_WITH_TYPE)]
|
UBinaryExpressionWithType ["not-yet-compile-time-constant" as? Device<?>] : PsiType:Device<?>
|
||||||
|
ULiteralExpression (value = "not-yet-compile-time-constant") ["not-yet-compile-time-constant"] : PsiType:Void
|
||||||
|
UTypeReferenceExpression (name = Device<?>) [Device<?>]
|
||||||
UMethod (name = getA) [public static final fun getA() : Device<?> = UastEmptyExpression]
|
UMethod (name = getA) [public static final fun getA() : Device<?> = UastEmptyExpression]
|
||||||
UClass (name = Device) [public final class Device {...}]
|
UClass (name = Device) [public final class Device {...}]
|
||||||
UMethod (name = Device) [public fun Device() = UastEmptyExpression]
|
UMethod (name = Device) [public fun Device() = UastEmptyExpression]
|
||||||
|
|||||||
+4
-2
@@ -1,7 +1,9 @@
|
|||||||
UFile (package = ) [public final class CycleInTypeParametersKt {...]
|
UFile (package = ) [public final class CycleInTypeParametersKt {...]
|
||||||
UClass (name = CycleInTypeParametersKt) [public final class CycleInTypeParametersKt {...}]
|
UClass (name = CycleInTypeParametersKt) [public final class CycleInTypeParametersKt {...}]
|
||||||
UField (name = a) [private static final var a: Device<?> = [!] UnknownKotlinExpression (BINARY_WITH_TYPE)]
|
UField (name = a) [private static final var a: Device<?> = "not-yet-compile-time-constant" as? Device<?>]
|
||||||
[!] UnknownKotlinExpression (BINARY_WITH_TYPE) [[!] UnknownKotlinExpression (BINARY_WITH_TYPE)] = Undetermined
|
UBinaryExpressionWithType ["not-yet-compile-time-constant" as? Device<?>] = Undetermined
|
||||||
|
ULiteralExpression (value = "not-yet-compile-time-constant") ["not-yet-compile-time-constant"] = "not-yet-compile-time-constant"
|
||||||
|
UTypeReferenceExpression (name = Device<?>) [Device<?>] = Undetermined
|
||||||
UMethod (name = getA) [public static final fun getA() : Device<?> = UastEmptyExpression]
|
UMethod (name = getA) [public static final fun getA() : Device<?> = UastEmptyExpression]
|
||||||
UClass (name = Device) [public final class Device {...}]
|
UClass (name = Device) [public final class Device {...}]
|
||||||
UMethod (name = Device) [public fun Device() = UastEmptyExpression]
|
UMethod (name = Device) [public fun Device() = UastEmptyExpression]
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import java.lang.Runnable
|
||||||
|
|
||||||
|
fun stringConsumer(s: String) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo(x: Any, isSafe: Boolean) =
|
||||||
|
if (isSafe) x as Runnable else x as? Runnable
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
// Unit as Any
|
||||||
|
val x = stringConsumer("Hi") as Any
|
||||||
|
if (x != Unit) return "Fail: $x"
|
||||||
|
|
||||||
|
// Unit as? Any
|
||||||
|
val y = stringConsumer("Hi, again") as Any
|
||||||
|
if (y != Unit) return "Fail: $y"
|
||||||
|
|
||||||
|
val r = object : Runnable {
|
||||||
|
override fun run() {}
|
||||||
|
}
|
||||||
|
if (foo(r, true) !=== r) return "Fail: $r"
|
||||||
|
if (foo(r, false) !=== r) return "Fail: $r"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
UFile (package = ) [import java.lang.Runnable...]
|
||||||
|
UImportStatement (isOnDemand = false) [import java.lang.Runnable]
|
||||||
|
UClass (name = TypeCastKt) [public final class TypeCastKt {...}]
|
||||||
|
UMethod (name = stringConsumer) [public static final fun stringConsumer(@org.jetbrains.annotations.NotNull s: java.lang.String) : void {...}]
|
||||||
|
UParameter (name = s) [@org.jetbrains.annotations.NotNull var s: java.lang.String]
|
||||||
|
UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull]
|
||||||
|
UBlockExpression [{...}] : PsiType:void
|
||||||
|
UMethod (name = foo) [public static final fun foo(@org.jetbrains.annotations.NotNull x: java.lang.Object, @org.jetbrains.annotations.NotNull isSafe: boolean) : java.lang.Runnable {...}]
|
||||||
|
UParameter (name = x) [@org.jetbrains.annotations.NotNull var x: java.lang.Object]
|
||||||
|
UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull]
|
||||||
|
UParameter (name = isSafe) [@org.jetbrains.annotations.NotNull var isSafe: boolean]
|
||||||
|
UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull]
|
||||||
|
UBlockExpression [{...}]
|
||||||
|
UReturnExpression [return if (isSafe) x as java.lang.Runnable else x as? java.lang.Runnable]
|
||||||
|
UIfExpression [if (isSafe) x as java.lang.Runnable else x as? java.lang.Runnable] : PsiType:Runnable
|
||||||
|
USimpleNameReferenceExpression (identifier = isSafe) [isSafe] : PsiType:boolean
|
||||||
|
UBinaryExpressionWithType [x as java.lang.Runnable] : PsiType:Runnable
|
||||||
|
USimpleNameReferenceExpression (identifier = x) [x] : PsiType:Object
|
||||||
|
UTypeReferenceExpression (name = java.lang.Runnable) [java.lang.Runnable]
|
||||||
|
UBinaryExpressionWithType [x as? java.lang.Runnable] : PsiType:Runnable
|
||||||
|
USimpleNameReferenceExpression (identifier = x) [x] : PsiType:Object
|
||||||
|
UTypeReferenceExpression (name = java.lang.Runnable) [java.lang.Runnable]
|
||||||
|
UMethod (name = box) [public static final fun box() : java.lang.String {...}]
|
||||||
|
UBlockExpression [{...}] : PsiType:Void
|
||||||
|
UDeclarationsExpression [var x: java.lang.Object = stringConsumer("Hi") as java.lang.Object]
|
||||||
|
ULocalVariable (name = x) [var x: java.lang.Object = stringConsumer("Hi") as java.lang.Object]
|
||||||
|
UBinaryExpressionWithType [stringConsumer("Hi") as java.lang.Object] : PsiType:Object
|
||||||
|
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [stringConsumer("Hi")] : PsiType:void
|
||||||
|
UIdentifier (Identifier (stringConsumer)) [UIdentifier (Identifier (stringConsumer))]
|
||||||
|
USimpleNameReferenceExpression (identifier = stringConsumer, resolvesTo = null) [stringConsumer] : PsiType:void
|
||||||
|
ULiteralExpression (value = "Hi") ["Hi"] : PsiType:String
|
||||||
|
UTypeReferenceExpression (name = java.lang.Object) [java.lang.Object]
|
||||||
|
UIfExpression [if (x != Unit) return "Fail: " + x] : PsiType:void
|
||||||
|
UBinaryExpression (operator = !=) [x != Unit] : PsiType:boolean
|
||||||
|
USimpleNameReferenceExpression (identifier = x) [x] : PsiType:Object
|
||||||
|
USimpleNameReferenceExpression (identifier = Unit) [Unit] : PsiType:void
|
||||||
|
UReturnExpression [return "Fail: " + x] : PsiType:Void
|
||||||
|
UPolyadicExpression (operator = +) ["Fail: " + x] : PsiType:String
|
||||||
|
ULiteralExpression (value = "Fail: ") ["Fail: "] : PsiType:String
|
||||||
|
USimpleNameReferenceExpression (identifier = x) [x] : PsiType:Object
|
||||||
|
UDeclarationsExpression [var y: java.lang.Object = stringConsumer("Hi, again") as java.lang.Object]
|
||||||
|
ULocalVariable (name = y) [var y: java.lang.Object = stringConsumer("Hi, again") as java.lang.Object]
|
||||||
|
UBinaryExpressionWithType [stringConsumer("Hi, again") as java.lang.Object] : PsiType:Object
|
||||||
|
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [stringConsumer("Hi, again")] : PsiType:void
|
||||||
|
UIdentifier (Identifier (stringConsumer)) [UIdentifier (Identifier (stringConsumer))]
|
||||||
|
USimpleNameReferenceExpression (identifier = stringConsumer, resolvesTo = null) [stringConsumer] : PsiType:void
|
||||||
|
ULiteralExpression (value = "Hi, again") ["Hi, again"] : PsiType:String
|
||||||
|
UTypeReferenceExpression (name = java.lang.Object) [java.lang.Object]
|
||||||
|
UIfExpression [if (y != Unit) return "Fail: " + y] : PsiType:void
|
||||||
|
UBinaryExpression (operator = !=) [y != Unit] : PsiType:boolean
|
||||||
|
USimpleNameReferenceExpression (identifier = y) [y] : PsiType:Object
|
||||||
|
USimpleNameReferenceExpression (identifier = Unit) [Unit] : PsiType:void
|
||||||
|
UReturnExpression [return "Fail: " + y] : PsiType:Void
|
||||||
|
UPolyadicExpression (operator = +) ["Fail: " + y] : PsiType:String
|
||||||
|
ULiteralExpression (value = "Fail: ") ["Fail: "] : PsiType:String
|
||||||
|
USimpleNameReferenceExpression (identifier = y) [y] : PsiType:Object
|
||||||
|
UDeclarationsExpression [var r: <ErrorType> = anonymous object : Runnable {... }]
|
||||||
|
ULocalVariable (name = r) [var r: <ErrorType> = anonymous object : Runnable {... }]
|
||||||
|
UObjectLiteralExpression [anonymous object : Runnable {... }] : PsiType:Runnable
|
||||||
|
UClass (name = null) [final class null : java.lang.Runnable {...}]
|
||||||
|
UMethod (name = run) [public fun run() : void {...}]
|
||||||
|
UBlockExpression [{...}] : PsiType:void
|
||||||
|
UMethod (name = ) [private fun () = UastEmptyExpression]
|
||||||
|
UIfExpression [if (foo(r, true) !== UastEmptyExpression <other> UastEmptyExpression) return "Fail: " + r] : PsiType:void
|
||||||
|
UBinaryExpression (operator = !==) [foo(r, true) !== UastEmptyExpression <other> UastEmptyExpression] : PsiType:boolean
|
||||||
|
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) [foo(r, true)] : PsiType:Runnable
|
||||||
|
UIdentifier (Identifier (foo)) [UIdentifier (Identifier (foo))]
|
||||||
|
USimpleNameReferenceExpression (identifier = foo, resolvesTo = null) [foo] : PsiType:Runnable
|
||||||
|
USimpleNameReferenceExpression (identifier = r) [r] : PsiType:<ErrorType>
|
||||||
|
ULiteralExpression (value = true) [true] : PsiType:boolean
|
||||||
|
UBinaryExpression (operator = <other>) [UastEmptyExpression <other> UastEmptyExpression]
|
||||||
|
UastEmptyExpression [UastEmptyExpression]
|
||||||
|
UastEmptyExpression [UastEmptyExpression]
|
||||||
|
UReturnExpression [return "Fail: " + r] : PsiType:Void
|
||||||
|
UPolyadicExpression (operator = +) ["Fail: " + r] : PsiType:String
|
||||||
|
ULiteralExpression (value = "Fail: ") ["Fail: "] : PsiType:String
|
||||||
|
USimpleNameReferenceExpression (identifier = r) [r] : PsiType:<ErrorType>
|
||||||
|
UIfExpression [if (foo(r, false) !== UastEmptyExpression <other> UastEmptyExpression) return "Fail: " + r] : PsiType:void
|
||||||
|
UBinaryExpression (operator = !==) [foo(r, false) !== UastEmptyExpression <other> UastEmptyExpression] : PsiType:boolean
|
||||||
|
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 2)) [foo(r, false)] : PsiType:Runnable
|
||||||
|
UIdentifier (Identifier (foo)) [UIdentifier (Identifier (foo))]
|
||||||
|
USimpleNameReferenceExpression (identifier = foo, resolvesTo = null) [foo] : PsiType:Runnable
|
||||||
|
USimpleNameReferenceExpression (identifier = r) [r] : PsiType:<ErrorType>
|
||||||
|
ULiteralExpression (value = false) [false] : PsiType:boolean
|
||||||
|
UBinaryExpression (operator = <other>) [UastEmptyExpression <other> UastEmptyExpression]
|
||||||
|
UastEmptyExpression [UastEmptyExpression]
|
||||||
|
UastEmptyExpression [UastEmptyExpression]
|
||||||
|
UReturnExpression [return "Fail: " + r] : PsiType:Void
|
||||||
|
UPolyadicExpression (operator = +) ["Fail: " + r] : PsiType:String
|
||||||
|
ULiteralExpression (value = "Fail: ") ["Fail: "] : PsiType:String
|
||||||
|
USimpleNameReferenceExpression (identifier = r) [r] : PsiType:<ErrorType>
|
||||||
|
UReturnExpression [return "OK"] : PsiType:Void
|
||||||
|
ULiteralExpression (value = "OK") ["OK"] : PsiType:String
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
UFile (package = ) [import java.lang.Runnable...]
|
||||||
|
UImportStatement (isOnDemand = false) [import java.lang.Runnable]
|
||||||
|
UClass (name = TypeCastKt) [public final class TypeCastKt {...}]
|
||||||
|
UMethod (name = stringConsumer) [public static final fun stringConsumer(s: java.lang.String) : void {...}]
|
||||||
|
UParameter (name = s) [var s: java.lang.String]
|
||||||
|
UBlockExpression [{...}] : PsiType:Unit
|
||||||
|
UMethod (name = foo) [public static final fun foo(x: java.lang.Object, isSafe: boolean) : java.lang.Runnable {...}]
|
||||||
|
UParameter (name = x) [var x: java.lang.Object]
|
||||||
|
UParameter (name = isSafe) [var isSafe: boolean]
|
||||||
|
UBlockExpression [{...}]
|
||||||
|
UReturnExpression [return if ([!] UnknownKotlinExpression (REFERENCE_EXPRESSION)) [!] UnknownKotlinExpression (REFERENCE_EXPRESSION) as java.lang.Runnable else [!] UnknownKotlinExpression (REFERENCE_EXPRESSION) as? java.lang.Runnable]
|
||||||
|
UIfExpression [if ([!] UnknownKotlinExpression (REFERENCE_EXPRESSION)) [!] UnknownKotlinExpression (REFERENCE_EXPRESSION) as java.lang.Runnable else [!] UnknownKotlinExpression (REFERENCE_EXPRESSION) as? java.lang.Runnable] : PsiType:Runnable
|
||||||
|
[!] UnknownKotlinExpression (REFERENCE_EXPRESSION) [[!] UnknownKotlinExpression (REFERENCE_EXPRESSION)]
|
||||||
|
UBinaryExpressionWithType [[!] UnknownKotlinExpression (REFERENCE_EXPRESSION) as java.lang.Runnable] : PsiType:Runnable
|
||||||
|
[!] UnknownKotlinExpression (REFERENCE_EXPRESSION) [[!] UnknownKotlinExpression (REFERENCE_EXPRESSION)]
|
||||||
|
UTypeReferenceExpression (name = java.lang.Runnable) [java.lang.Runnable]
|
||||||
|
UBinaryExpressionWithType [[!] UnknownKotlinExpression (REFERENCE_EXPRESSION) as? java.lang.Runnable] : PsiType:Runnable
|
||||||
|
[!] UnknownKotlinExpression (REFERENCE_EXPRESSION) [[!] UnknownKotlinExpression (REFERENCE_EXPRESSION)]
|
||||||
|
UTypeReferenceExpression (name = java.lang.Runnable) [java.lang.Runnable]
|
||||||
|
UMethod (name = box) [public static final fun box() : java.lang.String {...}]
|
||||||
|
UBlockExpression [{...}] : PsiType:Void
|
||||||
|
[!] UnknownKotlinExpression (PROPERTY) [[!] UnknownKotlinExpression (PROPERTY)]
|
||||||
|
UIfExpression [if ([!] UnknownKotlinExpression (BINARY_EXPRESSION)) return "Fail: " + [!] UnknownKotlinExpression (REFERENCE_EXPRESSION)] : PsiType:Unit
|
||||||
|
[!] UnknownKotlinExpression (BINARY_EXPRESSION) [[!] UnknownKotlinExpression (BINARY_EXPRESSION)]
|
||||||
|
UReturnExpression [return "Fail: " + [!] UnknownKotlinExpression (REFERENCE_EXPRESSION)] : PsiType:Void
|
||||||
|
UPolyadicExpression (operator = +) ["Fail: " + [!] UnknownKotlinExpression (REFERENCE_EXPRESSION)] : PsiType:String
|
||||||
|
ULiteralExpression (value = "Fail: ") ["Fail: "] : PsiType:String
|
||||||
|
[!] UnknownKotlinExpression (REFERENCE_EXPRESSION) [[!] UnknownKotlinExpression (REFERENCE_EXPRESSION)]
|
||||||
|
[!] UnknownKotlinExpression (PROPERTY) [[!] UnknownKotlinExpression (PROPERTY)]
|
||||||
|
UIfExpression [if ([!] UnknownKotlinExpression (BINARY_EXPRESSION)) return "Fail: " + [!] UnknownKotlinExpression (REFERENCE_EXPRESSION)] : PsiType:Unit
|
||||||
|
[!] UnknownKotlinExpression (BINARY_EXPRESSION) [[!] UnknownKotlinExpression (BINARY_EXPRESSION)]
|
||||||
|
UReturnExpression [return "Fail: " + [!] UnknownKotlinExpression (REFERENCE_EXPRESSION)] : PsiType:Void
|
||||||
|
UPolyadicExpression (operator = +) ["Fail: " + [!] UnknownKotlinExpression (REFERENCE_EXPRESSION)] : PsiType:String
|
||||||
|
ULiteralExpression (value = "Fail: ") ["Fail: "] : PsiType:String
|
||||||
|
[!] UnknownKotlinExpression (REFERENCE_EXPRESSION) [[!] UnknownKotlinExpression (REFERENCE_EXPRESSION)]
|
||||||
|
[!] UnknownKotlinExpression (PROPERTY) [[!] UnknownKotlinExpression (PROPERTY)]
|
||||||
|
UIfExpression [if ([!] UnknownKotlinExpression (BINARY_EXPRESSION)) return "Fail: " + [!] UnknownKotlinExpression (REFERENCE_EXPRESSION)] : PsiType:Unit
|
||||||
|
[!] UnknownKotlinExpression (BINARY_EXPRESSION) [[!] UnknownKotlinExpression (BINARY_EXPRESSION)]
|
||||||
|
UReturnExpression [return "Fail: " + [!] UnknownKotlinExpression (REFERENCE_EXPRESSION)] : PsiType:Void
|
||||||
|
UPolyadicExpression (operator = +) ["Fail: " + [!] UnknownKotlinExpression (REFERENCE_EXPRESSION)] : PsiType:String
|
||||||
|
ULiteralExpression (value = "Fail: ") ["Fail: "] : PsiType:String
|
||||||
|
[!] UnknownKotlinExpression (REFERENCE_EXPRESSION) [[!] UnknownKotlinExpression (REFERENCE_EXPRESSION)]
|
||||||
|
UIfExpression [if ([!] UnknownKotlinExpression (BINARY_EXPRESSION)) return "Fail: " + [!] UnknownKotlinExpression (REFERENCE_EXPRESSION)] : PsiType:Unit
|
||||||
|
[!] UnknownKotlinExpression (BINARY_EXPRESSION) [[!] UnknownKotlinExpression (BINARY_EXPRESSION)]
|
||||||
|
UReturnExpression [return "Fail: " + [!] UnknownKotlinExpression (REFERENCE_EXPRESSION)] : PsiType:Void
|
||||||
|
UPolyadicExpression (operator = +) ["Fail: " + [!] UnknownKotlinExpression (REFERENCE_EXPRESSION)] : PsiType:String
|
||||||
|
ULiteralExpression (value = "Fail: ") ["Fail: "] : PsiType:String
|
||||||
|
[!] UnknownKotlinExpression (REFERENCE_EXPRESSION) [[!] UnknownKotlinExpression (REFERENCE_EXPRESSION)]
|
||||||
|
UReturnExpression [return "OK"] : PsiType:Void
|
||||||
|
ULiteralExpression (value = "OK") ["OK"] : PsiType:String
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
fun <T> test1() = null as T
|
||||||
|
|
||||||
|
fun <T> test2(): T {
|
||||||
|
val a : Any? = null
|
||||||
|
return a as T
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T: Any> test3() = null as T
|
||||||
|
|
||||||
|
fun <T> castToString(t: T) {
|
||||||
|
t as String
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
if (test1<Int?>() != null) return "fail: test1"
|
||||||
|
if (test2<Int?>() != null) return "fail: test2"
|
||||||
|
var result3 = "fail"
|
||||||
|
try {
|
||||||
|
test3<Int>()
|
||||||
|
}
|
||||||
|
catch(e: NullPointerException) {
|
||||||
|
result3 = "OK"
|
||||||
|
}
|
||||||
|
if (result3 != "OK") return "fail: test3"
|
||||||
|
|
||||||
|
try {
|
||||||
|
castToString<Any?>(null)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
|
return "Fail"
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
UFile (package = ) [public final class WithGenericKt {...]
|
||||||
|
UClass (name = WithGenericKt) [public final class WithGenericKt {...}]
|
||||||
|
UMethod (name = test1) [public static final fun test1() : T {...}]
|
||||||
|
UBlockExpression [{...}]
|
||||||
|
UReturnExpression [return null as T]
|
||||||
|
UBinaryExpressionWithType [null as T] : PsiType:T
|
||||||
|
ULiteralExpression (value = null) [null] : PsiType:Void
|
||||||
|
UTypeReferenceExpression (name = T) [T]
|
||||||
|
UMethod (name = test2) [public static final fun test2() : T {...}]
|
||||||
|
UBlockExpression [{...}] : PsiType:Void
|
||||||
|
UDeclarationsExpression [var a: java.lang.Object = null]
|
||||||
|
ULocalVariable (name = a) [var a: java.lang.Object = null]
|
||||||
|
ULiteralExpression (value = null) [null] : PsiType:Void
|
||||||
|
UReturnExpression [return a as T] : PsiType:Void
|
||||||
|
UBinaryExpressionWithType [a as T] : PsiType:T
|
||||||
|
USimpleNameReferenceExpression (identifier = a) [a] : PsiType:Object
|
||||||
|
UTypeReferenceExpression (name = T) [T]
|
||||||
|
UMethod (name = test3) [public static final fun test3() : T {...}]
|
||||||
|
UBlockExpression [{...}]
|
||||||
|
UReturnExpression [return null as T]
|
||||||
|
UBinaryExpressionWithType [null as T] : PsiType:T
|
||||||
|
ULiteralExpression (value = null) [null] : PsiType:Void
|
||||||
|
UTypeReferenceExpression (name = T) [T]
|
||||||
|
UMethod (name = castToString) [public static final fun castToString(@org.jetbrains.annotations.Nullable t: T) : void {...}]
|
||||||
|
UParameter (name = t) [@org.jetbrains.annotations.Nullable var t: T]
|
||||||
|
UAnnotation (fqName = org.jetbrains.annotations.Nullable) [@org.jetbrains.annotations.Nullable]
|
||||||
|
UBlockExpression [{...}] : PsiType:String
|
||||||
|
UBinaryExpressionWithType [t as java.lang.String] : PsiType:String
|
||||||
|
USimpleNameReferenceExpression (identifier = t) [t] : PsiType:T
|
||||||
|
UTypeReferenceExpression (name = java.lang.String) [java.lang.String]
|
||||||
|
UMethod (name = box) [public static final fun box() : java.lang.String {...}]
|
||||||
|
UBlockExpression [{...}] : PsiType:Void
|
||||||
|
UIfExpression [if (test1() != null) return "fail: test1"] : PsiType:void
|
||||||
|
UBinaryExpression (operator = !=) [test1() != null] : PsiType:boolean
|
||||||
|
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [test1()] : PsiType:int
|
||||||
|
UIdentifier (Identifier (test1)) [UIdentifier (Identifier (test1))]
|
||||||
|
USimpleNameReferenceExpression (identifier = test1, resolvesTo = null) [test1] : PsiType:int
|
||||||
|
ULiteralExpression (value = null) [null] : PsiType:Void
|
||||||
|
UReturnExpression [return "fail: test1"] : PsiType:Void
|
||||||
|
ULiteralExpression (value = "fail: test1") ["fail: test1"] : PsiType:String
|
||||||
|
UIfExpression [if (test2() != null) return "fail: test2"] : PsiType:void
|
||||||
|
UBinaryExpression (operator = !=) [test2() != null] : PsiType:boolean
|
||||||
|
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [test2()] : PsiType:int
|
||||||
|
UIdentifier (Identifier (test2)) [UIdentifier (Identifier (test2))]
|
||||||
|
USimpleNameReferenceExpression (identifier = test2, resolvesTo = null) [test2] : PsiType:int
|
||||||
|
ULiteralExpression (value = null) [null] : PsiType:Void
|
||||||
|
UReturnExpression [return "fail: test2"] : PsiType:Void
|
||||||
|
ULiteralExpression (value = "fail: test2") ["fail: test2"] : PsiType:String
|
||||||
|
UDeclarationsExpression [var result3: java.lang.String = "fail"]
|
||||||
|
ULocalVariable (name = result3) [var result3: java.lang.String = "fail"]
|
||||||
|
ULiteralExpression (value = "fail") ["fail"] : PsiType:String
|
||||||
|
UTryExpression [try {...] : PsiType:Object
|
||||||
|
UBlockExpression [{...}] : PsiType:int
|
||||||
|
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 0)) [test3()] : PsiType:int
|
||||||
|
UIdentifier (Identifier (test3)) [UIdentifier (Identifier (test3))]
|
||||||
|
USimpleNameReferenceExpression (identifier = test3, resolvesTo = null) [test3] : PsiType:int
|
||||||
|
UCatchClause (e) [catch (@org.jetbrains.annotations.NotNull var e: java.lang.NullPointerException) {...}]
|
||||||
|
UParameter (name = e) [@org.jetbrains.annotations.NotNull var e: java.lang.NullPointerException]
|
||||||
|
UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull]
|
||||||
|
UBlockExpression [{...}] : PsiType:void
|
||||||
|
UBinaryExpression (operator = =) [result3 = "OK"] : PsiType:void
|
||||||
|
USimpleNameReferenceExpression (identifier = result3) [result3] : PsiType:String
|
||||||
|
ULiteralExpression (value = "OK") ["OK"] : PsiType:String
|
||||||
|
UIfExpression [if (result3 != "OK") return "fail: test3"] : PsiType:void
|
||||||
|
UBinaryExpression (operator = !=) [result3 != "OK"] : PsiType:boolean
|
||||||
|
USimpleNameReferenceExpression (identifier = result3) [result3] : PsiType:String
|
||||||
|
ULiteralExpression (value = "OK") ["OK"] : PsiType:String
|
||||||
|
UReturnExpression [return "fail: test3"] : PsiType:Void
|
||||||
|
ULiteralExpression (value = "fail: test3") ["fail: test3"] : PsiType:String
|
||||||
|
UTryExpression [try {...] : PsiType:void
|
||||||
|
UBlockExpression [{...}] : PsiType:void
|
||||||
|
UCallExpression (kind = UastCallKind(name='method_call'), argCount = 1)) [castToString(null)] : PsiType:void
|
||||||
|
UIdentifier (Identifier (castToString)) [UIdentifier (Identifier (castToString))]
|
||||||
|
USimpleNameReferenceExpression (identifier = castToString, resolvesTo = null) [castToString] : PsiType:void
|
||||||
|
ULiteralExpression (value = null) [null] : PsiType:Void
|
||||||
|
UCatchClause (e) [catch (@org.jetbrains.annotations.NotNull var e: java.lang.Exception) {...}]
|
||||||
|
UParameter (name = e) [@org.jetbrains.annotations.NotNull var e: java.lang.Exception]
|
||||||
|
UAnnotation (fqName = org.jetbrains.annotations.NotNull) [@org.jetbrains.annotations.NotNull]
|
||||||
|
UBlockExpression [{...}] : PsiType:Void
|
||||||
|
UReturnExpression [return "OK"] : PsiType:Void
|
||||||
|
ULiteralExpression (value = "OK") ["OK"] : PsiType:String
|
||||||
|
UReturnExpression [return "Fail"] : PsiType:Void
|
||||||
|
ULiteralExpression (value = "Fail") ["Fail"] : PsiType:String
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
UFile (package = ) [public final class WithGenericKt {...]
|
||||||
|
UClass (name = WithGenericKt) [public final class WithGenericKt {...}]
|
||||||
|
UMethod (name = test1) [public static final fun test1() : T {...}]
|
||||||
|
UBlockExpression [{...}]
|
||||||
|
UReturnExpression [return "not-yet-compile-time-constant" as T]
|
||||||
|
UBinaryExpressionWithType ["not-yet-compile-time-constant" as T] : PsiType:T
|
||||||
|
ULiteralExpression (value = "not-yet-compile-time-constant") ["not-yet-compile-time-constant"] : PsiType:Void
|
||||||
|
UTypeReferenceExpression (name = T) [T]
|
||||||
|
UMethod (name = test2) [public static final fun test2() : T {...}]
|
||||||
|
UBlockExpression [{...}] : PsiType:Void
|
||||||
|
[!] UnknownKotlinExpression (PROPERTY) [[!] UnknownKotlinExpression (PROPERTY)]
|
||||||
|
UReturnExpression [return [!] UnknownKotlinExpression (REFERENCE_EXPRESSION) as T] : PsiType:Void
|
||||||
|
UBinaryExpressionWithType [[!] UnknownKotlinExpression (REFERENCE_EXPRESSION) as T] : PsiType:T
|
||||||
|
[!] UnknownKotlinExpression (REFERENCE_EXPRESSION) [[!] UnknownKotlinExpression (REFERENCE_EXPRESSION)]
|
||||||
|
UTypeReferenceExpression (name = T) [T]
|
||||||
|
UMethod (name = test3) [public static final fun test3() : T {...}]
|
||||||
|
UBlockExpression [{...}]
|
||||||
|
UReturnExpression [return "not-yet-compile-time-constant" as T]
|
||||||
|
UBinaryExpressionWithType ["not-yet-compile-time-constant" as T] : PsiType:T
|
||||||
|
ULiteralExpression (value = "not-yet-compile-time-constant") ["not-yet-compile-time-constant"] : PsiType:Void
|
||||||
|
UTypeReferenceExpression (name = T) [T]
|
||||||
|
UMethod (name = castToString) [public static final fun castToString(t: T) : void {...}]
|
||||||
|
UParameter (name = t) [var t: T]
|
||||||
|
UBlockExpression [{...}] : PsiType:String
|
||||||
|
UBinaryExpressionWithType [[!] UnknownKotlinExpression (REFERENCE_EXPRESSION) as java.lang.String] : PsiType:String
|
||||||
|
[!] UnknownKotlinExpression (REFERENCE_EXPRESSION) [[!] UnknownKotlinExpression (REFERENCE_EXPRESSION)]
|
||||||
|
UTypeReferenceExpression (name = java.lang.String) [java.lang.String]
|
||||||
|
UMethod (name = box) [public static final fun box() : java.lang.String {...}]
|
||||||
|
UBlockExpression [{...}] : PsiType:Void
|
||||||
|
UIfExpression [if ([!] UnknownKotlinExpression (BINARY_EXPRESSION)) return "fail: test1"] : PsiType:Unit
|
||||||
|
[!] UnknownKotlinExpression (BINARY_EXPRESSION) [[!] UnknownKotlinExpression (BINARY_EXPRESSION)]
|
||||||
|
UReturnExpression [return "fail: test1"] : PsiType:Void
|
||||||
|
ULiteralExpression (value = "fail: test1") ["fail: test1"] : PsiType:String
|
||||||
|
UIfExpression [if ([!] UnknownKotlinExpression (BINARY_EXPRESSION)) return "fail: test2"] : PsiType:Unit
|
||||||
|
[!] UnknownKotlinExpression (BINARY_EXPRESSION) [[!] UnknownKotlinExpression (BINARY_EXPRESSION)]
|
||||||
|
UReturnExpression [return "fail: test2"] : PsiType:Void
|
||||||
|
ULiteralExpression (value = "fail: test2") ["fail: test2"] : PsiType:String
|
||||||
|
[!] UnknownKotlinExpression (PROPERTY) [[!] UnknownKotlinExpression (PROPERTY)]
|
||||||
|
[!] UnknownKotlinExpression (TRY) [[!] UnknownKotlinExpression (TRY)]
|
||||||
|
UIfExpression [if ([!] UnknownKotlinExpression (BINARY_EXPRESSION)) return "fail: test3"] : PsiType:Unit
|
||||||
|
[!] UnknownKotlinExpression (BINARY_EXPRESSION) [[!] UnknownKotlinExpression (BINARY_EXPRESSION)]
|
||||||
|
UReturnExpression [return "fail: test3"] : PsiType:Void
|
||||||
|
ULiteralExpression (value = "fail: test3") ["fail: test3"] : PsiType:String
|
||||||
|
[!] UnknownKotlinExpression (TRY) [[!] UnknownKotlinExpression (TRY)]
|
||||||
|
UReturnExpression [return "Fail"] : PsiType:Void
|
||||||
|
ULiteralExpression (value = "Fail") ["Fail"] : PsiType:String
|
||||||
Generated
+10
@@ -29,6 +29,11 @@ public class FE1UastTypesTestGenerated extends AbstractFE1UastTypesTest {
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/uast-kotlin-fir/testData/type"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/uast-kotlin-fir/testData/type"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeCast.kt")
|
||||||
|
public void testTypeCast() throws Exception {
|
||||||
|
runTest("plugins/uast-kotlin-fir/testData/type/typeCast.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("typeCheck.kt")
|
@TestMetadata("typeCheck.kt")
|
||||||
public void testTypeCheck() throws Exception {
|
public void testTypeCheck() throws Exception {
|
||||||
runTest("plugins/uast-kotlin-fir/testData/type/typeCheck.kt");
|
runTest("plugins/uast-kotlin-fir/testData/type/typeCheck.kt");
|
||||||
@@ -38,4 +43,9 @@ public class FE1UastTypesTestGenerated extends AbstractFE1UastTypesTest {
|
|||||||
public void testUnresolved() throws Exception {
|
public void testUnresolved() throws Exception {
|
||||||
runTest("plugins/uast-kotlin-fir/testData/type/unresolved.kt");
|
runTest("plugins/uast-kotlin-fir/testData/type/unresolved.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("withGeneric.kt")
|
||||||
|
public void testWithGeneric() throws Exception {
|
||||||
|
runTest("plugins/uast-kotlin-fir/testData/type/withGeneric.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+10
@@ -29,6 +29,11 @@ public class FirUastTypesTestGenerated extends AbstractFirUastTypesTest {
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/uast-kotlin-fir/testData/type"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/uast-kotlin-fir/testData/type"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeCast.kt")
|
||||||
|
public void testTypeCast() throws Exception {
|
||||||
|
runTest("plugins/uast-kotlin-fir/testData/type/typeCast.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("typeCheck.kt")
|
@TestMetadata("typeCheck.kt")
|
||||||
public void testTypeCheck() throws Exception {
|
public void testTypeCheck() throws Exception {
|
||||||
runTest("plugins/uast-kotlin-fir/testData/type/typeCheck.kt");
|
runTest("plugins/uast-kotlin-fir/testData/type/typeCheck.kt");
|
||||||
@@ -38,4 +43,9 @@ public class FirUastTypesTestGenerated extends AbstractFirUastTypesTest {
|
|||||||
public void testUnresolved() throws Exception {
|
public void testUnresolved() throws Exception {
|
||||||
runTest("plugins/uast-kotlin-fir/testData/type/unresolved.kt");
|
runTest("plugins/uast-kotlin-fir/testData/type/unresolved.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("withGeneric.kt")
|
||||||
|
public void testWithGeneric() throws Exception {
|
||||||
|
runTest("plugins/uast-kotlin-fir/testData/type/withGeneric.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.uast.kotlin
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.PsiType
|
||||||
|
import org.jetbrains.uast.*
|
||||||
|
|
||||||
|
class KotlinCustomUBinaryExpressionWithType(
|
||||||
|
override val psi: PsiElement,
|
||||||
|
givenParent: UElement?
|
||||||
|
) : KotlinAbstractUExpression(givenParent), UBinaryExpressionWithType {
|
||||||
|
override lateinit var operand: UExpression
|
||||||
|
internal set
|
||||||
|
|
||||||
|
override lateinit var operationKind: UastBinaryExpressionWithTypeKind
|
||||||
|
internal set
|
||||||
|
|
||||||
|
override val type: PsiType by lz { typeReference?.type ?: UastErrorType }
|
||||||
|
|
||||||
|
override var typeReference: UTypeReferenceExpression? = null
|
||||||
|
internal set
|
||||||
|
}
|
||||||
-59
@@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2016 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.uast.kotlin
|
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
|
||||||
import com.intellij.psi.PsiType
|
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
|
||||||
import org.jetbrains.kotlin.psi.KtBinaryExpressionWithTypeRHS
|
|
||||||
import org.jetbrains.uast.*
|
|
||||||
|
|
||||||
class KotlinUBinaryExpressionWithType(
|
|
||||||
override val sourcePsi: KtBinaryExpressionWithTypeRHS,
|
|
||||||
givenParent: UElement?
|
|
||||||
) : KotlinAbstractUExpression(givenParent), UBinaryExpressionWithType,
|
|
||||||
KotlinUElementWithType, KotlinEvaluatableUElement {
|
|
||||||
|
|
||||||
override val operand by lz { KotlinConverter.convertOrEmpty(sourcePsi.left, this) }
|
|
||||||
override val type by lz { sourcePsi.right.toPsiType(this) }
|
|
||||||
|
|
||||||
override val typeReference by lz {
|
|
||||||
sourcePsi.right?.let { KotlinUTypeReferenceExpression(it, this) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override val operationKind = when (sourcePsi.operationReference.getReferencedNameElementType()) {
|
|
||||||
KtTokens.AS_KEYWORD -> UastBinaryExpressionWithTypeKind.TYPE_CAST
|
|
||||||
KtTokens.AS_SAFE -> KotlinBinaryExpressionWithTypeKinds.SAFE_TYPE_CAST
|
|
||||||
else -> UastBinaryExpressionWithTypeKind.UNKNOWN
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class KotlinCustomUBinaryExpressionWithType(
|
|
||||||
override val psi: PsiElement,
|
|
||||||
givenParent: UElement?
|
|
||||||
) : KotlinAbstractUExpression(givenParent), UBinaryExpressionWithType {
|
|
||||||
lateinit override var operand: UExpression
|
|
||||||
internal set
|
|
||||||
|
|
||||||
lateinit override var operationKind: UastBinaryExpressionWithTypeKind
|
|
||||||
internal set
|
|
||||||
|
|
||||||
override val type: PsiType by lz { typeReference?.type ?: UastErrorType }
|
|
||||||
|
|
||||||
override var typeReference: UTypeReferenceExpression? = null
|
|
||||||
internal set
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user