Skip to content

Commit ddd7217

Browse files
committed
Merge remote-tracking branch 'origin/master' into faster-interface-check
* origin/master: (28 commits) LEGO: check in for master to temporary branch. LEGO: check in for master to temporary branch. Removes redundant comments (microsoft#20214) Catch illegal jsdoc tags on constructors (microsoft#20045) Use stricter types for event bodies Use {} instead of any to improve type checking Update public API baseline Update project on PackageInstalledResponse Unswap arguments LEGO: check in for master to temporary branch. Fix visibility checking of mutually recursive exports (microsoft#19929) Add dt baseline folder to gitignore (microsoft#20205) Support getJSDocCommentsAndTags for special property assignments (microsoft#20193) Clean up outliningElementsCollector (microsoft#20143) Correct project root path passed to Typings Installer Check hasOwnProperty before copying property Convert legacy safe list keys to lowercase on construction Port generated lib files (microsoft#20177) Clean up lexical classifier (microsoft#20123) Allow curly around `@type` jsdoc to be optional (microsoft#20074) ...
2 parents e895914 + eb5797f commit ddd7217

File tree

61 files changed

+3779
-2262
lines changed

Some content is hidden

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

61 files changed

+3779
-2262
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,4 @@ tests/cases/user/*/**/*.d.ts
6767
!tests/cases/user/zone.js/
6868
!tests/cases/user/bignumber.js/
6969
!tests/cases/user/discord.js/
70+
tests/baselines/reference/dt

src/compiler/checker.ts

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4049,25 +4049,30 @@ namespace ts {
40494049
}
40504050
}
40514051

