@abaplint/transpiler 2.10.27 → 2.10.29

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.
@@ -5,6 +5,7 @@ const core_1 = require("@abaplint/core");
5
5
  const traversal_1 = require("../traversal");
6
6
  const method_call_param_1 = require("./method_call_param");
7
7
  const chunk_1 = require("../chunk");
8
+ const feature_flags_1 = require("../feature_flags");
8
9
  class MethodCallTranspiler {
9
10
  transpile(node, traversal) {
10
11
  const nameToken = node.findDirectExpression(core_1.Expressions.MethodName)?.getFirstToken();
@@ -22,6 +23,10 @@ class MethodCallTranspiler {
22
23
  if (m?.name && traversal.isBuiltinMethod(nameToken) === false) {
23
24
  name = m.name.toLowerCase() + "(";
24
25
  }
26
+ if (feature_flags_1.FEATURE_FLAGS.private === true
27
+ && m?.def.getVisibility() === core_1.Visibility.Private) {
28
+ name = "#" + name;
29
+ }
25
30
  const step = node.findDirectExpression(core_1.Expressions.MethodCallParam);
26
31
  if (step === undefined) {
27
32
  throw new Error("MethodCallTranspiler, unexpected node");
@@ -0,0 +1,3 @@
1
+ export declare const FEATURE_FLAGS: {
2
+ private: boolean;
3
+ };
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FEATURE_FLAGS = void 0;
4
+ exports.FEATURE_FLAGS = {
5
+ private: true,
6
+ };
7
+ //# sourceMappingURL=feature_flags.js.map
@@ -23,6 +23,7 @@ static INTERNAL_TYPE = 'CLAS';
23
23
  static INTERNAL_NAME = '${traversal.buildInternalName(token.getStr(), def)}';
24
24
  static IMPLEMENTED_INTERFACES = [${this.findImplementedByClass(traversal, def, scope).map(e => `"` + e.toUpperCase() + `"`).join(",")}];
25
25
  static ATTRIBUTES = {${traversal.buildAttributes(def, scope).join(",\n")}};
26
+ static FRIENDS_ACCESS_STATIC = {}; // todo
26
27
  static METHODS = {${traversal.buildMethods(def, scope).join(",\n")}};`, node, traversal);
27
28
  }
28
29
  findImplementedInterface(traversal, def, scope) {
@@ -8,6 +8,7 @@ const traversal_1 = require("../traversal");
8
8
  const expressions_1 = require("../expressions");
9
9
  const chunk_1 = require("../chunk");
10
10
  const unique_identifier_1 = require("../unique_identifier");
11
+ const feature_flags_1 = require("../feature_flags");
11
12
  class MethodImplementationTranspiler {
12
13
  transpile(node, traversal) {
13
14
  const token = node.findFirstExpression(abaplint.Expressions.MethodName).getFirstToken();
@@ -116,15 +117,21 @@ class MethodImplementationTranspiler {
116
117
  methodName = a.getComponent().replace("~", "$").toLowerCase();
117
118
  }
118
119
  }
120
+ // https://github.com/tc39/proposal-class-fields
121
+ let isPrivate = "";
122
+ if (feature_flags_1.FEATURE_FLAGS.private === true
123
+ && method?.getVisibility() === abaplint.Visibility.Private) {
124
+ isPrivate = "#";
125
+ }
119
126
  if (method && method.isStatic()) {
120
127
  // in ABAP static methods can be called with instance arrows, "->"
121
128
  const className = scope.getParent()?.getIdentifier().sname?.toLowerCase();
122
- staticMethod = "async " + traversal_1.Traversal.escapeNamespace(methodName) + "(" + unique + ") {\n" +
129
+ staticMethod = "async " + isPrivate + traversal_1.Traversal.escapeNamespace(methodName) + "(" + unique + ") {\n" +
123
130
  "return " + traversal_1.Traversal.escapeNamespace(className) + "." + traversal_1.Traversal.escapeNamespace(methodName) + "(" + unique + ");\n" +
124
131
  "}\n" + "static ";
125
132
  }
126
133
  unique_identifier_1.UniqueIdentifier.resetIndexBackup();
127
- const str = staticMethod + "async " + traversal_1.Traversal.escapeNamespace(methodName) + "(" + unique + ") {" + after;
134
+ const str = staticMethod + "async " + isPrivate + traversal_1.Traversal.escapeNamespace(methodName) + "(" + unique + ") {" + after;
128
135
  return new chunk_1.Chunk().append(str, node, traversal);
129
136
  }
130
137
  /////////////////////////////
@@ -25,6 +25,7 @@ class ${className?.toLowerCase()} {
25
25
  static IMPLEMENTED_INTERFACES = [];
26
26
  static INTERNAL_NAME = 'ABSTRACT_CLASS_INTERNAL_NAME';
27
27
  static ATTRIBUTES = {};
28
+ static FRIENDS_ACCESS_STATIC = {};
28
29
  async constructor_() {
29
30
  this.me = new abap.types.ABAPObject();
30
31
  this.me.set(this);
@@ -39,6 +39,8 @@ export declare class Traversal {
39
39
  isTypePool(token: abaplint.Token): string | undefined;
40
40
  isInterfaceAttribute(token: abaplint.Token): string | undefined;
41
41
  private findReadOrWriteReference;
42
+ private buildThisAttributes;
43
+ private buildFriendsAccess;
42
44
  buildConstructorContents(scope: abaplint.ISpaghettiScopeNode | undefined, def: abaplint.IClassDefinition): string;
43
45
  findInterfaceDefinition(name: string, scope: abaplint.ISpaghettiScopeNode | undefined): abaplint.IInterfaceDefinition | undefined;
44
46
  findTable(name: string): abaplint.Objects.Table | undefined;
@@ -9,6 +9,7 @@ const transpile_types_1 = require("./transpile_types");
9
9
  const chunk_1 = require("./chunk");
10
10
  const expressions_1 = require("./expressions");
11
11
  const keywords_1 = require("./keywords");
12
+ const feature_flags_1 = require("./feature_flags");
12
13
  class Traversal {
13
14
  constructor(spaghetti, file, obj, reg, options) {
14
15
  this.scopeCache = undefined;
@@ -376,15 +377,8 @@ class Traversal {
376
377
  }
377
378
  return undefined;
378
379
  }
379
- buildConstructorContents(scope, def) {
380
+ buildThisAttributes(def, cName) {
380
381
  let ret = "";
381
- if (def.getSuperClass() !== undefined || def.getName().toUpperCase() === "CX_ROOT") {
382
- ret += "super();\n";
383
- }
384
- const cName = Traversal.escapeNamespace(def.getName().toLowerCase());
385
- ret += `this.me = new abap.types.ABAPObject();
386
- this.me.set(this);
387
- this.INTERNAL_ID = abap.internalIdCounter++;\n`;
388
382
  for (const a of def.getAttributes()?.getAll() || []) {
389
383
  const escaped = Traversal.escapeNamespace(a.getName().toLowerCase());
390
384
  if (a.getMeta().includes("static" /* abaplint.IdentifierMeta.Static */) === true) {
@@ -395,6 +389,39 @@ this.INTERNAL_ID = abap.internalIdCounter++;\n`;
395
389
  ret += name + " = " + new transpile_types_1.TranspileTypes().toType(a.getType()) + ";\n";
396
390
  ret += this.setValues(a, name);
397
391
  }
392
+ return ret;
393
+ }
394
+ buildFriendsAccess(def, hasSuperClass) {
395
+ let ret = "this.FRIENDS_ACCESS_INSTANCE = {\n";
396
+ if (hasSuperClass === true) {
397
+ ret += `"SUPER": sup.FRIENDS_ACCESS_INSTANCE,\n`;
398
+ }
399
+ for (const a of def.getMethodDefinitions()?.getAll() || []) {
400
+ const name = a.getName().toLowerCase();
401
+ if (name === "constructor" || a.isStatic() === true) {
402
+ continue;
403
+ }
404
+ let privateHash = "";
405
+ if (feature_flags_1.FEATURE_FLAGS.private === true && a.getVisibility() === abaplint.Visibility.Private) {
406
+ privateHash = "#";
407
+ }
408
+ const methodName = privateHash + Traversal.escapeNamespace(name.replace("~", "$"));
409
+ ret += `"${name.replace("~", "$")}": this.${methodName}.bind(this),\n`;
410
+ }
411
+ ret += "};\n";
412
+ return ret;
413
+ }
414
+ buildConstructorContents(scope, def) {
415
+ let ret = "";
416
+ if (def.getSuperClass() !== undefined || def.getName().toUpperCase() === "CX_ROOT") {
417
+ ret += "const sup = super();\n";
418
+ }
419
+ const cName = Traversal.escapeNamespace(def.getName().toLowerCase());
420
+ ret += `this.me = new abap.types.ABAPObject();
421
+ this.me.set(this);
422
+ this.INTERNAL_ID = abap.internalIdCounter++;\n`;
423
+ ret += this.buildFriendsAccess(def, def.getSuperClass() !== undefined);
424
+ ret += this.buildThisAttributes(def, cName);
398
425
  // attributes from directly implemented interfaces(not interfaces implemented in super classes)
399
426
  for (const i of def.getImplementing()) {
400
427
  ret += this.dataFromInterfaces(i.name, scope, cName);
@@ -225,10 +225,13 @@ async function run() {
225
225
  continue;
226
226
  }
227
227
  ret += ` {\n const test = await (new ${lc}()).constructor_();\n`;
228
+ // todo, some refactoring here,
228
229
  ret += ` if (test.setup) await test.setup();\n`;
230
+ ret += ` if (test.FRIENDS_ACCESS_INSTANCE.setup) await test.FRIENDS_ACCESS_INSTANCE.setup();\n`;
231
+ ret += ` if (test.FRIENDS_ACCESS_INSTANCE.SUPER && test.FRIENDS_ACCESS_INSTANCE.SUPER.setup) await test.FRIENDS_ACCESS_INSTANCE.SUPER.setup();\n`;
229
232
  ret += ` console.log("${st.obj.getName()}: running ${lc}->${m}");\n`;
230
233
  ret += ` meth = locl.addMethod("${m}");\n`;
231
- ret += ` await test.${m}();\n`;
234
+ ret += ` await test.FRIENDS_ACCESS_INSTANCE.${m}();\n`;
232
235
  ret += ` meth.pass();\n`;
233
236
  ret += ` if (test.teardown) await test.teardown();\n`;
234
237
  ret += ` }\n`;
@@ -236,59 +239,6 @@ async function run() {
236
239
  ret += ` if (${lc}.class_teardown) await ${lc}.class_teardown();\n`;
237
240
  ret += ` }\n`;
238
241
  }
239
- /*
240
- for (const obj of reg.getObjects()) {
241
- if (reg.isDependency(obj) || !(obj instanceof abaplint.Objects.Class)) {
242
- continue;
243
- }
244
- ret += `// --------------------------------------------\n`;
245
- ret += ` clas = unit.addObject("${obj.getName()}");\n`;
246
- for (const file of obj.getABAPFiles()) {
247
- for (const def of file.getInfo().listClassDefinitions()) {
248
- if (def.isForTesting === false
249
- || def.isGlobal === true
250
- || def.methods.length === 0
251
- || def.isAbstract === true) {
252
- // todo, fix, there might be global test methods
253
- continue;
254
- }
255
- const hasTestFile = obj.getFiles().some(f => { return f.getFilename().includes(".testclasses."); });
256
- if (hasTestFile === false) {
257
- break;
258
- }
259
- ret += ` {
260
- const {${def.name}} = await import("./${this.escapeNamespace(obj.getName().toLowerCase())}.${obj.getType().toLowerCase()}.testclasses.mjs");
261
- locl = clas.addTestClass("${def.name}");
262
- if (${def.name}.class_setup) await ${def.name}.class_setup();\n`;
263
-
264
- for (const m of def.methods) {
265
- if (m.isForTesting === false) {
266
- continue;
267
- }
268
- const skipThis = (skip || []).some(a => a.object === obj.getName() && a.class === def.name && a.method === m.name);
269
- if (skipThis) {
270
- ret += ` console.log('${obj.getName()}: running ${def.name}->${m.name}, skipped');\n`;
271
- ret += ` meth = locl.addMethod("${m.name}");\n`;
272
- ret += ` meth.skip();\n`;
273
- continue;
274
- }
275
-
276
- ret += ` {\n const test = await (new ${def.name}()).constructor_();\n`;
277
- ret += ` if (test.setup) await test.setup();\n`;
278
- ret += ` console.log("${obj.getName()}: running ${def.name}->${m.name}");\n`;
279
- ret += ` meth = locl.addMethod("${m.name}");\n`;
280
- ret += ` await test.${m.name}();\n`;
281
- ret += ` meth.pass();\n`;
282
- ret += ` if (test.teardown) await test.teardown();\n`;
283
- ret += ` }\n`;
284
- }
285
-
286
- ret += ` if (${def.name}.class_teardown) await ${def.name}.class_teardown();\n`;
287
- ret += ` }\n`;
288
- }
289
- }
290
- }
291
- */
292
242
  ret += `// -------------------END-------------------
293
243
  fs.writeFileSync(__dirname + path.sep + "_output.xml", unit.xUnitXML());
294
244
  } catch (e) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abaplint/transpiler",
3
- "version": "2.10.27",
3
+ "version": "2.10.29",
4
4
  "description": "Transpiler",
5
5
  "main": "build/src/index.js",
6
6
  "typings": "build/src/index.d.ts",