Skip to content

Commit 9791f1d

Browse files
committed
Merge branch 'master' into assertionsInControlFlow
# Conflicts: # tests/baselines/reference/api/tsserverlibrary.d.ts # tests/baselines/reference/api/typescript.d.ts
2 parents cdeddf1 + 2a2866c commit 9791f1d

File tree

170 files changed

+1615
-752
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

170 files changed

+1615
-752
lines changed

src/compiler/binder.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1860,7 +1860,8 @@ namespace ts {
18601860
node.originalKeywordKind! >= SyntaxKind.FirstFutureReservedWord &&
18611861
node.originalKeywordKind! <= SyntaxKind.LastFutureReservedWord &&
18621862
!isIdentifierName(node) &&
1863-
!(node.flags & NodeFlags.Ambient)) {
1863+
!(node.flags & NodeFlags.Ambient) &&
1864+
!(node.flags & NodeFlags.JSDoc)) {
18641865

18651866
// Report error only if there are no parse errors in file
18661867
if (!file.parseDiagnostics.length) {

src/compiler/checker.ts

Lines changed: 42 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5940,7 +5940,9 @@ namespace ts {
59405940
// Otherwise, fall back to 'any'.
59415941
else {
59425942
if (setter) {
5943-
errorOrSuggestion(noImplicitAny, setter, Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation, symbolToString(symbol));
5943+
if (!isPrivateWithinAmbient(setter)) {
5944+
errorOrSuggestion(noImplicitAny, setter, Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation, symbolToString(symbol));
5945+
}
59445946
}
59455947
else {
59465948
Debug.assert(!!getter, "there must existed getter as we are current checking either setter or getter in this function");
@@ -26330,8 +26332,9 @@ namespace ts {
2633026332

2633126333
let duplicateFunctionDeclaration = false;
2633226334
let multipleConstructorImplementation = false;
26335+
let hasNonAmbientClass = false;
2633326336
for (const current of declarations) {
26334-
const node = <SignatureDeclaration>current;
26337+
const node = <SignatureDeclaration | ClassDeclaration | ClassExpression>current;
2633526338
const inAmbientContext = node.flags & NodeFlags.Ambient;
2633626339
const inAmbientContextOrInterface = node.parent.kind === SyntaxKind.InterfaceDeclaration || node.parent.kind === SyntaxKind.TypeLiteral || inAmbientContext;
2633726340
if (inAmbientContextOrInterface) {
@@ -26345,6 +26348,10 @@ namespace ts {
2634526348
previousDeclaration = undefined;
2634626349
}
2634726350

26351+
if ((node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression) && !inAmbientContext) {
26352+
hasNonAmbientClass = true;
26353+
}
26354+
2634826355
if (node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.MethodSignature || node.kind === SyntaxKind.Constructor) {
2634926356
const currentNodeFlags = getEffectiveDeclarationFlags(node, flagsToCheck);
2635026357
someNodeFlags |= currentNodeFlags;
@@ -26393,6 +26400,16 @@ namespace ts {
2639326400
});
2639426401
}
2639526402

26403+
if (hasNonAmbientClass && !isConstructor && symbol.flags & SymbolFlags.Function) {
26404+
// A non-ambient class cannot be an implementation for a non-constructor function/class merge
26405+
// TODO: The below just replicates our older error from when classes and functions were
26406+
// entirely unable to merge - a more helpful message like "Class declaration cannot implement overload list"
26407+
// might be warranted. :shrug:
26408+
forEach(declarations, declaration => {
26409+
addDuplicateDeclarationError(getNameOfDeclaration(declaration) || declaration, Diagnostics.Duplicate_identifier_0, symbolName(symbol), filter(declarations, d => d !== declaration));
26410+
});
26411+
}
26412+
2639626413
// Abstract methods can't have an implementation -- in particular, they don't need one.
2639726414
if (lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body &&
2639826415
!hasModifier(lastSeenNonAmbientDeclaration, ModifierFlags.Abstract) && !lastSeenNonAmbientDeclaration.questionToken) {
@@ -31704,7 +31721,7 @@ namespace ts {
3170431721
if (!symbol || !(symbol.flags & SymbolFlags.Function)) {
3170531722
return false;
3170631723
}
31707-
return !!forEachEntry(getExportsOfSymbol(symbol), p => p.flags & SymbolFlags.Value && isPropertyAccessExpression(p.valueDeclaration));
31724+
return !!forEachEntry(getExportsOfSymbol(symbol), p => p.flags & SymbolFlags.Value && p.valueDeclaration && isPropertyAccessExpression(p.valueDeclaration));
3170831725
}
3170931726

3171031727
function getPropertiesOfContainerFunction(node: Declaration): Symbol[] {
@@ -33098,43 +33115,39 @@ namespace ts {
3309833115
}
3309933116

3310033117
function checkGrammarAccessor(accessor: AccessorDeclaration): boolean {
33101-
const kind = accessor.kind;
33102-
if (languageVersion < ScriptTarget.ES5) {
33103-
return grammarErrorOnNode(accessor.name, Diagnostics.Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher);
33104-
}
33105-
else if (accessor.flags & NodeFlags.Ambient) {
33106-
return grammarErrorOnNode(accessor.name, Diagnostics.An_accessor_cannot_be_declared_in_an_ambient_context);
33107-
}
33108-
else if (accessor.body === undefined && !hasModifier(accessor, ModifierFlags.Abstract)) {
33109-
return grammarErrorAtPos(accessor, accessor.end - 1, ";".length, Diagnostics._0_expected, "{");
33118+
if (!(accessor.flags & NodeFlags.Ambient)) {
33119+
if (languageVersion < ScriptTarget.ES5) {
33120+
return grammarErrorOnNode(accessor.name, Diagnostics.Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher);
33121+
}
33122+
if (accessor.body === undefined && !hasModifier(accessor, ModifierFlags.Abstract)) {
33123+
return grammarErrorAtPos(accessor, accessor.end - 1, ";".length, Diagnostics._0_expected, "{");
33124+
}
3311033125
}
33111-
else if (accessor.body && hasModifier(accessor, ModifierFlags.Abstract)) {
33126+
if (accessor.body && hasModifier(accessor, ModifierFlags.Abstract)) {
3311233127
return grammarErrorOnNode(accessor, Diagnostics.An_abstract_accessor_cannot_have_an_implementation);
3311333128
}
33114-
else if (accessor.typeParameters) {
33129+
if (accessor.typeParameters) {
3311533130
return grammarErrorOnNode(accessor.name, Diagnostics.An_accessor_cannot_have_type_parameters);
3311633131
}
33117-
else if (!doesAccessorHaveCorrectParameterCount(accessor)) {
33132+
if (!doesAccessorHaveCorrectParameterCount(accessor)) {
3311833133
return grammarErrorOnNode(accessor.name,
33119-
kind === SyntaxKind.GetAccessor ?
33134+
accessor.kind === SyntaxKind.GetAccessor ?
3312033135
Diagnostics.A_get_accessor_cannot_have_parameters :
3312133136
Diagnostics.A_set_accessor_must_have_exactly_one_parameter);
3312233137
}
33123-
else if (kind === SyntaxKind.SetAccessor) {
33138+
if (accessor.kind === SyntaxKind.SetAccessor) {
3312433139
if (accessor.type) {
3312533140
return grammarErrorOnNode(accessor.name, Diagnostics.A_set_accessor_cannot_have_a_return_type_annotation);
3312633141
}
33127-
else {
33128-
const parameter = accessor.parameters[0];
33129-
if (parameter.dotDotDotToken) {
33130-
return grammarErrorOnNode(parameter.dotDotDotToken, Diagnostics.A_set_accessor_cannot_have_rest_parameter);
33131-
}
33132-
else if (parameter.questionToken) {
33133-
return grammarErrorOnNode(parameter.questionToken, Diagnostics.A_set_accessor_cannot_have_an_optional_parameter);
33134-
}
33135-
else if (parameter.initializer) {
33136-
return grammarErrorOnNode(accessor.name, Diagnostics.A_set_accessor_parameter_cannot_have_an_initializer);
33137-
}
33142+
const parameter = Debug.assertDefined(getSetAccessorValueParameter(accessor), "Return value does not match parameter count assertion.");
33143+
if (parameter.dotDotDotToken) {
33144+
return grammarErrorOnNode(parameter.dotDotDotToken, Diagnostics.A_set_accessor_cannot_have_rest_parameter);
33145+
}
33146+
if (parameter.questionToken) {
33147+
return grammarErrorOnNode(parameter.questionToken, Diagnostics.A_set_accessor_cannot_have_an_optional_parameter);
33148+
}
33149+
if (parameter.initializer) {
33150+
return grammarErrorOnNode(accessor.name, Diagnostics.A_set_accessor_parameter_cannot_have_an_initializer);
3313833151
}
3313933152
}
3314033153
return false;
@@ -33622,14 +33635,9 @@ namespace ts {
3362233635

3362333636
function checkGrammarStatementInAmbientContext(node: Node): boolean {
3362433637
if (node.flags & NodeFlags.Ambient) {
33625-
// An accessors is already reported about the ambient context
33626-
if (isAccessor(node.parent)) {
33627-
return getNodeLinks(node).hasReportedStatementInAmbientContext = true;
33628-
}
33629-
3363033638
// Find containing block which is either Block, ModuleBlock, SourceFile
3363133639
const links = getNodeLinks(node);
33632-
if (!links.hasReportedStatementInAmbientContext && isFunctionLike(node.parent)) {
33640+
if (!links.hasReportedStatementInAmbientContext && (isFunctionLike(node.parent) || isAccessor(node.parent))) {
3363333641
return getNodeLinks(node).hasReportedStatementInAmbientContext = grammarErrorOnFirstToken(node, Diagnostics.An_implementation_cannot_be_declared_in_ambient_contexts);
3363433642
}
3363533643

src/compiler/diagnosticMessages.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,10 +243,6 @@
243243
"category": "Error",
244244
"code": 1085
245245
},
246-
"An accessor cannot be declared in an ambient context.": {
247-
"category": "Error",
248-
"code": 1086
249-
},
250246
"'{0}' modifier cannot appear on a constructor declaration.": {
251247
"category": "Error",
252248
"code": 1089

src/compiler/emitter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1609,7 +1609,7 @@ namespace ts {
16091609
for (let i = 0; i < numNodes; i++) {
16101610
const currentNode = bundle ? i < numPrepends ? bundle.prepends[i] : bundle.sourceFiles[i - numPrepends] : node;
16111611
const sourceFile = isSourceFile(currentNode) ? currentNode : isUnparsedSource(currentNode) ? undefined : currentSourceFile!;
1612-
const shouldSkip = printerOptions.noEmitHelpers || (!!sourceFile && getExternalHelpersModuleName(sourceFile) !== undefined);
1612+
const shouldSkip = printerOptions.noEmitHelpers || (!!sourceFile && hasRecordedExternalHelpers(sourceFile));
16131613
const shouldBundle = (isSourceFile(currentNode) || isUnparsedSource(currentNode)) && !isOwnFileEmit;
16141614
const helpers = isUnparsedSource(currentNode) ? currentNode.helpers : getSortedEmitHelpers(currentNode);
16151615
if (helpers) {

src/compiler/factory.ts

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3629,12 +3629,16 @@ namespace ts {
36293629

36303630
// Helpers
36313631

3632-
export function getHelperName(name: string) {
3632+
/**
3633+
* Gets an identifier for the name of an *unscoped* emit helper.
3634+
*/
3635+
export function getUnscopedHelperName(name: string) {
36333636
return setEmitFlags(createIdentifier(name), EmitFlags.HelperName | EmitFlags.AdviseOnEmitNode);
36343637
}
36353638

36363639
export const valuesHelper: UnscopedEmitHelper = {
36373640
name: "typescript:values",
3641+
importName: "__values",
36383642
scoped: false,
36393643
text: `
36403644
var __values = (this && this.__values) || function(o) {
@@ -3654,7 +3658,7 @@ namespace ts {
36543658
context.requestEmitHelper(valuesHelper);
36553659
return setTextRange(
36563660
createCall(
3657-
getHelperName("__values"),
3661+
getUnscopedHelperName("__values"),
36583662
/*typeArguments*/ undefined,
36593663
[expression]
36603664
),
@@ -3664,6 +3668,7 @@ namespace ts {
36643668

36653669
export const readHelper: UnscopedEmitHelper = {
36663670
name: "typescript:read",
3671+
importName: "__read",
36673672
scoped: false,
36683673
text: `
36693674
var __read = (this && this.__read) || function (o, n) {
@@ -3688,7 +3693,7 @@ namespace ts {
36883693
context.requestEmitHelper(readHelper);
36893694
return setTextRange(
36903695
createCall(
3691-
getHelperName("__read"),
3696+
getUnscopedHelperName("__read"),
36923697
/*typeArguments*/ undefined,
36933698
count !== undefined
36943699
? [iteratorRecord, createLiteral(count)]
@@ -3700,6 +3705,7 @@ namespace ts {
37003705

37013706
export const spreadHelper: UnscopedEmitHelper = {
37023707
name: "typescript:spread",
3708+
importName: "__spread",
37033709
scoped: false,
37043710
text: `
37053711
var __spread = (this && this.__spread) || function () {
@@ -3713,7 +3719,7 @@ namespace ts {
37133719
context.requestEmitHelper(spreadHelper);
37143720
return setTextRange(
37153721
createCall(
3716-
getHelperName("__spread"),
3722+
getUnscopedHelperName("__spread"),
37173723
/*typeArguments*/ undefined,
37183724
argumentList
37193725
),
@@ -3723,6 +3729,7 @@ namespace ts {
37233729

37243730
export const spreadArraysHelper: UnscopedEmitHelper = {
37253731
name: "typescript:spreadArrays",
3732+
importName: "__spreadArrays",
37263733
scoped: false,
37273734
text: `
37283735
var __spreadArrays = (this && this.__spreadArrays) || function () {
@@ -3738,7 +3745,7 @@ namespace ts {
37383745
context.requestEmitHelper(spreadArraysHelper);
37393746
return setTextRange(
37403747
createCall(
3741-
getHelperName("__spreadArrays"),
3748+
getUnscopedHelperName("__spreadArrays"),
37423749
/*typeArguments*/ undefined,
37433750
argumentList
37443751
),
@@ -4864,6 +4871,65 @@ namespace ts {
48644871
return emitNode && emitNode.externalHelpersModuleName;
48654872
}
48664873

4874+
export function hasRecordedExternalHelpers(sourceFile: SourceFile) {
4875+
const parseNode = getOriginalNode(sourceFile, isSourceFile);
4876+
const emitNode = parseNode && parseNode.emitNode;
4877+
return !!emitNode && (!!emitNode.externalHelpersModuleName || !!emitNode.externalHelpers);
4878+
}
4879+
4880+
export function createExternalHelpersImportDeclarationIfNeeded(sourceFile: SourceFile, compilerOptions: CompilerOptions, hasExportStarsToExportValues?: boolean, hasImportStar?: boolean, hasImportDefault?: boolean) {
4881+
if (compilerOptions.importHelpers && isEffectiveExternalModule(sourceFile, compilerOptions)) {
4882+
let namedBindings: NamedImportBindings | undefined;
4883+
const moduleKind = getEmitModuleKind(compilerOptions);
4884+
if (moduleKind >= ModuleKind.ES2015 && moduleKind <= ModuleKind.ESNext) {
4885+
// use named imports
4886+
const helpers = getEmitHelpers(sourceFile);
4887+
if (helpers) {
4888+
const helperNames: string[] = [];
4889+
for (const helper of helpers) {
4890+
if (!helper.scoped) {
4891+
const importName = (helper as UnscopedEmitHelper).importName;
4892+
if (importName) {
4893+
pushIfUnique(helperNames, importName);
4894+
}
4895+
}
4896+
}
4897+
if (some(helperNames)) {
4898+
helperNames.sort(compareStringsCaseSensitive);
4899+
// Alias the imports if the names are used somewhere in the file.
4900+
// NOTE: We don't need to care about global import collisions as this is a module.
4901+
namedBindings = createNamedImports(
4902+
map(helperNames, name => isFileLevelUniqueName(sourceFile, name)
4903+
? createImportSpecifier(/*propertyName*/ undefined, createIdentifier(name))
4904+
: createImportSpecifier(createIdentifier(name), getUnscopedHelperName(name))
4905+
)
4906+
);
4907+
const parseNode = getOriginalNode(sourceFile, isSourceFile);
4908+
const emitNode = getOrCreateEmitNode(parseNode);
4909+
emitNode.externalHelpers = true;
4910+
}
4911+
}
4912+
}
4913+
else {
4914+
// use a namespace import
4915+
const externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(sourceFile, compilerOptions, hasExportStarsToExportValues, hasImportStar || hasImportDefault);
4916+
if (externalHelpersModuleName) {
4917+
namedBindings = createNamespaceImport(externalHelpersModuleName);
4918+
}
4919+
}
4920+
if (namedBindings) {
4921+
const externalHelpersImportDeclaration = createImportDeclaration(
4922+
/*decorators*/ undefined,
4923+
/*modifiers*/ undefined,
4924+
createImportClause(/*name*/ undefined, namedBindings),
4925+
createLiteral(externalHelpersModuleNameText)
4926+
);
4927+
addEmitFlags(externalHelpersImportDeclaration, EmitFlags.NeverApplyImportHelper);
4928+
return externalHelpersImportDeclaration;
4929+
}
4930+
}
4931+
}
4932+
48674933
export function getOrCreateExternalHelpersModuleNameIfNeeded(node: SourceFile, compilerOptions: CompilerOptions, hasExportStarsToExportValues?: boolean, hasImportStarOrImportDefault?: boolean) {
48684934
if (compilerOptions.importHelpers && isEffectiveExternalModule(node, compilerOptions)) {
48694935
const externalHelpersModuleName = getExternalHelpersModuleName(node);

0 commit comments

Comments
 (0)