@abaplint/transpiler-cli 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.
package/build/bundle.js CHANGED
@@ -240,6 +240,7 @@ class FileOperations {
240
240
  return limit(async () => {
241
241
  // read as latin1, written as latin1: anything else re-encodes the
242
242
  // bytes on the way out and undoes the careful read
243
+ await fsPromises.mkdir(path.dirname(file.path), { recursive: true });
243
244
  await fsPromises.writeFile(file.path, file.contents, this.isBinaryFilename(file.path) ? { encoding: "latin1" } : undefined);
244
245
  });
245
246
  });
@@ -315,16 +316,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
315
316
  Object.defineProperty(exports, "__esModule", ({ value: true }));
316
317
  const fs = __importStar(__webpack_require__(/*! fs */ "fs"));
317
318
  const path = __importStar(__webpack_require__(/*! path */ "path"));
318
- const childProcess = __importStar(__webpack_require__(/*! child_process */ "child_process"));
319
- const os = __importStar(__webpack_require__(/*! os */ "os"));
320
- const module_1 = __webpack_require__(/*! module */ "module");
321
319
  const progress_1 = __importDefault(__webpack_require__(/*! progress */ "./node_modules/progress/index.js"));
322
320
  const Transpiler = __importStar(__webpack_require__(/*! @abaplint/transpiler */ "./node_modules/@abaplint/transpiler/build/src/index.js"));
323
- const abaplint = __importStar(__webpack_require__(/*! @abaplint/core */ "./node_modules/@abaplint/core/build/src/index.js"));
324
321
  const config_1 = __webpack_require__(/*! ./config */ "./build/config.js");
325
322
  const file_operations_1 = __webpack_require__(/*! ./file_operations */ "./build/file_operations.js");
326
- const git_clone_1 = __webpack_require__(/*! ./git_clone */ "./build/git_clone.js");
327
- const lib_folder_1 = __webpack_require__(/*! ./lib_folder */ "./build/lib_folder.js");
323
+ const libraries_1 = __webpack_require__(/*! ./libraries */ "./build/libraries.js");
324
+ const write_objects_1 = __webpack_require__(/*! ./write_objects */ "./build/write_objects.js");
328
325
  class Progress {
329
326
  bar;
330
327
  set(total, _text) {
@@ -335,142 +332,30 @@ class Progress {
335
332
  this.bar.render();
336
333
  }
337
334
  }
338
- async function loadLib(config) {
339
- const files = [];
340
- for (const lib of config.libs || []) {
341
- let dir = "";
342
- let cleanupFolder = false;
343
- const folder = (0, lib_folder_1.resolveLibFolder)(lib.folder, process.cwd());
344
- if (folder !== undefined && fs.existsSync(folder)) {
345
- console.log("From folder: " + folder);
346
- dir = folder;
347
- }
348
- else {
349
- if (lib.url === undefined || lib.url === "") {
350
- if (folder === undefined) {
351
- throw new Error("Library must define a non-empty url or an existing folder");
352
- }
353
- throw new Error("Library folder not found: " + folder);
354
- }
355
- console.log("Clone: " + lib.url);
356
- dir = fs.mkdtempSync(path.join(os.tmpdir(), "abap_transpile-"));
357
- const args = (0, git_clone_1.buildGitCloneArguments)(lib.url);
358
- childProcess.execFileSync("git", args, { cwd: dir, stdio: "inherit" });
359
- cleanupFolder = true;
360
- }
361
- let patterns = ["/src/**"];
362
- if (lib.files !== undefined && typeof lib.files === "string" && lib.files !== "") {
363
- patterns = [lib.files];
364
- }
365
- else if (Array.isArray(lib.files)) {
366
- patterns = lib.files;
367
- }
368
- const excludeFilters = (lib.exclude_filter ?? []).map(pattern => new RegExp(pattern, "i"));
369
- const filesToRead = [];
370
- for (const pattern of patterns) {
371
- for (const filename of file_operations_1.FileOperations.globSync(dir + pattern)) {
372
- if (filename.endsWith(".clas.testclasses.abap")) {
373
- continue;
374
- }
375
- else if (excludeFilters.length > 0 && excludeFilters.some(a => a.test(filename)) === true) {
376
- continue;
377
- }
378
- filesToRead.push(filename);
379
- }
380
- }
381
- files.push(...await file_operations_1.FileOperations.readAllFiles(filesToRead, ""));
382
- console.log("\t" + filesToRead.length + " files added from lib");
383
- if (cleanupFolder === true) {
384
- file_operations_1.FileOperations.deleteFolderRecursive(dir);
385
- }
386
- }
387
- return files;
388
- }
389
- async function writeObjects(outputFiles, config, outputFolder, files) {
390
- const writeSourceMaps = config.write_source_map || false;
391
- const filesToWrite = [];
392
- for (const output of outputFiles) {
393
- const type = output.object.type.toUpperCase();
394
- let contents = output.chunk.getCode();
395
- // PROG output gets a runtime bootstrap line prepended, which shifts every
396
- // generated line down by one - the source map must account for this offset
397
- let generatedLineOffset = 0;
398
- if (type === "PROG") {
399
- // hmm, will this work for INCLUDEs ?
400
- contents = `if (!globalThis.abap) await import("./_init.mjs");\n` + contents;
401
- generatedLineOffset = 1;
402
- }
403
- if (writeSourceMaps === true
404
- && (type === "PROG" || type === "FUGR" || type === "CLAS")) {
405
- const name = output.filename + ".map";
406
- // SourceMappingUrl needs to be percent-encoded, ref https://github.com/microsoft/TypeScript/issues/40951
407
- contents = contents + `\n//# sourceMappingURL=` + name.replace(/%/g, "%25").replace(/#/g, "%23");
408
- // map the bare abap filename each mapping carries to its path on disk;
409
- // source map "sources" are URLs, so always forward slashes, also on Windows
410
- const sourcePaths = {};
411
- for (const f of files) {
412
- if (f.relative === undefined) {
413
- continue;
414
- }
415
- const rel = f.relative.split(path.sep).join("/");
416
- sourcePaths[f.filename] = rel === "" ? f.filename : `${rel}/${f.filename}`;
417
- }
418
- const map = output.chunk.getMap(output.filename, { generatedLineOffset, sourcePaths });
419
- filesToWrite.push({ path: outputFolder + path.sep + name, contents: map });
420
- }
421
- filesToWrite.push({ path: outputFolder + path.sep + output.filename, contents });
422
- }
423
- await file_operations_1.FileOperations.writeFiles(filesToWrite);
424
- }
425
- const PLUGIN_MODULE = "@abaplint/transpiler-extras";
426
- function loadPlugin() {
427
- // createRequire so the plugin resolves from the project consuming the CLI, also after webpacking
428
- const projectRequire = (0, module_1.createRequire)(path.join(process.cwd(), "package.json"));
429
- try {
430
- projectRequire.resolve(PLUGIN_MODULE);
431
- }
432
- catch {
433
- // plugin package not installed
434
- return undefined;
435
- }
436
- const plugin = projectRequire(PLUGIN_MODULE).plugin;
437
- if (plugin === undefined) {
438
- throw new Error(PLUGIN_MODULE + " does not export a plugin");
439
- }
440
- console.log("Plugin loaded: " + PLUGIN_MODULE + ", object types: " + plugin.objectTypes().join(", "));
441
- console.log("Note this requires license for commercial use");
442
- return plugin;
443
- }
444
335
  async function build(config, files) {
445
- const libFiles = await loadLib(config);
336
+ const libraries = await (0, libraries_1.loadLibraries)(config);
446
337
  const options = { ...config.options };
447
338
  if (config.write_source_map !== true) {
448
339
  // Do not pay to allocate and copy mappings that the CLI will not write.
449
340
  options.ignoreSourceMap = true;
450
341
  }
451
- const t = new Transpiler.Transpiler(options, loadPlugin());
452
- const reg = new abaplint.Registry();
453
- for (const f of files) {
454
- reg.addFile(new abaplint.MemoryFile(f.filename, f.contents));
455
- }
456
- for (const l of libFiles) {
457
- reg.addDependency(new abaplint.MemoryFile(l.filename, l.contents));
458
- }
459
- const output = await t.run(reg, new Progress());
460
- return output;
342
+ const t = new Transpiler.Transpiler(options);
343
+ const { reg, folders, sources } = (0, libraries_1.libraryRegistry)(files, libraries, config.skip_duplicate_dependencies);
344
+ const output = await t.run(reg, new Progress(), folders);
345
+ return { output, sources };
461
346
  }
462
347
  async function run() {
463
348
  console.log("Transpiler CLI");
464
349
  const config = config_1.TranspilerConfig.find(process.argv[2]);
465
350
  const files = await file_operations_1.FileOperations.loadFiles(config);
466
351
  console.log("\nBuilding");
467
- const output = await build(config, files);
352
+ const { output, sources } = await build(config, files);
468
353
  console.log("\nOutput");
469
354
  const outputFolder = config.output_folder;
470
355
  if (!fs.existsSync(outputFolder)) {
471
- fs.mkdirSync(outputFolder);
356
+ fs.mkdirSync(outputFolder, { recursive: true });
472
357
  }
473
- await writeObjects(output.objects, config, outputFolder, files);
358
+ await (0, write_objects_1.writeObjects)(output.objects, config, sources);
474
359
  console.log(output.objects.length + " objects written to disk");
475
360
  if (config.write_unit_tests === true) {
476
361
  // breaking change? rename this output file,
@@ -553,6 +438,276 @@ function resolveLibFolder(folder, cwd) {
553
438
 
554
439
  /***/ },
555
440
 
441
+ /***/ "./build/libraries.js"
442
+ /*!****************************!*\
443
+ !*** ./build/libraries.js ***!
444
+ \****************************/
445
+ (__unused_webpack_module, exports, __webpack_require__) {
446
+
447
+ "use strict";
448
+
449
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
450
+ if (k2 === undefined) k2 = k;
451
+ var desc = Object.getOwnPropertyDescriptor(m, k);
452
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
453
+ desc = { enumerable: true, get: function() { return m[k]; } };
454
+ }
455
+ Object.defineProperty(o, k2, desc);
456
+ }) : (function(o, m, k, k2) {
457
+ if (k2 === undefined) k2 = k;
458
+ o[k2] = m[k];
459
+ }));
460
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
461
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
462
+ }) : function(o, v) {
463
+ o["default"] = v;
464
+ });
465
+ var __importStar = (this && this.__importStar) || (function () {
466
+ var ownKeys = function(o) {
467
+ ownKeys = Object.getOwnPropertyNames || function (o) {
468
+ var ar = [];
469
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
470
+ return ar;
471
+ };
472
+ return ownKeys(o);
473
+ };
474
+ return function (mod) {
475
+ if (mod && mod.__esModule) return mod;
476
+ var result = {};
477
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
478
+ __setModuleDefault(result, mod);
479
+ return result;
480
+ };
481
+ })();
482
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
483
+ exports.libraryNames = libraryNames;
484
+ exports.loadLibraries = loadLibraries;
485
+ exports.libraryRegistry = libraryRegistry;
486
+ const fs = __importStar(__webpack_require__(/*! fs */ "fs"));
487
+ const path = __importStar(__webpack_require__(/*! path */ "path"));
488
+ const childProcess = __importStar(__webpack_require__(/*! child_process */ "child_process"));
489
+ const os = __importStar(__webpack_require__(/*! os */ "os"));
490
+ const abaplint = __importStar(__webpack_require__(/*! @abaplint/core */ "./node_modules/@abaplint/core/build/src/index.js"));
491
+ const file_operations_1 = __webpack_require__(/*! ./file_operations */ "./build/file_operations.js");
492
+ const git_clone_1 = __webpack_require__(/*! ./git_clone */ "./build/git_clone.js");
493
+ const lib_folder_1 = __webpack_require__(/*! ./lib_folder */ "./build/lib_folder.js");
494
+ function libraryNames(libs) {
495
+ const used = new Set(["project"]);
496
+ return libs.map(lib => {
497
+ const source = (lib.url || lib.folder || "").replace(/\\/g, "/").replace(/\/+$/, "");
498
+ const name = lib.name ?? source.substring(Math.max(source.lastIndexOf("/"), source.lastIndexOf(":")) + 1)
499
+ .replace(/\.git$/i, "");
500
+ if (typeof name !== "string" || name.length === 0 || name === "." || name === ".."
501
+ || /[<>:"/\\|?*\u0000-\u001f]/.test(name) || /[. ]$/.test(name)
502
+ || /^(con|prn|aux|nul|com[1-9¹²³]|lpt[1-9¹²³])(\.|$)/i.test(name)) {
503
+ throw new Error("Invalid library name: " + JSON.stringify(name) + ". Set libs[].name to a valid folder name.");
504
+ }
505
+ if (used.has(name.toLowerCase())) {
506
+ throw new Error("Duplicate or reserved library name: " + name + ". Set a different libs[].name.");
507
+ }
508
+ used.add(name.toLowerCase());
509
+ return name;
510
+ });
511
+ }
512
+ async function loadLibraries(config) {
513
+ const libs = config.libs || [];
514
+ const names = libraryNames(libs);
515
+ const result = [];
516
+ for (const [index, lib] of libs.entries()) {
517
+ let dir;
518
+ let cleanupFolder = false;
519
+ const folder = (0, lib_folder_1.resolveLibFolder)(lib.folder, process.cwd());
520
+ if (folder !== undefined && fs.existsSync(folder)) {
521
+ console.log("From folder: " + folder);
522
+ dir = folder;
523
+ }
524
+ else {
525
+ if (!lib.url) {
526
+ throw new Error(folder === undefined
527
+ ? "Library must define a non-empty url or an existing folder"
528
+ : "Library folder not found: " + folder);
529
+ }
530
+ console.log("Clone: " + lib.url);
531
+ dir = fs.mkdtempSync(path.join(os.tmpdir(), "abap_transpile-"));
532
+ cleanupFolder = true;
533
+ }
534
+ try {
535
+ if (cleanupFolder) {
536
+ childProcess.execFileSync("git", (0, git_clone_1.buildGitCloneArguments)(lib.url), { cwd: dir, stdio: "inherit" });
537
+ }
538
+ const patterns = typeof lib.files === "string" && lib.files !== "" ? [lib.files]
539
+ : Array.isArray(lib.files) ? lib.files : ["/src/**"];
540
+ const excludeFilters = (lib.exclude_filter ?? []).map(pattern => new RegExp(pattern, "i"));
541
+ const filesToRead = new Set();
542
+ for (const pattern of patterns) {
543
+ for (const filename of file_operations_1.FileOperations.globSync(dir + pattern)) {
544
+ if (filename.endsWith(".clas.testclasses.abap") || excludeFilters.some(filter => filter.test(filename))) {
545
+ continue;
546
+ }
547
+ filesToRead.add(filename);
548
+ }
549
+ }
550
+ const files = await file_operations_1.FileOperations.readAllFiles([...filesToRead], config.output_folder);
551
+ result.push({ name: names[index], files });
552
+ console.log("\t" + files.length + " files added from lib");
553
+ }
554
+ finally {
555
+ if (cleanupFolder) {
556
+ file_operations_1.FileOperations.deleteFolderRecursive(dir);
557
+ }
558
+ }
559
+ }
560
+ return result;
561
+ }
562
+ function libraryRegistry(files, libraries, skipDuplicateDependencies = false) {
563
+ const reg = new abaplint.Registry();
564
+ const folders = new Map();
565
+ const objects = new Map();
566
+ const sources = new Map();
567
+ // Libraries first: addFile() then replaces a dependency object with the project's object.
568
+ for (const lib of libraries) {
569
+ const skipped = new Set();
570
+ for (const file of lib.files) {
571
+ const memory = new abaplint.MemoryFile(file.filename, file.contents);
572
+ const type = memory.getObjectType()?.toUpperCase();
573
+ if (type === undefined || file.filename.split(".").length <= 2) {
574
+ continue;
575
+ }
576
+ const key = type + ":" + memory.getObjectName().toUpperCase();
577
+ const owner = objects.get(key);
578
+ // abapGit repeats package.devc.xml across repositories; the registry keeps the last copy.
579
+ if (key !== "DEVC:PACKAGE" && owner !== undefined && owner !== lib.name) {
580
+ if (skipDuplicateDependencies === true) {
581
+ if (!skipped.has(key)) {
582
+ console.warn("Skipping duplicate dependency object " + key + " in " + lib.name + "; using " + owner);
583
+ skipped.add(key);
584
+ }
585
+ // Skip every file of the losing object, including locals, metadata, and binary assets.
586
+ continue;
587
+ }
588
+ throw new Error("Ambiguous dependency object " + key + " in " + owner + " and " + lib.name);
589
+ }
590
+ objects.set(key, lib.name);
591
+ reg.addDependency(memory);
592
+ folders.set(file.filename.toLowerCase(), lib.name);
593
+ sources.set(file.filename.toLowerCase(), file);
594
+ }
595
+ }
596
+ for (const file of files) {
597
+ reg.addFile(new abaplint.MemoryFile(file.filename, file.contents));
598
+ folders.set(file.filename.toLowerCase(), "project");
599
+ sources.set(file.filename.toLowerCase(), file);
600
+ }
601
+ return { reg, folders, sources: [...sources.values()] };
602
+ }
603
+ //# sourceMappingURL=libraries.js.map
604
+
605
+ /***/ },
606
+
607
+ /***/ "./build/write_objects.js"
608
+ /*!********************************!*\
609
+ !*** ./build/write_objects.js ***!
610
+ \********************************/
611
+ (__unused_webpack_module, exports, __webpack_require__) {
612
+
613
+ "use strict";
614
+
615
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
616
+ if (k2 === undefined) k2 = k;
617
+ var desc = Object.getOwnPropertyDescriptor(m, k);
618
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
619
+ desc = { enumerable: true, get: function() { return m[k]; } };
620
+ }
621
+ Object.defineProperty(o, k2, desc);
622
+ }) : (function(o, m, k, k2) {
623
+ if (k2 === undefined) k2 = k;
624
+ o[k2] = m[k];
625
+ }));
626
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
627
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
628
+ }) : function(o, v) {
629
+ o["default"] = v;
630
+ });
631
+ var __importStar = (this && this.__importStar) || (function () {
632
+ var ownKeys = function(o) {
633
+ ownKeys = Object.getOwnPropertyNames || function (o) {
634
+ var ar = [];
635
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
636
+ return ar;
637
+ };
638
+ return ownKeys(o);
639
+ };
640
+ return function (mod) {
641
+ if (mod && mod.__esModule) return mod;
642
+ var result = {};
643
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
644
+ __setModuleDefault(result, mod);
645
+ return result;
646
+ };
647
+ })();
648
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
649
+ exports.writeObjects = writeObjects;
650
+ const path = __importStar(__webpack_require__(/*! path */ "path"));
651
+ const url_1 = __webpack_require__(/*! url */ "url");
652
+ const transpiler_1 = __webpack_require__(/*! @abaplint/transpiler */ "./node_modules/@abaplint/transpiler/build/src/index.js");
653
+ const file_operations_1 = __webpack_require__(/*! ./file_operations */ "./build/file_operations.js");
654
+ async function writeObjects(outputFiles, config, files) {
655
+ const root = path.resolve(config.output_folder);
656
+ const filesToWrite = [];
657
+ const destinations = new Set();
658
+ const sources = new Map(files.map(file => [file.filename.toLowerCase(), file]));
659
+ const add = (filename, contents) => {
660
+ const target = path.resolve(root, filename);
661
+ const relative = path.relative(root, target);
662
+ if (relative === "" || relative.startsWith(".." + path.sep) || relative === ".." || path.isAbsolute(relative)) {
663
+ throw new Error("Output file escapes output_folder: " + filename);
664
+ }
665
+ const key = target.toLowerCase();
666
+ if (destinations.has(key)) {
667
+ throw new Error("Conflicting output file: " + filename);
668
+ }
669
+ destinations.add(key);
670
+ filesToWrite.push({ path: target, contents });
671
+ };
672
+ for (const output of outputFiles) {
673
+ const type = output.object.type.toUpperCase();
674
+ let contents = output.chunk.getCode();
675
+ let generatedLineOffset = 0;
676
+ if (type === "PROG") {
677
+ contents = 'if (!globalThis.abap) await import("' + (0, transpiler_1.importPath)(output.filename, "_init.mjs") + '");\n' + contents;
678
+ generatedLineOffset = 1;
679
+ }
680
+ if (config.write_source_map === true && (type === "PROG" || type === "FUGR" || type === "CLAS")) {
681
+ const name = output.filename + ".map";
682
+ contents += "\n//# sourceMappingURL=" + encodeURIComponent(path.basename(name));
683
+ const sourcePaths = {};
684
+ const sourceContents = {};
685
+ const mapDirectory = path.dirname(path.join(root, name));
686
+ for (const filename of new Set(output.chunk.mappings.map(mapping => mapping.source))) {
687
+ const file = sources.get(filename.toLowerCase());
688
+ if (file === undefined) {
689
+ continue;
690
+ }
691
+ if (file.relative !== undefined) {
692
+ const source = path.resolve(root, file.relative, file.filename);
693
+ const relative = path.relative(mapDirectory, source);
694
+ // Sources on another Windows drive cannot be expressed as relative paths.
695
+ sourcePaths[filename] = path.isAbsolute(relative) ? (0, url_1.pathToFileURL)(source).href
696
+ : relative.split(path.sep).map(segment => encodeURIComponent(segment)).join("/");
697
+ }
698
+ // Include sources for local and cloned libraries; clones are removed before emission.
699
+ sourceContents[filename] = file.contents;
700
+ }
701
+ add(name, output.chunk.getMap(path.basename(output.filename), { generatedLineOffset, sourcePaths, sourceContents }));
702
+ }
703
+ add(output.filename, contents);
704
+ }
705
+ await file_operations_1.FileOperations.writeFiles(filesToWrite);
706
+ }
707
+ //# sourceMappingURL=write_objects.js.map
708
+
709
+ /***/ },
710
+
556
711
  /***/ "./node_modules/@abaplint/core/build/src/abap/1_lexer/lexer.js"
