@abaplint/transpiler 2.13.86 → 2.13.88
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/src/db/populate_tables.js +40 -2
- package/build/src/expressions/source.d.ts +1 -0
- package/build/src/expressions/source.js +40 -0
- package/build/src/handlers/handle_abap.js +3 -2
- package/build/src/handlers/handle_w3mi.js +2 -1
- package/build/src/initialization.d.ts +1 -0
- package/build/src/initialization.js +13 -1
- package/build/src/keywords.js +6 -2
- package/build/src/rearranger.js +17 -1
- package/build/src/statements/create_object.d.ts +6 -0
- package/build/src/statements/create_object.js +28 -0
- package/build/src/structures/function_module.js +7 -7
- package/build/src/w3mi_name.d.ts +16 -0
- package/build/src/w3mi_name.js +42 -0
- package/package.json +3 -3
|
@@ -1,6 +1,42 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.PopulateTables = void 0;
|
|
37
|
+
/* eslint-disable max-len */
|
|
38
|
+
const abaplint = __importStar(require("@abaplint/core"));
|
|
39
|
+
const w3mi_name_1 = require("../w3mi_name");
|
|
4
40
|
class PopulateTables {
|
|
5
41
|
hasREPOSRC;
|
|
6
42
|
hasSEOSUBCO;
|
|
@@ -136,7 +172,9 @@ class PopulateTables {
|
|
|
136
172
|
return "";
|
|
137
173
|
}
|
|
138
174
|
const type = obj.getType().toUpperCase();
|
|
139
|
-
const name = obj.
|
|
175
|
+
const name = obj instanceof abaplint.Objects.WebMIME
|
|
176
|
+
? (0, w3mi_name_1.w3miObjectName)(obj)
|
|
177
|
+
: obj.getName().toUpperCase();
|
|
140
178
|
return `INSERT INTO "tadir" ("pgmid", "object", "obj_name", "devclass", "korrnum", "srcsystem", "delflag", "genflag", "edtflag", "masterlang")
|
|
141
179
|
VALUES ('R3TR', '${type}', '${this.escape(name)}', '$TMP', '', 'ABC', '', '', '', 'E');`;
|
|
142
180
|
}
|
|
@@ -145,7 +183,7 @@ class PopulateTables {
|
|
|
145
183
|
return [];
|
|
146
184
|
}
|
|
147
185
|
const ret = [];
|
|
148
|
-
const name =
|
|
186
|
+
const name = (0, w3mi_name_1.w3miObjectName)(obj);
|
|
149
187
|
for (const [key, value] of Object.entries(obj.getParameters())) {
|
|
150
188
|
ret.push(`INSERT INTO "wwwparams" ("relid", "objid", "name", "value") VALUES ('MI', '${name}', '${this.escape(key)}', '${this.escape(value)}');`);
|
|
151
189
|
}
|
|
@@ -5,5 +5,6 @@ import { Traversal } from "../traversal";
|
|
|
5
5
|
export declare class SourceTranspiler implements IExpressionTranspiler {
|
|
6
6
|
private readonly addGet;
|
|
7
7
|
constructor(addGet?: boolean);
|
|
8
|
+
private concatOperands;
|
|
8
9
|
transpile(node: Nodes.ExpressionNode, traversal: Traversal, context?: AbstractType): Chunk;
|
|
9
10
|
}
|
|
@@ -15,10 +15,50 @@ class SourceTranspiler {
|
|
|
15
15
|
constructor(addGet = false) {
|
|
16
16
|
this.addGet = addGet;
|
|
17
17
|
}
|
|
18
|
+
// the operands of a chain of & / && (the rearranger leaves them as a binary
|
|
19
|
+
// tree of Source nodes); an empty list when the node is not such a chain
|
|
20
|
+
concatOperands(node) {
|
|
21
|
+
const children = node.getChildren();
|
|
22
|
+
if (children.length !== 3) {
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
const op = children[1];
|
|
26
|
+
if (!(op instanceof core_1.Nodes.TokenNode) || (op.getFirstToken().getStr() !== "&&" && op.getFirstToken().getStr() !== "&")) {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
const side = (c) => {
|
|
30
|
+
if (c instanceof core_1.Nodes.ExpressionNode && c.get() instanceof core_1.Expressions.Source) {
|
|
31
|
+
const inner = this.concatOperands(c);
|
|
32
|
+
return inner.length > 0 ? inner : [c];
|
|
33
|
+
}
|
|
34
|
+
const wrapped = new core_1.Nodes.ExpressionNode(new core_1.Expressions.Source());
|
|
35
|
+
wrapped.setChildren([c]);
|
|
36
|
+
return [wrapped];
|
|
37
|
+
};
|
|
38
|
+
return [...side(children[0]), ...side(children[2])];
|
|
39
|
+
}
|
|
18
40
|
transpile(node, traversal, context) {
|
|
19
41
|
let ret = new chunk_1.Chunk();
|
|
20
42
|
const post = new chunk_1.Chunk();
|
|
21
43
|
const children = node.getChildren();
|
|
44
|
+
// a & b & c ... : one flat concat([a, b, c]) instead of one nested
|
|
45
|
+
// concat( ) per operand (a long chain would otherwise exhaust the stack
|
|
46
|
+
// of a parser with a small budget, e.g. a service worker's)
|
|
47
|
+
const operands = this.concatOperands(node);
|
|
48
|
+
if (operands.length > 2) {
|
|
49
|
+
const flat = new chunk_1.Chunk().appendString("abap.operators.concat([");
|
|
50
|
+
for (let i = 0; i < operands.length; i++) {
|
|
51
|
+
if (i > 0) {
|
|
52
|
+
flat.appendString(",");
|
|
53
|
+
}
|
|
54
|
+
flat.appendChunk(new SourceTranspiler(false).transpile(operands[i], traversal, context));
|
|
55
|
+
}
|
|
56
|
+
flat.appendString("])");
|
|
57
|
+
if (this.addGet) {
|
|
58
|
+
flat.appendString(".get()");
|
|
59
|
+
}
|
|
60
|
+
return flat;
|
|
61
|
+
}
|
|
22
62
|
// Pre-scan for unary prefix +/- tokens (WDashW / WPlusW) before any expression
|
|
23
63
|
let prefixNegated = false;
|
|
24
64
|
let startIdx = 0;
|
|
@@ -39,6 +39,7 @@ const traversal_1 = require("../traversal");
|
|
|
39
39
|
const requires_1 = require("../requires");
|
|
40
40
|
const rearranger_1 = require("../rearranger");
|
|
41
41
|
const chunk_1 = require("../chunk");
|
|
42
|
+
const initialization_1 = require("../initialization");
|
|
42
43
|
class HandleABAP {
|
|
43
44
|
options;
|
|
44
45
|
constructor(options) {
|
|
@@ -143,10 +144,10 @@ class HandleABAP {
|
|
|
143
144
|
continue;
|
|
144
145
|
}
|
|
145
146
|
if (name) {
|
|
146
|
-
contents.appendString("const {" + traversal_1.Traversal.escapeNamespace(name) + "} = await import(\"./" +
|
|
147
|
+
contents.appendString("const {" + traversal_1.Traversal.escapeNamespace(name) + "} = await import(\"./" + (0, initialization_1.escapeFilenameForImport)(filename) + "\");\n");
|
|
147
148
|
}
|
|
148
149
|
else {
|
|
149
|
-
contents.appendString("await import(\"./" +
|
|
150
|
+
contents.appendString("await import(\"./" + (0, initialization_1.escapeFilenameForImport)(filename) + "\");\n");
|
|
150
151
|
}
|
|
151
152
|
}
|
|
152
153
|
contents.appendChunk(output.chunk);
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.HandleW3MI = void 0;
|
|
4
4
|
const chunk_1 = require("../chunk");
|
|
5
|
+
const w3mi_name_1 = require("../w3mi_name");
|
|
5
6
|
class HandleW3MI {
|
|
6
7
|
runObject(obj, _reg) {
|
|
7
8
|
const filename = obj.getXMLFile()?.getFilename().replace(".xml", ".mjs").toLowerCase();
|
|
@@ -10,7 +11,7 @@ class HandleW3MI {
|
|
|
10
11
|
}
|
|
11
12
|
obj.parse();
|
|
12
13
|
const dataFile = obj.getDataFile();
|
|
13
|
-
const chunk = new chunk_1.Chunk().appendString(`abap.W3MI["${
|
|
14
|
+
const chunk = new chunk_1.Chunk().appendString(`abap.W3MI["${(0, w3mi_name_1.w3miObjectName)(obj)}"] = {
|
|
14
15
|
"objectType": "W3MI",
|
|
15
16
|
"filename": ${JSON.stringify(dataFile?.getFilename())},
|
|
16
17
|
};`);
|
|
@@ -2,6 +2,7 @@ import { DatabaseSetupResult } from "./db/database_setup_result";
|
|
|
2
2
|
import * as abaplint from "@abaplint/core";
|
|
3
3
|
import { ITranspilerOptions, IOutputFile } from "./types";
|
|
4
4
|
export declare function escapeNamespaceFilename(filename: string): string;
|
|
5
|
+
export declare function escapeFilenameForImport(filename: string): string;
|
|
5
6
|
export declare class Initialization {
|
|
6
7
|
script(reg: abaplint.IRegistry, dbSetup: DatabaseSetupResult, options: ITranspilerOptions | undefined, useImport?: boolean, pluginOutputs?: readonly IOutputFile[]): string;
|
|
7
8
|
private buildImports;
|
|
@@ -35,12 +35,24 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.Initialization = void 0;
|
|
37
37
|
exports.escapeNamespaceFilename = escapeNamespaceFilename;
|
|
38
|
+
exports.escapeFilenameForImport = escapeFilenameForImport;
|
|
38
39
|
const abaplint = __importStar(require("@abaplint/core"));
|
|
39
40
|
const handle_fugr_1 = require("./handlers/handle_fugr");
|
|
40
41
|
function escapeNamespaceFilename(filename) {
|
|
41
42
|
// ES modules are resolved and cached as URLs. This means that special characters must be
|
|
42
43
|
// percent-encoded, such as # with %23 and ? with %3F.
|
|
43
|
-
|
|
44
|
+
//
|
|
45
|
+
// The percent sign goes first, and the order is the whole point. A URL is
|
|
46
|
+
// percent-decoded before it is resolved, so a file whose *name* contains a
|
|
47
|
+
// percent has to carry it escaped or the decoding eats it: abapGit stores
|
|
48
|
+
// ZO4D_06_PLASMA.PNG as zo4d_06_plasma%2epng, and "./zo4d_06_plasma%2epng.w3mi.mjs"
|
|
49
|
+
// resolves to zo4d_06_plasma.png.w3mi.mjs, which is not there. Escaping the
|
|
50
|
+
// percent after the slash would corrupt the %23 this function just wrote.
|
|
51
|
+
return filename.replace(/%/g, "%25").replace(/\//g, "%23");
|
|
52
|
+
}
|
|
53
|
+
// The same rule for a name that already carries abapGit's # rather than a slash
|
|
54
|
+
function escapeFilenameForImport(filename) {
|
|
55
|
+
return filename.replace(/%/g, "%25").replace(/#/g, "%23");
|
|
44
56
|
}
|
|
45
57
|
class Initialization {
|
|
46
58
|
script(reg, dbSetup, options, useImport, pluginOutputs) {
|
package/build/src/keywords.js
CHANGED
|
@@ -20,7 +20,11 @@ exports.DEFAULT_KEYWORDS = new Set([
|
|
|
20
20
|
"throw", "throws", "transient", "true",
|
|
21
21
|
"try", "typeof", "var", "void",
|
|
22
22
|
"delete",
|
|
23
|
-
"volatile", "while", "yield"
|
|
23
|
+
"volatile", "while", "yield",
|
|
24
|
+
// both produce a SyntaxError in the emitted module: they are reserved words
|
|
25
|
+
// in JavaScript and legal ABAP names. "super" is NOT in this list on purpose -
|
|
26
|
+
// the emitted code uses the JS `super` for ABAP's `super->method( )`, and
|
|
27
|
+
// escaping it turns that call into `$super.get().method()`
|
|
28
|
+
"case", "with"
|
|
24
29
|
]);
|
|
25
|
-
// "with"
|
|
26
30
|
//# sourceMappingURL=keywords.js.map
|
package/build/src/rearranger.js
CHANGED
|
@@ -189,7 +189,23 @@ class Rearranger {
|
|
|
189
189
|
return node;
|
|
190
190
|
}
|
|
191
191
|
const withoutLast = node.getChildren().slice(0, children.length - 1);
|
|
192
|
-
|
|
192
|
+
// The nested children come up so that precedence can be decided across
|
|
193
|
+
// the whole chain, and everything before the nested operator has to
|
|
194
|
+
// arrive as one operand. For "a * b / c" that is already true, b being a
|
|
195
|
+
// single Source. For "a * CONV f( b ) / c" it is not: CONV is five
|
|
196
|
+
// children, and hoisting them one by one puts the type name and the
|
|
197
|
+
// body beside the arithmetic, where the transpiler reads them as
|
|
198
|
+
// operands and loses the rest of the expression. So the head is wrapped
|
|
199
|
+
// back into one Source before it moves.
|
|
200
|
+
const nested = last.getChildren();
|
|
201
|
+
const firstOperator = nested.findIndex((c) => c instanceof core_1.Nodes.ExpressionNode && c.get() instanceof core_1.Expressions.ArithOperator);
|
|
202
|
+
let head = nested.slice(0, firstOperator);
|
|
203
|
+
if (head.length > 1) {
|
|
204
|
+
const operand = new core_1.Nodes.ExpressionNode(last.get());
|
|
205
|
+
operand.setChildren(head);
|
|
206
|
+
head = [operand];
|
|
207
|
+
}
|
|
208
|
+
const flat = withoutLast.concat(head, nested.slice(firstOperator));
|
|
193
209
|
node.setChildren(flat);
|
|
194
210
|
return node;
|
|
195
211
|
}
|
|
@@ -4,5 +4,11 @@ import { Traversal } from "../traversal";
|
|
|
4
4
|
import { Chunk } from "../chunk";
|
|
5
5
|
export declare class CreateObjectTranspiler implements IStatementTranspiler {
|
|
6
6
|
transpile(node: abaplint.Nodes.StatementNode, traversal: Traversal): Chunk;
|
|
7
|
+
/** The name of the target reference's STATIC type, or undefined when there
|
|
8
|
+
* is nothing to check against - a generic `REF TO object`, or a target this
|
|
9
|
+
* cannot resolve (which is reported by findClassName on the static path and
|
|
10
|
+
* must not turn a working dynamic CREATE OBJECT into a transpile error
|
|
11
|
+
* here). */
|
|
12
|
+
private findTargetTypeName;
|
|
7
13
|
private findClassName;
|
|
8
14
|
}
|
|
@@ -77,11 +77,39 @@ class CreateObjectTranspiler {
|
|
|
77
77
|
ret += ` ${id} = abap.Classes[${internalName}.get().trimEnd()];\n`;
|
|
78
78
|
ret += `}\n`;
|
|
79
79
|
ret += `if (${id} === undefined) { throw new ${cx}; }\n`;
|
|
80
|
+
// ...and it has to be compatible with the STATIC type of the target.
|
|
81
|
+
// A system raises CX_SY_CREATE_OBJECT_ERROR for a class that is not,
|
|
82
|
+
// before the constructor runs; without this the class was assigned to
|
|
83
|
+
// the reference whatever it was, and the mismatch surfaced later as a
|
|
84
|
+
// javascript TypeError on the first member access - which no CATCH
|
|
85
|
+
// takes, so a caller that guards its dynamic CREATE OBJECT the way the
|
|
86
|
+
// documentation asks for was not guarded at all
|
|
87
|
+
const staticName = this.findTargetTypeName(node, traversal);
|
|
88
|
+
if (staticName !== undefined) {
|
|
89
|
+
const staticType = traversal.lookupClassOrInterface(staticName, node.getFirstToken());
|
|
90
|
+
ret += `abap.statements.checkCreateObjectType(${id}, ${staticType}, "${staticName.toUpperCase()}");\n`;
|
|
91
|
+
}
|
|
80
92
|
clas = id;
|
|
81
93
|
}
|
|
82
94
|
ret += target + ".set(await (new " + clas + "()).constructor_(" + para + "));";
|
|
83
95
|
return new chunk_1.Chunk(ret);
|
|
84
96
|
}
|
|
97
|
+
/** The name of the target reference's STATIC type, or undefined when there
|
|
98
|
+
* is nothing to check against - a generic `REF TO object`, or a target this
|
|
99
|
+
* cannot resolve (which is reported by findClassName on the static path and
|
|
100
|
+
* must not turn a working dynamic CREATE OBJECT into a transpile error
|
|
101
|
+
* here). */
|
|
102
|
+
findTargetTypeName(node, traversal) {
|
|
103
|
+
const scope = traversal.findCurrentScopeByToken(node.getFirstToken());
|
|
104
|
+
if (scope === undefined) {
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
const type = traversal.determineType(node, scope);
|
|
108
|
+
if (type instanceof abaplint.BasicTypes.ObjectReferenceType) {
|
|
109
|
+
return type.getIdentifierName();
|
|
110
|
+
}
|
|
111
|
+
return undefined;
|
|
112
|
+
}
|
|
85
113
|
findClassName(node, traversal) {
|
|
86
114
|
const c = node.findDirectExpression(abaplint.Expressions.ClassName);
|
|
87
115
|
if (c) {
|
|
@@ -87,16 +87,16 @@ class FunctionModuleTranspiler {
|
|
|
87
87
|
direction = "importing";
|
|
88
88
|
}
|
|
89
89
|
// note: all directions are optional
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
ret += `let ${
|
|
90
|
+
const name = p.name.toLowerCase();
|
|
91
|
+
// a parameter named like a JavaScript keyword, RETURN on every BAPI,
|
|
92
|
+
// is declared the way the function body refers to it
|
|
93
|
+
const variable = traversal_1.Traversal.prefixVariable(name);
|
|
94
|
+
ret += `let ${variable} = INPUT.${direction}?.${name};\n`;
|
|
95
95
|
const type = scope?.findVariable(name)?.getType();
|
|
96
96
|
if (type !== undefined && p.optional === true) {
|
|
97
97
|
// todo, set DEFAULT value
|
|
98
|
-
ret += `if (${
|
|
99
|
-
${
|
|
98
|
+
ret += `if (${variable} === undefined) {
|
|
99
|
+
${variable} = ${transpile_types_1.TranspileTypes.toType(type)};
|
|
100
100
|
}\n`;
|
|
101
101
|
}
|
|
102
102
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as abaplint from "@abaplint/core";
|
|
2
|
+
/**
|
|
3
|
+
* The name a system knows a Web Repository object by: `wwwdata-objid`.
|
|
4
|
+
*
|
|
5
|
+
* It is not the file name. abapGit percent-escapes the characters a file name
|
|
6
|
+
* cannot hold, so `ZOISEE-EAR-02.MP3` is stored as `zoisee-ear-02%2emp3`, and
|
|
7
|
+
* abaplint derives an object's name from the file it was read from. Keying
|
|
8
|
+
* anything a caller sees on that spelling turns an abapGit storage detail into
|
|
9
|
+
* an API: ABAP that asks `SELECT ... FROM wwwparams WHERE objid = 'X.MP3'`,
|
|
10
|
+
* which is how the object is addressed on a system, then finds nothing.
|
|
11
|
+
*
|
|
12
|
+
* The real name is in the object's own XML, and abapGit puts it there from the
|
|
13
|
+
* key itself — `io_xml->add( iv_name = 'NAME' ig_data = ms_key-objid )` in
|
|
14
|
+
* `zcl_abapgit_object_w3xx_super`, in both serializer versions.
|
|
15
|
+
*/
|
|
16
|
+
export declare function w3miObjectName(obj: abaplint.Objects.WebMIME): string;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.w3miObjectName = w3miObjectName;
|
|
4
|
+
/**
|
|
5
|
+
* The name a system knows a Web Repository object by: `wwwdata-objid`.
|
|
6
|
+
*
|
|
7
|
+
* It is not the file name. abapGit percent-escapes the characters a file name
|
|
8
|
+
* cannot hold, so `ZOISEE-EAR-02.MP3` is stored as `zoisee-ear-02%2emp3`, and
|
|
9
|
+
* abaplint derives an object's name from the file it was read from. Keying
|
|
10
|
+
* anything a caller sees on that spelling turns an abapGit storage detail into
|
|
11
|
+
* an API: ABAP that asks `SELECT ... FROM wwwparams WHERE objid = 'X.MP3'`,
|
|
12
|
+
* which is how the object is addressed on a system, then finds nothing.
|
|
13
|
+
*
|
|
14
|
+
* The real name is in the object's own XML, and abapGit puts it there from the
|
|
15
|
+
* key itself — `io_xml->add( iv_name = 'NAME' ig_data = ms_key-objid )` in
|
|
16
|
+
* `zcl_abapgit_object_w3xx_super`, in both serializer versions.
|
|
17
|
+
*/
|
|
18
|
+
function w3miObjectName(obj) {
|
|
19
|
+
const raw = obj.getXMLFile()?.getRaw();
|
|
20
|
+
if (raw !== undefined) {
|
|
21
|
+
// every entry of <PARAMS> carries a <NAME> of its own, so only the part
|
|
22
|
+
// before the parameter list can be searched for the object's
|
|
23
|
+
const head = raw.split(/<PARAMS[\s/>]/)[0];
|
|
24
|
+
const found = /<NAME>([^<]*)<\/NAME>/.exec(head);
|
|
25
|
+
const name = found === null ? "" : unescapeXML(found[1]).trim();
|
|
26
|
+
if (name.length > 0) {
|
|
27
|
+
return name.toUpperCase();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// an object with no XML, or an XML from something that is not abapGit: the
|
|
31
|
+
// file name is the only name there is, and a wrong key beats no key
|
|
32
|
+
return obj.getName().toUpperCase();
|
|
33
|
+
}
|
|
34
|
+
function unescapeXML(value) {
|
|
35
|
+
// a W3MI name may hold < and > and &, which reach the file escaped
|
|
36
|
+
return value.replace(/</g, "<")
|
|
37
|
+
.replace(/>/g, ">")
|
|
38
|
+
.replace(/"/g, "\"")
|
|
39
|
+
.replace(/'/g, "'")
|
|
40
|
+
.replace(/&/g, "&");
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=w3mi_name.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abaplint/transpiler",
|
|
3
|
-
"version": "2.13.
|
|
3
|
+
"version": "2.13.88",
|
|
4
4
|
"description": "Transpiler",
|
|
5
5
|
"main": "build/src/index.js",
|
|
6
6
|
"typings": "build/src/index.d.ts",
|
|
@@ -29,14 +29,14 @@
|
|
|
29
29
|
"author": "abaplint",
|
|
30
30
|
"license": "MIT",
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@abaplint/core": "^2.120.
|
|
32
|
+
"@abaplint/core": "^2.120.54",
|
|
33
33
|
"source-map": "^0.8.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/chai": "^5.2.3",
|
|
37
37
|
"@types/mocha": "^10.0.10",
|
|
38
38
|
"chai": "^6.2.2",
|
|
39
|
-
"mocha": "^12.0.
|
|
39
|
+
"mocha": "^12.0.2",
|
|
40
40
|
"source-map-support": "^0.5.21",
|
|
41
41
|
"typescript": "^6.0.3"
|
|
42
42
|
}
|