@abaplint/transpiler-cli 2.14.1 → 2.14.3
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/README.md +22 -6
- package/build/bundle.js +884 -240
- package/build/types.d.ts +2 -0
- package/package.json +3 -3
package/build/bundle.js
CHANGED
|
@@ -71,6 +71,7 @@ class TranspilerConfig {
|
|
|
71
71
|
input_folder: "src",
|
|
72
72
|
input_filter: [],
|
|
73
73
|
output_folder: "output",
|
|
74
|
+
incremental_output: false,
|
|
74
75
|
libs: [
|
|
75
76
|
{ "url": "https://github.com/open-abap/open-abap-core" },
|
|
76
77
|
],
|
|
@@ -314,14 +315,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
314
315
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
315
316
|
};
|
|
316
317
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
317
|
-
const fs = __importStar(__webpack_require__(/*! fs */ "fs"));
|
|
318
|
-
const path = __importStar(__webpack_require__(/*! path */ "path"));
|
|
319
318
|
const progress_1 = __importDefault(__webpack_require__(/*! progress */ "./node_modules/progress/index.js"));
|
|
320
319
|
const Transpiler = __importStar(__webpack_require__(/*! @abaplint/transpiler */ "./node_modules/@abaplint/transpiler/build/src/index.js"));
|
|
321
320
|
const config_1 = __webpack_require__(/*! ./config */ "./build/config.js");
|
|
322
321
|
const file_operations_1 = __webpack_require__(/*! ./file_operations */ "./build/file_operations.js");
|
|
323
322
|
const libraries_1 = __webpack_require__(/*! ./libraries */ "./build/libraries.js");
|
|
324
323
|
const write_objects_1 = __webpack_require__(/*! ./write_objects */ "./build/write_objects.js");
|
|
324
|
+
const output_writer_1 = __webpack_require__(/*! ./output_writer */ "./build/output_writer.js");
|
|
325
325
|
class Progress {
|
|
326
326
|
bar;
|
|
327
327
|
set(total, _text) {
|
|
@@ -351,23 +351,23 @@ async function run() {
|
|
|
351
351
|
console.log("\nBuilding");
|
|
352
352
|
const { output, sources } = await build(config, files);
|
|
353
353
|
console.log("\nOutput");
|
|
354
|
-
const
|
|
355
|
-
if (!fs.existsSync(outputFolder)) {
|
|
356
|
-
fs.mkdirSync(outputFolder, { recursive: true });
|
|
357
|
-
}
|
|
358
|
-
await (0, write_objects_1.writeObjects)(output.objects, config, sources);
|
|
359
|
-
console.log(output.objects.length + " objects written to disk");
|
|
354
|
+
const artifacts = (0, write_objects_1.collectObjectFiles)(output.objects, config, sources);
|
|
360
355
|
if (config.write_unit_tests === true) {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
356
|
+
artifacts.push({ path: "index.mjs", contents: output.unitTestScript });
|
|
357
|
+
artifacts.push({ path: "_unit_open.mjs", contents: output.unitTestScriptOpen });
|
|
358
|
+
}
|
|
359
|
+
artifacts.push({ path: "init.mjs", contents: output.initializationScript });
|
|
360
|
+
artifacts.push({ path: "_init.mjs", contents: output.initializationScript2 });
|
|
361
|
+
artifacts.push({ path: "_top.mjs", contents: `import runtime from "@abaplint/runtime";
|
|
362
|
+
globalThis.abap = new runtime.ABAP();` });
|
|
363
|
+
const written = await (0, output_writer_1.writeOutput)(config.output_folder, artifacts, config.incremental_output === true);
|
|
364
|
+
if (config.incremental_output === true) {
|
|
365
|
+
console.log("Output files: " + written.created + " created, " +
|
|
366
|
+
written.updated + " updated, " + written.unchanged + " unchanged, " + written.deleted + " deleted");
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
console.log(`Output files: ${written.updated} written`);
|
|
364
370
|
}
|
|
365
|
-
// breaking change? rename this output file,
|
|
366
|
-
fs.writeFileSync(outputFolder + path.sep + "init.mjs", output.initializationScript);
|
|
367
|
-
// new static referenced imports,
|
|
368
|
-
fs.writeFileSync(outputFolder + path.sep + "_init.mjs", output.initializationScript2);
|
|
369
|
-
fs.writeFileSync(outputFolder + path.sep + "_top.mjs", `import runtime from "@abaplint/runtime";
|
|
370
|
-
globalThis.abap = new runtime.ABAP();`);
|
|
371
371
|
}
|
|
372
372
|
run().then(() => {
|
|
373
373
|
process.exit();
|
|
@@ -491,6 +491,11 @@ const abaplint = __importStar(__webpack_require__(/*! @abaplint/core */ "./node_
|
|
|
491
491
|
const file_operations_1 = __webpack_require__(/*! ./file_operations */ "./build/file_operations.js");
|
|
492
492
|
const git_clone_1 = __webpack_require__(/*! ./git_clone */ "./build/git_clone.js");
|
|
493
493
|
const lib_folder_1 = __webpack_require__(/*! ./lib_folder */ "./build/lib_folder.js");
|
|
494
|
+
function logicalLibrarySource(library, directory, filename) {
|
|
495
|
+
const relative = path.relative(directory, filename).split(path.sep)
|
|
496
|
+
.map(segment => encodeURIComponent(segment)).join("/");
|
|
497
|
+
return "abaplint://" + encodeURIComponent(library) + "/" + relative;
|
|
498
|
+
}
|
|
494
499
|
function libraryNames(libs) {
|
|
495
500
|
const used = new Set(["project"]);
|
|
496
501
|
return libs.map(lib => {
|
|
@@ -514,6 +519,7 @@ async function loadLibraries(config) {
|
|
|
514
519
|
const names = libraryNames(libs);
|
|
515
520
|
const result = [];
|
|
516
521
|
for (const [index, lib] of libs.entries()) {
|
|
522
|
+
const libraryName = names[index];
|
|
517
523
|
let dir;
|
|
518
524
|
let cleanupFolder = false;
|
|
519
525
|
const folder = (0, lib_folder_1.resolveLibFolder)(lib.folder, process.cwd());
|
|
@@ -547,8 +553,15 @@ async function loadLibraries(config) {
|
|
|
547
553
|
filesToRead.add(filename);
|
|
548
554
|
}
|
|
549
555
|
}
|
|
550
|
-
const
|
|
551
|
-
|
|
556
|
+
const filenames = [...filesToRead];
|
|
557
|
+
const files = await file_operations_1.FileOperations.readAllFiles(filenames, config.output_folder);
|
|
558
|
+
if (cleanupFolder) {
|
|
559
|
+
for (const [index, file] of files.entries()) {
|
|
560
|
+
file.sourceMapPath = logicalLibrarySource(libraryName, dir, filenames[index]);
|
|
561
|
+
delete file.relative;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
result.push({ name: libraryName, files });
|
|
552
565
|
console.log("\t" + files.length + " files added from lib");
|
|
553
566
|
}
|
|
554
567
|
finally {
|
|
@@ -604,6 +617,347 @@ function libraryRegistry(files, libraries, skipDuplicateDependencies = false) {
|
|
|
604
617
|
|
|
605
618
|
/***/ },
|
|
606
619
|
|
|
620
|
+
/***/ "./build/output_writer.js"
|
|
621
|
+
/*!********************************!*\
|
|
622
|
+
!*** ./build/output_writer.js ***!
|
|
623
|
+
\********************************/
|
|
624
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
625
|
+
|
|
626
|
+
"use strict";
|
|
627
|
+
|
|
628
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
629
|
+
if (k2 === undefined) k2 = k;
|
|
630
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
631
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
632
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
633
|
+
}
|
|
634
|
+
Object.defineProperty(o, k2, desc);
|
|
635
|
+
}) : (function(o, m, k, k2) {
|
|
636
|
+
if (k2 === undefined) k2 = k;
|
|
637
|
+
o[k2] = m[k];
|
|
638
|
+
}));
|
|
639
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
640
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
641
|
+
}) : function(o, v) {
|
|
642
|
+
o["default"] = v;
|
|
643
|
+
});
|
|
644
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
645
|
+
var ownKeys = function(o) {
|
|
646
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
647
|
+
var ar = [];
|
|
648
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
649
|
+
return ar;
|
|
650
|
+
};
|
|
651
|
+
return ownKeys(o);
|
|
652
|
+
};
|
|
653
|
+
return function (mod) {
|
|
654
|
+
if (mod && mod.__esModule) return mod;
|
|
655
|
+
var result = {};
|
|
656
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
657
|
+
__setModuleDefault(result, mod);
|
|
658
|
+
return result;
|
|
659
|
+
};
|
|
660
|
+
})();
|
|
661
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
662
|
+
exports.writeOutput = writeOutput;
|
|
663
|
+
const fsPromises = __importStar(__webpack_require__(/*! node:fs/promises */ "node:fs/promises"));
|
|
664
|
+
const os = __importStar(__webpack_require__(/*! node:os */ "node:os"));
|
|
665
|
+
const path = __importStar(__webpack_require__(/*! node:path */ "node:path"));
|
|
666
|
+
const file_operations_1 = __webpack_require__(/*! ./file_operations */ "./build/file_operations.js");
|
|
667
|
+
const MANIFEST = ".abap-transpile-manifest.json";
|
|
668
|
+
function concurrency() {
|
|
669
|
+
return Math.max(1, Math.min(8, os.cpus().length));
|
|
670
|
+
}
|
|
671
|
+
async function forEachLimit(items, task, limit = concurrency()) {
|
|
672
|
+
let next = 0;
|
|
673
|
+
const workers = Array.from({ length: Math.min(limit, items.length) }, async () => {
|
|
674
|
+
while (next < items.length) {
|
|
675
|
+
const index = next++;
|
|
676
|
+
await task(items[index]);
|
|
677
|
+
}
|
|
678
|
+
});
|
|
679
|
+
const results = await Promise.allSettled(workers);
|
|
680
|
+
const failed = results.find(result => result.status === "rejected");
|
|
681
|
+
if (failed?.status === "rejected") {
|
|
682
|
+
throw failed.reason;
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
function normalizeRelative(filename, label) {
|
|
686
|
+
if (filename.length === 0 || filename.startsWith("/") || filename.includes("\\")
|
|
687
|
+
|| /^[a-zA-Z]:/.test(filename)) {
|
|
688
|
+
throw new Error("Invalid " + label + " path: " + filename);
|
|
689
|
+
}
|
|
690
|
+
const segments = filename.split("/");
|
|
691
|
+
if (segments.some(segment => segment.length === 0 || segment === "." || segment === "..")) {
|
|
692
|
+
throw new Error("Invalid " + label + " path: " + filename);
|
|
693
|
+
}
|
|
694
|
+
return segments.join("/");
|
|
695
|
+
}
|
|
696
|
+
function validatePaths(filenames, label) {
|
|
697
|
+
const paths = new Map();
|
|
698
|
+
for (const filename of filenames) {
|
|
699
|
+
if (typeof filename !== "string") {
|
|
700
|
+
throw new Error("Invalid " + label + " path");
|
|
701
|
+
}
|
|
702
|
+
const relative = normalizeRelative(filename, label);
|
|
703
|
+
const key = relative.toLowerCase();
|
|
704
|
+
if (key === MANIFEST || key.startsWith(MANIFEST + "/")) {
|
|
705
|
+
throw new Error("Reserved " + label + " path: " + relative);
|
|
706
|
+
}
|
|
707
|
+
const existing = paths.get(key);
|
|
708
|
+
if (existing !== undefined) {
|
|
709
|
+
throw new Error("Conflicting " + label + " paths: " + existing + " and " + relative);
|
|
710
|
+
}
|
|
711
|
+
paths.set(key, relative);
|
|
712
|
+
}
|
|
713
|
+
for (const filename of paths.values()) {
|
|
714
|
+
const segments = filename.split("/");
|
|
715
|
+
for (let index = 1; index < segments.length; index++) {
|
|
716
|
+
if (paths.has(segments.slice(0, index).join("/").toLowerCase())) {
|
|
717
|
+
throw new Error("Conflicting " + label + " file and directory paths: " + filename);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
return [...paths.values()];
|
|
722
|
+
}
|
|
723
|
+
function validateArtifactPaths(artifacts) {
|
|
724
|
+
const paths = validatePaths(artifacts.map(artifact => artifact.path.replace(/\\/g, "/")), "output");
|
|
725
|
+
return artifacts.map((artifact, index) => ({
|
|
726
|
+
...artifact,
|
|
727
|
+
relative: paths[index],
|
|
728
|
+
byteLength: Buffer.byteLength(artifact.contents, file_operations_1.FileOperations.isBinaryFilename(paths[index]) ? "latin1" : "utf8"),
|
|
729
|
+
binary: file_operations_1.FileOperations.isBinaryFilename(paths[index]),
|
|
730
|
+
}));
|
|
731
|
+
}
|
|
732
|
+
function parseManifest(contents) {
|
|
733
|
+
let parsed;
|
|
734
|
+
try {
|
|
735
|
+
parsed = JSON.parse(contents);
|
|
736
|
+
}
|
|
737
|
+
catch (error) {
|
|
738
|
+
throw new Error("Invalid incremental output manifest JSON: " + String(error));
|
|
739
|
+
}
|
|
740
|
+
if (typeof parsed !== "object" || parsed === null || !("version" in parsed) || !("files" in parsed)
|
|
741
|
+
|| parsed.version !== 1 || !Array.isArray(parsed.files)) {
|
|
742
|
+
throw new Error("Unsupported incremental output manifest");
|
|
743
|
+
}
|
|
744
|
+
return { version: 1, files: validatePaths(parsed.files, "incremental output manifest") };
|
|
745
|
+
}
|
|
746
|
+
function serializeManifest(files) {
|
|
747
|
+
return JSON.stringify({ version: 1, files: [...files].sort() }, null, 2) + "\n";
|
|
748
|
+
}
|
|
749
|
+
async function lstatOrMissing(filename) {
|
|
750
|
+
try {
|
|
751
|
+
return await fsPromises.lstat(filename);
|
|
752
|
+
}
|
|
753
|
+
catch (error) {
|
|
754
|
+
if (error.code === "ENOENT") {
|
|
755
|
+
return undefined;
|
|
756
|
+
}
|
|
757
|
+
throw error;
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
function isBelowRoot(root, filename) {
|
|
761
|
+
const relative = path.relative(root, filename);
|
|
762
|
+
return relative !== "" && relative !== ".." && !relative.startsWith(".." + path.sep) && !path.isAbsolute(relative);
|
|
763
|
+
}
|
|
764
|
+
async function inspectPaths(root, relativePaths, rootStats, ioConcurrency) {
|
|
765
|
+
const metadata = new Map();
|
|
766
|
+
const nodes = new Map();
|
|
767
|
+
for (const filename of relativePaths) {
|
|
768
|
+
const segments = filename.split("/");
|
|
769
|
+
for (let index = 1; index <= segments.length; index++) {
|
|
770
|
+
const relative = segments.slice(0, index).join("/");
|
|
771
|
+
const isDirectory = index < segments.length;
|
|
772
|
+
nodes.set(relative, (nodes.get(relative) ?? false) || isDirectory);
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
if (rootStats !== undefined) {
|
|
776
|
+
const byDepth = new Map();
|
|
777
|
+
for (const relative of nodes.keys()) {
|
|
778
|
+
const depth = relative.split("/").length;
|
|
779
|
+
const group = byDepth.get(depth) ?? [];
|
|
780
|
+
group.push(relative);
|
|
781
|
+
byDepth.set(depth, group);
|
|
782
|
+
}
|
|
783
|
+
for (const depth of [...byDepth.keys()].sort((a, b) => a - b)) {
|
|
784
|
+
const candidates = byDepth.get(depth).filter(relative => {
|
|
785
|
+
const parent = path.posix.dirname(relative);
|
|
786
|
+
return depth === 1 || metadata.get(parent)?.isDirectory() === true;
|
|
787
|
+
});
|
|
788
|
+
await forEachLimit(candidates, async (relative) => {
|
|
789
|
+
const absolute = path.resolve(root, ...relative.split("/"));
|
|
790
|
+
const stat = await lstatOrMissing(absolute);
|
|
791
|
+
if (stat?.isSymbolicLink()) {
|
|
792
|
+
throw new Error("Output path must not traverse a symlink: " + relative);
|
|
793
|
+
}
|
|
794
|
+
if (stat !== undefined && nodes.get(relative) === true && !stat.isDirectory()) {
|
|
795
|
+
throw new Error("Output path parent is not a directory: " + relative);
|
|
796
|
+
}
|
|
797
|
+
if (stat !== undefined && nodes.get(relative) === false && !stat.isFile()) {
|
|
798
|
+
throw new Error("Generated output path is not a regular file: " + relative);
|
|
799
|
+
}
|
|
800
|
+
metadata.set(relative, stat);
|
|
801
|
+
}, ioConcurrency);
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
else {
|
|
805
|
+
for (const relative of nodes.keys()) {
|
|
806
|
+
metadata.set(relative, undefined);
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
return metadata;
|
|
810
|
+
}
|
|
811
|
+
async function atomicWriteManifest(root, contents, current) {
|
|
812
|
+
if (current === contents) {
|
|
813
|
+
return;
|
|
814
|
+
}
|
|
815
|
+
await fsPromises.mkdir(root, { recursive: true });
|
|
816
|
+
const temporary = path.join(root, MANIFEST + ".tmp-" + process.pid + "-" + Math.random().toString(36).slice(2));
|
|
817
|
+
try {
|
|
818
|
+
await fsPromises.writeFile(temporary, contents, { flag: "wx", encoding: "utf8" });
|
|
819
|
+
await fsPromises.rename(temporary, path.join(root, MANIFEST));
|
|
820
|
+
}
|
|
821
|
+
catch (error) {
|
|
822
|
+
try {
|
|
823
|
+
await fsPromises.unlink(temporary);
|
|
824
|
+
}
|
|
825
|
+
catch {
|
|
826
|
+
// The temporary file can be absent when creation failed.
|
|
827
|
+
}
|
|
828
|
+
throw error;
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
async function writeOutput(rootFolder, artifacts, incremental, ioConcurrency = concurrency()) {
|
|
832
|
+
const root = path.resolve(rootFolder);
|
|
833
|
+
const prepared = validateArtifactPaths(artifacts);
|
|
834
|
+
const result = {
|
|
835
|
+
created: 0, updated: 0, unchanged: 0, deleted: 0,
|
|
836
|
+
};
|
|
837
|
+
if (!incremental) {
|
|
838
|
+
const files = prepared.map(file => ({ path: path.resolve(root, file.relative), contents: file.contents }));
|
|
839
|
+
await file_operations_1.FileOperations.writeFiles(files);
|
|
840
|
+
result.updated = files.length;
|
|
841
|
+
return result;
|
|
842
|
+
}
|
|
843
|
+
const manifestPath = path.join(root, MANIFEST);
|
|
844
|
+
const rootStats = await lstatOrMissing(root);
|
|
845
|
+
if (rootStats?.isSymbolicLink()) {
|
|
846
|
+
throw new Error("Output folder must not be a symlink: " + root);
|
|
847
|
+
}
|
|
848
|
+
if (rootStats !== undefined && !rootStats.isDirectory()) {
|
|
849
|
+
throw new Error("Output folder is not a directory: " + root);
|
|
850
|
+
}
|
|
851
|
+
let manifestContents;
|
|
852
|
+
let previous = [];
|
|
853
|
+
if (rootStats !== undefined) {
|
|
854
|
+
const manifestStat = await lstatOrMissing(manifestPath);
|
|
855
|
+
if (manifestStat?.isSymbolicLink() || (manifestStat !== undefined && !manifestStat.isFile())) {
|
|
856
|
+
throw new Error("Incremental output manifest must be a regular file");
|
|
857
|
+
}
|
|
858
|
+
if (manifestStat !== undefined) {
|
|
859
|
+
const contents = await fsPromises.readFile(manifestPath, "utf8");
|
|
860
|
+
manifestContents = contents;
|
|
861
|
+
previous = parseManifest(contents).files;
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
// A path can belong to both inventories; each inventory rejects its own duplicates.
|
|
865
|
+
validatePaths([...new Set([...prepared.map(file => file.relative), ...previous])], "incremental output");
|
|
866
|
+
const previousPaths = new Set(previous);
|
|
867
|
+
const current = new Set(prepared.map(file => file.relative));
|
|
868
|
+
const stale = previous.filter(filename => !current.has(filename));
|
|
869
|
+
const additions = prepared.some(file => !previousPaths.has(file.relative));
|
|
870
|
+
const pathsToInspect = [...new Set([...prepared.map(file => file.relative), ...stale])];
|
|
871
|
+
const metadata = await inspectPaths(root, pathsToInspect, rootStats, ioConcurrency);
|
|
872
|
+
await forEachLimit(prepared, async (file) => {
|
|
873
|
+
const stat = metadata.get(file.relative);
|
|
874
|
+
file.existed = stat !== undefined;
|
|
875
|
+
if (stat === undefined || stat.size !== file.byteLength) {
|
|
876
|
+
file.changed = true;
|
|
877
|
+
return;
|
|
878
|
+
}
|
|
879
|
+
let existing;
|
|
880
|
+
try {
|
|
881
|
+
existing = await fsPromises.readFile(path.resolve(root, ...file.relative.split("/")));
|
|
882
|
+
}
|
|
883
|
+
catch (error) {
|
|
884
|
+
if (error.code === "ENOENT") {
|
|
885
|
+
file.existed = false;
|
|
886
|
+
file.changed = true;
|
|
887
|
+
return;
|
|
888
|
+
}
|
|
889
|
+
throw error;
|
|
890
|
+
}
|
|
891
|
+
const generated = Buffer.from(file.contents, file.binary ? "latin1" : "utf8");
|
|
892
|
+
file.changed = !existing.equals(generated);
|
|
893
|
+
}, ioConcurrency);
|
|
894
|
+
if (additions) {
|
|
895
|
+
const union = serializeManifest(new Set([...previous, ...current]));
|
|
896
|
+
await atomicWriteManifest(root, union, manifestContents);
|
|
897
|
+
manifestContents = union;
|
|
898
|
+
}
|
|
899
|
+
const toWrite = prepared.filter(file => file.changed);
|
|
900
|
+
const directories = new Map();
|
|
901
|
+
for (const file of toWrite) {
|
|
902
|
+
const segments = file.relative.split("/");
|
|
903
|
+
for (let index = 1; index < segments.length; index++) {
|
|
904
|
+
const relative = segments.slice(0, index).join("/");
|
|
905
|
+
if (metadata.get(relative) === undefined) {
|
|
906
|
+
directories.set(relative, index);
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
const directoryDepths = [...new Set(directories.values())].sort((a, b) => a - b);
|
|
911
|
+
for (const depth of directoryDepths) {
|
|
912
|
+
const atDepth = [...directories.entries()].filter(([, candidateDepth]) => candidateDepth === depth)
|
|
913
|
+
.map(([relative]) => path.resolve(root, ...relative.split("/")));
|
|
914
|
+
await forEachLimit(atDepth, async (directory) => {
|
|
915
|
+
await fsPromises.mkdir(directory);
|
|
916
|
+
}, ioConcurrency);
|
|
917
|
+
}
|
|
918
|
+
await forEachLimit(toWrite, async (file) => {
|
|
919
|
+
await fsPromises.writeFile(path.resolve(root, ...file.relative.split("/")), file.contents, file.binary ? { encoding: "latin1" } : undefined);
|
|
920
|
+
}, ioConcurrency);
|
|
921
|
+
const staleFiles = stale.map(filename => path.resolve(root, ...filename.split("/")));
|
|
922
|
+
const removedDirectories = new Set();
|
|
923
|
+
for (const filename of staleFiles) {
|
|
924
|
+
try {
|
|
925
|
+
await fsPromises.unlink(filename);
|
|
926
|
+
result.deleted++;
|
|
927
|
+
}
|
|
928
|
+
catch (error) {
|
|
929
|
+
if (error.code !== "ENOENT") {
|
|
930
|
+
throw error;
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
let directory = path.dirname(filename);
|
|
934
|
+
while (isBelowRoot(root, directory)) {
|
|
935
|
+
removedDirectories.add(directory);
|
|
936
|
+
directory = path.dirname(directory);
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
await forEachLimit([...removedDirectories].sort((a, b) => b.length - a.length), async (directory) => {
|
|
940
|
+
try {
|
|
941
|
+
await fsPromises.rmdir(directory);
|
|
942
|
+
}
|
|
943
|
+
catch (error) {
|
|
944
|
+
const code = error.code;
|
|
945
|
+
if (code !== "ENOENT" && code !== "ENOTEMPTY" && code !== "EEXIST") {
|
|
946
|
+
throw error;
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
});
|
|
950
|
+
const finalManifest = serializeManifest(current);
|
|
951
|
+
await atomicWriteManifest(root, finalManifest, manifestContents);
|
|
952
|
+
result.created = prepared.filter(file => file.changed && !file.existed).length;
|
|
953
|
+
result.updated = prepared.filter(file => file.changed && file.existed).length;
|
|
954
|
+
result.unchanged = prepared.filter(file => !file.changed).length;
|
|
955
|
+
return result;
|
|
956
|
+
}
|
|
957
|
+
//# sourceMappingURL=output_writer.js.map
|
|
958
|
+
|
|
959
|
+
/***/ },
|
|
960
|
+
|
|
607
961
|
/***/ "./build/write_objects.js"
|
|
608
962
|
/*!********************************!*\
|
|
609
963
|
!*** ./build/write_objects.js ***!
|
|
@@ -646,28 +1000,16 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
646
1000
|
};
|
|
647
1001
|
})();
|
|
648
1002
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
649
|
-
exports.
|
|
1003
|
+
exports.collectObjectFiles = collectObjectFiles;
|
|
650
1004
|
const path = __importStar(__webpack_require__(/*! path */ "path"));
|
|
651
1005
|
const url_1 = __webpack_require__(/*! url */ "url");
|
|
652
1006
|
const transpiler_1 = __webpack_require__(/*! @abaplint/transpiler */ "./node_modules/@abaplint/transpiler/build/src/index.js");
|
|
653
|
-
|
|
654
|
-
async function writeObjects(outputFiles, config, files) {
|
|
1007
|
+
function collectObjectFiles(outputFiles, config, files) {
|
|
655
1008
|
const root = path.resolve(config.output_folder);
|
|
656
1009
|
const filesToWrite = [];
|
|
657
|
-
const destinations = new Set();
|
|
658
1010
|
const sources = new Map(files.map(file => [file.filename.toLowerCase(), file]));
|
|
659
1011
|
const add = (filename, contents) => {
|
|
660
|
-
|
|
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 });
|
|
1012
|
+
filesToWrite.push({ path: filename.replace(/\\/g, "/"), contents });
|
|
671
1013
|
};
|
|
672
1014
|
for (const output of outputFiles) {
|
|
673
1015
|
const type = output.object.type.toUpperCase();
|
|
@@ -688,21 +1030,24 @@ async function writeObjects(outputFiles, config, files) {
|
|
|
688
1030
|
if (file === undefined) {
|
|
689
1031
|
continue;
|
|
690
1032
|
}
|
|
691
|
-
if (file.
|
|
1033
|
+
if (file.sourceMapPath !== undefined) {
|
|
1034
|
+
sourcePaths[filename] = file.sourceMapPath;
|
|
1035
|
+
}
|
|
1036
|
+
else if (file.relative !== undefined) {
|
|
692
1037
|
const source = path.resolve(root, file.relative, file.filename);
|
|
693
1038
|
const relative = path.relative(mapDirectory, source);
|
|
694
1039
|
// Sources on another Windows drive cannot be expressed as relative paths.
|
|
695
1040
|
sourcePaths[filename] = path.isAbsolute(relative) ? (0, url_1.pathToFileURL)(source).href
|
|
696
1041
|
: relative.split(path.sep).map(segment => encodeURIComponent(segment)).join("/");
|
|
697
1042
|
}
|
|
698
|
-
//
|
|
1043
|
+
// Embedding source text keeps maps useful after temporary checkouts are removed.
|
|
699
1044
|
sourceContents[filename] = file.contents;
|
|
700
1045
|
}
|
|
701
1046
|
add(name, output.chunk.getMap(path.basename(output.filename), { generatedLineOffset, sourcePaths, sourceContents }));
|
|
702
1047
|
}
|
|
703
1048
|
add(output.filename, contents);
|
|
704
1049
|
}
|
|
705
|
-
|
|
1050
|
+
return filesToWrite;
|
|
706
1051
|
}
|
|
707
1052
|
//# sourceMappingURL=write_objects.js.map
|
|
708
1053
|
|
|
@@ -1060,7 +1405,7 @@ class Lexer {
|
|
|
1060
1405
|
else if (this.m === ModeTemplate
|
|
1061
1406
|
&& this.buffer.length() > 1
|
|
1062
1407
|
&& (current === CH_PIPE || current === CH_LBRACE)
|
|
1063
|
-
&&
|
|
1408
|
+
&& stream.countPrevious(CH_BACKSLASH) % 2 === 0) {
|
|
1064
1409
|
// end of template
|
|
1065
1410
|
if (current === CH_LBRACE || AFTER_LITERAL.has(ahead)) {
|
|
1066
1411
|
this.add();
|
|
@@ -1214,6 +1559,14 @@ class LexerStream {
|
|
|
1214
1559
|
}
|
|
1215
1560
|
return this.raw.charCodeAt(o);
|
|
1216
1561
|
}
|
|
1562
|
+
/** number of consecutive occurrences of the character directly before the current one */
|
|
1563
|
+
countPrevious(code) {
|
|
1564
|
+
let count = 0;
|
|
1565
|
+
for (let o = this.offset - 1; o >= 0 && this.raw.charCodeAt(o) === code; o--) {
|
|
1566
|
+
count++;
|
|
1567
|
+
}
|
|
1568
|
+
return count;
|
|
1569
|
+
}
|
|
1217
1570
|
currentChar() {
|
|
1218
1571
|
if (this.offset < 0) {
|
|
1219
1572
|
return NL; // simulate newline at start of file to handle star(*) comments
|
|
@@ -21213,6 +21566,21 @@ exports.sta = sta;
|
|
|
21213
21566
|
exports.sub = sub;
|
|
21214
21567
|
const nodes_1 = __webpack_require__(/*! ../../nodes */ "./node_modules/@abaplint/core/build/src/abap/nodes/index.js");
|
|
21215
21568
|
const _statement_1 = __webpack_require__(/*! ../../2_statements/statements/_statement */ "./node_modules/@abaplint/core/build/src/abap/2_statements/statements/_statement.js");
|
|
21569
|
+
function toMatch(statements, m) {
|
|
21570
|
+
return {
|
|
21571
|
+
matched: statements.slice(0, m.next),
|
|
21572
|
+
unmatched: statements.slice(m.next),
|
|
21573
|
+
error: m.error,
|
|
21574
|
+
errorDescription: m.errorDescription,
|
|
21575
|
+
errorMatched: m.errorMatched,
|
|
21576
|
+
};
|
|
21577
|
+
}
|
|
21578
|
+
function success(next) {
|
|
21579
|
+
return { next, error: false, errorDescription: "", errorMatched: 0 };
|
|
21580
|
+
}
|
|
21581
|
+
function failure(next, errorDescription, errorMatched) {
|
|
21582
|
+
return { next, error: true, errorDescription, errorMatched };
|
|
21583
|
+
}
|
|
21216
21584
|
class Sequence {
|
|
21217
21585
|
constructor(list) {
|
|
21218
21586
|
if (list.length < 2) {
|
|
@@ -21231,36 +21599,18 @@ class Sequence {
|
|
|
21231
21599
|
return this.list[0].first();
|
|
21232
21600
|
}
|
|
21233
21601
|
run(statements, parent) {
|
|
21234
|
-
|
|
21235
|
-
|
|
21602
|
+
return toMatch(statements, this.runAt(statements, 0, parent));
|
|
21603
|
+
}
|
|
21604
|
+
runAt(statements, index, parent) {
|
|
21605
|
+
let next = index;
|
|
21236
21606
|
for (const i of this.list) {
|
|
21237
|
-
const match = i.
|
|
21607
|
+
const match = i.runAt(statements, next, parent);
|
|
21238
21608
|
if (match.error) {
|
|
21239
|
-
return
|
|
21240
|
-
matched: [],
|
|
21241
|
-
unmatched: statements,
|
|
21242
|
-
error: true,
|
|
21243
|
-
errorDescription: match.errorDescription,
|
|
21244
|
-
errorMatched: out.length,
|
|
21245
|
-
};
|
|
21246
|
-
}
|
|
21247
|
-
if (match.matched.length < 100) {
|
|
21248
|
-
out.push(...match.matched);
|
|
21249
|
-
}
|
|
21250
|
-
else {
|
|
21251
|
-
// avoid using the spread operator, it might trigger "Maximum call stack size exceeded"
|
|
21252
|
-
// when the number of matched elements is very large
|
|
21253
|
-
out = out.concat(match.matched);
|
|
21609
|
+
return failure(index, match.errorDescription, next - index);
|
|
21254
21610
|
}
|
|
21255
|
-
|
|
21611
|
+
next = match.next;
|
|
21256
21612
|
}
|
|
21257
|
-
return
|
|
21258
|
-
matched: out,
|
|
21259
|
-
unmatched: inn,
|
|
21260
|
-
error: false,
|
|
21261
|
-
errorDescription: "",
|
|
21262
|
-
errorMatched: 0,
|
|
21263
|
-
};
|
|
21613
|
+
return success(next);
|
|
21264
21614
|
}
|
|
21265
21615
|
}
|
|
21266
21616
|
// Note that the Alternative does not nessesarily return the first in the alternative
|
|
@@ -21299,21 +21649,18 @@ class Alternative {
|
|
|
21299
21649
|
return this.list.reduce((a, c) => { return a.concat(c.getUsing()); }, []);
|
|
21300
21650
|
}
|
|
21301
21651
|
run(statements, parent) {
|
|
21652
|
+
return toMatch(statements, this.runAt(statements, 0, parent));
|
|
21653
|
+
}
|
|
21654
|
+
runAt(statements, index, parent) {
|
|
21302
21655
|
this.setupMap();
|
|
21303
21656
|
let count = 0;
|
|
21304
21657
|
let countError = "";
|
|
21305
|
-
if (statements.length
|
|
21306
|
-
return
|
|
21307
|
-
matched: [],
|
|
21308
|
-
unmatched: statements,
|
|
21309
|
-
error: true,
|
|
21310
|
-
errorDescription: countError,
|
|
21311
|
-
errorMatched: count,
|
|
21312
|
-
};
|
|
21658
|
+
if (index >= statements.length) {
|
|
21659
|
+
return failure(index, countError, count);
|
|
21313
21660
|
}
|
|
21314
|
-
const token = statements[
|
|
21661
|
+
const token = statements[index].getFirstToken().getStr().toUpperCase();
|
|
21315
21662
|
for (const i of this.map[token] || []) {
|
|
21316
|
-
const match = i.
|
|
21663
|
+
const match = i.runAt(statements, index, parent);
|
|
21317
21664
|
if (match.error === false) {
|
|
21318
21665
|
return match;
|
|
21319
21666
|
}
|
|
@@ -21323,7 +21670,7 @@ class Alternative {
|
|
|
21323
21670
|
}
|
|
21324
21671
|
}
|
|
21325
21672
|
for (const i of this.map[""] || []) {
|
|
21326
|
-
const match = i.
|
|
21673
|
+
const match = i.runAt(statements, index, parent);
|
|
21327
21674
|
if (match.error === false) {
|
|
21328
21675
|
return match;
|
|
21329
21676
|
}
|
|
@@ -21333,22 +21680,10 @@ class Alternative {
|
|
|
21333
21680
|
}
|
|
21334
21681
|
}
|
|
21335
21682
|
if (count === 0) {
|
|
21336
|
-
return
|
|
21337
|
-
matched: [],
|
|
21338
|
-
unmatched: statements,
|
|
21339
|
-
error: true,
|
|
21340
|
-
errorDescription: "Unexpected code structure",
|
|
21341
|
-
errorMatched: count,
|
|
21342
|
-
};
|
|
21683
|
+
return failure(index, "Unexpected code structure", count);
|
|
21343
21684
|
}
|
|
21344
21685
|
else {
|
|
21345
|
-
return
|
|
21346
|
-
matched: [],
|
|
21347
|
-
unmatched: statements,
|
|
21348
|
-
error: true,
|
|
21349
|
-
errorDescription: countError,
|
|
21350
|
-
errorMatched: count,
|
|
21351
|
-
};
|
|
21686
|
+
return failure(index, countError, count);
|
|
21352
21687
|
}
|
|
21353
21688
|
}
|
|
21354
21689
|
}
|
|
@@ -21363,7 +21698,10 @@ class Optional {
|
|
|
21363
21698
|
return this.obj.getUsing();
|
|
21364
21699
|
}
|
|
21365
21700
|
run(statements, parent) {
|
|
21366
|
-
|
|
21701
|
+
return toMatch(statements, this.runAt(statements, 0, parent));
|
|
21702
|
+
}
|
|
21703
|
+
runAt(statements, index, parent) {
|
|
21704
|
+
const ret = this.obj.runAt(statements, index, parent);
|
|
21367
21705
|
ret.error = false;
|
|
21368
21706
|
return ret;
|
|
21369
21707
|
}
|
|
@@ -21382,48 +21720,24 @@ class Star {
|
|
|
21382
21720
|
return this.obj.getUsing();
|
|
21383
21721
|
}
|
|
21384
21722
|
run(statements, parent) {
|
|
21385
|
-
|
|
21386
|
-
|
|
21723
|
+
return toMatch(statements, this.runAt(statements, 0, parent));
|
|
21724
|
+
}
|
|
21725
|
+
runAt(statements, index, parent) {
|
|
21726
|
+
let next = index;
|
|
21387
21727
|
while (true) {
|
|
21388
|
-
if (
|
|
21389
|
-
return
|
|
21390
|
-
matched: out,
|
|
21391
|
-
unmatched: inn,
|
|
21392
|
-
error: false,
|
|
21393
|
-
errorDescription: "",
|
|
21394
|
-
errorMatched: 0,
|
|
21395
|
-
};
|
|
21728
|
+
if (next >= statements.length) {
|
|
21729
|
+
return success(next);
|
|
21396
21730
|
}
|
|
21397
|
-
const match = this.obj.
|
|
21731
|
+
const match = this.obj.runAt(statements, next, parent);
|
|
21398
21732
|
if (match.error === true) {
|
|
21399
21733
|
if (match.errorMatched > 0) {
|
|
21400
|
-
return
|
|
21401
|
-
matched: out,
|
|
21402
|
-
unmatched: inn,
|
|
21403
|
-
error: true,
|
|
21404
|
-
errorDescription: match.errorDescription,
|
|
21405
|
-
errorMatched: match.errorMatched,
|
|
21406
|
-
};
|
|
21734
|
+
return failure(next, match.errorDescription, match.errorMatched);
|
|
21407
21735
|
}
|
|
21408
21736
|
else {
|
|
21409
|
-
return
|
|
21410
|
-
matched: out,
|
|
21411
|
-
unmatched: inn,
|
|
21412
|
-
error: false,
|
|
21413
|
-
errorDescription: "",
|
|
21414
|
-
errorMatched: 0,
|
|
21415
|
-
};
|
|
21737
|
+
return success(next);
|
|
21416
21738
|
}
|
|
21417
21739
|
}
|
|
21418
|
-
|
|
21419
|
-
out.push(...match.matched);
|
|
21420
|
-
}
|
|
21421
|
-
else {
|
|
21422
|
-
// avoid using the spread operator, it might trigger "Maximum call stack size exceeded"
|
|
21423
|
-
// when the number of matched elements is very large
|
|
21424
|
-
out = out.concat(match.matched);
|
|
21425
|
-
}
|
|
21426
|
-
inn = match.unmatched;
|
|
21740
|
+
next = match.next;
|
|
21427
21741
|
}
|
|
21428
21742
|
}
|
|
21429
21743
|
first() {
|
|
@@ -21452,10 +21766,13 @@ class SubStructure {
|
|
|
21452
21766
|
}
|
|
21453
21767
|
}
|
|
21454
21768
|
run(statements, parent) {
|
|
21769
|
+
return toMatch(statements, this.runAt(statements, 0, parent));
|
|
21770
|
+
}
|
|
21771
|
+
runAt(statements, index, parent) {
|
|
21455
21772
|
const nparent = new nodes_1.StructureNode(this.s);
|
|
21456
21773
|
this.setupMatcher();
|
|
21457
|
-
const ret = this.matcher.
|
|
21458
|
-
if (ret.
|
|
21774
|
+
const ret = this.matcher.runAt(statements, index, nparent);
|
|
21775
|
+
if (ret.next === index) {
|
|
21459
21776
|
ret.error = true;
|
|
21460
21777
|
}
|
|
21461
21778
|
else {
|
|
@@ -21485,33 +21802,18 @@ class SubStatement {
|
|
|
21485
21802
|
return this.obj.name;
|
|
21486
21803
|
}
|
|
21487
21804
|
run(statements, parent) {
|
|
21488
|
-
|
|
21489
|
-
|
|
21490
|
-
|
|
21491
|
-
|
|
21492
|
-
|
|
21493
|
-
errorDescription: "Expected " + this.className().toUpperCase(),
|
|
21494
|
-
errorMatched: 0,
|
|
21495
|
-
};
|
|
21805
|
+
return toMatch(statements, this.runAt(statements, 0, parent));
|
|
21806
|
+
}
|
|
21807
|
+
runAt(statements, index, parent) {
|
|
21808
|
+
if (index >= statements.length) {
|
|
21809
|
+
return failure(statements.length, "Expected " + this.className().toUpperCase(), 0);
|
|
21496
21810
|
}
|
|
21497
|
-
else if (statements[
|
|
21498
|
-
parent.addChild(statements[
|
|
21499
|
-
return
|
|
21500
|
-
matched: [statements[0]],
|
|
21501
|
-
unmatched: statements.splice(1),
|
|
21502
|
-
error: false,
|
|
21503
|
-
errorDescription: "",
|
|
21504
|
-
errorMatched: 0,
|
|
21505
|
-
};
|
|
21811
|
+
else if (statements[index].get() instanceof this.obj) {
|
|
21812
|
+
parent.addChild(statements[index]);
|
|
21813
|
+
return success(index + 1);
|
|
21506
21814
|
}
|
|
21507
21815
|
else {
|
|
21508
|
-
return
|
|
21509
|
-
matched: [],
|
|
21510
|
-
unmatched: statements,
|
|
21511
|
-
error: true,
|
|
21512
|
-
errorDescription: "Expected " + this.className().toUpperCase(),
|
|
21513
|
-
errorMatched: 0,
|
|
21514
|
-
};
|
|
21816
|
+
return failure(index, "Expected " + this.className().toUpperCase(), 0);
|
|
21515
21817
|
}
|
|
21516
21818
|
}
|
|
21517
21819
|
}
|
|
@@ -29257,7 +29559,7 @@ class BasicTypes {
|
|
|
29257
29559
|
if (children.length === 0) {
|
|
29258
29560
|
return new Types.UnknownType("Type error, could not resolve \"" + fullName + "\", resolveLikeName1");
|
|
29259
29561
|
}
|
|
29260
|
-
let type
|
|
29562
|
+
let type;
|
|
29261
29563
|
if (children[1] && (children[1].getFirstToken().getStr() === "=>" || children[1].getFirstToken().getStr() === "->")) {
|
|
29262
29564
|
type = field_chain_1.FieldChain.runSyntax(chain, this.input, _reference_1.ReferenceType.TypeReference);
|
|
29263
29565
|
}
|
|
@@ -29520,7 +29822,7 @@ class BasicTypes {
|
|
|
29520
29822
|
primaryKey: primaryKey,
|
|
29521
29823
|
secondary: secondaryKeys,
|
|
29522
29824
|
};
|
|
29523
|
-
let found
|
|
29825
|
+
let found;
|
|
29524
29826
|
if (text.startsWith("TYPE TABLE OF REF TO ")
|
|
29525
29827
|
|| text.startsWith("TYPE STANDARD TABLE OF REF TO ")
|
|
29526
29828
|
|| text.startsWith("TYPE SORTED TABLE OF REF TO ")
|
|
@@ -29658,7 +29960,7 @@ class BasicTypes {
|
|
|
29658
29960
|
name = typeName === null || typeName === void 0 ? void 0 : typeName.concatTokens();
|
|
29659
29961
|
}
|
|
29660
29962
|
const type = this.resolveLikeName(e, false);
|
|
29661
|
-
let row
|
|
29963
|
+
let row;
|
|
29662
29964
|
if (type === undefined) {
|
|
29663
29965
|
return new Types.UnknownType("Type error, could not resolve \"" + name + "\", parseType");
|
|
29664
29966
|
}
|
|
@@ -29853,7 +30155,7 @@ class BasicTypes {
|
|
|
29853
30155
|
rest = split[1];
|
|
29854
30156
|
}
|
|
29855
30157
|
const subs = rest.split("-");
|
|
29856
|
-
let foundType
|
|
30158
|
+
let foundType;
|
|
29857
30159
|
if (className && chainText.includes("=>")) {
|
|
29858
30160
|
const split = chainText.split("=>");
|
|
29859
30161
|
const className = split[0];
|
|
@@ -30276,6 +30578,143 @@ function checkDatabaseFields(fields, dbSources, input, token) {
|
|
|
30276
30578
|
|
|
30277
30579
|
/***/ },
|
|
30278
30580
|
|
|
30581
|
+
/***/ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/_check_database_work_area.js"
|
|
30582
|
+
/*!******************************************************************************************************!*\
|
|
30583
|
+
!*** ./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/_check_database_work_area.js ***!
|
|
30584
|
+
\******************************************************************************************************/
|
|
30585
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
30586
|
+
|
|
30587
|
+
"use strict";
|
|
30588
|
+
|
|
30589
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
30590
|
+
if (k2 === undefined) k2 = k;
|
|
30591
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
30592
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
30593
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
30594
|
+
}
|
|
30595
|
+
Object.defineProperty(o, k2, desc);
|
|
30596
|
+
}) : (function(o, m, k, k2) {
|
|
30597
|
+
if (k2 === undefined) k2 = k;
|
|
30598
|
+
o[k2] = m[k];
|
|
30599
|
+
}));
|
|
30600
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
30601
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
30602
|
+
}) : function(o, v) {
|
|
30603
|
+
o["default"] = v;
|
|
30604
|
+
});
|
|
30605
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
30606
|
+
var ownKeys = function(o) {
|
|
30607
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
30608
|
+
var ar = [];
|
|
30609
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30610
|
+
return ar;
|
|
30611
|
+
};
|
|
30612
|
+
return ownKeys(o);
|
|
30613
|
+
};
|
|
30614
|
+
return function (mod) {
|
|
30615
|
+
if (mod && mod.__esModule) return mod;
|
|
30616
|
+
var result = {};
|
|
30617
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
30618
|
+
__setModuleDefault(result, mod);
|
|
30619
|
+
return result;
|
|
30620
|
+
};
|
|
30621
|
+
})();
|
|
30622
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
30623
|
+
exports.checkDatabaseWorkArea = checkDatabaseWorkArea;
|
|
30624
|
+
const nodes_1 = __webpack_require__(/*! ../../nodes */ "./node_modules/@abaplint/core/build/src/abap/nodes/index.js");
|
|
30625
|
+
const Expressions = __importStar(__webpack_require__(/*! ../../2_statements/expressions */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js"));
|
|
30626
|
+
const Basic = __importStar(__webpack_require__(/*! ../../types/basic */ "./node_modules/@abaplint/core/build/src/abap/types/basic/index.js"));
|
|
30627
|
+
const objects_1 = __webpack_require__(/*! ../../../objects */ "./node_modules/@abaplint/core/build/src/objects/index.js");
|
|
30628
|
+
const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
|
|
30629
|
+
// byte length of a flat type in a unicode system, as a lower and an upper bound:
|
|
30630
|
+
// IntegerType also stands for INT1 and INT2, and padding is left out of the lower bound
|
|
30631
|
+
function bounds(type) {
|
|
30632
|
+
if (type instanceof Basic.CharacterType || type instanceof Basic.NumericType) {
|
|
30633
|
+
return { min: type.getLength() * 2, max: type.getLength() * 2, align: 2 };
|
|
30634
|
+
}
|
|
30635
|
+
else if (type instanceof Basic.DateType) {
|
|
30636
|
+
return { min: 16, max: 16, align: 2 };
|
|
30637
|
+
}
|
|
30638
|
+
else if (type instanceof Basic.TimeType) {
|
|
30639
|
+
return { min: 12, max: 12, align: 2 };
|
|
30640
|
+
}
|
|
30641
|
+
else if (type instanceof Basic.IntegerType) {
|
|
30642
|
+
return { min: 1, max: 4, align: 4 };
|
|
30643
|
+
}
|
|
30644
|
+
else if (type instanceof Basic.Integer8Type || type instanceof Basic.FloatType
|
|
30645
|
+
|| type instanceof Basic.DecFloat16Type || type instanceof Basic.UTCLongType) {
|
|
30646
|
+
return { min: 8, max: 8, align: 8 };
|
|
30647
|
+
}
|
|
30648
|
+
else if (type instanceof Basic.DecFloat34Type) {
|
|
30649
|
+
return { min: 16, max: 16, align: 16 };
|
|
30650
|
+
}
|
|
30651
|
+
else if (type instanceof Basic.PackedType || type instanceof Basic.HexType) {
|
|
30652
|
+
return { min: type.getLength(), max: type.getLength(), align: 1 };
|
|
30653
|
+
}
|
|
30654
|
+
else if (type instanceof Basic.StructureType) {
|
|
30655
|
+
let min = 0;
|
|
30656
|
+
let max = 0;
|
|
30657
|
+
let align = 1;
|
|
30658
|
+
for (const component of type.getComponents()) {
|
|
30659
|
+
const sub = bounds(component.type);
|
|
30660
|
+
if (sub === undefined) {
|
|
30661
|
+
return undefined;
|
|
30662
|
+
}
|
|
30663
|
+
align = Math.max(align, sub.align);
|
|
30664
|
+
max = Math.ceil(max / sub.align) * sub.align + sub.max;
|
|
30665
|
+
min = min + sub.min;
|
|
30666
|
+
}
|
|
30667
|
+
max = Math.ceil(max / align) * align;
|
|
30668
|
+
return { min, max, align };
|
|
30669
|
+
}
|
|
30670
|
+
// deep, generic, void or unknown
|
|
30671
|
+
return undefined;
|
|
30672
|
+
}
|
|
30673
|
+
// INSERT/MODIFY/UPDATE dbtab FROM wa: the work area must be at least as long as the table line,
|
|
30674
|
+
// client field included, else the statement is a syntax error on the system
|
|
30675
|
+
function checkDatabaseWorkArea(node, dbSource, sourceTypes, input) {
|
|
30676
|
+
var _a;
|
|
30677
|
+
if (!(dbSource instanceof objects_1.Table)) {
|
|
30678
|
+
return;
|
|
30679
|
+
}
|
|
30680
|
+
const children = node.getChildren();
|
|
30681
|
+
let workArea = undefined;
|
|
30682
|
+
for (let i = 0; i < children.length - 1; i++) {
|
|
30683
|
+
const child = children[i];
|
|
30684
|
+
if (child instanceof nodes_1.TokenNode && child.concatTokens().toUpperCase() === "FROM") {
|
|
30685
|
+
const next = children[i + 1];
|
|
30686
|
+
if (next instanceof nodes_1.ExpressionNode && next.get() instanceof Expressions.SQLSource) {
|
|
30687
|
+
workArea = next;
|
|
30688
|
+
}
|
|
30689
|
+
break;
|
|
30690
|
+
}
|
|
30691
|
+
}
|
|
30692
|
+
if (workArea === undefined) {
|
|
30693
|
+
return;
|
|
30694
|
+
}
|
|
30695
|
+
const source = (_a = workArea.findFirstExpression(Expressions.SimpleSource3)) !== null && _a !== void 0 ? _a : workArea.findFirstExpression(Expressions.Source);
|
|
30696
|
+
if (source === undefined) {
|
|
30697
|
+
return;
|
|
30698
|
+
}
|
|
30699
|
+
const waType = sourceTypes.get(source);
|
|
30700
|
+
if (!(waType instanceof Basic.StructureType)) {
|
|
30701
|
+
return;
|
|
30702
|
+
}
|
|
30703
|
+
const tableType = dbSource.parseType(input.scope.getRegistry());
|
|
30704
|
+
const waBounds = bounds(waType);
|
|
30705
|
+
const tableBounds = bounds(tableType);
|
|
30706
|
+
if (waBounds === undefined || tableBounds === undefined) {
|
|
30707
|
+
return;
|
|
30708
|
+
}
|
|
30709
|
+
if (waBounds.max < tableBounds.min) {
|
|
30710
|
+
const message = "The work area \"" + source.concatTokens() + "\" is not long enough for table " + dbSource.getName();
|
|
30711
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, source.getFirstToken(), message));
|
|
30712
|
+
}
|
|
30713
|
+
}
|
|
30714
|
+
//# sourceMappingURL=_check_database_work_area.js.map
|
|
30715
|
+
|
|
30716
|
+
/***/ },
|
|
30717
|
+
|
|
30279
30718
|
/***/ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/_check_offset_length.js"
|
|
30280
30719
|
/*!*************************************************************************************************!*\
|
|
30281
30720
|
!*** ./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/_check_offset_length.js ***!
|
|
@@ -30597,7 +31036,7 @@ class AttributeName {
|
|
|
30597
31036
|
return context;
|
|
30598
31037
|
}
|
|
30599
31038
|
const helper = new _object_oriented_1.ObjectOriented(input.scope);
|
|
30600
|
-
let ret
|
|
31039
|
+
let ret;
|
|
30601
31040
|
if (context instanceof object_reference_type_1.ObjectReferenceType) {
|
|
30602
31041
|
const def = input.scope.findObjectDefinition(context.getIdentifierName());
|
|
30603
31042
|
if (def === undefined) {
|
|
@@ -31622,7 +32061,7 @@ const let_1 = __webpack_require__(/*! ./let */ "./node_modules/@abaplint/core/bu
|
|
|
31622
32061
|
const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
|
|
31623
32062
|
const basic_1 = __webpack_require__(/*! ../../types/basic */ "./node_modules/@abaplint/core/build/src/abap/types/basic/index.js");
|
|
31624
32063
|
class ConvBody {
|
|
31625
|
-
static runSyntax(node, input) {
|
|
32064
|
+
static runSyntax(node, input, targetType) {
|
|
31626
32065
|
let scoped = false;
|
|
31627
32066
|
const l = node.findDirectExpression(Expressions.Let);
|
|
31628
32067
|
if (l) {
|
|
@@ -31634,7 +32073,7 @@ class ConvBody {
|
|
|
31634
32073
|
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
31635
32074
|
return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
|
|
31636
32075
|
}
|
|
31637
|
-
const sourceType = source_1.Source.runSyntax(s, input);
|
|
32076
|
+
const sourceType = source_1.Source.runSyntax(s, input, targetType);
|
|
31638
32077
|
if (scoped === true) {
|
|
31639
32078
|
input.scope.pop(node.getLastToken().getEnd());
|
|
31640
32079
|
}
|
|
@@ -32167,7 +32606,7 @@ class FieldChain {
|
|
|
32167
32606
|
return found.getType();
|
|
32168
32607
|
}
|
|
32169
32608
|
}
|
|
32170
|
-
let context
|
|
32609
|
+
let context;
|
|
32171
32610
|
const children = node.getChildren();
|
|
32172
32611
|
context = this.findTop(children[0], input, refType);
|
|
32173
32612
|
let prev = children[0].concatTokens();
|
|
@@ -32660,7 +33099,7 @@ class FormParam {
|
|
|
32660
33099
|
if (node.findDirectTokenByText("STRUCTURE") && nameToken) {
|
|
32661
33100
|
// STRUCTURES typing
|
|
32662
33101
|
const typeName = (_a = node.findDirectExpression(expressions_1.SimpleFieldChain)) === null || _a === void 0 ? void 0 : _a.getFirstToken().getStr();
|
|
32663
|
-
let type
|
|
33102
|
+
let type;
|
|
32664
33103
|
if (typeName) {
|
|
32665
33104
|
type = (_b = input.scope.findType(typeName)) === null || _b === void 0 ? void 0 : _b.getType();
|
|
32666
33105
|
if (type === undefined) {
|
|
@@ -34233,7 +34672,7 @@ class MethodParameters {
|
|
|
34233
34672
|
}
|
|
34234
34673
|
checkImporting(node, input, method) {
|
|
34235
34674
|
for (const item of this.parameterListT(node, input)) {
|
|
34236
|
-
let parameterType
|
|
34675
|
+
let parameterType;
|
|
34237
34676
|
if (method instanceof basic_1.VoidType) {
|
|
34238
34677
|
parameterType = method;
|
|
34239
34678
|
}
|
|
@@ -34270,7 +34709,7 @@ class MethodParameters {
|
|
|
34270
34709
|
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
34271
34710
|
return;
|
|
34272
34711
|
}
|
|
34273
|
-
let parameterType
|
|
34712
|
+
let parameterType;
|
|
34274
34713
|
if (method instanceof basic_1.VoidType) {
|
|
34275
34714
|
parameterType = method;
|
|
34276
34715
|
}
|
|
@@ -35587,9 +36026,8 @@ class Select {
|
|
|
35587
36026
|
}
|
|
35588
36027
|
static findFields(node, input) {
|
|
35589
36028
|
var _a, _b;
|
|
35590
|
-
|
|
36029
|
+
const expr = node.findFirstExpression(Expressions.SQLFieldList);
|
|
35591
36030
|
const ret = [];
|
|
35592
|
-
expr = node.findFirstExpression(Expressions.SQLFieldList);
|
|
35593
36031
|
if (((_a = expr === null || expr === void 0 ? void 0 : expr.getFirstChild()) === null || _a === void 0 ? void 0 : _a.get()) instanceof Expressions.Dynamic) {
|
|
35594
36032
|
dynamic_1.Dynamic.runSyntax(expr.getFirstChild(), input);
|
|
35595
36033
|
}
|
|
@@ -35683,6 +36121,7 @@ const _typed_identifier_1 = __webpack_require__(/*! ../../types/_typed_identifie
|
|
|
35683
36121
|
const _type_utils_1 = __webpack_require__(/*! ../_type_utils */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_type_utils.js");
|
|
35684
36122
|
const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
|
|
35685
36123
|
const assert_error_1 = __webpack_require__(/*! ../assert_error */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/assert_error.js");
|
|
36124
|
+
const version_1 = __webpack_require__(/*! ../../../version */ "./node_modules/@abaplint/core/build/src/version.js");
|
|
35686
36125
|
/*
|
|
35687
36126
|
* Type interference, valid scenarios:
|
|
35688
36127
|
* typed = VALUE #( ... ). right hand side must follow left hand type
|
|
@@ -35695,7 +36134,7 @@ const assert_error_1 = __webpack_require__(/*! ../assert_error */ "./node_module
|
|
|
35695
36134
|
// TODO: refactor all these method parameters to objects, this is getting messy
|
|
35696
36135
|
class Source {
|
|
35697
36136
|
static runSyntax(node, input, targetType, writeReference = false, allowGenericDeference = false, readReference = true) {
|
|
35698
|
-
var _a;
|
|
36137
|
+
var _a, _b, _c, _d;
|
|
35699
36138
|
if (node === undefined) {
|
|
35700
36139
|
return undefined;
|
|
35701
36140
|
}
|
|
@@ -35773,7 +36212,7 @@ class Source {
|
|
|
35773
36212
|
case "CONV":
|
|
35774
36213
|
{
|
|
35775
36214
|
const foundType = this.determineType(node, input, targetType);
|
|
35776
|
-
const bodyType = conv_body_1.ConvBody.runSyntax(node.findDirectExpression(Expressions.ConvBody), input);
|
|
36215
|
+
const bodyType = conv_body_1.ConvBody.runSyntax(node.findDirectExpression(Expressions.ConvBody), input, foundType);
|
|
35777
36216
|
const inferred = (_a = node.findDirectExpression(Expressions.TypeNameOrInfer)) === null || _a === void 0 ? void 0 : _a.concatTokens();
|
|
35778
36217
|
if (new _type_utils_1.TypeUtils(input.scope).isConvable(foundType, bodyType) === false) {
|
|
35779
36218
|
const message = `CONV: Types not compatible, ${foundType === null || foundType === void 0 ? void 0 : foundType.constructor.name}, ${bodyType === null || bodyType === void 0 ? void 0 : bodyType.constructor.name}`;
|
|
@@ -35790,7 +36229,13 @@ class Source {
|
|
|
35790
36229
|
this.traverseRemainingChildren(children, input);
|
|
35791
36230
|
return bodyType;
|
|
35792
36231
|
}
|
|
35793
|
-
|
|
36232
|
+
const bodySource = (_b = node.findDirectExpression(Expressions.ConvBody)) === null || _b === void 0 ? void 0 : _b.findDirectExpression(Expressions.Source);
|
|
36233
|
+
const nestedType = (_c = bodySource === null || bodySource === void 0 ? void 0 : bodySource.findDirectExpression(Expressions.TypeNameOrInfer)) === null || _c === void 0 ? void 0 : _c.concatTokens();
|
|
36234
|
+
// CONV # passes its target type into a nested inferred constructor, so
|
|
36235
|
+
// showing both inferred types would produce duplicate inlay hints.
|
|
36236
|
+
if (!(inferred === "#" && nestedType === "#")) {
|
|
36237
|
+
this.addIfInferred(node, input, foundType);
|
|
36238
|
+
}
|
|
35794
36239
|
this.traverseRemainingChildren(children, input);
|
|
35795
36240
|
return foundType;
|
|
35796
36241
|
}
|
|
@@ -35847,6 +36292,15 @@ class Source {
|
|
|
35847
36292
|
case "CORRESPONDING":
|
|
35848
36293
|
{
|
|
35849
36294
|
const foundType = this.determineType(node, input, targetType);
|
|
36295
|
+
if ((foundType === null || foundType === void 0 ? void 0 : foundType.isGeneric()) === true
|
|
36296
|
+
&& ((_d = node.findDirectExpression(Expressions.TypeNameOrInfer)) === null || _d === void 0 ? void 0 : _d.concatTokens()) === "#"
|
|
36297
|
+
&& !(0, version_1.releaseAtLeast)(input.scope.getRelease(), version_1.Release.v756)
|
|
36298
|
+
&& input.scope.getLanguageVersion() !== version_1.LanguageVersion.Cloud
|
|
36299
|
+
&& !input.scope.getOpenABAP()) {
|
|
36300
|
+
const message = "CORRESPONDING #, the type of the target is generic";
|
|
36301
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
36302
|
+
return basic_1.VoidType.get(_syntax_input_1.CheckSyntaxKey);
|
|
36303
|
+
}
|
|
35850
36304
|
corresponding_body_1.CorrespondingBody.runSyntax(node.findDirectExpression(Expressions.CorrespondingBody), input, foundType);
|
|
35851
36305
|
this.addIfInferred(node, input, foundType);
|
|
35852
36306
|
return foundType;
|
|
@@ -38492,6 +38946,7 @@ const basic_1 = __webpack_require__(/*! ../../types/basic */ "./node_modules/@ab
|
|
|
38492
38946
|
const dynamic_1 = __webpack_require__(/*! ../expressions/dynamic */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/dynamic.js");
|
|
38493
38947
|
const _type_utils_1 = __webpack_require__(/*! ../_type_utils */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_type_utils.js");
|
|
38494
38948
|
const _syntax_input_1 = __webpack_require__(/*! ../_syntax_input */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_syntax_input.js");
|
|
38949
|
+
const version_1 = __webpack_require__(/*! ../../../version */ "./node_modules/@abaplint/core/build/src/version.js");
|
|
38495
38950
|
class Assign {
|
|
38496
38951
|
runSyntax(node, input) {
|
|
38497
38952
|
var _a;
|
|
@@ -38499,7 +38954,7 @@ class Assign {
|
|
|
38499
38954
|
const isComponent = ((_a = assignSource === null || assignSource === void 0 ? void 0 : assignSource.getFirstChild()) === null || _a === void 0 ? void 0 : _a.concatTokens().toUpperCase()) === "COMPONENT";
|
|
38500
38955
|
const sources = (assignSource === null || assignSource === void 0 ? void 0 : assignSource.findDirectExpressionsMulti([Expressions.Source, Expressions.SimpleSource3])) || [];
|
|
38501
38956
|
const theSource = sources[sources.length - 1];
|
|
38502
|
-
let sourceType
|
|
38957
|
+
let sourceType;
|
|
38503
38958
|
const firstAssign = assignSource === null || assignSource === void 0 ? void 0 : assignSource.getChildren()[0];
|
|
38504
38959
|
const secondAssign = assignSource === null || assignSource === void 0 ? void 0 : assignSource.getChildren()[1];
|
|
38505
38960
|
const thirdAssign = assignSource === null || assignSource === void 0 ? void 0 : assignSource.getChildren()[2];
|
|
@@ -38515,6 +38970,19 @@ class Assign {
|
|
|
38515
38970
|
}
|
|
38516
38971
|
else {
|
|
38517
38972
|
sourceType = source_1.Source.runSyntax(theSource, input, undefined, false, isComponent === false);
|
|
38973
|
+
if ((secondAssign === null || secondAssign === void 0 ? void 0 : secondAssign.concatTokens()) === "->"
|
|
38974
|
+
&& (thirdAssign === null || thirdAssign === void 0 ? void 0 : thirdAssign.get()) instanceof Expressions.Dynamic
|
|
38975
|
+
&& (sourceType === null || sourceType === void 0 ? void 0 : sourceType.isGeneric()) === true
|
|
38976
|
+
&& !(sourceType instanceof basic_1.DataReference)
|
|
38977
|
+
&& !(sourceType instanceof basic_1.ObjectReferenceType)
|
|
38978
|
+
&& !(sourceType instanceof basic_1.GenericObjectReferenceType)
|
|
38979
|
+
&& !(0, version_1.releaseAtLeast)(input.scope.getRelease(), version_1.Release.v756)
|
|
38980
|
+
&& input.scope.getLanguageVersion() !== version_1.LanguageVersion.Cloud
|
|
38981
|
+
&& !input.scope.getOpenABAP()) {
|
|
38982
|
+
const message = `"${theSource.concatTokens()}" is not a reference variable`;
|
|
38983
|
+
input.issues.push((0, _syntax_input_1.syntaxIssue)(input, node.getFirstToken(), message));
|
|
38984
|
+
return;
|
|
38985
|
+
}
|
|
38518
38986
|
}
|
|
38519
38987
|
if ((assignSource === null || assignSource === void 0 ? void 0 : assignSource.getChildren().length) === 5
|
|
38520
38988
|
&& isComponent) {
|
|
@@ -43241,20 +43709,23 @@ const Expressions = __importStar(__webpack_require__(/*! ../../2_statements/expr
|
|
|
43241
43709
|
const source_1 = __webpack_require__(/*! ../expressions/source */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/source.js");
|
|
43242
43710
|
const dynamic_1 = __webpack_require__(/*! ../expressions/dynamic */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/dynamic.js");
|
|
43243
43711
|
const database_table_1 = __webpack_require__(/*! ../expressions/database_table */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/database_table.js");
|
|
43712
|
+
const _check_database_work_area_1 = __webpack_require__(/*! ../expressions/_check_database_work_area */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/_check_database_work_area.js");
|
|
43244
43713
|
class InsertDatabase {
|
|
43245
43714
|
runSyntax(node, input) {
|
|
43715
|
+
const sourceTypes = new Map();
|
|
43246
43716
|
for (const s of node.findAllExpressions(Expressions.Source)) {
|
|
43247
|
-
source_1.Source.runSyntax(s, input);
|
|
43717
|
+
sourceTypes.set(s, source_1.Source.runSyntax(s, input));
|
|
43248
43718
|
}
|
|
43249
43719
|
for (const s of node.findAllExpressions(Expressions.SimpleSource3)) {
|
|
43250
|
-
source_1.Source.runSyntax(s, input);
|
|
43720
|
+
sourceTypes.set(s, source_1.Source.runSyntax(s, input));
|
|
43251
43721
|
}
|
|
43252
43722
|
for (const d of node.findAllExpressions(Expressions.Dynamic)) {
|
|
43253
43723
|
dynamic_1.Dynamic.runSyntax(d, input);
|
|
43254
43724
|
}
|
|
43255
43725
|
const dbtab = node.findFirstExpression(Expressions.DatabaseTable);
|
|
43256
43726
|
if (dbtab !== undefined) {
|
|
43257
|
-
database_table_1.DatabaseTable.runSyntax(dbtab, input);
|
|
43727
|
+
const dbSource = database_table_1.DatabaseTable.runSyntax(dbtab, input);
|
|
43728
|
+
(0, _check_database_work_area_1.checkDatabaseWorkArea)(node, dbSource, sourceTypes, input);
|
|
43258
43729
|
}
|
|
43259
43730
|
}
|
|
43260
43731
|
}
|
|
@@ -43840,7 +44311,7 @@ class Loop {
|
|
|
43840
44311
|
&& topType instanceof basic_1.TableType) {
|
|
43841
44312
|
// https://github.com/abap2xlsx/abap2xlsx/issues/1341
|
|
43842
44313
|
const keyName = node.findExpressionAfterToken("KEY");
|
|
43843
|
-
let key
|
|
44314
|
+
let key;
|
|
43844
44315
|
const name = (keyName === null || keyName === void 0 ? void 0 : keyName.get()) instanceof Expressions.SimpleName ? keyName.getFirstToken().getStr().toUpperCase() : undefined;
|
|
43845
44316
|
// it might be dynamic, in that case we cannot check anything; and
|
|
43846
44317
|
// primary_key is the predefined name of the primary key every table has
|
|
@@ -44197,11 +44668,13 @@ const dynamic_1 = __webpack_require__(/*! ../expressions/dynamic */ "./node_modu
|
|
|
44197
44668
|
const database_table_1 = __webpack_require__(/*! ../expressions/database_table */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/database_table.js");
|
|
44198
44669
|
const source_1 = __webpack_require__(/*! ../expressions/source */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/source.js");
|
|
44199
44670
|
const _reference_1 = __webpack_require__(/*! ../_reference */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/_reference.js");
|
|
44671
|
+
const _check_database_work_area_1 = __webpack_require__(/*! ../expressions/_check_database_work_area */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/_check_database_work_area.js");
|
|
44200
44672
|
class ModifyDatabase {
|
|
44201
44673
|
runSyntax(node, input) {
|
|
44202
44674
|
for (const d of node.findAllExpressions(Expressions.Dynamic)) {
|
|
44203
44675
|
dynamic_1.Dynamic.runSyntax(d, input);
|
|
44204
44676
|
}
|
|
44677
|
+
let dbSource = undefined;
|
|
44205
44678
|
const dbtab = node.findFirstExpression(Expressions.DatabaseTable);
|
|
44206
44679
|
if (dbtab !== undefined) {
|
|
44207
44680
|
if (node.getChildren().length === 5) {
|
|
@@ -44210,19 +44683,21 @@ class ModifyDatabase {
|
|
|
44210
44683
|
input.scope.addReference(dbtab.getFirstToken(), found, _reference_1.ReferenceType.DataWriteReference, input.filename);
|
|
44211
44684
|
}
|
|
44212
44685
|
else {
|
|
44213
|
-
database_table_1.DatabaseTable.runSyntax(dbtab, input);
|
|
44686
|
+
dbSource = database_table_1.DatabaseTable.runSyntax(dbtab, input);
|
|
44214
44687
|
}
|
|
44215
44688
|
}
|
|
44216
44689
|
else {
|
|
44217
|
-
database_table_1.DatabaseTable.runSyntax(dbtab, input);
|
|
44690
|
+
dbSource = database_table_1.DatabaseTable.runSyntax(dbtab, input);
|
|
44218
44691
|
}
|
|
44219
44692
|
}
|
|
44693
|
+
const sourceTypes = new Map();
|
|
44220
44694
|
for (const s of node.findAllExpressions(Expressions.Source)) {
|
|
44221
|
-
source_1.Source.runSyntax(s, input);
|
|
44695
|
+
sourceTypes.set(s, source_1.Source.runSyntax(s, input));
|
|
44222
44696
|
}
|
|
44223
44697
|
for (const s of node.findAllExpressions(Expressions.SimpleSource3)) {
|
|
44224
|
-
source_1.Source.runSyntax(s, input);
|
|
44698
|
+
sourceTypes.set(s, source_1.Source.runSyntax(s, input));
|
|
44225
44699
|
}
|
|
44700
|
+
(0, _check_database_work_area_1.checkDatabaseWorkArea)(node, dbSource, sourceTypes, input);
|
|
44226
44701
|
}
|
|
44227
44702
|
}
|
|
44228
44703
|
exports.ModifyDatabase = ModifyDatabase;
|
|
@@ -48122,11 +48597,13 @@ const identifier_1 = __webpack_require__(/*! ../../1_lexer/tokens/identifier */
|
|
|
48122
48597
|
const database_table_1 = __webpack_require__(/*! ../expressions/database_table */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/database_table.js");
|
|
48123
48598
|
const dynamic_1 = __webpack_require__(/*! ../expressions/dynamic */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/dynamic.js");
|
|
48124
48599
|
const _check_database_fields_1 = __webpack_require__(/*! ../expressions/_check_database_fields */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/_check_database_fields.js");
|
|
48600
|
+
const _check_database_work_area_1 = __webpack_require__(/*! ../expressions/_check_database_work_area */ "./node_modules/@abaplint/core/build/src/abap/5_syntax/expressions/_check_database_work_area.js");
|
|
48125
48601
|
class UpdateDatabase {
|
|
48126
48602
|
runSyntax(node, input) {
|
|
48603
|
+
let dbSource = undefined;
|
|
48127
48604
|
const dbtab = node.findFirstExpression(Expressions.DatabaseTable);
|
|
48128
48605
|
if (dbtab !== undefined) {
|
|
48129
|
-
|
|
48606
|
+
dbSource = database_table_1.DatabaseTable.runSyntax(dbtab, input);
|
|
48130
48607
|
const fields = node.findAllExpressions(Expressions.SQLFieldAndValue)
|
|
48131
48608
|
.flatMap(fieldAndValue => fieldAndValue.findDirectExpressions(Expressions.SQLFieldName))
|
|
48132
48609
|
.map(field => field.concatTokens().toUpperCase());
|
|
@@ -48149,15 +48626,17 @@ class UpdateDatabase {
|
|
|
48149
48626
|
}
|
|
48150
48627
|
}
|
|
48151
48628
|
}
|
|
48629
|
+
const sourceTypes = new Map();
|
|
48152
48630
|
for (const s of node.findAllExpressions(Expressions.Source)) {
|
|
48153
|
-
source_1.Source.runSyntax(s, input);
|
|
48631
|
+
sourceTypes.set(s, source_1.Source.runSyntax(s, input));
|
|
48154
48632
|
}
|
|
48155
48633
|
for (const s of node.findAllExpressions(Expressions.SimpleSource3)) {
|
|
48156
|
-
source_1.Source.runSyntax(s, input);
|
|
48634
|
+
sourceTypes.set(s, source_1.Source.runSyntax(s, input));
|
|
48157
48635
|
}
|
|
48158
48636
|
for (const d of node.findAllExpressions(Expressions.Dynamic)) {
|
|
48159
48637
|
dynamic_1.Dynamic.runSyntax(d, input);
|
|
48160
48638
|
}
|
|
48639
|
+
(0, _check_database_work_area_1.checkDatabaseWorkArea)(node, dbSource, sourceTypes, input);
|
|
48161
48640
|
if (input.scope.getType() === _scope_type_1.ScopeType.OpenSQL) {
|
|
48162
48641
|
input.scope.pop(node.getLastToken().getEnd());
|
|
48163
48642
|
}
|
|
@@ -48346,7 +48825,7 @@ class WhenType {
|
|
|
48346
48825
|
if (nameToken === undefined) {
|
|
48347
48826
|
return undefined;
|
|
48348
48827
|
}
|
|
48349
|
-
let type
|
|
48828
|
+
let type;
|
|
48350
48829
|
const className = nameToken.getStr().toUpperCase();
|
|
48351
48830
|
const found = input.scope.existsObject(className);
|
|
48352
48831
|
if (found === null || found === void 0 ? void 0 : found.id) {
|
|
@@ -53470,7 +53949,7 @@ class Attributes {
|
|
|
53470
53949
|
return false;
|
|
53471
53950
|
}
|
|
53472
53951
|
parseAttribute(node, visibility, input) {
|
|
53473
|
-
let found
|
|
53952
|
+
let found;
|
|
53474
53953
|
const s = node.get();
|
|
53475
53954
|
if (s instanceof Statements.Data) {
|
|
53476
53955
|
found = new data_1.Data().runSyntax(node, input);
|
|
@@ -55646,7 +56125,7 @@ class CDSLexer {
|
|
|
55646
56125
|
break;
|
|
55647
56126
|
case "@":
|
|
55648
56127
|
// @ starts a new annotation; flush current token and start building with @
|
|
55649
|
-
|
|
56128
|
+
result.add(build, row, col, mode);
|
|
55650
56129
|
build = "@";
|
|
55651
56130
|
break;
|
|
55652
56131
|
default:
|
|
@@ -60520,7 +60999,7 @@ class Help {
|
|
|
60520
60999
|
return content;
|
|
60521
61000
|
}
|
|
60522
61001
|
static dumpABAP(file, reg, textDocument, position) {
|
|
60523
|
-
let content
|
|
61002
|
+
let content;
|
|
60524
61003
|
content = `
|
|
60525
61004
|
<a href="#_tokens" rel="no-refresh">Tokens</a> |
|
|
60526
61005
|
<a href="#_statements" rel="no-refresh">Statements</a> |
|
|
@@ -60553,7 +61032,7 @@ class Help {
|
|
|
60553
61032
|
return `<h3 id="_info">Info Dump</h3><pre>` + text + "</pre>";
|
|
60554
61033
|
}
|
|
60555
61034
|
static cursorInformation(reg, textDocument, position, file) {
|
|
60556
|
-
let ret
|
|
61035
|
+
let ret;
|
|
60557
61036
|
const found = _lsp_utils_1.LSPUtils.findCursor(reg, { textDocument, position });
|
|
60558
61037
|
if (found !== undefined) {
|
|
60559
61038
|
ret = "Statement: " + this.linkToStatement(found.snode.get()) + "<br>\n" +
|
|
@@ -64311,7 +64790,7 @@ class DataElement extends _abstract_object_1.AbstractObject {
|
|
|
64311
64790
|
}
|
|
64312
64791
|
parseType(reg) {
|
|
64313
64792
|
const references = [];
|
|
64314
|
-
let lookup
|
|
64793
|
+
let lookup;
|
|
64315
64794
|
this.parse();
|
|
64316
64795
|
if (this.parsedXML === undefined) {
|
|
64317
64796
|
lookup = { type: new Types.UnknownType("Data Element " + this.getName() + ", parser error") };
|
|
@@ -69762,6 +70241,7 @@ class Table extends _abstract_object_1.AbstractObject {
|
|
|
69762
70241
|
PRECFIELD: field.PRECFIELD,
|
|
69763
70242
|
LENG: field.LENG,
|
|
69764
70243
|
INTLEN: field.INTLEN,
|
|
70244
|
+
INTTYPE: field.INTTYPE,
|
|
69765
70245
|
DATATYPE: field.DATATYPE,
|
|
69766
70246
|
DECIMALS: field.DECIMALS,
|
|
69767
70247
|
KEYFLAG: field.KEYFLAG,
|
|
@@ -71280,7 +71760,7 @@ class Registry {
|
|
|
71280
71760
|
}
|
|
71281
71761
|
static abaplintVersion() {
|
|
71282
71762
|
// magic, see build script "version.js"
|
|
71283
|
-
return "2.120.
|
|
71763
|
+
return "2.120.72";
|
|
71284
71764
|
}
|
|
71285
71765
|
getDDICReferences() {
|
|
71286
71766
|
return this.ddicReferences;
|
|
@@ -72628,7 +73108,7 @@ class AlignPseudoComments extends _abap_rule_1.ABAPRule {
|
|
|
72628
73108
|
}
|
|
72629
73109
|
const col = firstCommentToken.getStart().getCol();
|
|
72630
73110
|
if (previousEnd.getCol() < expectedColumn && col !== expectedColumn) {
|
|
72631
|
-
let fix
|
|
73111
|
+
let fix;
|
|
72632
73112
|
if (col < expectedColumn) {
|
|
72633
73113
|
fix = edit_helper_1.EditHelper.insertAt(file, firstCommentToken.getStart(), " ".repeat(expectedColumn - col));
|
|
72634
73114
|
}
|
|
@@ -72795,7 +73275,7 @@ ENDINTERFACE.`,
|
|
|
72795
73275
|
if (f.after.getCol() === column) {
|
|
72796
73276
|
continue;
|
|
72797
73277
|
}
|
|
72798
|
-
let fix
|
|
73278
|
+
let fix;
|
|
72799
73279
|
if (f.after.getCol() < column) {
|
|
72800
73280
|
fix = edit_helper_1.EditHelper.insertAt(file, f.after, " ".repeat(column - f.after.getCol()));
|
|
72801
73281
|
}
|
|
@@ -75186,7 +75666,7 @@ ENDCASE.`,
|
|
|
75186
75666
|
if (tuples.length === 1) {
|
|
75187
75667
|
return false;
|
|
75188
75668
|
}
|
|
75189
|
-
let chain
|
|
75669
|
+
let chain;
|
|
75190
75670
|
if (tuples[0].left === tuples[1].left) {
|
|
75191
75671
|
chain = tuples[0].left;
|
|
75192
75672
|
}
|
|
@@ -75475,7 +75955,7 @@ class CheckDDIC {
|
|
|
75475
75955
|
this.conf = conf;
|
|
75476
75956
|
}
|
|
75477
75957
|
run(obj) {
|
|
75478
|
-
let found
|
|
75958
|
+
let found;
|
|
75479
75959
|
if (obj instanceof Objects.DataElement
|
|
75480
75960
|
|| obj instanceof Objects.Domain
|
|
75481
75961
|
|| obj instanceof Objects.Table
|
|
@@ -76199,7 +76679,6 @@ ENDCLASS.`,
|
|
|
76199
76679
|
this.conf = conf;
|
|
76200
76680
|
}
|
|
76201
76681
|
runParsed(file, obj) {
|
|
76202
|
-
let issues = [];
|
|
76203
76682
|
if (this.conf.patternKind === undefined) {
|
|
76204
76683
|
this.conf.patternKind = "required";
|
|
76205
76684
|
}
|
|
@@ -76220,8 +76699,7 @@ ENDCLASS.`,
|
|
|
76220
76699
|
attributes = attributes.concat(intfDef.attributes);
|
|
76221
76700
|
}
|
|
76222
76701
|
}
|
|
76223
|
-
|
|
76224
|
-
return issues;
|
|
76702
|
+
return this.checkAttributes(attributes);
|
|
76225
76703
|
}
|
|
76226
76704
|
checkAttributes(attr) {
|
|
76227
76705
|
if (attr === undefined) {
|
|
@@ -78891,7 +79369,7 @@ Make sure to test the downported code, it might not always be completely correct
|
|
|
78891
79369
|
if (found) {
|
|
78892
79370
|
return found;
|
|
78893
79371
|
}
|
|
78894
|
-
found = this.outlineGetReferenceSimple(high, lowFile);
|
|
79372
|
+
found = this.outlineGetReferenceSimple(high, lowFile, highSyntax);
|
|
78895
79373
|
if (found) {
|
|
78896
79374
|
return found;
|
|
78897
79375
|
}
|
|
@@ -79566,7 +80044,17 @@ ${indentation}CATCH ${className} INTO ${targetName}.`;
|
|
|
79566
80044
|
const fix = edit_helper_1.EditHelper.replaceRange(lowFile, node.getStart(), node.getEnd(), code);
|
|
79567
80045
|
return issue_1.Issue.atToken(lowFile, node.getFirstToken(), "Outline DATA", this.getMetadata().key, this.conf.severity, fix);
|
|
79568
80046
|
}
|
|
79569
|
-
|
|
80047
|
+
/** the type of a reference to the source: LIKE REF TO it, or REF TO data when its type is generic,
|
|
80048
|
+
* as LIKE REF TO a generically typed field symbol or parameter does not activate */
|
|
80049
|
+
refTypeOf(sourceName, node, lowFile, highSyntax) {
|
|
80050
|
+
var _a;
|
|
80051
|
+
const spag = highSyntax.spaghetti.lookupPosition(node.getFirstToken().getStart(), lowFile.getFilename());
|
|
80052
|
+
if (((_a = spag === null || spag === void 0 ? void 0 : spag.findVariable(sourceName)) === null || _a === void 0 ? void 0 : _a.getType().isGeneric()) === true) {
|
|
80053
|
+
return "TYPE REF TO data";
|
|
80054
|
+
}
|
|
80055
|
+
return "LIKE REF TO " + sourceName;
|
|
80056
|
+
}
|
|
80057
|
+
outlineGetReferenceSimple(node, lowFile, highSyntax) {
|
|
79570
80058
|
var _a, _b, _c;
|
|
79571
80059
|
if (!(node.get() instanceof Statements.GetReference)) {
|
|
79572
80060
|
return undefined;
|
|
@@ -79583,7 +80071,8 @@ ${indentation}CATCH ${className} INTO ${targetName}.`;
|
|
|
79583
80071
|
const indentation = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
|
|
79584
80072
|
const firstToken = target.getFirstToken();
|
|
79585
80073
|
const lastToken = target.getLastToken();
|
|
79586
|
-
const
|
|
80074
|
+
const refType = this.refTypeOf(source.concatTokens(), node, lowFile, highSyntax);
|
|
80075
|
+
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getStart(), `DATA ${targetName} ${refType}.\n${indentation}`);
|
|
79587
80076
|
const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, firstToken.getStart(), lastToken.getEnd(), targetName);
|
|
79588
80077
|
const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
|
|
79589
80078
|
return issue_1.Issue.atToken(lowFile, node.getFirstToken(), "Outline DATA", this.getMetadata().key, this.conf.severity, fix);
|
|
@@ -79600,7 +80089,7 @@ ${indentation}CATCH ${className} INTO ${targetName}.`;
|
|
|
79600
80089
|
if (!(((_a = target === null || target === void 0 ? void 0 : target.getFirstChild()) === null || _a === void 0 ? void 0 : _a.get()) instanceof Expressions.InlineData)) {
|
|
79601
80090
|
return undefined;
|
|
79602
80091
|
}
|
|
79603
|
-
let type
|
|
80092
|
+
let type;
|
|
79604
80093
|
const source = node.findFirstExpression(Expressions.Source);
|
|
79605
80094
|
if (source === undefined) {
|
|
79606
80095
|
return undefined;
|
|
@@ -79690,8 +80179,8 @@ ${indentation}CATCH ${className} INTO ${targetName}.`;
|
|
|
79690
80179
|
if (!(node.get() instanceof Statements.Raise)) {
|
|
79691
80180
|
return undefined;
|
|
79692
80181
|
}
|
|
79693
|
-
let id
|
|
79694
|
-
let number
|
|
80182
|
+
let id;
|
|
80183
|
+
let number;
|
|
79695
80184
|
let startToken = node.findDirectTokenByText("ID");
|
|
79696
80185
|
if (startToken) {
|
|
79697
80186
|
const sources = node.findDirectExpressions(Expressions.Source);
|
|
@@ -79849,7 +80338,7 @@ ${indentation}${uniqueName2}->if_t100_message~t100key = ${uniqueName1}.\n`;
|
|
|
79849
80338
|
|| sourceRef.getChildren().length !== 1) {
|
|
79850
80339
|
return undefined;
|
|
79851
80340
|
}
|
|
79852
|
-
let code
|
|
80341
|
+
let code;
|
|
79853
80342
|
if (sourceRef.findFirstExpression(Expressions.TableExpression)) {
|
|
79854
80343
|
const uniqueName = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
79855
80344
|
code = `ASSIGN ${sourceRef.concatTokens()} TO FIELD-SYMBOL(<${uniqueName}>).
|
|
@@ -80041,7 +80530,7 @@ LOOP AT ${groupTargetName}tab ${groupTarget}.`;
|
|
|
80041
80530
|
|| !(tableExpression instanceof nodes_1.ExpressionNode)) {
|
|
80042
80531
|
return undefined;
|
|
80043
80532
|
}
|
|
80044
|
-
let condition
|
|
80533
|
+
let condition;
|
|
80045
80534
|
if (tableExpression.getChildren().length === 3) {
|
|
80046
80535
|
const index = tableExpression.findDirectExpression(Expressions.Source);
|
|
80047
80536
|
if (index === undefined) {
|
|
@@ -80225,7 +80714,7 @@ ${indentation}${uniqueName}`;
|
|
|
80225
80714
|
return undefined;
|
|
80226
80715
|
}
|
|
80227
80716
|
const op = secondChild.getFirstToken();
|
|
80228
|
-
let operator
|
|
80717
|
+
let operator;
|
|
80229
80718
|
switch (op.getStr()) {
|
|
80230
80719
|
case "+":
|
|
80231
80720
|
operator = " + ";
|
|
@@ -80267,7 +80756,7 @@ ${indentation}${uniqueName}`;
|
|
|
80267
80756
|
|| (formatting === null || formatting === void 0 ? void 0 : formatting.startsWith("ALPHA = ")) === false) {
|
|
80268
80757
|
continue;
|
|
80269
80758
|
}
|
|
80270
|
-
let functionName
|
|
80759
|
+
let functionName;
|
|
80271
80760
|
switch (formatting) {
|
|
80272
80761
|
case "ALPHA = IN":
|
|
80273
80762
|
functionName = "CONVERSION_EXIT_ALPHA_INPUT";
|
|
@@ -80563,13 +81052,12 @@ ${indentation} output = ${uniqueName}.\n`;
|
|
|
80563
81052
|
const uniqueName = this.uniqueName(firstToken.getStart(), lowFile.getFilename(), highSyntax);
|
|
80564
81053
|
const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
|
|
80565
81054
|
let body = "";
|
|
80566
|
-
let name = "";
|
|
80567
81055
|
const switchBody = i.findDirectExpression(Expressions.SwitchBody);
|
|
80568
81056
|
if (switchBody === undefined) {
|
|
80569
81057
|
continue;
|
|
80570
81058
|
}
|
|
80571
81059
|
for (const l of ((_c = switchBody === null || switchBody === void 0 ? void 0 : switchBody.findDirectExpression(Expressions.Let)) === null || _c === void 0 ? void 0 : _c.findDirectExpressions(Expressions.InlineFieldDefinition)) || []) {
|
|
80572
|
-
name = l.getFirstToken().getStr();
|
|
81060
|
+
const name = l.getFirstToken().getStr();
|
|
80573
81061
|
body += indentation + `DATA(${name}) = ${(_d = switchBody.findFirstExpression(Expressions.Source)) === null || _d === void 0 ? void 0 : _d.concatTokens()}.\n`;
|
|
80574
81062
|
}
|
|
80575
81063
|
body += `DATA ${uniqueName} ${type}.\n`;
|
|
@@ -80627,7 +81115,6 @@ ${indentation} output = ${uniqueName}.\n`;
|
|
|
80627
81115
|
const uniqueName = this.uniqueName(firstToken.getStart(), lowFile.getFilename(), highSyntax);
|
|
80628
81116
|
const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
|
|
80629
81117
|
let body = "";
|
|
80630
|
-
let name = "";
|
|
80631
81118
|
const reduceBody = i.findDirectExpression(Expressions.ReduceBody);
|
|
80632
81119
|
if (reduceBody === undefined) {
|
|
80633
81120
|
continue;
|
|
@@ -80638,7 +81125,7 @@ ${indentation} output = ${uniqueName}.\n`;
|
|
|
80638
81125
|
}
|
|
80639
81126
|
let firstName = "";
|
|
80640
81127
|
for (const init of reduceBody.findDirectExpressions(Expressions.InlineFieldDefinition)) {
|
|
80641
|
-
name = init.getFirstToken().getStr();
|
|
81128
|
+
const name = init.getFirstToken().getStr();
|
|
80642
81129
|
if (firstName === "") {
|
|
80643
81130
|
firstName = name;
|
|
80644
81131
|
}
|
|
@@ -80870,7 +81357,7 @@ ${indentation} output = ${uniqueName}.\n`;
|
|
|
80870
81357
|
after += c.concatTokens();
|
|
80871
81358
|
}
|
|
80872
81359
|
}
|
|
80873
|
-
let condition
|
|
81360
|
+
let condition;
|
|
80874
81361
|
if ((tableExpression === null || tableExpression === void 0 ? void 0 : tableExpression.getChildren().length) === 3) {
|
|
80875
81362
|
condition = "INDEX " + ((_d = tableExpression === null || tableExpression === void 0 ? void 0 : tableExpression.findDirectExpression(Expressions.Source)) === null || _d === void 0 ? void 0 : _d.concatTokens());
|
|
80876
81363
|
}
|
|
@@ -81021,7 +81508,7 @@ ${indentation} output = ${uniqueName}.\n`;
|
|
|
81021
81508
|
continue;
|
|
81022
81509
|
}
|
|
81023
81510
|
const name = nameToken.getStr();
|
|
81024
|
-
let type
|
|
81511
|
+
let type;
|
|
81025
81512
|
if (high.concatTokens().toUpperCase().startsWith("APPEND INITIAL LINE TO ")) {
|
|
81026
81513
|
type = "LIKE LINE OF " + ((_b = high.findFirstExpression(Expressions.Target)) === null || _b === void 0 ? void 0 : _b.concatTokens());
|
|
81027
81514
|
}
|
|
@@ -81387,7 +81874,7 @@ ${indentation} output = ${uniqueName}.\n`;
|
|
|
81387
81874
|
}
|
|
81388
81875
|
return undefined;
|
|
81389
81876
|
}
|
|
81390
|
-
getReference(node, lowFile,
|
|
81877
|
+
getReference(node, lowFile, highSyntax) {
|
|
81391
81878
|
var _a, _b, _c;
|
|
81392
81879
|
if (!(node.get() instanceof Statements.GetReference)) {
|
|
81393
81880
|
return undefined;
|
|
@@ -81401,7 +81888,7 @@ ${indentation} output = ${uniqueName}.\n`;
|
|
|
81401
81888
|
if (targetName === undefined || sourceName === undefined) {
|
|
81402
81889
|
return undefined;
|
|
81403
81890
|
}
|
|
81404
|
-
const code = `DATA ${targetName}
|
|
81891
|
+
const code = `DATA ${targetName} ${this.refTypeOf(sourceName, node, lowFile, highSyntax)}.\n`;
|
|
81405
81892
|
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, node.getFirstToken().getStart(), code);
|
|
81406
81893
|
const fix2 = edit_helper_1.EditHelper.replaceRange(lowFile, inline.getFirstToken().getStart(), inline.getLastToken().getEnd(), targetName);
|
|
81407
81894
|
const fix = edit_helper_1.EditHelper.merge(fix2, fix1);
|
|
@@ -81478,18 +81965,30 @@ ${indentation} output = ${uniqueName}.\n`;
|
|
|
81478
81965
|
const uniqueName = this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax);
|
|
81479
81966
|
const indentation = " ".repeat(node.getFirstToken().getStart().getCol() - 1);
|
|
81480
81967
|
const sy = func === "LINE_EXISTS" ? "sy-subrc" : "sy-tabix";
|
|
81481
|
-
const code = `DATA ${uniqueName} LIKE sy-subrc.\n` +
|
|
81482
|
-
indentation + `READ TABLE ${tableName} ${condition}TRANSPORTING NO FIELDS.\n` +
|
|
81483
|
-
indentation + uniqueName + ` = ${sy}.\n` +
|
|
81484
|
-
indentation;
|
|
81485
81968
|
let insertAt = node.getFirstToken().getStart();
|
|
81486
81969
|
if (node.get() instanceof statements_1.ElseIf) {
|
|
81487
|
-
// assumption: no side effects in IF conditions
|
|
81970
|
+
// assumption: no side effects in IF conditions, except the READ itself, see below
|
|
81488
81971
|
insertAt = this.findStartOfIf(node, highFile);
|
|
81489
81972
|
if (insertAt === undefined) {
|
|
81490
81973
|
continue;
|
|
81491
81974
|
}
|
|
81492
81975
|
}
|
|
81976
|
+
// the READ sets sy-subrc and sy-tabix, which the built-in function does not,
|
|
81977
|
+
// keep the values for the code that reads them after the inserted READ
|
|
81978
|
+
const keep = [];
|
|
81979
|
+
const reads = this.readSyFields(insertAt, highFile);
|
|
81980
|
+
for (const field of ["sy-subrc", "sy-tabix"]) {
|
|
81981
|
+
if (reads.has(field)) {
|
|
81982
|
+
keep.push({ field, name: this.uniqueName(node.getFirstToken().getStart(), lowFile.getFilename(), highSyntax) });
|
|
81983
|
+
}
|
|
81984
|
+
}
|
|
81985
|
+
const code = `DATA ${uniqueName} LIKE sy-subrc.\n` +
|
|
81986
|
+
keep.map(k => indentation + `DATA ${k.name} LIKE ${k.field}.\n`).join("") +
|
|
81987
|
+
keep.map(k => indentation + `${k.name} = ${k.field}.\n`).join("") +
|
|
81988
|
+
indentation + `READ TABLE ${tableName} ${condition}TRANSPORTING NO FIELDS.\n` +
|
|
81989
|
+
indentation + uniqueName + ` = ${sy}.\n` +
|
|
81990
|
+
keep.map(k => indentation + `${k.field} = ${k.name}.\n`).join("") +
|
|
81991
|
+
indentation;
|
|
81493
81992
|
const fix1 = edit_helper_1.EditHelper.insertAt(lowFile, insertAt, code);
|
|
81494
81993
|
const start = expression.getFirstToken().getStart();
|
|
81495
81994
|
const end = expression.getLastToken().getEnd();
|
|
@@ -81500,6 +81999,46 @@ ${indentation} output = ${uniqueName}.\n`;
|
|
|
81500
81999
|
}
|
|
81501
82000
|
return undefined;
|
|
81502
82001
|
}
|
|
82002
|
+
/** sy-subrc and sy-tabix, when read from the position on, in the procedure around it or the file outside of one;
|
|
82003
|
+
* inside a loop from the start of the outermost loop, as the next pass reads what this one left */
|
|
82004
|
+
readSyFields(position, highFile) {
|
|
82005
|
+
const structure = highFile.getStructure();
|
|
82006
|
+
const contains = (s) => !position.isBefore(s.getFirstToken().getStart())
|
|
82007
|
+
&& !position.isAfter(s.getLastToken().getStart());
|
|
82008
|
+
let scope = undefined;
|
|
82009
|
+
for (const s of [Structures.Method, Structures.Form, Structures.FunctionModule]) {
|
|
82010
|
+
for (const p of (structure === null || structure === void 0 ? void 0 : structure.findAllStructuresRecursive(s)) || []) {
|
|
82011
|
+
if (contains(p)) {
|
|
82012
|
+
scope = p;
|
|
82013
|
+
}
|
|
82014
|
+
}
|
|
82015
|
+
}
|
|
82016
|
+
scope = scope || structure;
|
|
82017
|
+
let from = position;
|
|
82018
|
+
for (const s of [Structures.Loop, Structures.Do, Structures.While, Structures.Select]) {
|
|
82019
|
+
for (const l of (scope === null || scope === void 0 ? void 0 : scope.findAllStructuresRecursive(s)) || []) {
|
|
82020
|
+
if (contains(l) && l.getFirstToken().getStart().isBefore(from)) {
|
|
82021
|
+
from = l.getFirstToken().getStart();
|
|
82022
|
+
}
|
|
82023
|
+
}
|
|
82024
|
+
}
|
|
82025
|
+
const ret = new Set();
|
|
82026
|
+
for (const s of (scope === null || scope === void 0 ? void 0 : scope.findAllStatementNodes()) || []) {
|
|
82027
|
+
if (s.getLastToken().getStart().isBefore(from)) {
|
|
82028
|
+
continue;
|
|
82029
|
+
}
|
|
82030
|
+
const tokens = s.getTokens();
|
|
82031
|
+
for (let i = 0; i < tokens.length - 2; i++) {
|
|
82032
|
+
if (tokens[i].getStr().toUpperCase() === "SY" && tokens[i + 1].getStr() === "-") {
|
|
82033
|
+
const field = "sy-" + tokens[i + 2].getStr().toLowerCase();
|
|
82034
|
+
if (field === "sy-subrc" || field === "sy-tabix") {
|
|
82035
|
+
ret.add(field);
|
|
82036
|
+
}
|
|
82037
|
+
}
|
|
82038
|
+
}
|
|
82039
|
+
}
|
|
82040
|
+
return ret;
|
|
82041
|
+
}
|
|
81503
82042
|
findStartOfIf(node, highFile) {
|
|
81504
82043
|
const structure = highFile.getStructure();
|
|
81505
82044
|
for (const c of (structure === null || structure === void 0 ? void 0 : structure.findAllStructuresRecursive(Structures.If)) || []) {
|
|
@@ -81512,6 +82051,7 @@ ${indentation} output = ${uniqueName}.\n`;
|
|
|
81512
82051
|
return undefined;
|
|
81513
82052
|
}
|
|
81514
82053
|
newToCreateObject(low, high, lowFile, highSyntax) {
|
|
82054
|
+
var _a;
|
|
81515
82055
|
if (!(low.get() instanceof _statement_1.Unknown)) {
|
|
81516
82056
|
return undefined;
|
|
81517
82057
|
}
|
|
@@ -81527,7 +82067,7 @@ ${indentation} output = ${uniqueName}.\n`;
|
|
|
81527
82067
|
&& found
|
|
81528
82068
|
&& source.concatTokens() === found.concatTokens()
|
|
81529
82069
|
&& target.findDirectExpression(Expressions.InlineData) === undefined) {
|
|
81530
|
-
const abap = this.newParameters(found, target.concatTokens(), highSyntax, lowFile);
|
|
82070
|
+
const abap = (_a = this.newDataReference(high, target, found, lowFile, highSyntax)) !== null && _a !== void 0 ? _a : this.newParameters(found, target.concatTokens(), highSyntax, lowFile);
|
|
81531
82071
|
if (abap !== undefined) {
|
|
81532
82072
|
fix = edit_helper_1.EditHelper.replaceRange(lowFile, high.getFirstToken().getStart(), high.getLastToken().getEnd(), abap);
|
|
81533
82073
|
}
|
|
@@ -81566,6 +82106,42 @@ ${indentation} output = ${uniqueName}.\n`;
|
|
|
81566
82106
|
return undefined;
|
|
81567
82107
|
}
|
|
81568
82108
|
}
|
|
82109
|
+
/** NEW into a data reference creates data, CREATE OBJECT cannot: "target = NEW #|type( [value] )"
|
|
82110
|
+
* with a variable typed REF TO a data type becomes CREATE DATA plus the assignment of the value */
|
|
82111
|
+
newDataReference(high, target, found, lowFile, highSyntax) {
|
|
82112
|
+
var _a, _b, _c;
|
|
82113
|
+
if (target.getChildren().length !== 1 || !(((_a = target.getFirstChild()) === null || _a === void 0 ? void 0 : _a.get()) instanceof Expressions.TargetField)) {
|
|
82114
|
+
return undefined;
|
|
82115
|
+
}
|
|
82116
|
+
const children = found.getChildren();
|
|
82117
|
+
const value = found.findDirectExpression(Expressions.Source);
|
|
82118
|
+
// NEW, the type, "(", optionally one value, ")"
|
|
82119
|
+
if (children.length !== 4 + (value ? 1 : 0)) {
|
|
82120
|
+
return undefined;
|
|
82121
|
+
}
|
|
82122
|
+
const name = target.concatTokens();
|
|
82123
|
+
const spag = highSyntax.spaghetti.lookupPosition(high.getFirstToken().getStart(), lowFile.getFilename());
|
|
82124
|
+
const type = (_b = spag === null || spag === void 0 ? void 0 : spag.findVariable(name)) === null || _b === void 0 ? void 0 : _b.getType();
|
|
82125
|
+
if (!(type instanceof basic_1.DataReference)) {
|
|
82126
|
+
return undefined;
|
|
82127
|
+
}
|
|
82128
|
+
const typeName = (_c = found.findDirectExpression(Expressions.TypeNameOrInfer)) === null || _c === void 0 ? void 0 : _c.concatTokens();
|
|
82129
|
+
const indentation = " ".repeat(high.getFirstToken().getStart().getCol() - 1);
|
|
82130
|
+
let abap = `CREATE DATA ${name}` + (typeName === "#" ? "" : ` TYPE ${typeName}`) + ".";
|
|
82131
|
+
if (value === undefined) {
|
|
82132
|
+
return abap;
|
|
82133
|
+
}
|
|
82134
|
+
else if (type.getType().isGeneric() === false) {
|
|
82135
|
+
return abap + `\n${indentation}${name}->* = ${value.concatTokens()}.`;
|
|
82136
|
+
}
|
|
82137
|
+
// a generic reference cannot be dereferenced as a target below v756
|
|
82138
|
+
const fs = this.uniqueName(high.getFirstToken().getStart(), lowFile.getFilename(), highSyntax, true);
|
|
82139
|
+
abap = `FIELD-SYMBOLS ${fs} TYPE any.\n` +
|
|
82140
|
+
indentation + abap + "\n" +
|
|
82141
|
+
indentation + `ASSIGN ${name}->* TO ${fs}.\n` +
|
|
82142
|
+
indentation + `${fs} = ${value.concatTokens()}.`;
|
|
82143
|
+
return abap;
|
|
82144
|
+
}
|
|
81569
82145
|
newParameters(found, name, highSyntax, lowFile) {
|
|
81570
82146
|
var _a, _b, _c;
|
|
81571
82147
|
const typeToken = (_a = found.findDirectExpression(Expressions.TypeNameOrInfer)) === null || _a === void 0 ? void 0 : _a.getFirstToken();
|
|
@@ -82357,6 +82933,8 @@ class EmptyStructureConf extends _basic_rule_config_1.BasicRuleConfig {
|
|
|
82357
82933
|
this.try = true;
|
|
82358
82934
|
/** Checks for empty WHEN blocks */
|
|
82359
82935
|
this.when = true;
|
|
82936
|
+
/** Checks for empty CATCH blocks, unless the CATCH has pragma ##NO_HANDLER or pseudo comment "#EC NO_HANDLER */
|
|
82937
|
+
this.catch = false;
|
|
82360
82938
|
// todo, other category containing ELSE
|
|
82361
82939
|
}
|
|
82362
82940
|
}
|
|
@@ -82469,6 +83047,21 @@ result = xsdbool( sy-subrc = 0 ).`,
|
|
|
82469
83047
|
}
|
|
82470
83048
|
}
|
|
82471
83049
|
}
|
|
83050
|
+
if (this.getConfig().catch === true) {
|
|
83051
|
+
for (const c of stru.findAllStructuresRecursive(Structures.Catch)) {
|
|
83052
|
+
// a comment in the block does not count, the extended check (SLIN) reports it too
|
|
83053
|
+
if (c.findDirectStructure(Structures.Body) !== undefined) {
|
|
83054
|
+
continue;
|
|
83055
|
+
}
|
|
83056
|
+
const catchStatement = c.getFirstStatement();
|
|
83057
|
+
if (catchStatement === undefined || this.isNoHandler(catchStatement, statements)) {
|
|
83058
|
+
continue;
|
|
83059
|
+
}
|
|
83060
|
+
const token = c.getFirstToken();
|
|
83061
|
+
const issue = issue_1.Issue.atToken(file, token, this.getDescription(c.get().constructor.name), this.getMetadata().key, this.conf.severity);
|
|
83062
|
+
issues.push(issue);
|
|
83063
|
+
}
|
|
83064
|
+
}
|
|
82472
83065
|
if (this.getConfig().when === true) {
|
|
82473
83066
|
const tries = stru.findAllStructuresRecursive(Structures.When);
|
|
82474
83067
|
for (const t of tries) {
|
|
@@ -82482,6 +83075,15 @@ result = xsdbool( sy-subrc = 0 ).`,
|
|
|
82482
83075
|
}
|
|
82483
83076
|
return issues;
|
|
82484
83077
|
}
|
|
83078
|
+
isNoHandler(catchStatement, statements) {
|
|
83079
|
+
if (catchStatement.getPragmas().some(p => p.getStr().toUpperCase() === "##NO_HANDLER")) {
|
|
83080
|
+
return true;
|
|
83081
|
+
}
|
|
83082
|
+
const next = statements[statements.indexOf(catchStatement) + 1];
|
|
83083
|
+
return (next === null || next === void 0 ? void 0 : next.get()) instanceof _statement_1.Comment
|
|
83084
|
+
&& next.getStart().getRow() === catchStatement.getEnd().getRow()
|
|
83085
|
+
&& next.concatTokens().toUpperCase().replace(/\s/g, "").includes("\"#ECNO_HANDLER");
|
|
83086
|
+
}
|
|
82485
83087
|
}
|
|
82486
83088
|
exports.EmptyStructure = EmptyStructure;
|
|
82487
83089
|
//# sourceMappingURL=empty_structure.js.map
|
|
@@ -83918,7 +84520,7 @@ cl_abap_typedescr=>describe_by_name(
|
|
|
83918
84520
|
const methodSource = statNode.findDirectExpression(Expressions.MethodSource);
|
|
83919
84521
|
let methodSourceStr = methodSource === null || methodSource === void 0 ? void 0 : methodSource.concatTokens();
|
|
83920
84522
|
const methodBody = statNode.findDirectExpression(Expressions.MethodCallBody);
|
|
83921
|
-
let methodBodyStr
|
|
84523
|
+
let methodBodyStr;
|
|
83922
84524
|
if (methodBody) {
|
|
83923
84525
|
const methodCallParam = methodBody.findDirectExpression(Expressions.MethodCallParam);
|
|
83924
84526
|
if (methodCallParam && methodCallParam.getFirstToken().getStr() === "(") {
|
|
@@ -86812,7 +87414,7 @@ class KeywordCase extends _abap_rule_1.ABAPRule {
|
|
|
86812
87414
|
const firstToken = tokens[0].token;
|
|
86813
87415
|
const lastToken = tokens[tokens.length - 1].token;
|
|
86814
87416
|
const firstTokenValue = firstToken.getStr();
|
|
86815
|
-
let description
|
|
87417
|
+
let description;
|
|
86816
87418
|
if (first.keyword === true) {
|
|
86817
87419
|
description = `Keyword should be ${this.conf.style} case: "${firstTokenValue}"`;
|
|
86818
87420
|
}
|
|
@@ -87337,7 +87939,7 @@ ENDCLASS.`,
|
|
|
87337
87939
|
continue;
|
|
87338
87940
|
}
|
|
87339
87941
|
const className = classDef.name;
|
|
87340
|
-
let expected
|
|
87942
|
+
let expected;
|
|
87341
87943
|
if (classDef.isForTesting) {
|
|
87342
87944
|
expected = this.conf.test;
|
|
87343
87945
|
}
|
|
@@ -88003,7 +88605,7 @@ ENDIF.
|
|
|
88003
88605
|
issues.push(...this.analyzeCondition(file, cond));
|
|
88004
88606
|
}
|
|
88005
88607
|
for (const sub of structure.findAllExpressionsMulti([Expressions.CondSub, Expressions.ComponentCondSub])) {
|
|
88006
|
-
let cond
|
|
88608
|
+
let cond;
|
|
88007
88609
|
if (sub.get() instanceof Expressions.CondSub) {
|
|
88008
88610
|
cond = sub.findDirectExpressions(Expressions.Cond);
|
|
88009
88611
|
}
|
|
@@ -92041,13 +92643,9 @@ ENDIF.`,
|
|
|
92041
92643
|
}
|
|
92042
92644
|
else if (statement instanceof Statements.ClassDefinitionLoad ||
|
|
92043
92645
|
statement instanceof Statements.InterfaceLoad) {
|
|
92044
|
-
|
|
92045
|
-
|
|
92046
|
-
|
|
92047
|
-
}
|
|
92048
|
-
else {
|
|
92049
|
-
token = statementNode.getChildren()[2].getFirstToken();
|
|
92050
|
-
}
|
|
92646
|
+
const token = statement instanceof Statements.ClassDefinitionLoad
|
|
92647
|
+
? statementNode.getChildren()[3].getFirstToken()
|
|
92648
|
+
: statementNode.getChildren()[2].getFirstToken();
|
|
92051
92649
|
let startPosition = token.getStart();
|
|
92052
92650
|
startPosition = new position_1.Position(startPosition.getRow(), startPosition.getCol() - 1);
|
|
92053
92651
|
return edit_helper_1.EditHelper.deleteRange(file, startPosition, token.getEnd());
|
|
@@ -92844,7 +93442,6 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
|
92844
93442
|
exports.ParserMissingSpace = exports.ParserMissingSpaceConf = void 0;
|
|
92845
93443
|
const Expressions = __importStar(__webpack_require__(/*! ../abap/2_statements/expressions */ "./node_modules/@abaplint/core/build/src/abap/2_statements/expressions/index.js"));
|
|
92846
93444
|
const issue_1 = __webpack_require__(/*! ../issue */ "./node_modules/@abaplint/core/build/src/issue.js");
|
|
92847
|
-
const position_1 = __webpack_require__(/*! ../position */ "./node_modules/@abaplint/core/build/src/position.js");
|
|
92848
93445
|
const _abap_rule_1 = __webpack_require__(/*! ./_abap_rule */ "./node_modules/@abaplint/core/build/src/rules/_abap_rule.js");
|
|
92849
93446
|
const nodes_1 = __webpack_require__(/*! ../abap/nodes */ "./node_modules/@abaplint/core/build/src/abap/nodes/index.js");
|
|
92850
93447
|
const _basic_rule_config_1 = __webpack_require__(/*! ./_basic_rule_config */ "./node_modules/@abaplint/core/build/src/rules/_basic_rule_config.js");
|
|
@@ -92877,7 +93474,7 @@ This rule makes sure the spaces are consistently required across the language.`,
|
|
|
92877
93474
|
}
|
|
92878
93475
|
runParsed(file) {
|
|
92879
93476
|
const issues = [];
|
|
92880
|
-
let start
|
|
93477
|
+
let start;
|
|
92881
93478
|
for (const statement of file.getStatements()) {
|
|
92882
93479
|
const missing = this.missingSpace(statement);
|
|
92883
93480
|
if (missing) {
|
|
@@ -94438,14 +95035,8 @@ From 752 and up`,
|
|
|
94438
95035
|
}
|
|
94439
95036
|
getFix(file, statement, withExporting) {
|
|
94440
95037
|
const children = statement.getChildren();
|
|
94441
|
-
|
|
94442
|
-
|
|
94443
|
-
const fixText = "( " + children[5].concatTokens() + " ).";
|
|
94444
|
-
contentFix = edit_helper_1.EditHelper.replaceRange(file, children[3].getLastToken().getEnd(), statement.getEnd(), fixText);
|
|
94445
|
-
}
|
|
94446
|
-
else {
|
|
94447
|
-
contentFix = edit_helper_1.EditHelper.replaceRange(file, children[3].getLastToken().getEnd(), statement.getEnd(), "( ).");
|
|
94448
|
-
}
|
|
95038
|
+
const fixText = withExporting ? "( " + children[5].concatTokens() + " )." : "( ).";
|
|
95039
|
+
const contentFix = edit_helper_1.EditHelper.replaceRange(file, children[3].getLastToken().getEnd(), statement.getEnd(), fixText);
|
|
94449
95040
|
const replaceType = edit_helper_1.EditHelper.replaceToken(file, children[2].getFirstToken(), "NEW");
|
|
94450
95041
|
return edit_helper_1.EditHelper.merge(contentFix, replaceType);
|
|
94451
95042
|
}
|
|
@@ -102872,6 +103463,7 @@ class XMLConsistency {
|
|
|
102872
103463
|
* Naming for CLAS and INTF objects
|
|
102873
103464
|
* QUAN fields in TABL objects have reference table and field values
|
|
102874
103465
|
* Transparent TABL objects have delivery class and size category set
|
|
103466
|
+
* TABL fields with a built-in type carry the INTTYPE abapGit serializes for it, for the confirmed pairs
|
|
102875
103467
|
* Lock parameter names in ENQU objects are max 16 characters
|
|
102876
103468
|
* Texts and translations do not exceed maximum allowed length.`,
|
|
102877
103469
|
tags: [_irule_1.RuleTag.Naming, _irule_1.RuleTag.Syntax],
|
|
@@ -103138,6 +103730,12 @@ class XMLConsistency {
|
|
|
103138
103730
|
const message = `QUAN field ${field.FIELDNAME} must have REFTABLE and REFFIELD set`;
|
|
103139
103731
|
issues.push(issue_1.Issue.atRow(file, 1, message, this.getMetadata().key, this.conf.severity));
|
|
103140
103732
|
}
|
|
103733
|
+
const expected = field.DATATYPE ? XMLConsistency.intTypes[field.DATATYPE] : undefined;
|
|
103734
|
+
if (expected !== undefined && field.INTTYPE !== undefined && field.INTTYPE !== expected) {
|
|
103735
|
+
const message = `Field ${field.FIELDNAME}: INTTYPE "${field.INTTYPE}" does not match DATATYPE ${field.DATATYPE}, ` +
|
|
103736
|
+
`abapGit serializes "${expected}"`;
|
|
103737
|
+
issues.push(issue_1.Issue.atRow(file, 1, message, this.getMetadata().key, this.conf.severity));
|
|
103738
|
+
}
|
|
103141
103739
|
}
|
|
103142
103740
|
if (obj.getTableCategory() === Objects.TableCategory.Transparent) {
|
|
103143
103741
|
// Confirmed reserved database field names, see issue #4331, DAY and HOUR reported by activation.
|
|
@@ -103161,6 +103759,15 @@ class XMLConsistency {
|
|
|
103161
103759
|
}
|
|
103162
103760
|
}
|
|
103163
103761
|
exports.XMLConsistency = XMLConsistency;
|
|
103762
|
+
// INTTYPE that abapGit serializes for a built-in DATATYPE, confirmed by exported tables;
|
|
103763
|
+
// a different value activates, but shows as a diff on every pull
|
|
103764
|
+
XMLConsistency.intTypes = {
|
|
103765
|
+
"CHAR": "C", "CLNT": "C", "CUKY": "C", "LANG": "C",
|
|
103766
|
+
"DATS": "D", "TIMS": "T",
|
|
103767
|
+
"INT4": "X", "RAW": "X",
|
|
103768
|
+
"DEC": "P", "CURR": "P",
|
|
103769
|
+
"STRG": "g", "SSTR": "g", "RSTR": "y",
|
|
103770
|
+
};
|
|
103164
103771
|
//# sourceMappingURL=xml_consistency.js.map
|
|
103165
103772
|
|
|
103166
103773
|
/***/ },
|
|
@@ -103783,7 +104390,7 @@ class FormLengthStats {
|
|
|
103783
104390
|
return res;
|
|
103784
104391
|
}
|
|
103785
104392
|
static findName(stat) {
|
|
103786
|
-
let name
|
|
104393
|
+
let name;
|
|
103787
104394
|
const nameExpr = stat.findFirstExpression(expressions_1.FormName);
|
|
103788
104395
|
if (nameExpr) {
|
|
103789
104396
|
name = nameExpr.getFirstToken().getStr();
|
|
@@ -104194,7 +104801,7 @@ class MethodLengthStats {
|
|
|
104194
104801
|
return res;
|
|
104195
104802
|
}
|
|
104196
104803
|
static findName(stat) {
|
|
104197
|
-
let name
|
|
104804
|
+
let name;
|
|
104198
104805
|
const nameExpr = stat.findFirstExpression(expressions_1.MethodName);
|
|
104199
104806
|
if (nameExpr) {
|
|
104200
104807
|
name = nameExpr.getFirstToken().getStr();
|
|
@@ -127051,13 +127658,20 @@ class Traversal {
|
|
|
127051
127658
|
if (ref === undefined) {
|
|
127052
127659
|
return undefined;
|
|
127053
127660
|
}
|
|
127054
|
-
// local
|
|
127661
|
+
// local, also when the interface is declared in another include of the same object,
|
|
127662
|
+
// eg. a local interface in the locals_imp of a class, used in its test classes
|
|
127055
127663
|
if (ref.getFilename() === this.getFilename()) {
|
|
127056
127664
|
const scope = this.findCurrentScopeByToken(ref.getToken());
|
|
127057
127665
|
if (scope?.getIdentifier().stype === abaplint.ScopeType.Interface) {
|
|
127058
127666
|
return scope?.getIdentifier().sname;
|
|
127059
127667
|
}
|
|
127060
127668
|
}
|
|
127669
|
+
else if (this.getCurrentObject().getABAPFileByName(ref.getFilename()) !== undefined) {
|
|
127670
|
+
const scope = this.spaghetti.lookupPosition(ref.getStart(), ref.getFilename());
|
|
127671
|
+
if (scope?.getIdentifier().stype === abaplint.ScopeType.Interface) {
|
|
127672
|
+
return scope?.getIdentifier().sname;
|
|
127673
|
+
}
|
|
127674
|
+
}
|
|
127061
127675
|
// global
|
|
127062
127676
|
for (const obj of this.reg.getObjectsByType("INTF")) {
|
|
127063
127677
|
if (obj.getFiles().some(f => f.getFilename() === ref.getFilename())) {
|
|
@@ -127422,8 +128036,33 @@ this.INTERNAL_ID = abap.internalIdCounter++;\n`;
|
|
|
127422
128036
|
return `abap.Classes['${name}'] = ${Traversal.escapeNamespace(def.getName().toLowerCase())};`;
|
|
127423
128037
|
}
|
|
127424
128038
|
setValues(identifier, name) {
|
|
128039
|
+
// an enumerated value of a class or interface, declared without STRUCTURE: number the
|
|
128040
|
+
// values in the order they are declared, like the STRUCTURE components in setValues below
|
|
128041
|
+
if (identifier.getValue() === "novalueClassAttributeEnum"
|
|
128042
|
+
&& !(identifier.getType() instanceof abaplint.BasicTypes.StructureType)) {
|
|
128043
|
+
const index = this.findEnumValueIndex(identifier);
|
|
128044
|
+
return index === undefined ? "" : Traversal.prefixVariable(name) + ".set(" + index + ");\n";
|
|
128045
|
+
}
|
|
127425
128046
|
return Traversal.setValues(identifier, name);
|
|
127426
128047
|
}
|
|
128048
|
+
/** position of an enumerated value in its TYPES BEGIN OF ENUM, counting from 0 */
|
|
128049
|
+
findEnumValueIndex(identifier) {
|
|
128050
|
+
// the enum can be declared in another object, eg. a global interface the class implements
|
|
128051
|
+
const filename = identifier.getFilename();
|
|
128052
|
+
const raw = this.reg.getFileByName(filename);
|
|
128053
|
+
const obj = raw === undefined ? undefined : this.reg.findObjectForFile(raw);
|
|
128054
|
+
const file = obj instanceof abaplint.ABAPObject ? obj.getABAPFileByName(filename) : undefined;
|
|
128055
|
+
for (const enumeration of file?.getStructure()?.findAllStructures(abaplint.Structures.TypeEnum) || []) {
|
|
128056
|
+
const values = enumeration.getChildren().filter(c => c instanceof abaplint.Nodes.StatementNode
|
|
128057
|
+
&& (c.get() instanceof abaplint.Statements.Type || c.get() instanceof abaplint.Statements.TypeEnum));
|
|
128058
|
+
const index = values.findIndex(v => v
|
|
128059
|
+
.findFirstExpression(abaplint.Expressions.NamespaceSimpleName)?.getFirstToken().getStart().equals(identifier.getStart()));
|
|
128060
|
+
if (index >= 0) {
|
|
128061
|
+
return index;
|
|
128062
|
+
}
|
|
128063
|
+
}
|
|
128064
|
+
return undefined;
|
|
128065
|
+
}
|
|
127427
128066
|
static setValues(identifier, name) {
|
|
127428
128067
|
const val = identifier.getValue();
|
|
127429
128068
|
let ret = "";
|
|
@@ -127819,6 +128458,11 @@ run().then(() => {
|
|
|
127819
128458
|
}
|
|
127820
128459
|
methods.push(m.name);
|
|
127821
128460
|
}
|
|
128461
|
+
if (methods.length === 0) {
|
|
128462
|
+
// FOR TESTING helper class without test methods, nothing to run; it might also
|
|
128463
|
+
// live in locals_imp, which is not exported from the .testclasses module
|
|
128464
|
+
continue;
|
|
128465
|
+
}
|
|
127822
128466
|
tests.push({
|
|
127823
128467
|
obj,
|
|
127824
128468
|
filename: `${(0, output_layout_1.importPath)("index.mjs", this.layout.objectModule(obj, ".testclasses"))}`,
|