557
712
  /*!*********************************************************************!*\
558
713
  !*** ./node_modules/@abaplint/core/build/src/abap/1_lexer/lexer.js ***!
@@ -10941,7 +11096,7 @@ class StringTemplateFormatting extends combi_1.Expression {
10941
11096
  const alpha = (0, combi_1.ver)(version_1.Release.v740sp02, (0, combi_1.seq)("ALPHA =", alphaOptions), { also: combi_1.AlsoIn.OpenABAP });
10942
11097
  const xsd = (0, combi_1.ver)(version_1.Release.v740sp02, (0, combi_1.seq)("XSD =", zeroXSDOptions));
10943
11098
  const country = (0, combi_1.seq)("COUNTRY =", _1.Source);
10944
- const formatting = (0, combi_1.altPrio)((0, combi_1.seq)("TIME =", dateTimeOptions), (0, combi_1.seq)("DATE =", dateTimeOptions), (0, combi_1.seq)("CASE =", caseOptions), (0, combi_1.seq)("EXPONENT", _1.Source), (0, combi_1.seq)("ZERO =", zeroXSDOptions), xsd, (0, combi_1.seq)("STYLE =", styleOptions), (0, combi_1.seq)("CURRENCY =", _1.Source), (0, combi_1.per)(sign, number, decimals, width, pad, alpha, align, country), (0, combi_1.per)(timezone, timestamp));
11099
+ const formatting = (0, combi_1.altPrio)((0, combi_1.seq)("TIME =", dateTimeOptions), (0, combi_1.seq)("DATE =", dateTimeOptions), (0, combi_1.seq)("CASE =", caseOptions), (0, combi_1.seq)("ZERO =", zeroXSDOptions), xsd, (0, combi_1.seq)("STYLE =", styleOptions), (0, combi_1.seq)("CURRENCY =", _1.Source), (0, combi_1.per)(sign, number, decimals, width, pad, alpha, align, country, (0, combi_1.seq)("EXPONENT =", _1.Source)), (0, combi_1.per)(timezone, timestamp));
10945
11100
  return formatting;
10946
11101
  }
10947
11102
  }
@@ -30673,12 +30828,15 @@ var __importStar = (this && this.__importStar) || (function () {
30673
30828
  Object.defineProperty(exports, "__esModule", ({ value: true }));
30674
30829
  exports.Compare = void 0;
30675
30830
  const Expressions = __importStar(__webpack_require__(/*! ../../2_statements/expressions */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js"));
