Skip to content
This repository was archived by the owner on May 22, 2025. It is now read-only.

Commit d0678a3

Browse files
blicklycopybara-github
authored andcommitted
Upgrade TypeScript to 5.3.2.
PiperOrigin-RevId: 583523736
1 parent d5c2921 commit d0678a3

16 files changed

+303
-99
lines changed

src/googmodule.ts

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,9 @@ export interface GoogModuleProcessorHost {
2929
* Takes the import URL of an ES6 import and returns the googmodule module
3030
* name for the imported module, iff the module is an original closure
3131
* JavaScript file.
32-
*
33-
* Warning: If this function is present, GoogModule won't produce diagnostics
34-
* for multiple provides.
3532
*/
36-
jsPathToModuleName?(importPath: string): string|undefined;
33+
jsPathToModuleName?
34+
(importPath: string): {name: string, multipleProvides: boolean}|undefined;
3735
/**
3836
* Takes the import URL of an ES6 import and returns the property name that
3937
* should be stripped from the usage.
@@ -89,7 +87,8 @@ export function jsPathToNamespace(
8987
host: GoogModuleProcessorHost, context: ts.Node,
9088
diagnostics: ts.Diagnostic[], importPath: string,
9189
getModuleSymbol: () => ts.Symbol | undefined): string|undefined {
92-
const namespace = localJsPathToNamespace(host, importPath);
90+
const namespace =
91+
localJsPathToNamespace(host, context, diagnostics, importPath);
9392
if (namespace) return namespace;
9493

9594
const moduleSymbol = getModuleSymbol();
@@ -105,15 +104,21 @@ export function jsPathToNamespace(
105104
* Forwards to `jsPathToModuleName` on the host if present.
106105
*/
107106
export function localJsPathToNamespace(
108-
host: GoogModuleProcessorHost, importPath: string): string|undefined {
107+
host: GoogModuleProcessorHost, context: ts.Node|undefined,
108+
diagnostics: ts.Diagnostic[], importPath: string): string|undefined {
109109
if (importPath.match(/^goog:/)) {
110110
// This is a namespace import, of the form "goog:foo.bar".
111111
// Fix it to just "foo.bar".
112112
return importPath.substring('goog:'.length);
113113
}
114114

115115
if (host.jsPathToModuleName) {
116-
return host.jsPathToModuleName(importPath);
116+
const module = host.jsPathToModuleName(importPath);
117+
if (!module) return undefined;
118+
if (module.multipleProvides) {
119+
reportMultipleProvidesError(context, diagnostics, importPath);
120+
}
121+
return module.name;
117122
}
118123

119124
return undefined;
@@ -394,10 +399,7 @@ function getGoogNamespaceFromClutzComments(
394399
findLocalInDeclarations(moduleSymbol, '__clutz_multiple_provides');
395400
if (hasMultipleProvides) {
396401
// Report an error...
397-
reportDiagnostic(
398-
tsickleDiagnostics, context,
399-
`referenced JavaScript module ${
400-
tsImport} provides multiple namespaces and cannot be imported by path.`);
402+
reportMultipleProvidesError(context, tsickleDiagnostics, tsImport);
401403
// ... but continue producing an emit that effectively references the first
402404
// provided symbol (to continue finding any additional errors).
403405
}
@@ -411,6 +413,15 @@ function getGoogNamespaceFromClutzComments(
411413
return actualNamespace;
412414
}
413415

416+
function reportMultipleProvidesError(
417+
context: ts.Node|undefined, diagnostics: ts.Diagnostic[],
418+
importPath: string) {
419+
reportDiagnostic(
420+
diagnostics, context,
421+
`referenced JavaScript module ${
422+
importPath} provides multiple namespaces and cannot be imported by path.`);
423+
}
424+
414425
/**
415426
* Converts a TS/ES module './import/path' into a goog.module compatible
416427
* namespace, handling regular imports and `goog:` namespace imports.

src/jsdoc_transformer.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -846,10 +846,9 @@ export function jsdocTransformer(
846846
continue;
847847
}
848848
}
849-
const newDecl =
850-
// TODO: go/ts50upgrade - Remove after upgrade.
851-
// tslint:disable-next-line:no-unnecessary-type-assertion
852-
ts.visitNode(decl, visitor, ts.isVariableDeclaration)!;
849+
const newDecl = ts.setEmitFlags(
850+
ts.visitNode(decl, visitor, ts.isVariableDeclaration)!,
851+
ts.EmitFlags.NoComments);
853852
const newStmt = ts.factory.createVariableStatement(
854853
varStmt.modifiers,
855854
ts.factory.createVariableDeclarationList([newDecl], flags));

src/ns_transformer.ts

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ export function namespaceTransformer(
7272
// transformation fails.
7373
function transformNamespace(
7474
ns: ts.ModuleDeclaration,
75-
mergedDecl: ts.ClassDeclaration|
76-
ts.InterfaceDeclaration): ts.Statement[] {
75+
mergedDecl: ts.ClassDeclaration|ts.InterfaceDeclaration|
76+
ts.EnumDeclaration): ts.Statement[] {
7777
if (!ns.body || !ts.isModuleBlock(ns.body)) {
7878
if (ts.isModuleDeclaration(ns)) {
7979
error(
@@ -83,10 +83,15 @@ export function namespaceTransformer(
8383
return [ns];
8484
}
8585
const nsName = getIdentifierText(ns.name as ts.Identifier);
86+
const mergingWithEnum = ts.isEnumDeclaration(mergedDecl);
8687
const transformedNsStmts: ts.Statement[] = [];
8788
for (const stmt of ns.body.statements) {
8889
if (ts.isEmptyStatement(stmt)) continue;
8990
if (ts.isClassDeclaration(stmt)) {
91+
if (mergingWithEnum) {
92+
errorNotAllowed(stmt, 'class');
93+
continue;
94+
}
9095
transformInnerDeclaration(
9196
stmt, (classDecl, notExported, hoistedIdent) => {
9297
return ts.factory.updateClassDeclaration(
@@ -95,12 +100,20 @@ export function namespaceTransformer(
95100
classDecl.members);
96101
});
97102
} else if (ts.isEnumDeclaration(stmt)) {
103+
if (mergingWithEnum) {
104+
errorNotAllowed(stmt, 'enum');
105+
continue;
106+
}
98107
transformInnerDeclaration(
99108
stmt, (enumDecl, notExported, hoistedIdent) => {
100109
return ts.factory.updateEnumDeclaration(
101110
enumDecl, notExported, hoistedIdent, enumDecl.members);
102111
});
103112
} else if (ts.isInterfaceDeclaration(stmt)) {
113+
if (mergingWithEnum) {
114+
errorNotAllowed(stmt, 'interface');
115+
continue;
116+
}
104117
transformInnerDeclaration(
105118
stmt, (interfDecl, notExported, hoistedIdent) => {
106119
return ts.factory.updateInterfaceDeclaration(
@@ -109,20 +122,39 @@ export function namespaceTransformer(
109122
interfDecl.members);
110123
});
111124
} else if (ts.isTypeAliasDeclaration(stmt)) {
125+
if (mergingWithEnum) {
126+
errorNotAllowed(stmt, 'type alias');
127+
continue;
128+
}
112129
transformTypeAliasDeclaration(stmt);
113130
} else if (ts.isVariableStatement(stmt)) {
114131
if ((ts.getCombinedNodeFlags(stmt.declarationList) &
115132
ts.NodeFlags.Const) === 0) {
116133
error(
117134
stmt,
118135
'non-const values are not supported. (go/ts-merged-namespaces)');
136+
continue;
119137
}
120138
if (!ts.isInterfaceDeclaration(mergedDecl)) {
121139
error(
122140
stmt,
123141
'const declaration only allowed when merging with an interface (go/ts-merged-namespaces)');
142+
continue;
124143
}
125144
transformConstDeclaration(stmt);
145+
} else if (ts.isFunctionDeclaration(stmt)) {
146+
if (!ts.isEnumDeclaration(mergedDecl)) {
147+
error(
148+
stmt,
149+
'function declaration only allowed when merging with an enum (go/ts-merged-namespaces)');
150+
}
151+
transformInnerDeclaration(
152+
stmt, (funcDecl, notExported, hoistedIdent) => {
153+
return ts.factory.updateFunctionDeclaration(
154+
funcDecl, notExported, funcDecl.asteriskToken,
155+
hoistedIdent, funcDecl.typeParameters,
156+
funcDecl.parameters, funcDecl.type, funcDecl.body);
157+
});
126158
} else {
127159
error(
128160
stmt,
@@ -145,6 +177,12 @@ export function namespaceTransformer(
145177

146178
// Local functions follow.
147179

180+
function errorNotAllowed(stmt: ts.Statement, declKind: string) {
181+
error(
182+
stmt,
183+
`${declKind} cannot be merged with enum declaration. (go/ts-merged-namespaces)`);
184+
}
185+
148186
type DeclarationStatement = ts.Declaration&ts.DeclarationStatement;
149187

150188
function transformConstDeclaration(varDecl: ts.VariableStatement) {
@@ -365,12 +403,13 @@ export function namespaceTransformer(
365403
}
366404

367405
if (!ts.isInterfaceDeclaration(mergedDecl) &&
368-
!ts.isClassDeclaration(mergedDecl)) {
369-
// The previous declaration is not a class or interface.
406+
!ts.isClassDeclaration(mergedDecl) &&
407+
!ts.isEnumDeclaration(mergedDecl)) {
408+
// The previous declaration is not a class, enum, or interface.
370409
transformedStmts.push(ns); // Nothing to do here.
371410
error(
372411
ns.name,
373-
'merged declaration must be local class or interface. (go/ts-merged-namespaces)');
412+
'merged declaration must be local class, enum, or interface. (go/ts-merged-namespaces)');
374413
return;
375414
}
376415

src/summary.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ export class FileSummary {
5454
modName: string|undefined;
5555
autochunk = false;
5656
enhanceable = false;
57+
legacyNamespace = false;
5758
moduleType = ModuleType.UNKNOWN;
5859

5960
private stringify(symbol: Symbol): string {

src/transformer_util.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -227,28 +227,30 @@ export function reportDebugWarning(
227227
* @param textRange pass to overrride the text range from the node with a more specific range.
228228
*/
229229
export function reportDiagnostic(
230-
diagnostics: ts.Diagnostic[], node: ts.Node, messageText: string, textRange?: ts.TextRange,
231-
category = ts.DiagnosticCategory.Error) {
230+
diagnostics: ts.Diagnostic[], node: ts.Node|undefined, messageText: string,
231+
textRange?: ts.TextRange, category = ts.DiagnosticCategory.Error) {
232232
diagnostics.push(createDiagnostic(node, messageText, textRange, category));
233233
}
234234

235235
function createDiagnostic(
236-
node: ts.Node, messageText: string, textRange: ts.TextRange|undefined,
236+
node: ts.Node|undefined, messageText: string,
237+
textRange: ts.TextRange|undefined,
237238
category: ts.DiagnosticCategory): ts.Diagnostic {
238-
let start, length: number;
239+
let start: number|undefined;
240+
let length: number|undefined;
239241
// getStart on a synthesized node can crash (due to not finding an associated
240242
// source file). Make sure to use the original node.
241243
node = ts.getOriginalNode(node);
242244
if (textRange) {
243245
start = textRange.pos;
244246
length = textRange.end - textRange.pos;
245-
} else {
247+
} else if (node) {
246248
// Only use getStart if node has a valid pos, as it might be synthesized.
247249
start = node.pos >= 0 ? node.getStart() : 0;
248250
length = node.end - node.pos;
249251
}
250252
return {
251-
file: node.getSourceFile(),
253+
file: node?.getSourceFile(),
252254
start,
253255
length,
254256
messageText,
@@ -431,4 +433,4 @@ export function getPreviousDeclaration(
431433
}
432434
}
433435
return null;
434-
}
436+
}

src/ts_migration_exports_shim.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,9 @@ class Generator {
457457
fileSummary.addStrongRequire({type: Type.CLOSURE, name: 'goog'});
458458
fileSummary.addStrongRequire(
459459
{type: Type.CLOSURE, name: this.srcIds.googModuleId});
460+
if (maybeDeclareLegacyNameCall) {
461+
fileSummary.legacyNamespace = true;
462+
}
460463

461464
fileSummary.autochunk = isAutoChunk;
462465
fileSummary.moduleType = ModuleType.GOOG_MODULE;

test/googmodule_test.ts

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import * as googmodule from '../src/googmodule';
1313
import {ModulesManifest} from '../src/modules_manifest';
1414

1515
import * as testSupport from './test_support';
16+
import {outdent} from './test_support';
1617

1718
interface ResolvedNamespace {
1819
name: string;
@@ -42,8 +43,14 @@ function processES5(
4243
transformDynamicImport: 'closure',
4344
};
4445
if (pathToNamespaceMap) {
45-
host.jsPathToModuleName = (importPath: string) =>
46-
pathToNamespaceMap.get(importPath)?.name;
46+
host.jsPathToModuleName = (importPath: string) => {
47+
const module = pathToNamespaceMap.get(importPath);
48+
if (!module) return undefined;
49+
return {
50+
name: module.name,
51+
multipleProvides: false,
52+
};
53+
};
4754
host.jsPathToStripProperty = (importPath: string) =>
4855
pathToNamespaceMap.get(importPath)?.stripProperty;
4956
}
@@ -71,21 +78,6 @@ function processES5(
7178
return {output, manifest, rootDir};
7279
}
7380

74-
/**
75-
* Remove the first line (if empty) and unindents the all other lines by the
76-
* amount of leading whitespace in the second line.
77-
*/
78-
function outdent(str: string) {
79-
const lines = str.split('\n');
80-
if (lines.length < 2) return str;
81-
if (lines.shift() !== '') return str;
82-
const indent = lines[0].match(/^ */)![0].length;
83-
for (let i = 0; i < lines.length; i++) {
84-
lines[i] = lines[i].substring(indent);
85-
}
86-
return lines.join('\n');
87-
}
88-
8981
describe('convertCommonJsToGoogModule', () => {
9082
beforeEach(() => {
9183
testSupport.addDiffMatchers();

test/test_support.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,3 +453,18 @@ export function pathToModuleName(
453453
if (fileName === tslibPath()) return 'tslib';
454454
return cliSupport.pathToModuleName(rootModulePath, context, fileName);
455455
}
456+
457+
/**
458+
* Remove the first line (if empty) and unindents the all other lines by the
459+
* amount of leading whitespace in the second line.
460+
*/
461+
export function outdent(str: string) {
462+
const lines = str.split('\n');
463+
if (lines.length < 2) return str;
464+
if (lines.shift() !== '') return str;
465+
const indent = lines[0].match(/^ */)![0].length;
466+
for (let i = 0; i < lines.length; i++) {
467+
lines[i] = lines[i].substring(indent);
468+
}
469+
return lines.join('\n');
470+
}

0 commit comments

Comments
 (0)