Skip to content

Commit 5acbadf

Browse files
authored
Support EtsLexicalEnvType (#331)
1 parent ade31dd commit 5acbadf

File tree

11 files changed

+180
-28
lines changed

11 files changed

+180
-28
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ jobs:
126126
DEST_DIR="arkanalyzer"
127127
MAX_RETRIES=10
128128
RETRY_DELAY=3 # Delay between retries in seconds
129-
BRANCH="neo/2025-06-16"
129+
BRANCH="neo/2025-07-18"
130130
131131
for ((i=1; i<=MAX_RETRIES; i++)); do
132132
git clone --depth=1 --branch $BRANCH $REPO_URL $DEST_DIR && break

jacodb-ets/src/main/kotlin/org/jacodb/ets/dto/Convert.kt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,13 @@ import org.jacodb.ets.model.EtsBooleanType
3535
import org.jacodb.ets.model.EtsCallExpr
3636
import org.jacodb.ets.model.EtsCallStmt
3737
import org.jacodb.ets.model.EtsCastExpr
38+
import org.jacodb.ets.model.EtsCaughtExceptionRef
3839
import org.jacodb.ets.model.EtsClass
3940
import org.jacodb.ets.model.EtsClassCategory
4041
import org.jacodb.ets.model.EtsClassImpl
4142
import org.jacodb.ets.model.EtsClassSignature
4243
import org.jacodb.ets.model.EtsClassType
44+
import org.jacodb.ets.model.EtsClosureFieldRef
4345
import org.jacodb.ets.model.EtsConstant
4446
import org.jacodb.ets.model.EtsDecorator
4547
import org.jacodb.ets.model.EtsDeleteExpr
@@ -57,6 +59,7 @@ import org.jacodb.ets.model.EtsFile
5759
import org.jacodb.ets.model.EtsFileSignature
5860
import org.jacodb.ets.model.EtsFunctionType
5961
import org.jacodb.ets.model.EtsGenericType
62+
import org.jacodb.ets.model.EtsGlobalRef
6063
import org.jacodb.ets.model.EtsGtEqExpr
6164
import org.jacodb.ets.model.EtsGtExpr
6265
import org.jacodb.ets.model.EtsIfStmt
@@ -66,6 +69,7 @@ import org.jacodb.ets.model.EtsInstanceFieldRef
6669
import org.jacodb.ets.model.EtsInstanceOfExpr
6770
import org.jacodb.ets.model.EtsIntersectionType
6871
import org.jacodb.ets.model.EtsLeftShiftExpr
72+
import org.jacodb.ets.model.EtsLexicalEnvType
6973
import org.jacodb.ets.model.EtsLiteralType
7074
import org.jacodb.ets.model.EtsLocal
7175
import org.jacodb.ets.model.EtsLocalSignature
@@ -394,6 +398,21 @@ class EtsMethodBuilder(
394398

395399
is FieldRefDto -> toEtsFieldRef()
396400

401+
is CaughtExceptionRefDto -> EtsCaughtExceptionRef(
402+
type = type.toEtsType(),
403+
)
404+
405+
is GlobalRefDto -> EtsGlobalRef(
406+
name = name,
407+
ref = ref?.let { ensureLocal(it.toEtsEntity()) },
408+
)
409+
410+
is ClosureFieldRefDto -> EtsClosureFieldRef(
411+
base = base.toEtsLocal(),
412+
fieldName = fieldName,
413+
type = type.toEtsType(),
414+
)
415+
397416
is RawValueDto -> EtsRawEntity(
398417
kind = kind,
399418
extra = extra,
@@ -513,6 +532,11 @@ fun TypeDto.toEtsType(): EtsType = when (this) {
513532
types = types.map { it.toEtsType() },
514533
)
515534

535+
is LexicalEnvTypeDto -> EtsLexicalEnvType(
536+
nestedMethod = method.toEtsMethodSignature(),
537+
closures = closures.map { it.toEtsLocal() },
538+
)
539+
516540
is LiteralTypeDto -> EtsLiteralType(
517541
literalTypeName = literal.toString(),
518542
)

jacodb-ets/src/main/kotlin/org/jacodb/ets/dto/Types.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ data class AliasTypeDto(
6161
val signature: LocalSignatureDto,
6262
) : TypeDto
6363

64+
@Serializable
65+
@SerialName("LexicalEnvType")
66+
data class LexicalEnvTypeDto(
67+
val method: MethodSignatureDto,
68+
val closures: List<LocalDto>,
69+
) : TypeDto
70+
6471
@Serializable
6572
@SerialName("EnumValueType")
6673
data class EnumValueTypeDto(

jacodb-ets/src/main/kotlin/org/jacodb/ets/dto/Values.kt

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -287,29 +287,29 @@ data class ParameterRefDto(
287287
override val type: TypeDto,
288288
) : RefDto
289289

290-
// @Serializable
291-
// @SerialName("CaughtExceptionRef")
292-
// data class CaughtExceptionRefDto(
293-
// override val type: TypeDto,
294-
// ) : RefDto
295-
//
296-
// @Serializable
297-
// @SerialName("GlobalRef")
298-
// data class GlobalRefDto(
299-
// val name: String,
300-
// val ref: ValueDto?,
301-
// ) : RefDto {
302-
// override val type: TypeDto
303-
// get() = ref?.type ?: UnknownTypeDto
304-
// }
305-
//
306-
// @Serializable
307-
// @SerialName("ClosureFieldRef")
308-
// data class ClosureFieldRefDto(
309-
// val base: LocalDto,
310-
// val fieldName: String,
311-
// override val type: TypeDto,
312-
// ) : RefDto
290+
@Serializable
291+
@SerialName("CaughtExceptionRef")
292+
data class CaughtExceptionRefDto(
293+
override val type: TypeDto,
294+
) : RefDto
295+
296+
@Serializable
297+
@SerialName("GlobalRef")
298+
data class GlobalRefDto(
299+
val name: String,
300+
val ref: ValueDto?,
301+
) : RefDto {
302+
override val type: TypeDto
303+
get() = ref?.type ?: UnknownTypeDto
304+
}
305+
306+
@Serializable
307+
@SerialName("ClosureFieldRef")
308+
data class ClosureFieldRefDto(
309+
val base: LocalDto,
310+
val fieldName: String,
311+
override val type: TypeDto,
312+
) : RefDto
313313

314314
@Serializable
315315
@SerialName("ArrayRef")

jacodb-ets/src/main/kotlin/org/jacodb/ets/model/Expr.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,7 @@ data class EtsInstanceCallExpr(
736736
override val type: EtsType,
737737
) : EtsCallExpr, CommonInstanceCallExpr {
738738
override fun toString(): String {
739-
return "$instance.${callee.name}(${args.joinToString()})"
739+
return "virtual ${instance}.${callee.name}(${args.joinToString()})"
740740
}
741741

742742
override fun <R> accept(visitor: EtsExpr.Visitor<R>): R {
@@ -750,7 +750,7 @@ data class EtsStaticCallExpr(
750750
override val type: EtsType,
751751
) : EtsCallExpr {
752752
override fun toString(): String {
753-
return "${callee.enclosingClass.name}.${callee.name}(${args.joinToString()})"
753+
return "static ${callee.enclosingClass.name}.${callee.name}(${args.joinToString()})"
754754
}
755755

756756
override fun <R> accept(visitor: EtsExpr.Visitor<R>): R {
@@ -765,7 +765,7 @@ data class EtsPtrCallExpr(
765765
override val type: EtsType,
766766
) : EtsCallExpr {
767767
override fun toString(): String {
768-
return "${ptr}.${callee.name}(${args.joinToString()})"
768+
return "ptr ${ptr}(${args.joinToString()})"
769769
}
770770

771771
override fun <R> accept(visitor: EtsExpr.Visitor<R>): R {

jacodb-ets/src/main/kotlin/org/jacodb/ets/model/Local.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ data class EtsLocal(
2121
override val type: EtsType = EtsUnknownType,
2222
) : EtsImmediate, EtsLValue {
2323
override fun toString(): String {
24+
if (type is EtsLexicalEnvType) {
25+
return "$name<${type.closures.joinToString(",")}>"
26+
}
2427
return name
2528
}
2629

jacodb-ets/src/main/kotlin/org/jacodb/ets/model/Ref.kt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,45 @@ data class EtsStaticFieldRef(
9494
return visitor.visit(this)
9595
}
9696
}
97+
98+
data class EtsCaughtExceptionRef(
99+
override val type: EtsType,
100+
) : EtsRef {
101+
override fun toString(): String {
102+
return "caught $type"
103+
}
104+
105+
override fun <R> accept(visitor: EtsValue.Visitor<R>): R {
106+
return visitor.visit(this)
107+
}
108+
}
109+
110+
data class EtsGlobalRef(
111+
val name: String,
112+
val ref: EtsLocal?,
113+
) : EtsRef {
114+
override val type: EtsType
115+
get() = ref?.type ?: EtsUnknownType
116+
117+
override fun toString(): String {
118+
return "global $name"
119+
}
120+
121+
override fun <R> accept(visitor: EtsValue.Visitor<R>): R {
122+
return visitor.visit(this)
123+
}
124+
}
125+
126+
data class EtsClosureFieldRef(
127+
val base: EtsLocal,
128+
val fieldName: String,
129+
override val type: EtsType,
130+
) : EtsRef {
131+
override fun toString(): String {
132+
return "$base.$fieldName"
133+
}
134+
135+
override fun <R> accept(visitor: EtsValue.Visitor<R>): R {
136+
return visitor.visit(this)
137+
}
138+
}

jacodb-ets/src/main/kotlin/org/jacodb/ets/model/Type.kt

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ interface EtsType : TypeName, CommonType {
3030
fun visit(type: EtsIntersectionType): R
3131
fun visit(type: EtsGenericType): R
3232
fun visit(type: EtsAliasType): R
33+
fun visit(type: EtsLexicalEnvType): R
3334
fun visit(type: EtsEnumValueType): R
3435

3536
// Primitive
@@ -63,6 +64,7 @@ interface EtsType : TypeName, CommonType {
6364
override fun visit(type: EtsIntersectionType): R = defaultVisit(type)
6465
override fun visit(type: EtsGenericType): R = defaultVisit(type)
6566
override fun visit(type: EtsAliasType): R = defaultVisit(type)
67+
override fun visit(type: EtsLexicalEnvType): R = defaultVisit(type)
6668
override fun visit(type: EtsEnumValueType): R = defaultVisit(type)
6769

6870
override fun visit(type: EtsBooleanType): R = defaultVisit(type)
@@ -374,10 +376,26 @@ data class EtsFunctionType(
374376
}
375377
}
376378

379+
data class EtsLexicalEnvType(
380+
@Deprecated("This signature is incomplete due to the removed cyclic reference. You probably do not want to rely on it.")
381+
val nestedMethod: EtsMethodSignature,
382+
val closures: List<EtsLocal>,
383+
) : EtsType {
384+
@Suppress("DEPRECATION")
385+
override val typeName: String
386+
get() = "${nestedMethod.name}(${closures.joinToString { it.name }})"
387+
388+
override fun toString(): String = typeName
389+
390+
override fun <R> accept(visitor: EtsType.Visitor<R>): R {
391+
return visitor.visit(this)
392+
}
393+
}
394+
377395
data class EtsEnumValueType(
378396
val signature: EtsFieldSignature,
379397
val constant: EtsConstant? = null,
380-
): EtsType {
398+
) : EtsType {
381399
override val typeName: String
382400
get() = signature.name
383401

jacodb-ets/src/main/kotlin/org/jacodb/ets/model/Value.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ interface EtsValue : EtsEntity, CommonValue {
3737
fun visit(value: EtsInstanceFieldRef): R
3838
fun visit(value: EtsStaticFieldRef): R
3939

40+
fun visit(value: EtsCaughtExceptionRef): R
41+
fun visit(value: EtsGlobalRef): R
42+
fun visit(value: EtsClosureFieldRef): R
43+
4044
interface Default<out R> : Visitor<R> {
4145
override fun visit(value: EtsLocal): R = defaultVisit(value)
4246

@@ -53,6 +57,10 @@ interface EtsValue : EtsEntity, CommonValue {
5357
override fun visit(value: EtsInstanceFieldRef): R = defaultVisit(value)
5458
override fun visit(value: EtsStaticFieldRef): R = defaultVisit(value)
5559

60+
override fun visit(value: EtsCaughtExceptionRef): R = defaultVisit(value)
61+
override fun visit(value: EtsGlobalRef): R = defaultVisit(value)
62+
override fun visit(value: EtsClosureFieldRef): R = defaultVisit(value)
63+
5664
fun defaultVisit(value: EtsValue): R
5765
}
5866
}

jacodb-ets/src/main/kotlin/org/jacodb/ets/utils/GetOperands.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,15 @@ import org.jacodb.ets.model.EtsBitXorExpr
2828
import org.jacodb.ets.model.EtsBooleanConstant
2929
import org.jacodb.ets.model.EtsCallStmt
3030
import org.jacodb.ets.model.EtsCastExpr
31+
import org.jacodb.ets.model.EtsCaughtExceptionRef
32+
import org.jacodb.ets.model.EtsClosureFieldRef
3133
import org.jacodb.ets.model.EtsConstant
3234
import org.jacodb.ets.model.EtsDeleteExpr
3335
import org.jacodb.ets.model.EtsDivExpr
3436
import org.jacodb.ets.model.EtsEntity
3537
import org.jacodb.ets.model.EtsEqExpr
3638
import org.jacodb.ets.model.EtsExpExpr
39+
import org.jacodb.ets.model.EtsGlobalRef
3740
import org.jacodb.ets.model.EtsGtEqExpr
3841
import org.jacodb.ets.model.EtsGtExpr
3942
import org.jacodb.ets.model.EtsIfStmt
@@ -153,6 +156,15 @@ private object EntityGetOperands : EtsEntity.Visitor<Sequence<EtsEntity>> {
153156
override fun visit(value: EtsStaticFieldRef): Sequence<EtsEntity> =
154157
emptySequence()
155158

159+
override fun visit(value: EtsCaughtExceptionRef): Sequence<EtsEntity> =
160+
emptySequence()
161+
162+
override fun visit(value: EtsGlobalRef): Sequence<EtsEntity> =
163+
listOfNotNull(value.ref).asSequence()
164+
165+
override fun visit(value: EtsClosureFieldRef): Sequence<EtsEntity> =
166+
sequenceOf(value.base)
167+
156168
override fun visit(expr: EtsNewExpr): Sequence<EtsEntity> =
157169
emptySequence()
158170

0 commit comments

Comments
 (0)