@boperators/mcp-server 0.2.1 → 0.3.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 +6 -6
- package/dist/index.js +165 -298
- 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 });
|
|
@@ -249298,7 +249321,7 @@ var require_OverloadInjector = __commonJS((exports) => {
|
|
|
249298
249321
|
const overloadDesc = this._overloadStore.findOverload(operatorKind, leftType, rightType);
|
|
249299
249322
|
if (!overloadDesc)
|
|
249300
249323
|
continue;
|
|
249301
|
-
const { className: classNameRaw, classFilePath, operatorString,
|
|
249324
|
+
const { className: classNameRaw, classFilePath, operatorString, isStatic } = overloadDesc;
|
|
249302
249325
|
const classSourceFile = this._project.getSourceFileOrThrow(classFilePath);
|
|
249303
249326
|
const classDecl = classSourceFile.getClassOrThrow(classNameRaw);
|
|
249304
249327
|
const classSymbol = classDecl.getSymbol();
|
|
@@ -249306,7 +249329,7 @@ var require_OverloadInjector = __commonJS((exports) => {
|
|
|
249306
249329
|
throw new Error(`No symbol for class "${classNameRaw}"`);
|
|
249307
249330
|
const classModuleSpecifier = (0, getModuleSpecifier_1.getModuleSpecifier)(sourceFile, classSourceFile);
|
|
249308
249331
|
const className = (0, ensureImportedName_1.ensureImportedName)(sourceFile, classSymbol, classModuleSpecifier);
|
|
249309
|
-
const overloadCall = isStatic ? `${className}["${operatorString}"]
|
|
249332
|
+
const overloadCall = isStatic ? `${className}["${operatorString}"](${lhs.getText()}, ${rhs.getText()})` : `${lhs.getText()}["${operatorString}"](${rhs.getText()})`;
|
|
249310
249333
|
this._logger.debug(`${fileName}: ${expression.getText()} => ${overloadCall}`);
|
|
249311
249334
|
expression.replaceWithText(overloadCall);
|
|
249312
249335
|
transformCount++;
|
|
@@ -249328,7 +249351,7 @@ var require_OverloadInjector = __commonJS((exports) => {
|
|
|
249328
249351
|
const overloadDesc = this._overloadStore.findPrefixUnaryOverload(operatorKind, operandType);
|
|
249329
249352
|
if (!overloadDesc)
|
|
249330
249353
|
continue;
|
|
249331
|
-
const { className: classNameRaw, classFilePath, operatorString
|
|
249354
|
+
const { className: classNameRaw, classFilePath, operatorString } = overloadDesc;
|
|
249332
249355
|
const classSourceFile = this._project.getSourceFileOrThrow(classFilePath);
|
|
249333
249356
|
const classDecl = classSourceFile.getClassOrThrow(classNameRaw);
|
|
249334
249357
|
const classSymbol = classDecl.getSymbol();
|
|
@@ -249336,7 +249359,7 @@ var require_OverloadInjector = __commonJS((exports) => {
|
|
|
249336
249359
|
throw new Error(`No symbol for class "${classNameRaw}"`);
|
|
249337
249360
|
const classModuleSpecifier = (0, getModuleSpecifier_1.getModuleSpecifier)(sourceFile, classSourceFile);
|
|
249338
249361
|
const className = (0, ensureImportedName_1.ensureImportedName)(sourceFile, classSymbol, classModuleSpecifier);
|
|
249339
|
-
const overloadCall = `${className}["${operatorString}"]
|
|
249362
|
+
const overloadCall = `${className}["${operatorString}"](${operand.getText()})`;
|
|
249340
249363
|
this._logger.debug(`${fileName}: ${expression.getText()} => ${overloadCall}`);
|
|
249341
249364
|
expression.replaceWithText(overloadCall);
|
|
249342
249365
|
transformCount++;
|
|
@@ -249358,8 +249381,8 @@ var require_OverloadInjector = __commonJS((exports) => {
|
|
|
249358
249381
|
const overloadDesc = this._overloadStore.findPostfixUnaryOverload(operatorKind, operandType);
|
|
249359
249382
|
if (!overloadDesc)
|
|
249360
249383
|
continue;
|
|
249361
|
-
const { operatorString
|
|
249362
|
-
const overloadCall = `${operand.getText()}["${operatorString}"]
|
|
249384
|
+
const { operatorString } = overloadDesc;
|
|
249385
|
+
const overloadCall = `${operand.getText()}["${operatorString}"]()`;
|
|
249363
249386
|
this._logger.debug(`${fileName}: ${expression.getText()} => ${overloadCall}`);
|
|
249364
249387
|
expression.replaceWithText(overloadCall);
|
|
249365
249388
|
transformCount++;
|
|
@@ -249387,9 +249410,8 @@ var require_OverloadStore = __commonJS((exports) => {
|
|
|
249387
249410
|
var ts_morph_1 = require_ts_morph();
|
|
249388
249411
|
var operatorSymbols_1 = require_operatorSymbols();
|
|
249389
249412
|
var ErrorManager_1 = require_ErrorManager();
|
|
249390
|
-
var
|
|
249413
|
+
var getOperatorStringFromMethod_1 = require_getOperatorStringFromMethod();
|
|
249391
249414
|
var resolveExpressionType_1 = require_resolveExpressionType();
|
|
249392
|
-
var unwrapInitializer_1 = require_unwrapInitializer();
|
|
249393
249415
|
var operatorMap_1 = require_operatorMap();
|
|
249394
249416
|
|
|
249395
249417
|
class OverloadStore extends Map {
|
|
@@ -249509,15 +249531,29 @@ var require_OverloadStore = __commonJS((exports) => {
|
|
|
249509
249531
|
this._parsedFiles.add(filePath);
|
|
249510
249532
|
const classes = sourceFile.getClasses();
|
|
249511
249533
|
classes.forEach((classDecl) => {
|
|
249534
|
+
const className = classDecl.getName();
|
|
249535
|
+
if (!className)
|
|
249536
|
+
return;
|
|
249512
249537
|
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);
|
|
249538
|
+
const methodGroups = new Map;
|
|
249539
|
+
for (const method of classDecl.getMethods()) {
|
|
249540
|
+
const operatorString = (0, getOperatorStringFromMethod_1.getOperatorStringFromMethod)(method);
|
|
249519
249541
|
if (!operatorString || !operatorSymbols_1.operatorSymbols.includes(operatorString))
|
|
249542
|
+
continue;
|
|
249543
|
+
let group = methodGroups.get(operatorString);
|
|
249544
|
+
if (!group) {
|
|
249545
|
+
group = [];
|
|
249546
|
+
methodGroups.set(operatorString, group);
|
|
249547
|
+
}
|
|
249548
|
+
const overloadSigs = method.getOverloads();
|
|
249549
|
+
group.push(...overloadSigs.length > 0 ? overloadSigs : [method]);
|
|
249550
|
+
}
|
|
249551
|
+
methodGroups.forEach((methods, operatorString) => {
|
|
249552
|
+
const overloadSigs = methods.filter((m) => !m.hasBody());
|
|
249553
|
+
const sigsToProcess = overloadSigs.length > 0 ? overloadSigs : methods;
|
|
249554
|
+
if (sigsToProcess.length === 0)
|
|
249520
249555
|
return;
|
|
249556
|
+
const isStatic = sigsToProcess[0].isStatic();
|
|
249521
249557
|
const binarySyntaxKind = operatorMap_1.operatorMap[operatorString];
|
|
249522
249558
|
const prefixUnarySyntaxKind = operatorMap_1.prefixUnaryOperatorMap[operatorString];
|
|
249523
249559
|
const postfixUnarySyntaxKind = operatorMap_1.postfixUnaryOperatorMap[operatorString];
|
|
@@ -249526,93 +249562,74 @@ var require_OverloadStore = __commonJS((exports) => {
|
|
|
249526
249562
|
const shouldBeStatic = binarySyntaxKind != null && !operatorMap_1.instanceOperators.has(binarySyntaxKind) || prefixUnarySyntaxKind != null;
|
|
249527
249563
|
const shouldBeInstance = binarySyntaxKind != null && operatorMap_1.instanceOperators.has(binarySyntaxKind) || postfixUnarySyntaxKind != null;
|
|
249528
249564
|
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);
|
|
249565
|
+
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(`
|
|
249566
|
+
`)[0])));
|
|
249536
249567
|
return;
|
|
249537
249568
|
}
|
|
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");
|
|
249569
|
+
sigsToProcess.forEach((method) => {
|
|
249570
|
+
const parameters = method.getParameters().filter((p) => p.getName() !== "this");
|
|
249560
249571
|
const paramCount = parameters.length;
|
|
249561
249572
|
if (paramCount === 2 && isStatic && binarySyntaxKind && !operatorMap_1.instanceOperators.has(binarySyntaxKind)) {
|
|
249562
|
-
this._addBinaryOverload(binarySyntaxKind,
|
|
249573
|
+
this._addBinaryOverload(binarySyntaxKind, className, classType, filePath, method, parameters, operatorString, true);
|
|
249563
249574
|
} else if (paramCount === 1 && !isStatic && binarySyntaxKind && operatorMap_1.instanceOperators.has(binarySyntaxKind)) {
|
|
249564
|
-
this._addBinaryOverload(binarySyntaxKind,
|
|
249575
|
+
this._addBinaryOverload(binarySyntaxKind, className, classType, filePath, method, parameters, operatorString, false);
|
|
249565
249576
|
} else if (paramCount === 1 && isStatic && prefixUnarySyntaxKind) {
|
|
249566
|
-
this._addPrefixUnaryOverload(prefixUnarySyntaxKind,
|
|
249577
|
+
this._addPrefixUnaryOverload(prefixUnarySyntaxKind, className, classType, filePath, method, parameters, operatorString);
|
|
249567
249578
|
} else if (paramCount === 0 && !isStatic && postfixUnarySyntaxKind) {
|
|
249568
|
-
this._addPostfixUnaryOverload(postfixUnarySyntaxKind,
|
|
249579
|
+
this._addPostfixUnaryOverload(postfixUnarySyntaxKind, className, classType, filePath, method, operatorString);
|
|
249569
249580
|
} else {
|
|
249570
|
-
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Overload
|
|
249581
|
+
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(`
|
|
249582
|
+
`)[0])));
|
|
249571
249583
|
}
|
|
249572
249584
|
});
|
|
249573
249585
|
});
|
|
249574
249586
|
});
|
|
249575
249587
|
}
|
|
249576
|
-
_addBinaryOverload(syntaxKind,
|
|
249577
|
-
var _a, _b
|
|
249588
|
+
_addBinaryOverload(syntaxKind, className, classType, filePath, method, parameters, operatorString, isStatic) {
|
|
249589
|
+
var _a, _b;
|
|
249578
249590
|
let hasWarning = false;
|
|
249579
|
-
const
|
|
249580
|
-
|
|
249591
|
+
const getParamTypeName = (p) => {
|
|
249592
|
+
var _a2, _b2, _c;
|
|
249593
|
+
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 : "");
|
|
249594
|
+
};
|
|
249595
|
+
const lhsType = isStatic ? getParamTypeName(parameters[0]) : classType;
|
|
249596
|
+
const rhsType = isStatic ? getParamTypeName(parameters[1]) : getParamTypeName(parameters[0]);
|
|
249581
249597
|
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.",
|
|
249598
|
+
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(`
|
|
249599
|
+
`)[0])));
|
|
249583
249600
|
hasWarning = true;
|
|
249584
249601
|
}
|
|
249585
|
-
const returnType =
|
|
249602
|
+
const returnType = method.getReturnType().getText();
|
|
249586
249603
|
if (operatorMap_1.comparisonOperators.has(syntaxKind) && returnType !== "boolean") {
|
|
249587
|
-
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Overload
|
|
249604
|
+
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(`
|
|
249605
|
+
`)[0])));
|
|
249588
249606
|
hasWarning = true;
|
|
249589
249607
|
}
|
|
249590
249608
|
if (!isStatic && returnType !== "void") {
|
|
249591
|
-
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Overload
|
|
249609
|
+
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(`
|
|
249610
|
+
`)[0])));
|
|
249592
249611
|
hasWarning = true;
|
|
249593
249612
|
}
|
|
249594
|
-
const operatorOverloads = (
|
|
249595
|
-
const lhsMap = (
|
|
249613
|
+
const operatorOverloads = (_a = this.get(syntaxKind)) !== null && _a !== undefined ? _a : new Map;
|
|
249614
|
+
const lhsMap = (_b = operatorOverloads.get(lhsType)) !== null && _b !== undefined ? _b : new Map;
|
|
249596
249615
|
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}`,
|
|
249616
|
+
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(`
|
|
249617
|
+
`)[0])));
|
|
249598
249618
|
hasWarning = true;
|
|
249599
249619
|
}
|
|
249600
249620
|
if (hasWarning)
|
|
249601
249621
|
return;
|
|
249602
249622
|
lhsMap.set(rhsType, {
|
|
249603
249623
|
isStatic,
|
|
249604
|
-
className
|
|
249624
|
+
className,
|
|
249605
249625
|
classFilePath: filePath,
|
|
249606
249626
|
operatorString,
|
|
249607
|
-
index,
|
|
249608
249627
|
returnType
|
|
249609
249628
|
});
|
|
249610
249629
|
operatorOverloads.set(lhsType, lhsMap);
|
|
249611
249630
|
this.set(syntaxKind, operatorOverloads);
|
|
249612
|
-
const funcName = ts_morph_1.Node.isFunctionExpression(element) ? element.getName() : undefined;
|
|
249613
249631
|
const sl = this._shortTypeName.bind(this);
|
|
249614
|
-
|
|
249615
|
-
this._logger.debug(`Loaded ${classDecl.getName()}["${operatorString}"][${index}]: ${label} => ${sl(element.getReturnType().getText())}${isStatic ? " (static)" : " (instance)"}`);
|
|
249632
|
+
this._logger.debug(`Loaded ${className}["${operatorString}"]: (${sl(lhsType)}, ${sl(rhsType)}) => ${sl(returnType)}${isStatic ? " (static)" : " (instance)"}`);
|
|
249616
249633
|
let fileEntries = this._fileEntries.get(filePath);
|
|
249617
249634
|
if (!fileEntries) {
|
|
249618
249635
|
fileEntries = [];
|
|
@@ -249620,35 +249637,34 @@ var require_OverloadStore = __commonJS((exports) => {
|
|
|
249620
249637
|
}
|
|
249621
249638
|
fileEntries.push({ syntaxKind, lhsType, rhsType });
|
|
249622
249639
|
}
|
|
249623
|
-
_addPrefixUnaryOverload(syntaxKind,
|
|
249624
|
-
var _a, _b, _c;
|
|
249640
|
+
_addPrefixUnaryOverload(syntaxKind, className, classType, filePath, method, parameters, operatorString) {
|
|
249641
|
+
var _a, _b, _c, _d, _e, _f;
|
|
249625
249642
|
let hasWarning = false;
|
|
249626
|
-
const operandType = (0, resolveExpressionType_1.normalizeTypeName)((_b = (_a = parameters[0]) === null || _a === undefined ? undefined : _a.getType().getText()) !== null &&
|
|
249643
|
+
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
249644
|
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.",
|
|
249645
|
+
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(`
|
|
249646
|
+
`)[0])));
|
|
249629
249647
|
hasWarning = true;
|
|
249630
249648
|
}
|
|
249631
|
-
const operatorOverloads = (
|
|
249649
|
+
const operatorOverloads = (_f = this._prefixUnaryOverloads.get(syntaxKind)) !== null && _f !== undefined ? _f : new Map;
|
|
249632
249650
|
if (operatorOverloads.has(operandType)) {
|
|
249633
|
-
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Duplicate prefix unary overload for operator ${operatorString} with operand type ${operandType}`,
|
|
249651
|
+
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(`
|
|
249652
|
+
`)[0])));
|
|
249634
249653
|
hasWarning = true;
|
|
249635
249654
|
}
|
|
249636
249655
|
if (hasWarning)
|
|
249637
249656
|
return;
|
|
249638
|
-
const returnType =
|
|
249657
|
+
const returnType = method.getReturnType().getText();
|
|
249639
249658
|
operatorOverloads.set(operandType, {
|
|
249640
249659
|
isStatic: true,
|
|
249641
|
-
className
|
|
249660
|
+
className,
|
|
249642
249661
|
classFilePath: filePath,
|
|
249643
249662
|
operatorString,
|
|
249644
|
-
index,
|
|
249645
249663
|
returnType
|
|
249646
249664
|
});
|
|
249647
249665
|
this._prefixUnaryOverloads.set(syntaxKind, operatorOverloads);
|
|
249648
|
-
const funcName = ts_morph_1.Node.isFunctionExpression(element) ? element.getName() : undefined;
|
|
249649
249666
|
const sl = this._shortTypeName.bind(this);
|
|
249650
|
-
|
|
249651
|
-
this._logger.debug(`Loaded ${classDecl.getName()}["${operatorString}"][${index}]: ${operatorString}${label} => ${sl(returnType)} (prefix unary)`);
|
|
249667
|
+
this._logger.debug(`Loaded ${className}["${operatorString}"]: ${operatorString}(${sl(operandType)}) => ${sl(returnType)} (prefix unary)`);
|
|
249652
249668
|
let fileEntries = this._prefixUnaryFileEntries.get(filePath);
|
|
249653
249669
|
if (!fileEntries) {
|
|
249654
249670
|
fileEntries = [];
|
|
@@ -249656,34 +249672,33 @@ var require_OverloadStore = __commonJS((exports) => {
|
|
|
249656
249672
|
}
|
|
249657
249673
|
fileEntries.push({ syntaxKind, operandType });
|
|
249658
249674
|
}
|
|
249659
|
-
_addPostfixUnaryOverload(syntaxKind,
|
|
249675
|
+
_addPostfixUnaryOverload(syntaxKind, className, classType, filePath, method, operatorString) {
|
|
249660
249676
|
var _a;
|
|
249661
249677
|
let hasWarning = false;
|
|
249662
|
-
const returnType =
|
|
249678
|
+
const returnType = method.getReturnType().getText();
|
|
249663
249679
|
if (returnType !== "void") {
|
|
249664
|
-
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Overload
|
|
249680
|
+
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(`
|
|
249681
|
+
`)[0])));
|
|
249665
249682
|
hasWarning = true;
|
|
249666
249683
|
}
|
|
249667
249684
|
const operandType = classType;
|
|
249668
249685
|
const operatorOverloads = (_a = this._postfixUnaryOverloads.get(syntaxKind)) !== null && _a !== undefined ? _a : new Map;
|
|
249669
249686
|
if (operatorOverloads.has(operandType)) {
|
|
249670
|
-
this._errorManager.addWarning(new ErrorManager_1.ErrorDescription(`Duplicate postfix unary overload for operator ${operatorString} with operand type ${operandType}`,
|
|
249687
|
+
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(`
|
|
249688
|
+
`)[0])));
|
|
249671
249689
|
hasWarning = true;
|
|
249672
249690
|
}
|
|
249673
249691
|
if (hasWarning)
|
|
249674
249692
|
return;
|
|
249675
249693
|
operatorOverloads.set(operandType, {
|
|
249676
249694
|
isStatic: false,
|
|
249677
|
-
className
|
|
249695
|
+
className,
|
|
249678
249696
|
classFilePath: filePath,
|
|
249679
249697
|
operatorString,
|
|
249680
|
-
index,
|
|
249681
249698
|
returnType
|
|
249682
249699
|
});
|
|
249683
249700
|
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)`);
|
|
249701
|
+
this._logger.debug(`Loaded ${className}["${operatorString}"]: ${this._shortTypeName(operandType)}${operatorString} () (postfix unary)`);
|
|
249687
249702
|
let fileEntries = this._postfixUnaryFileEntries.get(filePath);
|
|
249688
249703
|
if (!fileEntries) {
|
|
249689
249704
|
fileEntries = [];
|
|
@@ -249691,155 +249706,6 @@ var require_OverloadStore = __commonJS((exports) => {
|
|
|
249691
249706
|
}
|
|
249692
249707
|
fileEntries.push({ syntaxKind, operandType });
|
|
249693
249708
|
}
|
|
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
249709
|
_getTypeChain(typeName) {
|
|
249844
249710
|
var _a, _b;
|
|
249845
249711
|
const cached2 = this._typeChainCache.get(typeName);
|
|
@@ -250085,7 +249951,7 @@ var require_validateExports = __commonJS((exports) => {
|
|
|
250085
249951
|
// ../package/dist/index.js
|
|
250086
249952
|
var require_dist4 = __commonJS((exports) => {
|
|
250087
249953
|
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;
|
|
249954
|
+
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
249955
|
var BopConfig_1 = require_BopConfig();
|
|
250090
249956
|
Object.defineProperty(exports, "ConsoleLogger", { enumerable: true, get: function() {
|
|
250091
249957
|
return BopConfig_1.ConsoleLogger;
|
|
@@ -250100,6 +249966,10 @@ var require_dist4 = __commonJS((exports) => {
|
|
|
250100
249966
|
Object.defineProperty(exports, "ErrorManager", { enumerable: true, get: function() {
|
|
250101
249967
|
return ErrorManager_1.ErrorManager;
|
|
250102
249968
|
} });
|
|
249969
|
+
var getOperatorStringFromMethod_1 = require_getOperatorStringFromMethod();
|
|
249970
|
+
Object.defineProperty(exports, "getOperatorStringFromMethod", { enumerable: true, get: function() {
|
|
249971
|
+
return getOperatorStringFromMethod_1.getOperatorStringFromMethod;
|
|
249972
|
+
} });
|
|
250103
249973
|
var getOperatorStringFromProperty_1 = require_getOperatorStringFromProperty();
|
|
250104
249974
|
Object.defineProperty(exports, "getOperatorStringFromProperty", { enumerable: true, get: function() {
|
|
250105
249975
|
return getOperatorStringFromProperty_1.getOperatorStringFromProperty;
|
|
@@ -263293,58 +263163,48 @@ var postfixUnaryOperatorStrings = new Set(["++", "--"]);
|
|
|
263293
263163
|
function generateOverloadProperty(className, operator) {
|
|
263294
263164
|
if (postfixUnaryOperatorStrings.has(operator)) {
|
|
263295
263165
|
return [
|
|
263296
|
-
` public
|
|
263297
|
-
|
|
263298
|
-
"\t
|
|
263299
|
-
"\t\t},",
|
|
263300
|
-
"\t] as const;"
|
|
263166
|
+
` public "${operator}"(): void {`,
|
|
263167
|
+
"\t\t// TODO: implement",
|
|
263168
|
+
"\t}"
|
|
263301
263169
|
].join(`
|
|
263302
263170
|
`);
|
|
263303
263171
|
}
|
|
263304
263172
|
if (exclusivePrefixUnaryStrings.has(operator)) {
|
|
263305
263173
|
return [
|
|
263306
|
-
` public static
|
|
263307
|
-
|
|
263308
|
-
|
|
263309
|
-
|
|
263310
|
-
"\t\t},",
|
|
263311
|
-
"\t] as const;"
|
|
263174
|
+
` public static "${operator}"(a: ${className}): ${className} {`,
|
|
263175
|
+
"\t\t// TODO: implement",
|
|
263176
|
+
` return new ${className}();`,
|
|
263177
|
+
"\t}"
|
|
263312
263178
|
].join(`
|
|
263313
263179
|
`);
|
|
263314
263180
|
}
|
|
263315
263181
|
if (instanceOperatorStrings.has(operator)) {
|
|
263316
263182
|
return [
|
|
263317
|
-
` public
|
|
263318
|
-
|
|
263319
|
-
"\t
|
|
263320
|
-
"\t\t},",
|
|
263321
|
-
"\t] as const;"
|
|
263183
|
+
` public "${operator}"(other: ${className}): void {`,
|
|
263184
|
+
"\t\t// TODO: implement",
|
|
263185
|
+
"\t}"
|
|
263322
263186
|
].join(`
|
|
263323
263187
|
`);
|
|
263324
263188
|
}
|
|
263325
263189
|
if (comparisonOperatorStrings.has(operator)) {
|
|
263326
263190
|
return [
|
|
263327
|
-
` public static
|
|
263328
|
-
|
|
263329
|
-
"\t\
|
|
263330
|
-
"\t
|
|
263331
|
-
"\t\t},",
|
|
263332
|
-
"\t] as const;"
|
|
263191
|
+
` public static "${operator}"(a: ${className}, b: ${className}): boolean {`,
|
|
263192
|
+
"\t\t// TODO: implement",
|
|
263193
|
+
"\t\treturn false;",
|
|
263194
|
+
"\t}"
|
|
263333
263195
|
].join(`
|
|
263334
263196
|
`);
|
|
263335
263197
|
}
|
|
263336
263198
|
return [
|
|
263337
|
-
` public static
|
|
263338
|
-
|
|
263339
|
-
|
|
263340
|
-
|
|
263341
|
-
"\t\t},",
|
|
263342
|
-
"\t] as const;"
|
|
263199
|
+
` public static "${operator}"(a: ${className}, b: ${className}): ${className} {`,
|
|
263200
|
+
"\t\t// TODO: implement",
|
|
263201
|
+
` return new ${className}();`,
|
|
263202
|
+
"\t}"
|
|
263343
263203
|
].join(`
|
|
263344
263204
|
`);
|
|
263345
263205
|
}
|
|
263346
263206
|
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
|
|
263207
|
+
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
263208
|
inputSchema: {
|
|
263349
263209
|
className: exports_external.string().describe("The class name to generate overloads for."),
|
|
263350
263210
|
operators: exports_external.array(exports_external.string()).describe(`Array of operator strings. Valid operators: ${import_boperators2.operatorSymbols.join(", ")}`)
|
|
@@ -263384,7 +263244,7 @@ function createCapturingLogger(warnings) {
|
|
|
263384
263244
|
};
|
|
263385
263245
|
}
|
|
263386
263246
|
server2.registerTool("validate_overloads", {
|
|
263387
|
-
description: "Validate operator overload definitions in a single file. " + "Returns structured diagnostics: errors (wrong arity, bad types
|
|
263247
|
+
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
263248
|
inputSchema: {
|
|
263389
263249
|
tsconfig: exports_external.string().describe("Absolute path to tsconfig.json for the project."),
|
|
263390
263250
|
filePath: exports_external.string().describe("Absolute path to the TypeScript file to validate.")
|
|
@@ -263436,75 +263296,83 @@ server2.registerTool("validate_overloads", {
|
|
|
263436
263296
|
};
|
|
263437
263297
|
}
|
|
263438
263298
|
});
|
|
263439
|
-
var
|
|
263440
|
-
var
|
|
263299
|
+
var postfixCallPattern = /\["([^"]+)"\]\(\)$/;
|
|
263300
|
+
var instanceCallPattern = /^([a-z_$]\w*)\["([^"]+)"\]\(/;
|
|
263301
|
+
var staticCallPattern = /^([A-Z]\w*)\["([^"]+)"\]\(/;
|
|
263441
263302
|
server2.registerTool("explain_expression", {
|
|
263442
|
-
description: "Explain a transformed boperators expression. " + 'Given an expression like
|
|
263303
|
+
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
263304
|
inputSchema: {
|
|
263444
|
-
expression: exports_external.string().describe(`The transformed expression to explain, e.g. '
|
|
263305
|
+
expression: exports_external.string().describe(`The transformed expression to explain, e.g. 'Vec2["+"](a, b)'.`),
|
|
263445
263306
|
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
263307
|
}
|
|
263447
263308
|
}, async ({ expression, tsconfig }) => {
|
|
263448
263309
|
try {
|
|
263449
263310
|
const trimmed = expression.trim();
|
|
263311
|
+
const postfixMatch = trimmed.match(postfixCallPattern);
|
|
263312
|
+
if (postfixMatch) {
|
|
263313
|
+
const [, operator] = postfixMatch;
|
|
263314
|
+
const result = {
|
|
263315
|
+
kind: "postfix unary",
|
|
263316
|
+
operator,
|
|
263317
|
+
isStatic: false,
|
|
263318
|
+
originalExpression: `operand${operator}`,
|
|
263319
|
+
explanation: `Postfix unary operator "${operator}": mutates the operand in place.`
|
|
263320
|
+
};
|
|
263321
|
+
if (tsconfig) {
|
|
263322
|
+
const overloadInfo = lookupOverload(tsconfig, operator, false);
|
|
263323
|
+
if (overloadInfo)
|
|
263324
|
+
Object.assign(result, overloadInfo);
|
|
263325
|
+
}
|
|
263326
|
+
return {
|
|
263327
|
+
content: [
|
|
263328
|
+
{ type: "text", text: JSON.stringify(result, null, 2) }
|
|
263329
|
+
]
|
|
263330
|
+
};
|
|
263331
|
+
}
|
|
263450
263332
|
const instanceMatch = trimmed.match(instanceCallPattern);
|
|
263451
263333
|
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}`;
|
|
263334
|
+
const [, , operator] = instanceMatch;
|
|
263458
263335
|
const result = {
|
|
263459
|
-
kind,
|
|
263336
|
+
kind: "instance binary",
|
|
263460
263337
|
operator,
|
|
263461
|
-
index,
|
|
263462
263338
|
isStatic: false,
|
|
263463
|
-
originalExpression:
|
|
263464
|
-
explanation:
|
|
263339
|
+
originalExpression: `lhs ${operator} rhs`,
|
|
263340
|
+
explanation: `Instance binary operator "${operator}": mutates the left-hand side in place (e.g. compound assignment).`
|
|
263465
263341
|
};
|
|
263466
263342
|
if (tsconfig) {
|
|
263467
|
-
const overloadInfo = lookupOverload(tsconfig, operator,
|
|
263343
|
+
const overloadInfo = lookupOverload(tsconfig, operator, false);
|
|
263468
263344
|
if (overloadInfo)
|
|
263469
263345
|
Object.assign(result, overloadInfo);
|
|
263470
263346
|
}
|
|
263471
263347
|
return {
|
|
263472
263348
|
content: [
|
|
263473
|
-
{
|
|
263474
|
-
type: "text",
|
|
263475
|
-
text: JSON.stringify(result, null, 2)
|
|
263476
|
-
}
|
|
263349
|
+
{ type: "text", text: JSON.stringify(result, null, 2) }
|
|
263477
263350
|
]
|
|
263478
263351
|
};
|
|
263479
263352
|
}
|
|
263480
263353
|
const staticMatch = trimmed.match(staticCallPattern);
|
|
263481
263354
|
if (staticMatch) {
|
|
263482
|
-
const [, className, operator
|
|
263483
|
-
const index = Number.parseInt(indexStr, 10);
|
|
263355
|
+
const [, className, operator] = staticMatch;
|
|
263484
263356
|
const argsStr = trimmed.slice(trimmed.indexOf("](") + 2, trimmed.lastIndexOf(")"));
|
|
263485
|
-
const argCount = argsStr.split(",").length;
|
|
263357
|
+
const argCount = argsStr.trim() === "" ? 0 : argsStr.split(",").length;
|
|
263486
263358
|
const kind = argCount >= 2 ? "static binary" : "prefix unary";
|
|
263487
263359
|
const originalPattern = argCount >= 2 ? `lhs ${operator} rhs` : `${operator}operand`;
|
|
263488
263360
|
const result = {
|
|
263489
263361
|
kind,
|
|
263490
263362
|
operator,
|
|
263491
|
-
index,
|
|
263492
263363
|
className,
|
|
263493
263364
|
isStatic: true,
|
|
263494
263365
|
originalExpression: originalPattern,
|
|
263495
263366
|
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
263367
|
};
|
|
263497
263368
|
if (tsconfig) {
|
|
263498
|
-
const overloadInfo = lookupOverload(tsconfig, operator,
|
|
263369
|
+
const overloadInfo = lookupOverload(tsconfig, operator, true, className);
|
|
263499
263370
|
if (overloadInfo)
|
|
263500
263371
|
Object.assign(result, overloadInfo);
|
|
263501
263372
|
}
|
|
263502
263373
|
return {
|
|
263503
263374
|
content: [
|
|
263504
|
-
{
|
|
263505
|
-
type: "text",
|
|
263506
|
-
text: JSON.stringify(result, null, 2)
|
|
263507
|
-
}
|
|
263375
|
+
{ type: "text", text: JSON.stringify(result, null, 2) }
|
|
263508
263376
|
]
|
|
263509
263377
|
};
|
|
263510
263378
|
}
|
|
@@ -263513,8 +263381,9 @@ server2.registerTool("explain_expression", {
|
|
|
263513
263381
|
{
|
|
263514
263382
|
type: "text",
|
|
263515
263383
|
text: `Could not parse expression as a boperators transformed call. ` + `Expected patterns:
|
|
263516
|
-
` + ` Static: ClassName["op"]
|
|
263517
|
-
` + ` Instance: expr["op"]
|
|
263384
|
+
` + ` Static: ClassName["op"](args)
|
|
263385
|
+
` + ` Instance: expr["op"](other)
|
|
263386
|
+
` + ` Postfix: expr["op"]()`
|
|
263518
263387
|
}
|
|
263519
263388
|
],
|
|
263520
263389
|
isError: true
|
|
@@ -263531,15 +263400,13 @@ server2.registerTool("explain_expression", {
|
|
|
263531
263400
|
};
|
|
263532
263401
|
}
|
|
263533
263402
|
});
|
|
263534
|
-
function lookupOverload(tsconfig, operator,
|
|
263403
|
+
function lookupOverload(tsconfig, operator, isStatic, className) {
|
|
263535
263404
|
try {
|
|
263536
263405
|
projectManager.initialize(tsconfig);
|
|
263537
263406
|
const allOverloads = projectManager.overloadStore.getAllOverloads();
|
|
263538
263407
|
const match = allOverloads.find((o) => {
|
|
263539
263408
|
if (o.operatorString !== operator)
|
|
263540
263409
|
return false;
|
|
263541
|
-
if (o.index !== index)
|
|
263542
|
-
return false;
|
|
263543
263410
|
if (className && o.className !== className)
|
|
263544
263411
|
return false;
|
|
263545
263412
|
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.0",
|
|
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.0",
|
|
46
46
|
"zod": "^3.25.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|