@abaplint/runtime 2.13.100 → 2.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,45 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.instance_of = instance_of;
4
+ /** true when the class or interface is the target or a subtype of it:
5
+ * superclasses, implemented interfaces and interfaces they include */
6
+ function isSubtype(start, cname) {
7
+ const seen = new Set();
8
+ const matches = (source) => {
9
+ if (source == null || seen.has(source)) {
10
+ return false;
11
+ }
12
+ else if (source === cname) {
13
+ return true;
14
+ }
15
+ seen.add(source);
16
+ const internalName = source.INTERNAL_NAME || "";
17
+ const prefix = internalName.substring(0, internalName.lastIndexOf("-") + 1);
18
+ const interfaces = source.IMPLEMENTED_INTERFACES || [];
19
+ return interfaces.some(i => matches(abap.Classes[prefix + i] || abap.Classes[i]))
20
+ || matches(Object.getPrototypeOf(source));
21
+ };
22
+ return matches(start);
23
+ }
4
24
  function instance_of(val, cname) {
5
- return val.get() instanceof cname;
25
+ const obj = val.get();
26
+ if (obj === undefined) {
27
+ const name = val.getQualifiedName()?.toUpperCase();
28
+ if (name === undefined || name === "OBJECT") {
29
+ return cname === "OBJECT";
30
+ }
31
+ else if (cname === "OBJECT") {
32
+ return true;
33
+ }
34
+ // Local qualified names are short; RTTI carries the declaring program or class pool.
35
+ const scope = val.getRTTIName()?.toUpperCase().match(/^\\(PROGRAM|CLASS-POOL)=([^\\]+)/);
36
+ const prefix = scope ? (scope[1] === "PROGRAM" ? "PROG" : "CLAS") + "-" + scope[2] + "-" : "";
37
+ return isSubtype(abap.Classes[prefix + name] || abap.Classes[name], cname);
38
+ }
39
+ else if (cname === "OBJECT") {
40
+ return true;
41
+ }
42
+ // an interface is not on the prototype chain of the classes implementing it
43
+ return obj instanceof cname || isSubtype(obj.constructor, cname);
6
44
  }
7
45
  //# sourceMappingURL=instance_of.js.map
@@ -8,5 +8,6 @@ export interface IAssignInput {
8
8
  dynamicSource?: ICharacter;
9
9
  casting?: boolean;
10
10
  component?: string | ICharacter;
11
+ keepSubrc?: boolean;
11
12
  }
12
13
  export declare function assign(input: IAssignInput): void;
@@ -187,7 +187,9 @@ function assign(input) {
187
187
  }
188
188
  input.target.assign(input.source);
189
189
  }
190
- abap.builtin.sy.get().subrc.set(0);
190
+ if (input.keepSubrc !== true) {
191
+ abap.builtin.sy.get().subrc.set(0);
192
+ }
191
193
  }
192
194
  }
193
195
  }
@@ -4,7 +4,6 @@ exports.cast = cast;
4
4
  const throw_error_1 = require("../throw_error");
5
5
  const types_1 = require("../types");
6
6
  // todo, field symbols as input?
7
- // todo, local classes?
8
7
  // check with javascript instanceof?
9
8
  // handling interfaces?
10
9
  // todo: remove the "async"
@@ -34,6 +33,14 @@ async function cast(target, source) {
34
33
  // todo, for unit testing,
35
34
  targetClass = abap.Classes["PROG-ZFOOBAR-" + targetName];
36
35
  }
36
+ if (targetClass === undefined && target instanceof types_1.ABAPObject) {
37
+ // local class, RTTI name "\CLASS-POOL=ZCL_FOO\CLASS=LCL_BAR" is registered as "CLAS-ZCL_FOO-LCL_BAR"
38
+ const match = /^\\(CLASS-POOL|PROGRAM)=([^\\]+)\\CLASS=(.+)$/.exec(target.getRTTIName()?.toUpperCase() || "");
39
+ if (match) {
40
+ const prefix = match[1] === "PROGRAM" ? "PROG" : "CLAS";
41
+ targetClass = abap.Classes[prefix + "-" + match[2] + "-" + match[3]];
42
+ }
43
+ }
37
44
  if (targetClass?.INTERNAL_TYPE === "CLAS") {
38
45
  // using "instanceof" is probably wrong in some cases,
39
46
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof
@@ -13,6 +13,7 @@ export declare class FieldSymbol {
13
13
  constructor(type?: PointerType);
14
14
  clone(): void;
15
15
  getQualifiedName(): any;
16
+ getRTTIName(): string | undefined;
16
17
  assign(pointer: PointerType): void;
17
18
  getType(): PointerType;
18
19
  setCasting(): void;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FieldSymbol = void 0;
4
+ const abap_object_1 = require("./abap_object");
4
5
  const table_1 = require("./table");
5
6
  const string_1 = require("./string");
6
7
  const hex_1 = require("./hex");
@@ -24,6 +25,9 @@ class FieldSymbol {
24
25
  // @ts-ignore
25
26
  return this.type.getQualifiedName();
26
27
  }
28
+ getRTTIName() {
29
+ return this.type instanceof abap_object_1.ABAPObject ? this.type.getRTTIName() : undefined;
30
+ }
27
31
  assign(pointer) {
28
32
  this.pointer = pointer;
29
33
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/runtime",
3
- "version": "2.13.100",
3
+ "version": "2.14.1",
4
4
  "description": "Transpiler - Runtime",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/src/index.d.ts",