Skip to content

Commit 1cfec8e

Browse files
committed
Make InvalidAmbientIdentifierName error a diagnostic
1 parent 65562cb commit 1cfec8e

6 files changed

Lines changed: 274 additions & 42 deletions

File tree

src/transformation/utils/diagnostics.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,7 @@ export const unsupportedProperty = createDiagnosticFactory(
122122
export const forOfUnsupportedObjectDestructuring = createDiagnosticFactory(
123123
`Unsupported object destructuring in for...of statement.`
124124
);
125+
126+
export const invalidAmbientIdentifierName = createDiagnosticFactory(
127+
(text: string) => `Invalid ambient identifier name '${text}'. Ambient identifiers must be valid lua identifiers.`
128+
);

src/transformation/utils/errors.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,3 @@ export const ReferencedBeforeDeclaration = (node: ts.Identifier) =>
2121
"must be moved before the identifier's use, or hoisting must be enabled.",
2222
node
2323
);
24-
25-
export const InvalidAmbientIdentifierName = (node: ts.Identifier) =>
26-
new TranspileError(
27-
`Invalid ambient identifier name "${node.text}". Ambient identifiers must be valid lua identifiers.`,
28-
node
29-
);

src/transformation/utils/safe-names.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import * as ts from "typescript";
22
import { TransformationContext } from "../context";
3-
import { InvalidAmbientIdentifierName } from "./errors";
4-
import { isAmbientNode } from "./typescript";
3+
import { invalidAmbientIdentifierName } from "./diagnostics";
54
import { isSymbolExported } from "./export";
5+
import { isAmbientNode } from "./typescript";
66

77
export const isValidLuaIdentifier = (name: string) => !luaKeywords.has(name) && /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name);
88
export const luaKeywords: ReadonlySet<string> = new Set([
@@ -61,23 +61,31 @@ export function hasUnsafeSymbolName(
6161
): boolean {
6262
const isAmbient = symbol.declarations && symbol.declarations.some(d => isAmbientNode(d));
6363

64+
// Catch ambient declarations of identifiers with bad names
6465
if (!isValidLuaIdentifier(symbol.name) && isAmbient) {
65-
// Catch ambient declarations of identifiers with bad names
66-
throw InvalidAmbientIdentifierName(tsOriginal);
66+
context.diagnostics.push(invalidAmbientIdentifierName(tsOriginal, symbol.name));
67+
return true;
6768
}
6869

6970
// only unsafe when non-ambient and not exported
7071
return isUnsafeName(symbol.name) && !isAmbient && !isSymbolExported(context, symbol);
7172
}
7273

73-
export function hasUnsafeIdentifierName(context: TransformationContext, identifier: ts.Identifier): boolean {
74-
const symbol = context.checker.getSymbolAtLocation(identifier);
75-
if (symbol) {
76-
return hasUnsafeSymbolName(context, symbol, identifier);
74+
export function hasUnsafeIdentifierName(
75+
context: TransformationContext,
76+
identifier: ts.Identifier,
77+
checkSymbol = true
78+
): boolean {
79+
if (checkSymbol) {
80+
const symbol = context.checker.getSymbolAtLocation(identifier);
81+
if (symbol) {
82+
return hasUnsafeSymbolName(context, symbol, identifier);
83+
}
7784
}
7885

7986
if (!isValidLuaIdentifier(identifier.text)) {
80-
throw InvalidAmbientIdentifierName(identifier);
87+
context.diagnostics.push(invalidAmbientIdentifierName(identifier, identifier.text));
88+
return true;
8189
}
8290

8391
return false;

src/transformation/visitors/literal.ts

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,9 @@ import * as lua from "../../LuaAST";
33
import { assertNever } from "../../utils";
44
import { FunctionVisitor, TransformationContext, Visitors } from "../context";
55
import { unsupportedAccessorInObjectLiteral } from "../utils/diagnostics";
6-
import { InvalidAmbientIdentifierName } from "../utils/errors";
76
import { createExportedIdentifier, getSymbolExportScope } from "../utils/export";
87
import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib";
9-
import {
10-
createSafeName,
11-
hasUnsafeIdentifierName,
12-
hasUnsafeSymbolName,
13-
isValidLuaIdentifier,
14-
} from "../utils/safe-names";
8+
import { createSafeName, hasUnsafeIdentifierName, hasUnsafeSymbolName } from "../utils/safe-names";
159
import { getSymbolIdOfSymbol, trackSymbolReference } from "../utils/symbols";
1610
import { isArrayType } from "../utils/typescript";
1711
import { transformFunctionLikeDeclaration } from "./function";
@@ -32,20 +26,13 @@ export function createShorthandIdentifier(
3226
valueSymbol: ts.Symbol | undefined,
3327
propertyIdentifier: ts.Identifier
3428
): lua.Expression {
35-
let name: string;
36-
if (valueSymbol !== undefined) {
37-
name = hasUnsafeSymbolName(context, valueSymbol, propertyIdentifier)
38-
? createSafeName(valueSymbol.name)
39-
: valueSymbol.name;
40-
} else {
41-
const propertyName = propertyIdentifier.text;
42-
if (!isValidLuaIdentifier(propertyName)) {
43-
// Catch ambient declarations of identifiers with bad names
44-
throw InvalidAmbientIdentifierName(propertyIdentifier);
45-
}
29+
const propertyName = propertyIdentifier.text;
4630

47-
name = hasUnsafeIdentifierName(context, propertyIdentifier) ? createSafeName(propertyName) : propertyName;
48-
}
31+
const isUnsafeName = valueSymbol
32+
? hasUnsafeSymbolName(context, valueSymbol, propertyIdentifier)
33+
: hasUnsafeIdentifierName(context, propertyIdentifier, false);
34+
35+
const name = isUnsafeName ? createSafeName(propertyName) : propertyName;
4936

5037
let identifier = context.transformExpression(ts.createIdentifier(name));
5138
lua.setNodeOriginal(identifier, propertyIdentifier);

0 commit comments

Comments
 (0)