@boperators/mcp-server 0.2.1 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/dist/index.js +168 -299
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ bun add -D @boperators/mcp-server
|
|
|
22
22
|
|------|-------------|:-------------------:|
|
|
23
23
|
| [`list_overloads`](#list_overloads) | List all registered overloads in the project, with optional filtering by class or operator | ✓ |
|
|
24
24
|
| [`transform_preview`](#transform_preview) | Preview the transformed output for a file or a line range within it | ✓ |
|
|
25
|
-
| [`scaffold_overloads`](#scaffold_overloads) | Generate
|
|
25
|
+
| [`scaffold_overloads`](#scaffold_overloads) | Generate method boilerplate for a set of operators on a named class | — |
|
|
26
26
|
| [`validate_overloads`](#validate_overloads) | Validate overload definitions in a single file and return structured diagnostics | ✓ |
|
|
27
27
|
| [`explain_expression`](#explain_expression) | Reverse-engineer a transformed call expression back to its original operator and overload metadata | optional |
|
|
28
28
|
|
|
@@ -57,11 +57,11 @@ Transforms a file and returns the original and transformed text side by side, al
|
|
|
57
57
|
|
|
58
58
|
### `scaffold_overloads`
|
|
59
59
|
|
|
60
|
-
Generates ready-to-paste TypeScript
|
|
60
|
+
Generates ready-to-paste TypeScript method declarations for a list of operators on a given class. Automatically uses the correct form for each operator:
|
|
61
61
|
|
|
62
|
-
- **Static binary** (`+`, `-`, `*`, …) — `static
|
|
62
|
+
- **Static binary** (`+`, `-`, `*`, …) — `static "+"(a: T, b: T): T { … }`
|
|
63
63
|
- **Comparison** (`>`, `==`, …) — static, returns `boolean`
|
|
64
|
-
- **Instance compound** (`+=`, `-=`, …) — instance, `
|
|
64
|
+
- **Instance compound** (`+=`, `-=`, …) — instance, `"+="(rhs: T): void { … }`
|
|
65
65
|
- **Prefix unary** (`!`, `~`) — static, one parameter
|
|
66
66
|
- **Postfix unary** (`++`, `--`) — instance, no parameters, returns `void`
|
|
67
67
|
|
|
@@ -80,7 +80,7 @@ Does not require a `tsconfig` — it is purely generative.
|
|
|
80
80
|
|
|
81
81
|
Runs the boperators scanning pipeline against a single file in isolation and returns structured diagnostics without modifying any state. Reports:
|
|
82
82
|
|
|
83
|
-
- **Errors** — wrong arity,
|
|
83
|
+
- **Errors** — wrong arity, return type violations
|
|
84
84
|
- **Warnings** — duplicate/conflicting overload registrations
|
|
85
85
|
- The count of successfully parsed overloads
|
|
86
86
|
|
|
@@ -95,7 +95,7 @@ Runs the boperators scanning pipeline against a single file in isolation and ret
|
|
|
95
95
|
|
|
96
96
|
### `explain_expression`
|
|
97
97
|
|
|
98
|
-
Given a transformed boperators expression (e.g. `Vector3["+"]
|
|
98
|
+
Given a transformed boperators expression (e.g. `Vector3["+"](a, b)` or `v["+="](rhs)` or `v["++"]( )`), decodes it back to the original operator, identifies whether it is static/instance and binary/unary, and optionally enriches the result with metadata from the project's overload store.
|
|
99
99
|
|
|
100
100
|
**Inputs**
|
|
101
101
|
|
package/dist/index.js
CHANGED
|
@@ -248869,6 +248869,29 @@ Node text: ${this.#forgottenText}`;
|
|
|
248869
248869
|
exports.setScopeForNode = setScopeForNode;
|
|
248870
248870
|
});
|
|
248871
248871
|
|
|
248872
|
+
// ../package/dist/core/helpers/getOperatorStringFromMethod.js
|
|
248873
|
+
var require_getOperatorStringFromMethod = __commonJS((exports) => {
|
|
248874
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
248875
|
+
exports.getOperatorStringFromMethod = getOperatorStringFromMethod;
|
|
248876
|
+
var ts_morph_1 = require_ts_morph();
|
|
248877
|
+
function getOperatorStringFromMethod(method) {
|
|
248878
|
+
const nameNode = method.getNameNode();
|
|
248879
|
+
if (nameNode.isKind(ts_morph_1.SyntaxKind.ComputedPropertyName)) {
|
|
248880
|
+
const expression = nameNode.getExpression();
|
|
248881
|
+
if (expression.isKind(ts_morph_1.SyntaxKind.StringLiteral)) {
|
|
248882
|
+
return expression.getLiteralValue();
|
|
248883
|
+
}
|
|
248884
|
+
const literalValue = expression.getType().getLiteralValue();
|
|
248885
|
+
if (typeof literalValue === "string") {
|
|
248886
|
+
return literalValue;
|
|
248887
|
+
}
|
|
248888
|
+
} else if (nameNode.isKind(ts_morph_1.SyntaxKind.StringLiteral)) {
|
|
248889
|
+
return nameNode.getLiteralValue();
|
|
248890
|
+
}
|
|
248891
|
+
return;
|
|
248892
|
+
}
|
|
248893
|
+
});
|
|
248894
|
+
|
|
248872
248895
|
// ../package/dist/core/helpers/getOperatorStringFromProperty.js
|
|
248873
248896
|
var require_getOperatorStringFromProperty = __commonJS((exports) => {
|
|
248874
248897
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -248899,7 +248922,9 @@ var require_resolveExpressionType = __commonJS((exports) => {
|
|
|
248899
248922
|
exports.resolveExpressionType = resolveExpressionType;
|
|
248900
248923
|
var ts_morph_1 = require_ts_morph();
|
|
248901
248924
|
function normalizeTypeName(typeName) {
|
|
248902
|
-
|
|
248925
|
+
const withoutImport = typeName.replace(/import\("[^"]*"\)\./g, "");
|
|
248926
|
+
const genericIdx = withoutImport.indexOf("<");
|
|
248927
|
+
return genericIdx === -1 ? withoutImport : withoutImport.slice(0, genericIdx);
|
|
248903
248928
|
}
|
|
248904
248929
|
function resolveExpressionType(node) {
|
|
248905
248930
|
var _a;
|
|
@@ -249298,7 +249323,7 @@ var require_OverloadInjector = __commonJS((exports) => {
|
|
|
249298
249323
|
const overloadDesc = this._overloadStore.findOverload(operatorKind, leftType, rightType);
|
|
249299
249324
|
if (!overloadDesc)
|
|
249300
249325
|
continue;
|
|
249301
|
-
const { className: classNameRaw, classFilePath, operatorString,
|
|
249326
|
+
const { className: classNameRaw, classFilePath, operatorString, isStatic } = overloadDesc;
|
|
249302
249327
|
const classSourceFile = this._project.getSourceFileOrThrow(classFilePath);
|
|
249303
249328
|
const classDecl = classSourceFile.getClassOrThrow(classNameRaw);
|
|
249304
249329
|
const classSymbol = classDecl.getSymbol();
|
|
@@ -249306,7 +249331,7 @@ var require_OverloadInjector = __commonJS((exports) => {
|
|
|
249306
249331
|
throw new Error(`No symbol for class "${classNameRaw}"`);
|
|
249307
249332
|
const classModuleSpecifier = (0, getModuleSpecifier_1.getModuleSpecifier)(sourceFile, classSourceFile);
|
|
249308
249333
|
const className = (0, ensureImportedName_1.ensureImportedName)(sourceFile, classSymbol, classModuleSpecifier);
|
|
249309
|
-
const overloadCall = isStatic ? `${className}["${operatorString}"]
|
|
249334
|
+
const overloadCall = isStatic ? `${className}["${operatorString}"](${lhs.getText()}, ${rhs.getText()})` : `${lhs.getText()}["${operatorString}"](${rhs.getText()})`;
|
|
249310
249335
|
this._logger.debug(`${fileName}: ${expression.getText()} => ${overloadCall}`);
|
|
249311
249336
|
expression.replaceWithText(overloadCall);
|
|
249312
249337
|
transformCount++;
|
|
@@ -249328,7 +249353,7 @@ var require_OverloadInjector = __commonJS((exports) => {
|
|
|
249328
249353
|
const overloadDesc = this._overloadStore.findPrefixUnaryOverload(operatorKind, operandType);
|
|
249329
249354
|
if (!overloadDesc)
|
|
249330
249355
|
continue;
|
|
249331
|
-
const { className: classNameRaw, classFilePath, operatorString
|
|
249356
|
+
const { className: classNameRaw, classFilePath, operatorString } = overloadDesc;
|
|
249332
249357
|
const classSourceFile = this._project.getSourceFileOrThrow(classFilePath);
|
|
249333
249358
|
const classDecl = classSourceFile.getClassOrThrow(classNameRaw);
|
|
249334
249359
|
const classSymbol = classDecl.getSymbol();
|
|
@@ -249336,7 +249361,7 @@ var require_OverloadInjector = __commonJS((exports) => {
|
|
|
249336
249361
|
throw new Error(`No symbol for class "${classNameRaw}"`);
|
|
249337
249362
|
const classModuleSpecifier = (0, getModuleSpecifier_1.getModuleSpecifier)(sourceFile, classSourceFile);
|
|
249338
249363
|
const className = (0, ensureImportedName_1.ensureImportedName)(sourceFile, classSymbol, classModuleSpecifier);
|
|
249339
|
-
const overloadCall = `${className}["${operatorString}"]
|
|
249364
|
+
const overloadCall = `${className}["${operatorString}"](${operand.getText()})`;
|
|
249340
249365
|
this._logger.debug(`${fileName}: ${expression.getText()} => ${overloadCall}`);
|
|
249341
249366
|
expression.replaceWithText(overloadCall);
|
|
249342
249367
|
transformCount++;
|
|
@@ -249358,8 +249383,8 @@ var require_OverloadInjector = __commonJS((exports) => {
|
|
|
249358
249383
|
const overloadDesc = this._overloadStore.findPostfixUnaryOverload(operatorKind, operandType);
|
|
249359
249384
|
if (!overloadDesc)
|
|
249360
249385
|
continue;
|
|
249361
|
-
const { operatorString
|
|
249362
|
-
const overloadCall = `${operand.getText()}["${operatorString}"]
|
|
249386
|
+
const { operatorString } = overloadDesc;
|
|
249387
|
+
const overloadCall = `${operand.getText()}["${operatorString}"]()`;
|
|
249363
249388
|
this._logger.debug(`${fileName}: ${expression.getText()} => ${overloadCall}`);
|
|
249364
249389
|
expression.replaceWithText(overloadCall);
|
|
249365
249390
|
transformCount++;
|
|
@@ -249387,9 +249412,8 @@ var require_OverloadStore = __commonJS((exports) => {
|
|
|
249387
249412
|
var ts_morph_1 = require_ts_morph();
|
|
249388
249413
|
var operatorSymbols_1 = require_operatorSymbols();
|
|
249389
249414
|
var ErrorManager_1 = require_ErrorManager();
|
|
249390
|
-
var
|
|
249415
|
+
var getOperatorStringFromMethod_1 = require_getOperatorStringFromMethod();
|
|
249391
249416
|
var resolveExpressionType_1 = require_resolveExpressionType();
|
|
249392
|
-
var unwrapInitializer_1 = require_unwrapInitializer();
|
|
249393
249417
|
var operatorMap_1 = require_operatorMap();
|
|
249394
249418
|
|
|
249395
249419
|
class OverloadStore extends Map {
|
|
@@ -249509,15 +249533,29 @@ var require_OverloadStore = __commonJS((exports) => {
|
|
|
249509
249533
|
this._parsedFiles.add(filePath);
|
|
249510
249534
|
const classes = sourceFile.getClasses();
|
|
249511
249535
|
classes.forEach((classDecl) => {
|
|
249536
|
+
const className = classDecl.getName();
|
|
249537
|
+
if (!className)
|
|
249538
|
+
return;
|
|
249512
249539
|
const classType = (0, resolveExpressionType_1.normalizeTypeName)(classDecl.getType().getText());
|
|
249513
|
-
|
|
249514
|
-
|
|
249515
|
-
|
|
249516
|
-
return;
|
|
249517
|
-
const isStatic = property.isStatic();
|
|
249518
|
-
const operatorString = (0, getOperatorStringFromProperty_1.getOperatorStringFromProperty)(property);
|
|
249540
|
+
const methodGroups = new Map;
|
|
249541
|
+
for (const method of classDecl.getMethods()) {
|
|
249542
|
+
const operatorString = (0, getOperatorStringFromMethod_1.getOperatorStringFromMethod)(method);
|
|
249519
249543
|
if (!operatorString || !operatorSymbols_1.operatorSymbols.includes(operatorString))
|
|
249544
|
+
continue;
|
|
249545
|
+
let group = methodGroups.get(operatorString);
|
|
249546
|
+
if (!group) {
|
|
249547
|
+
group = [];
|
|
249548
|
+
methodGroups.set(operatorString, group);
|
|
249549
|
+
}
|
|
249550
|
+
const overloadSigs = method.getOverloads();
|
|
249551
|
+
group.push(...overloadSigs.length > 0 ? overloadSigs : [method]);
|
|
249552
|
+
}
|
|
249553
|
+
methodGroups.forEach((methods, operatorString) => {
|
|
249554
|
+
const overloadSigs = methods.filter((m) => !m.hasBody());
|
|
249555
|
+
const sigsToProcess = overloadSigs.length > 0 ? overloadSigs : methods;
|
|
249556
|
+
if (sigsToProcess.length === 0)
|
|
249520
249557
|
return;
|
|
249558
|
+
const isStatic = sigsToProcess[0].isStatic();
|
|
249521
249559
|
const binarySyntaxKind = operatorMap_1.operatorMap[operatorString];
|
|
249522
249560
|
const prefixUnarySyntaxKind = operatorMap_1.prefixUnaryOperatorMap[operatorString];
|
|
249523
249561
|
const postfixUnarySyntaxKind = operatorMap_1.postfixUnaryOperatorMap[operatorString];
|
|
@@ -249526,93 +249564,74 @@ var require_OverloadStore = __commonJS((exports) => {
|
|
|
249526
249564
|
const shouldBeStatic = binarySyntaxKind != null && !operatorMap_1.instanceOperators.has(binarySyntaxKind) || prefixUnarySyntaxKind != null;
|
|
249527
249565
|
const shouldBeInstance = binarySyntaxKind != null && operatorMap_1.instanceOperators.has(binarySyntaxKind) || postfixUnarySyntaxKind != null;
|
|
249528
249566
|
if (isStatic && !shouldBeStatic || !isStatic && !shouldBeInstance) {
|
|
249529
|
-
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Expected overload for operator ${operatorString} ` + `to be ${isStatic ? "a static" : "an instance"}
|
|
249530
|
-
`)[0]));
|
|
249531
|
-
return;
|
|
249532
|
-
}
|
|
249533
|
-
const rawInitializer = property.getInitializer();
|
|
249534
|
-
if (!rawInitializer) {
|
|
249535
|
-
this._addOverloadsFromTypeAnnotation(property, classDecl, classType, filePath, isStatic, operatorString, binarySyntaxKind, prefixUnarySyntaxKind, postfixUnarySyntaxKind);
|
|
249567
|
+
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Expected overload for operator "${operatorString}" ` + `to be ${isStatic ? "a static" : "an instance"} method.`, sigsToProcess[0].getSourceFile().getFilePath(), sigsToProcess[0].getStartLineNumber(), this._minifyString(sigsToProcess[0].getText().split(`
|
|
249568
|
+
`)[0])));
|
|
249536
249569
|
return;
|
|
249537
249570
|
}
|
|
249538
|
-
|
|
249539
|
-
|
|
249540
|
-
if (!initializer3 || !ts_morph_1.Node.isArrayLiteralExpression(initializer3)) {
|
|
249541
|
-
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Overload field for operator ${operatorString} ` + "must be an array of overload functions.", property.getSourceFile().getFilePath(), property.getStartLineNumber(), this._minifyString(property.getName())));
|
|
249542
|
-
return;
|
|
249543
|
-
}
|
|
249544
|
-
if (!hasAsConst) {
|
|
249545
|
-
this._errorManager.addError(new ErrorManager_1.ErrorDescription(`Overload array for operator ${operatorString} must use "as const". ` + "Without it, TypeScript widens the array type and loses individual " + "function signatures, causing type errors in generated code.", property.getSourceFile().getFilePath(), property.getStartLineNumber(), this._minifyString((_b = property.getText().split(`
|
|
249546
|
-
`)[0]) !== null && _b !== undefined ? _b : "")));
|
|
249547
|
-
return;
|
|
249548
|
-
}
|
|
249549
|
-
initializer3.getElements().forEach((element, index) => {
|
|
249550
|
-
if (element.isKind(ts_morph_1.SyntaxKind.ArrowFunction) && !isStatic) {
|
|
249551
|
-
this._errorManager.addError(new ErrorManager_1.ErrorDescription(`Overload ${index} for operator ${operatorString} must not be an arrow function. ` + "Use a function expression instead, as arrow functions cannot bind `this` correctly for instance operators.", element.getSourceFile().getFilePath(), element.getStartLineNumber(), this._minifyString(element.getText())));
|
|
249552
|
-
return;
|
|
249553
|
-
}
|
|
249554
|
-
if (!element.isKind(ts_morph_1.SyntaxKind.FunctionExpression) && !element.isKind(ts_morph_1.SyntaxKind.FunctionDeclaration) && !element.isKind(ts_morph_1.SyntaxKind.ArrowFunction)) {
|
|
249555
|
-
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Expected overload ${index} for operator ${operatorString} to be a function.`, element.getSourceFile().getFilePath(), element.getStartLineNumber(), this._minifyString(element.getText())));
|
|
249556
|
-
return;
|
|
249557
|
-
}
|
|
249558
|
-
const funcElement = element;
|
|
249559
|
-
const parameters = funcElement.getParameters().filter((p) => p.getName() !== "this");
|
|
249571
|
+
sigsToProcess.forEach((method) => {
|
|
249572
|
+
const parameters = method.getParameters().filter((p) => p.getName() !== "this");
|
|
249560
249573
|
const paramCount = parameters.length;
|
|
249561
249574
|
if (paramCount === 2 && isStatic && binarySyntaxKind && !operatorMap_1.instanceOperators.has(binarySyntaxKind)) {
|
|
249562
|
-
this._addBinaryOverload(binarySyntaxKind,
|
|
249575
|
+
this._addBinaryOverload(binarySyntaxKind, className, classType, filePath, method, parameters, operatorString, true);
|
|
249563
249576
|
} else if (paramCount === 1 && !isStatic && binarySyntaxKind && operatorMap_1.instanceOperators.has(binarySyntaxKind)) {
|
|
249564
|
-
this._addBinaryOverload(binarySyntaxKind,
|
|
249577
|
+
this._addBinaryOverload(binarySyntaxKind, className, classType, filePath, method, parameters, operatorString, false);
|
|
249565
249578
|
} else if (paramCount === 1 && isStatic && prefixUnarySyntaxKind) {
|
|
249566
|
-
this._addPrefixUnaryOverload(prefixUnarySyntaxKind,
|
|
249579
|
+
this._addPrefixUnaryOverload(prefixUnarySyntaxKind, className, classType, filePath, method, parameters, operatorString);
|
|
249567
249580
|
} else if (paramCount === 0 && !isStatic && postfixUnarySyntaxKind) {
|
|
249568
|
-
this._addPostfixUnaryOverload(postfixUnarySyntaxKind,
|
|
249581
|
+
this._addPostfixUnaryOverload(postfixUnarySyntaxKind, className, classType, filePath, method, operatorString);
|
|
249569
249582
|
} else {
|
|
249570
|
-
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Overload
|
|
249583
|
+
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Overload signature for operator "${operatorString}" ` + `has invalid parameter count (${paramCount}) for this operator context.`, method.getSourceFile().getFilePath(), method.getStartLineNumber(), this._minifyString(method.getText().split(`
|
|
249584
|
+
`)[0])));
|
|
249571
249585
|
}
|
|
249572
249586
|
});
|
|
249573
249587
|
});
|
|
249574
249588
|
});
|
|
249575
249589
|
}
|
|
249576
|
-
_addBinaryOverload(syntaxKind,
|
|
249577
|
-
var _a, _b
|
|
249590
|
+
_addBinaryOverload(syntaxKind, className, classType, filePath, method, parameters, operatorString, isStatic) {
|
|
249591
|
+
var _a, _b;
|
|
249578
249592
|
let hasWarning = false;
|
|
249579
|
-
const
|
|
249580
|
-
|
|
249593
|
+
const getParamTypeName = (p) => {
|
|
249594
|
+
var _a2, _b2, _c;
|
|
249595
|
+
return (0, resolveExpressionType_1.normalizeTypeName)((_c = (_b2 = (_a2 = p === null || p === undefined ? undefined : p.getTypeNode()) === null || _a2 === undefined ? undefined : _a2.getText()) !== null && _b2 !== undefined ? _b2 : p === null || p === undefined ? undefined : p.getType().getText()) !== null && _c !== undefined ? _c : "");
|
|
249596
|
+
};
|
|
249597
|
+
const lhsType = isStatic ? getParamTypeName(parameters[0]) : classType;
|
|
249598
|
+
const rhsType = isStatic ? getParamTypeName(parameters[1]) : getParamTypeName(parameters[0]);
|
|
249581
249599
|
if (isStatic && lhsType !== classType && rhsType !== classType) {
|
|
249582
|
-
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Overload for operator ${operatorString} ` + "must have either LHS or RHS parameter matching its class type.",
|
|
249600
|
+
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Overload for operator "${operatorString}" ` + "must have either LHS or RHS parameter matching its class type.", method.getSourceFile().getFilePath(), method.getStartLineNumber(), this._minifyString(method.getText().split(`
|
|
249601
|
+
`)[0])));
|
|
249583
249602
|
hasWarning = true;
|
|
249584
249603
|
}
|
|
249585
|
-
const returnType =
|
|
249604
|
+
const returnType = method.getReturnType().getText();
|
|
249586
249605
|
if (operatorMap_1.comparisonOperators.has(syntaxKind) && returnType !== "boolean") {
|
|
249587
|
-
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Overload
|
|
249606
|
+
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Overload for comparison operator "${operatorString}" ` + `must have a return type of 'boolean', got '${returnType}'.`, method.getSourceFile().getFilePath(), method.getStartLineNumber(), this._minifyString(method.getText().split(`
|
|
249607
|
+
`)[0])));
|
|
249588
249608
|
hasWarning = true;
|
|
249589
249609
|
}
|
|
249590
249610
|
if (!isStatic && returnType !== "void") {
|
|
249591
|
-
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Overload
|
|
249611
|
+
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Overload for instance operator "${operatorString}" ` + `must have a return type of 'void', got '${returnType}'.`, method.getSourceFile().getFilePath(), method.getStartLineNumber(), this._minifyString(method.getText().split(`
|
|
249612
|
+
`)[0])));
|
|
249592
249613
|
hasWarning = true;
|
|
249593
249614
|
}
|
|
249594
|
-
const operatorOverloads = (
|
|
249595
|
-
const lhsMap = (
|
|
249615
|
+
const operatorOverloads = (_a = this.get(syntaxKind)) !== null && _a !== undefined ? _a : new Map;
|
|
249616
|
+
const lhsMap = (_b = operatorOverloads.get(lhsType)) !== null && _b !== undefined ? _b : new Map;
|
|
249596
249617
|
if (lhsMap.has(rhsType)) {
|
|
249597
|
-
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Duplicate overload for operator ${operatorString} with LHS type ${lhsType} and RHS type ${rhsType}`,
|
|
249618
|
+
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Duplicate overload for operator "${operatorString}" with LHS type ${lhsType} and RHS type ${rhsType}`, method.getSourceFile().getFilePath(), method.getStartLineNumber(), this._minifyString(method.getText().split(`
|
|
249619
|
+
`)[0])));
|
|
249598
249620
|
hasWarning = true;
|
|
249599
249621
|
}
|
|
249600
249622
|
if (hasWarning)
|
|
249601
249623
|
return;
|
|
249602
249624
|
lhsMap.set(rhsType, {
|
|
249603
249625
|
isStatic,
|
|
249604
|
-
className
|
|
249626
|
+
className,
|
|
249605
249627
|
classFilePath: filePath,
|
|
249606
249628
|
operatorString,
|
|
249607
|
-
index,
|
|
249608
249629
|
returnType
|
|
249609
249630
|
});
|
|
249610
249631
|
operatorOverloads.set(lhsType, lhsMap);
|
|
249611
249632
|
this.set(syntaxKind, operatorOverloads);
|
|
249612
|
-
const funcName = ts_morph_1.Node.isFunctionExpression(element) ? element.getName() : undefined;
|
|
249613
249633
|
const sl = this._shortTypeName.bind(this);
|
|
249614
|
-
|
|
249615
|
-
this._logger.debug(`Loaded ${classDecl.getName()}["${operatorString}"][${index}]: ${label} => ${sl(element.getReturnType().getText())}${isStatic ? " (static)" : " (instance)"}`);
|
|
249634
|
+
this._logger.debug(`Loaded ${className}["${operatorString}"]: (${sl(lhsType)}, ${sl(rhsType)}) => ${sl(returnType)}${isStatic ? " (static)" : " (instance)"}`);
|
|
249616
249635
|
let fileEntries = this._fileEntries.get(filePath);
|
|
249617
249636
|
if (!fileEntries) {
|
|
249618
249637
|
fileEntries = [];
|
|
@@ -249620,35 +249639,34 @@ var require_OverloadStore = __commonJS((exports) => {
|
|
|
249620
249639
|
}
|
|
249621
249640
|
fileEntries.push({ syntaxKind, lhsType, rhsType });
|
|
249622
249641
|
}
|
|
249623
|
-
_addPrefixUnaryOverload(syntaxKind,
|
|
249624
|
-
var _a, _b, _c;
|
|
249642
|
+
_addPrefixUnaryOverload(syntaxKind, className, classType, filePath, method, parameters, operatorString) {
|
|
249643
|
+
var _a, _b, _c, _d, _e, _f;
|
|
249625
249644
|
let hasWarning = false;
|
|
249626
|
-
const operandType = (0, resolveExpressionType_1.normalizeTypeName)((_b = (_a = parameters[0]) === null || _a === undefined ? undefined : _a.getType().getText()) !== null &&
|
|
249645
|
+
const operandType = (0, resolveExpressionType_1.normalizeTypeName)((_e = (_c = (_b = (_a = parameters[0]) === null || _a === undefined ? undefined : _a.getTypeNode()) === null || _b === undefined ? undefined : _b.getText()) !== null && _c !== undefined ? _c : (_d = parameters[0]) === null || _d === undefined ? undefined : _d.getType().getText()) !== null && _e !== undefined ? _e : "");
|
|
249627
249646
|
if (operandType !== classType) {
|
|
249628
|
-
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Prefix unary overload for operator ${operatorString} ` + "must have its parameter matching its class type.",
|
|
249647
|
+
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Prefix unary overload for operator "${operatorString}" ` + "must have its parameter matching its class type.", method.getSourceFile().getFilePath(), method.getStartLineNumber(), this._minifyString(method.getText().split(`
|
|
249648
|
+
`)[0])));
|
|
249629
249649
|
hasWarning = true;
|
|
249630
249650
|
}
|
|
249631
|
-
const operatorOverloads = (
|
|
249651
|
+
const operatorOverloads = (_f = this._prefixUnaryOverloads.get(syntaxKind)) !== null && _f !== undefined ? _f : new Map;
|
|
249632
249652
|
if (operatorOverloads.has(operandType)) {
|
|
249633
|
-
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Duplicate prefix unary overload for operator ${operatorString} with operand type ${operandType}`,
|
|
249653
|
+
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Duplicate prefix unary overload for operator "${operatorString}" with operand type ${operandType}`, method.getSourceFile().getFilePath(), method.getStartLineNumber(), this._minifyString(method.getText().split(`
|
|
249654
|
+
`)[0])));
|
|
249634
249655
|
hasWarning = true;
|
|
249635
249656
|
}
|
|
249636
249657
|
if (hasWarning)
|
|
249637
249658
|
return;
|
|
249638
|
-
const returnType =
|
|
249659
|
+
const returnType = method.getReturnType().getText();
|
|
249639
249660
|
operatorOverloads.set(operandType, {
|
|
249640
249661
|
isStatic: true,
|
|
249641
|
-
className
|
|
249662
|
+
className,
|
|
249642
249663
|
classFilePath: filePath,
|
|
249643
249664
|
operatorString,
|
|
249644
|
-
index,
|
|
249645
249665
|
returnType
|
|
249646
249666
|
});
|
|
249647
249667
|
this._prefixUnaryOverloads.set(syntaxKind, operatorOverloads);
|
|
249648
|
-
const funcName = ts_morph_1.Node.isFunctionExpression(element) ? element.getName() : undefined;
|
|
249649
249668
|
const sl = this._shortTypeName.bind(this);
|
|
249650
|
-
|
|
249651
|
-
this._logger.debug(`Loaded ${classDecl.getName()}["${operatorString}"][${index}]: ${operatorString}${label} => ${sl(returnType)} (prefix unary)`);
|
|
249669
|
+
this._logger.debug(`Loaded ${className}["${operatorString}"]: ${operatorString}(${sl(operandType)}) => ${sl(returnType)} (prefix unary)`);
|
|
249652
249670
|
let fileEntries = this._prefixUnaryFileEntries.get(filePath);
|
|
249653
249671
|
if (!fileEntries) {
|
|
249654
249672
|
fileEntries = [];
|
|
@@ -249656,34 +249674,33 @@ var require_OverloadStore = __commonJS((exports) => {
|
|
|
249656
249674
|
}
|
|
249657
249675
|
fileEntries.push({ syntaxKind, operandType });
|
|
249658
249676
|
}
|
|
249659
|
-
_addPostfixUnaryOverload(syntaxKind,
|
|
249677
|
+
_addPostfixUnaryOverload(syntaxKind, className, classType, filePath, method, operatorString) {
|
|
249660
249678
|
var _a;
|
|
249661
249679
|
let hasWarning = false;
|
|
249662
|
-
const returnType =
|
|
249680
|
+
const returnType = method.getReturnType().getText();
|
|
249663
249681
|
if (returnType !== "void") {
|
|
249664
|
-
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Overload
|
|
249682
|
+
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Overload for postfix operator "${operatorString}" ` + `must have a return type of 'void', got '${returnType}'.`, method.getSourceFile().getFilePath(), method.getStartLineNumber(), this._minifyString(method.getText().split(`
|
|
249683
|
+
`)[0])));
|
|
249665
249684
|
hasWarning = true;
|
|
249666
249685
|
}
|
|
249667
249686
|
const operandType = classType;
|
|
249668
249687
|
const operatorOverloads = (_a = this._postfixUnaryOverloads.get(syntaxKind)) !== null && _a !== undefined ? _a : new Map;
|
|
249669
249688
|
if (operatorOverloads.has(operandType)) {
|
|
249670
|
-
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Duplicate postfix unary overload for operator ${operatorString} with operand type ${operandType}`,
|
|
249689
|
+
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Duplicate postfix unary overload for operator "${operatorString}" with operand type ${operandType}`, method.getSourceFile().getFilePath(), method.getStartLineNumber(), this._minifyString(method.getText().split(`
|
|
249690
|
+
`)[0])));
|
|
249671
249691
|
hasWarning = true;
|
|
249672
249692
|
}
|
|
249673
249693
|
if (hasWarning)
|
|
249674
249694
|
return;
|
|
249675
249695
|
operatorOverloads.set(operandType, {
|
|
249676
249696
|
isStatic: false,
|
|
249677
|
-
className
|
|
249697
|
+
className,
|
|
249678
249698
|
classFilePath: filePath,
|
|
249679
249699
|
operatorString,
|
|
249680
|
-
index,
|
|
249681
249700
|
returnType
|
|
249682
249701
|
});
|
|
249683
249702
|
this._postfixUnaryOverloads.set(syntaxKind, operatorOverloads);
|
|
249684
|
-
|
|
249685
|
-
const label = funcName ? `${funcName}()` : "()";
|
|
249686
|
-
this._logger.debug(`Loaded ${classDecl.getName()}["${operatorString}"][${index}]: ${this._shortTypeName(operandType)}${operatorString} ${label} (postfix unary)`);
|
|
249703
|
+
this._logger.debug(`Loaded ${className}["${operatorString}"]: ${this._shortTypeName(operandType)}${operatorString} () (postfix unary)`);
|
|
249687
249704
|
let fileEntries = this._postfixUnaryFileEntries.get(filePath);
|
|
249688
249705
|
if (!fileEntries) {
|
|
249689
249706
|
fileEntries = [];
|
|
@@ -249691,155 +249708,6 @@ var require_OverloadStore = __commonJS((exports) => {
|
|
|
249691
249708
|
}
|
|
249692
249709
|
fileEntries.push({ syntaxKind, operandType });
|
|
249693
249710
|
}
|
|
249694
|
-
_addOverloadsFromTypeAnnotation(property, classDecl, classType, filePath, isStatic, operatorString, binarySyntaxKind, prefixUnarySyntaxKind, postfixUnarySyntaxKind) {
|
|
249695
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
249696
|
-
const propertyType = property.getType();
|
|
249697
|
-
if (!propertyType.isTuple())
|
|
249698
|
-
return;
|
|
249699
|
-
const tupleElements = propertyType.getTupleElements();
|
|
249700
|
-
const className = classDecl.getName();
|
|
249701
|
-
if (!className)
|
|
249702
|
-
return;
|
|
249703
|
-
const sl = this._shortTypeName.bind(this);
|
|
249704
|
-
for (let index = 0;index < tupleElements.length; index++) {
|
|
249705
|
-
const elementType = tupleElements[index];
|
|
249706
|
-
const callSigs = elementType.getCallSignatures();
|
|
249707
|
-
if (callSigs.length === 0)
|
|
249708
|
-
continue;
|
|
249709
|
-
const sig = callSigs[0];
|
|
249710
|
-
const params = [];
|
|
249711
|
-
for (const sym of sig.getParameters()) {
|
|
249712
|
-
const name = sym.getName();
|
|
249713
|
-
if (name === "this")
|
|
249714
|
-
continue;
|
|
249715
|
-
const decl = sym.getValueDeclaration();
|
|
249716
|
-
if (!decl)
|
|
249717
|
-
continue;
|
|
249718
|
-
params.push({
|
|
249719
|
-
name,
|
|
249720
|
-
type: (0, resolveExpressionType_1.normalizeTypeName)(decl.getType().getText())
|
|
249721
|
-
});
|
|
249722
|
-
}
|
|
249723
|
-
const paramCount = params.length;
|
|
249724
|
-
const returnType = sig.getReturnType().getText();
|
|
249725
|
-
if (paramCount === 2 && isStatic && binarySyntaxKind && !operatorMap_1.instanceOperators.has(binarySyntaxKind)) {
|
|
249726
|
-
const lhsType = params[0].type;
|
|
249727
|
-
const rhsType = params[1].type;
|
|
249728
|
-
if (lhsType !== classType && rhsType !== classType) {
|
|
249729
|
-
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Overload for operator ${operatorString} ` + "must have either LHS or RHS parameter matching its class type.", filePath, property.getStartLineNumber(), this._minifyString((_a = property.getText().split(`
|
|
249730
|
-
`)[0]) !== null && _a !== undefined ? _a : "")));
|
|
249731
|
-
continue;
|
|
249732
|
-
}
|
|
249733
|
-
if (operatorMap_1.comparisonOperators.has(binarySyntaxKind) && returnType !== "boolean") {
|
|
249734
|
-
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Overload function ${index} for comparison operator ${operatorString} ` + `must have a return type of 'boolean', got '${returnType}'.`, filePath, property.getStartLineNumber(), this._minifyString((_b = property.getText().split(`
|
|
249735
|
-
`)[0]) !== null && _b !== undefined ? _b : "")));
|
|
249736
|
-
continue;
|
|
249737
|
-
}
|
|
249738
|
-
const operatorOverloads = (_c = this.get(binarySyntaxKind)) !== null && _c !== undefined ? _c : new Map;
|
|
249739
|
-
const lhsMap = (_d = operatorOverloads.get(lhsType)) !== null && _d !== undefined ? _d : new Map;
|
|
249740
|
-
if (lhsMap.has(rhsType))
|
|
249741
|
-
continue;
|
|
249742
|
-
lhsMap.set(rhsType, {
|
|
249743
|
-
isStatic: true,
|
|
249744
|
-
className,
|
|
249745
|
-
classFilePath: filePath,
|
|
249746
|
-
operatorString,
|
|
249747
|
-
index,
|
|
249748
|
-
returnType
|
|
249749
|
-
});
|
|
249750
|
-
operatorOverloads.set(lhsType, lhsMap);
|
|
249751
|
-
this.set(binarySyntaxKind, operatorOverloads);
|
|
249752
|
-
this._logger.debug(`Loaded ${className}["${operatorString}"][${index}]: (${sl(lhsType)}, ${sl(rhsType)}) => ${sl(returnType)} (static, from .d.ts)`);
|
|
249753
|
-
let fileEntries = this._fileEntries.get(filePath);
|
|
249754
|
-
if (!fileEntries) {
|
|
249755
|
-
fileEntries = [];
|
|
249756
|
-
this._fileEntries.set(filePath, fileEntries);
|
|
249757
|
-
}
|
|
249758
|
-
fileEntries.push({ syntaxKind: binarySyntaxKind, lhsType, rhsType });
|
|
249759
|
-
} else if (paramCount === 1 && !isStatic && binarySyntaxKind && operatorMap_1.instanceOperators.has(binarySyntaxKind)) {
|
|
249760
|
-
const lhsType = classType;
|
|
249761
|
-
const rhsType = params[0].type;
|
|
249762
|
-
if (returnType !== "void") {
|
|
249763
|
-
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Overload function ${index} for instance operator ${operatorString} ` + `must have a return type of 'void', got '${returnType}'.`, filePath, property.getStartLineNumber(), this._minifyString((_e = property.getText().split(`
|
|
249764
|
-
`)[0]) !== null && _e !== undefined ? _e : "")));
|
|
249765
|
-
continue;
|
|
249766
|
-
}
|
|
249767
|
-
const operatorOverloads = (_f = this.get(binarySyntaxKind)) !== null && _f !== undefined ? _f : new Map;
|
|
249768
|
-
const lhsMap = (_g = operatorOverloads.get(lhsType)) !== null && _g !== undefined ? _g : new Map;
|
|
249769
|
-
if (lhsMap.has(rhsType))
|
|
249770
|
-
continue;
|
|
249771
|
-
lhsMap.set(rhsType, {
|
|
249772
|
-
isStatic: false,
|
|
249773
|
-
className,
|
|
249774
|
-
classFilePath: filePath,
|
|
249775
|
-
operatorString,
|
|
249776
|
-
index,
|
|
249777
|
-
returnType
|
|
249778
|
-
});
|
|
249779
|
-
operatorOverloads.set(lhsType, lhsMap);
|
|
249780
|
-
this.set(binarySyntaxKind, operatorOverloads);
|
|
249781
|
-
this._logger.debug(`Loaded ${className}["${operatorString}"][${index}]: (${sl(lhsType)}, ${sl(rhsType)}) => void (instance, from .d.ts)`);
|
|
249782
|
-
let fileEntries = this._fileEntries.get(filePath);
|
|
249783
|
-
if (!fileEntries) {
|
|
249784
|
-
fileEntries = [];
|
|
249785
|
-
this._fileEntries.set(filePath, fileEntries);
|
|
249786
|
-
}
|
|
249787
|
-
fileEntries.push({ syntaxKind: binarySyntaxKind, lhsType, rhsType });
|
|
249788
|
-
} else if (paramCount === 1 && isStatic && prefixUnarySyntaxKind) {
|
|
249789
|
-
const operandType = params[0].type;
|
|
249790
|
-
if (operandType !== classType) {
|
|
249791
|
-
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Prefix unary overload for operator ${operatorString} ` + "must have its parameter matching its class type.", filePath, property.getStartLineNumber(), this._minifyString((_h = property.getText().split(`
|
|
249792
|
-
`)[0]) !== null && _h !== undefined ? _h : "")));
|
|
249793
|
-
continue;
|
|
249794
|
-
}
|
|
249795
|
-
const operatorOverloads = (_j = this._prefixUnaryOverloads.get(prefixUnarySyntaxKind)) !== null && _j !== undefined ? _j : new Map;
|
|
249796
|
-
if (operatorOverloads.has(operandType))
|
|
249797
|
-
continue;
|
|
249798
|
-
operatorOverloads.set(operandType, {
|
|
249799
|
-
isStatic: true,
|
|
249800
|
-
className,
|
|
249801
|
-
classFilePath: filePath,
|
|
249802
|
-
operatorString,
|
|
249803
|
-
index,
|
|
249804
|
-
returnType
|
|
249805
|
-
});
|
|
249806
|
-
this._prefixUnaryOverloads.set(prefixUnarySyntaxKind, operatorOverloads);
|
|
249807
|
-
this._logger.debug(`Loaded ${className}["${operatorString}"][${index}]: ${operatorString}(${sl(operandType)}) => ${sl(returnType)} (prefix unary, from .d.ts)`);
|
|
249808
|
-
let fileEntries = this._prefixUnaryFileEntries.get(filePath);
|
|
249809
|
-
if (!fileEntries) {
|
|
249810
|
-
fileEntries = [];
|
|
249811
|
-
this._prefixUnaryFileEntries.set(filePath, fileEntries);
|
|
249812
|
-
}
|
|
249813
|
-
fileEntries.push({ syntaxKind: prefixUnarySyntaxKind, operandType });
|
|
249814
|
-
} else if (paramCount === 0 && !isStatic && postfixUnarySyntaxKind) {
|
|
249815
|
-
if (returnType !== "void") {
|
|
249816
|
-
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Overload function ${index} for postfix operator ${operatorString} ` + `must have a return type of 'void', got '${returnType}'.`, filePath, property.getStartLineNumber(), this._minifyString((_k = property.getText().split(`
|
|
249817
|
-
`)[0]) !== null && _k !== undefined ? _k : "")));
|
|
249818
|
-
continue;
|
|
249819
|
-
}
|
|
249820
|
-
const operandType = classType;
|
|
249821
|
-
const operatorOverloads = (_l = this._postfixUnaryOverloads.get(postfixUnarySyntaxKind)) !== null && _l !== undefined ? _l : new Map;
|
|
249822
|
-
if (operatorOverloads.has(operandType))
|
|
249823
|
-
continue;
|
|
249824
|
-
operatorOverloads.set(operandType, {
|
|
249825
|
-
isStatic: false,
|
|
249826
|
-
className,
|
|
249827
|
-
classFilePath: filePath,
|
|
249828
|
-
operatorString,
|
|
249829
|
-
index,
|
|
249830
|
-
returnType
|
|
249831
|
-
});
|
|
249832
|
-
this._postfixUnaryOverloads.set(postfixUnarySyntaxKind, operatorOverloads);
|
|
249833
|
-
this._logger.debug(`Loaded ${className}["${operatorString}"][${index}]: ${sl(operandType)}${operatorString} () (postfix unary, from .d.ts)`);
|
|
249834
|
-
let fileEntries = this._postfixUnaryFileEntries.get(filePath);
|
|
249835
|
-
if (!fileEntries) {
|
|
249836
|
-
fileEntries = [];
|
|
249837
|
-
this._postfixUnaryFileEntries.set(filePath, fileEntries);
|
|
249838
|
-
}
|
|
249839
|
-
fileEntries.push({ syntaxKind: postfixUnarySyntaxKind, operandType });
|
|
249840
|
-
}
|
|
249841
|
-
}
|
|
249842
|
-
}
|
|
249843
249711
|
_getTypeChain(typeName) {
|
|
249844
249712
|
var _a, _b;
|
|
249845
249713
|
const cached2 = this._typeChainCache.get(typeName);
|
|
@@ -250085,7 +249953,7 @@ var require_validateExports = __commonJS((exports) => {
|
|
|
250085
249953
|
// ../package/dist/index.js
|
|
250086
249954
|
var require_dist4 = __commonJS((exports) => {
|
|
250087
249955
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
250088
|
-
exports.SyntaxKind = exports.Project = exports.Node = exports.operatorSymbols = exports.Operator = exports.validateExports = exports.toV3SourceMap = exports.computeEdits = exports.isPrefixUnaryOperatorSyntaxKind = exports.isPostfixUnaryOperatorSyntaxKind = exports.isOperatorSyntaxKind = exports.OverloadStore = exports.OverloadInjector = exports.unwrapInitializer = exports.resolveExpressionType = exports.getOperatorStringFromProperty = exports.ErrorManager = exports.ErrorDescription = exports.loadConfig = exports.ConsoleLogger = undefined;
|
|
249956
|
+
exports.SyntaxKind = exports.Project = exports.Node = exports.operatorSymbols = exports.Operator = exports.validateExports = exports.toV3SourceMap = exports.computeEdits = exports.isPrefixUnaryOperatorSyntaxKind = exports.isPostfixUnaryOperatorSyntaxKind = exports.isOperatorSyntaxKind = exports.OverloadStore = exports.OverloadInjector = exports.unwrapInitializer = exports.resolveExpressionType = exports.getOperatorStringFromProperty = exports.getOperatorStringFromMethod = exports.ErrorManager = exports.ErrorDescription = exports.loadConfig = exports.ConsoleLogger = undefined;
|
|
250089
249957
|
var BopConfig_1 = require_BopConfig();
|
|
250090
249958
|
Object.defineProperty(exports, "ConsoleLogger", { enumerable: true, get: function() {
|
|
250091
249959
|
return BopConfig_1.ConsoleLogger;
|
|
@@ -250100,6 +249968,10 @@ var require_dist4 = __commonJS((exports) => {
|
|
|
250100
249968
|
Object.defineProperty(exports, "ErrorManager", { enumerable: true, get: function() {
|
|
250101
249969
|
return ErrorManager_1.ErrorManager;
|
|
250102
249970
|
} });
|
|
249971
|
+
var getOperatorStringFromMethod_1 = require_getOperatorStringFromMethod();
|
|
249972
|
+
Object.defineProperty(exports, "getOperatorStringFromMethod", { enumerable: true, get: function() {
|
|
249973
|
+
return getOperatorStringFromMethod_1.getOperatorStringFromMethod;
|
|
249974
|
+
} });
|
|
250103
249975
|
var getOperatorStringFromProperty_1 = require_getOperatorStringFromProperty();
|
|
250104
249976
|
Object.defineProperty(exports, "getOperatorStringFromProperty", { enumerable: true, get: function() {
|
|
250105
249977
|
return getOperatorStringFromProperty_1.getOperatorStringFromProperty;
|
|
@@ -263293,58 +263165,48 @@ var postfixUnaryOperatorStrings = new Set(["++", "--"]);
|
|
|
263293
263165
|
function generateOverloadProperty(className, operator) {
|
|
263294
263166
|
if (postfixUnaryOperatorStrings.has(operator)) {
|
|
263295
263167
|
return [
|
|
263296
|
-
` public
|
|
263297
|
-
|
|
263298
|
-
"\t
|
|
263299
|
-
"\t\t},",
|
|
263300
|
-
"\t] as const;"
|
|
263168
|
+
` public "${operator}"(): void {`,
|
|
263169
|
+
"\t\t// TODO: implement",
|
|
263170
|
+
"\t}"
|
|
263301
263171
|
].join(`
|
|
263302
263172
|
`);
|
|
263303
263173
|
}
|
|
263304
263174
|
if (exclusivePrefixUnaryStrings.has(operator)) {
|
|
263305
263175
|
return [
|
|
263306
|
-
` public static
|
|
263307
|
-
|
|
263308
|
-
|
|
263309
|
-
|
|
263310
|
-
"\t\t},",
|
|
263311
|
-
"\t] as const;"
|
|
263176
|
+
` public static "${operator}"(a: ${className}): ${className} {`,
|
|
263177
|
+
"\t\t// TODO: implement",
|
|
263178
|
+
` return new ${className}();`,
|
|
263179
|
+
"\t}"
|
|
263312
263180
|
].join(`
|
|
263313
263181
|
`);
|
|
263314
263182
|
}
|
|
263315
263183
|
if (instanceOperatorStrings.has(operator)) {
|
|
263316
263184
|
return [
|
|
263317
|
-
` public
|
|
263318
|
-
|
|
263319
|
-
"\t
|
|
263320
|
-
"\t\t},",
|
|
263321
|
-
"\t] as const;"
|
|
263185
|
+
` public "${operator}"(other: ${className}): void {`,
|
|
263186
|
+
"\t\t// TODO: implement",
|
|
263187
|
+
"\t}"
|
|
263322
263188
|
].join(`
|
|
263323
263189
|
`);
|
|
263324
263190
|
}
|
|
263325
263191
|
if (comparisonOperatorStrings.has(operator)) {
|
|
263326
263192
|
return [
|
|
263327
|
-
` public static
|
|
263328
|
-
|
|
263329
|
-
"\t\
|
|
263330
|
-
"\t
|
|
263331
|
-
"\t\t},",
|
|
263332
|
-
"\t] as const;"
|
|
263193
|
+
` public static "${operator}"(a: ${className}, b: ${className}): boolean {`,
|
|
263194
|
+
"\t\t// TODO: implement",
|
|
263195
|
+
"\t\treturn false;",
|
|
263196
|
+
"\t}"
|
|
263333
263197
|
].join(`
|
|
263334
263198
|
`);
|
|
263335
263199
|
}
|
|
263336
263200
|
return [
|
|
263337
|
-
` public static
|
|
263338
|
-
|
|
263339
|
-
|
|
263340
|
-
|
|
263341
|
-
"\t\t},",
|
|
263342
|
-
"\t] as const;"
|
|
263201
|
+
` public static "${operator}"(a: ${className}, b: ${className}): ${className} {`,
|
|
263202
|
+
"\t\t// TODO: implement",
|
|
263203
|
+
` return new ${className}();`,
|
|
263204
|
+
"\t}"
|
|
263343
263205
|
].join(`
|
|
263344
263206
|
`);
|
|
263345
263207
|
}
|
|
263346
263208
|
server2.registerTool("scaffold_overloads", {
|
|
263347
|
-
description: "Generate TypeScript boilerplate for operator overload definitions on a class. " + "Returns code ready to paste into a class body, with correct static/instance " + "placement
|
|
263209
|
+
description: "Generate TypeScript boilerplate for operator overload definitions on a class. " + "Returns code ready to paste into a class body, with correct static/instance " + "placement and parameter types.",
|
|
263348
263210
|
inputSchema: {
|
|
263349
263211
|
className: exports_external.string().describe("The class name to generate overloads for."),
|
|
263350
263212
|
operators: exports_external.array(exports_external.string()).describe(`Array of operator strings. Valid operators: ${import_boperators2.operatorSymbols.join(", ")}`)
|
|
@@ -263384,7 +263246,7 @@ function createCapturingLogger(warnings) {
|
|
|
263384
263246
|
};
|
|
263385
263247
|
}
|
|
263386
263248
|
server2.registerTool("validate_overloads", {
|
|
263387
|
-
description: "Validate operator overload definitions in a single file. " + "Returns structured diagnostics: errors (wrong arity, bad types
|
|
263249
|
+
description: "Validate operator overload definitions in a single file. " + "Returns structured diagnostics: errors (wrong arity, bad types) " + "and warnings (e.g. conflicting overloads). Does not transform the file.",
|
|
263388
263250
|
inputSchema: {
|
|
263389
263251
|
tsconfig: exports_external.string().describe("Absolute path to tsconfig.json for the project."),
|
|
263390
263252
|
filePath: exports_external.string().describe("Absolute path to the TypeScript file to validate.")
|
|
@@ -263436,75 +263298,83 @@ server2.registerTool("validate_overloads", {
|
|
|
263436
263298
|
};
|
|
263437
263299
|
}
|
|
263438
263300
|
});
|
|
263439
|
-
var
|
|
263440
|
-
var
|
|
263301
|
+
var postfixCallPattern = /\["([^"]+)"\]\(\)$/;
|
|
263302
|
+
var instanceCallPattern = /^([a-z_$]\w*)\["([^"]+)"\]\(/;
|
|
263303
|
+
var staticCallPattern = /^([A-Z]\w*)\["([^"]+)"\]\(/;
|
|
263441
263304
|
server2.registerTool("explain_expression", {
|
|
263442
|
-
description: "Explain a transformed boperators expression. " + 'Given an expression like
|
|
263305
|
+
description: "Explain a transformed boperators expression. " + 'Given an expression like Vec2["+"](a, b) or a["+="](b) or a["++"](), ' + "identifies the operator kind, class, and overload entry. " + "Optionally looks up full overload metadata when tsconfig is provided.",
|
|
263443
263306
|
inputSchema: {
|
|
263444
|
-
expression: exports_external.string().describe(`The transformed expression to explain, e.g. '
|
|
263307
|
+
expression: exports_external.string().describe(`The transformed expression to explain, e.g. 'Vec2["+"](a, b)'.`),
|
|
263445
263308
|
tsconfig: exports_external.string().optional().describe("Absolute path to tsconfig.json. When provided, the overload is looked up " + "in the project for richer metadata (file path, parameter types).")
|
|
263446
263309
|
}
|
|
263447
263310
|
}, async ({ expression, tsconfig }) => {
|
|
263448
263311
|
try {
|
|
263449
263312
|
const trimmed = expression.trim();
|
|
263313
|
+
const postfixMatch = trimmed.match(postfixCallPattern);
|
|
263314
|
+
if (postfixMatch) {
|
|
263315
|
+
const [, operator] = postfixMatch;
|
|
263316
|
+
const result = {
|
|
263317
|
+
kind: "postfix unary",
|
|
263318
|
+
operator,
|
|
263319
|
+
isStatic: false,
|
|
263320
|
+
originalExpression: `operand${operator}`,
|
|
263321
|
+
explanation: `Postfix unary operator "${operator}": mutates the operand in place.`
|
|
263322
|
+
};
|
|
263323
|
+
if (tsconfig) {
|
|
263324
|
+
const overloadInfo = lookupOverload(tsconfig, operator, false);
|
|
263325
|
+
if (overloadInfo)
|
|
263326
|
+
Object.assign(result, overloadInfo);
|
|
263327
|
+
}
|
|
263328
|
+
return {
|
|
263329
|
+
content: [
|
|
263330
|
+
{ type: "text", text: JSON.stringify(result, null, 2) }
|
|
263331
|
+
]
|
|
263332
|
+
};
|
|
263333
|
+
}
|
|
263450
263334
|
const instanceMatch = trimmed.match(instanceCallPattern);
|
|
263451
263335
|
if (instanceMatch) {
|
|
263452
|
-
const [,
|
|
263453
|
-
const index = Number.parseInt(indexStr, 10);
|
|
263454
|
-
const callArgs = trimmed.slice(trimmed.indexOf(".call(") + 6, trimmed.lastIndexOf(")"));
|
|
263455
|
-
const hasSecondArg = callArgs.includes(",");
|
|
263456
|
-
const kind = hasSecondArg ? "instance binary" : "postfix unary";
|
|
263457
|
-
const originalPattern = hasSecondArg ? `lhs ${operator} rhs` : `operand${operator}`;
|
|
263336
|
+
const [, , operator] = instanceMatch;
|
|
263458
263337
|
const result = {
|
|
263459
|
-
kind,
|
|
263338
|
+
kind: "instance binary",
|
|
263460
263339
|
operator,
|
|
263461
|
-
index,
|
|
263462
263340
|
isStatic: false,
|
|
263463
|
-
originalExpression:
|
|
263464
|
-
explanation:
|
|
263341
|
+
originalExpression: `lhs ${operator} rhs`,
|
|
263342
|
+
explanation: `Instance binary operator "${operator}": mutates the left-hand side in place (e.g. compound assignment).`
|
|
263465
263343
|
};
|
|
263466
263344
|
if (tsconfig) {
|
|
263467
|
-
const overloadInfo = lookupOverload(tsconfig, operator,
|
|
263345
|
+
const overloadInfo = lookupOverload(tsconfig, operator, false);
|
|
263468
263346
|
if (overloadInfo)
|
|
263469
263347
|
Object.assign(result, overloadInfo);
|
|
263470
263348
|
}
|
|
263471
263349
|
return {
|
|
263472
263350
|
content: [
|
|
263473
|
-
{
|
|
263474
|
-
type: "text",
|
|
263475
|
-
text: JSON.stringify(result, null, 2)
|
|
263476
|
-
}
|
|
263351
|
+
{ type: "text", text: JSON.stringify(result, null, 2) }
|
|
263477
263352
|
]
|
|
263478
263353
|
};
|
|
263479
263354
|
}
|
|
263480
263355
|
const staticMatch = trimmed.match(staticCallPattern);
|
|
263481
263356
|
if (staticMatch) {
|
|
263482
|
-
const [, className, operator
|
|
263483
|
-
const index = Number.parseInt(indexStr, 10);
|
|
263357
|
+
const [, className, operator] = staticMatch;
|
|
263484
263358
|
const argsStr = trimmed.slice(trimmed.indexOf("](") + 2, trimmed.lastIndexOf(")"));
|
|
263485
|
-
const argCount = argsStr.split(",").length;
|
|
263359
|
+
const argCount = argsStr.trim() === "" ? 0 : argsStr.split(",").length;
|
|
263486
263360
|
const kind = argCount >= 2 ? "static binary" : "prefix unary";
|
|
263487
263361
|
const originalPattern = argCount >= 2 ? `lhs ${operator} rhs` : `${operator}operand`;
|
|
263488
263362
|
const result = {
|
|
263489
263363
|
kind,
|
|
263490
263364
|
operator,
|
|
263491
|
-
index,
|
|
263492
263365
|
className,
|
|
263493
263366
|
isStatic: true,
|
|
263494
263367
|
originalExpression: originalPattern,
|
|
263495
263368
|
explanation: argCount >= 2 ? `Static binary operator "${operator}": returns a new value from two operands.` : `Prefix unary operator "${operator}": returns a new value from a single operand.`
|
|
263496
263369
|
};
|
|
263497
263370
|
if (tsconfig) {
|
|
263498
|
-
const overloadInfo = lookupOverload(tsconfig, operator,
|
|
263371
|
+
const overloadInfo = lookupOverload(tsconfig, operator, true, className);
|
|
263499
263372
|
if (overloadInfo)
|
|
263500
263373
|
Object.assign(result, overloadInfo);
|
|
263501
263374
|
}
|
|
263502
263375
|
return {
|
|
263503
263376
|
content: [
|
|
263504
|
-
{
|
|
263505
|
-
type: "text",
|
|
263506
|
-
text: JSON.stringify(result, null, 2)
|
|
263507
|
-
}
|
|
263377
|
+
{ type: "text", text: JSON.stringify(result, null, 2) }
|
|
263508
263378
|
]
|
|
263509
263379
|
};
|
|
263510
263380
|
}
|
|
@@ -263513,8 +263383,9 @@ server2.registerTool("explain_expression", {
|
|
|
263513
263383
|
{
|
|
263514
263384
|
type: "text",
|
|
263515
263385
|
text: `Could not parse expression as a boperators transformed call. ` + `Expected patterns:
|
|
263516
|
-
` + ` Static: ClassName["op"]
|
|
263517
|
-
` + ` Instance: expr["op"]
|
|
263386
|
+
` + ` Static: ClassName["op"](args)
|
|
263387
|
+
` + ` Instance: expr["op"](other)
|
|
263388
|
+
` + ` Postfix: expr["op"]()`
|
|
263518
263389
|
}
|
|
263519
263390
|
],
|
|
263520
263391
|
isError: true
|
|
@@ -263531,15 +263402,13 @@ server2.registerTool("explain_expression", {
|
|
|
263531
263402
|
};
|
|
263532
263403
|
}
|
|
263533
263404
|
});
|
|
263534
|
-
function lookupOverload(tsconfig, operator,
|
|
263405
|
+
function lookupOverload(tsconfig, operator, isStatic, className) {
|
|
263535
263406
|
try {
|
|
263536
263407
|
projectManager.initialize(tsconfig);
|
|
263537
263408
|
const allOverloads = projectManager.overloadStore.getAllOverloads();
|
|
263538
263409
|
const match = allOverloads.find((o) => {
|
|
263539
263410
|
if (o.operatorString !== operator)
|
|
263540
263411
|
return false;
|
|
263541
|
-
if (o.index !== index)
|
|
263542
|
-
return false;
|
|
263543
263412
|
if (className && o.className !== className)
|
|
263544
263413
|
return false;
|
|
263545
263414
|
if (o.isStatic !== isStatic)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@boperators/mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "MCP server for boperators - gives AI assistants access to operator overload information.",
|
|
6
6
|
"repository": {
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
],
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
45
|
-
"boperators": "0.
|
|
45
|
+
"boperators": "0.3.1",
|
|
46
46
|
"zod": "^3.25.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|