• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS of ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16package std.core;
17
18// Class Value
19
20native function ValueAPIGetFieldBoolean(obj: Object, i: long): boolean
21
22native function ValueAPIGetFieldByte(obj: Object, i: long): byte
23
24native function ValueAPIGetFieldShort(obj: Object, i: long): short
25
26native function ValueAPIGetFieldChar(obj: Object, i: long): char
27
28native function ValueAPIGetFieldInt(obj: Object, i: long): int
29
30native function ValueAPIGetFieldFloat(obj: Object, i: long): float
31
32native function ValueAPIGetFieldDouble(obj: Object, i: long): double
33
34native function ValueAPIGetFieldLong(obj: Object, i: long): long
35
36native function ValueAPIGetFieldObject(obj: Object, i: long): Object
37
38
39native function ValueAPIGetFieldByNameBoolean(obj: Object, name: String): boolean
40
41native function ValueAPIGetFieldByNameByte(obj: Object, name: String): byte
42
43native function ValueAPIGetFieldByNameShort(obj: Object, name: String): short
44
45native function ValueAPIGetFieldByNameChar(obj: Object, name: String): char
46
47native function ValueAPIGetFieldByNameInt(obj: Object, name: String): int
48
49native function ValueAPIGetFieldByNameFloat(obj: Object, name: String): float
50
51native function ValueAPIGetFieldByNameDouble(obj: Object, name: String): double
52
53native function ValueAPIGetFieldByNameLong(obj: Object, name: String): long
54
55native function ValueAPIGetFieldByNameObject(obj: Object, name: String): Object
56
57
58native function ValueAPISetFieldBoolean(obj: Object, i: long, val: boolean): void
59
60native function ValueAPISetFieldByte(obj: Object, i: long, val: byte): void
61
62native function ValueAPISetFieldShort(obj: Object, i: long, val: short): void
63
64native function ValueAPISetFieldChar(obj: Object, i: long, val: char): void
65
66native function ValueAPISetFieldInt(obj: Object, i: long, val: int): void
67
68native function ValueAPISetFieldFloat(obj: Object, i: long, val: float): void
69
70native function ValueAPISetFieldDouble(obj: Object, i: long, val: double): void
71
72native function ValueAPISetFieldLong(obj: Object, i: long, val: long): void
73
74native function ValueAPISetFieldObject(obj: Object, i: long, val: Object): void
75
76
77native function ValueAPISetFieldByNameBoolean(obj: Object, name: String, val: boolean): void
78
79native function ValueAPISetFieldByNameByte(obj: Object, name: String, val: byte): void
80
81native function ValueAPISetFieldByNameShort(obj: Object, name: String, val: short): void
82
83native function ValueAPISetFieldByNameChar(obj: Object, name: String, val: char): void
84
85native function ValueAPISetFieldByNameInt(obj: Object, name: String, val: int): void
86
87native function ValueAPISetFieldByNameFloat(obj: Object, name: String, val: float): void
88
89native function ValueAPISetFieldByNameDouble(obj: Object, name: String, val: double): void
90
91native function ValueAPISetFieldByNameLong(obj: Object, name: String, val: long): void
92
93native function ValueAPISetFieldByNameObject(obj: Object, name: String, val: Object): void
94
95// Array Value
96native function ValueAPIGetArrayLength(obj: Object): long
97
98native function ValueAPISetElementBoolean(obj: Object, i: long, val: boolean): void
99
100native function ValueAPISetElementByte(obj: Object, i: long, val: byte): void
101
102native function ValueAPISetElementShort(obj: Object, i: long, val: short): void
103
104native function ValueAPISetElementChar(obj: Object, i: long, val: char): void
105
106native function ValueAPISetElementInt(obj: Object, i: long, val: int): void
107
108native function ValueAPISetElementFloat(obj: Object, i: long, val: float): void
109
110native function ValueAPISetElementDouble(obj: Object, i: long, val: double): void
111
112native function ValueAPISetElementLong(obj: Object, i: long, val: long): void
113
114native function ValueAPISetElementObject(obj: Object, i: long, val: Object): void
115
116
117native function ValueAPIGetElementBoolean(obj: Object, i: long): boolean
118
119native function ValueAPIGetElementByte(obj: Object, i: long): byte
120
121native function ValueAPIGetElementShort(obj: Object, i: long): short
122
123native function ValueAPIGetElementChar(obj: Object, i: long): char
124
125native function ValueAPIGetElementInt(obj: Object, i: long): int
126
127native function ValueAPIGetElementFloat(obj: Object, i: long): float
128
129native function ValueAPIGetElementDouble(obj: Object, i: long): double
130
131native function ValueAPIGetElementLong(obj: Object, i: long): long
132
133native function ValueAPIGetElementObject(obj: Object, i: long): Object
134
135/**
136 * Represents abstract value
137 */
138export abstract class Value extends Object {
139    public static of(v: boolean): Value {
140        return new BooleanValue(BooleanType.VAL, v)
141    }
142
143    public static of(v: char): Value {
144        return new CharValue(CharType.VAL, v)
145    }
146
147    public static of(v: byte): Value {
148        return new ByteValue(ByteType.VAL, v)
149    }
150
151    public static of(v: short): Value {
152        return new ShortValue(ShortType.VAL, v)
153    }
154
155    public static of(v: int): Value {
156        return new IntValue(IntType.VAL, v)
157    }
158
159    public static of(v: long): Value {
160        return new LongValue(LongType.VAL, v)
161    }
162
163    public static of(v: float): Value {
164        return new FloatValue(FloatType.VAL, v)
165    }
166
167    public static of(v: double): Value {
168        return new DoubleValue(DoubleType.VAL, v)
169    }
170
171    // -----
172
173    /**
174     * Returns value of this object
175     *
176     * @param o object instance
177     *
178     * @returns {@link Value} of this object
179     */
180    public static of(o: NullishType): Value {
181        if (o instanceof Value) {
182            return o as Value
183        } else if (o instanceof Boolean) {
184            return new BooleanValue(BooleanType.REF, o as Boolean)
185        } else if (o instanceof Char) {
186            return new CharValue(CharType.REF, o as Char)
187        } else if (o instanceof Byte) {
188            return new ByteValue(ByteType.REF, o as Byte)
189        } else if (o instanceof Short) {
190            return new ShortValue(ShortType.REF, o as Short)
191        } else if (o instanceof Int) {
192            return new IntValue(IntType.REF, o as Int)
193        } else if (o instanceof Long) {
194            return new LongValue(LongType.REF, o as Long)
195        } else if (o instanceof Float) {
196            return new FloatValue(FloatType.REF, o as Float)
197        } else if (o instanceof Double) {
198            return new DoubleValue(DoubleType.REF, o as Double)
199        }
200
201        let t = Type.of(o)
202        if (t instanceof NullType) {
203            return NullValue.INSTANCE
204        } else if (t instanceof UndefinedType) {
205            return UndefinedValue.INSTANCE
206        } else if (t instanceof VoidType) {
207            return VoidValue.INSTANCE
208        } else if (t instanceof ClassType) {
209            return new ClassValue(t as ClassType, __narrowAny(o)!)
210        } else if (t instanceof ArrayType) {
211            return new ArrayValue(t as ArrayType, __narrowAny(o)!)
212        } else if (t instanceof StringType) {
213            return new StringValue(t as StringType, o! as string)
214        } else if (t instanceof LambdaType) {
215            return new LambdaValue(t as LambdaType, __narrowAny(o)!)
216        } else if (t instanceof MethodType) {
217            throw new Error("The MethodType cannot be instantiated")
218        } else if (t instanceof EnumType) {
219            throw new Error("Not implemented")
220        } else if (t instanceof UnionType) {
221            throw new Error("Not implemented")
222        } else if (t instanceof TupleType) {
223            throw new Error("Not implemented")
224        }
225        throw new Error("Unknown type")
226    }
227
228    // -----
229
230    public static of(v: FixedArray<boolean>): Value {
231        return new ArrayValue(ArrayType.BOOLEAN_VAL, v)
232    }
233
234    public static of(v: FixedArray<char>): Value {
235        return new ArrayValue(ArrayType.CHAR_VAL, v)
236    }
237
238    public static of(v: FixedArray<byte>): Value {
239        return new ArrayValue(ArrayType.BYTE_VAL, v)
240    }
241
242    public static of(v: FixedArray<short>): Value {
243        return new ArrayValue(ArrayType.SHORT_VAL, v)
244    }
245
246    public static of(v: FixedArray<int>): Value {
247        return new ArrayValue(ArrayType.INT_VAL, v)
248    }
249
250    public static of(v: FixedArray<long>): Value {
251        return new ArrayValue(ArrayType.LONG_VAL, v)
252    }
253
254    public static of(v: FixedArray<float>): Value {
255        return new ArrayValue(ArrayType.FLOAT_VAL, v)
256    }
257
258    public static of(v: FixedArray<double>): Value {
259        return new ArrayValue(ArrayType.DOUBLE_VAL, v)
260    }
261
262    public abstract getType(): Type
263
264    public abstract getData(): NullishType
265
266    public abstract toPrint(depth: int): string
267}
268
269
270/**
271 * Represents value of object of class type
272 */
273export final class ClassValue extends Value {
274    private typ: ClassType
275    private data: Object
276
277    public override getType(): Type {
278        return this.typ as Type
279    }
280
281    public override getData(): NullishType {
282        return this.data
283    }
284
285    internal constructor(typ: ClassType, data: Object) {
286        this.typ = typ
287        this.data = data
288    }
289
290    /**
291     * Returns number of fields of this value
292     *
293     * @returns number of fields
294     */
295    public getFieldsNum(): long {
296        return this.typ.getFieldsNum()
297    }
298
299    /**
300     * Returns ith field of value
301     *
302     * @param i index
303     *
304     * @throws error when i greater then field's number
305     *
306     * @returns field {@link Value}
307     */
308    public getField(i: long): Value {
309        let f = this.typ.getField(i)
310        if (f.isStatic()) {
311            throw new Error("Field must be not static")
312        }
313        let ft = f.getType()
314        if (!ft.isReference()) {
315            if (ft instanceof BooleanType) {
316                return new BooleanValue(ft as BooleanType, ValueAPIGetFieldBoolean(this.data, i))
317            } else if (ft instanceof ByteType) {
318                return new ByteValue(ft as ByteType, ValueAPIGetFieldByte(this.data, i))
319            } else if (ft instanceof ShortType) {
320                return new ShortValue(ft as ShortType, ValueAPIGetFieldShort(this.data, i))
321            } else if (ft instanceof CharType) {
322                return new CharValue(ft as CharType, ValueAPIGetFieldChar(this.data, i))
323            } else if (ft instanceof IntType) {
324                return new IntValue(ft as IntType, ValueAPIGetFieldInt(this.data, i))
325            } else if (ft instanceof FloatType) {
326                return new FloatValue(ft as FloatType, ValueAPIGetFieldFloat(this.data, i))
327            } else if (ft instanceof DoubleType) {
328                return new DoubleValue(ft as DoubleType, ValueAPIGetFieldDouble(this.data, i))
329            } else if (ft instanceof LongType) {
330                return new LongValue(ft as LongType, ValueAPIGetFieldLong(this.data, i))
331            }
332        }
333        return Value.of(ValueAPIGetFieldObject(this.data, i))
334    }
335
336    public getFieldByName(name: string): Value {
337        let f = this.typ.getFieldByName(name)
338        if (f.isStatic()) {
339            throw new Error("Field must be not static")
340        }
341        const ft = f.getType()
342        if (!ft.isReference()) {
343            if (ft instanceof BooleanType) {
344                return new BooleanValue(ft as BooleanType, ValueAPIGetFieldByNameBoolean(this.data, name))
345            } else if (ft instanceof ByteType) {
346                return new ByteValue(ft as ByteType, ValueAPIGetFieldByNameByte(this.data, name))
347            } else if (ft instanceof ShortType) {
348                return new ShortValue(ft as ShortType, ValueAPIGetFieldByNameShort(this.data, name))
349            } else if (ft instanceof CharType) {
350                return new CharValue(ft as CharType, ValueAPIGetFieldByNameChar(this.data, name))
351            } else if (ft instanceof IntType) {
352                return new IntValue(ft as IntType, ValueAPIGetFieldByNameInt(this.data, name))
353            } else if (ft instanceof FloatType) {
354                return new FloatValue(ft as FloatType, ValueAPIGetFieldByNameFloat(this.data, name))
355            } else if (ft instanceof DoubleType) {
356                return new DoubleValue(ft as DoubleType, ValueAPIGetFieldByNameDouble(this.data, name))
357            } else if (ft instanceof LongType) {
358                return new LongValue(ft as LongType, ValueAPIGetFieldByNameLong(this.data, name))
359            }
360            throw new AssertionError("Type " + f.getType() + " is not a (un)boxed primitive")
361        }
362        return Value.of(ValueAPIGetFieldByNameObject(this.data, name))
363    }
364
365    /**
366     * Sets field value by it's name
367     *
368     * @param name of field
369     *
370     * @param val @{link Value}
371     *
372     * @throws error if this value doesn't have field with {@link name}
373     * or type of {@link val} doesn't assignable to type of this value
374     */
375    public setFieldByName(name: string, val: Value) {
376        let f = this.typ.getFieldByName(name)
377        if (f.isStatic()) {
378            throw new Error("Field must be not static")
379        }
380        let ft = f.getType()
381        let vt = val.getType()
382        if (!ft.assignableFrom(vt)) {
383            throw new Error("Cannot assign field of type " + ft + " with value of type " + vt)
384        }
385
386        if (ft instanceof BooleanType && val instanceof BooleanValue) {
387            ValueAPISetFieldByNameBoolean(this.data, name, (val as BooleanValue).getValueData())
388        } else if (ft instanceof ByteType && val instanceof ByteValue) {
389            ValueAPISetFieldByNameByte(this.data, name, (val as ByteValue).getValueData())
390        } else if (ft instanceof ShortType && val instanceof ShortValue) {
391            ValueAPISetFieldByNameShort(this.data, name, (val as ShortValue).getValueData())
392        } else if (ft instanceof CharType && val instanceof CharValue) {
393            ValueAPISetFieldByNameChar(this.data, name, (val as CharValue).getValueData())
394        } else if (ft instanceof IntType && val instanceof IntValue) {
395            ValueAPISetFieldByNameInt(this.data, name, (val as IntValue).getValueData())
396        } else if (ft instanceof FloatType && val instanceof FloatValue) {
397            ValueAPISetFieldByNameFloat(this.data, name, (val as FloatValue).getValueData())
398        } else if (ft instanceof DoubleType && val instanceof DoubleValue) {
399            ValueAPISetFieldByNameDouble(this.data, name, (val as DoubleValue).getValueData())
400        } else if (ft instanceof LongType && val instanceof LongValue) {
401            ValueAPISetFieldByNameLong(this.data, name, (val as LongValue).getValueData())
402        } else if (ft.assignableFrom(StringType.REF) && val instanceof StringValue) {
403            ValueAPISetFieldByNameObject(this.data, name, (val as StringValue).getData()! as string)
404        } else if (ft instanceof ArrayType && val instanceof ArrayValue) {
405            ValueAPISetFieldByNameObject(this.data, name, __narrowAny((val as ArrayValue).getData())!)
406        } else if (ft instanceof ClassType && this.isAssignableToObject(val)) {
407            ValueAPISetFieldByNameObject(this.data, name, __narrowAny(val.getData())!)
408        } else if (ft instanceof LambdaType && val instanceof LambdaValue) {
409            ValueAPISetFieldByNameObject(this.data, name, __narrowAny((val as LambdaValue).getData())!)
410        } else if (ft instanceof DoubleType && val instanceof ByteValue) {
411            ValueAPISetFieldByNameDouble(this.data, name, val.getValueData())
412        } else if (ft instanceof DoubleType && val instanceof ShortValue) {
413            ValueAPISetFieldByNameDouble(this.data, name, val.getValueData())
414        } else if (ft instanceof DoubleType && val instanceof IntValue) {
415            ValueAPISetFieldByNameDouble(this.data, name, val.getValueData())
416        } else if (ft instanceof DoubleType && val instanceof LongValue) {
417            ValueAPISetFieldByNameDouble(this.data, name, val.getValueData())
418        } else if (ft instanceof DoubleType && val instanceof FloatValue) {
419            ValueAPISetFieldByNameDouble(this.data, name, val.getValueData())
420        } else if (ft instanceof FloatType && val instanceof ByteValue) {
421            ValueAPISetFieldByNameFloat(this.data, name, val.getValueData())
422        } else if (ft instanceof FloatType && val instanceof ShortValue) {
423            ValueAPISetFieldByNameFloat(this.data, name, val.getValueData())
424        } else if (ft instanceof FloatType && val instanceof IntValue) {
425            ValueAPISetFieldByNameFloat(this.data, name, val.getValueData())
426        } else if (ft instanceof FloatType && val instanceof LongValue) {
427            ValueAPISetFieldByNameFloat(this.data, name, val.getValueData())
428        } else if (ft instanceof LongType && val instanceof ByteValue) {
429            ValueAPISetFieldByNameLong(this.data, name, val.getValueData())
430        } else if (ft instanceof LongType && val instanceof ShortValue) {
431            ValueAPISetFieldByNameLong(this.data, name, val.getValueData())
432        } else if (ft instanceof LongType && val instanceof IntValue) {
433            ValueAPISetFieldByNameLong(this.data, name, val.getValueData())
434        } else if (ft instanceof LongType && val instanceof ByteValue) {
435            ValueAPISetFieldByNameLong(this.data, name, val.getValueData())
436        } else if (ft instanceof LongType && val instanceof ShortValue) {
437            ValueAPISetFieldByNameLong(this.data, name, val.getValueData())
438        } else if (ft instanceof IntType && val instanceof ByteValue) {
439            ValueAPISetFieldByNameInt(this.data, name, val.getValueData())
440        } else if (ft instanceof IntType && val instanceof ShortValue) {
441            ValueAPISetFieldByNameInt(this.data, name, val.getValueData())
442        } else if (ft instanceof ShortType && val instanceof ByteValue) {
443            ValueAPISetFieldByNameShort(this.data, name, val.getValueData())
444        } else {
445            throw new Error("Cannot assign field of type " + ft + " with value of type " + vt)
446        }
447    }
448
449    private isAssignableToObject(v: Value): boolean {
450        return v instanceof ClassValue
451            || v instanceof LambdaValue
452            || v instanceof StringValue
453            || v instanceof ArrayValue
454    }
455
456    /**
457     * Sets field value by it's index
458     *
459     * @param i of field
460     *
461     * @param val @{link Value}
462     *
463     * @throws error if this value doesn't have field with {@link index}'th index
464     * or type of {@link val} doesn't assignable to type of this value
465     */
466    public setField(i: long, val: Value) {
467        let f = this.typ.getField(i)
468        if (f.isStatic()) {
469            throw new Error("Field must be not static")
470        }
471        let ft = f.getType()
472        let vt = val.getType()
473        if (!ft.assignableFrom(vt)) {
474            throw new Error("Cannot assign field of type " + ft + " with value of type " + vt)
475        }
476        if (ft instanceof BooleanType && val instanceof BooleanValue) {
477            ValueAPISetFieldBoolean(this.data, i, (val as BooleanValue).getValueData())
478        } else if (ft instanceof ByteType && val instanceof ByteValue) {
479            ValueAPISetFieldByte(this.data, i, (val as ByteValue).getValueData())
480        } else if (ft instanceof ShortType && val instanceof ShortValue) {
481            ValueAPISetFieldShort(this.data, i, (val as ShortValue).getValueData())
482        } else if (ft instanceof CharType && val instanceof CharValue) {
483            ValueAPISetFieldChar(this.data, i, (val as CharValue).getValueData())
484        } else if (ft instanceof IntType && val instanceof IntValue) {
485            ValueAPISetFieldInt(this.data, i, (val as IntValue).getValueData())
486        } else if (ft instanceof FloatType && val instanceof FloatValue) {
487            ValueAPISetFieldFloat(this.data, i, (val as FloatValue).getValueData())
488        } else if (ft instanceof DoubleType && val instanceof DoubleValue) {
489            ValueAPISetFieldDouble(this.data, i, (val as DoubleValue).getValueData())
490        } else if (ft instanceof LongType && val instanceof LongValue) {
491            ValueAPISetFieldLong(this.data, i, (val as LongValue).getValueData())
492        } else if (ft instanceof StringType && val instanceof StringValue) {
493            ValueAPISetFieldObject(this.data, i, (val as StringValue).getData()! as string)
494        } else if (ft instanceof ArrayType && val instanceof ArrayValue) {
495            ValueAPISetFieldObject(this.data, i, __narrowAny((val as ArrayValue).getData())!)
496        } else if (ft instanceof ClassType && this.isAssignableToObject(val)) {
497            ValueAPISetFieldObject(this.data, i, __narrowAny((val as ClassValue).getData())!)
498        } else if (ft instanceof LambdaType && val instanceof LambdaValue) {
499            ValueAPISetFieldObject(this.data, i, __narrowAny(val.getData())!)
500        } else {
501            throw new Error("Cannot assign field of type " + ft + " with value of type " + vt)
502        }
503    }
504
505    public override toPrint(depth: int): string {
506        if (this.typ.getName() == "escompat.Date") {
507            return new StringBuilder("Date: ").append("\"").append((this.data as Date).toISOString()).append("\"").toString()
508        }
509        if (depth == 0) {
510            return this.typ.getName() + " {...}"
511        }
512
513        const thisStr = this.data.toString()
514        const objStr = new Object().toString()
515        if (thisStr != objStr) {
516            return thisStr
517        }
518        const fnum = this.getFieldsNum()
519        if (fnum == 0) {
520            return this.typ.getName() + " {}"
521        }
522        let res = new StringBuilder(this.typ.getName())
523        res.append(" {")
524        for (let i = 0; i < fnum; i++) {
525            const f = this.typ.getField(i)
526            if (f.isStatic()) {
527                continue
528            }
529            const fv = this.getField(i)
530            res.append(f.getName())
531            res.append(": ")
532            res.append(fv.toPrint(depth - 1))
533            if (i != fnum - 1) {
534                res.append(", ")
535            }
536        }
537        res.append("}")
538        return res.toString()
539    }
540
541    public override toString(): string {
542        return "[object Object]"
543    }
544
545    public override toLocaleString(): string {
546        return this.toString()
547    }
548}
549
550/**
551 * Represents array value
552 */
553export final class ArrayValue extends Value {
554    private typ: ArrayType
555    private data: Object
556
557    public override getType(): Type {
558        return this.typ as Type
559    }
560
561    public override getData(): NullishType {
562        return this.data
563    }
564
565    internal constructor(typ: ArrayType, data: Object) {
566        this.typ = typ
567        this.data = data
568    }
569
570    public getLength(): long {
571        return ValueAPIGetArrayLength(this.data)
572    }
573
574    public getElement(i: long): Value {
575        const et = this.typ.getElementType()
576        if (!et.isReference()) {
577            if (et instanceof BooleanType) {
578                return new BooleanValue(et as BooleanType, ValueAPIGetElementBoolean(this.data, i))
579            } else if (et instanceof ByteType) {
580                return new ByteValue(et as ByteType, ValueAPIGetElementByte(this.data, i))
581            } else if (et instanceof ShortType) {
582                return new ShortValue(et as ShortType, ValueAPIGetElementShort(this.data, i))
583            } else if (et instanceof CharType) {
584                return new CharValue(et as CharType, ValueAPIGetElementChar(this.data, i))
585            } else if (et instanceof IntType) {
586                return new IntValue(et as IntType, ValueAPIGetElementInt(this.data, i))
587            } else if (et instanceof FloatType) {
588                return new FloatValue(et as FloatType, ValueAPIGetElementFloat(this.data, i))
589            } else if (et instanceof DoubleType) {
590                return new DoubleValue(et as DoubleType, ValueAPIGetElementDouble(this.data, i))
591            } else if (et instanceof LongType) {
592                return new LongValue(et as LongType, ValueAPIGetElementLong(this.data, i))
593            }
594            throw new AssertionError("Type " + et + " is not a (un)boxed primitive")
595        }
596        return Value.of(ValueAPIGetElementObject(this.data, i))
597    }
598
599    /**
600     * Sets i'th element of array
601     *
602     * @param i index
603     *
604     * @param val {@link Value} to be set
605     *
606     * @throws error if of {@link val} cannot be assign to i'th element of array
607     */
608    public setElement(i: long, val: Value) {
609        let et = this.typ.getElementType()
610        let vt = val.getType()
611        if (!et.assignableFrom(vt)) {
612            throw new Error("Cannot assign array of type " + et + " with value of type " + vt)
613        }
614        if (et instanceof BooleanType && val instanceof BooleanValue) {
615            ValueAPISetElementBoolean(this.data, i, (val as BooleanValue).getValueData())
616        } else if (et instanceof ByteType && val instanceof ByteValue) {
617            ValueAPISetElementByte(this.data, i, (val as ByteValue).getValueData())
618        } else if (et instanceof ShortType && val instanceof ShortValue) {
619            ValueAPISetElementShort(this.data, i, (val as ShortValue).getValueData())
620        } else if (et instanceof CharType && val instanceof CharValue) {
621            ValueAPISetElementChar(this.data, i, (val as CharValue).getValueData())
622        } else if (et instanceof IntType && val instanceof IntValue) {
623            ValueAPISetElementInt(this.data, i, (val as IntValue).getValueData())
624        } else if (et instanceof FloatType && val instanceof FloatValue) {
625            ValueAPISetElementFloat(this.data, i, (val as FloatValue).getValueData())
626        } else if (et instanceof DoubleType && val instanceof DoubleValue) {
627            ValueAPISetElementDouble(this.data, i, (val as DoubleValue).getValueData())
628        } else if (et instanceof LongType && val instanceof LongValue) {
629            ValueAPISetElementLong(this.data, i, (val as LongValue).getValueData())
630        } else if (et instanceof StringType && val instanceof StringValue) {
631            ValueAPISetElementObject(this.data, i, (val as StringValue).getData()! as string)
632        } else if (et instanceof ArrayType && val instanceof ArrayValue) {
633            ValueAPISetElementObject(this.data, i, __narrowAny((val as ArrayValue).getData())!)
634        } else if (et instanceof ClassType && val instanceof ClassValue) {
635            ValueAPISetElementObject(this.data, i, __narrowAny((val as ClassValue).getData())!)
636        } else {
637            throw new Error("Cannot assign array of type " + et + " with value of type " + vt)
638        }
639    }
640
641    public override toPrint(depth: int): string {
642        if (depth == 0) {
643            return "[...]"
644        }
645        const len = this.getLength()
646        if (len == 0) {
647            return "[]"
648        }
649        let res = new StringBuilder("[")
650        for (let i = 0; i < len; i++) {
651            res.append(this.getElement(i).toPrint(depth - 1))
652            if (i != len - 1) {
653                res.append(", ")
654            }
655        }
656        res.append("]")
657        return res.toString()
658    }
659
660    public override toString(): string {
661        const len = this.getLength()
662        if (len == 0) {
663            return ""
664        }
665        let res = new StringBuilder()
666        for (let i = 0; i < len; i++) {
667            res.append(this.getElement(i).toString())
668            if (i != len - 1) {
669                res.append(",")
670            }
671        }
672        return res.toString()
673    }
674
675    public override toLocaleString(): string {
676        const len = this.getLength()
677        if (len == 0) {
678            return ""
679        }
680        let res = new StringBuilder()
681        for (let i = 0; i < len; i++) {
682            res.append(this.getElement(i).toLocaleString())
683            if (i != len - 1) {
684                res.append(",")
685            }
686        }
687        return res.toString()
688    }
689}
690
691export final class LambdaValue extends Value {
692    private typ: LambdaType
693    private data: Object
694
695    public override getType(): Type {
696        return this.typ as Type
697    }
698
699    public override getData(): NullishType {
700        return this.data
701    }
702
703    internal constructor(typ: LambdaType, data: Object) {
704        this.typ = typ
705        this.data = data
706    }
707
708    public invoke(...args: Object[]): Object {
709        // NOTE(shumilov-petr): not implemented
710        throw new Error("Not implemented")
711    }
712
713    public override toPrint(depth: int): string {
714        return "[object Function]"
715    }
716
717    public override toString(): string {
718        return "Cannot get source code of function";
719    }
720
721    public override toLocaleString(): string {
722        return this.toString()
723    }
724}
725
726/**
727 * Represents boolean value
728 */
729export final class BooleanValue extends Value {
730    private typ: BooleanType
731    private data: boolean
732
733    public override getType(): Type {
734        return this.typ as Type
735    }
736
737    public override getData(): NullishType {
738        return new Boolean(this.data)
739    }
740
741    public getValueData(): boolean {
742        return this.data
743    }
744
745    internal constructor(typ: BooleanType, data: boolean) {
746        this.typ = typ
747        this.data = data
748    }
749
750    public override toPrint(depth: int): string {
751        return new StringBuilder().append(this.data).toString()
752    }
753
754    public override toString(): string {
755        return new StringBuilder().append(this.data).toString()
756    }
757
758    public override toLocaleString(): string {
759        return this.toString()
760    }
761}
762
763/**
764 * Represents byte value
765 */
766export final class ByteValue extends Value {
767    private typ: ByteType
768    private data: byte
769
770    public override getType(): Type {
771        return this.typ as Type
772    }
773
774    public override getData(): NullishType {
775        return new Byte(this.data)
776    }
777
778    public getValueData(): byte {
779        return this.data
780    }
781
782    internal constructor(typ: ByteType, data: byte) {
783        this.typ = typ
784        this.data = data
785    }
786
787    public override toPrint(depth: int): string {
788        return new StringBuilder().append(this.data).toString()
789    }
790
791    public override toString(): string {
792        return new StringBuilder().append(this.data).toString()
793    }
794
795    public override toLocaleString(): string {
796        return this.toString()
797    }
798}
799
800/**
801 * Represents short value
802 */
803export final class ShortValue extends Value {
804    private typ: ShortType
805    private data: short
806
807    public override getType(): Type {
808        return this.typ as Type
809    }
810
811    public override getData(): NullishType {
812        return new Short(this.data)
813    }
814
815    public getValueData(): short {
816        return this.data
817    }
818
819    internal constructor(typ: ShortType, data: short) {
820        this.typ = typ
821        this.data = data
822    }
823
824    public override toPrint(depth: int): string {
825        return new StringBuilder().append(this.data).toString()
826    }
827
828    public override toString(): string {
829        return new StringBuilder().append(this.data).toString()
830    }
831
832    public override toLocaleString(): string {
833        return this.toString()
834    }
835}
836
837/**
838 * Represents char value
839 */
840export final class CharValue extends Value {
841    private typ: CharType
842    private data: char
843
844    public override getType(): Type {
845        return this.typ as Type
846    }
847
848    public override getData(): NullishType {
849        return new Char(this.data)
850    }
851
852    public getValueData(): char {
853        return this.data
854    }
855
856    internal constructor(typ: CharType, data: char) {
857        this.typ = typ
858        this.data = data
859    }
860
861    public override toPrint(depth: int): string {
862        return new StringBuilder("\"").append(this.data).append("\"").toString()
863    }
864
865    public override toString(): string {
866        return new StringBuilder("\"").append(this.data).append("\"").toString()
867    }
868
869    public override toLocaleString(): string {
870        return this.toString()
871    }
872}
873
874/**
875 * Represents int value
876 */
877export final class IntValue extends Value {
878    private typ: IntType
879    private data: int
880
881    public override getType(): Type {
882        return this.typ as Type
883    }
884
885    public override getData(): NullishType {
886        return new Int(this.data)
887    }
888
889    public getValueData(): int {
890        return this.data
891    }
892
893    internal constructor(typ: IntType, data: int) {
894        this.typ = typ
895        this.data = data
896    }
897
898    public override toPrint(depth: int): string {
899        return new StringBuilder().append(this.data).toString()
900    }
901
902    public override toString(): string {
903        return new StringBuilder().append(this.data).toString()
904    }
905
906    public override toLocaleString(): string {
907        return this.toString()
908    }
909}
910
911/**
912 * Represents float value
913 */
914export final class FloatValue extends Value {
915    private typ: FloatType
916    private data: float
917
918    public override getType(): Type {
919        return this.typ as Type
920    }
921
922    public override getData(): NullishType {
923        return new Float(this.data)
924    }
925
926    public getValueData(): float {
927        return this.data
928    }
929
930    internal constructor(typ: FloatType, data: float) {
931        this.typ = typ
932        this.data = data
933    }
934
935    public override toPrint(depth: int): string {
936        return new StringBuilder().append(this.data).toString()
937    }
938
939    public override toString(): string {
940        return new StringBuilder().append(this.data).toString()
941    }
942
943    public override toLocaleString(): string {
944        return this.toString()
945    }
946}
947
948/**
949 * Represents double value
950 */
951export final class DoubleValue extends Value {
952    private typ: DoubleType
953    private data: double
954
955    public override getType(): Type {
956        return this.typ as Type
957    }
958
959    public override getData(): NullishType {
960        return this.data
961    }
962
963    public getValueData(): double {
964        return this.data
965    }
966
967    internal constructor(typ: DoubleType, data: double) {
968        this.typ = typ
969        this.data = data
970    }
971
972    public override toPrint(depth: int): string {
973        return new StringBuilder().append(this.data).toString()
974    }
975
976    public override toString(): string {
977        return new StringBuilder().append(this.data).toString()
978    }
979
980    public override toLocaleString(): string {
981        return this.toString()
982    }
983}
984
985/**
986 * Represents long value
987 */
988export final class LongValue extends Value {
989    private typ: LongType
990    private data: long
991
992    public override getType(): Type {
993        return this.typ as Type
994    }
995
996    public override getData(): NullishType {
997        return new Long(this.data)
998    }
999
1000    public getValueData(): long {
1001        return this.data
1002    }
1003
1004    internal constructor(typ: LongType, data: long) {
1005        this.typ = typ
1006        this.data = data
1007    }
1008
1009    public override toPrint(depth: int): string {
1010        return new StringBuilder().append(this.data).toString()
1011    }
1012
1013    public override toString(): string {
1014        return new StringBuilder().append(this.data).toString()
1015    }
1016
1017    public override toLocaleString(): string {
1018        return this.toString()
1019    }
1020}
1021
1022/**
1023 * Represents string value
1024 */
1025export final class StringValue extends Value {
1026    private typ: StringType
1027    private data: string
1028
1029    public override getType(): Type {
1030        return this.typ as Type
1031    }
1032
1033    public override getData(): NullishType {
1034        return this.data
1035    }
1036
1037    internal constructor(typ: StringType, data: String) {
1038        this.typ = typ
1039        this.data = data
1040    }
1041
1042    public override toPrint(depth: int): string {
1043        return new StringBuilder().append(this.data).toString()
1044    }
1045
1046    public override toString(): string {
1047        return new StringBuilder().append(this.data).toString()
1048    }
1049
1050    public override toLocaleString(): string {
1051        return this.toString()
1052    }
1053}
1054
1055/**
1056 * Represents null value
1057 */
1058export final class NullValue extends Value {
1059    public static readonly INSTANCE = new NullValue()
1060
1061    public override getType(): Type {
1062        return NullType.REF as Type
1063    }
1064
1065    public override getData(): NullishType {
1066        return null
1067    }
1068
1069    internal constructor() {}
1070
1071    public override toPrint(depth: int): string {
1072        return NullType.REF.toString()
1073    }
1074
1075    public override toString(): string {
1076        return NullType.REF.toString()
1077    }
1078
1079    public override toLocaleString(): string {
1080        return this.toString()
1081    }
1082}
1083
1084/**
1085 * Represents undefined value
1086 */
1087export final class UndefinedValue extends Value {
1088    public static readonly INSTANCE = new UndefinedValue()
1089
1090    public override getType(): Type {
1091        return UndefinedType.REF as Type
1092    }
1093
1094    public override getData(): NullishType {
1095        return undefined
1096    }
1097
1098    internal constructor() {}
1099
1100    public override toPrint(depth: int): string {
1101        return UndefinedType.REF.toString()
1102    }
1103
1104    public override toString(): string {
1105        return UndefinedType.REF.toString()
1106    }
1107
1108    public override toLocaleString(): string {
1109        return this.toString()
1110    }
1111}
1112
1113/**
1114 * Represents void value
1115 */
1116export final class VoidValue extends Value {
1117    public static readonly INSTANCE = new VoidValue()
1118
1119    public override getType(): Type {
1120        return VoidType.REF as Type
1121    }
1122
1123    public override getData(): NullishType {
1124        return Void.void_instance
1125    }
1126
1127    internal constructor() {}
1128
1129    public override toPrint(depth: int): string {
1130        return VoidType.REF.toString()
1131    }
1132
1133    public override toString(): string {
1134        return VoidType.REF.toString()
1135    }
1136
1137    public override toLocaleString(): string {
1138        return this.toString()
1139    }
1140}
1141