30831
+ const nodes_1 = __webpack_require__(/*! ../../nodes */ "./node_modules/@abaplint/core/build/src/abap/nodes/index.js");
30676
30832
  const source_1 = __webpack_require__(/*! ./source */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/source.js");
30677
30833
  const method_call_chain_1 = __webpack_require__(/*! ./method_call_chain */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/method_call_chain.js");
30678
30834
  const source_field_symbol_1 = __webpack_require__(/*! ./source_field_symbol */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/source_field_symbol.js");
30679
30835
  const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
30680
30836
  const basic_1 = __webpack_require__(/*! ../../types/basic */ "./node_modules/@abaplint/core/build/src/abap/types/basic/index.js");
30681
30837
  const _type_utils_1 = __webpack_require__(/*! ../_type_utils */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_type_utils.js");
30838
+ const _builtin_1 = __webpack_require__(/*! ../_builtin */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_builtin.js");
30839
+ const _object_oriented_1 = __webpack_require__(/*! ../_object_oriented */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_object_oriented.js");
30682
30840
  class Compare {
30683
30841
  static runSyntax(node, input) {
30684
30842
  var _a;
@@ -30693,6 +30851,11 @@ class Compare {
30693
30851
  for (const t of node.findDirectExpressions(Expressions.MethodCallChain)) {
30694
30852
  method_call_chain_1.MethodCallChain.runSyntax(t, input);
30695
30853
  }
30854
+ const initialMessage = this.checkInitialOperand(node, input);
30855
+ if (initialMessage !== undefined) {
30856
+ input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), initialMessage));
30857
+ return;
30858
+ }
30696
30859
  const typeUtils = new _type_utils_1.TypeUtils(input.scope);
30697
30860
  const compareOperator = (_a = node.findDirectExpression(Expressions.CompareOperator)) === null || _a === void 0 ? void 0 : _a.concatTokens().toUpperCase();
30698
30861
  if (compareOperator === "CS"
@@ -30716,6 +30879,46 @@ class Compare {
30716
30879
  input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
30717
30880
  }
30718
30881
  }
30882
+ // a built-in function with a character-like result cannot be the operand of IS [NOT] INITIAL,
30883
+ // "Unexpected operator IS" on a system, while one with a numeric result, lines( ), can
30884
+ static checkInitialOperand(node, input) {
30885
+ var _a, _b, _c, _d;
30886
+ if (input.scope.getOpenABAP()) {
30887
+ return undefined;
30888
+ }
30889
+ const tokens = node.getChildren().filter(c => c instanceof nodes_1.TokenNode).map(c => c.getFirstToken().getStr().toUpperCase());
30890
+ if (tokens.includes("IS") === false || tokens[tokens.length - 1] !== "INITIAL") {
30891
+ return undefined;
30892
+ }
30893
+ const chain = (_a = node.findDirectExpression(Expressions.Source)) === null || _a === void 0 ? void 0 : _a.getChildren();
30894
+ // xsdbool( ) and boolc( ) are their own form in the Source grammar, a condition in parentheses
30895
+ const first = (_b = chain === null || chain === void 0 ? void 0 : chain[0]) === null || _b === void 0 ? void 0 : _b.getFirstToken().getStr().toUpperCase();
30896
+ if ((chain === null || chain === void 0 ? void 0 : chain.length) === 4 && chain[0] instanceof nodes_1.TokenNode && (first === "XSDBOOL" || first === "BOOLC")) {
30897
+ return `Built-in function "${chain[0].getFirstToken().getStr()}" cannot be the operand of IS INITIAL`;
30898
+ }
30899
+ if ((chain === null || chain === void 0 ? void 0 : chain.length) !== 1 || !(chain[0] instanceof nodes_1.ExpressionNode) || !(chain[0].get() instanceof Expressions.MethodCallChain)) {
30900
+ return undefined;
30901
+ }
30902
+ const calls = chain[0].getChildren();
30903
+ if (calls.length !== 1 || !(calls[0] instanceof nodes_1.ExpressionNode) || !(calls[0].get() instanceof Expressions.MethodCall)) {
30904
+ return undefined;
30905
+ }
30906
+ const name = (_c = calls[0].findDirectExpression(Expressions.MethodName)) === null || _c === void 0 ? void 0 : _c.concatTokens();
30907
+ const builtin = _builtin_1.BuiltIn.searchBuiltin(name);
30908
+ if (name === undefined || builtin === undefined) {
30909
+ return undefined;
30910
+ }
30911
+ // a method of the same name hides the built-in function
30912
+ const enclosing = input.scope.findClassDefinition(input.scope.getEnclosingClassName());
30913
+ if (enclosing !== undefined && new _object_oriented_1.ObjectOriented(input.scope).searchMethodName(enclosing, name).method !== undefined) {
30914
+ return undefined;
30915
+ }
30916
+ const returning = (_d = builtin.getParameters().getReturning()) === null || _d === void 0 ? void 0 : _d.getType();
30917
+ if (returning instanceof basic_1.StringType || returning instanceof basic_1.CharacterType) {
30918
+ return `Built-in function "${name}" cannot be the operand of IS INITIAL`;
30919
+ }
30920
+ return undefined;
30921
+ }
30719
30922
  }
30720
30923
  exports.Compare = Compare;
30721
30924
  //# sourceMappingURL=compare.js.map
@@ -71077,7 +71280,7 @@ class Registry {
71077
71280
  }
71078
71281
  static abaplintVersion() {
71079
71282
  // magic, see build script "version.js"
71080
- return "2.120.69";
71283
+ return "2.120.71";
71081
71284
  }
71082
71285
  getDDICReferences() {
71083
71286
  return this.ddicReferences;
@@ -73766,7 +73969,7 @@ exports.CDSCheckSyntaxConf = CDSCheckSyntaxConf;
73766
73969
  const KNOWN_QUAN_DATA_ELEMENTS = ["MENGE_D"];
73767
73970
  const KNOWN_CURR_DATA_ELEMENTS = ["BWERT", "DZWERT"];
73768
73971
  // Reserved names, cannot be used as element names, see DDIC table TRESE
73769
- const RESERVED_ELEMENT_NAMES = ["BEGIN", "NUMBER", "POSITION"];
73972
+ const RESERVED_ELEMENT_NAMES = ["BEGIN", "NUMBER", "POSITION", "ZONE", "HANDLER", "SECTION"];
73770
73973
  const MAX_LABEL_LENGTH = 40;
73771
73974
  // Annotations which are not supported in CDS view entities
73772
73975
  const VIEW_ENTITY_FORBIDDEN_ANNOTATIONS = ["Semantics.unitOfMeasure", "Semantics.currencyCode"];
@@ -95476,7 +95679,8 @@ class RedundantConversion {
95476
95679
  key: "redundant_conversion",
95477
95680
  title: "Redundant Conversion",
95478
95681
  shortDescription: `Find redundant CONV expressions`,
95479
- extendedInformation: `Reports CONV expressions whose operand already has the conversion's target type.`,
95682
+ extendedInformation: `Reports CONV expressions whose operand already has the conversion's target type,
95683
+ including the result of a built-in function with a fixed result type, like to_upper( ) or strlen( ).`,
95480
95684
  tags: [_irule_1.RuleTag.Quickfix],
95481
95685
  badExample: `DATA text TYPE string.
95482
95686
  text = CONV string( text ).`,
@@ -95513,7 +95717,8 @@ text = text.`,
95513
95717
  if (structure === undefined) {
95514
95718
  continue;
95515
95719
  }
95516
- for (const source of structure.findAllExpressions(Expressions.Source)) {
95720
+ // recursive, a CONV can be the argument of a built-in function, which is itself a Source
95721
+ for (const source of structure.findAllExpressionsRecursive(Expressions.Source)) {
95517
95722
  if (source.getFirstToken().getStr().toUpperCase() !== "CONV") {
95518
95723
  continue;
95519
95724
  }
@@ -95572,6 +95777,15 @@ text = text.`,
95572
95777
  }
95573
95778
  sourceType(source, scope) {
95574
95779
  let context;
95780
+ // boolc( <condition> ) is not a MethodCallChain, xsdbool( ) has the same shape but is not reported
95781
+ const first = source.getFirstToken();
95782
+ if (first.getStr().toUpperCase() === "BOOLC"
95783
+ && source.findDirectExpression(Expressions.Cond) !== undefined
95784
+ && source.getChildren().length === 4
95785
+ && scope.getData().references.some(reference => reference.referenceType === _reference_1.ReferenceType.BuiltinMethodReference
95786
+ && reference.position.getStart().equals(first.getStart()))) {
95787
+ return basic_1.StringType.get();
95788
+ }
95575
95789
  for (const child of source.getChildren()) {
95576
95790
  if (!(child instanceof nodes_1.ExpressionNode)) {
95577
95791
  continue;
@@ -95582,6 +95796,15 @@ text = text.`,
95582
95796
  return undefined;
95583
95797
  }
95584
95798
  }
95799
+ else if (child.get() instanceof Expressions.MethodCallChain) {
95800
+ if (source.getChildren().length !== 1) {
95801
+ return undefined;
95802
+ }
95803
+ context = this.builtinResultType(child, scope);
95804
+ if (context === undefined) {
95805
+ return undefined;
95806
+ }
95807
+ }
95585
95808
  else if (child.get() instanceof Expressions.Constant) {
95586
95809
  context = this.infer(context, constant_1.Constant.runSyntax(child));
95587
95810
  }
@@ -95602,6 +95825,32 @@ text = text.`,
95602
95825
  }
95603
95826
  return context;
95604
95827
  }
95828
+ /** The result type of a call to a built-in function whose result type does not depend on its arguments,
95829
+ * undefined for anything else, e.g. abs( ) or xsdbool( ), or a method of the same name */
95830
+ builtinResultType(chain, scope) {
95831
+ var _a;
95832
+ const children = chain.getChildren();
95833
+ if (children.length !== 1 || !(children[0].get() instanceof Expressions.MethodCall)) {
95834
+ return undefined;
95835
+ }
95836
+ const name = (_a = children[0].findDirectExpression(Expressions.MethodName)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
95837
+ if (name === undefined) {
95838
+ return undefined;
95839
+ }
95840
+ const isBuiltin = scope.getData().references.some(reference => reference.referenceType === _reference_1.ReferenceType.BuiltinMethodReference
95841
+ && reference.position.getStart().equals(name.getStart()));
95842
+ if (isBuiltin === false) {
95843
+ return undefined;
95844
+ }
95845
+ const upper = name.getStr().toUpperCase();
95846
+ if (RedundantConversion.stringResult.has(upper)) {
95847
+ return basic_1.StringType.get();
95848
+ }
95849
+ else if (RedundantConversion.integerResult.has(upper)) {
95850
+ return basic_1.IntegerType.get();
95851
+ }
95852
+ return undefined;
95853
+ }
95605
95854
  fieldChainType(fieldChain, scope) {
95606
95855
  var _a;
95607
95856
  const operand = (_a = scope.getData().references.find(reference => reference.referenceType === _reference_1.ReferenceType.DataReadReference
@@ -95666,6 +95915,17 @@ text = text.`,
95666
95915
  }
95667
95916
  }
95668
95917
  exports.RedundantConversion = RedundantConversion;
95918
+ // built-in functions that always return a string, whatever their arguments
95919
+ RedundantConversion.stringResult = new Set([
95920
+ "BOOLC", "CONCAT_LINES_OF", "CONDENSE", "ESCAPE", "FROM_MIXED", "INSERT", "REPEAT", "REPLACE",
95921
+ "REVERSE", "SEGMENT", "SHIFT_LEFT", "SHIFT_RIGHT", "SUBSTRING", "SUBSTRING_AFTER", "SUBSTRING_BEFORE",
95922
+ "SUBSTRING_FROM", "SUBSTRING_TO", "TO_LOWER", "TO_MIXED", "TO_UPPER", "TRANSLATE"
95923
+ ]);
95924
+ // built-in functions that always return an i
95925
+ RedundantConversion.integerResult = new Set([
95926
+ "CHARLEN", "COUNT", "COUNT_ANY_NOT_OF", "COUNT_ANY_OF", "DBMAXLEN", "DISTANCE", "FIND", "FIND_ANY_NOT_OF",
95927
+ "FIND_ANY_OF", "FIND_END", "LINES", "NUMOFCHAR", "STRLEN", "XSTRLEN"
95928
+ ]);
95669
95929
  //# sourceMappingURL=redundant_conversion.js.map
95670
95930
 
95671
95931
  /***/ },
@@ -102871,7 +103131,7 @@ class XMLConsistency {
102871
103131
  }
102872
103132
  runTable(obj, file) {
102873
103133
  var _a, _b, _c, _d;
102874
- var _e;
103134
+ var _e, _f;
102875
103135
  const issues = [];
102876
103136
  for (const field of (_e = obj.getFields()) !== null && _e !== void 0 ? _e : []) {
102877
103137
  if (field.DATATYPE === "QUAN" && (!((_a = field.REFTABLE) === null || _a === void 0 ? void 0 : _a.trim()) || !((_b = field.REFFIELD) === null || _b === void 0 ? void 0 : _b.trim()))) {
@@ -102880,6 +103140,14 @@ class XMLConsistency {
102880
103140
  }
102881
103141
  }
102882
103142
  if (obj.getTableCategory() === Objects.TableCategory.Transparent) {
103143
+ // Confirmed reserved database field names, see issue #4331, DAY and HOUR reported by activation.
103144
+ // TRESE also contains names such as TEXT and LENGTH which are allowed here.
103145
+ const reservedFieldNames = ["ZONE", "HANDLER", "SECTION", "PARAMETER", "DAY", "HOUR"];
103146
+ for (const field of (_f = obj.getFields()) !== null && _f !== void 0 ? _f : []) {
103147
+ if (reservedFieldNames.includes(field.FIELDNAME.toUpperCase())) {
103148
+ issues.push(issue_1.Issue.atRow(file, 1, `Table field name "${field.FIELDNAME}" is reserved`, this.getMetadata().key, this.conf.severity));
103149
+ }
103150
+ }
102883
103151
  if (!((_c = obj.getDeliveryClass()) === null || _c === void 0 ? void 0 : _c.trim())) {
102884
103152
  const message = `Transparent table must have delivery class(CONTFLAG in DD02V) set`;
102885
103153
  issues.push(issue_1.Issue.atRow(file, 1, message, this.getMetadata().key, this.conf.transparentTableSeverity));
@@ -104490,6 +104758,12 @@ class Chunk {
104490
104758
  original: m.original,
104491
104759
  generated: { line: m.generated.line + offset, column: m.generated.column },
104492
104760
  }));
104761
+ for (const source of new Set(this.mappings.map(m => m.source))) {
104762
+ const contents = options?.sourceContents?.[source];
104763
+ if (contents !== undefined) {
104764
+ sourceMapGenerator.setSourceContent(sourcePaths[source] ?? source, contents);
104765
+ }
104766
+ }
104493
104767
  const json = sourceMapGenerator.toJSON();
104494
104768
  json.file = generatedFilename;
104495
104769
  json.sourceRoot = "";
@@ -104501,6 +104775,231 @@ exports.Chunk = Chunk;
104501
104775
 
104502
104776
  /***/ },
104503
104777
 
104778
+ /***/ "./node_modules/@abaplint/transpiler/build/src/db/cds_database_view.js"
104779
+ /*!*****************************************************************************!*\
104780
+ !*** ./node_modules/@abaplint/transpiler/build/src/db/cds_database_view.js ***!
104781
+ \*****************************************************************************/
104782
+ (__unused_webpack_module, exports, __webpack_require__) {
104783
+
104784
+ "use strict";
104785
+
104786
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
104787
+ if (k2 === undefined) k2 = k;
104788
+ var desc = Object.getOwnPropertyDescriptor(m, k);
104789
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
104790
+ desc = { enumerable: true, get: function() { return m[k]; } };
104791
+ }
104792
+ Object.defineProperty(o, k2, desc);
104793
+ }) : (function(o, m, k, k2) {
104794
+ if (k2 === undefined) k2 = k;
104795
+ o[k2] = m[k];
104796
+ }));
104797
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
104798
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
104799
+ }) : function(o, v) {
104800
+ o["default"] = v;
104801
+ });
104802
+ var __importStar = (this && this.__importStar) || (function () {
104803
+ var ownKeys = function(o) {
104804
+ ownKeys = Object.getOwnPropertyNames || function (o) {
104805
+ var ar = [];
104806
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
104807
+ return ar;
104808
+ };
104809
+ return ownKeys(o);
104810
+ };
104811
+ return function (mod) {
104812
+ if (mod && mod.__esModule) return mod;
104813
+ var result = {};
104814
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
104815
+ __setModuleDefault(result, mod);
104816
+ return result;
104817
+ };
104818
+ })();
104819
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
104820
+ exports.CDSDatabaseView = void 0;
104821
+ const abaplint = __importStar(__webpack_require__(/*! @abaplint/core */ "./node_modules/@abaplint/core/build/src/index.js"));
104822
+ const cds = abaplint.ExpressionsCDS;
104823
+ /** SQL for the supported relational subset of CDS. Never discard unknown syntax. */
104824
+ class CDSDatabaseView {
104825
+ reg;
104826
+ viewName = "";
104827
+ sources = [];
104828
+ constructor(reg) {
104829
+ this.reg = reg;
104830
+ }
104831
+ build(obj) {
104832
+ this.viewName = obj.getName();
104833
+ const tree = new abaplint.CDSParser().parse(obj.findSourceFile());
104834
+ if (tree === undefined) {
104835
+ return this.unsupported("could not parse CDS definition");
104836
+ }
104837
+ else if (!(tree.get() instanceof cds.CDSDefineView)) {
104838
+ return undefined; // Abstract/custom entities have no database view.
104839
+ }
104840
+ const name = tree.findDirectExpression(cds.CDSName);
104841
+ const select = tree.findDirectExpression(cds.CDSSelect);
104842
+ if (name === undefined || select === undefined) {
104843
+ return this.unsupported("expected a SELECT view");
104844
+ }
104845
+ this.viewName = this.name(name);
104846
+ for (const child of tree.getChildren()) {
104847
+ if (child === name || child === select || child.get() instanceof cds.CDSAnnotation) {
104848
+ continue;
104849
+ }
104850
+ this.keyword(child, ["DEFINE", "ROOT", "VIEW", "ENTITY", "AS", ";"]);
104851
+ }
104852
+ const source = select.findDirectExpression(cds.CDSSource);
104853
+ if (source === undefined) {
104854
+ return this.unsupported("missing source");
104855
+ }
104856
+ const from = [this.source(source)];
104857
+ for (const join of select.findDirectExpressions(cds.CDSJoin)) {
104858
+ from.push(this.join(join));
104859
+ }
104860
+ const elements = select.findDirectExpressions(cds.CDSElement);
104861
+ if (elements.length === 0) {
104862
+ return this.unsupported("expected explicit projected fields");
104863
+ }
104864
+ const columns = elements.map(e => this.element(e)).join(", ");
104865
+ let where = "";
104866
+ for (const child of select.getChildren()) {
104867
+ if (child === source || child.get() instanceof cds.CDSJoin || child.get() instanceof cds.CDSElement) {
104868
+ continue;
104869
+ }
104870
+ else if (child.get() instanceof cds.CDSWhere) {
104871
+ where = " " + this.expression(child);
104872
+ }
104873
+ else {
104874
+ this.keyword(child, ["SELECT", "DISTINCT", "FROM", "{", "}", ","]);
104875
+ }
104876
+ }
104877
+ const distinct = select.findDirectTokenByText("DISTINCT") ? "DISTINCT " : "";
104878
+ return `CREATE VIEW ${this.quote(this.viewName)} AS SELECT ${distinct}${columns} FROM ${from.join(" ")}${where};`;
104879
+ }
104880
+ source(node) {
104881
+ const nameNode = node.findDirectExpression(cds.CDSPrefixedName);
104882
+ if (nameNode === undefined) {
104883
+ return this.unsupported("expected a table source");
104884
+ }
104885
+ const name = this.name(nameNode);
104886
+ if (this.reg.getObject("TABL", name)?.getType() !== "TABL") {
104887
+ return this.unsupported(`source ${name} does not resolve to a TABL`);
104888
+ }
104889
+ const as = node.findDirectExpression(cds.CDSAs);
104890
+ const alias = as?.findDirectExpression(cds.CDSName) || node.findDirectExpression(cds.CDSName);
104891
+ for (const child of node.getChildren()) {
104892
+ if (child !== nameNode && child !== as && child !== alias) {
104893
+ return this.unsupported("source parameters, filters or nested joins");
104894
+ }
104895
+ }
104896
+ this.sources.push(alias ? this.name(alias) : name);
104897
+ return this.quote(name) + (alias ? " AS " + this.quote(this.name(alias)) : "");
104898
+ }
104899
+ join(node) {
104900
+ const sources = node.findDirectExpressions(cds.CDSSource);
104901
+ const conditions = node.findDirectExpressions(cds.CDSCondition);
104902
+ const words = node.getDirectTokens().map(t => t.getStr().toUpperCase()).join(" ");
104903
+ const match = /^(?:(INNER|LEFT OUTER|RIGHT OUTER|CROSS) )?JOIN(?: ON)?$/.exec(words);
104904
+ if (sources.length !== 1 || match === null) {
104905
+ return this.unsupported("join shape: " + node.concatTokens());
104906
+ }
104907
+ const kind = match[1] || "INNER";
104908
+ if (conditions.length !== (kind === "CROSS" ? 0 : 1)) {
104909
+ return this.unsupported("join requires an ON condition (except CROSS JOIN)");
104910
+ }
104911
+ const source = this.source(sources[0]);
104912
+ return kind + " JOIN " + source + (conditions.length ? " ON " + this.expression(conditions[0]) : "");
104913
+ }
104914
+ element(node) {
104915
+ const field = node.findDirectExpression(cds.CDSPrefixedName);
104916
+ const as = node.findDirectExpression(cds.CDSAs);
104917
+ for (const child of node.getChildren()) {
104918
+ if (child === field || child === as || child.get() instanceof cds.CDSAnnotation) {
104919
+ continue;
104920
+ }
104921
+ this.keyword(child, ["KEY"]);
104922
+ }
104923
+ if (field === undefined) {
104924
+ return this.unsupported("expected a projected source field");
104925
+ }
104926
+ const parts = this.fieldParts(field);
104927
+ const alias = as?.findDirectExpression(cds.CDSName);
104928
+ return this.field(field) + " AS " + this.quote(alias ? this.name(alias) : parts[parts.length - 1]);
104929
+ }
104930
+ expression(node) {
104931
+ if (node instanceof abaplint.Nodes.TokenNode) {
104932
+ return this.keyword(node, ["WHERE", "AND", "OR", "NOT", "IS", "NULL", "LIKE", "ESCAPE", "BETWEEN",
104933
+ "=", "!", "<", ">", "(", ")"]);
104934
+ }
104935
+ else if (node.get() instanceof cds.CDSPrefixedName) {
104936
+ if (node.getTokens().map(t => t.getStr()).join("").toLowerCase() === "$session.system_language") {
104937
+ return "'E'";
104938
+ }
104939
+ return this.field(node);
104940
+ }
104941
+ else if (node.get() instanceof cds.CDSString || node.get() instanceof cds.CDSInteger) {
104942
+ return node.getTokens().map(t => t.getStr()).join("");
104943
+ }
104944
+ else if (node.get() instanceof cds.CDSCondition || node.get() instanceof cds.CDSWhere) {
104945
+ const parts = [];
104946
+ for (const child of node.getChildren()) {
104947
+ const part = this.expression(child);
104948
+ if (["<", ">", "!"].includes(parts[parts.length - 1]) && ["=", ">"].includes(part)) {
104949
+ parts[parts.length - 1] += part;
104950
+ }
104951
+ else {
104952
+ parts.push(part);
104953
+ }
104954
+ }
104955
+ return parts.join(" ");
104956
+ }
104957
+ return this.unsupported(node.concatTokens());
104958
+ }
104959
+ field(node) {
104960
+ const parts = this.fieldParts(node);
104961
+ if (parts.length === 1 && this.sources.length === 1) {
104962
+ parts.unshift(this.sources[0]);
104963
+ }
104964
+ else if (parts.length === 2 && !this.sources.includes(parts[0])) {
104965
+ return this.unsupported("unknown source qualifier " + parts[0]);
104966
+ }
104967
+ return parts.map(p => this.quote(p)).join(".");
104968
+ }
104969
+ fieldParts(node) {
104970
+ const text = node.getTokens().map(t => t.getStr()).join("").toLowerCase();
104971
+ const parts = text.split(".");
104972
+ if (parts.length > 2 || parts.some(p => !/^(\/\w+\/)?\w+$/.test(p))) {
104973
+ return this.unsupported("field path " + text);
104974
+ }
104975
+ return parts;
104976
+ }
104977
+ name(node) {
104978
+ const name = node.getTokens().map(t => t.getStr()).join("").toLowerCase();
104979
+ if (!/^(\/\w+\/)?\w+$/.test(name)) {
104980
+ return this.unsupported("identifier " + name);
104981
+ }
104982
+ return name;
104983
+ }
104984
+ keyword(node, allowed) {
104985
+ const text = node.concatTokens().toUpperCase();
104986
+ if (!(node instanceof abaplint.Nodes.TokenNode) || !allowed.includes(text)) {
104987
+ return this.unsupported(node.concatTokens());
104988
+ }
104989
+ return text;
104990
+ }
104991
+ quote(name) {
104992
+ return '"' + name.toLowerCase().replace(/"/g, '""') + '"';
104993
+ }
104994
+ unsupported(detail) {
104995
+ throw new Error(`CDS view ${this.viewName}: unsupported database definition: ${detail}`);
104996
+ }
104997
+ }
104998
+ exports.CDSDatabaseView = CDSDatabaseView;
104999
+ //# sourceMappingURL=cds_database_view.js.map
105000
+
105001
+ /***/ },
105002
+
104504
105003
  /***/ "./node_modules/@abaplint/transpiler/build/src/db/index.js"
104505
105004
  /*!*****************************************************************!*\
104506
105005
  !*** ./node_modules/@abaplint/transpiler/build/src/db/index.js ***!
@@ -104549,6 +105048,7 @@ const sqlite_database_schema_1 = __webpack_require__(/*! ./schema_generation/sql
104549
105048
  const pg_database_schema_1 = __webpack_require__(/*! ./schema_generation/pg_database_schema */ "./node_modules/@abaplint/transpiler/build/src/db/schema_generation/pg_database_schema.js");
104550
105049
  const snowflake_database_schema_1 = __webpack_require__(/*! ./schema_generation/snowflake_database_schema */ "./node_modules/@abaplint/transpiler/build/src/db/schema_generation/snowflake_database_schema.js");
104551
105050
  const populate_tables_1 = __webpack_require__(/*! ./populate_tables */ "./node_modules/@abaplint/transpiler/build/src/db/populate_tables.js");
105051
+ const cds_database_view_1 = __webpack_require__(/*! ./cds_database_view */ "./node_modules/@abaplint/transpiler/build/src/db/cds_database_view.js");
104552
105052
  /////////////////////////
104553
105053
  // NOTES
104554
105054
  /////////////////////////
@@ -104560,9 +105060,11 @@ class DatabaseSetup {
104560
105060
  this.reg = reg;
104561
105061
  }
104562
105062
  run(options) {
105063
+ // CDS views are dialect independent SQL, added after the tables and views they select from
105064
+ const cdsViews = this.buildCDSViews();
104563
105065
  return {
104564
105066
  schemas: {
104565
- sqlite: this.driver(new sqlite_database_schema_1.SQLiteDatabaseSchema(this.reg)),
105067
+ sqlite: [...this.driver(new sqlite_database_schema_1.SQLiteDatabaseSchema(this.reg)), ...cdsViews],
104566
105068
  // HANA takes the PG schema unchanged -- measured against HANA Express
104567
105069
  // on a tree of 77 tables. The one thing it needs is that identifiers
104568
105070
  // reach it quoted in UPPER case, and that is not a dialect of DDL: the
@@ -104571,13 +105073,25 @@ class DatabaseSetup {
104571
105073
  // here. (Unquoted would nearly work and then meet a column called
104572
105074
  // `cross`, which is one of HANA's reserved words.)
104573
105075
  hdb: this.driver(new pg_database_schema_1.PGDatabaseSchema(this.reg)),
104574
- pg: this.driver(new pg_database_schema_1.PGDatabaseSchema(this.reg)),
104575
- snowflake: this.driver(new snowflake_database_schema_1.SnowflakeDatabaseSchema(this.reg)),
105076
+ pg: [...this.driver(new pg_database_schema_1.PGDatabaseSchema(this.reg)), ...cdsViews],
105077
+ snowflake: [...this.driver(new snowflake_database_schema_1.SnowflakeDatabaseSchema(this.reg)), ...cdsViews],
104576
105078
  },
104577
105079
  insert: this.buildInsert(options),
104578
105080
  };
104579
105081
  }
104580
105082
  ////////////////////
105083
+ buildCDSViews() {
105084
+ const views = [];
105085
+ for (const obj of this.reg.getObjects()) {
105086
+ if (obj instanceof abaplint.Objects.DataDefinition) {
105087
+ const view = new cds_database_view_1.CDSDatabaseView(this.reg).build(obj);
105088
+ if (view !== undefined) {
105089
+ views.push(view);
105090
+ }
105091
+ }
105092
+ }
105093
+ return views;
105094
+ }
104581
105095
  driver(schemaGenerator) {
104582
105096
  const statements = [];
104583
105097
  // CREATE TABLEs
@@ -105728,12 +106242,12 @@ class CompareTranspiler {
105728
106242
  const field = concat.replace(" IS NOT REQUESTED", "").toLowerCase();
105729
106243
  return new chunk_1.Chunk().appendString(pre + "INPUT && INPUT." + field + " === undefined && INPUT.importing?." + field + " === undefined");
105730
106244
  }
105731
- if (concat.includes(" IS INSTANCE OF ")) {
105732
- const notted = concat.startsWith("NOT ") || concat.includes(" IS NOT INSTANCE OF ");
106245
+ if (concat.includes(" IS INSTANCE OF ") || concat.includes(" IS NOT INSTANCE OF ")) {
106246
+ const notted = concat.startsWith("NOT ") !== concat.includes(" IS NOT INSTANCE OF ");
105733
106247
  const falsed = notted ? " === false" : "";
105734
106248
  const expr = node.findDirectExpression(core_1.Expressions.ClassName);
105735
106249
  const cname = expr?.concatTokens();
105736
- const lookup = traversal.lookupClassOrInterface(cname, expr?.getFirstToken());
106250
+ const lookup = cname?.toUpperCase() === "OBJECT" ? '"OBJECT"' : traversal.lookupClassOrInterface(cname, expr?.getFirstToken());
105737
106251
  return new chunk_1.Chunk().appendString("abap.compare.instance_of(").appendChunk(s0).appendString(`, ${lookup})` + falsed);
105738
106252
  }
105739
106253
  }
@@ -111383,10 +111897,12 @@ const traversal_1 = __webpack_require__(/*! ../traversal */ "./node_modules/@aba
111383
111897
  const requires_1 = __webpack_require__(/*! ../requires */ "./node_modules/@abaplint/transpiler/build/src/requires.js");
111384
111898
  const rearranger_1 = __webpack_require__(/*! ../rearranger */ "./node_modules/@abaplint/transpiler/build/src/rearranger.js");
111385
111899
  const chunk_1 = __webpack_require__(/*! ../chunk */ "./node_modules/@abaplint/transpiler/build/src/chunk.js");
111386
- const initialization_1 = __webpack_require__(/*! ../initialization */ "./node_modules/@abaplint/transpiler/build/src/initialization.js");
111900
+ const output_layout_1 = __webpack_require__(/*! ../output_layout */ "./node_modules/@abaplint/transpiler/build/src/output_layout.js");
111387
111901
  class HandleABAP {
111902
+ layout;
111388
111903
  options;
111389
- constructor(options) {
111904
+ constructor(options, layout = new output_layout_1.OutputLayout()) {
111905
+ this.layout = layout;
111390
111906
  this.options = options;
111391
111907
  }
111392
111908
  runObject(obj, reg) {
@@ -111487,11 +112003,12 @@ class HandleABAP {
111487
112003
  if (filename === output.filename) {
111488
112004
  continue;
111489
112005
  }
112006
+ const specifier = (0, output_layout_1.importPath)(this.layout.file(output.object, output.filename), this.layout.sourceModule(r.filename));
111490
112007
  if (name) {
111491
- contents.appendString("const {" + traversal_1.Traversal.escapeNamespace(name) + "} = await import(\"./" + (0, initialization_1.escapeFilenameForImport)(filename) + "\");\n");
112008
+ contents.appendString("const {" + traversal_1.Traversal.escapeNamespace(name) + "} = await import(\"" + specifier + "\");\n");
111492
112009
  }
111493
112010
  else {
111494
- contents.appendString("await import(\"./" + (0, initialization_1.escapeFilenameForImport)(filename) + "\");\n");
112011
+ contents.appendString("await import(\"" + specifier + "\");\n");
111495
112012
  }
111496
112013
  }
111497
112014
  contents.appendChunk(output.chunk);
@@ -111819,7 +112336,13 @@ exports.HandleOA2P = HandleOA2P;
111819
112336
  Object.defineProperty(exports, "__esModule", ({ value: true }));
111820
112337
  exports.HandleSMIM = void 0;
111821
112338
  const chunk_1 = __webpack_require__(/*! ../chunk */ "./node_modules/@abaplint/transpiler/build/src/chunk.js");
112339
+ const output_layout_1 = __webpack_require__(/*! ../output_layout */ "./node_modules/@abaplint/transpiler/build/src/output_layout.js");
111822
112340
  class HandleSMIM {
112341
+ layout;
112342
+ constructor(layout = new output_layout_1.OutputLayout()) {
112343
+ this.layout = layout;
112344
+ // Asset paths are relative to the output root.
112345
+ }
111823
112346
  runObject(obj, _reg) {
111824
112347
  const filename = obj.getXMLFile()?.getFilename().replace(".xml", ".mjs").toLowerCase();
111825
112348
  if (filename === undefined) {
@@ -111827,9 +112350,10 @@ class HandleSMIM {
111827
112350
  }
111828
112351
  obj.parse();
111829
112352
  const dataFile = obj.getDataFile();
112353
+ const dataFilename = dataFile ? this.layout.file({ name: obj.getName(), type: obj.getType() }, dataFile.getFilename()) : undefined;
111830
112354
  const chunk = new chunk_1.Chunk().appendString(`abap.SMIM["${obj.getName().toUpperCase()}"] = {
111831
112355
  "objectType": "SMIM",
111832
- "filename": ${JSON.stringify(dataFile?.getFilename())},
112356
+ "filename": ${JSON.stringify(dataFilename)},
111833
112357
  "url": ${JSON.stringify(obj.getURL())},
111834
112358
  "class": ${JSON.stringify(obj.getClass())},
111835
112359
  };`);
@@ -112102,8 +112626,14 @@ exports.HandleView = HandleView;
112102
112626
  Object.defineProperty(exports, "__esModule", ({ value: true }));
112103
112627
  exports.HandleW3MI = void 0;
112104
112628
  const chunk_1 = __webpack_require__(/*! ../chunk */ "./node_modules/@abaplint/transpiler/build/src/chunk.js");
112629
+ const output_layout_1 = __webpack_require__(/*! ../output_layout */ "./node_modules/@abaplint/transpiler/build/src/output_layout.js");
112105
112630
  const w3mi_name_1 = __webpack_require__(/*! ../w3mi_name */ "./node_modules/@abaplint/transpiler/build/src/w3mi_name.js");
112106
112631
  class HandleW3MI {
112632
+ layout;
112633
+ constructor(layout = new output_layout_1.OutputLayout()) {
112634
+ this.layout = layout;
112635
+ // Asset paths are relative to the output root.
112636
+ }
112107
112637
  runObject(obj, _reg) {
112108
112638
  const filename = obj.getXMLFile()?.getFilename().replace(".xml", ".mjs").toLowerCase();
112109
112639
  if (filename === undefined) {
@@ -112111,9 +112641,10 @@ class HandleW3MI {
112111
112641
  }
112112
112642
  obj.parse();
112113
112643
  const dataFile = obj.getDataFile();
112644
+ const dataFilename = dataFile ? this.layout.file({ name: obj.getName(), type: obj.getType() }, dataFile.getFilename()) : undefined;
112114
112645
  const chunk = new chunk_1.Chunk().appendString(`abap.W3MI["${(0, w3mi_name_1.w3miObjectName)(obj)}"] = {
112115
112646
  "objectType": "W3MI",
112116
- "filename": ${JSON.stringify(dataFile?.getFilename())},
112647
+ "filename": ${JSON.stringify(dataFilename)},
112117
112648
  };`);
112118
112649
  const output = {
112119
112650
  object: {
@@ -112189,7 +112720,7 @@ var __importStar = (this && this.__importStar) || (function () {
112189
112720
  };
112190
112721
  })();
112191
112722
  Object.defineProperty(exports, "__esModule", ({ value: true }));
112192
- exports.Transpiler = exports.Chunk = exports.UnknownTypesEnum = exports.config = void 0;
112723
+ exports.Transpiler = exports.Chunk = exports.UnknownTypesEnum = exports.config = exports.importPath = exports.OutputLayout = void 0;
112193
112724
  const abaplint = __importStar(__webpack_require__(/*! @abaplint/core */ "./node_modules/@abaplint/core/build/src/index.js"));
112194
112725
  const validation_1 = __webpack_require__(/*! ./validation */ "./node_modules/@abaplint/transpiler/build/src/validation.js");
112195
112726
  Object.defineProperty(exports, "config", ({ enumerable: true, get: function () { return validation_1.config; } }));
@@ -112213,12 +112744,14 @@ const handle_msag_1 = __webpack_require__(/*! ./handlers/handle_msag */ "./node_
112213
112744
  const handle_oa2p_1 = __webpack_require__(/*! ./handlers/handle_oa2p */ "./node_modules/@abaplint/transpiler/build/src/handlers/handle_oa2p.js");
112214
112745
  const handle_fugr_1 = __webpack_require__(/*! ./handlers/handle_fugr */ "./node_modules/@abaplint/transpiler/build/src/handlers/handle_fugr.js");
112215
112746
  const initialization_1 = __webpack_require__(/*! ./initialization */ "./node_modules/@abaplint/transpiler/build/src/initialization.js");
112747
+ const output_layout_1 = __webpack_require__(/*! ./output_layout */ "./node_modules/@abaplint/transpiler/build/src/output_layout.js");
112748
+ var output_layout_2 = __webpack_require__(/*! ./output_layout */ "./node_modules/@abaplint/transpiler/build/src/output_layout.js");
112749
+ Object.defineProperty(exports, "OutputLayout", ({ enumerable: true, get: function () { return output_layout_2.OutputLayout; } }));
112750
+ Object.defineProperty(exports, "importPath", ({ enumerable: true, get: function () { return output_layout_2.importPath; } }));
112216
112751
  class Transpiler {
112217
112752
  options;
112218
- plugin;
112219
- constructor(options, plugin) {
112753
+ constructor(options) {
112220
112754
  this.options = options;
112221
- this.plugin = plugin;
112222
112755
  if (this.options === undefined) {
112223
112756
  this.options = {};
112224
112757
  }
@@ -112232,23 +112765,22 @@ class Transpiler {
112232
112765
  const reg = new abaplint.Registry().addFiles(memory);
112233
112766
  return this.run(reg);
112234
112767
  }
112235
- async run(reg, progress) {
112768
+ async run(reg, progress, folders) {
112236
112769
  // Validation installs the transpiler configuration and findIssues() parses
112237
112770
  // dirty registries. Parsing before that would be wasted because setConfig()
112238
112771
  // marks every registry object dirty again.
112239
112772
  this.validate(reg);
112773
+ const layout = new output_layout_1.OutputLayout(reg, folders);
112240
112774
  const dbSetup = new db_1.DatabaseSetup(reg).run(this.options);
112241
- this.plugin?.amendDatabaseSetup?.(dbSetup, reg, this.options || {});
112242
112775
  const output = {
112243
112776
  objects: [],
112244
- unitTestScript: new unit_test_1.UnitTest().unitTestScript(reg, this.options?.skip),
112245
- unitTestScriptOpen: new unit_test_1.UnitTest().unitTestScriptOpen(reg, this.options?.skip),
112777
+ unitTestScript: new unit_test_1.UnitTest(layout).unitTestScript(reg, this.options?.skip),
112778
+ unitTestScriptOpen: new unit_test_1.UnitTest(layout).unitTestScriptOpen(reg, this.options?.skip),
112246
112779
  initializationScript: "",
112247
112780
  initializationScript2: "",
112248
112781
  databaseSetup: dbSetup,
112249
112782
  reg: reg,
112250
112783
  };
112251
- const pluginOutputs = [];
112252
112784
  progress?.set(reg.getObjectCount().total, "Building");
112253
112785
  for (const obj of reg.getObjects()) {
112254
112786
  await progress?.tick("Building, " + obj.getName());
@@ -112265,7 +112797,7 @@ class Transpiler {
112265
112797
  output.objects.push(...new handle_fugr_1.HandleFUGR(this.options).runObject(obj, reg));
112266
112798
  }
112267
112799
  else if (obj instanceof abaplint.ABAPObject) {
112268
- output.objects.push(...new handle_abap_1.HandleABAP(this.options).runObject(obj, reg));
112800
+ output.objects.push(...new handle_abap_1.HandleABAP(this.options, layout).runObject(obj, reg));
112269
112801
  }
112270
112802
  else if (obj instanceof abaplint.Objects.Oauth2Profile) {
112271
112803
  output.objects.push(...new handle_oa2p_1.HandleOA2P().runObject(obj, reg));
@@ -112286,30 +112818,25 @@ class Transpiler {
112286
112818
  output.objects.push(...new handle_table_type_1.HandleTableType().runObject(obj, reg));
112287
112819
  }
112288
112820
  else if (obj instanceof abaplint.Objects.MIMEObject) {
112289
- output.objects.push(...new handle_smim_1.HandleSMIM().runObject(obj, reg));
112821
+ output.objects.push(...new handle_smim_1.HandleSMIM(layout).runObject(obj, reg));
112290
112822
  }
112291
112823
  else if (obj instanceof abaplint.Objects.WebMIME) {
112292
- output.objects.push(...new handle_w3mi_1.HandleW3MI().runObject(obj, reg));
112824
+ output.objects.push(...new handle_w3mi_1.HandleW3MI(layout).runObject(obj, reg));
112293
112825
  }
112294
112826
  else if (obj instanceof abaplint.Objects.MessageClass) {
112295
112827
  output.objects.push(...new handle_msag_1.HandleMSAG().runObject(obj, reg));
112296
112828
  }
112297
- else if (this.plugin !== undefined) {
112298
- const handled = this.plugin.handleObject(obj, reg, this.options || {});
112299
- if (handled !== undefined) {
112300
- output.objects.push(...handled);
112301
- pluginOutputs.push(...handled);
112302
- }
112303
- }
112304
112829
  }
112305
- // after the object loop, plugin output files are imported by the initialization scripts
112306
- output.initializationScript = new initialization_1.Initialization().script(reg, dbSetup, this.options, false, pluginOutputs);
112307
- output.initializationScript2 = new initialization_1.Initialization().script(reg, dbSetup, this.options, true, pluginOutputs);
112830
+ output.initializationScript = new initialization_1.Initialization(layout).script(reg, dbSetup, this.options, false);
112831
+ output.initializationScript2 = new initialization_1.Initialization(layout).script(reg, dbSetup, this.options, true);
112832
+ for (const file of output.objects) {
112833
+ file.filename = layout.file(file.object, file.filename);
112834
+ }
112308
112835
  return output;
112309
112836
  }
112310
112837
  // ///////////////////////////////
112311
112838
  validate(reg) {
112312
- const issues = new validation_1.Validation(this.options, this.plugin).run(reg);
112839
+ const issues = new validation_1.Validation(this.options).run(reg);
112313
112840
  if (issues.length > 0) {
112314
112841
  const messages = issues.map(i => i.getKey() + ", " +
112315
112842
  i.getMessage() + ", " +
@@ -112371,6 +112898,7 @@ exports.escapeNamespaceFilename = escapeNamespaceFilename;
112371
112898
  exports.escapeFilenameForImport = escapeFilenameForImport;
112372
112899
  const abaplint = __importStar(__webpack_require__(/*! @abaplint/core */ "./node_modules/@abaplint/core/build/src/index.js"));
112373
112900
  const handle_fugr_1 = __webpack_require__(/*! ./handlers/handle_fugr */ "./node_modules/@abaplint/transpiler/build/src/handlers/handle_fugr.js");
112901
+ const output_layout_1 = __webpack_require__(/*! ./output_layout */ "./node_modules/@abaplint/transpiler/build/src/output_layout.js");
112374
112902
  function escapeNamespaceFilename(filename) {
112375
112903
  // ES modules are resolved and cached as URLs. This means that special characters must be
112376
112904
  // percent-encoded, such as # with %23 and ? with %3F.
@@ -112388,7 +112916,12 @@ function escapeFilenameForImport(filename) {
112388
112916
  return filename.replace(/%/g, "%25").replace(/#/g, "%23");
112389
112917
  }
112390
112918
  class Initialization {
112391
- script(reg, dbSetup, options, useImport, pluginOutputs) {
112919
+ layout;
112920
+ constructor(layout = new output_layout_1.OutputLayout()) {
112921
+ this.layout = layout;
112922
+ // Flat output unless the caller supplies ownership information.
112923
+ }
112924
+ script(reg, dbSetup, options, useImport) {
112392
112925
  let ret = "";
112393
112926
  if (useImport === true) {
112394
112927
  ret = `/* eslint-disable import/newline-after-import */
@@ -112431,28 +112964,24 @@ globalThis.abap = new runtime.ABAP();\n`;
112431
112964
  }
112432
112965
  ret += `}\n\n`;
112433
112966
  ret += `await initializeABAP();\n\n`;
112434
- ret += `${this.buildImports(reg, useImport, options, pluginOutputs)}`;
112967
+ ret += `${this.buildImports(reg, useImport, options)}`;
112435
112968
  if (options?.setup?.postFunction !== undefined) {
112436
112969
  ret += `\n\nawait setup.${options?.setup?.postFunction}();\n`;
112437
112970
  }
112438
112971
  return ret;
112439
112972
  }
112440
- buildImports(reg, useImport, options, pluginOutputs) {
112973
+ buildImports(reg, useImport, options) {
112441
112974
  // note: ES modules are hoised, so use the dynamic import(), due to setting of globalThis.abap
112442
112975
  // some sorting required: eg. a class constructor using constant from interface
112443
112976
  const list = [];
112444
112977
  const late = [];
112445
112978
  const imp = (filename) => {
112446
- if (useImport === true) {
112447
- return `import "./${filename}.mjs";`;
112448
- }
112449
- else {
112450
- return `await import("./${filename}.mjs");`;
112451
- }
112979
+ const specifier = (0, output_layout_1.importPath)("init.mjs", filename);
112980
+ return {
112981
+ filename: specifier.split("/").pop(),
112982
+ code: useImport === true ? `import "${specifier}";` : `await import("${specifier}");`,
112983
+ };
112452
112984
  };
112453
- for (const pluginOutput of pluginOutputs || []) {
112454
- list.push(imp(pluginOutput.filename.replace(/\.mjs$/i, "")));
112455
- }
112456
112985
  for (const obj of reg.getObjects()) {
112457
112986
  if (obj instanceof abaplint.Objects.Table
112458
112987
  || obj instanceof abaplint.Objects.DataElement
@@ -112464,11 +112993,11 @@ globalThis.abap = new runtime.ABAP();\n`;
112464
112993
  || obj instanceof abaplint.Objects.TypePool
112465
112994
  || obj instanceof abaplint.Objects.TableType
112466
112995
  || obj instanceof abaplint.Objects.View) {
112467
- list.push(imp(`${escapeNamespaceFilename(obj.getName().toLowerCase())}.${obj.getType().toLowerCase()}`));
112996
+ list.push(imp(this.layout.objectModule(obj)));
112468
112997
  }
112469
112998
  }
112470
112999
  for (const obj of reg.getObjects()) {
112471
- const name = imp(`${escapeNamespaceFilename(obj.getName().toLowerCase())}.${obj.getType().toLowerCase()}`);
113000
+ const name = imp(this.layout.objectModule(obj));
112472
113001
  if (obj instanceof abaplint.Objects.Class
112473
113002
  && obj.getName().toUpperCase() !== "CL_ABAP_CHAR_UTILITIES"
112474
113003
  && this.hasClassConstructor(reg, obj)) {
@@ -112488,7 +113017,9 @@ globalThis.abap = new runtime.ABAP();\n`;
112488
113017
  list.push(name);
112489
113018
  }
112490
113019
  }
112491
- return [...list.sort(), ...late].join("\n");
113020
+ // Folder names must not change the original module initialization order.
113021
+ list.sort((a, b) => a.filename < b.filename ? -1 : a.filename > b.filename ? 1 : 0);
113022
+ return [...list, ...late].map(entry => entry.code).join("\n");
112492
113023
  }
112493
113024
  // class constructors might make early use of eg. constants from interfaces
112494
113025
  // sub classes will import() super classes and trigger a class constructor of the super
@@ -112640,6 +113171,89 @@ exports.DEFAULT_KEYWORDS = new Set([
112640
113171
 
112641
113172
  /***/ },
112642
113173
 
113174
+ /***/ "./node_modules/@abaplint/transpiler/build/src/output_layout.js"
113175
+ /*!**********************************************************************!*\
113176
+ !*** ./node_modules/@abaplint/transpiler/build/src/output_layout.js ***!
113177
+ \**********************************************************************/
113178
+ (__unused_webpack_module, exports) {
113179
+
113180
+ "use strict";
113181
+
113182
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
113183
+ exports.OutputLayout = void 0;
113184
+ exports.importPath = importPath;
113185
+ /** Browser-safe paths: generated modules use POSIX paths on every platform. */
113186
+ class OutputLayout {
113187
+ grouped;
113188
+ objectFolders = new Map();
113189
+ sourceFolders = new Map();
113190
+ constructor(reg, folders) {
113191
+ this.grouped = folders !== undefined;
113192
+ if (folders === undefined) {
113193
+ return;
113194
+ }
113195
+ for (const [filename, folder] of folders) {
113196
+ this.sourceFolders.set(filename.toLowerCase(), folder);
113197
+ }
113198
+ for (const obj of reg?.getObjects() || []) {
113199
+ const owners = new Set(obj.getFiles().map(f => this.sourceFolders.get(f.getFilename().toLowerCase()))
113200
+ .filter((folder) => folder !== undefined));
113201
+ if (owners.size !== 1) {
113202
+ throw new Error("Ambiguous output ownership for " + obj.getType() + " " + obj.getName());
113203
+ }
113204
+ const folder = [...owners][0];
113205
+ this.objectFolders.set(this.key({ type: obj.getType(), name: obj.getName() }), folder);
113206
+ for (const file of obj.getFiles()) {
113207
+ // Class locals are merged into a single module.
113208
+ this.sourceFolders.set(file.getFilename().toLowerCase().replace(/\.locals_(def|imp)\.abap$/, ".locals.abap"), folder);
113209
+ }
113210
+ }
113211
+ }
113212
+ key(obj) {
113213
+ return obj.type.toUpperCase() + ":" + obj.name.toUpperCase();
113214
+ }
113215
+ file(obj, filename) {
113216
+ const folder = this.objectFolders.get(this.key(obj));
113217
+ if (this.grouped && folder === undefined) {
113218
+ throw new Error("Missing output ownership for " + obj.type + " " + obj.name);
113219
+ }
113220
+ if (folder !== undefined && (filename.startsWith("/") || /[\\:]/.test(filename)
113221
+ || filename.split("/").some(segment => segment === "" || segment === "." || segment === ".."))) {
113222
+ throw new Error("Invalid output filename: " + filename);
113223
+ }
113224
+ return folder === undefined ? filename : folder + "/" + filename;
113225
+ }
113226
+ sourceModule(filename) {
113227
+ const folder = this.sourceFolders.get(filename.toLowerCase());
113228
+ if (this.grouped && folder === undefined) {
113229
+ throw new Error("Missing output ownership for source " + filename);
113230
+ }
113231
+ const module = filename.replace(/\.abap$/i, ".mjs").toLowerCase();
113232
+ return folder === undefined ? module : folder + "/" + module;
113233
+ }
113234
+ objectModule(obj, suffix = "") {
113235
+ const identifier = { name: obj.getName(), type: obj.getType() };
113236
+ const filename = obj.getName().toLowerCase().replace(/\//g, "#") + "." + obj.getType().toLowerCase() + suffix + ".mjs";
113237
+ return this.file(identifier, filename);
113238
+ }
113239
+ }
113240
+ exports.OutputLayout = OutputLayout;
113241
+ /** Escape each segment without turning directory separators into namespace markers. */
113242
+ function importPath(from, to) {
113243
+ const source = from.split("/").slice(0, -1);
113244
+ const target = to.split("/");
113245
+ while (source.length > 0 && target.length > 0 && source[0] === target[0]) {
113246
+ source.shift();
113247
+ target.shift();
113248
+ }
113249
+ const relative = [...source.map(() => ".."), ...target].join("/");
113250
+ const escaped = relative.split("/").map(segment => encodeURIComponent(segment)).join("/");
113251
+ return escaped.startsWith("../") ? escaped : "./" + escaped;
113252
+ }
113253
+ //# sourceMappingURL=output_layout.js.map
113254
+
113255
+ /***/ },
113256
+
112643
113257
  /***/ "./node_modules/@abaplint/transpiler/build/src/rearranger.js"
112644
113258
  /*!*******************************************************************!*\
112645
113259
  !*** ./node_modules/@abaplint/transpiler/build/src/rearranger.js ***!
@@ -113502,6 +114116,22 @@ throw error;
113502
114116
  }
113503
114117
  })())`;
113504
114118
  }
114119
+ /** ASSIGN of a statically specified data object, e.g. a variable, an attribute or an offset/length,
114120
+ * does not set sy-subrc, a dereference, a table expression or COMPONENT does */
114121
+ isStaticDataObject(node, source) {
114122
+ const concat = node.concatTokens().toUpperCase();
114123
+ if (source === undefined
114124
+ || concat.startsWith("ASSIGN COMPONENT ")
114125
+ || concat.includes(" INCREMENT ")
114126
+ || concat.includes(" ELSE UNASSIGN")
114127
+ || source.findFirstExpression(abaplint.Expressions.Dereference) !== undefined
114128
+ || source.findFirstExpression(abaplint.Expressions.TableExpression) !== undefined) {
114129
+ return false;
114130
+ }
114131
+ // field symbols are left as they are, not measured
114132
+ const first = source.findFirstExpression(abaplint.Expressions.FieldChain)?.getFirstChild();
114133
+ return first !== undefined && !(first.get() instanceof abaplint.Expressions.SourceFieldSymbol);
114134
+ }
113505
114135
  transpile(node, traversal) {
113506
114136
  const assignSource = node.findDirectExpression(abaplint.Expressions.AssignSource);
113507
114137
  const sourceExpressions = assignSource?.findDirectExpressionsMulti([abaplint.Expressions.Source, abaplint.Expressions.SimpleSource3]) || [];
@@ -113541,6 +114171,9 @@ throw error;
113541
114171
  }
113542
114172
  else {
113543
114173
  options.push("source: " + sources.pop());
114174
+ if (this.isStaticDataObject(node, sourceExprForCheck)) {
114175
+ options.push("keepSubrc: true");
114176
+ }
113544
114177
  }
113545
114178
  }
113546
114179
  else {
@@ -114572,7 +115205,7 @@ static INTERNAL_TYPE = 'CLAS';
114572
115205
  static INTERNAL_NAME = '${traversal.buildInternalName(token.getStr(), def)}';
114573
115206
  static IMPLEMENTED_INTERFACES = [${this.findImplementedByClass(traversal, def, scope).map(e => `"` + e.toUpperCase() + `"`).join(",")}];
114574
115207
  static ATTRIBUTES = {${Array.from(traversal.buildAttributes(def, scope)).join(",\n")}};
114575
- static METHODS = {${traversal.buildMethods(def).join(",\n")}};`, node, traversal);
115208
+ static METHODS = {${traversal.buildMethods(def, scope).join(",\n")}};`, node, traversal);
114576
115209
  }
114577
115210
  findImplementedInterface(traversal, def, scope) {
114578
115211
  if (def === undefined || scope === undefined) {
@@ -118964,6 +119597,16 @@ class MethodImplementationTranspiler {
118964
119597
  else {
118965
119598
  after += `let ${varPrefixed} = ${unique}?.${varName};\n`;
118966
119599
  }
119600
+ if (passByValue === true) {
119601
+ // pass by value: the method works on its own copy, also for a generic type,
119602
+ // which keeps the type of the actual parameter.
119603
+ // A field symbol that is unassigned or assigned with CASTING is passed on as it is
119604
+ after += `if (${varPrefixed} instanceof abap.types.FieldSymbol) {
119605
+ if (${varPrefixed}.getPointer()?.clone !== undefined) { ${varPrefixed} = ${varPrefixed}.getPointer().clone(); }
119606
+ } else if (${unique}?.${varName} !== undefined && ${varPrefixed}?.clone !== undefined) {
119607
+ ${varPrefixed} = ${varPrefixed}.clone();
119608
+ }\n`;
119609
+ }
118967
119610
  if (type instanceof abaplint.BasicTypes.NumericGenericType) {
118968
119611
  after += `if (${varPrefixed}.constructor.name === "Character") {
118969
119612
  ${varPrefixed} = ${transpile_types_1.TranspileTypes.toType(identifier.getType())};
@@ -121516,10 +122159,10 @@ abap.builtin.sy.get().dbcnt.set(${target}.getArrayLength());
121516
122159
  + ` : (("" + ${code}.get()).trim() === "" ? "" : "${keyword} " + ${code}.get()))`;
121517
122160
  }
121518
122161
  dynamicHavingClause(code) {
121519
- return `((value) => {
121520
- const condition = value instanceof abap.types.Table || value instanceof abap.types.HashedTable
121521
- ? value.array().map(row => row.get()).join(" ") : value.get();
121522
- return condition.trim() === "" ? "" : "HAVING " + abap.expandDynamic(condition, (name) => {try { return eval(name);} catch {}});
122162
+ return `((value) => {
122163
+ const condition = value instanceof abap.types.Table || value instanceof abap.types.HashedTable
122164
+ ? value.array().map(row => row.get()).join(" ") : value.get();
122165
+ return condition.trim() === "" ? "" : "HAVING " + abap.expandDynamic(condition, (name) => {try { return eval(name);} catch {}});
121523
122166
  })(${code})`;
121524
122167
  }
121525
122168
  isWhereExpression(node, expression) {
@@ -124762,8 +125405,11 @@ class InterfaceTranspiler {
124762
125405
  ret += `static INTERNAL_TYPE = 'INTF';\n`;
124763
125406
  ret += `static INTERNAL_NAME = '${traversal.buildInternalName(token.getStr(), def)}';\n`;
124764
125407
  ret += `static ATTRIBUTES = {${Array.from(traversal.buildAttributes(def, scope)).join(",\n")}};\n`;
124765
- ret += `static METHODS = {${traversal.buildMethods(def).join(",\n")}};\n`;
124766
- // todo, add IMPLEMENTED_INTERFACES ?
125408
+ ret += `static METHODS = {${traversal.buildMethods(def, scope).join(",\n")}};\n`;
125409
+ const interfaces = def?.getImplementing().map(i => `"${i.name.toUpperCase()}"`) || [];
125410
+ if (interfaces.length > 0) {
125411
+ ret += `static IMPLEMENTED_INTERFACES = [${interfaces.join(",")}];\n`;
125412
+ }
124767
125413
  }
124768
125414
  else if (c instanceof abaplint.Nodes.StatementNode && c.get() instanceof abaplint.Statements.EndInterface) {
124769
125415
  ret += "}\n";
@@ -125558,8 +126204,22 @@ class TranspileTypes {
125558
126204
  if (type instanceof abaplint.BasicTypes.ObjectReferenceType
125559
126205
  || type instanceof abaplint.BasicTypes.GenericObjectReferenceType) {
125560
126206
  resolved = "ABAPObject";
125561
- extra = "{qualifiedName: " + JSON.stringify(type.getQualifiedName()?.toUpperCase()) +
125562
- ", RTTIName: " + JSON.stringify(type.getRTTIName()?.toUpperCase()) + "}";
126207
+ const qualifiedName = type.getQualifiedName()
126208
+ ?? (type instanceof abaplint.BasicTypes.ObjectReferenceType ? type.getIdentifierName() : undefined);
126209
+ let RTTIName = type.getRTTIName();
126210
+ if (type instanceof abaplint.BasicTypes.ObjectReferenceType && RTTIName === undefined) {
126211
+ const id = type.getIdentifier();
126212
+ // NEW and CAST can omit metadata; recover it from the referenced definition.
126213
+ const [name, kind] = id.getFilename().split("/").pop().replace(/#/g, "/").split(".");
126214
+ const local = (id instanceof abaplint.Types.ClassDefinition || id instanceof abaplint.Types.InterfaceDefinition)
126215
+ && id.isGlobal() === false;
126216
+ const prefix = local && kind === "prog" ? "\\PROGRAM=" + name
126217
+ : local && kind === "clas" ? "\\CLASS-POOL=" + name : "";
126218
+ const category = id instanceof abaplint.Types.InterfaceDefinition || kind === "intf" ? "INTERFACE" : "CLASS";
126219
+ RTTIName = prefix + "\\" + category + "=" + id.getName();
126220
+ }
126221
+ extra = "{qualifiedName: " + JSON.stringify(qualifiedName?.toUpperCase()) +
126222
+ ", RTTIName: " + JSON.stringify(RTTIName?.toUpperCase()) + "}";
125563
126223
  }
125564
126224
  else if (type instanceof abaplint.BasicTypes.TableType) {
125565
126225
  resolved = "Table";
@@ -125687,6 +126347,11 @@ class TranspileTypes {
125687
126347
  resolved = "Packed";
125688
126348
  extra = "{length: 8, decimals: 2}";
125689
126349
  }
126350
+ else if (type instanceof abaplint.BasicTypes.PGenericType) {
126351
+ // if not supplied its a P LENGTH 8 DECIMALS 0
126352
+ resolved = "Packed";
126353
+ extra = "{length: 8, decimals: 0}";
126354
+ }
125690
126355
  else if (type instanceof abaplint.BasicTypes.XStringType) {
125691
126356
  resolved = "XString";
125692
126357
  if (type.getQualifiedName() !== undefined) {
@@ -126112,7 +126777,7 @@ class Traversal {
126112
126777
  }
126113
126778
  return undefined;
126114
126779
  }
126115
- buildMethods(def) {
126780
+ buildMethods(def, scope) {
126116
126781
  const methods = [];
126117
126782
  if (def === undefined) {
126118
126783
  return methods;
@@ -126123,29 +126788,57 @@ class Traversal {
126123
126788
  throw new Error("buildMethods: unexpected undefined, " + def.getName());
126124
126789
  }
126125
126790
  for (const m of methodDefinitions.getAll()) {
126126
- const parameters = [];
126127
- for (const p of m.getParameters().getAll()) {
126128
- const type = transpile_types_1.TranspileTypes.toType(p.getType());
126129
- const optional = m.getParameters().getOptional().includes(p.getName()) ? "X" : " ";
126130
- let pKind = "";
126131
- if (pKind === "") {
126132
- pKind = m.getParameters().getImporting().find((t) => { return t.getName() === p.getName(); }) ? "I" : "";
126133
- }
126134
- if (pKind === "") {
126135
- pKind = m.getParameters().getChanging().find((t) => { return t.getName() === p.getName(); }) ? "C" : "";
126136
- }
126137
- if (pKind === "") {
126138
- pKind = m.getParameters().getExporting().find((t) => { return t.getName() === p.getName(); }) ? "E" : "";
126139
- }
126140
- if (pKind === "") {
126141
- pKind = m.getParameters().getReturning()?.getName() === p.getName() ? "R" : "";
126142
- }
126143
- parameters.push(`"${p.getName().toUpperCase()}": {"type": () => {return ${type};}, "is_optional": "${optional}", "parm_kind": "${pKind}", "type_name": "${p.getType().constructor.name}"}`);
126791
+ methods.push(this.buildMethod(m.getName(), m, m.getVisibility()));
126792
+ }
126793
+ // an alias for an interface method is listed under its own name, pointing to the method
126794
+ for (const a of def.getAliases() || []) {
126795
+ const [intfName, methodName] = a.getComponent().split("~");
126796
+ if (methodName === undefined) {
126797
+ continue;
126798
+ }
126799
+ const aliased = this.findInterfaceDefinition(intfName, scope)?.getMethodDefinitions()?.getByName(methodName);
126800
+ if (aliased === undefined) {
126801
+ // not a method, or the interface is unknown
126802
+ continue;
126144
126803
  }
126145
- methods.push(`"${m.getName().toUpperCase()}": {"visibility": "${this.mapVisibility(m.getVisibility())}", "parameters": {${parameters.join(", ")}}}`);
126804
+ methods.push(this.buildMethod(a.getName(), aliased, a.getVisibility(), a.getComponent()));
126146
126805
  }
126147
126806
  return methods;
126148
126807
  }
126808
+ buildMethod(name, m, visibility, aliasFor) {
126809
+ const optionalNames = m.getParameters().getOptional().map(o => o.toUpperCase());
126810
+ const parameters = [];
126811
+ for (const p of m.getParameters().getAll()) {
126812
+ const type = transpile_types_1.TranspileTypes.toType(p.getType());
126813
+ const optional = optionalNames.includes(p.getName().toUpperCase()) ? "X" : " ";
126814
+ let pKind = "";
126815
+ if (pKind === "") {
126816
+ pKind = m.getParameters().getImporting().find((t) => { return t.getName() === p.getName(); }) ? "I" : "";
126817
+ }
126818
+ if (pKind === "") {
126819
+ pKind = m.getParameters().getChanging().find((t) => { return t.getName() === p.getName(); }) ? "C" : "";
126820
+ }
126821
+ if (pKind === "") {
126822
+ pKind = m.getParameters().getExporting().find((t) => { return t.getName() === p.getName(); }) ? "E" : "";
126823
+ }
126824
+ if (pKind === "") {
126825
+ pKind = m.getParameters().getReturning()?.getName() === p.getName() ? "R" : "";
126826
+ }
126827
+ parameters.push(`"${p.getName().toUpperCase()}": {"type": () => {return ${type};}, "is_optional": "${optional}", "parm_kind": "${pKind}", "type_name": "${p.getType().constructor.name}"}`);
126828
+ }
126829
+ // only written when set, a method without them is described as before
126830
+ let extra = "";
126831
+ if (m.isStatic() === true) {
126832
+ extra += `"is_class": "X", `;
126833
+ }
126834
+ if (m.getRaising().length > 0) {
126835
+ extra += `"exceptions": [${m.getRaising().map(e => `"${e.toUpperCase()}"`).join(", ")}], `;
126836
+ }
126837
+ if (aliasFor !== undefined) {
126838
+ extra += `"alias_for": "${aliasFor.toUpperCase()}", `;
126839
+ }
126840
+ return `"${name.toUpperCase()}": {"visibility": "${this.mapVisibility(visibility)}", ${extra}"parameters": {${parameters.join(", ")}}}`;
126841
+ }
126149
126842
  mapVisibility(vis) {
126150
126843
  switch (vis) {
126151
126844
  case abaplint.Visibility.Private:
@@ -127039,8 +127732,13 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
127039
127732
  exports.UnitTest = void 0;
127040
127733
  /* eslint-disable max-len */
127041
127734
  const abaplint = __importStar(__webpack_require__(/*! @abaplint/core */ "./node_modules/@abaplint/core/build/src/index.js"));
127042
- const initialization_1 = __webpack_require__(/*! ./initialization */ "./node_modules/@abaplint/transpiler/build/src/initialization.js");
127735
+ const output_layout_1 = __webpack_require__(/*! ./output_layout */ "./node_modules/@abaplint/transpiler/build/src/output_layout.js");
127043
127736
  class UnitTest {
127737
+ layout;
127738
+ constructor(layout = new output_layout_1.OutputLayout()) {
127739
+ this.layout = layout;
127740
+ // Test runners live at the output root.
127741
+ }
127044
127742
  unitTestScriptOpen(reg, _skip) {
127045
127743
  let ret = `/* eslint-disable curly */
127046
127744
  import fs from "fs";
@@ -127061,7 +127759,7 @@ async function run() {
127061
127759
  }
127062
127760
  const hasTestFile = obj.getFiles().some(f => { return f.getFilename().includes(".testclasses."); });
127063
127761
  if (hasTestFile === true) {
127064
- ret += ` await import("./${(0, initialization_1.escapeNamespaceFilename)(obj.getName().toLowerCase())}.${obj.getType().toLowerCase()}.testclasses.mjs");\n`;
127762
+ ret += ` await import("${(0, output_layout_1.importPath)("index.mjs", this.layout.objectModule(obj, ".testclasses"))}");\n`;
127065
127763
  }
127066
127764
  for (const file of obj.getABAPFiles()) {
127067
127765
  for (const def of file.getInfo().listClassDefinitions()) {
@@ -127123,7 +127821,7 @@ run().then(() => {
127123
127821
  }
127124
127822
  tests.push({
127125
127823
  obj,
127126
- filename: `./${(0, initialization_1.escapeNamespaceFilename)(obj.getName().toLowerCase())}.${obj.getType().toLowerCase()}.testclasses.mjs`,
127824
+ filename: `${(0, output_layout_1.importPath)("index.mjs", this.layout.objectModule(obj, ".testclasses"))}`,
127127
127825
  localClass: def.name.toLowerCase(),
127128
127826
  riskLevel: def.riskLevel,
127129
127827
  duration: def.duration,
@@ -127268,8 +127966,12 @@ const core_1 = __webpack_require__(/*! @abaplint/core */ "./node_modules/@abapli
127268
127966
  const types_1 = __webpack_require__(/*! ./types */ "./node_modules/@abaplint/transpiler/build/src/types.js");
127269
127967
  const defaultAllowedObjectTypes = [
127270
127968
  "APIS",
127969
+ "APLO",
127271
127970
  "AUTH",
127971
+ "BDEF",
127272
127972
  "CLAS",
127973
+ "DDLS",
127974
+ "DDLX",
127273
127975
  "DEVC",
127274
127976
  "DOMA",
127275
127977
  "DTEL",
@@ -127291,13 +127993,19 @@ const defaultAllowedObjectTypes = [
127291
127993
  "PARA",
127292
127994
  "PINF",
127293
127995
  "PROG",
127996
+ "SAJC",
127997
+ "SAJT",
127998
+ "SCO2",
127294
127999
  "WAPA",
127295
128000
  "SHLP",
127296
128001
  "SHMA",
128002
+ "SIA6",
127297
128003
  "SICF",
127298
128004
  "SMIM",
127299
128005
  "SPLO",
127300
128006
  "SRFC",
128007
+ "SRVB",
128008
+ "SRVD",
127301
128009
  "SUSC",
127302
128010
  "SUSH",
127303
128011
  "SUSO",
@@ -127373,10 +128081,8 @@ exports.config = {
127373
128081
  // hmm this ^ is okay? since lines will be prefixed with "abap.builtin"?
127374
128082
  class Validation {
127375
128083
  options;
127376
- plugin;
127377
- constructor(options, plugin) {
128084
+ constructor(options) {
127378
128085
  this.options = options;
127379
- this.plugin = plugin;
127380
128086
  }
127381
128087
  run(reg) {
127382
128088
  if (this.options?.ignoreSyntaxCheck === true) {
@@ -127386,13 +128092,6 @@ class Validation {
127386
128092
  exports.config.rules.check_syntax = true;
127387
128093
  }
127388
128094
  exports.config.rules.forbidden_identifier.check = ["^unique\\d+$"];
127389
- const allowed = [...defaultAllowedObjectTypes];
127390
- for (const type of this.plugin?.objectTypes() || []) {
127391
- if (allowed.includes(type.toUpperCase()) === false) {
127392
- allowed.push(type.toUpperCase());
127393
- }
127394
- }
127395
- exports.config.rules.allowed_object_types.allowed = allowed;
127396
128095
  if (this.options?.unknownTypes === types_1.UnknownTypesEnum.runtimeError) {
127397
128096
  // this is not a constant, just a regex that happens to not match anything
127398
128097
  exports.config.syntax.errorNamespace = "VOID_EVERYTHING";
@@ -130878,17 +131577,6 @@ module.exports = require("fs");
130878
131577
 
130879
131578
  /***/ },
130880
131579
 
130881
- /***/ "module"
130882
- /*!*************************!*\
130883
- !*** external "module" ***!
130884
- \*************************/
130885
- (module) {
130886
-
130887
- "use strict";
130888
- module.exports = require("module");
130889
-
130890
- /***/ },
130891
-
130892
131580
  /***/ "node:events"
130893
131581
  /*!******************************!*\
130894
131582
  !*** external "node:events" ***!