boperators 0.1.0
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 +202 -0
- package/dist/cjs/core/BopConfig.js +73 -0
- package/dist/cjs/core/ErrorManager.js +126 -0
- package/dist/cjs/core/OverloadInjector.js +136 -0
- package/dist/cjs/core/OverloadStore.js +622 -0
- package/dist/cjs/core/SourceMap.js +168 -0
- package/dist/cjs/core/helpers/ensureImportedName.js +50 -0
- package/dist/cjs/core/helpers/getImportedNameForSymbol.js +64 -0
- package/dist/cjs/core/helpers/getModuleSpecifier.js +61 -0
- package/dist/cjs/core/helpers/getOperatorStringFromProperty.js +33 -0
- package/dist/cjs/core/helpers/resolveExpressionType.js +30 -0
- package/dist/cjs/core/helpers/unwrapInitializer.js +18 -0
- package/dist/cjs/core/operatorMap.js +95 -0
- package/dist/cjs/core/validateExports.js +87 -0
- package/dist/cjs/index.js +36 -0
- package/dist/cjs/lib/index.js +17 -0
- package/dist/cjs/lib/operatorSymbols.js +37 -0
- package/dist/esm/core/BopConfig.d.ts +34 -0
- package/dist/esm/core/BopConfig.js +65 -0
- package/dist/esm/core/ErrorManager.d.ts +90 -0
- package/dist/esm/core/ErrorManager.js +118 -0
- package/dist/esm/core/OverloadInjector.d.ts +33 -0
- package/dist/esm/core/OverloadInjector.js +129 -0
- package/dist/esm/core/OverloadStore.d.ts +114 -0
- package/dist/esm/core/OverloadStore.js +618 -0
- package/dist/esm/core/SourceMap.d.ts +41 -0
- package/dist/esm/core/SourceMap.js +164 -0
- package/dist/esm/core/helpers/ensureImportedName.d.ts +11 -0
- package/dist/esm/core/helpers/ensureImportedName.js +46 -0
- package/dist/esm/core/helpers/getImportedNameForSymbol.d.ts +8 -0
- package/dist/esm/core/helpers/getImportedNameForSymbol.js +60 -0
- package/dist/esm/core/helpers/getModuleSpecifier.d.ts +2 -0
- package/dist/esm/core/helpers/getModuleSpecifier.js +57 -0
- package/dist/esm/core/helpers/getOperatorStringFromProperty.d.ts +13 -0
- package/dist/esm/core/helpers/getOperatorStringFromProperty.js +30 -0
- package/dist/esm/core/helpers/resolveExpressionType.d.ts +11 -0
- package/dist/esm/core/helpers/resolveExpressionType.js +27 -0
- package/dist/esm/core/helpers/unwrapInitializer.d.ts +9 -0
- package/dist/esm/core/helpers/unwrapInitializer.js +15 -0
- package/dist/esm/core/operatorMap.d.ts +77 -0
- package/dist/esm/core/operatorMap.js +89 -0
- package/dist/esm/core/validateExports.d.ts +30 -0
- package/dist/esm/core/validateExports.js +84 -0
- package/dist/esm/index.d.ts +19 -0
- package/dist/esm/index.js +14 -0
- package/dist/esm/lib/index.d.ts +1 -0
- package/dist/esm/lib/index.js +1 -0
- package/dist/esm/lib/operatorSymbols.d.ts +33 -0
- package/dist/esm/lib/operatorSymbols.js +34 -0
- package/license.txt +8 -0
- package/package.json +54 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SourceMap = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Bidirectional position mapping between original and transformed source text.
|
|
6
|
+
*
|
|
7
|
+
* Computes a list of edit records by diffing the two texts, then provides
|
|
8
|
+
* O(edits) position and span mapping in both directions.
|
|
9
|
+
*/
|
|
10
|
+
class SourceMap {
|
|
11
|
+
constructor(original, transformed) {
|
|
12
|
+
this.edits = computeEdits(original, transformed);
|
|
13
|
+
}
|
|
14
|
+
/** Returns true if no edits were detected (original === transformed). */
|
|
15
|
+
get isEmpty() {
|
|
16
|
+
return this.edits.length === 0;
|
|
17
|
+
}
|
|
18
|
+
/** Map a position from original source to transformed source. */
|
|
19
|
+
originalToTransformed(pos) {
|
|
20
|
+
let delta = 0;
|
|
21
|
+
for (const edit of this.edits) {
|
|
22
|
+
if (pos < edit.origStart) {
|
|
23
|
+
// Before this edit — just apply accumulated delta
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
if (pos < edit.origEnd) {
|
|
27
|
+
// Inside an edited region — map to start of the transformed replacement
|
|
28
|
+
return edit.transStart;
|
|
29
|
+
}
|
|
30
|
+
// Past this edit — accumulate the delta
|
|
31
|
+
delta = edit.transEnd - edit.origEnd;
|
|
32
|
+
}
|
|
33
|
+
return pos + delta;
|
|
34
|
+
}
|
|
35
|
+
/** Map a position from transformed source to original source. */
|
|
36
|
+
transformedToOriginal(pos) {
|
|
37
|
+
let delta = 0;
|
|
38
|
+
for (const edit of this.edits) {
|
|
39
|
+
if (pos < edit.transStart) {
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
if (pos < edit.transEnd) {
|
|
43
|
+
// Inside a transformed region — map to start of the original span
|
|
44
|
+
return edit.origStart;
|
|
45
|
+
}
|
|
46
|
+
delta = edit.origEnd - edit.transEnd;
|
|
47
|
+
}
|
|
48
|
+
return pos + delta;
|
|
49
|
+
}
|
|
50
|
+
/** Map a text span { start, length } from transformed positions to original positions. */
|
|
51
|
+
remapSpan(span) {
|
|
52
|
+
const origStart = this.transformedToOriginal(span.start);
|
|
53
|
+
const origEnd = this.transformedToOriginal(span.start + span.length);
|
|
54
|
+
return { start: origStart, length: origEnd - origStart };
|
|
55
|
+
}
|
|
56
|
+
/** Check if an original-source position falls inside an edited region. */
|
|
57
|
+
isInsideEdit(originalPos) {
|
|
58
|
+
for (const edit of this.edits) {
|
|
59
|
+
if (originalPos < edit.origStart)
|
|
60
|
+
return false;
|
|
61
|
+
if (originalPos < edit.origEnd)
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* For a position inside an edited region (in original coords),
|
|
68
|
+
* return the EditRecord it falls in, or undefined.
|
|
69
|
+
*/
|
|
70
|
+
getEditAt(originalPos) {
|
|
71
|
+
for (const edit of this.edits) {
|
|
72
|
+
if (originalPos < edit.origStart)
|
|
73
|
+
return undefined;
|
|
74
|
+
if (originalPos < edit.origEnd)
|
|
75
|
+
return edit;
|
|
76
|
+
}
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
exports.SourceMap = SourceMap;
|
|
81
|
+
/**
|
|
82
|
+
* Compute edit records by scanning both texts for mismatches.
|
|
83
|
+
*
|
|
84
|
+
* Uses character-level comparison with anchor-based convergence:
|
|
85
|
+
* identical characters are skipped, mismatches start an edit region,
|
|
86
|
+
* and convergence is found by searching for a matching anchor substring
|
|
87
|
+
* in the remaining text.
|
|
88
|
+
*/
|
|
89
|
+
function computeEdits(original, transformed) {
|
|
90
|
+
if (original === transformed)
|
|
91
|
+
return [];
|
|
92
|
+
const edits = [];
|
|
93
|
+
let i = 0; // index in original
|
|
94
|
+
let j = 0; // index in transformed
|
|
95
|
+
while (i < original.length && j < transformed.length) {
|
|
96
|
+
// Skip matching characters
|
|
97
|
+
if (original[i] === transformed[j]) {
|
|
98
|
+
i++;
|
|
99
|
+
j++;
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
// Mismatch — start of an edit
|
|
103
|
+
const origEditStart = i;
|
|
104
|
+
const transEditStart = j;
|
|
105
|
+
// Find where the texts converge again.
|
|
106
|
+
// Search for an anchor: a substring from `original` that also
|
|
107
|
+
// appears at the corresponding position in `transformed`.
|
|
108
|
+
const ANCHOR_LEN = 8;
|
|
109
|
+
let found = false;
|
|
110
|
+
// Scan ahead in original from the mismatch point
|
|
111
|
+
for (let oi = origEditStart + 1; oi <= original.length - ANCHOR_LEN; oi++) {
|
|
112
|
+
const anchor = original.substring(oi, oi + ANCHOR_LEN);
|
|
113
|
+
const transPos = transformed.indexOf(anchor, transEditStart);
|
|
114
|
+
if (transPos >= 0) {
|
|
115
|
+
// Verify the anchor actually converges by checking a few more chars
|
|
116
|
+
let valid = true;
|
|
117
|
+
const verifyLen = Math.min(ANCHOR_LEN * 2, original.length - oi, transformed.length - transPos);
|
|
118
|
+
for (let k = ANCHOR_LEN; k < verifyLen; k++) {
|
|
119
|
+
if (original[oi + k] !== transformed[transPos + k]) {
|
|
120
|
+
valid = false;
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (valid) {
|
|
125
|
+
edits.push({
|
|
126
|
+
origStart: origEditStart,
|
|
127
|
+
origEnd: oi,
|
|
128
|
+
transStart: transEditStart,
|
|
129
|
+
transEnd: transPos,
|
|
130
|
+
});
|
|
131
|
+
i = oi;
|
|
132
|
+
j = transPos;
|
|
133
|
+
found = true;
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (!found) {
|
|
139
|
+
// No convergence — remaining text is all part of the edit.
|
|
140
|
+
// Use common suffix to tighten the bounds.
|
|
141
|
+
let suffixLen = 0;
|
|
142
|
+
while (suffixLen < original.length - origEditStart &&
|
|
143
|
+
suffixLen < transformed.length - transEditStart &&
|
|
144
|
+
original[original.length - 1 - suffixLen] ===
|
|
145
|
+
transformed[transformed.length - 1 - suffixLen]) {
|
|
146
|
+
suffixLen++;
|
|
147
|
+
}
|
|
148
|
+
edits.push({
|
|
149
|
+
origStart: origEditStart,
|
|
150
|
+
origEnd: original.length - suffixLen,
|
|
151
|
+
transStart: transEditStart,
|
|
152
|
+
transEnd: transformed.length - suffixLen,
|
|
153
|
+
});
|
|
154
|
+
i = original.length;
|
|
155
|
+
j = transformed.length;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// Handle remaining text at the end
|
|
159
|
+
if (i < original.length || j < transformed.length) {
|
|
160
|
+
edits.push({
|
|
161
|
+
origStart: i,
|
|
162
|
+
origEnd: original.length,
|
|
163
|
+
transStart: j,
|
|
164
|
+
transEnd: transformed.length,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
return edits;
|
|
168
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ensureImportedName = void 0;
|
|
4
|
+
const ts_morph_1 = require("ts-morph");
|
|
5
|
+
const getImportedNameForSymbol_1 = require("./getImportedNameForSymbol");
|
|
6
|
+
/**
|
|
7
|
+
* Ensures that the specified symbol is imported into the source file.
|
|
8
|
+
* If it is not already imported, adds it.
|
|
9
|
+
*
|
|
10
|
+
* @param sourceFile The SourceFile to modify.
|
|
11
|
+
* @param symbol The AstSymbol representing the class to import.
|
|
12
|
+
* @param moduleSpecifier The module from which the class should be imported.
|
|
13
|
+
* @returns The imported identifier name to use in the source file.
|
|
14
|
+
*/
|
|
15
|
+
const ensureImportedName = (sourceFile, symbol, moduleSpecifier) => {
|
|
16
|
+
// Attempt to get the imported name if it already exists
|
|
17
|
+
const existingName = (0, getImportedNameForSymbol_1.getImportedNameForSymbol)(sourceFile, symbol);
|
|
18
|
+
if (existingName)
|
|
19
|
+
return existingName; // Return the already-imported name
|
|
20
|
+
// Generate a unique name for the new import
|
|
21
|
+
const symbolName = symbol.getName();
|
|
22
|
+
let newImportName = symbolName;
|
|
23
|
+
// Ensure the name doesn't clash with existing identifiers in the source file
|
|
24
|
+
const existingIdentifiers = sourceFile.getDescendantsOfKind(ts_morph_1.SyntaxKind.Identifier);
|
|
25
|
+
const existingNames = new Set(existingIdentifiers.map((id) => id.getText()));
|
|
26
|
+
while (existingNames.has(newImportName)) {
|
|
27
|
+
newImportName = `${symbolName}_${Math.random().toString(36).substr(2, 5)}`;
|
|
28
|
+
}
|
|
29
|
+
// Check if the module is already imported
|
|
30
|
+
const existingImport = sourceFile
|
|
31
|
+
.getImportDeclarations()
|
|
32
|
+
.find((importDecl) => importDecl.getModuleSpecifierValue() === moduleSpecifier);
|
|
33
|
+
if (existingImport) {
|
|
34
|
+
// Add the new import to the named imports
|
|
35
|
+
existingImport.addNamedImport(newImportName === symbolName
|
|
36
|
+
? symbolName
|
|
37
|
+
: { name: symbolName, alias: newImportName });
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
// Add a new import declaration
|
|
41
|
+
sourceFile.addImportDeclaration({
|
|
42
|
+
moduleSpecifier,
|
|
43
|
+
namedImports: newImportName === symbolName
|
|
44
|
+
? [symbolName]
|
|
45
|
+
: [{ name: symbolName, alias: newImportName }],
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
return newImportName;
|
|
49
|
+
};
|
|
50
|
+
exports.ensureImportedName = ensureImportedName;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getImportedNameForSymbol = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Checks if the given symbol is already imported in the SourceFile.
|
|
6
|
+
* @param sourceFile The SourceFile to search for imports.
|
|
7
|
+
* @param symbol The AstSymbol to match against imports.
|
|
8
|
+
* @returns The imported identifier name if found, otherwise undefined.
|
|
9
|
+
*/
|
|
10
|
+
const getImportedNameForSymbol = (sourceFile, symbol) => {
|
|
11
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
12
|
+
const aliasedSymbol = (_a = symbol.getAliasedSymbol()) !== null && _a !== void 0 ? _a : symbol;
|
|
13
|
+
// Helper function to compare symbols by their declarations
|
|
14
|
+
const symbolsAreEquivalent = (a, b) => {
|
|
15
|
+
if (!a || !b)
|
|
16
|
+
return false;
|
|
17
|
+
const aDecls = a.getDeclarations();
|
|
18
|
+
const bDecls = b.getDeclarations();
|
|
19
|
+
if (aDecls.length !== bDecls.length)
|
|
20
|
+
return false;
|
|
21
|
+
return aDecls.every((aDecl, i) => aDecl.getSourceFile() === bDecls[i].getSourceFile() &&
|
|
22
|
+
aDecl.getStart() === bDecls[i].getStart());
|
|
23
|
+
};
|
|
24
|
+
// Get all import declarations in the source file
|
|
25
|
+
const importDeclarations = sourceFile.getImportDeclarations();
|
|
26
|
+
for (const importDecl of importDeclarations) {
|
|
27
|
+
// Named imports
|
|
28
|
+
const namedImports = importDecl.getNamedImports();
|
|
29
|
+
for (const namedImport of namedImports) {
|
|
30
|
+
const importedSymbol = namedImport.getSymbol();
|
|
31
|
+
if (symbolsAreEquivalent(importedSymbol === null || importedSymbol === void 0 ? void 0 : importedSymbol.getAliasedSymbol(), aliasedSymbol)) {
|
|
32
|
+
return ((_c = (_b = namedImport.getAliasNode()) === null || _b === void 0 ? void 0 : _b.getText()) !== null && _c !== void 0 ? _c : namedImport.getNameNode().getText());
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// Default import
|
|
36
|
+
const defaultImport = importDecl.getDefaultImport();
|
|
37
|
+
if (defaultImport) {
|
|
38
|
+
const defaultSymbol = (_d = defaultImport.getSymbol()) === null || _d === void 0 ? void 0 : _d.getAliasedSymbol();
|
|
39
|
+
if (symbolsAreEquivalent(defaultSymbol, aliasedSymbol)) {
|
|
40
|
+
// Return the default import name
|
|
41
|
+
return defaultImport.getText();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// Check namespace imports
|
|
45
|
+
const namespaceImport = importDecl.getNamespaceImport();
|
|
46
|
+
if (namespaceImport) {
|
|
47
|
+
const namespaceSymbol = namespaceImport.getSymbol();
|
|
48
|
+
if (namespaceSymbol) {
|
|
49
|
+
// Look for the symbol under this namespace
|
|
50
|
+
const exports = (_f = (_e = namespaceSymbol.getAliasedSymbol()) === null || _e === void 0 ? void 0 : _e.getExports()) !== null && _f !== void 0 ? _f : [];
|
|
51
|
+
for (const exportedSymbol of exports) {
|
|
52
|
+
const resolvedExportedSymbol = (_g = exportedSymbol.getAliasedSymbol()) !== null && _g !== void 0 ? _g : exportedSymbol;
|
|
53
|
+
if (symbolsAreEquivalent(resolvedExportedSymbol, aliasedSymbol)) {
|
|
54
|
+
// Return namespace-qualified name (e.g., v3.Vector3)
|
|
55
|
+
return `${namespaceImport.getText()}.${exportedSymbol.getName()}`;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// No matching import found
|
|
62
|
+
return undefined;
|
|
63
|
+
};
|
|
64
|
+
exports.getImportedNameForSymbol = getImportedNameForSymbol;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getModuleSpecifier = void 0;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
/**
|
|
7
|
+
* Walk up from a file path to find the nearest `package.json` with a `name`
|
|
8
|
+
* field. Returns the package name and the directory containing it.
|
|
9
|
+
*/
|
|
10
|
+
function findPackageInfo(filePath) {
|
|
11
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
12
|
+
let dir = node_path_1.posix.dirname(normalized);
|
|
13
|
+
while (true) {
|
|
14
|
+
const pkgJsonPath = `${dir}/package.json`;
|
|
15
|
+
if ((0, node_fs_1.existsSync)(pkgJsonPath)) {
|
|
16
|
+
try {
|
|
17
|
+
const content = (0, node_fs_1.readFileSync)(pkgJsonPath, "utf-8");
|
|
18
|
+
const pkg = JSON.parse(content);
|
|
19
|
+
if (typeof pkg.name === "string") {
|
|
20
|
+
return { name: pkg.name, dir };
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch (_a) {
|
|
24
|
+
// Malformed package.json, continue searching up
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const parent = node_path_1.posix.dirname(dir);
|
|
28
|
+
if (parent === dir)
|
|
29
|
+
break; // filesystem root
|
|
30
|
+
dir = parent;
|
|
31
|
+
}
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Checks if `fromFile` already imports from `pkgName` (or a subpath of it)
|
|
36
|
+
* and returns that specifier if so. Otherwise returns `pkgName` bare.
|
|
37
|
+
*/
|
|
38
|
+
function reuseExistingImportOrReturn(fromFile, pkgName) {
|
|
39
|
+
for (const decl of fromFile.getImportDeclarations()) {
|
|
40
|
+
const specifier = decl.getModuleSpecifierValue();
|
|
41
|
+
if (specifier === pkgName || specifier.startsWith(`${pkgName}/`)) {
|
|
42
|
+
return specifier;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return pkgName;
|
|
46
|
+
}
|
|
47
|
+
const getModuleSpecifier = (fromFile, toFile) => {
|
|
48
|
+
const toPath = toFile.getFilePath();
|
|
49
|
+
const fromPath = fromFile.getFilePath();
|
|
50
|
+
// Check if source and target belong to different packages
|
|
51
|
+
const toPkg = findPackageInfo(toPath);
|
|
52
|
+
const fromPkg = findPackageInfo(fromPath);
|
|
53
|
+
if (toPkg && fromPkg && toPkg.dir !== fromPkg.dir) {
|
|
54
|
+
return reuseExistingImportOrReturn(fromFile, toPkg.name);
|
|
55
|
+
}
|
|
56
|
+
// Same package (or couldn't determine) — use a relative path
|
|
57
|
+
const fromDir = node_path_1.posix.dirname(fromPath);
|
|
58
|
+
const relativePath = node_path_1.posix.relative(fromDir, toPath);
|
|
59
|
+
return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
|
|
60
|
+
};
|
|
61
|
+
exports.getModuleSpecifier = getModuleSpecifier;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getOperatorStringFromProperty = getOperatorStringFromProperty;
|
|
4
|
+
const ts_morph_1 = require("ts-morph");
|
|
5
|
+
/**
|
|
6
|
+
* Extracts the operator string from a class property declaration, if it
|
|
7
|
+
* represents an operator overload.
|
|
8
|
+
*
|
|
9
|
+
* Handles three property name styles:
|
|
10
|
+
* - `["+"]` — ComputedPropertyName with a StringLiteral expression
|
|
11
|
+
* - `[Operator.PLUS]` — ComputedPropertyName with an enum member expression
|
|
12
|
+
* - `"+"` — StringLiteral property name
|
|
13
|
+
*
|
|
14
|
+
* Returns `undefined` if the property name doesn't resolve to an operator string.
|
|
15
|
+
*/
|
|
16
|
+
function getOperatorStringFromProperty(property) {
|
|
17
|
+
const nameNode = property.getNameNode();
|
|
18
|
+
if (nameNode.isKind(ts_morph_1.SyntaxKind.ComputedPropertyName)) {
|
|
19
|
+
const expression = nameNode.getExpression();
|
|
20
|
+
if (expression.isKind(ts_morph_1.SyntaxKind.StringLiteral)) {
|
|
21
|
+
return expression.getLiteralValue();
|
|
22
|
+
}
|
|
23
|
+
// Handle Operator.PLUS style (enum member access)
|
|
24
|
+
const literalValue = expression.getType().getLiteralValue();
|
|
25
|
+
if (typeof literalValue === "string") {
|
|
26
|
+
return literalValue;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
else if (nameNode.isKind(ts_morph_1.SyntaxKind.StringLiteral)) {
|
|
30
|
+
return nameNode.getLiteralValue();
|
|
31
|
+
}
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveExpressionType = resolveExpressionType;
|
|
4
|
+
const ts_morph_1 = require("ts-morph");
|
|
5
|
+
/**
|
|
6
|
+
* Resolves the effective type name for a node in a binary expression.
|
|
7
|
+
*
|
|
8
|
+
* Handles special cases:
|
|
9
|
+
* - Numeric literals → `"number"`
|
|
10
|
+
* - Boolean literals (not in string context) → `"boolean"`
|
|
11
|
+
* - `"any"` type → falls back to the declared type of the symbol
|
|
12
|
+
* (needed for compound assignments where TS can't infer the result type)
|
|
13
|
+
*/
|
|
14
|
+
function resolveExpressionType(node) {
|
|
15
|
+
var _a;
|
|
16
|
+
let typeName = node.getType().getText();
|
|
17
|
+
if (node.getKind() === ts_morph_1.SyntaxKind.NumericLiteral) {
|
|
18
|
+
return "number";
|
|
19
|
+
}
|
|
20
|
+
if (node.getKind() !== ts_morph_1.SyntaxKind.StringLiteral &&
|
|
21
|
+
(typeName === "true" || typeName === "false")) {
|
|
22
|
+
return "boolean";
|
|
23
|
+
}
|
|
24
|
+
if (typeName === "any") {
|
|
25
|
+
const decl = (_a = node.getSymbol()) === null || _a === void 0 ? void 0 : _a.getValueDeclaration();
|
|
26
|
+
if (decl)
|
|
27
|
+
typeName = decl.getType().getText();
|
|
28
|
+
}
|
|
29
|
+
return typeName;
|
|
30
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.unwrapInitializer = unwrapInitializer;
|
|
4
|
+
const ts_morph_1 = require("ts-morph");
|
|
5
|
+
/**
|
|
6
|
+
* Unwraps `as const` and `satisfies` type assertions from an initializer
|
|
7
|
+
* expression, returning the underlying expression.
|
|
8
|
+
*
|
|
9
|
+
* For example, given `[fn1, fn2] as const`, this returns the
|
|
10
|
+
* `[fn1, fn2]` ArrayLiteralExpression.
|
|
11
|
+
*/
|
|
12
|
+
function unwrapInitializer(initializer) {
|
|
13
|
+
if (initializer && ts_morph_1.Node.isAsExpression(initializer))
|
|
14
|
+
initializer = initializer.getExpression();
|
|
15
|
+
if (initializer && ts_morph_1.Node.isSatisfiesExpression(initializer))
|
|
16
|
+
initializer = initializer.getExpression();
|
|
17
|
+
return initializer;
|
|
18
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.postfixUnaryOperatorStrings = exports.prefixUnaryOperatorStrings = exports.isPostfixUnaryOperatorSyntaxKind = exports.postfixUnaryOperatorSyntaxKinds = exports.postfixUnaryOperatorMap = exports.isPrefixUnaryOperatorSyntaxKind = exports.prefixUnaryOperatorSyntaxKinds = exports.prefixUnaryOperatorMap = exports.comparisonOperators = exports.instanceOperators = exports.isOperatorSyntaxKind = exports.operatorSyntaxKinds = exports.operatorMap = void 0;
|
|
4
|
+
const ts_morph_1 = require("ts-morph");
|
|
5
|
+
const operatorSymbols_1 = require("../lib/operatorSymbols");
|
|
6
|
+
/**
|
|
7
|
+
* Maps operator string values to their corresponding TypeScript syntax kind.
|
|
8
|
+
*/
|
|
9
|
+
exports.operatorMap = {
|
|
10
|
+
[operatorSymbols_1.Operator.PLUS]: ts_morph_1.SyntaxKind.PlusToken,
|
|
11
|
+
[operatorSymbols_1.Operator.PLUS_EQUALS]: ts_morph_1.SyntaxKind.PlusEqualsToken,
|
|
12
|
+
[operatorSymbols_1.Operator.MINUS]: ts_morph_1.SyntaxKind.MinusToken,
|
|
13
|
+
[operatorSymbols_1.Operator.MINUS_EQUALS]: ts_morph_1.SyntaxKind.MinusEqualsToken,
|
|
14
|
+
[operatorSymbols_1.Operator.MULTIPLY]: ts_morph_1.SyntaxKind.AsteriskToken,
|
|
15
|
+
[operatorSymbols_1.Operator.MULTIPLY_EQUALS]: ts_morph_1.SyntaxKind.AsteriskEqualsToken,
|
|
16
|
+
[operatorSymbols_1.Operator.DIVIDE]: ts_morph_1.SyntaxKind.SlashToken,
|
|
17
|
+
[operatorSymbols_1.Operator.DIVIDE_EQUALS]: ts_morph_1.SyntaxKind.SlashEqualsToken,
|
|
18
|
+
[operatorSymbols_1.Operator.GREATER_THAN]: ts_morph_1.SyntaxKind.GreaterThanToken,
|
|
19
|
+
[operatorSymbols_1.Operator.GREATER_THAN_EQUAL_TO]: ts_morph_1.SyntaxKind.GreaterThanEqualsToken,
|
|
20
|
+
[operatorSymbols_1.Operator.LESS_THAN]: ts_morph_1.SyntaxKind.LessThanToken,
|
|
21
|
+
[operatorSymbols_1.Operator.LESS_THAN_EQUAL_TO]: ts_morph_1.SyntaxKind.LessThanEqualsToken,
|
|
22
|
+
[operatorSymbols_1.Operator.MODULO]: ts_morph_1.SyntaxKind.PercentToken,
|
|
23
|
+
[operatorSymbols_1.Operator.MODULO_EQUALS]: ts_morph_1.SyntaxKind.PercentEqualsToken,
|
|
24
|
+
[operatorSymbols_1.Operator.EQUALS]: ts_morph_1.SyntaxKind.EqualsEqualsToken,
|
|
25
|
+
[operatorSymbols_1.Operator.STRICT_EQUALS]: ts_morph_1.SyntaxKind.EqualsEqualsEqualsToken,
|
|
26
|
+
[operatorSymbols_1.Operator.NOT_EQUALS]: ts_morph_1.SyntaxKind.ExclamationEqualsToken,
|
|
27
|
+
[operatorSymbols_1.Operator.STRICT_NOT_EQUALS]: ts_morph_1.SyntaxKind.ExclamationEqualsEqualsToken,
|
|
28
|
+
[operatorSymbols_1.Operator.AND]: ts_morph_1.SyntaxKind.AmpersandAmpersandToken,
|
|
29
|
+
[operatorSymbols_1.Operator.AND_EQUALS]: ts_morph_1.SyntaxKind.AmpersandAmpersandEqualsToken,
|
|
30
|
+
[operatorSymbols_1.Operator.OR]: ts_morph_1.SyntaxKind.BarBarToken,
|
|
31
|
+
[operatorSymbols_1.Operator.OR_EQUALS]: ts_morph_1.SyntaxKind.BarBarEqualsToken,
|
|
32
|
+
[operatorSymbols_1.Operator.NULLISH]: ts_morph_1.SyntaxKind.QuestionQuestionToken,
|
|
33
|
+
};
|
|
34
|
+
exports.operatorSyntaxKinds = Object.values(exports.operatorMap);
|
|
35
|
+
const isOperatorSyntaxKind = (syntaxKind) => exports.operatorSyntaxKinds.includes(syntaxKind);
|
|
36
|
+
exports.isOperatorSyntaxKind = isOperatorSyntaxKind;
|
|
37
|
+
/**
|
|
38
|
+
* Set of which operators whose overloads should be instance operators
|
|
39
|
+
* i.e. operate on the LHS object.
|
|
40
|
+
* These should return void.
|
|
41
|
+
*/
|
|
42
|
+
exports.instanceOperators = new Set([
|
|
43
|
+
exports.operatorMap[operatorSymbols_1.Operator.PLUS_EQUALS],
|
|
44
|
+
exports.operatorMap[operatorSymbols_1.Operator.MINUS_EQUALS],
|
|
45
|
+
exports.operatorMap[operatorSymbols_1.Operator.MULTIPLY_EQUALS],
|
|
46
|
+
exports.operatorMap[operatorSymbols_1.Operator.DIVIDE_EQUALS],
|
|
47
|
+
exports.operatorMap[operatorSymbols_1.Operator.MODULO_EQUALS],
|
|
48
|
+
exports.operatorMap[operatorSymbols_1.Operator.AND_EQUALS],
|
|
49
|
+
exports.operatorMap[operatorSymbols_1.Operator.OR_EQUALS],
|
|
50
|
+
]);
|
|
51
|
+
/**
|
|
52
|
+
* Set of operators where the expected return type of their overload is a boolean.
|
|
53
|
+
*/
|
|
54
|
+
exports.comparisonOperators = new Set([
|
|
55
|
+
exports.operatorMap[operatorSymbols_1.Operator.GREATER_THAN],
|
|
56
|
+
exports.operatorMap[operatorSymbols_1.Operator.GREATER_THAN_EQUAL_TO],
|
|
57
|
+
exports.operatorMap[operatorSymbols_1.Operator.LESS_THAN],
|
|
58
|
+
exports.operatorMap[operatorSymbols_1.Operator.LESS_THAN_EQUAL_TO],
|
|
59
|
+
exports.operatorMap[operatorSymbols_1.Operator.EQUALS],
|
|
60
|
+
exports.operatorMap[operatorSymbols_1.Operator.STRICT_EQUALS],
|
|
61
|
+
exports.operatorMap[operatorSymbols_1.Operator.NOT_EQUALS],
|
|
62
|
+
exports.operatorMap[operatorSymbols_1.Operator.STRICT_NOT_EQUALS],
|
|
63
|
+
]);
|
|
64
|
+
/**
|
|
65
|
+
* Maps prefix unary operator strings to their corresponding TypeScript syntax kind.
|
|
66
|
+
* Operators like `-` and `+` share SyntaxKind tokens with their binary counterparts;
|
|
67
|
+
* disambiguation happens at the AST node level (PrefixUnaryExpression vs BinaryExpression).
|
|
68
|
+
*/
|
|
69
|
+
exports.prefixUnaryOperatorMap = {
|
|
70
|
+
[operatorSymbols_1.Operator.MINUS]: ts_morph_1.SyntaxKind.MinusToken,
|
|
71
|
+
[operatorSymbols_1.Operator.PLUS]: ts_morph_1.SyntaxKind.PlusToken,
|
|
72
|
+
[operatorSymbols_1.Operator.NOT]: ts_morph_1.SyntaxKind.ExclamationToken,
|
|
73
|
+
[operatorSymbols_1.Operator.BITWISE_NOT]: ts_morph_1.SyntaxKind.TildeToken,
|
|
74
|
+
};
|
|
75
|
+
exports.prefixUnaryOperatorSyntaxKinds = Object.values(exports.prefixUnaryOperatorMap);
|
|
76
|
+
const isPrefixUnaryOperatorSyntaxKind = (syntaxKind) => exports.prefixUnaryOperatorSyntaxKinds.includes(syntaxKind);
|
|
77
|
+
exports.isPrefixUnaryOperatorSyntaxKind = isPrefixUnaryOperatorSyntaxKind;
|
|
78
|
+
/**
|
|
79
|
+
* Maps postfix unary operator strings to their corresponding TypeScript syntax kind.
|
|
80
|
+
*/
|
|
81
|
+
exports.postfixUnaryOperatorMap = {
|
|
82
|
+
[operatorSymbols_1.Operator.INCREMENT]: ts_morph_1.SyntaxKind.PlusPlusToken,
|
|
83
|
+
[operatorSymbols_1.Operator.DECREMENT]: ts_morph_1.SyntaxKind.MinusMinusToken,
|
|
84
|
+
};
|
|
85
|
+
exports.postfixUnaryOperatorSyntaxKinds = Object.values(exports.postfixUnaryOperatorMap);
|
|
86
|
+
const isPostfixUnaryOperatorSyntaxKind = (syntaxKind) => exports.postfixUnaryOperatorSyntaxKinds.includes(syntaxKind);
|
|
87
|
+
exports.isPostfixUnaryOperatorSyntaxKind = isPostfixUnaryOperatorSyntaxKind;
|
|
88
|
+
/**
|
|
89
|
+
* Set of operator strings that can appear as prefix unary overloads.
|
|
90
|
+
*/
|
|
91
|
+
exports.prefixUnaryOperatorStrings = new Set(Object.keys(exports.prefixUnaryOperatorMap));
|
|
92
|
+
/**
|
|
93
|
+
* Set of operator strings that can appear as postfix unary overloads.
|
|
94
|
+
*/
|
|
95
|
+
exports.postfixUnaryOperatorStrings = new Set(Object.keys(exports.postfixUnaryOperatorMap));
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateExports = validateExports;
|
|
4
|
+
const ts_morph_1 = require("ts-morph");
|
|
5
|
+
/**
|
|
6
|
+
* Validate that all classes with registered operator overloads are exported
|
|
7
|
+
* and (optionally) reachable from a package entry point.
|
|
8
|
+
*
|
|
9
|
+
* @param project The ts-morph project containing the source files.
|
|
10
|
+
* @param overloadStore Populated OverloadStore for the project.
|
|
11
|
+
* @param projectDir Absolute path to the project root — used to filter out
|
|
12
|
+
* overloads sourced from library dependencies.
|
|
13
|
+
* @param entryPoint Absolute path to the source entry point (e.g. `src/index.ts`).
|
|
14
|
+
* When provided, a second pass checks that every overload
|
|
15
|
+
* class is transitively reachable from this file via its
|
|
16
|
+
* export graph. Omit to run the file-level check only.
|
|
17
|
+
*/
|
|
18
|
+
function validateExports({ project, overloadStore, projectDir, entryPoint, }) {
|
|
19
|
+
var _a;
|
|
20
|
+
const violations = [];
|
|
21
|
+
const normalizedDir = projectDir.replace(/\\/g, "/").replace(/\/$/, "");
|
|
22
|
+
// Deduplicate: collect unique (className, classFilePath) pairs whose
|
|
23
|
+
// source lives inside this project (skip .d.ts from dependencies).
|
|
24
|
+
const seen = new Set();
|
|
25
|
+
const classes = [];
|
|
26
|
+
for (const overload of overloadStore.getAllOverloads()) {
|
|
27
|
+
const normalized = overload.classFilePath.replace(/\\/g, "/");
|
|
28
|
+
const inProject = normalized.startsWith(`${normalizedDir}/`) ||
|
|
29
|
+
normalized === normalizedDir;
|
|
30
|
+
if (!inProject)
|
|
31
|
+
continue;
|
|
32
|
+
if (normalized.endsWith(".d.ts"))
|
|
33
|
+
continue;
|
|
34
|
+
const key = `${overload.className}::${normalized}`;
|
|
35
|
+
if (!seen.has(key)) {
|
|
36
|
+
seen.add(key);
|
|
37
|
+
classes.push({
|
|
38
|
+
className: overload.className,
|
|
39
|
+
classFilePath: overload.classFilePath,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// Level 2 setup: resolve the set of class declarations reachable from the
|
|
44
|
+
// entry point by walking the full export graph (follows re-exports).
|
|
45
|
+
let entryExportedClassDecls;
|
|
46
|
+
if (entryPoint) {
|
|
47
|
+
const entryFile = (_a = project.getSourceFile(entryPoint)) !== null && _a !== void 0 ? _a : project.addSourceFileAtPath(entryPoint);
|
|
48
|
+
entryExportedClassDecls = new Set();
|
|
49
|
+
for (const decls of entryFile.getExportedDeclarations().values()) {
|
|
50
|
+
for (const decl of decls) {
|
|
51
|
+
if (ts_morph_1.Node.isClassDeclaration(decl)) {
|
|
52
|
+
entryExportedClassDecls.add(decl);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Check each class.
|
|
58
|
+
for (const { className, classFilePath } of classes) {
|
|
59
|
+
const sourceFile = project.getSourceFile(classFilePath);
|
|
60
|
+
if (!sourceFile)
|
|
61
|
+
continue;
|
|
62
|
+
const classDecl = sourceFile.getClass(className);
|
|
63
|
+
if (!classDecl)
|
|
64
|
+
continue;
|
|
65
|
+
// Level 1: is the class exported from its own source file?
|
|
66
|
+
if (!classDecl.isExported()) {
|
|
67
|
+
violations.push({
|
|
68
|
+
className,
|
|
69
|
+
classFilePath,
|
|
70
|
+
reason: "not-exported-from-file",
|
|
71
|
+
});
|
|
72
|
+
// If not exported from file it cannot be in the entry point graph
|
|
73
|
+
// either — no need to run the deep check for this class.
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
// Level 2: is the class reachable from the entry point?
|
|
77
|
+
if (entryExportedClassDecls !== undefined &&
|
|
78
|
+
!entryExportedClassDecls.has(classDecl)) {
|
|
79
|
+
violations.push({
|
|
80
|
+
className,
|
|
81
|
+
classFilePath,
|
|
82
|
+
reason: "not-reachable-from-entry",
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return { violations };
|
|
87
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Core transformation pipeline
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.SyntaxKind = exports.Project = exports.Node = exports.operatorSymbols = exports.Operator = exports.validateExports = exports.SourceMap = exports.isPrefixUnaryOperatorSyntaxKind = exports.isPostfixUnaryOperatorSyntaxKind = exports.isOperatorSyntaxKind = exports.OverloadStore = exports.OverloadInjector = exports.unwrapInitializer = exports.resolveExpressionType = exports.getOperatorStringFromProperty = exports.ErrorManager = exports.ErrorDescription = exports.loadConfig = exports.ConsoleLogger = void 0;
|
|
5
|
+
var BopConfig_1 = require("./core/BopConfig");
|
|
6
|
+
Object.defineProperty(exports, "ConsoleLogger", { enumerable: true, get: function () { return BopConfig_1.ConsoleLogger; } });
|
|
7
|
+
Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return BopConfig_1.loadConfig; } });
|
|
8
|
+
var ErrorManager_1 = require("./core/ErrorManager");
|
|
9
|
+
Object.defineProperty(exports, "ErrorDescription", { enumerable: true, get: function () { return ErrorManager_1.ErrorDescription; } });
|
|
10
|
+
Object.defineProperty(exports, "ErrorManager", { enumerable: true, get: function () { return ErrorManager_1.ErrorManager; } });
|
|
11
|
+
var getOperatorStringFromProperty_1 = require("./core/helpers/getOperatorStringFromProperty");
|
|
12
|
+
Object.defineProperty(exports, "getOperatorStringFromProperty", { enumerable: true, get: function () { return getOperatorStringFromProperty_1.getOperatorStringFromProperty; } });
|
|
13
|
+
var resolveExpressionType_1 = require("./core/helpers/resolveExpressionType");
|
|
14
|
+
Object.defineProperty(exports, "resolveExpressionType", { enumerable: true, get: function () { return resolveExpressionType_1.resolveExpressionType; } });
|
|
15
|
+
var unwrapInitializer_1 = require("./core/helpers/unwrapInitializer");
|
|
16
|
+
Object.defineProperty(exports, "unwrapInitializer", { enumerable: true, get: function () { return unwrapInitializer_1.unwrapInitializer; } });
|
|
17
|
+
var OverloadInjector_1 = require("./core/OverloadInjector");
|
|
18
|
+
Object.defineProperty(exports, "OverloadInjector", { enumerable: true, get: function () { return OverloadInjector_1.OverloadInjector; } });
|
|
19
|
+
var OverloadStore_1 = require("./core/OverloadStore");
|
|
20
|
+
Object.defineProperty(exports, "OverloadStore", { enumerable: true, get: function () { return OverloadStore_1.OverloadStore; } });
|
|
21
|
+
var operatorMap_1 = require("./core/operatorMap");
|
|
22
|
+
Object.defineProperty(exports, "isOperatorSyntaxKind", { enumerable: true, get: function () { return operatorMap_1.isOperatorSyntaxKind; } });
|
|
23
|
+
Object.defineProperty(exports, "isPostfixUnaryOperatorSyntaxKind", { enumerable: true, get: function () { return operatorMap_1.isPostfixUnaryOperatorSyntaxKind; } });
|
|
24
|
+
Object.defineProperty(exports, "isPrefixUnaryOperatorSyntaxKind", { enumerable: true, get: function () { return operatorMap_1.isPrefixUnaryOperatorSyntaxKind; } });
|
|
25
|
+
var SourceMap_1 = require("./core/SourceMap");
|
|
26
|
+
Object.defineProperty(exports, "SourceMap", { enumerable: true, get: function () { return SourceMap_1.SourceMap; } });
|
|
27
|
+
var validateExports_1 = require("./core/validateExports");
|
|
28
|
+
Object.defineProperty(exports, "validateExports", { enumerable: true, get: function () { return validateExports_1.validateExports; } });
|
|
29
|
+
// Operator definitions
|
|
30
|
+
var operatorSymbols_1 = require("./lib/operatorSymbols");
|
|
31
|
+
Object.defineProperty(exports, "Operator", { enumerable: true, get: function () { return operatorSymbols_1.Operator; } });
|
|
32
|
+
Object.defineProperty(exports, "operatorSymbols", { enumerable: true, get: function () { return operatorSymbols_1.operatorSymbols; } });
|
|
33
|
+
var ts_morph_1 = require("ts-morph");
|
|
34
|
+
Object.defineProperty(exports, "Node", { enumerable: true, get: function () { return ts_morph_1.Node; } });
|
|
35
|
+
Object.defineProperty(exports, "Project", { enumerable: true, get: function () { return ts_morph_1.Project; } });
|
|
36
|
+
Object.defineProperty(exports, "SyntaxKind", { enumerable: true, get: function () { return ts_morph_1.SyntaxKind; } });
|
|
@@ -0,0 +1,17 @@
|
|
|
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./operatorSymbols"), exports);
|