4052-
function collectLinkedAliases(node: Identifier): Node[] {
4052+
function collectLinkedAliases(node: Identifier, setVisibility?: boolean): Node[] | undefined {
40534053
let exportSymbol: Symbol;
40544054
if (node.parent && node.parent.kind === SyntaxKind.ExportAssignment) {
4055-
exportSymbol = resolveName(node.parent, node.escapedText, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias, Diagnostics.Cannot_find_name_0, node, /*isUse*/ false);
4055+
exportSymbol = resolveName(node, node.escapedText, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias, /*nameNotFoundMessage*/ undefined, node, /*isUse*/ false);
40564056
}
40574057
else if (node.parent.kind === SyntaxKind.ExportSpecifier) {
40584058
exportSymbol = getTargetOfExportSpecifier(<ExportSpecifier>node.parent, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias);
40594059
}
4060-
const result: Node[] = [];
4060+
let result: Node[];
40614061
if (exportSymbol) {
40624062
buildVisibleNodeList(exportSymbol.declarations);
40634063
}
40644064
return result;
40654065

40664066
function buildVisibleNodeList(declarations: Declaration[]) {
40674067
forEach(declarations, declaration => {
4068-
getNodeLinks(declaration).isVisible = true;
40694068
const resultNode = getAnyImportSyntax(declaration) || declaration;
4070-
pushIfUnique(result, resultNode);
4069+
if (setVisibility) {
4070+
getNodeLinks(declaration).isVisible = true;
4071+
}
4072+
else {
4073+
result = result || [];
4074+
pushIfUnique(result, resultNode);
4075+
}
40714076

40724077
if (isInternalModuleImportEqualsDeclaration(declaration)) {
40734078
// Add the referenced top container visible
@@ -13208,8 +13213,10 @@ namespace ts {
1320813213
// the entire control flow graph from the variable's declaration (i.e. when the flow container and
1320913214
// declaration container are the same).
1321013215
const assumeInitialized = isParameter || isAlias || isOuterVariable ||
13211-
type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & TypeFlags.Any) !== 0 || isInTypeQuery(node) || node.parent.kind === SyntaxKind.ExportSpecifier) ||
13216+
type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & TypeFlags.Any) !== 0 ||
13217+
isInTypeQuery(node) || node.parent.kind === SyntaxKind.ExportSpecifier) ||
1321213218
node.parent.kind === SyntaxKind.NonNullExpression ||
13219+
declaration.kind === SyntaxKind.VariableDeclaration && (<VariableDeclaration>declaration).exclamationToken ||
1321313220
declaration.flags & NodeFlags.Ambient;
1321413221
const initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, getRootDeclaration(declaration) as VariableLikeDeclaration) : type) :
1321513222
type === autoType || type === autoArrayType ? undefinedType :
@@ -22758,6 +22765,7 @@ namespace ts {
2275822765
function isInstancePropertyWithoutInitializer(node: Node) {
2275922766
return node.kind === SyntaxKind.PropertyDeclaration &&
2276022767
!hasModifier(node, ModifierFlags.Static | ModifierFlags.Abstract) &&
22768+
!(<PropertyDeclaration>node).exclamationToken &&
2276122769
!(<PropertyDeclaration>node).initializer;
2276222770
}
2276322771

@@ -23415,6 +23423,9 @@ namespace ts {
2341523423

2341623424
function checkExportSpecifier(node: ExportSpecifier) {
2341723425
checkAliasSymbol(node);
23426+
if (compilerOptions.declaration) {
23427+
collectLinkedAliases(node.propertyName || node.name, /*setVisibility*/ true);
23428+
}
2341823429
if (!(<ExportDeclaration>node.parent.parent).moduleSpecifier) {
2341923430
const exportedName = node.propertyName || node.name;
2342023431
// find immediate value referenced by exported name (SymbolFlags.Alias is set so we don't chase down aliases)
@@ -23452,6 +23463,10 @@ namespace ts {
2345223463
}
2345323464
if (node.expression.kind === SyntaxKind.Identifier) {
2345423465
markExportAsReferenced(node);
23466+
23467+
if (compilerOptions.declaration) {
23468+
collectLinkedAliases(node.expression as Identifier, /*setVisibility*/ true);
23469+
}
2345523470
}
2345623471
else {
2345723472
checkExpressionCached(node.expression);
@@ -26193,6 +26208,10 @@ namespace ts {
2619326208
}
2619426209
}
2619526210

26211+
if (node.exclamationToken && (node.parent.parent.kind !== SyntaxKind.VariableStatement || !node.type || node.initializer || node.flags & NodeFlags.Ambient)) {
26212+
return grammarErrorOnNode(node.exclamationToken, Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context);
26213+
}
26214+
2619626215
if (compilerOptions.module !== ModuleKind.ES2015 && compilerOptions.module !== ModuleKind.ESNext && compilerOptions.module !== ModuleKind.System && !compilerOptions.noEmit &&
2619726216
!(node.parent.parent.flags & NodeFlags.Ambient) && hasModifier(node.parent.parent, ModifierFlags.Export)) {
2619826217
checkESModuleMarker(node.name);
@@ -26319,14 +26338,17 @@ namespace ts {
2631926338
}
2632026339

2632126340
function checkGrammarConstructorTypeParameters(node: ConstructorDeclaration) {
26322-
if (node.typeParameters) {
26323-
return grammarErrorAtPos(node, node.typeParameters.pos, node.typeParameters.end - node.typeParameters.pos, Diagnostics.Type_parameters_cannot_appear_on_a_constructor_declaration);
26341+
const typeParameters = getEffectiveTypeParameterDeclarations(node);
26342+
if (typeParameters) {
26343+
const { pos, end } = isNodeArray(typeParameters) ? typeParameters : first(typeParameters);
26344+
return grammarErrorAtPos(node, pos, end - pos, Diagnostics.Type_parameters_cannot_appear_on_a_constructor_declaration);
2632426345
}
2632526346
}
2632626347

2632726348
function checkGrammarConstructorTypeAnnotation(node: ConstructorDeclaration) {
26328-
if (node.type) {
26329-
return grammarErrorOnNode(node.type, Diagnostics.Type_annotation_cannot_appear_on_a_constructor_declaration);
26349+
const type = getEffectiveReturnTypeNode(node);
26350+
if (type) {
26351+
return grammarErrorOnNode(type, Diagnostics.Type_annotation_cannot_appear_on_a_constructor_declaration);
2633026352
}
2633126353
}
2633226354

@@ -26356,6 +26378,11 @@ namespace ts {
2635626378
if (node.flags & NodeFlags.Ambient && node.initializer) {
2635726379
return grammarErrorOnFirstToken(node.initializer, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
2635826380
}
26381+
26382+
if (node.exclamationToken && (!isClassLike(node.parent) || !node.type || node.initializer ||
26383+
node.flags & NodeFlags.Ambient || hasModifier(node, ModifierFlags.Static | ModifierFlags.Abstract))) {
26384+
return grammarErrorOnNode(node.exclamationToken, Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context);
26385+
}
2635926386
}
2636026387

2636126388
function checkGrammarTopLevelElementForRequiredDeclareModifier(node: Node): boolean {

src/compiler/core.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,10 +1260,12 @@ namespace ts {
12601260
return result;
12611261
}
12621262

1263-
export function arrayToNumericMap<T>(array: ReadonlyArray<T>, makeKey: (value: T) => number): T[] {
1264-
const result: T[] = [];
1263+
export function arrayToNumericMap<T>(array: ReadonlyArray<T>, makeKey: (value: T) => number): T[];
1264+
export function arrayToNumericMap<T, V>(array: ReadonlyArray<T>, makeKey: (value: T) => number, makeValue: (value: T) => V): V[];
1265+
export function arrayToNumericMap<T, V>(array: ReadonlyArray<T>, makeKey: (value: T) => number, makeValue?: (value: T) => V): V[] {
1266+
const result: V[] = [];
12651267
for (const value of array) {
1266-
result[makeKey(value)] = value;
1268+
result[makeKey(value)] = makeValue ? makeValue(value) : value as any as V;
12671269
}
12681270
return result;
12691271
}

src/compiler/declarationEmitter.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,10 +1249,18 @@ namespace ts {
12491249
writeLine();
12501250
}
12511251

1252+
function bindingNameContainsVisibleBindingElement(node: BindingName): boolean {
1253+
return !!node && isBindingPattern(node) && some(node.elements, elem => !isOmittedExpression(elem) && isVariableDeclarationVisible(elem));
1254+
}
1255+
1256+
function isVariableDeclarationVisible(node: VariableDeclaration | BindingElement) {
1257+
return resolver.isDeclarationVisible(node) || bindingNameContainsVisibleBindingElement(node.name);
1258+
}
1259+
12521260
function emitVariableDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration) {
12531261
// If we are emitting property it isn't moduleElement and hence we already know it needs to be emitted
12541262
// so there is no check needed to see if declaration is visible
1255-
if (node.kind !== SyntaxKind.VariableDeclaration || resolver.isDeclarationVisible(node)) {
1263+
if (node.kind !== SyntaxKind.VariableDeclaration || isVariableDeclarationVisible(node)) {
12561264
if (isBindingPattern(node.name)) {
12571265
emitBindingPattern(<BindingPattern>node.name);
12581266
}
@@ -1324,14 +1332,14 @@ namespace ts {
13241332
}
13251333

13261334
function emitBindingPattern(bindingPattern: BindingPattern) {
1327-
// Only select non-omitted expression from the bindingPattern's elements.
1335+
// Only select visible, non-omitted expression from the bindingPattern's elements.
13281336
// We have to do this to avoid emitting trailing commas.
13291337
// For example:
13301338
// original: var [, c,,] = [ 2,3,4]
13311339
// emitted: declare var c: number; // instead of declare var c:number, ;
13321340
const elements: Node[] = [];
13331341
for (const element of bindingPattern.elements) {
1334-
if (element.kind !== SyntaxKind.OmittedExpression) {
1342+
if (element.kind !== SyntaxKind.OmittedExpression && isVariableDeclarationVisible(element)) {
13351343
elements.push(element);
13361344
}
13371345
}
@@ -1371,7 +1379,7 @@ namespace ts {
13711379
}
13721380

13731381
function isVariableStatementVisible(node: VariableStatement) {
1374-
return forEach(node.declarationList.declarations, varDeclaration => resolver.isDeclarationVisible(varDeclaration));
1382+
return forEach(node.declarationList.declarations, varDeclaration => isVariableDeclarationVisible(varDeclaration));
13751383
}
13761384

13771385
function writeVariableStatement(node: VariableStatement) {
@@ -1390,7 +1398,7 @@ namespace ts {
13901398
else {
13911399
write("var ");
13921400
}
1393-
emitCommaList(node.declarationList.declarations, emitVariableDeclaration, resolver.isDeclarationVisible);
1401+
emitCommaList(node.declarationList.declarations, emitVariableDeclaration, isVariableDeclarationVisible);
13941402
write(";");
13951403
writeLine();
13961404
}

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,10 @@
831831
"category": "Error",
832832
"code": 1254
833833
},
834+
"A definite assignment assertion '!' is not permitted in this context.": {
835+
"category": "Error",
836+
"code": 1255
837+
},
834838
"'with' statements are not allowed in an async function block.": {
835839
"category": "Error",
836840
"code": 1300

src/compiler/parser.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ namespace ts {
9999
visitNode(cbNode, (<VariableLikeDeclaration>node).dotDotDotToken) ||
100100
visitNode(cbNode, (<VariableLikeDeclaration>node).name) ||
101101
visitNode(cbNode, (<VariableLikeDeclaration>node).questionToken) ||
102+
visitNode(cbNode, (<VariableLikeDeclaration>node).exclamationToken) ||
102103
visitNode(cbNode, (<VariableLikeDeclaration>node).type) ||
103104
visitNode(cbNode, (<VariableLikeDeclaration>node).initializer);
104105
case SyntaxKind.FunctionType:
@@ -5251,9 +5252,17 @@ namespace ts {
52515252
return parseIdentifier();
52525253
}
52535254

5254-
function parseVariableDeclaration(): VariableDeclaration {
5255+
function parseVariableDeclarationAllowExclamation() {
5256+
return parseVariableDeclaration(/*allowExclamation*/ true);
5257+
}
5258+
5259+
function parseVariableDeclaration(allowExclamation?: boolean): VariableDeclaration {
52555260
const node = <VariableDeclaration>createNode(SyntaxKind.VariableDeclaration);
52565261
node.name = parseIdentifierOrPattern();
5262+
if (allowExclamation && node.name.kind === SyntaxKind.Identifier &&
5263+
token() === SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak()) {
5264+
node.exclamationToken = parseTokenNode();
5265+
}
52575266
node.type = parseTypeAnnotation();
52585267
if (!isInOrOfKeyword(token())) {
52595268
node.initializer = parseInitializer();
@@ -5295,7 +5304,8 @@ namespace ts {
52955304
const savedDisallowIn = inDisallowInContext();
52965305
setDisallowInContext(inForStatementInitializer);
52975306

5298-
node.declarations = parseDelimitedList(ParsingContext.VariableDeclarations, parseVariableDeclaration);
5307+
node.declarations = parseDelimitedList(ParsingContext.VariableDeclarations,
5308+
inForStatementInitializer ? parseVariableDeclaration : parseVariableDeclarationAllowExclamation);
52995309

53005310
setDisallowInContext(savedDisallowIn);
53015311
}
@@ -5346,6 +5356,9 @@ namespace ts {
53465356

53475357
function parsePropertyDeclaration(node: PropertyDeclaration): PropertyDeclaration {
53485358
node.kind = SyntaxKind.PropertyDeclaration;
5359+
if (!node.questionToken && token() === SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak()) {
5360+
node.exclamationToken = parseTokenNode();
5361+
}
53495362
node.type = parseTypeAnnotation();
53505363

53515364
// For instance properties specifically, since they are evaluated inside the constructor,
@@ -6132,16 +6145,14 @@ namespace ts {
61326145
}
61336146

61346147
// Parses out a JSDoc type expression.
6135-
export function parseJSDocTypeExpression(): JSDocTypeExpression;
6136-
export function parseJSDocTypeExpression(requireBraces: true): JSDocTypeExpression | undefined;
6137-
export function parseJSDocTypeExpression(requireBraces?: boolean): JSDocTypeExpression | undefined {
6148+
export function parseJSDocTypeExpression(mayOmitBraces?: boolean): JSDocTypeExpression {
61386149
const result = <JSDocTypeExpression>createNode(SyntaxKind.JSDocTypeExpression, scanner.getTokenPos());
61396150

6140-
if (!parseExpected(SyntaxKind.OpenBraceToken) && requireBraces) {
6141-
return undefined;
6142-
}
6151+
const hasBrace = (mayOmitBraces ? parseOptional : parseExpected)(SyntaxKind.OpenBraceToken);
61436152
result.type = doInsideOfContext(NodeFlags.JSDoc, parseType);
6144-
parseExpected(SyntaxKind.CloseBraceToken);
6153+
if (!mayOmitBraces || hasBrace) {
6154+
parseExpected(SyntaxKind.CloseBraceToken);
6155+
}
61456156

61466157
fixupParentReferences(result);
61476158
return finishNode(result);
@@ -6597,7 +6608,7 @@ namespace ts {
65976608
const result = <JSDocTypeTag>createNode(SyntaxKind.JSDocTypeTag, atToken.pos);
65986609
result.atToken = atToken;
65996610
result.tagName = tagName;
6600-
result.typeExpression = parseJSDocTypeExpression(/*requireBraces*/ true);
6611+
result.typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true);
66016612
return finishNode(result);
66026613
}
66036614

src/compiler/scanner.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1873,14 +1873,25 @@ namespace ts {
18731873
return token = SyntaxKind.CommaToken;
18741874
case CharacterCodes.dot:
18751875
pos++;
1876+
if (text.substr(tokenPos, pos + 2) === "...") {
1877+
pos += 2;
1878+
return token = SyntaxKind.DotDotDotToken;
1879+
}
18761880
return token = SyntaxKind.DotToken;
1881+
case CharacterCodes.exclamation:
1882+
pos++;
1883+
return token = SyntaxKind.ExclamationToken;
1884+
case CharacterCodes.question:
1885+
pos++;
1886+
return token = SyntaxKind.QuestionToken;
18771887
}
18781888

18791889
if (isIdentifierStart(ch, ScriptTarget.Latest)) {
18801890
pos++;
18811891
while (isIdentifierPart(text.charCodeAt(pos), ScriptTarget.Latest) && pos < end) {
18821892
pos++;
18831893
}
1894+
tokenValue = text.substring(tokenPos, pos);
18841895
return token = SyntaxKind.Identifier;
18851896
}
18861897
else {

src/compiler/types.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,7 @@ namespace ts {
598598

599599
export type DotDotDotToken = Token<SyntaxKind.DotDotDotToken>;
600600
export type QuestionToken = Token<SyntaxKind.QuestionToken>;
601+
export type ExclamationToken = Token<SyntaxKind.ExclamationToken>;
601602
export type ColonToken = Token<SyntaxKind.ColonToken>;
602603
export type EqualsToken = Token<SyntaxKind.EqualsToken>;
603604
export type AsteriskToken = Token<SyntaxKind.AsteriskToken>;
@@ -761,9 +762,10 @@ namespace ts {
761762
export interface VariableDeclaration extends NamedDeclaration {
762763
kind: SyntaxKind.VariableDeclaration;
763764
parent?: VariableDeclarationList | CatchClause;
764-
name: BindingName; // Declared variable name
765-
type?: TypeNode; // Optional type annotation
766-
initializer?: Expression; // Optional initializer
765+
name: BindingName; // Declared variable name
766+
exclamationToken?: ExclamationToken; // Optional definite assignment assertion
767+
type?: TypeNode; // Optional type annotation
768+
initializer?: Expression; // Optional initializer
767769
}
768770

769771
export interface VariableDeclarationList extends Node {
@@ -801,8 +803,9 @@ namespace ts {
801803

802804
export interface PropertyDeclaration extends ClassElement, JSDocContainer {
803805
kind: SyntaxKind.PropertyDeclaration;
804-
questionToken?: QuestionToken; // Present for use with reporting a grammar error
805806
name: PropertyName;
807+
questionToken?: QuestionToken; // Present for use with reporting a grammar error
808+
exclamationToken?: ExclamationToken;
806809
type?: TypeNode;
807810
initializer?: Expression; // Optional initializer
808811
}
@@ -860,6 +863,7 @@ namespace ts {
860863
dotDotDotToken?: DotDotDotToken;
861864
name: DeclarationName;
862865
questionToken?: QuestionToken;
866+
exclamationToken?: ExclamationToken;
863867
type?: TypeNode;
864868
initializer?: Expression;
865869
}

0 commit comments

Comments
 (0)