Enable '--strictNullChecks' (#22088)

* Enable '--strictNullChecks'

* Fix API baselines

* Make sys.getEnvironmentVariable non-nullable

* make properties optional instead of using `| undefined` in thier type

* reportDiagnostics should be required

* Declare firstAccessor as non-nullable

* Make `some` a type guard

* Fix `getEnvironmentVariable` definition in tests

* Pretend transformFlags are always defined

* Fix one more use of sys.getEnvironmentVariable

* `requiredResponse` accepts undefined, remove assertions

* Mark optional properties as optional instead of using `| undefined`

* Mark optional properties as optional instead of using ` | undefined`

* Remove unnecessary null assertions

* Put the bang on the declaration instead of every use

* Make `createMapFromTemplate` require a parameter

* Mark `EmitResult.emittedFiles` and `EmitResult.sourceMaps` as optional

* Plumb through undefined in emitLsit and EmitExpressionList

* `ElementAccessExpression.argumentExpression` can not be `undefined`

* Add overloads for `writeTokenText`

* Make `shouldWriteSeparatingLineTerminator` argument non-nullable

* Make `synthesizedNodeStartsOnNewLine` argument required

* `PropertyAssignment.initializer` cannot be undefined

* Use one `!` at declaration site instead of on every use site

* Capture host in a constant and avoid null assertions

* Remove few more unused assertions

* Update baselines

* Use parameter defaults

* Update baselines

* Fix lint

* Make Symbol#valueDeclaration and Symbol#declarations non-optional to reduce assertions

* Make Node#symbol and Type#symbol non-optional to reduce assertions

* Make `flags` non-nullable to reduce assertions

* Convert some asserts to type guards

* Make `isNonLocalAlias` a type guard

* Add overload for `getSymbolOfNode` for `Declaration`

* Some more `getSymbolOfNode` changes

* Push undefined suppression into `typeToTypeNodeHelper`

* `NodeBuilderContext.tracker` is never `undefined`

* use `Debug.assertDefined`

* Remove unnecessary tag

* Mark `LiteralType.freshType` and `LiteralTupe.regularType` as required
This commit is contained in:
Andy
2018-05-22 14:46:57 -07:00
committed by GitHub
parent 3fe946df78
commit e53e56cf82
167 changed files with 4846 additions and 4735 deletions

View File

@@ -10,10 +10,10 @@ namespace ts {
}
// tslint:disable variable-name
let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
let TokenConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
let IdentifierConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
let SourceFileConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
let NodeConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node;
let TokenConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node;
let IdentifierConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node;
let SourceFileConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node;
// tslint:enable variable-name
export function createNode(kind: SyntaxKind, pos?: number, end?: number): Node {
@@ -31,11 +31,11 @@ namespace ts {
}
}
function visitNode<T>(cbNode: (node: Node) => T, node: Node): T | undefined {
function visitNode<T>(cbNode: (node: Node) => T, node: Node | undefined): T | undefined {
return node && cbNode(node);
}
function visitNodes<T>(cbNode: (node: Node) => T, cbNodes: (node: NodeArray<Node>) => T | undefined, nodes: NodeArray<Node>): T | undefined {
function visitNodes<T>(cbNode: (node: Node) => T, cbNodes: ((node: NodeArray<Node>) => T | undefined) | undefined, nodes: NodeArray<Node> | undefined): T | undefined {
if (nodes) {
if (cbNodes) {
return cbNodes(nodes);
@@ -481,7 +481,7 @@ namespace ts {
return visitNodes(cbNode, cbNodes, (<JSDocTemplateTag>node).typeParameters);
case SyntaxKind.JSDocTypedefTag:
if ((node as JSDocTypedefTag).typeExpression &&
(node as JSDocTypedefTag).typeExpression.kind === SyntaxKind.JSDocTypeExpression) {
(node as JSDocTypedefTag).typeExpression!.kind === SyntaxKind.JSDocTypeExpression) {
return visitNode(cbNode, (<JSDocTypedefTag>node).typeExpression) ||
visitNode(cbNode, (<JSDocTypedefTag>node).fullName);
}
@@ -500,7 +500,7 @@ namespace ts {
visitNode(cbNode, (<SignatureDeclaration>node).type);
case SyntaxKind.JSDocTypeLiteral:
if ((node as JSDocTypeLiteral).jsDocPropertyTags) {
for (const tag of (node as JSDocTypeLiteral).jsDocPropertyTags) {
for (const tag of (node as JSDocTypeLiteral).jsDocPropertyTags!) {
visitNode(cbNode, tag);
}
}
@@ -524,7 +524,7 @@ namespace ts {
return result;
}
export function parseIsolatedEntityName(text: string, languageVersion: ScriptTarget): EntityName {
export function parseIsolatedEntityName(text: string, languageVersion: ScriptTarget): EntityName | undefined {
return Parser.parseIsolatedEntityName(text, languageVersion);
}
@@ -551,7 +551,7 @@ namespace ts {
// from this SourceFile that are being held onto may change as a result (including
// becoming detached from any SourceFile). It is recommended that this SourceFile not
// be used once 'update' is called on it.
export function updateSourceFile(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks?: boolean): SourceFile {
export function updateSourceFile(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks = false): SourceFile {
const newSourceFile = IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks);
// Because new source file node is created, it may not have the flag PossiblyContainDynamicImport. This is the case if there is no new edit to add dynamic import.
// We will manually port the flag to the new source file.
@@ -596,7 +596,7 @@ namespace ts {
let sourceFile: SourceFile;
let parseDiagnostics: DiagnosticWithLocation[];
let syntaxCursor: IncrementalParser.SyntaxCursor;
let syntaxCursor: IncrementalParser.SyntaxCursor | undefined;
let currentToken: SyntaxKind;
let sourceText: string;
@@ -683,7 +683,7 @@ namespace ts {
// attached to the EOF token.
let parseErrorBeforeNextFinishedNode = false;
export function parseSourceFile(fileName: string, sourceText: string, languageVersion: ScriptTarget, syntaxCursor: IncrementalParser.SyntaxCursor, setParentNodes?: boolean, scriptKind?: ScriptKind): SourceFile {
export function parseSourceFile(fileName: string, sourceText: string, languageVersion: ScriptTarget, syntaxCursor: IncrementalParser.SyntaxCursor | undefined, setParentNodes = false, scriptKind?: ScriptKind): SourceFile {
scriptKind = ensureScriptKind(fileName, scriptKind);
if (scriptKind === ScriptKind.JSON) {
const result = parseJsonText(fileName, sourceText, languageVersion, syntaxCursor, setParentNodes);
@@ -702,7 +702,7 @@ namespace ts {
return result;
}
export function parseIsolatedEntityName(content: string, languageVersion: ScriptTarget): EntityName {
export function parseIsolatedEntityName(content: string, languageVersion: ScriptTarget): EntityName | undefined {
// Choice of `isDeclarationFile` should be arbitrary
initializeState(content, languageVersion, /*syntaxCursor*/ undefined, ScriptKind.JS);
// Prime the scanner.
@@ -775,7 +775,7 @@ namespace ts {
return scriptKind === ScriptKind.TSX || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSON ? LanguageVariant.JSX : LanguageVariant.Standard;
}
function initializeState(_sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, scriptKind: ScriptKind) {
function initializeState(_sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor | undefined, scriptKind: ScriptKind) {
NodeConstructor = objectAllocator.getNodeConstructor();
TokenConstructor = objectAllocator.getTokenConstructor();
IdentifierConstructor = objectAllocator.getIdentifierConstructor();
@@ -817,11 +817,11 @@ namespace ts {
scanner.setOnError(undefined);
// Clear any data. We don't want to accidentally hold onto it for too long.
parseDiagnostics = undefined;
sourceFile = undefined;
identifiers = undefined;
parseDiagnostics = undefined!;
sourceFile = undefined!;
identifiers = undefined!;
syntaxCursor = undefined;
sourceText = undefined;
sourceText = undefined!;
}
function parseSourceFileWorker(fileName: string, languageVersion: ScriptTarget, setParentNodes: boolean, scriptKind: ScriptKind): SourceFile {
@@ -865,7 +865,7 @@ namespace ts {
const comments = getJSDocCommentRanges(node, sourceFile.text);
if (comments) {
for (const comment of comments) {
node.jsDoc = append(node.jsDoc, JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos));
node.jsDoc = append<JSDoc>(node.jsDoc, JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos));
}
}
@@ -893,7 +893,7 @@ namespace ts {
parent = n;
forEachChild(n, visitNode);
if (hasJSDocNodes(n)) {
for (const jsDoc of n.jsDoc) {
for (const jsDoc of n.jsDoc!) {
jsDoc.parent = n;
parent = jsDoc;
forEachChild(jsDoc, visitNode);
@@ -1205,7 +1205,7 @@ namespace ts {
}
function parseOptionalToken<TKind extends SyntaxKind>(t: TKind): Token<TKind>;
function parseOptionalToken(t: SyntaxKind): Node {
function parseOptionalToken(t: SyntaxKind): Node | undefined {
if (token() === t) {
return parseTokenNode();
}
@@ -1250,7 +1250,7 @@ namespace ts {
function createNode(kind: SyntaxKind, pos?: number): Node {
nodeCount++;
const p = pos >= 0 ? pos : scanner.getStartPos();
const p = pos! >= 0 ? pos! : scanner.getStartPos();
return isNodeKind(kind) || kind === SyntaxKind.Unknown ? new NodeConstructor(kind, p, p) :
kind === SyntaxKind.Identifier ? new IdentifierConstructor(kind, p, p) :
new TokenConstructor(kind, p, p);
@@ -1527,7 +1527,7 @@ namespace ts {
return true;
}
Debug.fail("Non-exhaustive case in 'isListElement'.");
return Debug.fail("Non-exhaustive case in 'isListElement'.");
}
function isValidHeritageClauseObjectLiteral() {
@@ -1629,6 +1629,8 @@ namespace ts {
return token() === SyntaxKind.GreaterThanToken || token() === SyntaxKind.SlashToken;
case ParsingContext.JsxChildren:
return token() === SyntaxKind.LessThanToken && lookAhead(nextTokenIsSlash);
default:
return false;
}
}
@@ -1703,7 +1705,7 @@ namespace ts {
return parseElement();
}
function currentNode(parsingContext: ParsingContext): Node {
function currentNode(parsingContext: ParsingContext): Node | undefined {
// If there is an outstanding parse error that we've encountered, but not attached to
// some node, then we cannot get a node from the old source tree. This is because we
// want to mark the next node we encounter as being unusable.
@@ -2019,6 +2021,7 @@ namespace ts {
case ParsingContext.ImportOrExportSpecifiers: return Diagnostics.Identifier_expected;
case ParsingContext.JsxAttributes: return Diagnostics.Identifier_expected;
case ParsingContext.JsxChildren: return Diagnostics.Identifier_expected;
default: return undefined!; // TODO: GH#18217 `default: Debug.assertNever(context);`
}
}
@@ -2173,7 +2176,7 @@ namespace ts {
do {
list.push(parseTemplateSpan());
}
while (lastOrUndefined(list).literal.kind === SyntaxKind.TemplateMiddle);
while (last(list).literal.kind === SyntaxKind.TemplateMiddle);
template.templateSpans = createNodeArray(list, listPos);
@@ -2396,7 +2399,7 @@ namespace ts {
}
}
function parseParameterType(): TypeNode {
function parseParameterType(): TypeNode | undefined {
if (parseOptional(SyntaxKind.ColonToken)) {
return parseType();
}
@@ -2456,7 +2459,7 @@ namespace ts {
if (!(flags & SignatureFlags.JSDoc)) {
signature.typeParameters = parseTypeParameters();
}
signature.parameters = parseParameterList(flags);
signature.parameters = parseParameterList(flags)!; // TODO: GH#18217
if (shouldParseReturnType(returnToken, !!(flags & SignatureFlags.Type))) {
signature.type = parseTypeOrTypePredicate();
return signature.type !== undefined;
@@ -2638,7 +2641,7 @@ namespace ts {
if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) {
return true;
}
let idToken: boolean;
let idToken = false;
// Eat up all modifiers, but hold on to the last one in case it is actually an identifier
while (isModifierKind(token())) {
idToken = true;
@@ -2742,7 +2745,7 @@ namespace ts {
const node = <MappedTypeNode>createNode(SyntaxKind.MappedType);
parseExpected(SyntaxKind.OpenBraceToken);
if (token() === SyntaxKind.ReadonlyKeyword || token() === SyntaxKind.PlusToken || token() === SyntaxKind.MinusToken) {
node.readonlyToken = parseTokenNode();
node.readonlyToken = parseTokenNode<ReadonlyToken | PlusToken | MinusToken>();
if (node.readonlyToken.kind !== SyntaxKind.ReadonlyKeyword) {
parseExpectedToken(SyntaxKind.ReadonlyKeyword);
}
@@ -2751,7 +2754,7 @@ namespace ts {
node.typeParameter = parseMappedTypeParameter();
parseExpected(SyntaxKind.CloseBracketToken);
if (token() === SyntaxKind.QuestionToken || token() === SyntaxKind.PlusToken || token() === SyntaxKind.MinusToken) {
node.questionToken = parseTokenNode();
node.questionToken = parseTokenNode<QuestionToken | PlusToken | MinusToken>();
if (node.questionToken.kind !== SyntaxKind.QuestionToken) {
parseExpectedToken(SyntaxKind.QuestionToken);
}
@@ -2773,13 +2776,13 @@ namespace ts {
parseExpected(SyntaxKind.OpenParenToken);
node.type = parseType();
if (!node.type) {
return undefined;
return undefined!; // TODO: GH#18217
}
parseExpected(SyntaxKind.CloseParenToken);
return finishNode(node);
}
function parseFunctionOrConstructorType(kind: SyntaxKind): FunctionOrConstructorTypeNode {
function parseFunctionOrConstructorType(kind: SyntaxKind): FunctionOrConstructorTypeNode | undefined {
const node = <FunctionOrConstructorTypeNode>createNodeWithJSDoc(kind);
if (kind === SyntaxKind.ConstructorType) {
parseExpected(SyntaxKind.NewKeyword);
@@ -2800,7 +2803,7 @@ namespace ts {
function parseLiteralTypeNode(negative?: boolean): LiteralTypeNode {
const node = createNode(SyntaxKind.LiteralType) as LiteralTypeNode;
let unaryMinusExpression: PrefixUnaryExpression;
let unaryMinusExpression!: PrefixUnaryExpression;
if (negative) {
unaryMinusExpression = createNode(SyntaxKind.PrefixUnaryExpression) as PrefixUnaryExpression;
unaryMinusExpression.operator = SyntaxKind.MinusToken;
@@ -3129,10 +3132,10 @@ namespace ts {
function parseTypeWorker(noConditionalTypes?: boolean): TypeNode {
if (isStartOfFunctionType()) {
return parseFunctionOrConstructorType(SyntaxKind.FunctionType);
return parseFunctionOrConstructorType(SyntaxKind.FunctionType)!; // TODO: GH#18217
}
if (token() === SyntaxKind.NewKeyword) {
return parseFunctionOrConstructorType(SyntaxKind.ConstructorType);
return parseFunctionOrConstructorType(SyntaxKind.ConstructorType)!;
}
const type = parseUnionTypeOrHigher();
if (!noConditionalTypes && !scanner.hasPrecedingLineBreak() && parseOptional(SyntaxKind.ExtendsKeyword)) {
@@ -3149,7 +3152,7 @@ namespace ts {
return type;
}
function parseTypeAnnotation(): TypeNode {
function parseTypeAnnotation(): TypeNode | undefined {
return parseOptional(SyntaxKind.ColonToken) ? parseType() : undefined;
}
@@ -3373,7 +3376,7 @@ namespace ts {
}
}
function parseSimpleArrowFunctionExpression(identifier: Identifier, asyncModifier?: NodeArray<Modifier>): ArrowFunction {
function parseSimpleArrowFunctionExpression(identifier: Identifier, asyncModifier?: NodeArray<Modifier> | undefined): ArrowFunction {
Debug.assert(token() === SyntaxKind.EqualsGreaterThanToken, "parseSimpleArrowFunctionExpression should only have been called if we had a =>");
let node: ArrowFunction;
@@ -3572,7 +3575,7 @@ namespace ts {
}
}
function parsePossibleParenthesizedArrowFunctionExpressionHead(): ArrowFunction {
function parsePossibleParenthesizedArrowFunctionExpressionHead(): ArrowFunction | undefined {
return parseParenthesizedArrowFunctionExpressionHead(/*allowAmbiguity*/ false);
}
@@ -3609,7 +3612,7 @@ namespace ts {
return Tristate.False;
}
function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity: boolean): ArrowFunction {
function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity: boolean): ArrowFunction | undefined {
const node = <ArrowFunction>createNodeWithJSDoc(SyntaxKind.ArrowFunction);
node.modifiers = parseModifiersForArrowFunction();
const isAsync = hasModifier(node, ModifierFlags.Async) ? SignatureFlags.Await : SignatureFlags.None;
@@ -4208,7 +4211,7 @@ namespace ts {
badNode.end = invalidElement.end;
badNode.left = result;
badNode.right = invalidElement;
badNode.operatorToken = createMissingNode(SyntaxKind.CommaToken, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined);
badNode.operatorToken = createMissingNode(SyntaxKind.CommaToken, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined!); // TODO: GH#18217
badNode.operatorToken.pos = badNode.operatorToken.end = badNode.right.pos;
return <JsxElement><Node>badNode;
}
@@ -4902,7 +4905,7 @@ namespace ts {
const awaitToken = parseOptionalToken(SyntaxKind.AwaitKeyword);
parseExpected(SyntaxKind.OpenParenToken);
let initializer: VariableDeclarationList | Expression;
let initializer!: VariableDeclarationList | Expression;
if (token() !== SyntaxKind.SemicolonToken) {
if (token() === SyntaxKind.VarKeyword || token() === SyntaxKind.LetKeyword || token() === SyntaxKind.ConstKeyword) {
initializer = parseVariableDeclarationList(/*inForStatementInitializer*/ true);
@@ -5345,7 +5348,7 @@ namespace ts {
node.decorators = parseDecorators();
node.modifiers = parseModifiers();
if (some(node.modifiers, isDeclareModifier)) {
for (const m of node.modifiers) {
for (const m of node.modifiers!) {
m.flags |= NodeFlags.Ambient;
}
return doInsideOfContext(NodeFlags.Ambient, () => parseDeclarationWorker(node));
@@ -5398,6 +5401,7 @@ namespace ts {
missing.modifiers = node.modifiers;
return finishNode(missing);
}
return undefined!; // TODO: GH#18217
}
}
@@ -5406,7 +5410,7 @@ namespace ts {
return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token() === SyntaxKind.StringLiteral);
}
function parseFunctionBlockOrSemicolon(flags: SignatureFlags, diagnosticMessage?: DiagnosticMessage): Block {
function parseFunctionBlockOrSemicolon(flags: SignatureFlags, diagnosticMessage?: DiagnosticMessage): Block | undefined {
if (token() !== SyntaxKind.OpenBraceToken && canParseSemicolon()) {
parseSemicolon();
return;
@@ -5484,7 +5488,7 @@ namespace ts {
node.name = parseIdentifierOrPattern();
if (allowExclamation && node.name.kind === SyntaxKind.Identifier &&
token() === SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak()) {
node.exclamationToken = parseTokenNode();
node.exclamationToken = parseTokenNode<Token<SyntaxKind.ExclamationToken>>();
}
node.type = parseTypeAnnotation();
if (!isInOrOfKeyword(token())) {
@@ -5580,7 +5584,7 @@ namespace ts {
function parsePropertyDeclaration(node: PropertyDeclaration): PropertyDeclaration {
node.kind = SyntaxKind.PropertyDeclaration;
if (!node.questionToken && token() === SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak()) {
node.exclamationToken = parseTokenNode();
node.exclamationToken = parseTokenNode<Token<SyntaxKind.ExclamationToken>>();
}
node.type = parseTypeAnnotation();
@@ -5622,7 +5626,7 @@ namespace ts {
}
function isClassMemberStart(): boolean {
let idToken: SyntaxKind;
let idToken: SyntaxKind | undefined;
if (token() === SyntaxKind.AtToken) {
return true;
@@ -5714,7 +5718,7 @@ namespace ts {
* In such situations, 'permitInvalidConstAsModifier' should be set to true.
*/
function parseModifiers(permitInvalidConstAsModifier?: boolean): NodeArray<Modifier> | undefined {
let list: Modifier[];
let list: Modifier[] | undefined;
const listPos = getNodePos();
while (true) {
const modifierStart = scanner.getStartPos();
@@ -5739,8 +5743,8 @@ namespace ts {
return list && createNodeArray(list, listPos);
}
function parseModifiersForArrowFunction(): NodeArray<Modifier> {
let modifiers: NodeArray<Modifier>;
function parseModifiersForArrowFunction(): NodeArray<Modifier> | undefined {
let modifiers: NodeArray<Modifier> | undefined;
if (token() === SyntaxKind.AsyncKeyword) {
const modifierStart = scanner.getStartPos();
const modifierKind = token();
@@ -5796,7 +5800,7 @@ namespace ts {
}
// 'isClassMemberStart' should have hinted not to attempt parsing.
Debug.fail("Should not have attempted to parse class member declaration.");
return Debug.fail("Should not have attempted to parse class member declaration.");
}
function parseClassExpression(): ClassExpression {
@@ -5853,17 +5857,14 @@ namespace ts {
return undefined;
}
function parseHeritageClause(): HeritageClause | undefined {
function parseHeritageClause(): HeritageClause {
const tok = token();
if (tok === SyntaxKind.ExtendsKeyword || tok === SyntaxKind.ImplementsKeyword) {
const node = <HeritageClause>createNode(SyntaxKind.HeritageClause);
node.token = tok;
nextToken();
node.types = parseDelimitedList(ParsingContext.HeritageClauseElement, parseExpressionWithTypeArguments);
return finishNode(node);
}
return undefined;
Debug.assert(tok === SyntaxKind.ExtendsKeyword || tok === SyntaxKind.ImplementsKeyword); // isListElement() should ensure this.
const node = <HeritageClause>createNode(SyntaxKind.HeritageClause);
node.token = tok as SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword;
nextToken();
node.types = parseDelimitedList(ParsingContext.HeritageClauseElement, parseExpressionWithTypeArguments);
return finishNode(node);
}
function parseExpressionWithTypeArguments(): ExpressionWithTypeArguments {
@@ -6022,7 +6023,7 @@ namespace ts {
parseExpected(SyntaxKind.ImportKeyword);
const afterImportPos = scanner.getStartPos();
let identifier: Identifier;
let identifier: Identifier | undefined;
if (isIdentifier()) {
identifier = parseIdentifier();
if (token() !== SyntaxKind.CommaToken && token() !== SyntaxKind.FromKeyword) {
@@ -6056,7 +6057,7 @@ namespace ts {
return finishNode(node);
}
function parseImportClause(identifier: Identifier, fullStart: number) {
function parseImportClause(identifier: Identifier | undefined, fullStart: number) {
// ImportClause:
// ImportedDefaultBinding
// NameSpaceImport
@@ -6233,7 +6234,7 @@ namespace ts {
undefined;
}
function walkTreeForExternalModuleIndicators(node: Node): Node {
function walkTreeForExternalModuleIndicators(node: Node): Node | undefined {
return isImportMeta(node) ? node : forEachChild(node, walkTreeForExternalModuleIndicators);
}
@@ -6275,7 +6276,7 @@ namespace ts {
}
export namespace JSDocParser {
export function parseJSDocTypeExpressionForTests(content: string, start: number, length: number): { jsDocTypeExpression: JSDocTypeExpression, diagnostics: Diagnostic[] } | undefined {
export function parseJSDocTypeExpressionForTests(content: string, start: number | undefined, length: number | undefined): { jsDocTypeExpression: JSDocTypeExpression, diagnostics: Diagnostic[] } | undefined {
initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS);
sourceFile = createSourceFile("file.js", ScriptTarget.Latest, ScriptKind.JS, /*isDeclarationFile*/ false);
scanner.setText(content, start, length);
@@ -6301,7 +6302,7 @@ namespace ts {
return finishNode(result);
}
export function parseIsolatedJSDocComment(content: string, start: number, length: number): { jsDoc: JSDoc, diagnostics: Diagnostic[] } | undefined {
export function parseIsolatedJSDocComment(content: string, start: number | undefined, length: number | undefined): { jsDoc: JSDoc, diagnostics: Diagnostic[] } | undefined {
initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS);
sourceFile = <SourceFile>{ languageVariant: LanguageVariant.Standard, text: content }; // tslint:disable-line no-object-literal-type-assertion
const jsDoc = parseJSDocCommentWorker(start, length);
@@ -6311,7 +6312,7 @@ namespace ts {
return jsDoc ? { jsDoc, diagnostics } : undefined;
}
export function parseJSDocComment(parent: HasJSDoc, start: number, length: number): JSDoc {
export function parseJSDocComment(parent: HasJSDoc, start: number, length: number): JSDoc | undefined {
const saveToken = currentToken;
const saveParseDiagnosticsLength = parseDiagnostics.length;
const saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode;
@@ -6346,9 +6347,8 @@ namespace ts {
CallbackParameter = 1 << 2,
}
export function parseJSDocCommentWorker(start: number, length: number): JSDoc {
export function parseJSDocCommentWorker(start = 0, length: number | undefined): JSDoc | undefined {
const content = sourceText;
start = start || 0;
const end = length === undefined ? content.length : start + length;
length = end - start;
@@ -6360,7 +6360,7 @@ namespace ts {
let tagsPos: number;
let tagsEnd: number;
const comments: string[] = [];
let result: JSDoc;
let result: JSDoc | undefined;
// Check for /** (JSDoc opening part)
if (!isJSDocLikeText(content, start)) {
@@ -6518,7 +6518,7 @@ namespace ts {
return;
}
let tag: JSDocTag;
let tag: JSDocTag | undefined;
if (tagName) {
switch (tagName.escapedText) {
case "augments":
@@ -6638,7 +6638,7 @@ namespace ts {
return finishNode(result);
}
function addTag(tag: JSDocTag): void {
function addTag(tag: JSDocTag | undefined): void {
if (!tag) {
return;
}
@@ -6722,13 +6722,13 @@ namespace ts {
return finishNode(result);
}
function parseNestedTypeLiteral(typeExpression: JSDocTypeExpression, name: EntityName, target: PropertyLikeParse) {
function parseNestedTypeLiteral(typeExpression: JSDocTypeExpression | undefined, name: EntityName, target: PropertyLikeParse) {
if (typeExpression && isObjectOrObjectArrayTypeReference(typeExpression.type)) {
const typeLiteralExpression = <JSDocTypeExpression>createNode(SyntaxKind.JSDocTypeExpression, scanner.getTokenPos());
let child: JSDocPropertyLikeTag | JSDocTypeTag | false;
let jsdocTypeLiteral: JSDocTypeLiteral;
const start = scanner.getStartPos();
let children: JSDocPropertyLikeTag[];
let children: JSDocPropertyLikeTag[] | undefined;
while (child = tryParse(() => parseChildParameterOrPropertyTag(target, name))) {
if (child.kind === SyntaxKind.JSDocParameterTag || child.kind === SyntaxKind.JSDocPropertyTag) {
children = append(children, child);
@@ -6795,7 +6795,7 @@ namespace ts {
while (parseOptional(SyntaxKind.DotToken)) {
const prop: PropertyAccessEntityNameExpression = createNode(SyntaxKind.PropertyAccessExpression, node.pos) as PropertyAccessEntityNameExpression;
prop.expression = node;
prop.name = parseJSDocIdentifierName();
prop.name = parseJSDocIdentifierName()!; // TODO: GH#18217
node = finishNode(prop);
}
return node;
@@ -6821,11 +6821,11 @@ namespace ts {
typedefTag.comment = parseTagComments(indent);
typedefTag.typeExpression = typeExpression;
let end: number;
let end: number | undefined;
if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) {
let child: JSDocTypeTag | JSDocPropertyTag | false;
let jsdocTypeLiteral: JSDocTypeLiteral;
let childTypeTag: JSDocTypeTag;
let jsdocTypeLiteral: JSDocTypeLiteral | undefined;
let childTypeTag: JSDocTypeTag | undefined;
const start = scanner.getStartPos();
while (child = tryParse(() => parseChildPropertyTag())) {
if (!jsdocTypeLiteral) {
@@ -6949,7 +6949,7 @@ namespace ts {
const child = tryParseChildTag(target);
if (child && child.kind === SyntaxKind.JSDocParameterTag &&
target !== PropertyLikeParse.CallbackParameter &&
(ts.isIdentifier(child.name) || !escapedTextsEqual(name, child.name.left))) {
(ts.isIdentifier(child.name) || !escapedTextsEqual(name!, child.name.left))) { // TODO: GH#18217
return false;
}
return child;
@@ -7219,7 +7219,7 @@ namespace ts {
forEachChild(node, visitNode, visitArray);
if (hasJSDocNodes(node)) {
for (const jsDocComment of node.jsDoc) {
for (const jsDocComment of node.jsDoc!) {
visitNode(<IncrementalNode><Node>jsDocComment);
}
}
@@ -7331,7 +7331,7 @@ namespace ts {
pos = child.end;
};
if (hasJSDocNodes(node)) {
for (const jsDocComment of node.jsDoc) {
for (const jsDocComment of node.jsDoc!) {
visitNode(jsDocComment);
}
}
@@ -7374,7 +7374,7 @@ namespace ts {
adjustIntersectingElement(child, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
forEachChild(child, visitNode, visitArray);
if (hasJSDocNodes(child)) {
for (const jsDocComment of child.jsDoc) {
for (const jsDocComment of child.jsDoc!) {
visitNode(<IncrementalNode><Node>jsDocComment);
}
}
@@ -7450,7 +7450,7 @@ namespace ts {
function findNearestNodeStartingBeforeOrAtPosition(sourceFile: SourceFile, position: number): Node {
let bestResult: Node = sourceFile;
let lastNodeEntirelyBeforePosition: Node;
let lastNodeEntirelyBeforePosition: Node | undefined;
forEachChild(sourceFile, visit);
@@ -7551,10 +7551,10 @@ namespace ts {
}
interface IncrementalElement extends TextRange {
parent?: Node;
parent: Node;
intersectsChange: boolean;
length?: number;
_children: Node[];
_children: Node[] | undefined;
}
export interface IncrementalNode extends Node, IncrementalElement {
@@ -7620,9 +7620,9 @@ namespace ts {
// return it, we can easily return its next sibling in the list.
function findHighestListElementThatStartsAtPosition(position: number) {
// Clear out any cached state about the last node we found.
currentArray = undefined;
currentArray = undefined!;
currentArrayIndex = InvalidPosition.Value;
current = undefined;
current = undefined!;
// Recurse into the source file to find the highest node at this position.
forEachChild(sourceFile, visitNode, visitArray);
@@ -7720,17 +7720,17 @@ namespace ts {
context.pragmas = createMap() as PragmaMap;
for (const pragma of pragmas) {
if (context.pragmas.has(pragma.name)) {
const currentValue = context.pragmas.get(pragma.name);
if (context.pragmas.has(pragma!.name)) { // TODO: GH#18217
const currentValue = context.pragmas.get(pragma!.name);
if (currentValue instanceof Array) {
currentValue.push(pragma.args);
currentValue.push(pragma!.args);
}
else {
context.pragmas.set(pragma.name, [currentValue, pragma.args]);
context.pragmas.set(pragma!.name, [currentValue, pragma!.args]);
}
continue;
}
context.pragmas.set(pragma.name, pragma.args);
context.pragmas.set(pragma!.name, pragma!.args);
}
}
@@ -7744,7 +7744,7 @@ namespace ts {
context.typeReferenceDirectives = [];
context.amdDependencies = [];
context.hasNoDefaultLib = false;
context.pragmas.forEach((entryOrList, key) => {
context.pragmas!.forEach((entryOrList, key) => { // TODO: GH#18217
// TODO: The below should be strongly type-guarded and not need casts/explicit annotations, since entryOrList is related to
// key and key is constrained to a union; but it's not (see GH#21483 for at least partial fix) :(
switch (key) {
@@ -7752,17 +7752,18 @@ namespace ts {
const referencedFiles = context.referencedFiles;
const typeReferenceDirectives = context.typeReferenceDirectives;
forEach(toArray(entryOrList), (arg: PragmaPsuedoMap["reference"]) => {
if (arg.arguments["no-default-lib"]) {
// TODO: GH#18217
if (arg!.arguments["no-default-lib"]) {
context.hasNoDefaultLib = true;
}
else if (arg.arguments.types) {
typeReferenceDirectives.push({ pos: arg.arguments.types.pos, end: arg.arguments.types.end, fileName: arg.arguments.types.value });
else if (arg!.arguments.types) {
typeReferenceDirectives.push({ pos: arg!.arguments.types!.pos, end: arg!.arguments.types!.end, fileName: arg!.arguments.types!.value });
}
else if (arg.arguments.path) {
referencedFiles.push({ pos: arg.arguments.path.pos, end: arg.arguments.path.end, fileName: arg.arguments.path.value });
else if (arg!.arguments.path) {
referencedFiles.push({ pos: arg!.arguments.path!.pos, end: arg!.arguments.path!.end, fileName: arg!.arguments.path!.value });
}
else {
reportDiagnostic(arg.range.pos, arg.range.end - arg.range.pos, Diagnostics.Invalid_reference_directive_syntax);
reportDiagnostic(arg!.range.pos, arg!.range.end - arg!.range.pos, Diagnostics.Invalid_reference_directive_syntax);
}
});
break;
@@ -7770,8 +7771,7 @@ namespace ts {
case "amd-dependency": {
context.amdDependencies = map(
toArray(entryOrList),
({ arguments: { name, path } }: PragmaPsuedoMap["amd-dependency"]) => ({ name, path })
);
(x: PragmaPsuedoMap["amd-dependency"]) => ({ name: x!.arguments.name!, path: x!.arguments.path })); // TODO: GH#18217
break;
}
case "amd-module": {
@@ -7779,13 +7779,13 @@ namespace ts {
for (const entry of entryOrList) {
if (context.moduleName) {
// TODO: It's probably fine to issue this diagnostic on all instances of the pragma
reportDiagnostic(entry.range.pos, entry.range.end - entry.range.pos, Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments);
reportDiagnostic(entry!.range.pos, entry!.range.end - entry!.range.pos, Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments);
}
context.moduleName = (entry as PragmaPsuedoMap["amd-module"]).arguments.name;
context.moduleName = (entry as PragmaPsuedoMap["amd-module"])!.arguments.name;
}
}
else {
context.moduleName = (entryOrList as PragmaPsuedoMap["amd-module"]).arguments.name;
context.moduleName = (entryOrList as PragmaPsuedoMap["amd-module"])!.arguments.name;
}
break;
}
@@ -7793,11 +7793,11 @@ namespace ts {
case "ts-check": {
// _last_ of either nocheck or check in a file is the "winner"
forEach(toArray(entryOrList), entry => {
if (!context.checkJsDirective || entry.range.pos > context.checkJsDirective.pos) {
if (!context.checkJsDirective || entry!.range.pos > context.checkJsDirective.pos) { // TODO: GH#18217
context.checkJsDirective = {
enabled: key === "ts-check",
end: entry.range.end,
pos: entry.range.pos
end: entry!.range.end,
pos: entry!.range.pos
};
}
});
@@ -7810,9 +7810,9 @@ namespace ts {
}
const namedArgRegExCache = createMap<RegExp>();
function getNamedArgRegEx(name: string) {
function getNamedArgRegEx(name: string): RegExp {
if (namedArgRegExCache.has(name)) {
return namedArgRegExCache.get(name);
return namedArgRegExCache.get(name)!;
}
const result = new RegExp(`(\\s${name}\\s*=\\s*)('|")(.+?)\\2`, "im");
namedArgRegExCache.set(name, result);
@@ -7826,7 +7826,7 @@ namespace ts {
if (tripleSlash) {
const name = tripleSlash[1].toLowerCase() as keyof PragmaPsuedoMap; // Technically unsafe cast, but we do it so the below check to make it safe typechecks
const pragma = commentPragmas[name] as PragmaDefinition;
if (!pragma || !(pragma.kind & PragmaKindFlags.TripleSlashXML)) {
if (!pragma || !(pragma.kind! & PragmaKindFlags.TripleSlashXML)) {
return;
}
if (pragma.args) {
@@ -7866,7 +7866,7 @@ namespace ts {
if (range.kind === SyntaxKind.MultiLineCommentTrivia) {
const multiLinePragmaRegEx = /\s*@(\S+)\s*(.*)\s*$/gim; // Defined inline since it uses the "g" flag, which keeps a persistent index (for iterating)
let multiLineMatch: RegExpExecArray;
let multiLineMatch: RegExpExecArray | null;
while (multiLineMatch = multiLinePragmaRegEx.exec(text)) {
addPragmaForMatch(pragmas, range, PragmaKindFlags.MultiLine, multiLineMatch);
}
@@ -7877,7 +7877,7 @@ namespace ts {
if (!match) return;
const name = match[1].toLowerCase() as keyof PragmaPsuedoMap; // Technically unsafe cast, but we do it so they below check to make it safe typechecks
const pragma = commentPragmas[name] as PragmaDefinition;
if (!pragma || !(pragma.kind & kind)) {
if (!pragma || !(pragma.kind! & kind)) {
return;
}
const args = match[2]; // Split on spaces and match up positionally with definition