@@ -4968,7 +4968,7 @@ namespace ts {
4968
4968
const oldcontext = context;
4969
4969
context = {
4970
4970
...oldcontext,
4971
- usedSymbolNames: mapMap(symbolTable, (_symbol, name) => [unescapeLeadingUnderscores(name), true] ),
4971
+ usedSymbolNames: createMap( ),
4972
4972
remappedSymbolNames: createMap(),
4973
4973
tracker: {
4974
4974
...oldcontext.tracker,
@@ -4992,6 +4992,10 @@ namespace ts {
4992
4992
context.usedSymbolNames!.set(name, true);
4993
4993
});
4994
4994
}
4995
+ forEachEntry(symbolTable, (symbol, name) => {
4996
+ const baseName = unescapeLeadingUnderscores(name);
4997
+ void getInternalSymbolName(symbol, baseName); // Called to cache values into `usedSymbolNames` and `remappedSymbolNames`
4998
+ });
4995
4999
let addingDeclare = !bundled;
4996
5000
const exportEquals = symbolTable.get(InternalSymbolName.ExportEquals);
4997
5001
if (exportEquals && symbolTable.size > 1 && exportEquals.flags & SymbolFlags.Alias) {
@@ -5204,7 +5208,11 @@ namespace ts {
5204
5208
isPrivate = true;
5205
5209
}
5206
5210
const modifierFlags = (!isPrivate ? ModifierFlags.Export : 0) | (isDefault && !needsPostExportDefault ? ModifierFlags.Default : 0);
5207
- if (symbol.flags & SymbolFlags.Function) {
5211
+ const isConstMergedWithNS = symbol.flags & SymbolFlags.Module &&
5212
+ symbol.flags & (SymbolFlags.BlockScopedVariable | SymbolFlags.FunctionScopedVariable | SymbolFlags.Property) &&
5213
+ symbol.escapedName !== InternalSymbolName.ExportEquals;
5214
+ const isConstMergedWithNSPrintableAsSignatureMerge = isConstMergedWithNS && isTypeRepresentableAsFunctionNamespaceMerge(getTypeOfSymbol(symbol), symbol);
5215
+ if (symbol.flags & SymbolFlags.Function || isConstMergedWithNSPrintableAsSignatureMerge) {
5208
5216
serializeAsFunctionNamespaceMerge(getTypeOfSymbol(symbol), symbol, getInternalSymbolName(symbol, symbolName), modifierFlags);
5209
5217
}
5210
5218
if (symbol.flags & SymbolFlags.TypeAlias) {
@@ -5215,7 +5223,8 @@ namespace ts {
5215
5223
if (symbol.flags & (SymbolFlags.BlockScopedVariable | SymbolFlags.FunctionScopedVariable | SymbolFlags.Property)
5216
5224
&& symbol.escapedName !== InternalSymbolName.ExportEquals
5217
5225
&& !(symbol.flags & SymbolFlags.Prototype)
5218
- && !(symbol.flags & SymbolFlags.Class)) {
5226
+ && !(symbol.flags & SymbolFlags.Class)
5227
+ && !isConstMergedWithNSPrintableAsSignatureMerge) {
5219
5228
serializeVariableOrProperty(symbol, symbolName, isPrivate, needsPostExportDefault, propertyAsAlias, modifierFlags);
5220
5229
}
5221
5230
if (symbol.flags & SymbolFlags.Enum) {
@@ -5232,7 +5241,7 @@ namespace ts {
5232
5241
serializeAsClass(symbol, getInternalSymbolName(symbol, symbolName), modifierFlags);
5233
5242
}
5234
5243
}
5235
- if (symbol.flags & (SymbolFlags.ValueModule | SymbolFlags.NamespaceModule)) {
5244
+ if (( symbol.flags & (SymbolFlags.ValueModule | SymbolFlags.NamespaceModule) && (!isConstMergedWithNS || isTypeOnlyNamespace(symbol))) || isConstMergedWithNSPrintableAsSignatureMerge ) {
5236
5245
serializeModule(symbol, symbolName, modifierFlags);
5237
5246
}
5238
5247
if (symbol.flags & SymbolFlags.Interface) {
@@ -5259,7 +5268,9 @@ namespace ts {
5259
5268
}
5260
5269
5261
5270
function includePrivateSymbol(symbol: Symbol) {
5271
+ if (some(symbol.declarations, isParameterDeclaration)) return;
5262
5272
Debug.assertDefined(deferredPrivates);
5273
+ getUnusedName(unescapeLeadingUnderscores(symbol.escapedName), symbol); // Call to cache unique name for symbol
5263
5274
deferredPrivates!.set("" + getSymbolId(symbol), symbol);
5264
5275
}
5265
5276
@@ -5333,8 +5344,16 @@ namespace ts {
5333
5344
), modifierFlags);
5334
5345
}
5335
5346
5347
+ function getNamespaceMembersForSerialization(symbol: Symbol) {
5348
+ return !symbol.exports ? [] : filter(arrayFrom((symbol.exports).values()), p => !((p.flags & SymbolFlags.Prototype) || (p.escapedName === "prototype")));
5349
+ }
5350
+
5351
+ function isTypeOnlyNamespace(symbol: Symbol) {
5352
+ return every(getNamespaceMembersForSerialization(symbol), m => !(resolveSymbol(m).flags & SymbolFlags.Value));
5353
+ }
5354
+
5336
5355
function serializeModule(symbol: Symbol, symbolName: string, modifierFlags: ModifierFlags) {
5337
- const members = !symbol.exports ? [] : filter(arrayFrom(( symbol.exports).values()), p => !((p.flags & SymbolFlags.Prototype) || (p.escapedName === "prototype")) );
5356
+ const members = getNamespaceMembersForSerialization( symbol);
5338
5357
// Split NS members up by declaration - members whose parent symbol is the ns symbol vs those whose is not (but were added in later via merging)
5339
5358
const locationMap = arrayToMultiMap(members, m => m.parent && m.parent === symbol ? "real" : "merged");
5340
5359
const realMembers = locationMap.get("real") || emptyArray;
@@ -5344,18 +5363,21 @@ namespace ts {
5344
5363
// so we don't even have placeholders to fill in.
5345
5364
if (length(realMembers)) {
5346
5365
const localName = getInternalSymbolName(symbol, symbolName);
5347
- serializeAsNamespaceDeclaration(realMembers, localName, modifierFlags, !!(symbol.flags & SymbolFlags.Function));
5366
+ serializeAsNamespaceDeclaration(realMembers, localName, modifierFlags, !!(symbol.flags & ( SymbolFlags.Function | SymbolFlags.Assignment) ));
5348
5367
}
5349
5368
if (length(mergedMembers)) {
5350
5369
const localName = getInternalSymbolName(symbol, symbolName);
5351
- forEach(mergedMembers, includePrivateSymbol);
5352
5370
const nsBody = createModuleBlock([createExportDeclaration(
5353
5371
/*decorators*/ undefined,
5354
5372
/*modifiers*/ undefined,
5355
5373
createNamedExports(map(filter(mergedMembers, n => n.escapedName !== InternalSymbolName.ExportEquals), s => {
5356
5374
const name = unescapeLeadingUnderscores(s.escapedName);
5357
5375
const localName = getInternalSymbolName(s, name);
5358
- return createExportSpecifier(name === localName ? undefined : localName, name);
5376
+ const aliasDecl = s.declarations && getDeclarationOfAliasSymbol(s);
5377
+ const target = aliasDecl && getTargetOfAliasDeclaration(aliasDecl, /*dontRecursivelyResolve*/ true);
5378
+ includePrivateSymbol(target || s);
5379
+ const targetName = target ? getInternalSymbolName(target, unescapeLeadingUnderscores(target.escapedName)) : localName;
5380
+ return createExportSpecifier(name === targetName ? undefined : targetName, name);
5359
5381
}))
5360
5382
)]);
5361
5383
addResult(createModuleDeclaration(
@@ -5630,6 +5652,7 @@ namespace ts {
5630
5652
serializeMaybeAliasAssignment(symbol);
5631
5653
break;
5632
5654
case SyntaxKind.BinaryExpression:
5655
+ case SyntaxKind.PropertyAccessExpression:
5633
5656
// Could be best encoded as though an export specifier or as though an export assignment
5634
5657
// If name is default or export=, do an export assignment
5635
5658
// Otherwise do an export specifier
@@ -5640,10 +5663,6 @@ namespace ts {
5640
5663
serializeExportSpecifier(localName, targetName);
5641
5664
}
5642
5665
break;
5643
- case SyntaxKind.PropertyAccessExpression:
5644
- // A PAE alias is _always_ going to exist as an append to a top-level export, where our top level
5645
- // handling should always be sufficient to encode the export action itself
5646
- break;
5647
5666
default:
5648
5667
return Debug.failBadSyntaxKind(node, "Unhandled alias declaration kind in symbol serializer!");
5649
5668
}
@@ -5672,7 +5691,8 @@ namespace ts {
5672
5691
const aliasDecl = symbol.declarations && getDeclarationOfAliasSymbol(symbol);
5673
5692
// serialize what the alias points to, preserve the declaration's initializer
5674
5693
const target = aliasDecl && getTargetOfAliasDeclaration(aliasDecl, /*dontRecursivelyResolve*/ true);
5675
- if (target) {
5694
+ // If the target resolves and resolves to a thing defined in this file, emit as an alias, otherwise emit as a const
5695
+ if (target && length(target.declarations) && some(target.declarations, d => getSourceFileOfNode(d) === getSourceFileOfNode(enclosingDeclaration))) {
5676
5696
// In case `target` refers to a namespace member, look at the declaration and serialize the leftmost symbol in it
5677
5697
// eg, `namespace A { export class B {} }; exports = A.B;`
5678
5698
// Technically, this is all that's required in the case where the assignment is an entity name expression
@@ -5758,6 +5778,7 @@ namespace ts {
5758
5778
return getObjectFlags(typeToSerialize) & (ObjectFlags.Anonymous | ObjectFlags.Mapped) &&
5759
5779
!getIndexInfoOfType(typeToSerialize, IndexKind.String) &&
5760
5780
!getIndexInfoOfType(typeToSerialize, IndexKind.Number) &&
5781
+ !!(length(getPropertiesOfType(typeToSerialize)) || length(getSignaturesOfType(typeToSerialize, SignatureKind.Call))) &&
5761
5782
!length(getSignaturesOfType(typeToSerialize, SignatureKind.Construct)) && // TODO: could probably serialize as function + ns + class, now that that's OK
5762
5783
!getDeclarationWithTypeAnnotation(hostSymbol) &&
5763
5784
!(typeToSerialize.symbol && some(typeToSerialize.symbol.declarations, d => getSourceFileOfNode(d) !== ctxSrc)) &&
@@ -6112,11 +6133,8 @@ namespace ts {
6112
6133
return context.remappedSymbolNames!.get("" + getSymbolId(symbol))!;
6113
6134
}
6114
6135
}
6115
- if (input === InternalSymbolName.Default) {
6116
- input = "_default";
6117
- }
6118
- else if (input === InternalSymbolName.ExportEquals) {
6119
- input = "_exports";
6136
+ if (symbol) {
6137
+ input = getNameCandidateWorker(symbol, input);
6120
6138
}
6121
6139
let i = 0;
6122
6140
const original = input;
@@ -6131,17 +6149,29 @@ namespace ts {
6131
6149
return input;
6132
6150
}
6133
6151
6134
- function getInternalSymbolName(symbol: Symbol, localName: string) {
6135
- if (context.remappedSymbolNames!.has("" + getSymbolId(symbol))) {
6136
- return context.remappedSymbolNames!.get("" + getSymbolId(symbol))!;
6137
- }
6152
+ function getNameCandidateWorker(symbol: Symbol, localName: string) {
6138
6153
if (localName === InternalSymbolName.Default || localName === InternalSymbolName.Class || localName === InternalSymbolName.Function) {
6139
6154
const flags = context.flags;
6140
6155
context.flags |= NodeBuilderFlags.InInitialEntityName;
6141
6156
const nameCandidate = getNameOfSymbolAsWritten(symbol, context);
6142
6157
context.flags = flags;
6143
- localName = isIdentifierText(nameCandidate, languageVersion) && !isStringANonContextualKeyword(nameCandidate) ? nameCandidate : getUnusedName(`_default`, symbol);
6158
+ localName = nameCandidate.length > 0 && isSingleOrDoubleQuote(nameCandidate.charCodeAt(0)) ? stripQuotes(nameCandidate) : nameCandidate;
6159
+ }
6160
+ if (localName === InternalSymbolName.Default) {
6161
+ localName = "_default";
6162
+ }
6163
+ else if (localName === InternalSymbolName.ExportEquals) {
6164
+ localName = "_exports";
6165
+ }
6166
+ localName = isIdentifierText(localName, languageVersion) && !isStringANonContextualKeyword(localName) ? localName : "_" + localName.replace(/[^a-zA-Z0-9]/g, "_");
6167
+ return localName;
6168
+ }
6169
+
6170
+ function getInternalSymbolName(symbol: Symbol, localName: string) {
6171
+ if (context.remappedSymbolNames!.has("" + getSymbolId(symbol))) {
6172
+ return context.remappedSymbolNames!.get("" + getSymbolId(symbol))!;
6144
6173
}
6174
+ localName = getNameCandidateWorker(symbol, localName);
6145
6175
// The result of this is going to be used as the symbol's name - lock it in, so `getUnusedName` will also pick it up
6146
6176
context.remappedSymbolNames!.set("" + getSymbolId(symbol), localName);
6147
6177
return localName;
0 commit comments