Skip to content

Commit bb26fd6

Browse files
authored
fix(dts-generator): detect broken method names and throw error
Writing a method name like MyModule[SomeEnum.EnumValue] = async function (param) { in the UI5 source code led to a method name "undefined]" in api.json, which led to a broken dts file and all kinds of unrelated tsc errors. While it should have been detected earlier, it does not hurt to check some names here.
1 parent f6116ac commit bb26fd6

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

packages/dts-generator/docs/TECHNICAL.md

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ The generator works in several phases, which are reflected as modules in [`src/p
4444
Using `directives` as input and the information whether modules or globals should be generated, this phase does plenty of adjustments in the original api.json files:
4545

4646
- `mergeOverlays` merges in the overlays from directives
47+
- `validateNames` does some rudimentary sanity checks for real-world issues which are otherwise hard to debug
4748
- `substituteSapClassInfoTypedef` adds the sap.ClassInfo typedef
4849
- `convertCoreAndConfigurationIntoANamespace` converts `sap.ui.core.Core` and `sap.ui.core.Configuration` from a class (needed as such in the SDK) into a namespace because the module export of both is an _instance_, not the class
4950
- `moveTypeParametersFromConstructorToClass` moves any type parameters from a class's constructor to the class itself. It is more common to build a generic class than building a constructor that has a generic parameter. Newer versions of UI5 (starting with 1.113) will already export the api.json like that, the code in `moveTypeParametersFromConstructorToClass` can handle this.

packages/dts-generator/src/phases/json-fixer.ts

+30
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,35 @@ function mergeOverlays(
134134
});
135135
}
136136

137+
/**
138+
* Does some rudimentary validation of method names.
139+
* The method names are expected to be valid TypeScript identifiers.
140+
* This is not a full validation, but catches errors that happened in real life and were hard to debug.
141+
*
142+
* @param symbols
143+
*/
144+
function validateNames(symbols: ConcreteSymbol[]) {
145+
const invalid_characters = /[{}\[\]()<>]/;
146+
symbols.forEach((symbol) => {
147+
switch (symbol.kind) {
148+
case "class":
149+
case "namespace":
150+
if (symbol.methods) {
151+
symbol.methods.forEach((method) => {
152+
if (invalid_characters.test(method.name)) {
153+
throw new Error(
154+
`Invalid method name "${method.name}" in ${symbol.name}: ` +
155+
"Method names must not contain square brackets. " +
156+
"This might be caused by using unsupported notation in the source code - check it! " +
157+
"Also check the generated api.json, which is used as input here, whether it also contains such a broken name.",
158+
);
159+
}
160+
});
161+
}
162+
}
163+
});
164+
}
165+
137166
/**
138167
*
139168
* @param apijson
@@ -882,6 +911,7 @@ function _prepareApiJson(
882911
options = { mainLibrary: false, generateGlobals: false },
883912
) {
884913
mergeOverlays(json, directives, { generateGlobals: options.generateGlobals });
914+
validateNames(json.symbols);
885915
substituteSapClassInfoTypedef(json);
886916
convertCoreAndConfigurationIntoANamespace(json, directives);
887917
moveTypeParametersFromConstructorToClass(json);

0 commit comments

Comments
 (0)