mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
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:
+80
-78
@@ -123,13 +123,13 @@ namespace ts {
|
||||
|
||||
// state used by control flow analysis
|
||||
let currentFlow: FlowNode;
|
||||
let currentBreakTarget: FlowLabel;
|
||||
let currentContinueTarget: FlowLabel;
|
||||
let currentReturnTarget: FlowLabel;
|
||||
let currentTrueTarget: FlowLabel;
|
||||
let currentFalseTarget: FlowLabel;
|
||||
let preSwitchCaseFlow: FlowNode;
|
||||
let activeLabels: ActiveLabel[];
|
||||
let currentBreakTarget: FlowLabel | undefined;
|
||||
let currentContinueTarget: FlowLabel | undefined;
|
||||
let currentReturnTarget: FlowLabel | undefined;
|
||||
let currentTrueTarget: FlowLabel | undefined;
|
||||
let currentFalseTarget: FlowLabel | undefined;
|
||||
let preSwitchCaseFlow: FlowNode | undefined;
|
||||
let activeLabels: ActiveLabel[] | undefined;
|
||||
let hasExplicitReturn: boolean;
|
||||
|
||||
// state used for emit helpers
|
||||
@@ -180,23 +180,23 @@ namespace ts {
|
||||
delayedBindJSDocTypedefTag();
|
||||
}
|
||||
|
||||
file = undefined;
|
||||
options = undefined;
|
||||
languageVersion = undefined;
|
||||
parent = undefined;
|
||||
container = undefined;
|
||||
thisParentContainer = undefined;
|
||||
blockScopeContainer = undefined;
|
||||
lastContainer = undefined;
|
||||
delayedTypeAliases = undefined;
|
||||
file = undefined!;
|
||||
options = undefined!;
|
||||
languageVersion = undefined!;
|
||||
parent = undefined!;
|
||||
container = undefined!;
|
||||
thisParentContainer = undefined!;
|
||||
blockScopeContainer = undefined!;
|
||||
lastContainer = undefined!;
|
||||
delayedTypeAliases = undefined!;
|
||||
seenThisKeyword = false;
|
||||
currentFlow = undefined;
|
||||
currentFlow = undefined!;
|
||||
currentBreakTarget = undefined;
|
||||
currentContinueTarget = undefined;
|
||||
currentReturnTarget = undefined;
|
||||
currentTrueTarget = undefined;
|
||||
currentFalseTarget = undefined;
|
||||
activeLabels = undefined;
|
||||
activeLabels = undefined!;
|
||||
hasExplicitReturn = false;
|
||||
emitFlags = NodeFlags.None;
|
||||
subtreeTransformFlags = TransformFlags.None;
|
||||
@@ -234,7 +234,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (symbolFlags & SymbolFlags.Value) {
|
||||
const valueDeclaration = symbol.valueDeclaration;
|
||||
const { valueDeclaration } = symbol;
|
||||
if (!valueDeclaration ||
|
||||
(valueDeclaration.kind !== node.kind && valueDeclaration.kind === SyntaxKind.ModuleDeclaration)) {
|
||||
// other kinds of value declarations take precedence over modules
|
||||
@@ -245,7 +245,7 @@ namespace ts {
|
||||
|
||||
// Should not be called on a declaration with a computed property name,
|
||||
// unless it is a well known Symbol.
|
||||
function getDeclarationName(node: Declaration): __String {
|
||||
function getDeclarationName(node: Declaration): __String | undefined {
|
||||
if (node.kind === SyntaxKind.ExportAssignment) {
|
||||
return (<ExportAssignment>node).isExportEquals ? InternalSymbolName.ExportEquals : InternalSymbolName.Default;
|
||||
}
|
||||
@@ -306,7 +306,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getDisplayName(node: Declaration): string {
|
||||
return isNamedDeclaration(node) ? declarationNameToString(node.name) : unescapeLeadingUnderscores(getDeclarationName(node));
|
||||
return isNamedDeclaration(node) ? declarationNameToString(node.name) : unescapeLeadingUnderscores(getDeclarationName(node)!); // TODO: GH#18217
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -317,7 +317,7 @@ namespace ts {
|
||||
* @param includes - The SymbolFlags that node has in addition to its declaration type (eg: export, ambient, etc.)
|
||||
* @param excludes - The flags which node cannot be declared alongside in a symbol table. Used to report forbidden declarations.
|
||||
*/
|
||||
function declareSymbol(symbolTable: SymbolTable, parent: Symbol, node: Declaration, includes: SymbolFlags, excludes: SymbolFlags, isReplaceableByMethod?: boolean): Symbol {
|
||||
function declareSymbol(symbolTable: SymbolTable, parent: Symbol | undefined, node: Declaration, includes: SymbolFlags, excludes: SymbolFlags, isReplaceableByMethod?: boolean): Symbol {
|
||||
Debug.assert(!hasDynamicName(node));
|
||||
|
||||
const isDefaultExport = hasModifier(node, ModifierFlags.Default);
|
||||
@@ -325,7 +325,7 @@ namespace ts {
|
||||
// The exported symbol for an export default function/class node is always named "default"
|
||||
const name = isDefaultExport && parent ? InternalSymbolName.Default : getDeclarationName(node);
|
||||
|
||||
let symbol: Symbol;
|
||||
let symbol: Symbol | undefined;
|
||||
if (name === undefined) {
|
||||
symbol = createSymbol(SymbolFlags.None, InternalSymbolName.Missing);
|
||||
}
|
||||
@@ -432,10 +432,10 @@ namespace ts {
|
||||
const hasExportModifier = getCombinedModifierFlags(node) & ModifierFlags.Export;
|
||||
if (symbolFlags & SymbolFlags.Alias) {
|
||||
if (node.kind === SyntaxKind.ExportSpecifier || (node.kind === SyntaxKind.ImportEqualsDeclaration && hasExportModifier)) {
|
||||
return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
|
||||
return declareSymbol(container.symbol.exports!, container.symbol, node, symbolFlags, symbolExcludes);
|
||||
}
|
||||
else {
|
||||
return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
|
||||
return declareSymbol(container.locals!, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -457,16 +457,16 @@ namespace ts {
|
||||
if (isJSDocTypeAlias(node)) Debug.assert(isInJavaScriptFile(node)); // We shouldn't add symbols for JSDoc nodes if not in a JS file.
|
||||
if ((!isAmbientModule(node) && (hasExportModifier || container.flags & NodeFlags.ExportContext)) || isJSDocTypeAlias(node)) {
|
||||
if (hasModifier(node, ModifierFlags.Default) && !getDeclarationName(node)) {
|
||||
return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); // No local symbol for an unnamed default!
|
||||
return declareSymbol(container.symbol.exports!, container.symbol, node, symbolFlags, symbolExcludes); // No local symbol for an unnamed default!
|
||||
}
|
||||
const exportKind = symbolFlags & SymbolFlags.Value ? SymbolFlags.ExportValue : 0;
|
||||
const local = declareSymbol(container.locals, /*parent*/ undefined, node, exportKind, symbolExcludes);
|
||||
local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
|
||||
const local = declareSymbol(container.locals!, /*parent*/ undefined, node, exportKind, symbolExcludes);
|
||||
local.exportSymbol = declareSymbol(container.symbol.exports!, container.symbol, node, symbolFlags, symbolExcludes);
|
||||
node.localSymbol = local;
|
||||
return local;
|
||||
}
|
||||
else {
|
||||
return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
|
||||
return declareSymbol(container.locals!, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -547,6 +547,7 @@ namespace ts {
|
||||
if (node.kind === SyntaxKind.SourceFile) {
|
||||
node.flags |= emitFlags;
|
||||
}
|
||||
|
||||
if (currentReturnTarget) {
|
||||
addAntecedent(currentReturnTarget, currentFlow);
|
||||
currentFlow = finishFlowLabel(currentReturnTarget);
|
||||
@@ -595,12 +596,12 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function bindEachFunctionsFirst(nodes: NodeArray<Node>) {
|
||||
function bindEachFunctionsFirst(nodes: NodeArray<Node> | undefined): void {
|
||||
bindEach(nodes, n => n.kind === SyntaxKind.FunctionDeclaration ? bind(n) : undefined);
|
||||
bindEach(nodes, n => n.kind !== SyntaxKind.FunctionDeclaration ? bind(n) : undefined);
|
||||
}
|
||||
|
||||
function bindEach(nodes: NodeArray<Node>, bindFunction = bind) {
|
||||
function bindEach(nodes: NodeArray<Node> | undefined, bindFunction: (node: Node) => void = bind): void {
|
||||
if (nodes === undefined) {
|
||||
return;
|
||||
}
|
||||
@@ -820,7 +821,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function createFlowCondition(flags: FlowFlags, antecedent: FlowNode, expression: Expression): FlowNode {
|
||||
function createFlowCondition(flags: FlowFlags, antecedent: FlowNode, expression: Expression | undefined): FlowNode {
|
||||
if (antecedent.flags & FlowFlags.Unreachable) {
|
||||
return antecedent;
|
||||
}
|
||||
@@ -907,7 +908,7 @@ namespace ts {
|
||||
return !isStatementCondition(node) && !isLogicalExpression(node.parent);
|
||||
}
|
||||
|
||||
function bindCondition(node: Expression, trueTarget: FlowLabel, falseTarget: FlowLabel) {
|
||||
function bindCondition(node: Expression | undefined, trueTarget: FlowLabel, falseTarget: FlowLabel) {
|
||||
const saveTrueTarget = currentTrueTarget;
|
||||
const saveFalseTarget = currentFalseTarget;
|
||||
currentTrueTarget = trueTarget;
|
||||
@@ -947,7 +948,7 @@ namespace ts {
|
||||
function bindDoStatement(node: DoStatement): void {
|
||||
const preDoLabel = createLoopLabel();
|
||||
const enclosingLabeledStatement = node.parent.kind === SyntaxKind.LabeledStatement
|
||||
? lastOrUndefined(activeLabels)
|
||||
? lastOrUndefined(activeLabels!)
|
||||
: undefined;
|
||||
// if do statement is wrapped in labeled statement then target labels for break/continue with or without
|
||||
// label should be the same
|
||||
@@ -1032,7 +1033,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function bindBreakOrContinueFlow(node: BreakOrContinueStatement, breakTarget: FlowLabel, continueTarget: FlowLabel) {
|
||||
function bindBreakOrContinueFlow(node: BreakOrContinueStatement, breakTarget: FlowLabel | undefined, continueTarget: FlowLabel | undefined) {
|
||||
const flowLabel = node.kind === SyntaxKind.BreakStatement ? breakTarget : continueTarget;
|
||||
if (flowLabel) {
|
||||
addAntecedent(flowLabel, currentFlow);
|
||||
@@ -1162,7 +1163,8 @@ namespace ts {
|
||||
i++;
|
||||
}
|
||||
const preCaseLabel = createBranchLabel();
|
||||
addAntecedent(preCaseLabel, createFlowSwitchClause(preSwitchCaseFlow, node.parent, clauseStart, i + 1));
|
||||
addAntecedent(preCaseLabel, createFlowSwitchClause(preSwitchCaseFlow!, node.parent, clauseStart, i + 1));
|
||||
addAntecedent(preCaseLabel, createFlowSwitchClause(preSwitchCaseFlow!, node.parent, clauseStart, i + 1));
|
||||
addAntecedent(preCaseLabel, fallthroughFlow);
|
||||
currentFlow = finishFlowLabel(preCaseLabel);
|
||||
const clause = clauses[i];
|
||||
@@ -1178,7 +1180,7 @@ namespace ts {
|
||||
|
||||
function bindCaseClause(node: CaseClause): void {
|
||||
const saveCurrentFlow = currentFlow;
|
||||
currentFlow = preSwitchCaseFlow;
|
||||
currentFlow = preSwitchCaseFlow!;
|
||||
bind(node.expression);
|
||||
currentFlow = saveCurrentFlow;
|
||||
bindEach(node.statements);
|
||||
@@ -1196,7 +1198,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function popActiveLabel() {
|
||||
activeLabels.pop();
|
||||
activeLabels!.pop();
|
||||
}
|
||||
|
||||
function bindLabeledStatement(node: LabeledStatement): void {
|
||||
@@ -1301,7 +1303,7 @@ namespace ts {
|
||||
currentFlow = finishFlowLabel(postExpressionLabel);
|
||||
}
|
||||
else {
|
||||
bindLogicalExpression(node, currentTrueTarget, currentFalseTarget);
|
||||
bindLogicalExpression(node, currentTrueTarget!, currentFalseTarget!);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1478,7 +1480,7 @@ namespace ts {
|
||||
lastContainer = next;
|
||||
}
|
||||
|
||||
function declareSymbolAndAddToSymbolTable(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol {
|
||||
function declareSymbolAndAddToSymbolTable(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol | undefined {
|
||||
switch (container.kind) {
|
||||
// Modules, source files, and classes need specialized handling for how their
|
||||
// members are declared (for example, a member of a class will go into a specific
|
||||
@@ -1495,7 +1497,7 @@ namespace ts {
|
||||
return declareClassMember(node, symbolFlags, symbolExcludes);
|
||||
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
|
||||
return declareSymbol(container.symbol.exports!, container.symbol, node, symbolFlags, symbolExcludes);
|
||||
|
||||
case SyntaxKind.TypeLiteral:
|
||||
case SyntaxKind.JSDocTypeLiteral:
|
||||
@@ -1507,7 +1509,7 @@ namespace ts {
|
||||
// container, and are never in scope otherwise (even inside the body of the
|
||||
// object / type / interface declaring them). An exception is type parameters,
|
||||
// which are in scope without qualification (similar to 'locals').
|
||||
return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
|
||||
return declareSymbol(container.symbol.members!, container.symbol, node, symbolFlags, symbolExcludes);
|
||||
|
||||
case SyntaxKind.FunctionType:
|
||||
case SyntaxKind.ConstructorType:
|
||||
@@ -1534,20 +1536,20 @@ namespace ts {
|
||||
// their container in the tree). To accomplish this, we simply add their declared
|
||||
// symbol to the 'locals' of the container. These symbols can then be found as
|
||||
// the type checker walks up the containers, checking them for matching names.
|
||||
return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
|
||||
return declareSymbol(container.locals!, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
|
||||
}
|
||||
}
|
||||
|
||||
function declareClassMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
|
||||
return hasModifier(node, ModifierFlags.Static)
|
||||
? declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes)
|
||||
: declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
|
||||
? declareSymbol(container.symbol.exports!, container.symbol, node, symbolFlags, symbolExcludes)
|
||||
: declareSymbol(container.symbol.members!, container.symbol, node, symbolFlags, symbolExcludes);
|
||||
}
|
||||
|
||||
function declareSourceFileMember(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
|
||||
return isExternalModule(file)
|
||||
? declareModuleMember(node, symbolFlags, symbolExcludes)
|
||||
: declareSymbol(file.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
|
||||
: declareSymbol(file.locals!, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
|
||||
}
|
||||
|
||||
function hasExportDeclarations(node: ModuleDeclaration | SourceFile): boolean {
|
||||
@@ -1594,8 +1596,8 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
const symbol = declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes);
|
||||
file.patternAmbientModules = append(file.patternAmbientModules, pattern && { pattern, symbol });
|
||||
const symbol = declareSymbolAndAddToSymbolTable(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes)!;
|
||||
file.patternAmbientModules = append<PatternAmbientModule>(file.patternAmbientModules, pattern && { pattern, symbol });
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1628,7 +1630,7 @@ namespace ts {
|
||||
// We do that by making an anonymous type literal symbol, and then setting the function
|
||||
// symbol as its sole member. To the rest of the system, this symbol will be indistinguishable
|
||||
// from an actual type literal symbol you would have gotten had you used the long form.
|
||||
const symbol = createSymbol(SymbolFlags.Signature, getDeclarationName(node));
|
||||
const symbol = createSymbol(SymbolFlags.Signature, getDeclarationName(node)!); // TODO: GH#18217
|
||||
addDeclarationToSymbol(symbol, node, SymbolFlags.Signature);
|
||||
|
||||
const typeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, InternalSymbolName.Type);
|
||||
@@ -1757,8 +1759,8 @@ namespace ts {
|
||||
// check for reserved words used as identifiers in strict mode code.
|
||||
function checkStrictModeIdentifier(node: Identifier) {
|
||||
if (inStrictMode &&
|
||||
node.originalKeywordKind >= SyntaxKind.FirstFutureReservedWord &&
|
||||
node.originalKeywordKind <= SyntaxKind.LastFutureReservedWord &&
|
||||
node.originalKeywordKind! >= SyntaxKind.FirstFutureReservedWord &&
|
||||
node.originalKeywordKind! <= SyntaxKind.LastFutureReservedWord &&
|
||||
!isIdentifierName(node) &&
|
||||
!(node.flags & NodeFlags.Ambient)) {
|
||||
|
||||
@@ -1814,7 +1816,7 @@ namespace ts {
|
||||
return isIdentifier(node) && (node.escapedText === "eval" || node.escapedText === "arguments");
|
||||
}
|
||||
|
||||
function checkStrictModeEvalOrArguments(contextNode: Node, name: Node) {
|
||||
function checkStrictModeEvalOrArguments(contextNode: Node, name: Node | undefined) {
|
||||
if (name && name.kind === SyntaxKind.Identifier) {
|
||||
const identifier = <Identifier>name;
|
||||
if (isEvalOrArgumentsIdentifier(identifier)) {
|
||||
@@ -1925,7 +1927,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function bind(node: Node): void {
|
||||
function bind(node: Node | undefined): void {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
@@ -1980,12 +1982,12 @@ namespace ts {
|
||||
function bindJSDoc(node: Node) {
|
||||
if (hasJSDocNodes(node)) {
|
||||
if (isInJavaScriptFile(node)) {
|
||||
for (const j of node.jsDoc) {
|
||||
for (const j of node.jsDoc!) {
|
||||
bind(j);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (const j of node.jsDoc) {
|
||||
for (const j of node.jsDoc!) {
|
||||
setParentPointers(node, j);
|
||||
}
|
||||
}
|
||||
@@ -2231,7 +2233,7 @@ namespace ts {
|
||||
bindSourceFileAsExternalModule();
|
||||
// Create symbol equivalent for the module.exports = {}
|
||||
const originalSymbol = file.symbol;
|
||||
declareSymbol(file.symbol.exports, file.symbol, file, SymbolFlags.Property, SymbolFlags.All);
|
||||
declareSymbol(file.symbol.exports!, file.symbol, file, SymbolFlags.Property, SymbolFlags.All);
|
||||
file.symbol = originalSymbol;
|
||||
}
|
||||
}
|
||||
@@ -2243,7 +2245,7 @@ namespace ts {
|
||||
function bindExportAssignment(node: ExportAssignment) {
|
||||
if (!container.symbol || !container.symbol.exports) {
|
||||
// Export assignment in some sort of block construct
|
||||
bindAnonymousDeclaration(node, SymbolFlags.Alias, getDeclarationName(node));
|
||||
bindAnonymousDeclaration(node, SymbolFlags.Alias, getDeclarationName(node)!);
|
||||
}
|
||||
else {
|
||||
const flags = node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(node)
|
||||
@@ -2287,7 +2289,7 @@ namespace ts {
|
||||
function bindExportDeclaration(node: ExportDeclaration) {
|
||||
if (!container.symbol || !container.symbol.exports) {
|
||||
// Export * in some sort of block construct
|
||||
bindAnonymousDeclaration(node, SymbolFlags.ExportStar, getDeclarationName(node));
|
||||
bindAnonymousDeclaration(node, SymbolFlags.ExportStar, getDeclarationName(node)!);
|
||||
}
|
||||
else if (!node.exportClause) {
|
||||
// All export * declarations are collected in an __export symbol
|
||||
@@ -2319,7 +2321,7 @@ namespace ts {
|
||||
if (!original) {
|
||||
return undefined;
|
||||
}
|
||||
const s = getJSInitializerSymbol(original);
|
||||
const s = getJSInitializerSymbol(original)!;
|
||||
addDeclarationToSymbol(s, id, SymbolFlags.Module | SymbolFlags.JSContainer);
|
||||
return s;
|
||||
});
|
||||
@@ -2327,7 +2329,7 @@ namespace ts {
|
||||
const flags = isClassExpression(node.right) ?
|
||||
SymbolFlags.Property | SymbolFlags.ExportValue | SymbolFlags.Class :
|
||||
SymbolFlags.Property | SymbolFlags.ExportValue;
|
||||
declareSymbol(symbol.exports, symbol, lhs, flags, SymbolFlags.None);
|
||||
declareSymbol(symbol.exports!, symbol, lhs, flags, SymbolFlags.None);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2348,7 +2350,7 @@ namespace ts {
|
||||
const flags = exportAssignmentIsAlias(node)
|
||||
? SymbolFlags.Alias // An export= with an EntityNameExpression or a ClassExpression exports all meanings of that identifier or class
|
||||
: SymbolFlags.Property | SymbolFlags.ExportValue | SymbolFlags.ValueModule;
|
||||
declareSymbol(file.symbol.exports, file.symbol, node, flags, SymbolFlags.None);
|
||||
declareSymbol(file.symbol.exports!, file.symbol, node, flags, SymbolFlags.None);
|
||||
}
|
||||
|
||||
function bindThisPropertyAssignment(node: BinaryExpression | PropertyAccessExpression) {
|
||||
@@ -2362,7 +2364,7 @@ namespace ts {
|
||||
if (isBinaryExpression(thisContainer.parent) && thisContainer.parent.operatorToken.kind === SyntaxKind.EqualsToken) {
|
||||
const l = thisContainer.parent.left;
|
||||
if (isPropertyAccessEntityNameExpression(l) && isPrototypeAccess(l.expression)) {
|
||||
constructorSymbol = getJSInitializerSymbolFromName(l.expression.expression, thisParentContainer);
|
||||
constructorSymbol = getJSInitializerSymbolFromName(l.expression.expression, thisParentContainer)!;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2382,7 +2384,7 @@ namespace ts {
|
||||
// this.foo assignment in a JavaScript class
|
||||
// Bind this property to the containing class
|
||||
const containingClass = thisContainer.parent;
|
||||
const symbolTable = hasModifier(thisContainer, ModifierFlags.Static) ? containingClass.symbol.exports : containingClass.symbol.members;
|
||||
const symbolTable = hasModifier(thisContainer, ModifierFlags.Static) ? containingClass.symbol.exports! : containingClass.symbol.members!;
|
||||
declareSymbol(symbolTable, containingClass.symbol, node, SymbolFlags.Property, SymbolFlags.None, /*isReplaceableByMethod*/ true);
|
||||
break;
|
||||
case SyntaxKind.SourceFile:
|
||||
@@ -2461,7 +2463,7 @@ namespace ts {
|
||||
bindPropertyAssignment(node.expression, node, /*isPrototypeProperty*/ false);
|
||||
}
|
||||
|
||||
function getJSInitializerSymbolFromName(name: EntityNameExpression, lookupContainer?: Node): Symbol {
|
||||
function getJSInitializerSymbolFromName(name: EntityNameExpression, lookupContainer?: Node): Symbol | undefined {
|
||||
return getJSInitializerSymbol(lookupSymbolForPropertyAccess(name, lookupContainer));
|
||||
}
|
||||
|
||||
@@ -2482,7 +2484,7 @@ namespace ts {
|
||||
return original;
|
||||
}
|
||||
else {
|
||||
return symbol = declareSymbol(symbol ? symbol.exports : container.locals, symbol, id, flags, excludeFlags);
|
||||
return symbol = declareSymbol(symbol ? symbol.exports! : container.locals!, symbol, id, flags, excludeFlags);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -2497,7 +2499,7 @@ namespace ts {
|
||||
|
||||
// Declare the method/property
|
||||
const jsContainerFlag = isToplevelNamespaceableInitializer ? SymbolFlags.JSContainer : 0;
|
||||
const isMethod = isFunctionLikeDeclaration(getAssignedJavascriptInitializer(propertyAccess));
|
||||
const isMethod = isFunctionLikeDeclaration(getAssignedJavascriptInitializer(propertyAccess)!); // TODO: GH#18217
|
||||
const symbolFlags = (isMethod ? SymbolFlags.Method : SymbolFlags.Property) | jsContainerFlag;
|
||||
const symbolExcludes = (isMethod ? SymbolFlags.MethodExcludes : SymbolFlags.PropertyExcludes) & ~jsContainerFlag;
|
||||
declareSymbol(symbolTable, symbol, propertyAccess, symbolFlags, symbolExcludes);
|
||||
@@ -2520,7 +2522,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function forEachIdentifierInEntityName(e: EntityNameExpression, action: (e: Identifier, symbol: Symbol) => Symbol): Symbol {
|
||||
function forEachIdentifierInEntityName(e: EntityNameExpression, action: (e: Identifier, symbol: Symbol | undefined) => Symbol | undefined): Symbol | undefined {
|
||||
if (isExportsOrModuleExportsOrAlias(file, e)) {
|
||||
return file.symbol;
|
||||
}
|
||||
@@ -2529,7 +2531,7 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
const s = getJSInitializerSymbol(forEachIdentifierInEntityName(e.expression, action));
|
||||
Debug.assert(!!s && !!s.exports);
|
||||
if (!s || !s.exports) return Debug.fail();
|
||||
return action(e.name, s.exports.get(e.name.escapedText));
|
||||
}
|
||||
}
|
||||
@@ -2555,7 +2557,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
const symbol = node.symbol;
|
||||
const { symbol } = node;
|
||||
|
||||
// TypeScript 1.0 spec (April 2014): 8.4
|
||||
// Every class automatically contains a static property member named 'prototype', the
|
||||
@@ -2567,14 +2569,14 @@ namespace ts {
|
||||
// module might have an exported variable called 'prototype'. We can't allow that as
|
||||
// that would clash with the built-in 'prototype' for the class.
|
||||
const prototypeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Prototype, "prototype" as __String);
|
||||
const symbolExport = symbol.exports.get(prototypeSymbol.escapedName);
|
||||
const symbolExport = symbol.exports!.get(prototypeSymbol.escapedName);
|
||||
if (symbolExport) {
|
||||
if (node.name) {
|
||||
node.name.parent = node;
|
||||
}
|
||||
file.bindDiagnostics.push(createDiagnosticForNode(symbolExport.declarations[0], Diagnostics.Duplicate_identifier_0, symbolName(prototypeSymbol)));
|
||||
}
|
||||
symbol.exports.set(prototypeSymbol.escapedName, prototypeSymbol);
|
||||
symbol.exports!.set(prototypeSymbol.escapedName, prototypeSymbol);
|
||||
prototypeSymbol.parent = symbol;
|
||||
}
|
||||
|
||||
@@ -2632,7 +2634,7 @@ namespace ts {
|
||||
// containing class.
|
||||
if (isParameterPropertyDeclaration(node)) {
|
||||
const classDeclaration = <ClassLikeDeclaration>node.parent.parent;
|
||||
declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, SymbolFlags.Property | (node.questionToken ? SymbolFlags.Optional : SymbolFlags.None), SymbolFlags.PropertyExcludes);
|
||||
declareSymbol(classDeclaration.symbol.members!, classDeclaration.symbol, node, SymbolFlags.Property | (node.questionToken ? SymbolFlags.Optional : SymbolFlags.None), SymbolFlags.PropertyExcludes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2681,14 +2683,14 @@ namespace ts {
|
||||
: declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
|
||||
}
|
||||
|
||||
function getInferTypeContainer(node: Node): ConditionalTypeNode {
|
||||
function getInferTypeContainer(node: Node): ConditionalTypeNode | undefined {
|
||||
const extendsType = findAncestor(node, n => n.parent && isConditionalTypeNode(n.parent) && n.parent.extendsType === n);
|
||||
return extendsType && extendsType.parent as ConditionalTypeNode;
|
||||
}
|
||||
|
||||
function bindTypeParameter(node: TypeParameterDeclaration) {
|
||||
if (isJSDocTemplateTag(node.parent)) {
|
||||
const container = find((node.parent.parent as JSDoc).tags, isJSDocTypeAlias) || getHostSignatureFromJSDoc(node.parent);
|
||||
const container = find((node.parent.parent as JSDoc).tags!, isJSDocTypeAlias) || getHostSignatureFromJSDoc(node.parent); // TODO: GH#18217
|
||||
if (container) {
|
||||
if (!container.locals) {
|
||||
container.locals = createSymbolTable();
|
||||
@@ -2708,7 +2710,7 @@ namespace ts {
|
||||
declareSymbol(container.locals, /*parent*/ undefined, node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes);
|
||||
}
|
||||
else {
|
||||
bindAnonymousDeclaration(node, SymbolFlags.TypeParameter, getDeclarationName(node));
|
||||
bindAnonymousDeclaration(node, SymbolFlags.TypeParameter, getDeclarationName(node)!); // TODO: GH#18217
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -2720,7 +2722,7 @@ namespace ts {
|
||||
|
||||
function shouldReportErrorOnModuleDeclaration(node: ModuleDeclaration): boolean {
|
||||
const instanceState = getModuleInstanceState(node);
|
||||
return instanceState === ModuleInstanceState.Instantiated || (instanceState === ModuleInstanceState.ConstEnumOnly && options.preserveConstEnums);
|
||||
return instanceState === ModuleInstanceState.Instantiated || (instanceState === ModuleInstanceState.ConstEnumOnly && !!options.preserveConstEnums);
|
||||
}
|
||||
|
||||
function checkUnreachable(node: Node): boolean {
|
||||
@@ -2777,8 +2779,8 @@ namespace ts {
|
||||
|
||||
function isNameOfExportsOrModuleExportsAliasDeclaration(sourceFile: SourceFile, node: Identifier): boolean {
|
||||
const symbol = lookupSymbolForNameWorker(sourceFile, node.escapedText);
|
||||
return symbol && symbol.valueDeclaration && isVariableDeclaration(symbol.valueDeclaration) &&
|
||||
symbol.valueDeclaration.initializer && isExportsOrModuleExportsOrAliasOrAssignment(sourceFile, symbol.valueDeclaration.initializer);
|
||||
return !!symbol && !!symbol.valueDeclaration && isVariableDeclaration(symbol.valueDeclaration) &&
|
||||
!!symbol.valueDeclaration.initializer && isExportsOrModuleExportsOrAliasOrAssignment(sourceFile, symbol.valueDeclaration.initializer);
|
||||
}
|
||||
|
||||
function isExportsOrModuleExportsOrAliasOrAssignment(sourceFile: SourceFile, node: Expression): boolean {
|
||||
|
||||
+32
-31
@@ -3,6 +3,7 @@ namespace ts {
|
||||
/**
|
||||
* State to store the changed files, affected files and cache semantic diagnostics
|
||||
*/
|
||||
// TODO: GH#18217 Properties of this interface are frequently asserted to be defined.
|
||||
export interface BuilderProgramState extends BuilderState {
|
||||
/**
|
||||
* Cache of semantic diagnostics for files with their Path being the key
|
||||
@@ -41,7 +42,7 @@ namespace ts {
|
||||
|
||||
function hasSameKeys<T, U>(map1: ReadonlyMap<T> | undefined, map2: ReadonlyMap<U> | undefined): boolean {
|
||||
// Has same size and every key is present in both maps
|
||||
return map1 as ReadonlyMap<T | U> === map2 || map1 && map2 && map1.size === map2.size && !forEachKey(map1, key => !map2.has(key));
|
||||
return map1 as ReadonlyMap<T | U> === map2 || map1 !== undefined && map2 !== undefined && map1.size === map2.size && !forEachKey(map1, key => !map2.has(key));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,45 +57,45 @@ namespace ts {
|
||||
}
|
||||
state.changedFilesSet = createMap<true>();
|
||||
const useOldState = BuilderState.canReuseOldState(state.referencedMap, oldState);
|
||||
const canCopySemanticDiagnostics = useOldState && oldState.semanticDiagnosticsPerFile && !!state.semanticDiagnosticsPerFile;
|
||||
const canCopySemanticDiagnostics = useOldState && oldState!.semanticDiagnosticsPerFile && !!state.semanticDiagnosticsPerFile;
|
||||
if (useOldState) {
|
||||
// Verify the sanity of old state
|
||||
if (!oldState.currentChangedFilePath) {
|
||||
Debug.assert(!oldState.affectedFiles && (!oldState.currentAffectedFilesSignatures || !oldState.currentAffectedFilesSignatures.size), "Cannot reuse if only few affected files of currentChangedFile were iterated");
|
||||
if (!oldState!.currentChangedFilePath) {
|
||||
Debug.assert(!oldState!.affectedFiles && (!oldState!.currentAffectedFilesSignatures || !oldState!.currentAffectedFilesSignatures!.size), "Cannot reuse if only few affected files of currentChangedFile were iterated");
|
||||
}
|
||||
if (canCopySemanticDiagnostics) {
|
||||
Debug.assert(!forEachKey(oldState.changedFilesSet, path => oldState.semanticDiagnosticsPerFile.has(path)), "Semantic diagnostics shouldnt be available for changed files");
|
||||
Debug.assert(!forEachKey(oldState!.changedFilesSet, path => oldState!.semanticDiagnosticsPerFile!.has(path)), "Semantic diagnostics shouldnt be available for changed files");
|
||||
}
|
||||
|
||||
// Copy old state's changed files set
|
||||
copyEntries(oldState.changedFilesSet, state.changedFilesSet);
|
||||
copyEntries(oldState!.changedFilesSet, state.changedFilesSet);
|
||||
}
|
||||
|
||||
// Update changed files and copy semantic diagnostics if we can
|
||||
const referencedMap = state.referencedMap;
|
||||
const oldReferencedMap = useOldState && oldState.referencedMap;
|
||||
const oldReferencedMap = useOldState ? oldState!.referencedMap : undefined;
|
||||
state.fileInfos.forEach((info, sourceFilePath) => {
|
||||
let oldInfo: Readonly<BuilderState.FileInfo>;
|
||||
let newReferences: BuilderState.ReferencedSet;
|
||||
let oldInfo: Readonly<BuilderState.FileInfo> | undefined;
|
||||
let newReferences: BuilderState.ReferencedSet | undefined;
|
||||
|
||||
// if not using old state, every file is changed
|
||||
if (!useOldState ||
|
||||
// File wasnt present in old state
|
||||
!(oldInfo = oldState.fileInfos.get(sourceFilePath)) ||
|
||||
!(oldInfo = oldState!.fileInfos.get(sourceFilePath)) ||
|
||||
// versions dont match
|
||||
oldInfo.version !== info.version ||
|
||||
// Referenced files changed
|
||||
!hasSameKeys(newReferences = referencedMap && referencedMap.get(sourceFilePath), oldReferencedMap && oldReferencedMap.get(sourceFilePath)) ||
|
||||
// Referenced file was deleted in the new program
|
||||
newReferences && forEachKey(newReferences, path => !state.fileInfos.has(path) && oldState.fileInfos.has(path))) {
|
||||
newReferences && forEachKey(newReferences, path => !state.fileInfos.has(path) && oldState!.fileInfos.has(path))) {
|
||||
// Register file as changed file and do not copy semantic diagnostics, since all changed files need to be re-evaluated
|
||||
state.changedFilesSet.set(sourceFilePath, true);
|
||||
}
|
||||
else if (canCopySemanticDiagnostics) {
|
||||
// Unchanged file copy diagnostics
|
||||
const diagnostics = oldState.semanticDiagnosticsPerFile.get(sourceFilePath);
|
||||
const diagnostics = oldState!.semanticDiagnosticsPerFile!.get(sourceFilePath);
|
||||
if (diagnostics) {
|
||||
state.semanticDiagnosticsPerFile.set(sourceFilePath, diagnostics);
|
||||
state.semanticDiagnosticsPerFile!.set(sourceFilePath, diagnostics);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -106,7 +107,7 @@ namespace ts {
|
||||
* Verifies that source file is ok to be used in calls that arent handled by next
|
||||
*/
|
||||
function assertSourceFileOkWithoutNextAffectedCall(state: BuilderProgramState, sourceFile: SourceFile | undefined) {
|
||||
Debug.assert(!sourceFile || !state.affectedFiles || state.affectedFiles[state.affectedFilesIndex - 1] !== sourceFile || !state.semanticDiagnosticsPerFile.has(sourceFile.path));
|
||||
Debug.assert(!sourceFile || !state.affectedFiles || state.affectedFiles[state.affectedFilesIndex! - 1] !== sourceFile || !state.semanticDiagnosticsPerFile!.has(sourceFile.path));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,25 +121,25 @@ namespace ts {
|
||||
const { affectedFiles } = state;
|
||||
if (affectedFiles) {
|
||||
const { seenAffectedFiles, semanticDiagnosticsPerFile } = state;
|
||||
let { affectedFilesIndex } = state;
|
||||
let affectedFilesIndex = state.affectedFilesIndex!; // TODO: GH#18217
|
||||
while (affectedFilesIndex < affectedFiles.length) {
|
||||
const affectedFile = affectedFiles[affectedFilesIndex];
|
||||
if (!seenAffectedFiles.has(affectedFile.path)) {
|
||||
if (!seenAffectedFiles!.has(affectedFile.path)) {
|
||||
// Set the next affected file as seen and remove the cached semantic diagnostics
|
||||
state.affectedFilesIndex = affectedFilesIndex;
|
||||
semanticDiagnosticsPerFile.delete(affectedFile.path);
|
||||
semanticDiagnosticsPerFile!.delete(affectedFile.path);
|
||||
return affectedFile;
|
||||
}
|
||||
seenAffectedFiles.set(affectedFile.path, true);
|
||||
seenAffectedFiles!.set(affectedFile.path, true);
|
||||
affectedFilesIndex++;
|
||||
}
|
||||
|
||||
// Remove the changed file from the change set
|
||||
state.changedFilesSet.delete(state.currentChangedFilePath);
|
||||
state.changedFilesSet.delete(state.currentChangedFilePath!);
|
||||
state.currentChangedFilePath = undefined;
|
||||
// Commit the changes in file signature
|
||||
BuilderState.updateSignaturesFromCache(state, state.currentAffectedFilesSignatures);
|
||||
state.currentAffectedFilesSignatures.clear();
|
||||
BuilderState.updateSignaturesFromCache(state, state.currentAffectedFilesSignatures!);
|
||||
state.currentAffectedFilesSignatures!.clear();
|
||||
state.affectedFiles = undefined;
|
||||
}
|
||||
|
||||
@@ -161,7 +162,7 @@ namespace ts {
|
||||
state.currentAffectedFilesSignatures = state.currentAffectedFilesSignatures || createMap();
|
||||
state.affectedFiles = BuilderState.getFilesAffectedBy(state, state.program, nextKey.value as Path, cancellationToken, computeHash, state.currentAffectedFilesSignatures);
|
||||
state.currentChangedFilePath = nextKey.value as Path;
|
||||
state.semanticDiagnosticsPerFile.delete(nextKey.value as Path);
|
||||
state.semanticDiagnosticsPerFile!.delete(nextKey.value as Path);
|
||||
state.affectedFilesIndex = 0;
|
||||
state.seenAffectedFiles = state.seenAffectedFiles || createMap<true>();
|
||||
}
|
||||
@@ -176,8 +177,8 @@ namespace ts {
|
||||
state.changedFilesSet.clear();
|
||||
}
|
||||
else {
|
||||
state.seenAffectedFiles.set((affected as SourceFile).path, true);
|
||||
state.affectedFilesIndex++;
|
||||
state.seenAffectedFiles!.set((affected as SourceFile).path, true);
|
||||
state.affectedFilesIndex!++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,7 +196,7 @@ namespace ts {
|
||||
*/
|
||||
function getSemanticDiagnosticsOfFile(state: BuilderProgramState, sourceFile: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic> {
|
||||
const path = sourceFile.path;
|
||||
const cachedDiagnostics = state.semanticDiagnosticsPerFile.get(path);
|
||||
const cachedDiagnostics = state.semanticDiagnosticsPerFile!.get(path);
|
||||
// Report the semantic diagnostics from the cache if we already have those diagnostics present
|
||||
if (cachedDiagnostics) {
|
||||
return cachedDiagnostics;
|
||||
@@ -203,7 +204,7 @@ namespace ts {
|
||||
|
||||
// Diagnostics werent cached, get them from program, and cache the result
|
||||
const diagnostics = state.program.getSemanticDiagnostics(sourceFile, cancellationToken);
|
||||
state.semanticDiagnosticsPerFile.set(path, diagnostics);
|
||||
state.semanticDiagnosticsPerFile!.set(path, diagnostics);
|
||||
return diagnostics;
|
||||
}
|
||||
|
||||
@@ -250,7 +251,7 @@ namespace ts {
|
||||
// Return same program if underlying program doesnt change
|
||||
let oldState = oldProgram && oldProgram.getState();
|
||||
if (oldState && newProgram === oldState.program && configFileParsingDiagnostics === newProgram.getConfigFileParsingDiagnostics()) {
|
||||
newProgram = undefined;
|
||||
newProgram = undefined!; // TODO: GH#18217
|
||||
oldState = undefined;
|
||||
return oldProgram;
|
||||
}
|
||||
@@ -266,7 +267,7 @@ namespace ts {
|
||||
const state = createBuilderProgramState(newProgram, getCanonicalFileName, oldState);
|
||||
|
||||
// To ensure that we arent storing any references to old program or new program without state
|
||||
newProgram = undefined;
|
||||
newProgram = undefined!; // TODO: GH#18217
|
||||
oldProgram = undefined;
|
||||
oldState = undefined;
|
||||
|
||||
@@ -336,8 +337,8 @@ namespace ts {
|
||||
if (!targetSourceFile) {
|
||||
// Emit and report any errors we ran into.
|
||||
let sourceMaps: SourceMapData[] = [];
|
||||
let emitSkipped: boolean;
|
||||
let diagnostics: Diagnostic[];
|
||||
let emitSkipped = false;
|
||||
let diagnostics: Diagnostic[] | undefined;
|
||||
let emittedFiles: string[] = [];
|
||||
|
||||
let affectedEmitResult: AffectedFileResult<EmitResult>;
|
||||
@@ -423,7 +424,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
let diagnostics: Diagnostic[];
|
||||
let diagnostics: Diagnostic[] | undefined;
|
||||
for (const sourceFile of state.program.getSourceFiles()) {
|
||||
diagnostics = addRange(diagnostics, getSemanticDiagnosticsOfFile(state, sourceFile, cancellationToken));
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ namespace ts.BuilderState {
|
||||
return;
|
||||
}
|
||||
|
||||
const fileName = resolvedTypeReferenceDirective.resolvedFileName;
|
||||
const fileName = resolvedTypeReferenceDirective.resolvedFileName!; // TODO: GH#18217
|
||||
const typeFilePath = toPath(fileName, sourceFileDirectory, getCanonicalFileName);
|
||||
addReferencedFile(typeFilePath);
|
||||
});
|
||||
@@ -127,7 +127,7 @@ namespace ts.BuilderState {
|
||||
/**
|
||||
* Returns true if oldState is reusable, that is the emitKind = module/non module has not changed
|
||||
*/
|
||||
export function canReuseOldState(newReferencedMap: ReadonlyMap<ReferencedSet>, oldState: Readonly<BuilderState> | undefined) {
|
||||
export function canReuseOldState(newReferencedMap: ReadonlyMap<ReferencedSet> | undefined, oldState: Readonly<BuilderState> | undefined) {
|
||||
return oldState && !oldState.referencedMap === !newReferencedMap;
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ namespace ts.BuilderState {
|
||||
// Create the reference map, and set the file infos
|
||||
for (const sourceFile of newProgram.getSourceFiles()) {
|
||||
const version = sourceFile.version;
|
||||
const oldInfo = useOldState && oldState.fileInfos.get(sourceFile.path);
|
||||
const oldInfo = useOldState ? oldState!.fileInfos.get(sourceFile.path) : undefined;
|
||||
if (referencedMap) {
|
||||
const newReferences = getReferencedFiles(newProgram, sourceFile, getCanonicalFileName);
|
||||
if (newReferences) {
|
||||
@@ -194,7 +194,7 @@ namespace ts.BuilderState {
|
||||
*/
|
||||
export function updateSignaturesFromCache(state: BuilderState, signatureCache: Map<string>) {
|
||||
signatureCache.forEach((signature, path) => {
|
||||
state.fileInfos.get(path).signature = signature;
|
||||
state.fileInfos.get(path)!.signature = signature;
|
||||
state.hasCalledUpdateShapeSignature.set(path, true);
|
||||
});
|
||||
}
|
||||
@@ -211,7 +211,7 @@ namespace ts.BuilderState {
|
||||
}
|
||||
|
||||
const info = state.fileInfos.get(sourceFile.path);
|
||||
Debug.assert(!!info);
|
||||
if (!info) return Debug.fail();
|
||||
|
||||
const prevSignature = info.signature;
|
||||
let latestSignature: string;
|
||||
@@ -224,7 +224,7 @@ namespace ts.BuilderState {
|
||||
latestSignature = computeHash(emitOutput.outputFiles[0].text);
|
||||
}
|
||||
else {
|
||||
latestSignature = prevSignature;
|
||||
latestSignature = prevSignature!; // TODO: GH#18217
|
||||
}
|
||||
}
|
||||
cacheToUpdateSignature.set(sourceFile.path, latestSignature);
|
||||
@@ -251,7 +251,7 @@ namespace ts.BuilderState {
|
||||
const seenMap = createMap<true>();
|
||||
const queue = [sourceFile.path];
|
||||
while (queue.length) {
|
||||
const path = queue.pop();
|
||||
const path = queue.pop()!;
|
||||
if (!seenMap.has(path)) {
|
||||
seenMap.set(path, true);
|
||||
const references = state.referencedMap.get(path);
|
||||
@@ -285,7 +285,7 @@ namespace ts.BuilderState {
|
||||
* Gets the files referenced by the the file path
|
||||
*/
|
||||
function getReferencedByPaths(state: Readonly<BuilderState>, referencedFilePath: Path) {
|
||||
return arrayFrom(mapDefinedIterator(state.referencedMap.entries(), ([filePath, referencesInFile]) =>
|
||||
return arrayFrom(mapDefinedIterator(state.referencedMap!.entries(), ([filePath, referencesInFile]) =>
|
||||
referencesInFile.has(referencedFilePath) ? filePath as Path : undefined
|
||||
));
|
||||
}
|
||||
@@ -314,7 +314,7 @@ namespace ts.BuilderState {
|
||||
return state.allFilesExcludingDefaultLibraryFile;
|
||||
}
|
||||
|
||||
let result: SourceFile[];
|
||||
let result: SourceFile[] | undefined;
|
||||
addSourceFile(firstSourceFile);
|
||||
for (const sourceFile of programOfThisState.getSourceFiles()) {
|
||||
if (sourceFile !== firstSourceFile) {
|
||||
@@ -366,11 +366,11 @@ namespace ts.BuilderState {
|
||||
seenFileNamesMap.set(sourceFileWithUpdatedShape.path, sourceFileWithUpdatedShape);
|
||||
const queue = getReferencedByPaths(state, sourceFileWithUpdatedShape.path);
|
||||
while (queue.length > 0) {
|
||||
const currentPath = queue.pop();
|
||||
const currentPath = queue.pop()!;
|
||||
if (!seenFileNamesMap.has(currentPath)) {
|
||||
const currentSourceFile = programOfThisState.getSourceFileByPath(currentPath);
|
||||
const currentSourceFile = programOfThisState.getSourceFileByPath(currentPath)!;
|
||||
seenFileNamesMap.set(currentPath, currentSourceFile);
|
||||
if (currentSourceFile && updateShapeSignature(state, programOfThisState, currentSourceFile, cacheToUpdateSignature, cancellationToken, computeHash)) {
|
||||
if (currentSourceFile && updateShapeSignature(state, programOfThisState, currentSourceFile, cacheToUpdateSignature, cancellationToken, computeHash!)) { // TODO: GH#18217
|
||||
queue.push(...getReferencedByPaths(state, currentPath));
|
||||
}
|
||||
}
|
||||
|
||||
+1085
-1009
File diff suppressed because it is too large
Load Diff
@@ -814,7 +814,7 @@ namespace ts {
|
||||
case "string":
|
||||
return map(values, v => v || "");
|
||||
default:
|
||||
return filter(map(values, v => parseCustomTypeOption(<CommandLineOptionOfCustomType>opt.element, v, errors)), v => !!v);
|
||||
return mapDefined(values, v => parseCustomTypeOption(<CommandLineOptionOfCustomType>opt.element, v, errors));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -965,7 +965,7 @@ namespace ts {
|
||||
* Reads the config file, reports errors if any and exits if the config file cannot be found
|
||||
*/
|
||||
export function getParsedCommandLineOfConfigFile(configFileName: string, optionsToExtend: CompilerOptions, host: ParseConfigFileHost): ParsedCommandLine | undefined {
|
||||
let configFileText: string;
|
||||
let configFileText: string | undefined;
|
||||
try {
|
||||
configFileText = host.readFile(configFileName);
|
||||
}
|
||||
@@ -1035,7 +1035,7 @@ namespace ts {
|
||||
function getTsconfigRootOptionsMap() {
|
||||
if (_tsconfigRootOptions === undefined) {
|
||||
_tsconfigRootOptions = {
|
||||
name: undefined, // should never be needed since this is root
|
||||
name: undefined!, // should never be needed since this is root
|
||||
type: "object",
|
||||
elementOptions: commandLineOptionsToMap([
|
||||
{
|
||||
@@ -1194,7 +1194,7 @@ namespace ts {
|
||||
if (parentOption) {
|
||||
if (isValidOptionValue) {
|
||||
// Notify option set in the parent if its a valid option value
|
||||
jsonConversionNotifier.onSetValidOptionKeyValueInParent(parentOption, option, value);
|
||||
jsonConversionNotifier.onSetValidOptionKeyValueInParent(parentOption, option!, value);
|
||||
}
|
||||
}
|
||||
else if (isRootOptionMap(knownOptions)) {
|
||||
@@ -1220,7 +1220,7 @@ namespace ts {
|
||||
return (returnValue ? elements.map : elements.forEach).call(elements, (element: Expression) => convertPropertyValueToJson(element, elementOption));
|
||||
}
|
||||
|
||||
function convertPropertyValueToJson(valueExpression: Expression, option: CommandLineOption): any {
|
||||
function convertPropertyValueToJson(valueExpression: Expression, option: CommandLineOption | undefined): any {
|
||||
switch (valueExpression.kind) {
|
||||
case SyntaxKind.TrueKeyword:
|
||||
reportInvalidOptionValue(option && option.type !== "boolean");
|
||||
@@ -1303,9 +1303,9 @@ namespace ts {
|
||||
|
||||
return undefined;
|
||||
|
||||
function reportInvalidOptionValue(isError: boolean) {
|
||||
function reportInvalidOptionValue(isError: boolean | undefined) {
|
||||
if (isError) {
|
||||
errors.push(createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, Diagnostics.Compiler_option_0_requires_a_value_of_type_1, option.name, getCompilerOptionValueTypeString(option)));
|
||||
errors.push(createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, Diagnostics.Compiler_option_0_requires_a_value_of_type_1, option!.name, getCompilerOptionValueTypeString(option!)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1321,7 +1321,7 @@ namespace ts {
|
||||
isString(option.type) ? option.type : "string";
|
||||
}
|
||||
|
||||
function isCompilerOptionsValue(option: CommandLineOption, value: any): value is CompilerOptionsValue {
|
||||
function isCompilerOptionsValue(option: CommandLineOption | undefined, value: any): value is CompilerOptionsValue {
|
||||
if (option) {
|
||||
if (isNullOrUndefined(value)) return true; // All options are undefinable/nullable
|
||||
if (option.type === "list") {
|
||||
@@ -1330,6 +1330,7 @@ namespace ts {
|
||||
const expectedType = isString(option.type) ? option.type : "string";
|
||||
return typeof value === expectedType;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1373,7 +1374,7 @@ namespace ts {
|
||||
if (hasProperty(options, name)) {
|
||||
// tsconfig only options cannot be specified via command line,
|
||||
// so we can assume that only types that can appear here string | number | boolean
|
||||
if (optionsNameMap.has(name) && optionsNameMap.get(name).category === Diagnostics.Command_line_Options) {
|
||||
if (optionsNameMap.has(name) && optionsNameMap.get(name)!.category === Diagnostics.Command_line_Options) {
|
||||
continue;
|
||||
}
|
||||
const value = <CompilerOptionsValue>options[name];
|
||||
@@ -1387,7 +1388,7 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
if (optionDefinition.type === "list") {
|
||||
result.set(name, (value as ReadonlyArray<string | number>).map(element => getNameOfCompilerOptionValue(element, customTypeMap)));
|
||||
result.set(name, (value as ReadonlyArray<string | number>).map(element => getNameOfCompilerOptionValue(element, customTypeMap)!)); // TODO: GH#18217
|
||||
}
|
||||
else {
|
||||
// There is a typeMap associated with this command-line option so use it to map value back to its name
|
||||
@@ -1436,7 +1437,7 @@ namespace ts {
|
||||
const { category } = option;
|
||||
|
||||
if (isAllowedOption(option)) {
|
||||
categorizedOptions.add(getLocaleSpecificMessage(category), option);
|
||||
categorizedOptions.add(getLocaleSpecificMessage(category!), option);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1517,7 +1518,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function setConfigFileInOptions(options: CompilerOptions, configFile: TsConfigSourceFile) {
|
||||
export function setConfigFileInOptions(options: CompilerOptions, configFile: TsConfigSourceFile | undefined) {
|
||||
if (configFile) {
|
||||
Object.defineProperty(options, "configFile", { enumerable: false, writable: false, value: configFile });
|
||||
}
|
||||
@@ -1545,7 +1546,7 @@ namespace ts {
|
||||
*/
|
||||
function parseJsonConfigFileContentWorker(
|
||||
json: any,
|
||||
sourceFile: TsConfigSourceFile,
|
||||
sourceFile: TsConfigSourceFile | undefined,
|
||||
host: ParseConfigHost,
|
||||
basePath: string,
|
||||
existingOptions: CompilerOptions = {},
|
||||
@@ -1575,7 +1576,7 @@ namespace ts {
|
||||
};
|
||||
|
||||
function getFileNames(): ExpandResult {
|
||||
let filesSpecs: ReadonlyArray<string>;
|
||||
let filesSpecs: ReadonlyArray<string> | undefined;
|
||||
if (hasProperty(raw, "files") && !isNullOrUndefined(raw.files)) {
|
||||
if (isArray(raw.files)) {
|
||||
filesSpecs = <ReadonlyArray<string>>raw.files;
|
||||
@@ -1588,7 +1589,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
let includeSpecs: ReadonlyArray<string>;
|
||||
let includeSpecs: ReadonlyArray<string> | undefined;
|
||||
if (hasProperty(raw, "include") && !isNullOrUndefined(raw.include)) {
|
||||
if (isArray(raw.include)) {
|
||||
includeSpecs = <ReadonlyArray<string>>raw.include;
|
||||
@@ -1598,7 +1599,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
let excludeSpecs: ReadonlyArray<string>;
|
||||
let excludeSpecs: ReadonlyArray<string> | undefined;
|
||||
if (hasProperty(raw, "exclude") && !isNullOrUndefined(raw.exclude)) {
|
||||
if (isArray(raw.exclude)) {
|
||||
excludeSpecs = <ReadonlyArray<string>>raw.exclude;
|
||||
@@ -1692,10 +1693,10 @@ namespace ts {
|
||||
*/
|
||||
function parseConfig(
|
||||
json: any,
|
||||
sourceFile: TsConfigSourceFile,
|
||||
sourceFile: TsConfigSourceFile | undefined,
|
||||
host: ParseConfigHost,
|
||||
basePath: string,
|
||||
configFileName: string,
|
||||
configFileName: string | undefined,
|
||||
resolutionStack: string[],
|
||||
errors: Push<Diagnostic>,
|
||||
): ParsedTsconfig {
|
||||
@@ -1704,17 +1705,17 @@ namespace ts {
|
||||
|
||||
if (resolutionStack.indexOf(resolvedPath) >= 0) {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Circularity_detected_while_resolving_configuration_Colon_0, [...resolutionStack, resolvedPath].join(" -> ")));
|
||||
return { raw: json || convertToObject(sourceFile, errors) };
|
||||
return { raw: json || convertToObject(sourceFile!, errors) };
|
||||
}
|
||||
|
||||
const ownConfig = json ?
|
||||
parseOwnConfigOfJson(json, host, basePath, configFileName, errors) :
|
||||
parseOwnConfigOfJsonSourceFile(sourceFile, host, basePath, configFileName, errors);
|
||||
parseOwnConfigOfJsonSourceFile(sourceFile!, host, basePath, configFileName, errors);
|
||||
|
||||
if (ownConfig.extendedConfigPath) {
|
||||
// copy the resolution stack so it is never reused between branches in potential diamond-problem scenarios.
|
||||
resolutionStack = resolutionStack.concat([resolvedPath]);
|
||||
const extendedConfig = getExtendedConfig(sourceFile, ownConfig.extendedConfigPath, host, basePath, resolutionStack, errors);
|
||||
const extendedConfig = getExtendedConfig(sourceFile!, ownConfig.extendedConfigPath, host, basePath, resolutionStack, errors);
|
||||
if (extendedConfig && isSuccessfulParsedTsconfig(extendedConfig)) {
|
||||
const baseRaw = extendedConfig.raw;
|
||||
const raw = ownConfig.raw;
|
||||
@@ -1754,7 +1755,7 @@ namespace ts {
|
||||
// It should be removed in future releases - use typeAcquisition instead.
|
||||
const typeAcquisition = convertTypeAcquisitionFromJsonWorker(json.typeAcquisition || json.typingOptions, basePath, errors, configFileName);
|
||||
json.compileOnSave = convertCompileOnSaveOptionFromJson(json, basePath, errors);
|
||||
let extendedConfigPath: string;
|
||||
let extendedConfigPath: string | undefined;
|
||||
|
||||
if (json.extends) {
|
||||
if (!isString(json.extends)) {
|
||||
@@ -1776,8 +1777,8 @@ namespace ts {
|
||||
errors: Push<Diagnostic>
|
||||
): ParsedTsconfig {
|
||||
const options = getDefaultCompilerOptions(configFileName);
|
||||
let typeAcquisition: TypeAcquisition, typingOptionstypeAcquisition: TypeAcquisition;
|
||||
let extendedConfigPath: string;
|
||||
let typeAcquisition: TypeAcquisition | undefined, typingOptionstypeAcquisition: TypeAcquisition | undefined;
|
||||
let extendedConfigPath: string | undefined;
|
||||
|
||||
const optionsIterator: JsonConversionNotifier = {
|
||||
onSetValidOptionKeyValueInParent(parentOption: string, option: CommandLineOption, value: CompilerOptionsValue) {
|
||||
@@ -1879,7 +1880,7 @@ namespace ts {
|
||||
const extendedConfig = parseConfig(/*json*/ undefined, extendedResult, host, extendedDirname,
|
||||
getBaseFileName(extendedConfigPath), resolutionStack, errors);
|
||||
if (sourceFile) {
|
||||
sourceFile.extendedSourceFiles.push(...extendedResult.extendedSourceFiles);
|
||||
sourceFile.extendedSourceFiles!.push(...extendedResult.extendedSourceFiles!);
|
||||
}
|
||||
|
||||
if (isSuccessfulParsedTsconfig(extendedConfig)) {
|
||||
@@ -1903,13 +1904,10 @@ namespace ts {
|
||||
|
||||
function convertCompileOnSaveOptionFromJson(jsonOption: any, basePath: string, errors: Push<Diagnostic>): boolean {
|
||||
if (!hasProperty(jsonOption, compileOnSaveCommandLineOption.name)) {
|
||||
return undefined;
|
||||
return false;
|
||||
}
|
||||
const result = convertJsonOption(compileOnSaveCommandLineOption, jsonOption.compileOnSave, basePath, errors);
|
||||
if (typeof result === "boolean" && result) {
|
||||
return result;
|
||||
}
|
||||
return false;
|
||||
return typeof result === "boolean" && result;
|
||||
}
|
||||
|
||||
export function convertCompilerOptionsFromJson(jsonOptions: any, basePath: string, configFileName?: string): { options: CompilerOptions, errors: Diagnostic[] } {
|
||||
@@ -1943,7 +1941,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getDefaultTypeAcquisition(configFileName?: string): TypeAcquisition {
|
||||
return { enable: configFileName && getBaseFileName(configFileName) === "jsconfig.json", include: [], exclude: [] };
|
||||
return { enable: !!configFileName && getBaseFileName(configFileName) === "jsconfig.json", include: [], exclude: [] };
|
||||
}
|
||||
|
||||
function convertTypeAcquisitionFromJsonWorker(jsonOptions: any,
|
||||
@@ -2106,18 +2104,18 @@ namespace ts {
|
||||
* @param errors An array for diagnostic reporting.
|
||||
*/
|
||||
function matchFileNames(
|
||||
filesSpecs: ReadonlyArray<string>,
|
||||
includeSpecs: ReadonlyArray<string>,
|
||||
excludeSpecs: ReadonlyArray<string>,
|
||||
filesSpecs: ReadonlyArray<string> | undefined,
|
||||
includeSpecs: ReadonlyArray<string> | undefined,
|
||||
excludeSpecs: ReadonlyArray<string> | undefined,
|
||||
basePath: string,
|
||||
options: CompilerOptions,
|
||||
host: ParseConfigHost,
|
||||
errors: Push<Diagnostic>,
|
||||
extraFileExtensions: ReadonlyArray<FileExtensionInfo>,
|
||||
jsonSourceFile: TsConfigSourceFile
|
||||
jsonSourceFile: TsConfigSourceFile | undefined
|
||||
): ExpandResult {
|
||||
basePath = normalizePath(basePath);
|
||||
let validatedIncludeSpecs: ReadonlyArray<string>, validatedExcludeSpecs: ReadonlyArray<string>;
|
||||
let validatedIncludeSpecs: ReadonlyArray<string> | undefined, validatedExcludeSpecs: ReadonlyArray<string> | undefined;
|
||||
|
||||
// The exclude spec list is converted into a regular expression, which allows us to quickly
|
||||
// test whether a file or directory should be excluded before recursively traversing the
|
||||
@@ -2223,7 +2221,7 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
function validateSpecs(specs: ReadonlyArray<string>, errors: Push<Diagnostic>, allowTrailingRecursion: boolean, jsonSourceFile: TsConfigSourceFile, specKey: string): ReadonlyArray<string> {
|
||||
function validateSpecs(specs: ReadonlyArray<string>, errors: Push<Diagnostic>, allowTrailingRecursion: boolean, jsonSourceFile: TsConfigSourceFile | undefined, specKey: string): ReadonlyArray<string> {
|
||||
return specs.filter(spec => {
|
||||
const diag = specToDiagnostic(spec, allowTrailingRecursion);
|
||||
if (diag !== undefined) {
|
||||
@@ -2235,7 +2233,7 @@ namespace ts {
|
||||
function createDiagnostic(message: DiagnosticMessage, spec: string): Diagnostic {
|
||||
const element = getTsConfigPropArrayElementValue(jsonSourceFile, specKey, spec);
|
||||
return element ?
|
||||
createDiagnosticForNodeInSourceFile(jsonSourceFile, element, message, spec) :
|
||||
createDiagnosticForNodeInSourceFile(jsonSourceFile!, element, message, spec) :
|
||||
createCompilerDiagnostic(message, spec);
|
||||
}
|
||||
}
|
||||
@@ -2252,7 +2250,7 @@ namespace ts {
|
||||
/**
|
||||
* Gets directories in a set of include patterns that should be watched for changes.
|
||||
*/
|
||||
function getWildcardDirectories(include: ReadonlyArray<string>, exclude: ReadonlyArray<string>, path: string, useCaseSensitiveFileNames: boolean): MapLike<WatchDirectoryFlags> {
|
||||
function getWildcardDirectories(include: ReadonlyArray<string> | undefined, exclude: ReadonlyArray<string> | undefined, path: string, useCaseSensitiveFileNames: boolean): MapLike<WatchDirectoryFlags> {
|
||||
// We watch a directory recursively if it contains a wildcard anywhere in a directory segment
|
||||
// of the pattern:
|
||||
//
|
||||
@@ -2394,7 +2392,7 @@ namespace ts {
|
||||
if (optionEnumValue === value) {
|
||||
return optionStringValue;
|
||||
}
|
||||
});
|
||||
})!; // TODO: GH#18217
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
-14
@@ -3,8 +3,8 @@ namespace ts {
|
||||
export interface CommentWriter {
|
||||
reset(): void;
|
||||
setSourceFile(sourceFile: SourceFile): void;
|
||||
setWriter(writer: EmitTextWriter): void;
|
||||
emitNodeWithComments(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
|
||||
setWriter(writer: EmitTextWriter | undefined): void;
|
||||
emitNodeWithComments(hint: EmitHint, node: Node | undefined, emitCallback: (hint: EmitHint, node: Node) => void): void;
|
||||
emitBodyWithDetachedComments(node: Node, detachedRange: TextRange, emitCallback: (node: Node) => void): void;
|
||||
emitTrailingCommentsOfPosition(pos: number, prefixSpace?: boolean): void;
|
||||
emitLeadingCommentsOfPosition(pos: number): void;
|
||||
@@ -20,9 +20,9 @@ namespace ts {
|
||||
let currentSourceFile: SourceFile;
|
||||
let currentText: string;
|
||||
let currentLineMap: ReadonlyArray<number>;
|
||||
let detachedCommentsInfo: { nodePos: number, detachedCommentEndPos: number}[];
|
||||
let detachedCommentsInfo: { nodePos: number, detachedCommentEndPos: number}[] | undefined;
|
||||
let hasWrittenComment = false;
|
||||
let disabled: boolean = printerOptions.removeComments;
|
||||
let disabled: boolean = !!printerOptions.removeComments;
|
||||
|
||||
return {
|
||||
reset,
|
||||
@@ -44,7 +44,7 @@ namespace ts {
|
||||
hasWrittenComment = false;
|
||||
|
||||
const emitNode = node.emitNode;
|
||||
const emitFlags = emitNode && emitNode.flags;
|
||||
const emitFlags = emitNode && emitNode.flags || 0;
|
||||
const { pos, end } = emitNode && emitNode.commentRange || node;
|
||||
if ((pos < 0 && end < 0) || (pos === end)) {
|
||||
// Both pos and end are synthesized, so just emit the node without comments.
|
||||
@@ -114,7 +114,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitNodeWithSynthesizedComments(hint: EmitHint, node: Node, emitNode: EmitNode, emitFlags: EmitFlags, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
function emitNodeWithSynthesizedComments(hint: EmitHint, node: Node, emitNode: EmitNode | undefined, emitFlags: EmitFlags, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
const leadingComments = emitNode && emitNode.leadingComments;
|
||||
if (some(leadingComments)) {
|
||||
if (extendedDiagnostics) {
|
||||
@@ -170,7 +170,7 @@ namespace ts {
|
||||
function writeSynthesizedComment(comment: SynthesizedComment) {
|
||||
const text = formatSynthesizedComment(comment);
|
||||
const lineMap = comment.kind === SyntaxKind.MultiLineCommentTrivia ? computeLineStarts(text) : undefined;
|
||||
writeCommentRange(text, lineMap, writer, 0, text.length, newLine);
|
||||
writeCommentRange(text, lineMap!, writer, 0, text.length, newLine);
|
||||
}
|
||||
|
||||
function formatSynthesizedComment(comment: SynthesizedComment) {
|
||||
@@ -364,9 +364,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
function reset() {
|
||||
currentSourceFile = undefined;
|
||||
currentText = undefined;
|
||||
currentLineMap = undefined;
|
||||
currentSourceFile = undefined!;
|
||||
currentText = undefined!;
|
||||
currentLineMap = undefined!;
|
||||
detachedCommentsInfo = undefined;
|
||||
}
|
||||
|
||||
@@ -382,14 +382,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
function hasDetachedComments(pos: number) {
|
||||
return detachedCommentsInfo !== undefined && lastOrUndefined(detachedCommentsInfo).nodePos === pos;
|
||||
return detachedCommentsInfo !== undefined && last(detachedCommentsInfo).nodePos === pos;
|
||||
}
|
||||
|
||||
function forEachLeadingCommentWithoutDetachedComments(cb: (commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) => void) {
|
||||
// get the leading comments from detachedPos
|
||||
const pos = lastOrUndefined(detachedCommentsInfo).detachedCommentEndPos;
|
||||
if (detachedCommentsInfo.length - 1) {
|
||||
detachedCommentsInfo.pop();
|
||||
const pos = last(detachedCommentsInfo!).detachedCommentEndPos;
|
||||
if (detachedCommentsInfo!.length - 1) {
|
||||
detachedCommentsInfo!.pop();
|
||||
}
|
||||
else {
|
||||
detachedCommentsInfo = undefined;
|
||||
|
||||
+124
-97
@@ -59,7 +59,7 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function createMapFromTemplate<T>(template?: MapLike<T>): Map<T> {
|
||||
export function createMapFromTemplate<T>(template: MapLike<T>): Map<T> {
|
||||
const map: Map<T> = new MapCtr<T>();
|
||||
|
||||
// Copies keys/values from template. Note that for..in will not throw if
|
||||
@@ -107,7 +107,7 @@ namespace ts {
|
||||
private data = createDictionaryObject<T>();
|
||||
public size = 0;
|
||||
|
||||
get(key: string): T {
|
||||
get(key: string): T | undefined {
|
||||
return this.data[key];
|
||||
}
|
||||
|
||||
@@ -138,15 +138,15 @@ namespace ts {
|
||||
this.size = 0;
|
||||
}
|
||||
|
||||
keys() {
|
||||
keys(): Iterator<string> {
|
||||
return new MapIterator(this.data, (_data, key) => key);
|
||||
}
|
||||
|
||||
values() {
|
||||
values(): Iterator<T> {
|
||||
return new MapIterator(this.data, (data, key) => data[key]);
|
||||
}
|
||||
|
||||
entries() {
|
||||
entries(): Iterator<[string, T]> {
|
||||
return new MapIterator(this.data, (data, key) => [key, data[key]] as [string, T]);
|
||||
}
|
||||
|
||||
@@ -158,14 +158,14 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
export function toPath(fileName: string, basePath: string, getCanonicalFileName: (path: string) => string): Path {
|
||||
export function toPath(fileName: string, basePath: string | undefined, getCanonicalFileName: (path: string) => string): Path {
|
||||
const nonCanonicalizedPath = isRootedDiskPath(fileName)
|
||||
? normalizePath(fileName)
|
||||
: getNormalizedAbsolutePath(fileName, basePath);
|
||||
return <Path>getCanonicalFileName(nonCanonicalizedPath);
|
||||
}
|
||||
|
||||
export function length(array: ReadonlyArray<any>) {
|
||||
export function length(array: ReadonlyArray<any> | undefined): number {
|
||||
return array ? array.length : 0;
|
||||
}
|
||||
|
||||
@@ -220,9 +220,9 @@ namespace ts {
|
||||
* If no such value is found, it applies the callback until the parent pointer is undefined or the callback returns "quit"
|
||||
* At that point findAncestor returns undefined.
|
||||
*/
|
||||
export function findAncestor<T extends Node>(node: Node, callback: (element: Node) => element is T): T | undefined;
|
||||
export function findAncestor(node: Node, callback: (element: Node) => boolean | "quit"): Node | undefined;
|
||||
export function findAncestor(node: Node, callback: (element: Node) => boolean | "quit"): Node {
|
||||
export function findAncestor<T extends Node>(node: Node | undefined, callback: (element: Node) => element is T): T | undefined;
|
||||
export function findAncestor(node: Node | undefined, callback: (element: Node) => boolean | "quit"): Node | undefined;
|
||||
export function findAncestor(node: Node, callback: (element: Node) => boolean | "quit"): Node | undefined {
|
||||
while (node) {
|
||||
const result = callback(node);
|
||||
if (result === "quit") {
|
||||
@@ -340,10 +340,10 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Debug.fail();
|
||||
return Debug.fail();
|
||||
}
|
||||
|
||||
export function contains<T>(array: ReadonlyArray<T>, value: T, equalityComparer: EqualityComparer<T> = equateValues): boolean {
|
||||
export function contains<T>(array: ReadonlyArray<T> | undefined, value: T, equalityComparer: EqualityComparer<T> = equateValues): boolean {
|
||||
if (array) {
|
||||
for (const v of array) {
|
||||
if (equalityComparer(v, value)) {
|
||||
@@ -388,7 +388,11 @@ namespace ts {
|
||||
export function filter<T>(array: T[], f: (x: T) => boolean): T[];
|
||||
export function filter<T, U extends T>(array: ReadonlyArray<T>, f: (x: T) => x is U): ReadonlyArray<U>;
|
||||
export function filter<T, U extends T>(array: ReadonlyArray<T>, f: (x: T) => boolean): ReadonlyArray<T>;
|
||||
export function filter<T>(array: T[], f: (x: T) => boolean): T[] {
|
||||
export function filter<T, U extends T>(array: T[] | undefined, f: (x: T) => x is U): U[] | undefined;
|
||||
export function filter<T>(array: T[] | undefined, f: (x: T) => boolean): T[] | undefined;
|
||||
export function filter<T, U extends T>(array: ReadonlyArray<T> | undefined, f: (x: T) => x is U): ReadonlyArray<U> | undefined;
|
||||
export function filter<T, U extends T>(array: ReadonlyArray<T> | undefined, f: (x: T) => boolean): ReadonlyArray<T> | undefined;
|
||||
export function filter<T>(array: ReadonlyArray<T> | undefined, f: (x: T) => boolean): ReadonlyArray<T> | undefined {
|
||||
if (array) {
|
||||
const len = array.length;
|
||||
let i = 0;
|
||||
@@ -424,8 +428,10 @@ namespace ts {
|
||||
array.length = 0;
|
||||
}
|
||||
|
||||
export function map<T, U>(array: ReadonlyArray<T>, f: (x: T, i: number) => U): U[] {
|
||||
let result: U[];
|
||||
export function map<T, U>(array: ReadonlyArray<T>, f: (x: T, i: number) => U): U[];
|
||||
export function map<T, U>(array: ReadonlyArray<T> | undefined, f: (x: T, i: number) => U): U[] | undefined;
|
||||
export function map<T, U>(array: ReadonlyArray<T> | undefined, f: (x: T, i: number) => U): U[] | undefined {
|
||||
let result: U[] | undefined;
|
||||
if (array) {
|
||||
result = [];
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
@@ -448,7 +454,9 @@ namespace ts {
|
||||
// Maps from T to T and avoids allocation if all elements map to themselves
|
||||
export function sameMap<T>(array: T[], f: (x: T, i: number) => T): T[];
|
||||
export function sameMap<T>(array: ReadonlyArray<T>, f: (x: T, i: number) => T): ReadonlyArray<T>;
|
||||
export function sameMap<T>(array: T[], f: (x: T, i: number) => T): T[] {
|
||||
export function sameMap<T>(array: T[] | undefined, f: (x: T, i: number) => T): T[] | undefined;
|
||||
export function sameMap<T>(array: ReadonlyArray<T> | undefined, f: (x: T, i: number) => T): ReadonlyArray<T> | undefined;
|
||||
export function sameMap<T>(array: ReadonlyArray<T> | undefined, f: (x: T, i: number) => T): ReadonlyArray<T> | undefined {
|
||||
if (array) {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const item = array[i];
|
||||
@@ -471,8 +479,10 @@ namespace ts {
|
||||
*
|
||||
* @param array The array to flatten.
|
||||
*/
|
||||
export function flatten<T>(array: ReadonlyArray<T | ReadonlyArray<T>>): T[] {
|
||||
let result: T[];
|
||||
export function flatten<T>(array: ReadonlyArray<T | ReadonlyArray<T> | undefined>): T[];
|
||||
export function flatten<T>(array: ReadonlyArray<T | ReadonlyArray<T> | undefined> | undefined): T[] | undefined;
|
||||
export function flatten<T>(array: ReadonlyArray<T | ReadonlyArray<T> | undefined> | undefined): T[] | undefined {
|
||||
let result: T[] | undefined;
|
||||
if (array) {
|
||||
result = [];
|
||||
for (const v of array) {
|
||||
@@ -496,8 +506,10 @@ namespace ts {
|
||||
* @param array The array to map.
|
||||
* @param mapfn The callback used to map the result into one or more values.
|
||||
*/
|
||||
export function flatMap<T, U>(array: ReadonlyArray<T>, mapfn: (x: T, i: number) => U | ReadonlyArray<U> | undefined): U[];
|
||||
export function flatMap<T, U>(array: ReadonlyArray<T> | undefined, mapfn: (x: T, i: number) => U | ReadonlyArray<U> | undefined): U[] | undefined;
|
||||
export function flatMap<T, U>(array: ReadonlyArray<T> | undefined, mapfn: (x: T, i: number) => U | ReadonlyArray<U> | undefined): U[] | undefined {
|
||||
let result: U[];
|
||||
let result: U[] | undefined;
|
||||
if (array) {
|
||||
result = [];
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
@@ -553,7 +565,7 @@ namespace ts {
|
||||
export function sameFlatMap<T>(array: T[], mapfn: (x: T, i: number) => T | ReadonlyArray<T>): T[];
|
||||
export function sameFlatMap<T>(array: ReadonlyArray<T>, mapfn: (x: T, i: number) => T | ReadonlyArray<T>): ReadonlyArray<T>;
|
||||
export function sameFlatMap<T>(array: T[], mapfn: (x: T, i: number) => T | T[]): T[] {
|
||||
let result: T[];
|
||||
let result: T[] | undefined;
|
||||
if (array) {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const item = array[i];
|
||||
@@ -636,13 +648,15 @@ namespace ts {
|
||||
* @param keyfn A callback used to select the key for an element.
|
||||
* @param mapfn A callback used to map a contiguous chunk of values to a single value.
|
||||
*/
|
||||
export function spanMap<T, K, U>(array: ReadonlyArray<T>, keyfn: (x: T, i: number) => K, mapfn: (chunk: T[], key: K, start: number, end: number) => U): U[] {
|
||||
let result: U[];
|
||||
export function spanMap<T, K, U>(array: ReadonlyArray<T>, keyfn: (x: T, i: number) => K, mapfn: (chunk: T[], key: K, start: number, end: number) => U): U[];
|
||||
export function spanMap<T, K, U>(array: ReadonlyArray<T> | undefined, keyfn: (x: T, i: number) => K, mapfn: (chunk: T[], key: K, start: number, end: number) => U): U[] | undefined;
|
||||
export function spanMap<T, K, U>(array: ReadonlyArray<T> | undefined, keyfn: (x: T, i: number) => K, mapfn: (chunk: T[], key: K, start: number, end: number) => U): U[] | undefined {
|
||||
let result: U[] | undefined;
|
||||
if (array) {
|
||||
result = [];
|
||||
const len = array.length;
|
||||
let previousKey: K;
|
||||
let key: K;
|
||||
let previousKey: K | undefined;
|
||||
let key: K | undefined;
|
||||
let start = 0;
|
||||
let pos = 0;
|
||||
while (start < len) {
|
||||
@@ -660,7 +674,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (start < pos) {
|
||||
const v = mapfn(array.slice(start, pos), previousKey, start, pos);
|
||||
const v = mapfn(array.slice(start, pos), previousKey!, start, pos);
|
||||
if (v) {
|
||||
result.push(v);
|
||||
}
|
||||
@@ -676,7 +690,9 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function mapEntries<T, U>(map: ReadonlyMap<T>, f: (key: string, value: T) => [string, U]): Map<U> {
|
||||
export function mapEntries<T, U>(map: ReadonlyMap<T>, f: (key: string, value: T) => [string, U]): Map<U>;
|
||||
export function mapEntries<T, U>(map: ReadonlyMap<T> | undefined, f: (key: string, value: T) => [string, U]): Map<U> | undefined;
|
||||
export function mapEntries<T, U>(map: ReadonlyMap<T> | undefined, f: (key: string, value: T) => [string, U]): Map<U> | undefined {
|
||||
if (!map) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -688,8 +704,9 @@ namespace ts {
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
export function some<T>(array: ReadonlyArray<T>, predicate?: (value: T) => boolean): boolean {
|
||||
export function some<T>(array: ReadonlyArray<T> | undefined): array is ReadonlyArray<T>;
|
||||
export function some<T>(array: ReadonlyArray<T> | undefined, predicate: (value: T) => boolean): boolean;
|
||||
export function some<T>(array: ReadonlyArray<T> | undefined, predicate?: (value: T) => boolean): boolean {
|
||||
if (array) {
|
||||
if (predicate) {
|
||||
for (const v of array) {
|
||||
@@ -724,6 +741,8 @@ namespace ts {
|
||||
|
||||
export function concatenate<T>(array1: T[], array2: T[]): T[];
|
||||
export function concatenate<T>(array1: ReadonlyArray<T>, array2: ReadonlyArray<T>): ReadonlyArray<T>;
|
||||
export function concatenate<T>(array1: T[] | undefined, array2: T[] | undefined): T[];
|
||||
export function concatenate<T>(array1: ReadonlyArray<T> | undefined, array2: ReadonlyArray<T> | undefined): ReadonlyArray<T>;
|
||||
export function concatenate<T>(array1: T[], array2: T[]): T[] {
|
||||
if (!some(array2)) return array1;
|
||||
if (!some(array1)) return array2;
|
||||
@@ -766,7 +785,9 @@ namespace ts {
|
||||
* @param comparer An optional `Comparer` used to sort entries before comparison, though the
|
||||
* result will remain in the original order in `array`.
|
||||
*/
|
||||
export function deduplicate<T>(array: ReadonlyArray<T>, equalityComparer: EqualityComparer<T>, comparer?: Comparer<T>): T[] {
|
||||
export function deduplicate<T>(array: ReadonlyArray<T>, equalityComparer?: EqualityComparer<T>, comparer?: Comparer<T>): T[];
|
||||
export function deduplicate<T>(array: ReadonlyArray<T> | undefined, equalityComparer?: EqualityComparer<T>, comparer?: Comparer<T>): T[] | undefined;
|
||||
export function deduplicate<T>(array: ReadonlyArray<T> | undefined, equalityComparer: EqualityComparer<T>, comparer?: Comparer<T>): T[] | undefined {
|
||||
return !array ? undefined :
|
||||
array.length === 0 ? [] :
|
||||
array.length === 1 ? array.slice() :
|
||||
@@ -777,7 +798,9 @@ namespace ts {
|
||||
/**
|
||||
* Deduplicates an array that has already been sorted.
|
||||
*/
|
||||
function deduplicateSorted<T>(array: ReadonlyArray<T>, comparer: EqualityComparer<T> | Comparer<T>) {
|
||||
function deduplicateSorted<T>(array: ReadonlyArray<T>, comparer: EqualityComparer<T> | Comparer<T>): T[];
|
||||
function deduplicateSorted<T>(array: ReadonlyArray<T> | undefined, comparer: EqualityComparer<T> | Comparer<T>): T[] | undefined;
|
||||
function deduplicateSorted<T>(array: ReadonlyArray<T> | undefined, comparer: EqualityComparer<T> | Comparer<T>): T[] | undefined {
|
||||
if (!array) return undefined;
|
||||
if (array.length === 0) return [];
|
||||
|
||||
@@ -820,7 +843,7 @@ namespace ts {
|
||||
return deduplicateSorted(sort(array, comparer), equalityComparer || comparer);
|
||||
}
|
||||
|
||||
export function arrayIsEqualTo<T>(array1: ReadonlyArray<T>, array2: ReadonlyArray<T>, equalityComparer: (a: T, b: T) => boolean = equateValues): boolean {
|
||||
export function arrayIsEqualTo<T>(array1: ReadonlyArray<T> | undefined, array2: ReadonlyArray<T> | undefined, equalityComparer: (a: T, b: T) => boolean = equateValues): boolean {
|
||||
if (!array1 || !array2) {
|
||||
return array1 === array2;
|
||||
}
|
||||
@@ -863,7 +886,7 @@ namespace ts {
|
||||
export function compact<T>(array: T[]): T[];
|
||||
export function compact<T>(array: ReadonlyArray<T>): ReadonlyArray<T>;
|
||||
export function compact<T>(array: T[]): T[] {
|
||||
let result: T[];
|
||||
let result: T[] | undefined;
|
||||
if (array) {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const v = array[i];
|
||||
@@ -939,6 +962,9 @@ namespace ts {
|
||||
* @param value The value to append to the array. If `value` is `undefined`, nothing is
|
||||
* appended.
|
||||
*/
|
||||
export function append<T>(to: T[], value: T | undefined): T[];
|
||||
export function append<T>(to: T[] | undefined, value: T): T[];
|
||||
export function append<T>(to: T[] | undefined, value: T | undefined): T[] | undefined;
|
||||
export function append<T>(to: T[] | undefined, value: T | undefined): T[] | undefined {
|
||||
if (value === undefined) return to;
|
||||
if (to === undefined) return [value];
|
||||
@@ -964,6 +990,8 @@ namespace ts {
|
||||
* @param start The offset in `from` at which to start copying values.
|
||||
* @param end The offset in `from` at which to stop copying values (non-inclusive).
|
||||
*/
|
||||
export function addRange<T>(to: T[], from: ReadonlyArray<T> | undefined, start?: number, end?: number): T[];
|
||||
export function addRange<T>(to: T[] | undefined, from: ReadonlyArray<T> | undefined, start?: number, end?: number): T[] | undefined;
|
||||
export function addRange<T>(to: T[] | undefined, from: ReadonlyArray<T> | undefined, start?: number, end?: number): T[] | undefined {
|
||||
if (from === undefined || from.length === 0) return to;
|
||||
if (to === undefined) return from.slice(start, end);
|
||||
@@ -1026,7 +1054,7 @@ namespace ts {
|
||||
/**
|
||||
* Returns a new sorted array.
|
||||
*/
|
||||
export function sort<T>(array: ReadonlyArray<T>, comparer: Comparer<T>) {
|
||||
export function sort<T>(array: ReadonlyArray<T>, comparer: Comparer<T>): T[] {
|
||||
return array.slice().sort(comparer);
|
||||
}
|
||||
|
||||
@@ -1120,7 +1148,7 @@ namespace ts {
|
||||
/**
|
||||
* Returns the only element of an array if it contains only one element, `undefined` otherwise.
|
||||
*/
|
||||
export function singleOrUndefined<T>(array: ReadonlyArray<T>): T | undefined {
|
||||
export function singleOrUndefined<T>(array: ReadonlyArray<T> | undefined): T | undefined {
|
||||
return array && array.length === 1
|
||||
? array[0]
|
||||
: undefined;
|
||||
@@ -1132,7 +1160,9 @@ namespace ts {
|
||||
*/
|
||||
export function singleOrMany<T>(array: T[]): T | T[];
|
||||
export function singleOrMany<T>(array: ReadonlyArray<T>): T | ReadonlyArray<T>;
|
||||
export function singleOrMany<T>(array: T[]): T | T[] {
|
||||
export function singleOrMany<T>(array: T[] | undefined): T | T[] | undefined;
|
||||
export function singleOrMany<T>(array: ReadonlyArray<T> | undefined): T | ReadonlyArray<T> | undefined;
|
||||
export function singleOrMany<T>(array: ReadonlyArray<T> | undefined): T | ReadonlyArray<T> | undefined {
|
||||
return array && array.length === 1
|
||||
? array[0]
|
||||
: array;
|
||||
@@ -1181,9 +1211,9 @@ namespace ts {
|
||||
return ~low;
|
||||
}
|
||||
|
||||
export function reduceLeft<T, U>(array: ReadonlyArray<T>, f: (memo: U, value: T, i: number) => U, initial: U, start?: number, count?: number): U;
|
||||
export function reduceLeft<T>(array: ReadonlyArray<T>, f: (memo: T, value: T, i: number) => T): T;
|
||||
export function reduceLeft<T>(array: T[], f: (memo: T, value: T, i: number) => T, initial?: T, start?: number, count?: number): T {
|
||||
export function reduceLeft<T, U>(array: ReadonlyArray<T> | undefined, f: (memo: U, value: T, i: number) => U, initial: U, start?: number, count?: number): U;
|
||||
export function reduceLeft<T>(array: ReadonlyArray<T>, f: (memo: T, value: T, i: number) => T): T | undefined;
|
||||
export function reduceLeft<T>(array: T[], f: (memo: T, value: T, i: number) => T, initial?: T, start?: number, count?: number): T | undefined {
|
||||
if (array && array.length > 0) {
|
||||
const size = array.length;
|
||||
if (size > 0) {
|
||||
@@ -1195,7 +1225,7 @@ namespace ts {
|
||||
pos++;
|
||||
}
|
||||
else {
|
||||
result = initial;
|
||||
result = initial!;
|
||||
}
|
||||
while (pos <= end) {
|
||||
result = f(result, array[pos], pos);
|
||||
@@ -1306,11 +1336,11 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
|
||||
export function assign<T extends object>(t: T, ...args: T[]) {
|
||||
export function assign<T extends object>(t: T, ...args: (T | undefined)[]) {
|
||||
for (const arg of args) {
|
||||
for (const p in arg) {
|
||||
if (hasProperty(arg, p)) {
|
||||
t[p] = arg[p];
|
||||
for (const p in arg!) {
|
||||
if (hasProperty(arg!, p)) {
|
||||
t![p] = arg![p]; // TODO: GH#23368
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1323,7 +1353,7 @@ namespace ts {
|
||||
* @param left A map-like whose properties should be compared.
|
||||
* @param right A map-like whose properties should be compared.
|
||||
*/
|
||||
export function equalOwnProperties<T>(left: MapLike<T>, right: MapLike<T>, equalityComparer: EqualityComparer<T> = equateValues) {
|
||||
export function equalOwnProperties<T>(left: MapLike<T> | undefined, right: MapLike<T> | undefined, equalityComparer: EqualityComparer<T> = equateValues) {
|
||||
if (left === right) return true;
|
||||
if (!left || !right) return false;
|
||||
for (const key in left) {
|
||||
@@ -1503,10 +1533,10 @@ namespace ts {
|
||||
if (value !== undefined && test(value)) return value;
|
||||
|
||||
if (value && typeof (value as any).kind === "number") {
|
||||
Debug.fail(`Invalid cast. The supplied ${Debug.showSyntaxKind(value as any as Node)} did not pass the test '${Debug.getFunctionName(test)}'.`);
|
||||
return Debug.fail(`Invalid cast. The supplied ${Debug.showSyntaxKind(value as any as Node)} did not pass the test '${Debug.getFunctionName(test)}'.`);
|
||||
}
|
||||
else {
|
||||
Debug.fail(`Invalid cast. The supplied value did not pass the test '${Debug.getFunctionName(test)}'.`);
|
||||
return Debug.fail(`Invalid cast. The supplied value did not pass the test '${Debug.getFunctionName(test)}'.`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1535,7 +1565,7 @@ namespace ts {
|
||||
return () => {
|
||||
if (callback) {
|
||||
value = callback();
|
||||
callback = undefined;
|
||||
callback = undefined!;
|
||||
}
|
||||
return value;
|
||||
};
|
||||
@@ -1607,19 +1637,17 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function formatStringFromArgs(text: string, args: ArrayLike<string>, baseIndex?: number): string {
|
||||
baseIndex = baseIndex || 0;
|
||||
|
||||
return text.replace(/{(\d+)}/g, (_match, index?: string) => Debug.assertDefined(args[+index + baseIndex]));
|
||||
export function formatStringFromArgs(text: string, args: ArrayLike<string>, baseIndex = 0): string {
|
||||
return text.replace(/{(\d+)}/g, (_match, index: string) => Debug.assertDefined(args[+index + baseIndex]));
|
||||
}
|
||||
|
||||
export let localizedDiagnosticMessages: MapLike<string>;
|
||||
export let localizedDiagnosticMessages: MapLike<string> | undefined;
|
||||
|
||||
export function getLocaleSpecificMessage(message: DiagnosticMessage) {
|
||||
return localizedDiagnosticMessages && localizedDiagnosticMessages[message.key] || message.message;
|
||||
}
|
||||
|
||||
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: (string | number)[]): DiagnosticWithLocation;
|
||||
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithLocation;
|
||||
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage): DiagnosticWithLocation {
|
||||
Debug.assertGreaterThanOrEqual(start, 0);
|
||||
Debug.assertGreaterThanOrEqual(length, 0);
|
||||
@@ -1658,7 +1686,7 @@ namespace ts {
|
||||
return text;
|
||||
}
|
||||
|
||||
export function createCompilerDiagnostic(message: DiagnosticMessage, ...args: (string | number)[]): Diagnostic;
|
||||
export function createCompilerDiagnostic(message: DiagnosticMessage, ...args: (string | number | undefined)[]): Diagnostic;
|
||||
export function createCompilerDiagnostic(message: DiagnosticMessage): Diagnostic {
|
||||
let text = getLocaleSpecificMessage(message);
|
||||
|
||||
@@ -1690,8 +1718,8 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
export function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage, ...args: string[]): DiagnosticMessageChain;
|
||||
export function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage): DiagnosticMessageChain {
|
||||
export function chainDiagnosticMessages(details: DiagnosticMessageChain | undefined, message: DiagnosticMessage, ...args: (string | undefined)[]): DiagnosticMessageChain;
|
||||
export function chainDiagnosticMessages(details: DiagnosticMessageChain | undefined, message: DiagnosticMessage): DiagnosticMessageChain {
|
||||
let text = getLocaleSpecificMessage(message);
|
||||
|
||||
if (arguments.length > 2) {
|
||||
@@ -1746,9 +1774,9 @@ namespace ts {
|
||||
return equateValues(a, b);
|
||||
}
|
||||
|
||||
function compareComparableValues(a: string, b: string): Comparison;
|
||||
function compareComparableValues(a: number, b: number): Comparison;
|
||||
function compareComparableValues(a: string | number, b: string | number) {
|
||||
function compareComparableValues(a: string | undefined, b: string | undefined): Comparison;
|
||||
function compareComparableValues(a: number | undefined, b: number | undefined): Comparison;
|
||||
function compareComparableValues(a: string | number | undefined, b: string | number | undefined) {
|
||||
return a === b ? Comparison.EqualTo :
|
||||
a === undefined ? Comparison.LessThan :
|
||||
b === undefined ? Comparison.GreaterThan :
|
||||
@@ -1760,7 +1788,7 @@ namespace ts {
|
||||
* Compare two numeric values for their order relative to each other.
|
||||
* To compare strings, use any of the `compareStrings` functions.
|
||||
*/
|
||||
export function compareValues(a: number, b: number) {
|
||||
export function compareValues(a: number | undefined, b: number | undefined): Comparison {
|
||||
return compareComparableValues(a, b);
|
||||
}
|
||||
|
||||
@@ -1799,7 +1827,7 @@ namespace ts {
|
||||
* Case-sensitive comparisons compare both strings one code-point at a time using the integer
|
||||
* value of each code-point.
|
||||
*/
|
||||
export function compareStringsCaseSensitive(a: string, b: string) {
|
||||
export function compareStringsCaseSensitive(a: string | undefined, b: string | undefined): Comparison {
|
||||
return compareComparableValues(a, b);
|
||||
}
|
||||
|
||||
@@ -1902,7 +1930,7 @@ namespace ts {
|
||||
return uiLocale;
|
||||
}
|
||||
|
||||
export function setUILocale(value: string) {
|
||||
export function setUILocale(value: string | undefined) {
|
||||
if (uiLocale !== value) {
|
||||
uiLocale = value;
|
||||
uiComparerCaseSensitive = undefined;
|
||||
@@ -1924,14 +1952,14 @@ namespace ts {
|
||||
return comparer(a, b);
|
||||
}
|
||||
|
||||
export function compareProperties<T, K extends keyof T>(a: T, b: T, key: K, comparer: Comparer<T[K]>) {
|
||||
export function compareProperties<T, K extends keyof T>(a: T | undefined, b: T | undefined, key: K, comparer: Comparer<T[K]>): Comparison {
|
||||
return a === b ? Comparison.EqualTo :
|
||||
a === undefined ? Comparison.LessThan :
|
||||
b === undefined ? Comparison.GreaterThan :
|
||||
comparer(a[key], b[key]);
|
||||
}
|
||||
|
||||
function getDiagnosticFilePath(diagnostic: Diagnostic): string {
|
||||
function getDiagnosticFilePath(diagnostic: Diagnostic): string | undefined {
|
||||
return diagnostic.file ? diagnostic.file.path : undefined;
|
||||
}
|
||||
|
||||
@@ -1949,7 +1977,9 @@ namespace ts {
|
||||
return compareValues(a ? 1 : 0, b ? 1 : 0);
|
||||
}
|
||||
|
||||
function compareMessageText(text1: string | DiagnosticMessageChain, text2: string | DiagnosticMessageChain): Comparison {
|
||||
function compareMessageText(t1: string | DiagnosticMessageChain, t2: string | DiagnosticMessageChain): Comparison {
|
||||
let text1: string | DiagnosticMessageChain | undefined = t1;
|
||||
let text2: string | DiagnosticMessageChain | undefined = t2;
|
||||
while (text1 && text2) {
|
||||
// We still have both chains.
|
||||
const string1 = isString(text1) ? text1 : text1.messageText;
|
||||
@@ -2019,7 +2049,7 @@ namespace ts {
|
||||
export type StrictOptionName = "noImplicitAny" | "noImplicitThis" | "strictNullChecks" | "strictFunctionTypes" | "strictPropertyInitialization" | "alwaysStrict";
|
||||
|
||||
export function getStrictOptionValue(compilerOptions: CompilerOptions, flag: StrictOptionName): boolean {
|
||||
return compilerOptions[flag] === undefined ? compilerOptions.strict : compilerOptions[flag];
|
||||
return compilerOptions[flag] === undefined ? !!compilerOptions.strict : !!compilerOptions[flag];
|
||||
}
|
||||
|
||||
export function hasZeroOrOneAsteriskCharacter(str: string): boolean {
|
||||
@@ -2298,11 +2328,11 @@ namespace ts {
|
||||
* If the path is relative, the root component is `""`.
|
||||
* If the path is absolute, the root component includes the first path separator (`/`).
|
||||
*/
|
||||
export function getNormalizedPathComponents(path: string, currentDirectory: string) {
|
||||
export function getNormalizedPathComponents(path: string, currentDirectory: string | undefined) {
|
||||
return reducePathComponents(getPathComponents(path, currentDirectory));
|
||||
}
|
||||
|
||||
export function getNormalizedAbsolutePath(fileName: string, currentDirectory: string) {
|
||||
export function getNormalizedAbsolutePath(fileName: string, currentDirectory: string | undefined) {
|
||||
return getPathFromPathComponents(getNormalizedPathComponents(fileName, currentDirectory));
|
||||
}
|
||||
|
||||
@@ -2429,7 +2459,7 @@ namespace ts {
|
||||
/**
|
||||
* Combines paths. If a path is absolute, it replaces any previous path.
|
||||
*/
|
||||
export function combinePaths(path: string, ...paths: string[]): string {
|
||||
export function combinePaths(path: string, ...paths: (string | undefined)[]): string {
|
||||
if (path) path = normalizeSlashes(path);
|
||||
for (let relativePath of paths) {
|
||||
if (!relativePath) continue;
|
||||
@@ -2448,7 +2478,7 @@ namespace ts {
|
||||
* Combines and resolves paths. If a path is absolute, it replaces any previous path. Any
|
||||
* `.` and `..` path components are resolved.
|
||||
*/
|
||||
export function resolvePath(path: string, ...paths: string[]): string {
|
||||
export function resolvePath(path: string, ...paths: (string | undefined)[]): string {
|
||||
const combined = some(paths) ? combinePaths(path, ...paths) : normalizeSlashes(path);
|
||||
const normalized = getPathFromPathComponents(reducePathComponents(getPathComponents(combined)));
|
||||
return normalized && hasTrailingDirectorySeparator(combined) ? ensureTrailingDirectorySeparator(normalized) : normalized;
|
||||
@@ -2657,7 +2687,7 @@ namespace ts {
|
||||
exclude: excludeMatcher
|
||||
};
|
||||
|
||||
export function getRegularExpressionForWildcard(specs: ReadonlyArray<string>, basePath: string, usage: "files" | "directories" | "exclude"): string | undefined {
|
||||
export function getRegularExpressionForWildcard(specs: ReadonlyArray<string> | undefined, basePath: string, usage: "files" | "directories" | "exclude"): string | undefined {
|
||||
const patterns = getRegularExpressionsForWildcards(specs, basePath, usage);
|
||||
if (!patterns || !patterns.length) {
|
||||
return undefined;
|
||||
@@ -2669,7 +2699,7 @@ namespace ts {
|
||||
return `^(${pattern})${terminator}`;
|
||||
}
|
||||
|
||||
function getRegularExpressionsForWildcards(specs: ReadonlyArray<string>, basePath: string, usage: "files" | "directories" | "exclude"): string[] | undefined {
|
||||
function getRegularExpressionsForWildcards(specs: ReadonlyArray<string> | undefined, basePath: string, usage: "files" | "directories" | "exclude"): string[] | undefined {
|
||||
if (specs === undefined || specs.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -2690,7 +2720,7 @@ namespace ts {
|
||||
let subpattern = "";
|
||||
let hasWrittenComponent = false;
|
||||
const components = getNormalizedPathComponents(spec, basePath);
|
||||
const lastComponent = lastOrUndefined(components);
|
||||
const lastComponent = last(components);
|
||||
if (usage !== "exclude" && lastComponent === "**") {
|
||||
return undefined;
|
||||
}
|
||||
@@ -2773,15 +2803,15 @@ namespace ts {
|
||||
|
||||
export interface FileMatcherPatterns {
|
||||
/** One pattern for each "include" spec. */
|
||||
includeFilePatterns: ReadonlyArray<string>;
|
||||
includeFilePatterns: ReadonlyArray<string> | undefined;
|
||||
/** One pattern matching one of any of the "include" specs. */
|
||||
includeFilePattern: string;
|
||||
includeDirectoryPattern: string;
|
||||
excludePattern: string;
|
||||
includeFilePattern: string | undefined;
|
||||
includeDirectoryPattern: string | undefined;
|
||||
excludePattern: string | undefined;
|
||||
basePaths: ReadonlyArray<string>;
|
||||
}
|
||||
|
||||
export function getFileMatcherPatterns(path: string, excludes: ReadonlyArray<string>, includes: ReadonlyArray<string>, useCaseSensitiveFileNames: boolean, currentDirectory: string): FileMatcherPatterns {
|
||||
export function getFileMatcherPatterns(path: string, excludes: ReadonlyArray<string> | undefined, includes: ReadonlyArray<string> | undefined, useCaseSensitiveFileNames: boolean, currentDirectory: string): FileMatcherPatterns {
|
||||
path = normalizePath(path);
|
||||
currentDirectory = normalizePath(currentDirectory);
|
||||
const absolutePath = combinePaths(currentDirectory, path);
|
||||
@@ -2795,7 +2825,7 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
export function matchFiles(path: string, extensions: ReadonlyArray<string>, excludes: ReadonlyArray<string>, includes: ReadonlyArray<string>, useCaseSensitiveFileNames: boolean, currentDirectory: string, depth: number | undefined, getFileSystemEntries: (path: string) => FileSystemEntries): string[] {
|
||||
export function matchFiles(path: string, extensions: ReadonlyArray<string> | undefined, excludes: ReadonlyArray<string> | undefined, includes: ReadonlyArray<string> | undefined, useCaseSensitiveFileNames: boolean, currentDirectory: string, depth: number | undefined, getFileSystemEntries: (path: string) => FileSystemEntries): string[] {
|
||||
path = normalizePath(path);
|
||||
currentDirectory = normalizePath(currentDirectory);
|
||||
|
||||
@@ -2819,7 +2849,7 @@ namespace ts {
|
||||
function visitDirectory(path: string, absolutePath: string, depth: number | undefined) {
|
||||
const { files, directories } = getFileSystemEntries(path);
|
||||
|
||||
for (const current of sort(files, compareStringsCaseSensitive)) {
|
||||
for (const current of sort<string>(files, compareStringsCaseSensitive)) {
|
||||
const name = combinePaths(path, current);
|
||||
const absoluteName = combinePaths(absolutePath, current);
|
||||
if (extensions && !fileExtensionIsOneOf(name, extensions)) continue;
|
||||
@@ -2842,7 +2872,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
for (const current of sort(directories, compareStringsCaseSensitive)) {
|
||||
for (const current of sort<string>(directories, compareStringsCaseSensitive)) {
|
||||
const name = combinePaths(path, current);
|
||||
const absoluteName = combinePaths(absolutePath, current);
|
||||
if ((!includeDirectoryRegex || includeDirectoryRegex.test(absoluteName)) &&
|
||||
@@ -2856,7 +2886,7 @@ namespace ts {
|
||||
/**
|
||||
* Computes the unique non-wildcard base paths amongst the provided include patterns.
|
||||
*/
|
||||
function getBasePaths(path: string, includes: ReadonlyArray<string>, useCaseSensitiveFileNames: boolean) {
|
||||
function getBasePaths(path: string, includes: ReadonlyArray<string> | undefined, useCaseSensitiveFileNames: boolean): string[] {
|
||||
// Storage for our results in the form of literal paths (e.g. the paths as written by the user).
|
||||
const basePaths: string[] = [path];
|
||||
|
||||
@@ -2946,19 +2976,19 @@ namespace ts {
|
||||
...mapDefined(extraFileExtensions, x => x.scriptKind === ScriptKind.Deferred || needJsExtensions && isJavaScriptLike(x.scriptKind) ? x.extension : undefined)
|
||||
];
|
||||
|
||||
return deduplicate(extensions, equateStringsCaseSensitive, compareStringsCaseSensitive);
|
||||
return deduplicate<string>(extensions, equateStringsCaseSensitive, compareStringsCaseSensitive);
|
||||
}
|
||||
|
||||
function isJavaScriptLike(scriptKind: ScriptKind): boolean {
|
||||
function isJavaScriptLike(scriptKind: ScriptKind | undefined): boolean {
|
||||
return scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSX;
|
||||
}
|
||||
|
||||
export function hasJavaScriptFileExtension(fileName: string) {
|
||||
return forEach(supportedJavascriptExtensions, extension => fileExtensionIs(fileName, extension));
|
||||
export function hasJavaScriptFileExtension(fileName: string): boolean {
|
||||
return some(supportedJavascriptExtensions, extension => fileExtensionIs(fileName, extension));
|
||||
}
|
||||
|
||||
export function hasTypeScriptFileExtension(fileName: string) {
|
||||
return forEach(supportedTypeScriptExtensions, extension => fileExtensionIs(fileName, extension));
|
||||
export function hasTypeScriptFileExtension(fileName: string): boolean {
|
||||
return some(supportedTypeScriptExtensions, extension => fileExtensionIs(fileName, extension));
|
||||
}
|
||||
|
||||
export function isSupportedSourceFileName(fileName: string, compilerOptions?: CompilerOptions, extraFileExtensions?: ReadonlyArray<FileExtensionInfo>) {
|
||||
@@ -3079,8 +3109,8 @@ namespace ts {
|
||||
function Symbol(this: Symbol, flags: SymbolFlags, name: __String) {
|
||||
this.flags = flags;
|
||||
this.escapedName = name;
|
||||
this.declarations = undefined;
|
||||
this.valueDeclaration = undefined;
|
||||
this.declarations = undefined!;
|
||||
this.valueDeclaration = undefined!;
|
||||
this.id = undefined;
|
||||
this.mergeId = undefined;
|
||||
this.parent = undefined;
|
||||
@@ -3103,7 +3133,7 @@ namespace ts {
|
||||
this.flags = NodeFlags.None;
|
||||
this.modifierFlagsCache = ModifierFlags.None;
|
||||
this.transformFlags = TransformFlags.None;
|
||||
this.parent = undefined;
|
||||
this.parent = undefined!;
|
||||
this.original = undefined;
|
||||
}
|
||||
|
||||
@@ -3189,7 +3219,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function assertDefined<T>(value: T | null | undefined, message?: string): T {
|
||||
assert(value !== undefined && value !== null, message);
|
||||
if (value === undefined || value === null) return fail(message);
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -3224,7 +3254,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function showFlags(flags: number, flagsEnum: { [flag: number]: string }): string {
|
||||
const out = [];
|
||||
const out: string[] = [];
|
||||
for (let pow = 0; pow <= 30; pow++) {
|
||||
const n = 1 << pow;
|
||||
if (flags & n) {
|
||||
@@ -3375,10 +3405,7 @@ namespace ts {
|
||||
*/
|
||||
export function extensionFromPath(path: string): Extension {
|
||||
const ext = tryGetExtensionFromPath(path);
|
||||
if (ext !== undefined) {
|
||||
return ext;
|
||||
}
|
||||
Debug.fail(`File ${path} has unknown extension.`);
|
||||
return ext !== undefined ? ext : Debug.fail(`File ${path} has unknown extension.`);
|
||||
}
|
||||
|
||||
export function isAnySupportedFileExtension(path: string): boolean {
|
||||
|
||||
+63
-61
@@ -15,7 +15,7 @@ namespace ts {
|
||||
export function forEachEmittedFile<T>(
|
||||
host: EmitHost, action: (emitFileNames: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle) => T,
|
||||
sourceFilesOrTargetSourceFile?: ReadonlyArray<SourceFile> | SourceFile,
|
||||
emitOnlyDtsFiles?: boolean) {
|
||||
emitOnlyDtsFiles = false) {
|
||||
const sourceFiles = isArray(sourceFilesOrTargetSourceFile) ? sourceFilesOrTargetSourceFile : getSourceFilesToEmit(host, sourceFilesOrTargetSourceFile);
|
||||
const options = host.getCompilerOptions();
|
||||
if (options.outFile || options.out) {
|
||||
@@ -38,14 +38,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function getOutputPathsFor(sourceFile: SourceFile | Bundle, host: EmitHost, forceDtsPaths: boolean) {
|
||||
export function getOutputPathsFor(sourceFile: SourceFile | Bundle, host: EmitHost, forceDtsPaths: boolean): EmitFileNames {
|
||||
const options = host.getCompilerOptions();
|
||||
if (sourceFile.kind === SyntaxKind.Bundle) {
|
||||
const jsFilePath = options.outFile || options.out;
|
||||
const jsFilePath = options.outFile || options.out!;
|
||||
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
|
||||
const declarationFilePath = (forceDtsPaths || options.declaration) ? removeFileExtension(jsFilePath) + Extension.Dts : undefined;
|
||||
const declarationMapPath = getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined;
|
||||
const bundleInfoPath = options.references && jsFilePath && (removeFileExtension(jsFilePath) + infoExtension);
|
||||
const bundleInfoPath = options.references && jsFilePath ? (removeFileExtension(jsFilePath) + infoExtension) : undefined;
|
||||
return { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, bundleInfoPath };
|
||||
}
|
||||
else {
|
||||
@@ -97,8 +97,8 @@ namespace ts {
|
||||
// targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature
|
||||
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile, emitOnlyDtsFiles?: boolean, transformers?: TransformerFactory<Bundle | SourceFile>[], declarationTransformers?: TransformerFactory<Bundle | SourceFile>[]): EmitResult {
|
||||
const compilerOptions = host.getCompilerOptions();
|
||||
const sourceMapDataList: SourceMapData[] = (compilerOptions.sourceMap || compilerOptions.inlineSourceMap || getAreDeclarationMapsEnabled(compilerOptions)) ? [] : undefined;
|
||||
const emittedFilesList: string[] = compilerOptions.listEmittedFiles ? [] : undefined;
|
||||
const sourceMapDataList: SourceMapData[] | undefined = (compilerOptions.sourceMap || compilerOptions.inlineSourceMap || getAreDeclarationMapsEnabled(compilerOptions)) ? [] : undefined;
|
||||
const emittedFilesList: string[] | undefined = compilerOptions.listEmittedFiles ? [] : undefined;
|
||||
const emitterDiagnostics = createDiagnosticCollection();
|
||||
const newLine = host.getNewLine();
|
||||
const writer = createTextWriter(newLine);
|
||||
@@ -124,7 +124,7 @@ namespace ts {
|
||||
emitSkipped,
|
||||
diagnostics: emitterDiagnostics.getDiagnostics(),
|
||||
emittedFiles: emittedFilesList,
|
||||
sourceMaps: sourceMapDataList
|
||||
sourceMaps: sourceMapDataList,
|
||||
};
|
||||
|
||||
function emitSourceFileOrBundle({ jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, bundleInfoPath }: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle) {
|
||||
@@ -147,7 +147,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitJsFileOrBundle(sourceFileOrBundle: SourceFile | Bundle, jsFilePath: string, sourceMapFilePath: string, bundleInfoPath: string | undefined) {
|
||||
function emitJsFileOrBundle(sourceFileOrBundle: SourceFile | Bundle, jsFilePath: string, sourceMapFilePath: string | undefined, bundleInfoPath: string | undefined) {
|
||||
// Make sure not to write js file and source map file if any of them cannot be written
|
||||
if (host.isEmitBlocked(jsFilePath) || compilerOptions.noEmit || compilerOptions.emitDeclarationOnly) {
|
||||
emitSkipped = true;
|
||||
@@ -157,7 +157,7 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
// Transform the source files
|
||||
const transform = transformNodes(resolver, host, compilerOptions, [sourceFileOrBundle], transformers, /*allowDtsFiles*/ false);
|
||||
const transform = transformNodes(resolver, host, compilerOptions, [sourceFileOrBundle], transformers!, /*allowDtsFiles*/ false);
|
||||
|
||||
// Create a printer to print the nodes
|
||||
const printer = createPrinter({ ...compilerOptions, noEmitHelpers: compilerOptions.noEmitHelpers } as PrinterOptions, {
|
||||
@@ -194,7 +194,7 @@ namespace ts {
|
||||
const inputListOrBundle = (compilerOptions.outFile || compilerOptions.out) ? [createBundle(nonJsFiles, !isSourceFile(sourceFileOrBundle) ? sourceFileOrBundle.prepends : undefined)] : nonJsFiles;
|
||||
const declarationTransform = transformNodes(resolver, host, compilerOptions, inputListOrBundle, concatenate([transformDeclarations], declarationTransformers), /*allowDtsFiles*/ false);
|
||||
if (length(declarationTransform.diagnostics)) {
|
||||
for (const diagnostic of declarationTransform.diagnostics) {
|
||||
for (const diagnostic of declarationTransform.diagnostics!) {
|
||||
emitterDiagnostics.add(diagnostic);
|
||||
}
|
||||
}
|
||||
@@ -224,14 +224,14 @@ namespace ts {
|
||||
function printSourceFileOrBundle(jsFilePath: string, sourceMapFilePath: string | undefined, sourceFileOrBundle: SourceFile | Bundle, bundleInfoPath: string | undefined, printer: Printer, mapRecorder: SourceMapWriter) {
|
||||
const bundle = sourceFileOrBundle.kind === SyntaxKind.Bundle ? sourceFileOrBundle : undefined;
|
||||
const sourceFile = sourceFileOrBundle.kind === SyntaxKind.SourceFile ? sourceFileOrBundle : undefined;
|
||||
const sourceFiles = bundle ? bundle.sourceFiles : [sourceFile];
|
||||
const sourceFiles = bundle ? bundle.sourceFiles : [sourceFile!];
|
||||
mapRecorder.initialize(jsFilePath, sourceMapFilePath || "", sourceFileOrBundle, sourceMapDataList);
|
||||
|
||||
if (bundle) {
|
||||
printer.writeBundle(bundle, writer, bundleInfo);
|
||||
}
|
||||
else {
|
||||
printer.writeFile(sourceFile, writer);
|
||||
printer.writeFile(sourceFile!, writer);
|
||||
}
|
||||
|
||||
writer.writeLine();
|
||||
@@ -247,7 +247,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Write the output file
|
||||
writeFile(host, emitterDiagnostics, jsFilePath, writer.getText(), compilerOptions.emitBOM, sourceFiles);
|
||||
writeFile(host, emitterDiagnostics, jsFilePath, writer.getText(), !!compilerOptions.emitBOM, sourceFiles);
|
||||
|
||||
// Write bundled offset information if applicable
|
||||
if (bundleInfoPath) {
|
||||
@@ -302,7 +302,7 @@ namespace ts {
|
||||
emitLeadingCommentsOfPosition,
|
||||
} = comments;
|
||||
|
||||
let currentSourceFile: SourceFile | undefined;
|
||||
let currentSourceFile!: SourceFile;
|
||||
let nodeIdToGeneratedName: string[]; // Map of generated names for specific nodes.
|
||||
let autoGeneratedIdToGeneratedName: string[]; // Map of generated names for temp and loop variables.
|
||||
let generatedNames: Map<true>; // Set of names generated by the NameGenerator.
|
||||
@@ -478,8 +478,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function setWriter(output: EmitTextWriter | undefined) {
|
||||
writer = output;
|
||||
comments.setWriter(output);
|
||||
writer = output!; // TODO: GH#18217
|
||||
comments.setWriter(output!);
|
||||
}
|
||||
|
||||
function reset() {
|
||||
@@ -544,8 +544,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function pipelineEmitWithNotification(hint: EmitHint, node: Node) {
|
||||
Debug.assertDefined(onEmitNode);
|
||||
onEmitNode(hint, node, getNextPipelinePhase(PipelinePhase.Notification, hint));
|
||||
Debug.assertDefined(onEmitNode)(hint, node, getNextPipelinePhase(PipelinePhase.Notification, hint));
|
||||
}
|
||||
|
||||
function pipelineEmitWithComments(hint: EmitHint, node: Node) {
|
||||
@@ -560,9 +559,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function pipelineEmitWithSourceMap(hint: EmitHint, node: Node) {
|
||||
Debug.assertDefined(onEmitSourceMapOfNode);
|
||||
Debug.assert(hint !== EmitHint.SourceFile && hint !== EmitHint.IdentifierName);
|
||||
onEmitSourceMapOfNode(hint, node, pipelineEmitWithHint);
|
||||
Debug.assertDefined(onEmitSourceMapOfNode)(hint, node, pipelineEmitWithHint);
|
||||
}
|
||||
|
||||
function pipelineEmitWithHint(hint: EmitHint, node: Node): void {
|
||||
@@ -1503,7 +1501,7 @@ namespace ts {
|
||||
// check if numeric literal is a decimal literal that was originally written with a dot
|
||||
const text = getLiteralTextOfNode(<LiteralExpression>expression);
|
||||
return !expression.numericLiteralFlags
|
||||
&& !stringContains(text, tokenToString(SyntaxKind.DotToken));
|
||||
&& !stringContains(text, tokenToString(SyntaxKind.DotToken)!);
|
||||
}
|
||||
else if (isPropertyAccessExpression(expression) || isElementAccessExpression(expression)) {
|
||||
// check if constant enum value is integer
|
||||
@@ -1841,7 +1839,7 @@ namespace ts {
|
||||
emitEmbeddedStatement(node, node.statement);
|
||||
}
|
||||
|
||||
function emitForBinding(node: VariableDeclarationList | Expression) {
|
||||
function emitForBinding(node: VariableDeclarationList | Expression | undefined) {
|
||||
if (node !== undefined) {
|
||||
if (node.kind === SyntaxKind.VariableDeclarationList) {
|
||||
emit(node);
|
||||
@@ -1973,7 +1971,7 @@ namespace ts {
|
||||
writeKeyword("function");
|
||||
emit(node.asteriskToken);
|
||||
writeSpace();
|
||||
emitIdentifierName(node.name);
|
||||
emitIdentifierName(node.name!); // TODO: GH#18217
|
||||
emitSignatureAndBody(node, emitSignatureHead);
|
||||
}
|
||||
|
||||
@@ -2052,7 +2050,7 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
let previousStatement: Statement;
|
||||
let previousStatement: Statement | undefined;
|
||||
for (const statement of body.statements) {
|
||||
if (shouldWriteSeparatingLineTerminator(previousStatement, statement, ListFormat.PreserveLines)) {
|
||||
return false;
|
||||
@@ -2189,7 +2187,7 @@ namespace ts {
|
||||
while (body.kind === SyntaxKind.ModuleDeclaration) {
|
||||
writePunctuation(".");
|
||||
emit((<ModuleDeclaration>body).name);
|
||||
body = (<ModuleDeclaration>body).body;
|
||||
body = (<ModuleDeclaration>body).body!;
|
||||
}
|
||||
|
||||
writeSpace();
|
||||
@@ -2406,7 +2404,7 @@ namespace ts {
|
||||
|
||||
function emitJsxAttribute(node: JsxAttribute) {
|
||||
emit(node.name);
|
||||
emitNodeWithPrefix("=", writePunctuation, node.initializer, emit);
|
||||
emitNodeWithPrefix("=", writePunctuation, node.initializer!, emit); // TODO: GH#18217
|
||||
}
|
||||
|
||||
function emitJsxSpreadAttribute(node: JsxSpreadAttribute) {
|
||||
@@ -2562,7 +2560,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function emitSyntheticTripleSlashReferencesIfNeeded(node: Bundle) {
|
||||
emitTripleSlashDirectives(node.hasNoDefaultLib, node.syntheticFileReferences || [], node.syntheticTypeReferences || []);
|
||||
emitTripleSlashDirectives(!!node.hasNoDefaultLib, node.syntheticFileReferences || [], node.syntheticTypeReferences || []);
|
||||
}
|
||||
|
||||
function emitTripleSlashDirectivesIfNeeded(node: SourceFile) {
|
||||
@@ -2693,7 +2691,7 @@ namespace ts {
|
||||
write = savedWrite;
|
||||
}
|
||||
|
||||
function emitModifiers(node: Node, modifiers: NodeArray<Modifier>) {
|
||||
function emitModifiers(node: Node, modifiers: NodeArray<Modifier> | undefined) {
|
||||
if (modifiers && modifiers.length) {
|
||||
emitList(node, modifiers, ListFormat.Modifiers);
|
||||
writeSpace();
|
||||
@@ -2758,15 +2756,15 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitDecorators(parentNode: Node, decorators: NodeArray<Decorator>) {
|
||||
function emitDecorators(parentNode: Node, decorators: NodeArray<Decorator> | undefined) {
|
||||
emitList(parentNode, decorators, ListFormat.Decorators);
|
||||
}
|
||||
|
||||
function emitTypeArguments(parentNode: Node, typeArguments: NodeArray<TypeNode>) {
|
||||
function emitTypeArguments(parentNode: Node, typeArguments: NodeArray<TypeNode> | undefined) {
|
||||
emitList(parentNode, typeArguments, ListFormat.TypeArguments);
|
||||
}
|
||||
|
||||
function emitTypeParameters(parentNode: SignatureDeclaration | InterfaceDeclaration | TypeAliasDeclaration | ClassDeclaration | ClassExpression, typeParameters: NodeArray<TypeParameterDeclaration>) {
|
||||
function emitTypeParameters(parentNode: SignatureDeclaration | InterfaceDeclaration | TypeAliasDeclaration | ClassDeclaration | ClassExpression, typeParameters: NodeArray<TypeParameterDeclaration> | undefined) {
|
||||
if (isFunctionLike(parentNode) && parentNode.typeArguments) { // Quick info uses type arguments in place of type parameters on instantiated signatures
|
||||
return emitTypeArguments(parentNode, parentNode.typeArguments);
|
||||
}
|
||||
@@ -2807,12 +2805,12 @@ namespace ts {
|
||||
emitList(parentNode, parameters, ListFormat.IndexSignatureParameters);
|
||||
}
|
||||
|
||||
function emitList(parentNode: TextRange, children: NodeArray<Node>, format: ListFormat, start?: number, count?: number) {
|
||||
function emitList(parentNode: TextRange, children: NodeArray<Node> | undefined, format: ListFormat, start?: number, count?: number) {
|
||||
emitNodeList(emit, parentNode, children, format, start, count);
|
||||
}
|
||||
|
||||
function emitExpressionList(parentNode: TextRange, children: NodeArray<Node>, format: ListFormat, start?: number, count?: number) {
|
||||
emitNodeList(emitExpression, parentNode, children, format, start, count);
|
||||
function emitExpressionList(parentNode: TextRange, children: NodeArray<Node> | undefined, format: ListFormat, start?: number, count?: number) {
|
||||
emitNodeList(emitExpression as (node: Node) => void, parentNode, children, format, start, count); // TODO: GH#18217
|
||||
}
|
||||
|
||||
function writeDelimiter(format: ListFormat) {
|
||||
@@ -2833,13 +2831,13 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitNodeList(emit: (node: Node) => void, parentNode: TextRange, children: NodeArray<Node>, format: ListFormat, start = 0, count = children ? children.length - start : 0) {
|
||||
function emitNodeList(emit: (node: Node) => void, parentNode: TextRange, children: NodeArray<Node> | undefined, format: ListFormat, start = 0, count = children ? children.length - start : 0) {
|
||||
const isUndefined = children === undefined;
|
||||
if (isUndefined && format & ListFormat.OptionalIfUndefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isEmpty = isUndefined || start >= children.length || count === 0;
|
||||
const isEmpty = children === undefined || start >= children.length || count === 0;
|
||||
if (isEmpty && format & ListFormat.OptionalIfEmpty) {
|
||||
if (onBeforeEmitNodeArray) {
|
||||
onBeforeEmitNodeArray(children);
|
||||
@@ -2853,7 +2851,8 @@ namespace ts {
|
||||
if (format & ListFormat.BracketsMask) {
|
||||
writePunctuation(getOpeningBracket(format));
|
||||
if (isEmpty && !isUndefined) {
|
||||
emitTrailingCommentsOfPosition(children.pos, /*prefixSpace*/ true); // Emit comments within empty bracketed lists
|
||||
// TODO: GH#18217
|
||||
emitTrailingCommentsOfPosition(children!.pos, /*prefixSpace*/ true); // Emit comments within empty bracketed lists
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2874,7 +2873,7 @@ namespace ts {
|
||||
// Write the opening line terminator or leading whitespace.
|
||||
const mayEmitInterveningComments = (format & ListFormat.NoInterveningComments) === 0;
|
||||
let shouldEmitInterveningComments = mayEmitInterveningComments;
|
||||
if (shouldWriteLeadingLineTerminator(parentNode, children, format)) {
|
||||
if (shouldWriteLeadingLineTerminator(parentNode, children!, format)) { // TODO: GH#18217
|
||||
writeLine();
|
||||
shouldEmitInterveningComments = false;
|
||||
}
|
||||
@@ -2888,10 +2887,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Emit each child.
|
||||
let previousSibling: Node;
|
||||
let shouldDecreaseIndentAfterEmit: boolean;
|
||||
let previousSibling: Node | undefined;
|
||||
let shouldDecreaseIndentAfterEmit = false;
|
||||
for (let i = 0; i < count; i++) {
|
||||
const child = children[start + i];
|
||||
const child = children![start + i];
|
||||
|
||||
// Write the delimiter if this is not the first node.
|
||||
if (previousSibling) {
|
||||
@@ -2945,7 +2944,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Write a trailing comma, if requested.
|
||||
const hasTrailingComma = (format & ListFormat.AllowTrailingComma) && children.hasTrailingComma;
|
||||
const hasTrailingComma = (format & ListFormat.AllowTrailingComma) && children!.hasTrailingComma;
|
||||
if (format & ListFormat.CommaDelimited && hasTrailingComma) {
|
||||
writePunctuation(",");
|
||||
}
|
||||
@@ -2967,7 +2966,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Write the closing line terminator or closing whitespace.
|
||||
if (shouldWriteClosingLineTerminator(parentNode, children, format)) {
|
||||
if (shouldWriteClosingLineTerminator(parentNode, children!, format)) {
|
||||
writeLine();
|
||||
}
|
||||
else if (format & ListFormat.SpaceBetweenBraces) {
|
||||
@@ -2981,7 +2980,8 @@ namespace ts {
|
||||
|
||||
if (format & ListFormat.BracketsMask) {
|
||||
if (isEmpty && !isUndefined) {
|
||||
emitLeadingCommentsOfPosition(children.end); // Emit leading comments within empty lists
|
||||
// TODO: GH#18217
|
||||
emitLeadingCommentsOfPosition(children!.end); // Emit leading comments within empty lists
|
||||
}
|
||||
writePunctuation(getClosingBracket(format));
|
||||
}
|
||||
@@ -3077,16 +3077,18 @@ namespace ts {
|
||||
if (onBeforeEmitToken) {
|
||||
onBeforeEmitToken(node);
|
||||
}
|
||||
writer(tokenToString(node.kind));
|
||||
writer(tokenToString(node.kind)!);
|
||||
if (onAfterEmitToken) {
|
||||
onAfterEmitToken(node);
|
||||
}
|
||||
}
|
||||
|
||||
function writeTokenText(token: SyntaxKind, writer: (s: string) => void, pos?: number) {
|
||||
const tokenString = tokenToString(token);
|
||||
function writeTokenText(token: SyntaxKind, writer: (s: string) => void): void;
|
||||
function writeTokenText(token: SyntaxKind, writer: (s: string) => void, pos: number): number;
|
||||
function writeTokenText(token: SyntaxKind, writer: (s: string) => void, pos?: number): number {
|
||||
const tokenString = tokenToString(token)!;
|
||||
writer(tokenString);
|
||||
return pos < 0 ? pos : pos + tokenString.length;
|
||||
return pos! < 0 ? pos! : pos! + tokenString.length;
|
||||
}
|
||||
|
||||
function writeLineOrSpace(node: Node) {
|
||||
@@ -3160,7 +3162,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function shouldWriteSeparatingLineTerminator(previousNode: Node, nextNode: Node, format: ListFormat) {
|
||||
function shouldWriteSeparatingLineTerminator(previousNode: Node | undefined, nextNode: Node, format: ListFormat) {
|
||||
if (format & ListFormat.MultiLine) {
|
||||
return true;
|
||||
}
|
||||
@@ -3205,7 +3207,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function synthesizedNodeStartsOnNewLine(node: Node, format?: ListFormat) {
|
||||
function synthesizedNodeStartsOnNewLine(node: Node, format: ListFormat) {
|
||||
if (nodeIsSynthesized(node)) {
|
||||
const startsOnNewLine = getStartsOnNewLine(node);
|
||||
if (startsOnNewLine === undefined) {
|
||||
@@ -3255,7 +3257,7 @@ namespace ts {
|
||||
return idText(node);
|
||||
}
|
||||
else if (node.kind === SyntaxKind.StringLiteral && (<StringLiteral>node).textSourceNode) {
|
||||
return getTextOfNode((<StringLiteral>node).textSourceNode, includeTrivia);
|
||||
return getTextOfNode((<StringLiteral>node).textSourceNode!, includeTrivia);
|
||||
}
|
||||
else if (isLiteralExpression(node) && (nodeIsSynthesized(node) || !node.parent)) {
|
||||
return node.text;
|
||||
@@ -3266,7 +3268,7 @@ namespace ts {
|
||||
|
||||
function getLiteralTextOfNode(node: LiteralLikeNode): string {
|
||||
if (node.kind === SyntaxKind.StringLiteral && (<StringLiteral>node).textSourceNode) {
|
||||
const textSourceNode = (<StringLiteral>node).textSourceNode;
|
||||
const textSourceNode = (<StringLiteral>node).textSourceNode!;
|
||||
if (isIdentifier(textSourceNode)) {
|
||||
return getEmitFlags(node) & EmitFlags.NoAsciiEscaping ?
|
||||
`"${escapeString(getTextOfNode(textSourceNode))}"` :
|
||||
@@ -3299,8 +3301,8 @@ namespace ts {
|
||||
if (node && getEmitFlags(node) & EmitFlags.ReuseTempVariableScope) {
|
||||
return;
|
||||
}
|
||||
tempFlags = tempFlagsStack.pop();
|
||||
reservedNames = reservedNamesStack.pop();
|
||||
tempFlags = tempFlagsStack.pop()!;
|
||||
reservedNames = reservedNamesStack.pop()!;
|
||||
}
|
||||
|
||||
function reserveNameInNestedScopes(name: string) {
|
||||
@@ -3430,7 +3432,7 @@ namespace ts {
|
||||
else {
|
||||
// Auto, Loop, and Unique names are cached based on their unique
|
||||
// autoGenerateId.
|
||||
const autoGenerateId = name.autoGenerateId;
|
||||
const autoGenerateId = name.autoGenerateId!;
|
||||
return autoGeneratedIdToGeneratedName[autoGenerateId] || (autoGeneratedIdToGeneratedName[autoGenerateId] = makeName(name));
|
||||
}
|
||||
}
|
||||
@@ -3461,7 +3463,7 @@ namespace ts {
|
||||
* Returns a value indicating whether a name is unique within a container.
|
||||
*/
|
||||
function isUniqueLocalName(name: string, container: Node): boolean {
|
||||
for (let node = container; isNodeDescendantOf(node, container); node = node.nextContainer) {
|
||||
for (let node = container; isNodeDescendantOf(node, container); node = node.nextContainer!) {
|
||||
if (node.locals) {
|
||||
const local = node.locals.get(escapeLeadingUnderscores(name));
|
||||
// We conservatively include alias symbols to cover cases where they're emitted as locals
|
||||
@@ -3563,7 +3565,7 @@ namespace ts {
|
||||
* Generates a unique name for an ImportDeclaration or ExportDeclaration.
|
||||
*/
|
||||
function generateNameForImportOrExportDeclaration(node: ImportDeclaration | ExportDeclaration) {
|
||||
const expr = getExternalModuleName(node);
|
||||
const expr = getExternalModuleName(node)!; // TODO: GH#18217
|
||||
const baseName = isStringLiteral(expr) ?
|
||||
makeIdentifierFromModuleName(expr.text) : "module";
|
||||
return makeUniqueName(baseName);
|
||||
@@ -3599,8 +3601,8 @@ namespace ts {
|
||||
return makeUniqueName(
|
||||
getTextOfNode(node),
|
||||
isUniqueName,
|
||||
!!(flags & GeneratedIdentifierFlags.Optimistic),
|
||||
!!(flags & GeneratedIdentifierFlags.ReservedInNestedScopes)
|
||||
!!(flags! & GeneratedIdentifierFlags.Optimistic),
|
||||
!!(flags! & GeneratedIdentifierFlags.ReservedInNestedScopes)
|
||||
);
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
@@ -3641,7 +3643,7 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
Debug.fail("Unsupported GeneratedIdentifierKind.");
|
||||
return Debug.fail("Unsupported GeneratedIdentifierKind.");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3657,7 +3659,7 @@ namespace ts {
|
||||
// if "node" is a different generated name (having a different
|
||||
// "autoGenerateId"), use it and stop traversing.
|
||||
if (isIdentifier(node)
|
||||
&& !!(node.autoGenerateFlags & GeneratedIdentifierFlags.Node)
|
||||
&& !!(node.autoGenerateFlags! & GeneratedIdentifierFlags.Node)
|
||||
&& node.autoGenerateId !== autoGenerateId) {
|
||||
break;
|
||||
}
|
||||
|
||||
+86
-84
@@ -39,13 +39,13 @@ namespace ts {
|
||||
* Creates a shallow, memberwise clone of a node with no source map location.
|
||||
*/
|
||||
/* @internal */
|
||||
export function getSynthesizedClone<T extends Node>(node: T | undefined): T | undefined {
|
||||
export function getSynthesizedClone<T extends Node>(node: T): T {
|
||||
// We don't use "clone" from core.ts here, as we need to preserve the prototype chain of
|
||||
// the original node. We also need to exclude specific properties and only include own-
|
||||
// properties (to skip members already defined on the shared prototype).
|
||||
|
||||
if (node === undefined) {
|
||||
return undefined;
|
||||
return node;
|
||||
}
|
||||
|
||||
const clone = <T>createSynthesizedNode(node.kind);
|
||||
@@ -116,7 +116,7 @@ namespace ts {
|
||||
|
||||
export function createIdentifier(text: string): Identifier;
|
||||
/* @internal */
|
||||
export function createIdentifier(text: string, typeArguments: ReadonlyArray<TypeNode | TypeParameterDeclaration>): Identifier; // tslint:disable-line unified-signatures
|
||||
export function createIdentifier(text: string, typeArguments: ReadonlyArray<TypeNode | TypeParameterDeclaration> | undefined): Identifier; // tslint:disable-line unified-signatures
|
||||
export function createIdentifier(text: string, typeArguments?: ReadonlyArray<TypeNode | TypeParameterDeclaration>): Identifier {
|
||||
const node = <Identifier>createSynthesizedNode(SyntaxKind.Identifier);
|
||||
node.escapedText = escapeLeadingUnderscores(text);
|
||||
@@ -142,9 +142,9 @@ namespace ts {
|
||||
|
||||
/** Create a unique temporary variable. */
|
||||
export function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined): Identifier;
|
||||
/* @internal */ export function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined, reservedInNestedScopes: boolean): Identifier; // tslint:disable-line unified-signatures
|
||||
export function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined, reservedInNestedScopes?: boolean): Identifier {
|
||||
const name = createIdentifier("");
|
||||
/* @internal */ export function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined, reservedInNestedScopes: boolean): GeneratedIdentifier; // tslint:disable-line unified-signatures
|
||||
export function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined, reservedInNestedScopes?: boolean): GeneratedIdentifier {
|
||||
const name = createIdentifier("") as GeneratedIdentifier;
|
||||
name.autoGenerateFlags = GeneratedIdentifierFlags.Auto;
|
||||
name.autoGenerateId = nextAutoGenerateId;
|
||||
nextAutoGenerateId++;
|
||||
@@ -175,9 +175,11 @@ namespace ts {
|
||||
return name;
|
||||
}
|
||||
|
||||
/* @internal */ export function createOptimisticUniqueName(text: string): GeneratedIdentifier;
|
||||
/** Create a unique name based on the supplied text. */
|
||||
export function createOptimisticUniqueName(text: string): Identifier {
|
||||
const name = createIdentifier(text);
|
||||
export function createOptimisticUniqueName(text: string): Identifier;
|
||||
export function createOptimisticUniqueName(text: string): GeneratedIdentifier {
|
||||
const name = createIdentifier(text) as GeneratedIdentifier;
|
||||
name.autoGenerateFlags = GeneratedIdentifierFlags.Unique | GeneratedIdentifierFlags.Optimistic;
|
||||
name.autoGenerateId = nextAutoGenerateId;
|
||||
nextAutoGenerateId++;
|
||||
@@ -196,7 +198,7 @@ namespace ts {
|
||||
/* @internal */ export function getGeneratedNameForNode(node: Node, flags: GeneratedIdentifierFlags): Identifier; // tslint:disable-line unified-signatures
|
||||
export function getGeneratedNameForNode(node: Node, flags?: GeneratedIdentifierFlags): Identifier {
|
||||
const name = createIdentifier(isIdentifier(node) ? idText(node) : "");
|
||||
name.autoGenerateFlags = GeneratedIdentifierFlags.Node | flags;
|
||||
name.autoGenerateFlags = GeneratedIdentifierFlags.Node | flags!;
|
||||
name.autoGenerateId = nextAutoGenerateId;
|
||||
name.original = node;
|
||||
nextAutoGenerateId++;
|
||||
@@ -713,7 +715,7 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createTypeLiteralNode(members: ReadonlyArray<TypeElement>) {
|
||||
export function createTypeLiteralNode(members: ReadonlyArray<TypeElement> | undefined) {
|
||||
const node = createSynthesizedNode(SyntaxKind.TypeLiteral) as TypeLiteralNode;
|
||||
node.members = createNodeArray(members);
|
||||
return node;
|
||||
@@ -846,7 +848,7 @@ namespace ts {
|
||||
export function createTypeOperatorNode(operatorOrType: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | TypeNode, type?: TypeNode) {
|
||||
const node = createSynthesizedNode(SyntaxKind.TypeOperator) as TypeOperatorNode;
|
||||
node.operator = typeof operatorOrType === "number" ? operatorOrType : SyntaxKind.KeyOfKeyword;
|
||||
node.type = parenthesizeElementTypeMember(typeof operatorOrType === "number" ? type : operatorOrType);
|
||||
node.type = parenthesizeElementTypeMember(typeof operatorOrType === "number" ? type! : operatorOrType);
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -970,10 +972,10 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createPropertyAccess(expression: Expression, name: string | Identifier) {
|
||||
export function createPropertyAccess(expression: Expression, name: string | Identifier | undefined) {
|
||||
const node = <PropertyAccessExpression>createSynthesizedNode(SyntaxKind.PropertyAccessExpression);
|
||||
node.expression = parenthesizeForAccess(expression);
|
||||
node.name = asName(name);
|
||||
node.name = asName(name)!; // TODO: GH#18217
|
||||
setEmitFlags(node, EmitFlags.NoIndentation);
|
||||
return node;
|
||||
}
|
||||
@@ -1001,7 +1003,7 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createCall(expression: Expression, typeArguments: ReadonlyArray<TypeNode> | undefined, argumentsArray: ReadonlyArray<Expression>) {
|
||||
export function createCall(expression: Expression, typeArguments: ReadonlyArray<TypeNode> | undefined, argumentsArray: ReadonlyArray<Expression> | undefined) {
|
||||
const node = <CallExpression>createSynthesizedNode(SyntaxKind.CallExpression);
|
||||
node.expression = parenthesizeForAccess(expression);
|
||||
node.typeArguments = asNodeArray(typeArguments);
|
||||
@@ -1034,15 +1036,15 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function createTaggedTemplate(tag: Expression, template: TemplateLiteral): TaggedTemplateExpression;
|
||||
export function createTaggedTemplate(tag: Expression, typeArguments: ReadonlyArray<TypeNode>, template: TemplateLiteral): TaggedTemplateExpression;
|
||||
export function createTaggedTemplate(tag: Expression, typeArguments: ReadonlyArray<TypeNode> | undefined, template: TemplateLiteral): TaggedTemplateExpression;
|
||||
/** @internal */
|
||||
export function createTaggedTemplate(tag: Expression, typeArgumentsOrTemplate: ReadonlyArray<TypeNode> | TemplateLiteral, template?: TemplateLiteral): TaggedTemplateExpression;
|
||||
export function createTaggedTemplate(tag: Expression, typeArgumentsOrTemplate: ReadonlyArray<TypeNode> | TemplateLiteral, template?: TemplateLiteral) {
|
||||
export function createTaggedTemplate(tag: Expression, typeArgumentsOrTemplate: ReadonlyArray<TypeNode> | TemplateLiteral | undefined, template?: TemplateLiteral): TaggedTemplateExpression;
|
||||
export function createTaggedTemplate(tag: Expression, typeArgumentsOrTemplate: ReadonlyArray<TypeNode> | TemplateLiteral | undefined, template?: TemplateLiteral) {
|
||||
const node = <TaggedTemplateExpression>createSynthesizedNode(SyntaxKind.TaggedTemplateExpression);
|
||||
node.tag = parenthesizeForAccess(tag);
|
||||
if (template) {
|
||||
node.typeArguments = asNodeArray(typeArgumentsOrTemplate as ReadonlyArray<TypeNode>);
|
||||
node.template = template!;
|
||||
node.template = template;
|
||||
}
|
||||
else {
|
||||
node.typeArguments = undefined;
|
||||
@@ -1052,8 +1054,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral): TaggedTemplateExpression;
|
||||
export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArguments: ReadonlyArray<TypeNode>, template: TemplateLiteral): TaggedTemplateExpression;
|
||||
export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArgumentsOrTemplate: ReadonlyArray<TypeNode> | TemplateLiteral, template?: TemplateLiteral) {
|
||||
export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArguments: ReadonlyArray<TypeNode> | undefined, template: TemplateLiteral): TaggedTemplateExpression;
|
||||
export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArgumentsOrTemplate: ReadonlyArray<TypeNode> | TemplateLiteral | undefined, template?: TemplateLiteral) {
|
||||
return node.tag !== tag
|
||||
|| (template
|
||||
? node.typeArguments !== typeArgumentsOrTemplate || node.template !== template
|
||||
@@ -1093,7 +1095,7 @@ namespace ts {
|
||||
asteriskToken: AsteriskToken | undefined,
|
||||
name: string | Identifier | undefined,
|
||||
typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined,
|
||||
parameters: ReadonlyArray<ParameterDeclaration>,
|
||||
parameters: ReadonlyArray<ParameterDeclaration> | undefined,
|
||||
type: TypeNode | undefined,
|
||||
body: Block) {
|
||||
const node = <FunctionExpression>createSynthesizedNode(SyntaxKind.FunctionExpression);
|
||||
@@ -1288,7 +1290,7 @@ namespace ts {
|
||||
node.condition = parenthesizeForConditionalHead(condition);
|
||||
node.questionToken = whenFalse ? <QuestionToken>questionTokenOrWhenTrue : createToken(SyntaxKind.QuestionToken);
|
||||
node.whenTrue = parenthesizeSubexpressionOfConditionalExpression(whenFalse ? whenTrueOrWhenFalse : <Expression>questionTokenOrWhenTrue);
|
||||
node.colonToken = whenFalse ? colonToken : createToken(SyntaxKind.ColonToken);
|
||||
node.colonToken = whenFalse ? colonToken! : createToken(SyntaxKind.ColonToken);
|
||||
node.whenFalse = parenthesizeSubexpressionOfConditionalExpression(whenFalse ? whenFalse : whenTrueOrWhenFalse);
|
||||
return node;
|
||||
}
|
||||
@@ -1360,8 +1362,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function createYield(expression?: Expression): YieldExpression;
|
||||
export function createYield(asteriskToken: AsteriskToken, expression: Expression): YieldExpression;
|
||||
export function createYield(asteriskTokenOrExpression?: AsteriskToken | Expression, expression?: Expression) {
|
||||
export function createYield(asteriskToken: AsteriskToken | undefined, expression: Expression): YieldExpression;
|
||||
export function createYield(asteriskTokenOrExpression?: AsteriskToken | undefined | Expression, expression?: Expression) {
|
||||
const node = <YieldExpression>createSynthesizedNode(SyntaxKind.YieldExpression);
|
||||
node.asteriskToken = asteriskTokenOrExpression && asteriskTokenOrExpression.kind === SyntaxKind.AsteriskToken ? <AsteriskToken>asteriskTokenOrExpression : undefined;
|
||||
node.expression = asteriskTokenOrExpression && asteriskTokenOrExpression.kind !== SyntaxKind.AsteriskToken ? asteriskTokenOrExpression : expression;
|
||||
@@ -1391,7 +1393,7 @@ namespace ts {
|
||||
modifiers: ReadonlyArray<Modifier> | undefined,
|
||||
name: string | Identifier | undefined,
|
||||
typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined,
|
||||
heritageClauses: ReadonlyArray<HeritageClause>,
|
||||
heritageClauses: ReadonlyArray<HeritageClause> | undefined,
|
||||
members: ReadonlyArray<ClassElement>) {
|
||||
const node = <ClassExpression>createSynthesizedNode(SyntaxKind.ClassExpression);
|
||||
node.decorators = undefined;
|
||||
@@ -1408,7 +1410,7 @@ namespace ts {
|
||||
modifiers: ReadonlyArray<Modifier> | undefined,
|
||||
name: Identifier | undefined,
|
||||
typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined,
|
||||
heritageClauses: ReadonlyArray<HeritageClause>,
|
||||
heritageClauses: ReadonlyArray<HeritageClause> | undefined,
|
||||
members: ReadonlyArray<ClassElement>) {
|
||||
return node.modifiers !== modifiers
|
||||
|| node.name !== name
|
||||
@@ -1423,14 +1425,14 @@ namespace ts {
|
||||
return <OmittedExpression>createSynthesizedNode(SyntaxKind.OmittedExpression);
|
||||
}
|
||||
|
||||
export function createExpressionWithTypeArguments(typeArguments: ReadonlyArray<TypeNode>, expression: Expression) {
|
||||
export function createExpressionWithTypeArguments(typeArguments: ReadonlyArray<TypeNode> | undefined, expression: Expression) {
|
||||
const node = <ExpressionWithTypeArguments>createSynthesizedNode(SyntaxKind.ExpressionWithTypeArguments);
|
||||
node.expression = parenthesizeForAccess(expression);
|
||||
node.typeArguments = asNodeArray(typeArguments);
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, typeArguments: ReadonlyArray<TypeNode>, expression: Expression) {
|
||||
export function updateExpressionWithTypeArguments(node: ExpressionWithTypeArguments, typeArguments: ReadonlyArray<TypeNode> | undefined, expression: Expression) {
|
||||
return node.typeArguments !== typeArguments
|
||||
|| node.expression !== expression
|
||||
? updateNode(createExpressionWithTypeArguments(typeArguments, expression), node)
|
||||
@@ -1625,7 +1627,7 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createForOf(awaitModifier: AwaitKeywordToken, initializer: ForInitializer, expression: Expression, statement: Statement) {
|
||||
export function createForOf(awaitModifier: AwaitKeywordToken | undefined, initializer: ForInitializer, expression: Expression, statement: Statement) {
|
||||
const node = <ForOfStatement>createSynthesizedNode(SyntaxKind.ForOfStatement);
|
||||
node.awaitModifier = awaitModifier;
|
||||
node.initializer = initializer;
|
||||
@@ -1634,7 +1636,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateForOf(node: ForOfStatement, awaitModifier: AwaitKeywordToken, initializer: ForInitializer, expression: Expression, statement: Statement) {
|
||||
export function updateForOf(node: ForOfStatement, awaitModifier: AwaitKeywordToken | undefined, initializer: ForInitializer, expression: Expression, statement: Statement) {
|
||||
return node.awaitModifier !== awaitModifier
|
||||
|| node.initializer !== initializer
|
||||
|| node.expression !== expression
|
||||
@@ -1769,7 +1771,7 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createVariableDeclarationList(declarations: ReadonlyArray<VariableDeclaration>, flags?: NodeFlags) {
|
||||
export function createVariableDeclarationList(declarations: ReadonlyArray<VariableDeclaration>, flags = NodeFlags.None) {
|
||||
const node = <VariableDeclarationList>createSynthesizedNode(SyntaxKind.VariableDeclarationList);
|
||||
node.flags |= flags & NodeFlags.BlockScoped;
|
||||
node.declarations = createNodeArray(declarations);
|
||||
@@ -1830,7 +1832,7 @@ namespace ts {
|
||||
modifiers: ReadonlyArray<Modifier> | undefined,
|
||||
name: string | Identifier | undefined,
|
||||
typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined,
|
||||
heritageClauses: ReadonlyArray<HeritageClause>,
|
||||
heritageClauses: ReadonlyArray<HeritageClause> | undefined,
|
||||
members: ReadonlyArray<ClassElement>) {
|
||||
const node = <ClassDeclaration>createSynthesizedNode(SyntaxKind.ClassDeclaration);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
@@ -1848,7 +1850,7 @@ namespace ts {
|
||||
modifiers: ReadonlyArray<Modifier> | undefined,
|
||||
name: Identifier | undefined,
|
||||
typeParameters: ReadonlyArray<TypeParameterDeclaration> | undefined,
|
||||
heritageClauses: ReadonlyArray<HeritageClause>,
|
||||
heritageClauses: ReadonlyArray<HeritageClause> | undefined,
|
||||
members: ReadonlyArray<ClassElement>) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
@@ -1953,7 +1955,7 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createModuleDeclaration(decorators: ReadonlyArray<Decorator> | undefined, modifiers: ReadonlyArray<Modifier> | undefined, name: ModuleName, body: ModuleBody | undefined, flags?: NodeFlags) {
|
||||
export function createModuleDeclaration(decorators: ReadonlyArray<Decorator> | undefined, modifiers: ReadonlyArray<Modifier> | undefined, name: ModuleName, body: ModuleBody | undefined, flags = NodeFlags.None) {
|
||||
const node = <ModuleDeclaration>createSynthesizedNode(SyntaxKind.ModuleDeclaration);
|
||||
node.flags |= flags & (NodeFlags.Namespace | NodeFlags.NestedNamespace | NodeFlags.GlobalAugmentation);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
@@ -2044,7 +2046,7 @@ namespace ts {
|
||||
decorators: ReadonlyArray<Decorator> | undefined,
|
||||
modifiers: ReadonlyArray<Modifier> | undefined,
|
||||
importClause: ImportClause | undefined,
|
||||
moduleSpecifier: Expression | undefined) {
|
||||
moduleSpecifier: Expression) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.importClause !== importClause
|
||||
@@ -2105,7 +2107,7 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createExportAssignment(decorators: ReadonlyArray<Decorator> | undefined, modifiers: ReadonlyArray<Modifier> | undefined, isExportEquals: boolean, expression: Expression) {
|
||||
export function createExportAssignment(decorators: ReadonlyArray<Decorator> | undefined, modifiers: ReadonlyArray<Modifier> | undefined, isExportEquals: boolean | undefined, expression: Expression) {
|
||||
const node = <ExportAssignment>createSynthesizedNode(SyntaxKind.ExportAssignment);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
@@ -2402,7 +2404,7 @@ namespace ts {
|
||||
|
||||
export function createSpreadAssignment(expression: Expression) {
|
||||
const node = <SpreadAssignment>createSynthesizedNode(SyntaxKind.SpreadAssignment);
|
||||
node.expression = expression !== undefined ? parenthesizeExpressionForList(expression) : undefined;
|
||||
node.expression = expression !== undefined ? parenthesizeExpressionForList(expression) : undefined!; // TODO: GH#18217
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -2512,7 +2514,7 @@ namespace ts {
|
||||
/* @internal */
|
||||
export function createEndOfDeclarationMarker(original: Node) {
|
||||
const node = <EndOfDeclarationMarker>createSynthesizedNode(SyntaxKind.EndOfDeclarationMarker);
|
||||
node.emitNode = {};
|
||||
node.emitNode = {} as EmitNode;
|
||||
node.original = original;
|
||||
return node;
|
||||
}
|
||||
@@ -2524,7 +2526,7 @@ namespace ts {
|
||||
/* @internal */
|
||||
export function createMergeDeclarationMarker(original: Node) {
|
||||
const node = <MergeDeclarationMarker>createSynthesizedNode(SyntaxKind.MergeDeclarationMarker);
|
||||
node.emitNode = {};
|
||||
node.emitNode = {} as EmitNode;
|
||||
node.original = original;
|
||||
return node;
|
||||
}
|
||||
@@ -2701,12 +2703,7 @@ namespace ts {
|
||||
|
||||
// Utilities
|
||||
|
||||
function asName(name: string | Identifier): Identifier;
|
||||
function asName(name: string | BindingName): BindingName;
|
||||
function asName(name: string | PropertyName): PropertyName;
|
||||
function asName(name: string | EntityName): EntityName;
|
||||
function asName(name: string | Identifier | ThisTypeNode): Identifier | ThisTypeNode;
|
||||
function asName(name: string | Identifier | BindingName | PropertyName | QualifiedName | ThisTypeNode) {
|
||||
function asName<T extends Identifier | BindingName | PropertyName | EntityName | ThisTypeNode | undefined>(name: string | T): T | Identifier {
|
||||
return isString(name) ? createIdentifier(name) : name;
|
||||
}
|
||||
|
||||
@@ -2714,6 +2711,8 @@ namespace ts {
|
||||
return isString(value) || typeof value === "number" ? createLiteral(value) : value;
|
||||
}
|
||||
|
||||
function asNodeArray<T extends Node>(array: ReadonlyArray<T>): NodeArray<T>;
|
||||
function asNodeArray<T extends Node>(array: ReadonlyArray<T> | undefined): NodeArray<T> | undefined;
|
||||
function asNodeArray<T extends Node>(array: ReadonlyArray<T> | undefined): NodeArray<T> | undefined {
|
||||
return array ? createNodeArray(array) : undefined;
|
||||
}
|
||||
@@ -2748,21 +2747,21 @@ namespace ts {
|
||||
* various transient transformation properties.
|
||||
*/
|
||||
/* @internal */
|
||||
export function getOrCreateEmitNode(node: Node) {
|
||||
export function getOrCreateEmitNode(node: Node): EmitNode {
|
||||
if (!node.emitNode) {
|
||||
if (isParseTreeNode(node)) {
|
||||
// To avoid holding onto transformation artifacts, we keep track of any
|
||||
// parse tree node we are annotating. This allows us to clean them up after
|
||||
// all transformations have completed.
|
||||
if (node.kind === SyntaxKind.SourceFile) {
|
||||
return node.emitNode = { annotatedNodes: [node] };
|
||||
return node.emitNode = { annotatedNodes: [node] } as EmitNode;
|
||||
}
|
||||
|
||||
const sourceFile = getSourceFileOfNode(node);
|
||||
getOrCreateEmitNode(sourceFile).annotatedNodes.push(node);
|
||||
getOrCreateEmitNode(sourceFile).annotatedNodes!.push(node);
|
||||
}
|
||||
|
||||
node.emitNode = {};
|
||||
node.emitNode = {} as EmitNode;
|
||||
}
|
||||
|
||||
return node.emitNode;
|
||||
@@ -2878,7 +2877,7 @@ namespace ts {
|
||||
return emitNode && emitNode.leadingComments;
|
||||
}
|
||||
|
||||
export function setSyntheticLeadingComments<T extends Node>(node: T, comments: SynthesizedComment[]) {
|
||||
export function setSyntheticLeadingComments<T extends Node>(node: T, comments: SynthesizedComment[] | undefined) {
|
||||
getOrCreateEmitNode(node).leadingComments = comments;
|
||||
return node;
|
||||
}
|
||||
@@ -2892,7 +2891,7 @@ namespace ts {
|
||||
return emitNode && emitNode.trailingComments;
|
||||
}
|
||||
|
||||
export function setSyntheticTrailingComments<T extends Node>(node: T, comments: SynthesizedComment[]) {
|
||||
export function setSyntheticTrailingComments<T extends Node>(node: T, comments: SynthesizedComment[] | undefined) {
|
||||
getOrCreateEmitNode(node).trailingComments = comments;
|
||||
return node;
|
||||
}
|
||||
@@ -2913,7 +2912,7 @@ namespace ts {
|
||||
/**
|
||||
* Gets the constant value to emit for an expression.
|
||||
*/
|
||||
export function getConstantValue(node: PropertyAccessExpression | ElementAccessExpression) {
|
||||
export function getConstantValue(node: PropertyAccessExpression | ElementAccessExpression): string | number | undefined {
|
||||
const emitNode = node.emitNode;
|
||||
return emitNode && emitNode.constantValue;
|
||||
}
|
||||
@@ -3015,7 +3014,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
function mergeEmitNode(sourceEmitNode: EmitNode, destEmitNode: EmitNode) {
|
||||
function mergeEmitNode(sourceEmitNode: EmitNode, destEmitNode: EmitNode | undefined) {
|
||||
const {
|
||||
flags,
|
||||
leadingComments,
|
||||
@@ -3027,21 +3026,21 @@ namespace ts {
|
||||
helpers,
|
||||
startsOnNewLine,
|
||||
} = sourceEmitNode;
|
||||
if (!destEmitNode) destEmitNode = {};
|
||||
if (!destEmitNode) destEmitNode = {} as EmitNode;
|
||||
// We are using `.slice()` here in case `destEmitNode.leadingComments` is pushed to later.
|
||||
if (leadingComments) destEmitNode.leadingComments = addRange(leadingComments.slice(), destEmitNode.leadingComments);
|
||||
if (trailingComments) destEmitNode.trailingComments = addRange(trailingComments.slice(), destEmitNode.trailingComments);
|
||||
if (flags) destEmitNode.flags = flags;
|
||||
if (commentRange) destEmitNode.commentRange = commentRange;
|
||||
if (sourceMapRange) destEmitNode.sourceMapRange = sourceMapRange;
|
||||
if (tokenSourceMapRanges) destEmitNode.tokenSourceMapRanges = mergeTokenSourceMapRanges(tokenSourceMapRanges, destEmitNode.tokenSourceMapRanges);
|
||||
if (tokenSourceMapRanges) destEmitNode.tokenSourceMapRanges = mergeTokenSourceMapRanges(tokenSourceMapRanges, destEmitNode.tokenSourceMapRanges!);
|
||||
if (constantValue !== undefined) destEmitNode.constantValue = constantValue;
|
||||
if (helpers) destEmitNode.helpers = addRange(destEmitNode.helpers, helpers);
|
||||
if (startsOnNewLine !== undefined) destEmitNode.startsOnNewLine = startsOnNewLine;
|
||||
return destEmitNode;
|
||||
}
|
||||
|
||||
function mergeTokenSourceMapRanges(sourceRanges: TextRange[], destRanges: TextRange[]) {
|
||||
function mergeTokenSourceMapRanges(sourceRanges: (TextRange | undefined)[], destRanges: (TextRange | undefined)[]) {
|
||||
if (!destRanges) destRanges = [];
|
||||
for (const key in sourceRanges) {
|
||||
destRanges[key] = sourceRanges[key];
|
||||
@@ -3178,7 +3177,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function createJsxFactoryExpression(jsxFactoryEntity: EntityName, reactNamespace: string, parent: JsxOpeningLikeElement | JsxOpeningFragment): Expression {
|
||||
function createJsxFactoryExpression(jsxFactoryEntity: EntityName | undefined, reactNamespace: string, parent: JsxOpeningLikeElement | JsxOpeningFragment): Expression {
|
||||
return jsxFactoryEntity ?
|
||||
createJsxFactoryExpressionFromEntityName(jsxFactoryEntity, parent) :
|
||||
createPropertyAccess(
|
||||
@@ -3187,7 +3186,7 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
export function createExpressionForJsxElement(jsxFactoryEntity: EntityName, reactNamespace: string, tagName: Expression, props: Expression, children: ReadonlyArray<Expression>, parentElement: JsxOpeningLikeElement, location: TextRange): LeftHandSideExpression {
|
||||
export function createExpressionForJsxElement(jsxFactoryEntity: EntityName | undefined, reactNamespace: string, tagName: Expression, props: Expression, children: ReadonlyArray<Expression>, parentElement: JsxOpeningLikeElement, location: TextRange): LeftHandSideExpression {
|
||||
const argumentsList = [tagName];
|
||||
if (props) {
|
||||
argumentsList.push(props);
|
||||
@@ -3219,7 +3218,7 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
export function createExpressionForJsxFragment(jsxFactoryEntity: EntityName, reactNamespace: string, children: ReadonlyArray<Expression>, parentElement: JsxOpeningFragment, location: TextRange): LeftHandSideExpression {
|
||||
export function createExpressionForJsxFragment(jsxFactoryEntity: EntityName | undefined, reactNamespace: string, children: ReadonlyArray<Expression>, parentElement: JsxOpeningFragment, location: TextRange): LeftHandSideExpression {
|
||||
const tagName = createPropertyAccess(
|
||||
createReactNamespace(reactNamespace, parentElement),
|
||||
"Fragment"
|
||||
@@ -3347,7 +3346,7 @@ namespace ts {
|
||||
|
||||
export function createForOfBindingStatement(node: ForInitializer, boundValue: Expression): Statement {
|
||||
if (isVariableDeclarationList(node)) {
|
||||
const firstDeclaration = firstOrUndefined(node.declarations);
|
||||
const firstDeclaration = first(node.declarations);
|
||||
const updatedDeclaration = updateVariableDeclaration(
|
||||
firstDeclaration,
|
||||
firstDeclaration.name,
|
||||
@@ -3377,7 +3376,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function restoreEnclosingLabel(node: Statement, outermostLabeledStatement: LabeledStatement, afterRestoreLabelCallback?: (node: LabeledStatement) => void): Statement {
|
||||
export function restoreEnclosingLabel(node: Statement, outermostLabeledStatement: LabeledStatement | undefined, afterRestoreLabelCallback?: (node: LabeledStatement) => void): Statement {
|
||||
if (!outermostLabeledStatement) {
|
||||
return node;
|
||||
}
|
||||
@@ -3421,7 +3420,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function createCallBinding(expression: Expression, recordTempVariable: (temp: Identifier) => void, languageVersion?: ScriptTarget, cacheIdentifiers?: boolean): CallBinding {
|
||||
export function createCallBinding(expression: Expression, recordTempVariable: (temp: Identifier) => void, languageVersion?: ScriptTarget, cacheIdentifiers = false): CallBinding {
|
||||
const callee = skipOuterExpressions(expression, OuterExpressionKinds.All);
|
||||
let thisArg: Expression;
|
||||
let target: LeftHandSideExpression;
|
||||
@@ -3431,7 +3430,7 @@ namespace ts {
|
||||
}
|
||||
else if (callee.kind === SyntaxKind.SuperKeyword) {
|
||||
thisArg = createThis();
|
||||
target = languageVersion < ScriptTarget.ES2015
|
||||
target = languageVersion! < ScriptTarget.ES2015
|
||||
? setTextRange(createIdentifier("_super"), callee)
|
||||
: <PrimaryExpression>callee;
|
||||
}
|
||||
@@ -3505,7 +3504,7 @@ namespace ts {
|
||||
// stack size exceeded" errors.
|
||||
return expressions.length > 10
|
||||
? createCommaList(expressions)
|
||||
: reduceLeft(expressions, createComma);
|
||||
: reduceLeft(expressions, createComma)!;
|
||||
}
|
||||
|
||||
export function createExpressionFromEntityName(node: EntityName | Expression): Expression {
|
||||
@@ -3531,11 +3530,11 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function createExpressionForObjectLiteralElementLike(node: ObjectLiteralExpression, property: ObjectLiteralElementLike, receiver: Expression): Expression {
|
||||
export function createExpressionForObjectLiteralElementLike(node: ObjectLiteralExpression, property: ObjectLiteralElementLike, receiver: Expression): Expression | undefined {
|
||||
switch (property.kind) {
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
return createExpressionForAccessorDeclaration(node.properties, property, receiver, node.multiLine);
|
||||
return createExpressionForAccessorDeclaration(node.properties, property, receiver, !!node.multiLine);
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
return createExpressionForPropertyAssignment(property, receiver);
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
@@ -3557,7 +3556,7 @@ namespace ts {
|
||||
/*typeParameters*/ undefined,
|
||||
getAccessor.parameters,
|
||||
/*type*/ undefined,
|
||||
getAccessor.body
|
||||
getAccessor.body! // TODO: GH#18217
|
||||
);
|
||||
setTextRange(getterFunction, getAccessor);
|
||||
setOriginalNode(getterFunction, getAccessor);
|
||||
@@ -3573,7 +3572,7 @@ namespace ts {
|
||||
/*typeParameters*/ undefined,
|
||||
setAccessor.parameters,
|
||||
/*type*/ undefined,
|
||||
setAccessor.body
|
||||
setAccessor.body! // TODO: GH#18217
|
||||
);
|
||||
setTextRange(setterFunction, setAccessor);
|
||||
setOriginalNode(setterFunction, setAccessor);
|
||||
@@ -3648,7 +3647,7 @@ namespace ts {
|
||||
/*typeParameters*/ undefined,
|
||||
method.parameters,
|
||||
/*type*/ undefined,
|
||||
method.body
|
||||
method.body! // TODO: GH#18217
|
||||
),
|
||||
/*location*/ method
|
||||
),
|
||||
@@ -3738,7 +3737,7 @@ namespace ts {
|
||||
return getName(node, allowComments, allowSourceMaps);
|
||||
}
|
||||
|
||||
function getName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) {
|
||||
function getName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags: EmitFlags = 0) {
|
||||
const nodeName = getNameOfDeclaration(node);
|
||||
if (nodeName && isIdentifier(nodeName) && !isGeneratedIdentifier(nodeName)) {
|
||||
const name = getMutableClone(nodeName);
|
||||
@@ -3780,7 +3779,7 @@ namespace ts {
|
||||
export function getNamespaceMemberName(ns: Identifier, name: Identifier, allowComments?: boolean, allowSourceMaps?: boolean): PropertyAccessExpression {
|
||||
const qualifiedName = createPropertyAccess(ns, nodeIsSynthesized(name) ? name : getSynthesizedClone(name));
|
||||
setTextRange(qualifiedName, name);
|
||||
let emitFlags: EmitFlags;
|
||||
let emitFlags: EmitFlags = 0;
|
||||
if (!allowSourceMaps) emitFlags |= EmitFlags.NoSourceMap;
|
||||
if (!allowComments) emitFlags |= EmitFlags.NoComments;
|
||||
if (emitFlags) setEmitFlags(qualifiedName, emitFlags);
|
||||
@@ -3792,7 +3791,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function convertFunctionDeclarationToExpression(node: FunctionDeclaration) {
|
||||
Debug.assert(!!node.body);
|
||||
if (!node.body) return Debug.fail();
|
||||
const updated = createFunctionExpression(
|
||||
node.modifiers,
|
||||
node.asteriskToken,
|
||||
@@ -3867,9 +3866,11 @@ namespace ts {
|
||||
* This function needs to be called whenever we transform the statement
|
||||
* list of a source file, namespace, or function-like body.
|
||||
*/
|
||||
export function addCustomPrologue(target: Statement[], source: ReadonlyArray<Statement>, statementOffset: number, visitor?: (node: Node) => VisitResult<Node>): number {
|
||||
export function addCustomPrologue(target: Statement[], source: ReadonlyArray<Statement>, statementOffset: number, visitor?: (node: Node) => VisitResult<Node>): number;
|
||||
export function addCustomPrologue(target: Statement[], source: ReadonlyArray<Statement>, statementOffset: number | undefined, visitor?: (node: Node) => VisitResult<Node>): number | undefined;
|
||||
export function addCustomPrologue(target: Statement[], source: ReadonlyArray<Statement>, statementOffset: number | undefined, visitor?: (node: Node) => VisitResult<Node>): number | undefined {
|
||||
const numStatements = source.length;
|
||||
while (statementOffset < numStatements) {
|
||||
while (statementOffset !== undefined && statementOffset < numStatements) {
|
||||
const statement = source[statementOffset];
|
||||
if (getEmitFlags(statement) & EmitFlags.CustomPrologue) {
|
||||
append(target, visitor ? visitNode(statement, visitor, isStatement) : statement);
|
||||
@@ -3951,7 +3952,7 @@ namespace ts {
|
||||
* @param isLeftSideOfBinary A value indicating whether the operand is the left side of the
|
||||
* BinaryExpression.
|
||||
*/
|
||||
function binaryOperandNeedsParentheses(binaryOperator: SyntaxKind, operand: Expression, isLeftSideOfBinary: boolean, leftOperand: Expression) {
|
||||
function binaryOperandNeedsParentheses(binaryOperator: SyntaxKind, operand: Expression, isLeftSideOfBinary: boolean, leftOperand: Expression | undefined) {
|
||||
// If the operand has lower precedence, then it needs to be parenthesized to preserve the
|
||||
// intent of the expression. For example, if the operand is `a + b` and the operator is
|
||||
// `*`, then we need to parenthesize the operand to preserve the intended order of
|
||||
@@ -4196,7 +4197,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function parenthesizeListElements(elements: NodeArray<Expression>) {
|
||||
let result: Expression[];
|
||||
let result: Expression[] | undefined;
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
const element = parenthesizeExpressionForList(elements[i]);
|
||||
if (result !== undefined || element !== elements[i]) {
|
||||
@@ -4273,7 +4274,7 @@ namespace ts {
|
||||
return createNodeArray(sameMap(members, parenthesizeElementTypeMember));
|
||||
}
|
||||
|
||||
export function parenthesizeTypeParameters(typeParameters: ReadonlyArray<TypeNode>) {
|
||||
export function parenthesizeTypeParameters(typeParameters: ReadonlyArray<TypeNode> | undefined) {
|
||||
if (some(typeParameters)) {
|
||||
const params: TypeNode[] = [];
|
||||
for (let i = 0; i < typeParameters.length; ++i) {
|
||||
@@ -4475,7 +4476,7 @@ namespace ts {
|
||||
/**
|
||||
* Get the name of that target module from an import or export declaration
|
||||
*/
|
||||
export function getLocalNameForExternalImport(node: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration, sourceFile: SourceFile): Identifier {
|
||||
export function getLocalNameForExternalImport(node: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration, sourceFile: SourceFile): Identifier | undefined {
|
||||
const namespaceDeclaration = getNamespaceDeclarationNode(node);
|
||||
if (namespaceDeclaration && !isDefaultImport(node)) {
|
||||
const name = namespaceDeclaration.name;
|
||||
@@ -4499,7 +4500,7 @@ namespace ts {
|
||||
* Otherwise, a new StringLiteral node representing the module name will be returned.
|
||||
*/
|
||||
export function getExternalModuleNameLiteral(importNode: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration, sourceFile: SourceFile, host: EmitHost, resolver: EmitResolver, compilerOptions: CompilerOptions) {
|
||||
const moduleName = getExternalModuleName(importNode);
|
||||
const moduleName = getExternalModuleName(importNode)!; // TODO: GH#18217
|
||||
if (moduleName.kind === SyntaxKind.StringLiteral) {
|
||||
return tryGetModuleNameFromDeclaration(importNode, host, resolver, compilerOptions)
|
||||
|| tryRenameExternalModule(<StringLiteral>moduleName, sourceFile)
|
||||
@@ -4525,7 +4526,7 @@ namespace ts {
|
||||
* 2. --out or --outFile is used, making the name relative to the rootDir
|
||||
* Otherwise, a new StringLiteral node representing the module name will be returned.
|
||||
*/
|
||||
export function tryGetModuleNameFromFile(file: SourceFile, host: EmitHost, options: CompilerOptions): StringLiteral {
|
||||
export function tryGetModuleNameFromFile(file: SourceFile | undefined, host: EmitHost, options: CompilerOptions): StringLiteral | undefined {
|
||||
if (!file) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -4561,8 +4562,9 @@ namespace ts {
|
||||
// `1` in `({ a: b = 1 } = ...)`
|
||||
// `1` in `({ a: {b} = 1 } = ...)`
|
||||
// `1` in `({ a: [b] = 1 } = ...)`
|
||||
return isAssignmentExpression(bindingElement.initializer, /*excludeCompoundAssignment*/ true)
|
||||
? bindingElement.initializer.right
|
||||
const initializer = bindingElement.initializer;
|
||||
return isAssignmentExpression(initializer, /*excludeCompoundAssignment*/ true)
|
||||
? initializer.right
|
||||
: undefined;
|
||||
}
|
||||
|
||||
@@ -4587,7 +4589,7 @@ namespace ts {
|
||||
/**
|
||||
* Gets the name of an BindingOrAssignmentElement.
|
||||
*/
|
||||
export function getTargetOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): BindingOrAssignmentElementTarget {
|
||||
export function getTargetOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): BindingOrAssignmentElementTarget | undefined {
|
||||
if (isDeclarationBindingElement(bindingElement)) {
|
||||
// `a` in `let { a } = ...`
|
||||
// `a` in `let { a = 1 } = ...`
|
||||
@@ -4662,7 +4664,7 @@ namespace ts {
|
||||
/**
|
||||
* Determines whether an BindingOrAssignmentElement is a rest element.
|
||||
*/
|
||||
export function getRestIndicatorOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): BindingOrAssignmentElementRestIndicator {
|
||||
export function getRestIndicatorOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): BindingOrAssignmentElementRestIndicator | undefined {
|
||||
switch (bindingElement.kind) {
|
||||
case SyntaxKind.Parameter:
|
||||
case SyntaxKind.BindingElement:
|
||||
|
||||
@@ -2,12 +2,12 @@ namespace ts {
|
||||
/* @internal */
|
||||
export function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void;
|
||||
export function trace(host: ModuleResolutionHost): void {
|
||||
host.trace(formatMessage.apply(undefined, arguments));
|
||||
host.trace!(formatMessage.apply(undefined, arguments));
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isTraceEnabled(compilerOptions: CompilerOptions, host: ModuleResolutionHost): boolean {
|
||||
return compilerOptions.traceResolution && host.trace !== undefined;
|
||||
return !!compilerOptions.traceResolution && host.trace !== undefined;
|
||||
}
|
||||
|
||||
/** Array that is only intended to be pushed to, never read. */
|
||||
@@ -16,11 +16,11 @@ namespace ts {
|
||||
push(value: T): void;
|
||||
}
|
||||
|
||||
function withPackageId(packageId: PackageId | undefined, r: PathAndExtension | undefined): Resolved {
|
||||
function withPackageId(packageId: PackageId | undefined, r: PathAndExtension | undefined): Resolved | undefined {
|
||||
return r && { path: r.path, extension: r.ext, packageId };
|
||||
}
|
||||
|
||||
function noPackageId(r: PathAndExtension | undefined): Resolved {
|
||||
function noPackageId(r: PathAndExtension | undefined): Resolved | undefined {
|
||||
return withPackageId(/*packageId*/ undefined, r);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace ts {
|
||||
|
||||
interface PathAndPackageId {
|
||||
readonly fileName: string;
|
||||
readonly packageId: PackageId;
|
||||
readonly packageId: PackageId | undefined;
|
||||
}
|
||||
/** Used with `Extensions.DtsOnly` to extract the path from TypeScript results. */
|
||||
function resolvedTypeScriptOnly(resolved: Resolved | undefined): PathAndPackageId | undefined {
|
||||
@@ -141,7 +141,7 @@ namespace ts {
|
||||
return options.typeRoots;
|
||||
}
|
||||
|
||||
let currentDirectory: string;
|
||||
let currentDirectory: string | undefined;
|
||||
if (options.configFilePath) {
|
||||
currentDirectory = getDirectoryPath(options.configFilePath);
|
||||
}
|
||||
@@ -164,10 +164,10 @@ namespace ts {
|
||||
// And if it doesn't exist, tough.
|
||||
}
|
||||
|
||||
let typeRoots: string[];
|
||||
let typeRoots: string[] | undefined;
|
||||
forEachAncestorDirectory(normalizePath(currentDirectory), directory => {
|
||||
const atTypes = combinePaths(directory, nodeModulesAtTypes);
|
||||
if (host.directoryExists(atTypes)) {
|
||||
if (host.directoryExists!(atTypes)) {
|
||||
(typeRoots || (typeRoots = [])).push(atTypes);
|
||||
}
|
||||
return undefined;
|
||||
@@ -254,7 +254,6 @@ namespace ts {
|
||||
}
|
||||
|
||||
function secondaryLookup(): PathAndPackageId | undefined {
|
||||
let resolvedFile: PathAndPackageId;
|
||||
const initialLocationForSecondaryLookup = containingFile && getDirectoryPath(containingFile);
|
||||
|
||||
if (initialLocationForSecondaryLookup !== undefined) {
|
||||
@@ -263,7 +262,7 @@ namespace ts {
|
||||
trace(host, Diagnostics.Looking_up_in_node_modules_folder_initial_location_0, initialLocationForSecondaryLookup);
|
||||
}
|
||||
const result = loadModuleFromNodeModules(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, failedLookupLocations, moduleResolutionState, /*cache*/ undefined);
|
||||
resolvedFile = resolvedTypeScriptOnly(result && result.value);
|
||||
const resolvedFile = resolvedTypeScriptOnly(result && result.value);
|
||||
if (!resolvedFile && traceEnabled) {
|
||||
trace(host, Diagnostics.Type_reference_directive_0_was_not_resolved, typeReferenceDirectiveName);
|
||||
}
|
||||
@@ -334,7 +333,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export interface PerModuleNameCache {
|
||||
get(directory: string): ResolvedModuleWithFailedLookupLocations;
|
||||
get(directory: string): ResolvedModuleWithFailedLookupLocations | undefined;
|
||||
set(directory: string, result: ResolvedModuleWithFailedLookupLocations): void;
|
||||
}
|
||||
|
||||
@@ -366,9 +365,9 @@ namespace ts {
|
||||
return perFolderCache;
|
||||
}
|
||||
|
||||
function getOrCreateCacheForModuleName(nonRelativeModuleName: string) {
|
||||
function getOrCreateCacheForModuleName(nonRelativeModuleName: string): PerModuleNameCache {
|
||||
if (isExternalModuleNameRelative(nonRelativeModuleName)) {
|
||||
return undefined;
|
||||
return undefined!; // TODO: GH#18217
|
||||
}
|
||||
let perModuleNameCache = moduleNameToDirectoryMap.get(nonRelativeModuleName);
|
||||
if (!perModuleNameCache) {
|
||||
@@ -383,7 +382,7 @@ namespace ts {
|
||||
|
||||
return { get, set };
|
||||
|
||||
function get(directory: string): ResolvedModuleWithFailedLookupLocations {
|
||||
function get(directory: string): ResolvedModuleWithFailedLookupLocations | undefined {
|
||||
return directoryPathMap.get(toPath(directory, currentDirectory, getCanonicalFileName));
|
||||
}
|
||||
|
||||
@@ -427,7 +426,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getCommonPrefix(directory: Path, resolution: string) {
|
||||
function getCommonPrefix(directory: Path, resolution: string | undefined) {
|
||||
if (resolution === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -492,13 +491,13 @@ namespace ts {
|
||||
result = classicNameResolver(moduleName, containingFile, compilerOptions, host, cache);
|
||||
break;
|
||||
default:
|
||||
Debug.fail(`Unexpected moduleResolution: ${moduleResolution}`);
|
||||
return Debug.fail(`Unexpected moduleResolution: ${moduleResolution}`);
|
||||
}
|
||||
|
||||
if (perFolderCache) {
|
||||
perFolderCache.set(moduleName, result);
|
||||
// put result in per-module name cache
|
||||
const perModuleNameCache = cache.getOrCreateCacheForModuleName(moduleName);
|
||||
const perModuleNameCache = cache!.getOrCreateCacheForModuleName(moduleName);
|
||||
if (perModuleNameCache) {
|
||||
perModuleNameCache.set(containingDirectory, result);
|
||||
}
|
||||
@@ -611,8 +610,8 @@ namespace ts {
|
||||
|
||||
const candidate = normalizePath(combinePaths(containingDirectory, moduleName));
|
||||
|
||||
let matchedRootDir: string;
|
||||
let matchedNormalizedPrefix: string;
|
||||
let matchedRootDir: string | undefined;
|
||||
let matchedNormalizedPrefix: string | undefined;
|
||||
for (const rootDir of state.compilerOptions.rootDirs) {
|
||||
// rootDirs are expected to be absolute
|
||||
// in case of tsconfig.json this will happen automatically - compiler will expand relative names
|
||||
@@ -698,9 +697,9 @@ namespace ts {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.Module_name_0_matched_pattern_1, moduleName, matchedPatternText);
|
||||
}
|
||||
return forEach(state.compilerOptions.paths[matchedPatternText], subst => {
|
||||
return forEach(state.compilerOptions.paths![matchedPatternText], subst => {
|
||||
const path = matchedStar ? subst.replace("*", matchedStar) : subst;
|
||||
const candidate = normalizePath(combinePaths(state.compilerOptions.baseUrl, path));
|
||||
const candidate = normalizePath(combinePaths(state.compilerOptions.baseUrl!, path));
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.Trying_substitution_0_candidate_module_location_Colon_1, subst, path);
|
||||
}
|
||||
@@ -781,7 +780,7 @@ namespace ts {
|
||||
let originalPath: string | undefined;
|
||||
if (!compilerOptions.preserveSymlinks && resolvedValue) {
|
||||
originalPath = resolvedValue.path;
|
||||
const path = realPath(resolved.value.path, host, traceEnabled);
|
||||
const path = realPath(resolvedValue.path, host, traceEnabled);
|
||||
if (path === originalPath) {
|
||||
originalPath = undefined;
|
||||
}
|
||||
@@ -899,7 +898,7 @@ namespace ts {
|
||||
return !host.directoryExists || host.directoryExists(directoryName);
|
||||
}
|
||||
|
||||
function loadModuleFromFileNoPackageId(extensions: Extensions, candidate: string, failedLookupLocations: Push<string>, onlyRecordFailures: boolean, state: ModuleResolutionState): Resolved {
|
||||
function loadModuleFromFileNoPackageId(extensions: Extensions, candidate: string, failedLookupLocations: Push<string>, onlyRecordFailures: boolean, state: ModuleResolutionState): Resolved | undefined {
|
||||
return noPackageId(loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state));
|
||||
}
|
||||
|
||||
@@ -910,7 +909,7 @@ namespace ts {
|
||||
function loadModuleFromFile(extensions: Extensions, candidate: string, failedLookupLocations: Push<string>, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined {
|
||||
if (extensions === Extensions.Json) {
|
||||
const extensionLess = tryRemoveExtension(candidate, Extension.Json);
|
||||
return extensionLess && tryAddingExtensions(extensionLess, extensions, failedLookupLocations, onlyRecordFailures, state);
|
||||
return extensionLess === undefined ? undefined : tryAddingExtensions(extensionLess, extensions, failedLookupLocations, onlyRecordFailures, state);
|
||||
}
|
||||
|
||||
// First, try adding an extension. An import of "foo" could be matched by a file "foo.ts", or "foo.js" by "foo.js.ts"
|
||||
@@ -954,7 +953,7 @@ namespace ts {
|
||||
|
||||
function tryExtension(ext: Extension): PathAndExtension | undefined {
|
||||
const path = tryFile(candidate + ext, failedLookupLocations, onlyRecordFailures, state);
|
||||
return path && { path, ext };
|
||||
return path === undefined ? undefined : { path, ext };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1025,7 +1024,7 @@ namespace ts {
|
||||
if (!endsWith(subModuleName, Extension.Dts)) {
|
||||
subModuleName = addExtensionAndIndex(subModuleName);
|
||||
}
|
||||
const packageId: PackageId = typeof packageJsonContent.name === "string" && typeof packageJsonContent.version === "string"
|
||||
const packageId: PackageId | undefined = typeof packageJsonContent.name === "string" && typeof packageJsonContent.version === "string"
|
||||
? { name: packageJsonContent.name, subModuleName, version: packageJsonContent.version }
|
||||
: undefined;
|
||||
if (traceEnabled) {
|
||||
@@ -1141,7 +1140,7 @@ namespace ts {
|
||||
return idx === -1 ? { packageName: moduleName, rest: "" } : { packageName: moduleName.slice(0, idx), rest: moduleName.slice(idx + 1) };
|
||||
}
|
||||
|
||||
function loadModuleFromNodeModules(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: Push<string>, state: ModuleResolutionState, cache: NonRelativeModuleNameResolutionCache): SearchResult<Resolved> {
|
||||
function loadModuleFromNodeModules(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: Push<string>, state: ModuleResolutionState, cache: NonRelativeModuleNameResolutionCache | undefined): SearchResult<Resolved> {
|
||||
return loadModuleFromNodeModulesWorker(extensions, moduleName, directory, failedLookupLocations, state, /*typesOnly*/ false, cache);
|
||||
}
|
||||
function loadModuleFromNodeModulesAtTypes(moduleName: string, directory: string, failedLookupLocations: Push<string>, state: ModuleResolutionState): SearchResult<Resolved> {
|
||||
@@ -1149,7 +1148,7 @@ namespace ts {
|
||||
return loadModuleFromNodeModulesWorker(Extensions.DtsOnly, moduleName, directory, failedLookupLocations, state, /*typesOnly*/ true, /*cache*/ undefined);
|
||||
}
|
||||
|
||||
function loadModuleFromNodeModulesWorker(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: Push<string>, state: ModuleResolutionState, typesOnly: boolean, cache: NonRelativeModuleNameResolutionCache): SearchResult<Resolved> {
|
||||
function loadModuleFromNodeModulesWorker(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: Push<string>, state: ModuleResolutionState, typesOnly: boolean, cache: NonRelativeModuleNameResolutionCache | undefined): SearchResult<Resolved> {
|
||||
const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName);
|
||||
return forEachAncestorDirectory(normalizeSlashes(directory), ancestorDirectory => {
|
||||
if (getBaseFileName(ancestorDirectory) !== "node_modules") {
|
||||
@@ -1289,7 +1288,7 @@ namespace ts {
|
||||
* This is the minumum code needed to expose that functionality; the rest is in LSHost.
|
||||
*/
|
||||
/* @internal */
|
||||
export function loadModuleFromGlobalCache(moduleName: string, projectName: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, globalCache: string): ResolvedModuleWithFailedLookupLocations {
|
||||
export function loadModuleFromGlobalCache(moduleName: string, projectName: string | undefined, compilerOptions: CompilerOptions, host: ModuleResolutionHost, globalCache: string): ResolvedModuleWithFailedLookupLocations {
|
||||
const traceEnabled = isTraceEnabled(compilerOptions, host);
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2, projectName, moduleName, globalCache);
|
||||
|
||||
+111
-111
@@ -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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
namespace ts {
|
||||
declare const performance: { now?(): number } | undefined;
|
||||
/** Gets a timestamp with (at least) ms resolution */
|
||||
export const timestamp = typeof performance !== "undefined" && performance.now ? () => performance.now() : Date.now ? Date.now : () => +(new Date());
|
||||
export const timestamp = typeof performance !== "undefined" && performance.now ? () => performance.now!() : Date.now ? Date.now : () => +(new Date());
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
|
||||
Regular → Executable
+92
-91
@@ -16,7 +16,7 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export function computeCommonSourceDirectoryOfFilenames(fileNames: string[], currentDirectory: string, getCanonicalFileName: GetCanonicalFileName): string {
|
||||
let commonPathComponents: string[];
|
||||
let commonPathComponents: string[] | undefined;
|
||||
const failed = forEach(fileNames, sourceFile => {
|
||||
// Each file contributes into common source file path
|
||||
const sourcePathComponents = getNormalizedPathComponents(sourceFile, currentDirectory);
|
||||
@@ -75,8 +75,8 @@ namespace ts {
|
||||
return sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
|
||||
}
|
||||
|
||||
function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile {
|
||||
let text: string;
|
||||
function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile | undefined {
|
||||
let text: string | undefined;
|
||||
try {
|
||||
performance.mark("beforeIORead");
|
||||
text = sys.readFile(fileName, options.charset);
|
||||
@@ -119,8 +119,8 @@ namespace ts {
|
||||
outputFingerprints = createMap<OutputFingerprint>();
|
||||
}
|
||||
|
||||
const hash = sys.createHash(data);
|
||||
const mtimeBefore = sys.getModifiedTime(fileName);
|
||||
const hash = sys.createHash!(data); // TODO: GH#18217
|
||||
const mtimeBefore = sys.getModifiedTime!(fileName); // TODO: GH#18217
|
||||
|
||||
if (mtimeBefore) {
|
||||
const fingerprint = outputFingerprints.get(fileName);
|
||||
@@ -135,7 +135,7 @@ namespace ts {
|
||||
|
||||
sys.writeFile(fileName, data, writeByteOrderMark);
|
||||
|
||||
const mtimeAfter = sys.getModifiedTime(fileName);
|
||||
const mtimeAfter = sys.getModifiedTime!(fileName); // TODO: GH#18217
|
||||
|
||||
outputFingerprints.set(fileName, {
|
||||
hash,
|
||||
@@ -171,7 +171,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
const newLine = getNewLineCharacter(options);
|
||||
const realpath = sys.realpath && ((path: string) => sys.realpath(path));
|
||||
const realpath = sys.realpath && ((path: string) => sys.realpath!(path));
|
||||
|
||||
return {
|
||||
getSourceFile,
|
||||
@@ -228,7 +228,7 @@ namespace ts {
|
||||
const errorMessage = `${diagnosticCategoryName(diagnostic)} TS${diagnostic.code}: ${flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine())}${host.getNewLine()}`;
|
||||
|
||||
if (diagnostic.file) {
|
||||
const { line, character } = getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
|
||||
const { line, character } = getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start!); // TODO: GH#18217
|
||||
const fileName = diagnostic.file.fileName;
|
||||
const relativeFileName = convertToRelativePath(fileName, host.getCurrentDirectory(), fileName => host.getCanonicalFileName(fileName));
|
||||
return `${relativeFileName}(${line + 1},${character + 1}): ` + errorMessage;
|
||||
@@ -276,8 +276,8 @@ namespace ts {
|
||||
let context = "";
|
||||
if (diagnostic.file) {
|
||||
const { start, length, file } = diagnostic;
|
||||
const { line: firstLine, character: firstLineChar } = getLineAndCharacterOfPosition(file, start);
|
||||
const { line: lastLine, character: lastLineChar } = getLineAndCharacterOfPosition(file, start + length);
|
||||
const { line: firstLine, character: firstLineChar } = getLineAndCharacterOfPosition(file, start!); // TODO: GH#18217
|
||||
const { line: lastLine, character: lastLineChar } = getLineAndCharacterOfPosition(file, start! + length!);
|
||||
const lastLineInFile = getLineAndCharacterOfPosition(file, file.text.length).line;
|
||||
const relativeFileName = host ? convertToRelativePath(file.fileName, host.getCurrentDirectory(), fileName => host.getCanonicalFileName(fileName)) : file.fileName;
|
||||
|
||||
@@ -349,7 +349,7 @@ namespace ts {
|
||||
return output + host.getNewLine();
|
||||
}
|
||||
|
||||
export function flattenDiagnosticMessageText(messageText: string | DiagnosticMessageChain, newLine: string): string {
|
||||
export function flattenDiagnosticMessageText(messageText: string | DiagnosticMessageChain | undefined, newLine: string): string {
|
||||
if (isString(messageText)) {
|
||||
return messageText;
|
||||
}
|
||||
@@ -384,7 +384,7 @@ namespace ts {
|
||||
for (const name of names) {
|
||||
let result: T;
|
||||
if (cache.has(name)) {
|
||||
result = cache.get(name);
|
||||
result = cache.get(name)!;
|
||||
}
|
||||
else {
|
||||
cache.set(name, result = loader(name, containingFile));
|
||||
@@ -407,7 +407,7 @@ namespace ts {
|
||||
program: Program | undefined,
|
||||
rootFileNames: string[],
|
||||
newOptions: CompilerOptions,
|
||||
getSourceVersion: (path: Path) => string,
|
||||
getSourceVersion: (path: Path) => string | undefined,
|
||||
fileExists: (fileName: string) => boolean,
|
||||
hasInvalidatedResolution: HasInvalidatedResolution,
|
||||
hasChangedAutomaticTypeDirectiveNames: boolean,
|
||||
@@ -461,7 +461,7 @@ namespace ts {
|
||||
/**
|
||||
* Determined if source file needs to be re-created even if its text hasn't changed
|
||||
*/
|
||||
function shouldProgramCreateNewSourceFiles(program: Program, newOptions: CompilerOptions) {
|
||||
function shouldProgramCreateNewSourceFiles(program: Program | undefined, newOptions: CompilerOptions) {
|
||||
// If any of these options change, we can't reuse old source file even if version match
|
||||
// The change in options like these could result in change in syntax tree change
|
||||
const oldOptions = program && program.getCompilerOptions();
|
||||
@@ -505,9 +505,9 @@ namespace ts {
|
||||
export function createProgram(createProgramOptions: CreateProgramOptions): Program;
|
||||
export function createProgram(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): Program;
|
||||
export function createProgram(rootNamesOrOptions: ReadonlyArray<string> | CreateProgramOptions, _options?: CompilerOptions, _host?: CompilerHost, _oldProgram?: Program, _configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): Program {
|
||||
const createProgramOptions = isArray(rootNamesOrOptions) ? createCreateProgramOptions(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) : rootNamesOrOptions;
|
||||
const createProgramOptions = isArray(rootNamesOrOptions) ? createCreateProgramOptions(rootNamesOrOptions, _options!, _host, _oldProgram, _configFileParsingDiagnostics) : rootNamesOrOptions; // TODO: GH#18217
|
||||
const { rootNames, options, configFileParsingDiagnostics, projectReferences } = createProgramOptions;
|
||||
let { host, oldProgram } = createProgramOptions;
|
||||
let { oldProgram } = createProgramOptions;
|
||||
|
||||
let program: Program;
|
||||
let files: SourceFile[] = [];
|
||||
@@ -542,7 +542,7 @@ namespace ts {
|
||||
|
||||
performance.mark("beforeProgram");
|
||||
|
||||
host = host || createCompilerHost(options);
|
||||
const host = createProgramOptions.host || createCompilerHost(options);
|
||||
const configParsingHost = parseConfigHostFromCompilerHost(host);
|
||||
|
||||
let skipDefaultLib = options.noLib;
|
||||
@@ -554,14 +554,14 @@ namespace ts {
|
||||
|
||||
// Map storing if there is emit blocking diagnostics for given input
|
||||
const hasEmitBlockingDiagnostics = createMap<boolean>();
|
||||
let _compilerOptionsObjectLiteralSyntax: ObjectLiteralExpression;
|
||||
let _referencesArrayLiteralSyntax: ArrayLiteralExpression;
|
||||
let _compilerOptionsObjectLiteralSyntax: ObjectLiteralExpression | null | undefined;
|
||||
let _referencesArrayLiteralSyntax: ArrayLiteralExpression | null | undefined;
|
||||
|
||||
let moduleResolutionCache: ModuleResolutionCache;
|
||||
let moduleResolutionCache: ModuleResolutionCache | undefined;
|
||||
let resolveModuleNamesWorker: (moduleNames: string[], containingFile: string, reusedNames?: string[]) => ResolvedModuleFull[];
|
||||
const hasInvalidatedResolution = host.hasInvalidatedResolution || returnFalse;
|
||||
if (host.resolveModuleNames) {
|
||||
resolveModuleNamesWorker = (moduleNames, containingFile, reusedNames) => host.resolveModuleNames(Debug.assertEachDefined(moduleNames), containingFile, reusedNames).map(resolved => {
|
||||
resolveModuleNamesWorker = (moduleNames, containingFile, reusedNames) => host.resolveModuleNames!(Debug.assertEachDefined(moduleNames), containingFile, reusedNames).map(resolved => {
|
||||
// An older host may have omitted extension, in which case we should infer it from the file extension of resolvedFileName.
|
||||
if (!resolved || (resolved as ResolvedModuleFull).extension !== undefined) {
|
||||
return resolved as ResolvedModuleFull;
|
||||
@@ -573,17 +573,17 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
moduleResolutionCache = createModuleResolutionCache(currentDirectory, x => host.getCanonicalFileName(x));
|
||||
const loader = (moduleName: string, containingFile: string) => resolveModuleName(moduleName, containingFile, options, host, moduleResolutionCache).resolvedModule;
|
||||
resolveModuleNamesWorker = (moduleNames, containingFile) => loadWithLocalCache(Debug.assertEachDefined(moduleNames), containingFile, loader);
|
||||
const loader = (moduleName: string, containingFile: string) => resolveModuleName(moduleName, containingFile, options, host, moduleResolutionCache).resolvedModule!; // TODO: GH#18217
|
||||
resolveModuleNamesWorker = (moduleNames, containingFile) => loadWithLocalCache<ResolvedModuleFull>(Debug.assertEachDefined(moduleNames), containingFile, loader);
|
||||
}
|
||||
|
||||
let resolveTypeReferenceDirectiveNamesWorker: (typeDirectiveNames: string[], containingFile: string) => ResolvedTypeReferenceDirective[];
|
||||
if (host.resolveTypeReferenceDirectives) {
|
||||
resolveTypeReferenceDirectiveNamesWorker = (typeDirectiveNames, containingFile) => host.resolveTypeReferenceDirectives(Debug.assertEachDefined(typeDirectiveNames), containingFile);
|
||||
resolveTypeReferenceDirectiveNamesWorker = (typeDirectiveNames, containingFile) => host.resolveTypeReferenceDirectives!(Debug.assertEachDefined(typeDirectiveNames), containingFile);
|
||||
}
|
||||
else {
|
||||
const loader = (typesRef: string, containingFile: string) => resolveTypeReferenceDirective(typesRef, containingFile, options, host).resolvedTypeReferenceDirective;
|
||||
resolveTypeReferenceDirectiveNamesWorker = (typeReferenceDirectiveNames, containingFile) => loadWithLocalCache(Debug.assertEachDefined(typeReferenceDirectiveNames), containingFile, loader);
|
||||
const loader = (typesRef: string, containingFile: string) => resolveTypeReferenceDirective(typesRef, containingFile, options, host).resolvedTypeReferenceDirective!; // TODO: GH#18217
|
||||
resolveTypeReferenceDirectiveNamesWorker = (typeReferenceDirectiveNames, containingFile) => loadWithLocalCache<ResolvedTypeReferenceDirective>(Debug.assertEachDefined(typeReferenceDirectiveNames), containingFile, loader);
|
||||
}
|
||||
|
||||
// Map from a stringified PackageId to the source file with that id.
|
||||
@@ -595,7 +595,7 @@ namespace ts {
|
||||
let redirectTargetsSet = createMap<true>();
|
||||
|
||||
const filesByName = createMap<SourceFile | undefined>();
|
||||
let missingFilePaths: ReadonlyArray<Path>;
|
||||
let missingFilePaths: ReadonlyArray<Path> | undefined;
|
||||
// stores 'filename -> file association' ignoring case
|
||||
// used to track cases when two file names differ only in casing
|
||||
const filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? createMap<SourceFile>() : undefined;
|
||||
@@ -606,7 +606,7 @@ namespace ts {
|
||||
if (projectReferences) {
|
||||
for (const ref of projectReferences) {
|
||||
const parsedRef = parseProjectReferenceConfigFile(ref);
|
||||
resolvedProjectReferences.push(parsedRef);
|
||||
resolvedProjectReferences!.push(parsedRef);
|
||||
if (parsedRef) {
|
||||
if (parsedRef.commandLine.options.outFile) {
|
||||
const dtsOutfile = changeExtension(parsedRef.commandLine.options.outFile, ".d.ts");
|
||||
@@ -677,7 +677,7 @@ namespace ts {
|
||||
getSourceFile,
|
||||
getSourceFileByPath,
|
||||
getSourceFiles: () => files,
|
||||
getMissingFilePaths: () => missingFilePaths,
|
||||
getMissingFilePaths: () => missingFilePaths!, // TODO: GH#18217
|
||||
getCompilerOptions: () => options,
|
||||
getSyntacticDiagnostics,
|
||||
getOptionsDiagnostics,
|
||||
@@ -714,7 +714,7 @@ namespace ts {
|
||||
|
||||
return program;
|
||||
|
||||
function getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): ResolvedModuleWithFailedLookupLocations {
|
||||
function getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): ResolvedModuleWithFailedLookupLocations | undefined {
|
||||
return moduleResolutionCache && resolveModuleNameFromCache(moduleName, containingFile, moduleResolutionCache);
|
||||
}
|
||||
|
||||
@@ -731,7 +731,7 @@ namespace ts {
|
||||
}
|
||||
else if (options.composite) {
|
||||
// Project compilations never infer their root from the input source paths
|
||||
commonSourceDirectory = getDirectoryPath(normalizeSlashes(options.configFilePath));
|
||||
commonSourceDirectory = getDirectoryPath(normalizeSlashes(options.configFilePath!)); // TODO: GH#18217
|
||||
checkSourceFilesBelongToPath(emittedFiles, commonSourceDirectory);
|
||||
}
|
||||
else {
|
||||
@@ -755,7 +755,7 @@ namespace ts {
|
||||
classifiableNames = createUnderscoreEscapedMap<true>();
|
||||
|
||||
for (const sourceFile of files) {
|
||||
copyEntries(sourceFile.classifiableNames, classifiableNames);
|
||||
copyEntries(sourceFile.classifiableNames!, classifiableNames);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -766,7 +766,7 @@ namespace ts {
|
||||
program: Program | undefined;
|
||||
oldSourceFile: SourceFile | undefined;
|
||||
/** The collection of paths modified *since* the old program. */
|
||||
modifiedFilePaths: Path[];
|
||||
modifiedFilePaths: Path[] | undefined;
|
||||
}
|
||||
|
||||
function resolveModuleNamesReusingOldState(moduleNames: string[], containingFile: string, file: SourceFile, oldProgramState: OldProgramState) {
|
||||
@@ -788,7 +788,7 @@ namespace ts {
|
||||
// it is safe to reuse resolutions from the earlier call.
|
||||
const result: ResolvedModuleFull[] = [];
|
||||
for (const moduleName of moduleNames) {
|
||||
const resolvedModule = file.resolvedModules.get(moduleName);
|
||||
const resolvedModule = file.resolvedModules.get(moduleName)!;
|
||||
result.push(resolvedModule);
|
||||
}
|
||||
return result;
|
||||
@@ -799,7 +799,7 @@ namespace ts {
|
||||
// With this information, we can infer some module resolutions without performing resolution.
|
||||
|
||||
/** An ordered list of module names for which we cannot recover the resolution. */
|
||||
let unknownModuleNames: string[];
|
||||
let unknownModuleNames: string[] | undefined;
|
||||
/**
|
||||
* The indexing of elements in this list matches that of `moduleNames`.
|
||||
*
|
||||
@@ -809,8 +809,8 @@ namespace ts {
|
||||
* Needs to be reset to undefined before returning,
|
||||
* * ResolvedModuleFull instance: can be reused.
|
||||
*/
|
||||
let result: ResolvedModuleFull[];
|
||||
let reusedNames: string[];
|
||||
let result: ResolvedModuleFull[] | undefined;
|
||||
let reusedNames: string[] | undefined;
|
||||
/** A transient placeholder used to mark predicted resolution in the result list. */
|
||||
const predictedToResolveToAmbientModuleMarker: ResolvedModuleFull = <any>{};
|
||||
|
||||
@@ -818,7 +818,7 @@ namespace ts {
|
||||
const moduleName = moduleNames[i];
|
||||
// If the source file is unchanged and doesnt have invalidated resolution, reuse the module resolutions
|
||||
if (file === oldSourceFile && !hasInvalidatedResolution(oldSourceFile.path)) {
|
||||
const oldResolvedModule = oldSourceFile && oldSourceFile.resolvedModules.get(moduleName);
|
||||
const oldResolvedModule = oldSourceFile && oldSourceFile.resolvedModules!.get(moduleName);
|
||||
if (oldResolvedModule) {
|
||||
if (isTraceEnabled(options, host)) {
|
||||
trace(host, Diagnostics.Reusing_resolution_of_module_0_to_file_1_from_old_program, moduleName, containingFile);
|
||||
@@ -869,7 +869,7 @@ namespace ts {
|
||||
// `result[i]` is either a `ResolvedModuleFull` or a marker.
|
||||
// If it is the former, we can leave it as is.
|
||||
if (result[i] === predictedToResolveToAmbientModuleMarker) {
|
||||
result[i] = undefined;
|
||||
result[i] = undefined!; // TODO: GH#18217
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -884,7 +884,7 @@ namespace ts {
|
||||
// If we change our policy of rechecking failed lookups on each program create,
|
||||
// we should adjust the value returned here.
|
||||
function moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName: string, oldProgramState: OldProgramState): boolean {
|
||||
const resolutionToFile = getResolvedModule(oldProgramState.oldSourceFile, moduleName);
|
||||
const resolutionToFile = getResolvedModule(oldProgramState.oldSourceFile!, moduleName); // TODO: GH#18217
|
||||
const resolvedFile = resolutionToFile && oldProgramState.program && oldProgramState.program.getSourceFile(resolutionToFile.resolvedFileName);
|
||||
if (resolutionToFile && resolvedFile && !resolvedFile.externalModuleIndicator) {
|
||||
// In the old program, we resolved to an ambient module that was in the same
|
||||
@@ -927,7 +927,7 @@ namespace ts {
|
||||
return oldProgram.structureIsReused = StructureIsReused.Not;
|
||||
}
|
||||
|
||||
Debug.assert(!(oldProgram.structureIsReused & (StructureIsReused.Completely | StructureIsReused.SafeModules)));
|
||||
Debug.assert(!(oldProgram.structureIsReused! & (StructureIsReused.Completely | StructureIsReused.SafeModules)));
|
||||
|
||||
// there is an old program, check if we can reuse its structure
|
||||
const oldRootNames = oldProgram.getRootFileNames();
|
||||
@@ -987,8 +987,8 @@ namespace ts {
|
||||
|
||||
for (const oldSourceFile of oldSourceFiles) {
|
||||
let newSourceFile = host.getSourceFileByPath
|
||||
? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.path, options.target, /*onError*/ undefined, shouldCreateNewSourceFile)
|
||||
: host.getSourceFile(oldSourceFile.fileName, options.target, /*onError*/ undefined, shouldCreateNewSourceFile);
|
||||
? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.path, options.target!, /*onError*/ undefined, shouldCreateNewSourceFile)
|
||||
: host.getSourceFile(oldSourceFile.fileName, options.target!, /*onError*/ undefined, shouldCreateNewSourceFile); // TODO: GH#18217
|
||||
|
||||
if (!newSourceFile) {
|
||||
return oldProgram.structureIsReused = StructureIsReused.Not;
|
||||
@@ -1134,7 +1134,7 @@ namespace ts {
|
||||
for (let i = 0; i < newSourceFiles.length; i++) {
|
||||
filesByName.set(filePaths[i], newSourceFiles[i]);
|
||||
// Set the file as found during node modules search if it was found that way in old progra,
|
||||
if (oldProgram.isSourceFileFromExternalLibrary(oldProgram.getSourceFileByPath(filePaths[i]))) {
|
||||
if (oldProgram.isSourceFileFromExternalLibrary(oldProgram.getSourceFileByPath(filePaths[i])!)) {
|
||||
sourceFilesFoundSearchingNodeModules.set(filePaths[i], true);
|
||||
}
|
||||
}
|
||||
@@ -1185,7 +1185,7 @@ namespace ts {
|
||||
const nodes: InputFiles[] = [];
|
||||
for (let i = 0; i < projectReferences.length; i++) {
|
||||
const ref = projectReferences[i];
|
||||
const resolvedRefOpts = resolvedProjectReferences[i].commandLine;
|
||||
const resolvedRefOpts = resolvedProjectReferences![i]!.commandLine;
|
||||
if (ref.prepend && resolvedRefOpts && resolvedRefOpts.options) {
|
||||
// Upstream project didn't have outFile set -- skip (error will have been issued earlier)
|
||||
if (!resolvedRefOpts.options.outFile) continue;
|
||||
@@ -1201,7 +1201,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isSourceFileFromExternalLibrary(file: SourceFile): boolean {
|
||||
return sourceFilesFoundSearchingNodeModules.get(file.path);
|
||||
return !!sourceFilesFoundSearchingNodeModules.get(file.path);
|
||||
}
|
||||
|
||||
function isSourceFileDefaultLibrary(file: SourceFile): boolean {
|
||||
@@ -1220,7 +1220,7 @@ namespace ts {
|
||||
return equalityComparer(file.fileName, getDefaultLibraryFileName());
|
||||
}
|
||||
else {
|
||||
return forEach(options.lib, libFileName => equalityComparer(file.fileName, combinePaths(defaultLibraryPath, libFileName)));
|
||||
return some(options.lib, libFileName => equalityComparer(file.fileName, combinePaths(defaultLibraryPath, libFileName)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1229,7 +1229,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function dropDiagnosticsProducingTypeChecker() {
|
||||
diagnosticsProducingTypeChecker = undefined;
|
||||
diagnosticsProducingTypeChecker = undefined!;
|
||||
}
|
||||
|
||||
function getTypeChecker() {
|
||||
@@ -1244,7 +1244,7 @@ namespace ts {
|
||||
return hasEmitBlockingDiagnostics.has(toPath(emitFileName));
|
||||
}
|
||||
|
||||
function emitWorker(program: Program, sourceFile: SourceFile, writeFileCallback: WriteFileCallback, cancellationToken: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult {
|
||||
function emitWorker(program: Program, sourceFile: SourceFile | undefined, writeFileCallback: WriteFileCallback | undefined, cancellationToken: CancellationToken | undefined, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult {
|
||||
let declarationDiagnostics: ReadonlyArray<Diagnostic> = [];
|
||||
|
||||
if (!emitOnlyDtsFiles) {
|
||||
@@ -1294,7 +1294,7 @@ namespace ts {
|
||||
const emitResult = emitFiles(
|
||||
emitResolver,
|
||||
getEmitHost(writeFileCallback),
|
||||
sourceFile,
|
||||
sourceFile!, // TODO: GH#18217
|
||||
emitOnlyDtsFiles,
|
||||
transformers,
|
||||
customTransformers && customTransformers.afterDeclarations
|
||||
@@ -1374,8 +1374,8 @@ namespace ts {
|
||||
// cancel when the user has made a change anyways. And, in that case, we (the
|
||||
// program instance) will get thrown away anyways. So trying to keep one of
|
||||
// these type checkers alive doesn't serve much purpose.
|
||||
noDiagnosticsTypeChecker = undefined;
|
||||
diagnosticsProducingTypeChecker = undefined;
|
||||
noDiagnosticsTypeChecker = undefined!;
|
||||
diagnosticsProducingTypeChecker = undefined!;
|
||||
}
|
||||
|
||||
throw e;
|
||||
@@ -1386,7 +1386,7 @@ namespace ts {
|
||||
return getAndCacheDiagnostics(sourceFile, cancellationToken, cachedSemanticDiagnosticsForFile, getSemanticDiagnosticsForFileNoCache);
|
||||
}
|
||||
|
||||
function getSemanticDiagnosticsForFileNoCache(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
function getSemanticDiagnosticsForFileNoCache(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] | undefined {
|
||||
return runWithCancellationToken(() => {
|
||||
// If skipLibCheck is enabled, skip reporting errors if file is a declaration file.
|
||||
// If skipDefaultLibCheck is enabled, skip reporting errors if file contains a
|
||||
@@ -1429,7 +1429,7 @@ namespace ts {
|
||||
const { file, start } = diagnostic;
|
||||
if (file) {
|
||||
const lineStarts = getLineStarts(file);
|
||||
let { line } = computeLineAndCharacterOfPosition(lineStarts, start);
|
||||
let { line } = computeLineAndCharacterOfPosition(lineStarts, start!); // TODO: GH#18217
|
||||
while (line > 0) {
|
||||
const previousLineText = file.text.slice(lineStarts[line - 1], lineStarts[line]);
|
||||
const result = ignoreDiagnosticCommentRegEx.exec(previousLineText);
|
||||
@@ -1646,7 +1646,7 @@ namespace ts {
|
||||
sourceFile: SourceFile | undefined,
|
||||
cancellationToken: CancellationToken,
|
||||
cache: DiagnosticCache<T>,
|
||||
getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationToken) => T[],
|
||||
getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationToken) => T[] | undefined,
|
||||
): ReadonlyArray<T> {
|
||||
|
||||
const cachedResult = sourceFile
|
||||
@@ -1656,7 +1656,7 @@ namespace ts {
|
||||
if (cachedResult) {
|
||||
return cachedResult;
|
||||
}
|
||||
const result = getDiagnostics(sourceFile, cancellationToken) || emptyArray;
|
||||
const result = getDiagnostics(sourceFile!, cancellationToken) || emptyArray; // TODO: GH#18217
|
||||
if (sourceFile) {
|
||||
if (!cache.perFile) {
|
||||
cache.perFile = createMap<T[]>();
|
||||
@@ -1715,8 +1715,8 @@ namespace ts {
|
||||
|
||||
// file.imports may not be undefined if there exists dynamic import
|
||||
let imports: StringLiteralLike[] | undefined;
|
||||
let moduleAugmentations: (StringLiteral | Identifier)[];
|
||||
let ambientModules: string[];
|
||||
let moduleAugmentations: (StringLiteral | Identifier)[] | undefined;
|
||||
let ambientModules: string[] | undefined;
|
||||
|
||||
// If we are importing helpers, we need to add a synthetic reference to resolve the
|
||||
// helpers library.
|
||||
@@ -1867,7 +1867,7 @@ namespace ts {
|
||||
/** This has side effects through `findSourceFile`. */
|
||||
function processSourceFile(fileName: string, isDefaultLib: boolean, packageId: PackageId | undefined, refFile?: SourceFile, refPos?: number, refEnd?: number): void {
|
||||
getSourceFileFromReferenceWorker(fileName,
|
||||
fileName => findSourceFile(fileName, toPath(fileName), isDefaultLib, refFile, refPos, refEnd, packageId),
|
||||
fileName => findSourceFile(fileName, toPath(fileName), isDefaultLib, refFile!, refPos!, refEnd!, packageId), // TODO: GH#18217
|
||||
(diagnostic, ...args) => {
|
||||
fileProcessingDiagnostics.add(refFile !== undefined && refEnd !== undefined && refPos !== undefined
|
||||
? createFileDiagnostic(refFile, refPos, refEnd - refPos, diagnostic, ...args)
|
||||
@@ -1893,12 +1893,12 @@ namespace ts {
|
||||
redirect.redirectInfo = { redirectTarget, unredirected };
|
||||
Object.defineProperties(redirect, {
|
||||
id: {
|
||||
get(this: SourceFile) { return this.redirectInfo.redirectTarget.id; },
|
||||
set(this: SourceFile, value: SourceFile["id"]) { this.redirectInfo.redirectTarget.id = value; },
|
||||
get(this: SourceFile) { return this.redirectInfo!.redirectTarget.id; },
|
||||
set(this: SourceFile, value: SourceFile["id"]) { this.redirectInfo!.redirectTarget.id = value; },
|
||||
},
|
||||
symbol: {
|
||||
get(this: SourceFile) { return this.redirectInfo.redirectTarget.symbol; },
|
||||
set(this: SourceFile, value: SourceFile["symbol"]) { this.redirectInfo.redirectTarget.symbol = value; },
|
||||
get(this: SourceFile) { return this.redirectInfo!.redirectTarget.symbol; },
|
||||
set(this: SourceFile, value: SourceFile["symbol"]) { this.redirectInfo!.redirectTarget.symbol = value; },
|
||||
},
|
||||
});
|
||||
return redirect;
|
||||
@@ -1953,7 +1953,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// We haven't looked for this file, do so now and cache result
|
||||
const file = host.getSourceFile(fileName, options.target, hostErrorMessage => {
|
||||
const file = host.getSourceFile(fileName, options.target!, hostErrorMessage => { // TODO: GH#18217
|
||||
if (refFile !== undefined && refPos !== undefined && refEnd !== undefined) {
|
||||
fileProcessingDiagnostics.add(createFileDiagnostic(refFile, refPos, refEnd - refPos,
|
||||
Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage));
|
||||
@@ -1969,7 +1969,7 @@ namespace ts {
|
||||
if (fileFromPackageId) {
|
||||
// Some other SourceFile already exists with this package name and version.
|
||||
// Instead of creating a duplicate, just redirect to the existing one.
|
||||
const dupFile = createRedirectSourceFile(fileFromPackageId, file, fileName, path);
|
||||
const dupFile = createRedirectSourceFile(fileFromPackageId, file!, fileName, path); // TODO: GH#18217
|
||||
redirectTargetsSet.set(fileFromPackageId.path, true);
|
||||
filesByName.set(path, dupFile);
|
||||
sourceFileToPackageName.set(path, packageId.name);
|
||||
@@ -1995,12 +1995,12 @@ namespace ts {
|
||||
if (host.useCaseSensitiveFileNames()) {
|
||||
const pathLowerCase = path.toLowerCase();
|
||||
// for case-sensitive file systems check if we've already seen some file with similar filename ignoring case
|
||||
const existingFile = filesByNameIgnoreCase.get(pathLowerCase);
|
||||
const existingFile = filesByNameIgnoreCase!.get(pathLowerCase);
|
||||
if (existingFile) {
|
||||
reportFileNamesDifferOnlyInCasingError(fileName, existingFile.fileName, refFile, refPos, refEnd);
|
||||
}
|
||||
else {
|
||||
filesByNameIgnoreCase.set(pathLowerCase, file);
|
||||
filesByNameIgnoreCase!.set(pathLowerCase, file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2080,7 +2080,7 @@ namespace ts {
|
||||
if (resolvedTypeReferenceDirective) {
|
||||
if (resolvedTypeReferenceDirective.primary) {
|
||||
// resolved from the primary path
|
||||
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, refFile, refPos, refEnd);
|
||||
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName!, /*isDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, refFile, refPos, refEnd); // TODO: GH#18217
|
||||
}
|
||||
else {
|
||||
// If we already resolved to this file, it must have been a secondary reference. Check file contents
|
||||
@@ -2088,9 +2088,9 @@ namespace ts {
|
||||
if (previousResolution) {
|
||||
// Don't bother reading the file again if it's the same file.
|
||||
if (resolvedTypeReferenceDirective.resolvedFileName !== previousResolution.resolvedFileName) {
|
||||
const otherFileText = host.readFile(resolvedTypeReferenceDirective.resolvedFileName);
|
||||
if (otherFileText !== getSourceFile(previousResolution.resolvedFileName).text) {
|
||||
fileProcessingDiagnostics.add(createDiagnostic(refFile, refPos, refEnd,
|
||||
const otherFileText = host.readFile(resolvedTypeReferenceDirective.resolvedFileName!);
|
||||
if (otherFileText !== getSourceFile(previousResolution.resolvedFileName!)!.text) {
|
||||
fileProcessingDiagnostics.add(createDiagnostic(refFile!, refPos!, refEnd!, // TODO: GH#18217
|
||||
Diagnostics.Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_library_to_resolve_the_conflict,
|
||||
typeReferenceDirective,
|
||||
resolvedTypeReferenceDirective.resolvedFileName,
|
||||
@@ -2103,12 +2103,12 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
// First resolution of this library
|
||||
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, refFile, refPos, refEnd);
|
||||
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName!, /*isDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, refFile, refPos, refEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
fileProcessingDiagnostics.add(createDiagnostic(refFile, refPos, refEnd, Diagnostics.Cannot_find_type_definition_file_for_0, typeReferenceDirective));
|
||||
fileProcessingDiagnostics.add(createDiagnostic(refFile!, refPos!, refEnd!, Diagnostics.Cannot_find_type_definition_file_for_0, typeReferenceDirective)); // TODO: GH#18217
|
||||
}
|
||||
|
||||
if (saveResolution) {
|
||||
@@ -2221,7 +2221,7 @@ namespace ts {
|
||||
|
||||
function parseProjectReferenceConfigFile(ref: ProjectReference): { commandLine: ParsedCommandLine, sourceFile: SourceFile } | undefined {
|
||||
// The actual filename (i.e. add "/tsconfig.json" if necessary)
|
||||
const refPath = resolveProjectReferencePath(host, ref);
|
||||
const refPath = resolveProjectReferencePath(host, ref)!; // TODO: GH#18217
|
||||
// An absolute path pointing to the containing directory of the config file
|
||||
const basePath = getNormalizedAbsolutePath(getDirectoryPath(refPath), host.getCurrentDirectory());
|
||||
const sourceFile = host.getSourceFile(refPath, ScriptTarget.JSON) as JsonSourceFile;
|
||||
@@ -2234,14 +2234,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
function addProjectReferenceRedirects(referencedProject: ParsedCommandLine, target: Map<string>) {
|
||||
const rootDir = normalizePath(referencedProject.options.rootDir || getDirectoryPath(referencedProject.options.configFilePath));
|
||||
const rootDir = normalizePath(referencedProject.options.rootDir || getDirectoryPath(referencedProject.options.configFilePath!)); // TODO: GH#18217
|
||||
target.set(rootDir, getDeclarationOutputDirectory(referencedProject));
|
||||
}
|
||||
|
||||
function getDeclarationOutputDirectory(proj: ParsedCommandLine) {
|
||||
return proj.options.declarationDir ||
|
||||
proj.options.outDir ||
|
||||
getDirectoryPath(proj.options.configFilePath);
|
||||
getDirectoryPath(proj.options.configFilePath!); // TODO: GH#18217
|
||||
}
|
||||
|
||||
function verifyCompilerOptions() {
|
||||
@@ -2289,7 +2289,7 @@ namespace ts {
|
||||
if (projectReferences) {
|
||||
for (let i = 0; i < projectReferences.length; i++) {
|
||||
const ref = projectReferences[i];
|
||||
const resolvedRefOpts = resolvedProjectReferences[i] && resolvedProjectReferences[i].commandLine.options;
|
||||
const resolvedRefOpts = resolvedProjectReferences![i] && resolvedProjectReferences![i]!.commandLine.options;
|
||||
if (resolvedRefOpts === undefined) {
|
||||
createDiagnosticForReference(i, Diagnostics.File_0_does_not_exist, ref.path);
|
||||
continue;
|
||||
@@ -2409,7 +2409,7 @@ namespace ts {
|
||||
}
|
||||
else if (firstNonAmbientExternalModuleSourceFile && languageVersion < ScriptTarget.ES2015 && options.module === ModuleKind.None) {
|
||||
// We cannot use createDiagnosticFromNode because nodes do not have parents yet
|
||||
const span = getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, firstNonAmbientExternalModuleSourceFile.externalModuleIndicator);
|
||||
const span = getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, firstNonAmbientExternalModuleSourceFile.externalModuleIndicator!);
|
||||
programDiagnostics.add(createFileDiagnostic(firstNonAmbientExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_use_imports_exports_or_module_augmentations_when_module_is_none));
|
||||
}
|
||||
|
||||
@@ -2419,7 +2419,7 @@ namespace ts {
|
||||
createDiagnosticForOptionName(Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile", "module");
|
||||
}
|
||||
else if (options.module === undefined && firstNonAmbientExternalModuleSourceFile) {
|
||||
const span = getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, firstNonAmbientExternalModuleSourceFile.externalModuleIndicator);
|
||||
const span = getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, firstNonAmbientExternalModuleSourceFile.externalModuleIndicator!);
|
||||
programDiagnostics.add(createFileDiagnostic(firstNonAmbientExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system, options.out ? "out" : "outFile"));
|
||||
}
|
||||
}
|
||||
@@ -2493,12 +2493,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Verify that all the emit files are unique and don't overwrite input files
|
||||
function verifyEmitFilePath(emitFileName: string, emitFilesSeen: Map<true>) {
|
||||
function verifyEmitFilePath(emitFileName: string | undefined, emitFilesSeen: Map<true>) {
|
||||
if (emitFileName) {
|
||||
const emitFilePath = toPath(emitFileName);
|
||||
// Report error if the output overwrites input file
|
||||
if (filesByName.has(emitFilePath)) {
|
||||
let chain: DiagnosticMessageChain;
|
||||
let chain: DiagnosticMessageChain | undefined;
|
||||
if (!options.configFilePath) {
|
||||
// The program is from either an inferred project or an external project
|
||||
chain = chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript_files_Learn_more_at_https_Colon_Slash_Slashaka_ms_Slashtsconfig);
|
||||
@@ -2526,9 +2526,9 @@ namespace ts {
|
||||
for (const pathProp of pathsSyntax) {
|
||||
if (isObjectLiteralExpression(pathProp.initializer)) {
|
||||
for (const keyProps of getPropertyAssignment(pathProp.initializer, key)) {
|
||||
if (isArrayLiteralExpression(keyProps.initializer) &&
|
||||
keyProps.initializer.elements.length > valueIndex) {
|
||||
programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile, keyProps.initializer.elements[valueIndex], message, arg0, arg1, arg2));
|
||||
const initializer = keyProps.initializer;
|
||||
if (isArrayLiteralExpression(initializer) && initializer.elements.length > valueIndex) {
|
||||
programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile!, initializer.elements[valueIndex], message, arg0, arg1, arg2));
|
||||
needCompilerDiagnostic = false;
|
||||
}
|
||||
}
|
||||
@@ -2586,7 +2586,7 @@ namespace ts {
|
||||
programDiagnostics.add(createCompilerDiagnostic(message, arg0, arg1));
|
||||
}
|
||||
|
||||
function createDiagnosticForOption(onKey: boolean, option1: string, option2: string, message: DiagnosticMessage, arg0: string | number, arg1?: string | number, arg2?: string | number) {
|
||||
function createDiagnosticForOption(onKey: boolean, option1: string, option2: string | undefined, message: DiagnosticMessage, arg0: string | number, arg1?: string | number, arg2?: string | number) {
|
||||
const compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax();
|
||||
const needCompilerDiagnostic = !compilerOptionsObjectLiteralSyntax ||
|
||||
!createOptionDiagnosticInObjectLiteralSyntax(compilerOptionsObjectLiteralSyntax, onKey, option1, option2, message, arg0, arg1, arg2);
|
||||
@@ -2600,7 +2600,7 @@ namespace ts {
|
||||
if (_referencesArrayLiteralSyntax === undefined) {
|
||||
_referencesArrayLiteralSyntax = null; // tslint:disable-line:no-null-keyword
|
||||
if (options.configFile) {
|
||||
const jsonObjectLiteral = getTsConfigObjectLiteralExpression(options.configFile);
|
||||
const jsonObjectLiteral = getTsConfigObjectLiteralExpression(options.configFile)!; // TODO: GH#18217
|
||||
for (const prop of getPropertyAssignment(jsonObjectLiteral, "references")) {
|
||||
if (isArrayLiteralExpression(prop.initializer)) {
|
||||
_referencesArrayLiteralSyntax = prop.initializer;
|
||||
@@ -2628,20 +2628,21 @@ namespace ts {
|
||||
return _compilerOptionsObjectLiteralSyntax;
|
||||
}
|
||||
|
||||
function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string, message: DiagnosticMessage, arg0: string | number, arg1?: string | number, arg2?: string | number): boolean {
|
||||
function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, message: DiagnosticMessage, arg0: string | number, arg1?: string | number, arg2?: string | number): boolean {
|
||||
const props = getPropertyAssignment(objectLiteral, key1, key2);
|
||||
for (const prop of props) {
|
||||
programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile, onKey ? prop.name : prop.initializer, message, arg0, arg1, arg2));
|
||||
programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile!, onKey ? prop.name : prop.initializer, message, arg0, arg1, arg2));
|
||||
}
|
||||
return !!props.length;
|
||||
}
|
||||
|
||||
function createOptionDiagnosticInArrayLiteralSyntax(arrayLiteral: ArrayLiteralExpression, index: number, message: DiagnosticMessage, arg0: string | number, arg1?: string | number, arg2?: string | number): boolean {
|
||||
function createOptionDiagnosticInArrayLiteralSyntax(arrayLiteral: ArrayLiteralExpression, index: number, message: DiagnosticMessage, arg0: string | number | undefined, arg1?: string | number, arg2?: string | number): boolean {
|
||||
if (arrayLiteral.elements.length <= index) {
|
||||
// Out-of-bounds
|
||||
return false;
|
||||
}
|
||||
programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile, arrayLiteral.elements[index], message, arg0, arg1, arg2));
|
||||
programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile!, arrayLiteral.elements[index], message, arg0, arg1, arg2));
|
||||
return false; // TODO: GH#18217 This function always returns `false`!`
|
||||
}
|
||||
|
||||
function blockEmittingOfFile(emitFileName: string, diag: Diagnostic) {
|
||||
@@ -2649,7 +2650,7 @@ namespace ts {
|
||||
programDiagnostics.add(diag);
|
||||
}
|
||||
|
||||
function isEmittedFile(file: string) {
|
||||
function isEmittedFile(file: string): boolean {
|
||||
if (options.noEmit) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -3,10 +3,10 @@ namespace ts {
|
||||
/** This is the cache of module/typedirectives resolution that can be retained across program */
|
||||
export interface ResolutionCache {
|
||||
startRecordingFilesWithChangedResolutions(): void;
|
||||
finishRecordingFilesWithChangedResolutions(): Path[];
|
||||
finishRecordingFilesWithChangedResolutions(): Path[] | undefined;
|
||||
|
||||
resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined): ResolvedModuleFull[];
|
||||
getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): ResolvedModuleWithFailedLookupLocations;
|
||||
getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): ResolvedModuleWithFailedLookupLocations | undefined;
|
||||
resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
|
||||
invalidateResolutionOfFile(filePath: Path): void;
|
||||
@@ -76,13 +76,13 @@ namespace ts {
|
||||
type GetResolutionWithResolvedFileName<T extends ResolutionWithFailedLookupLocations = ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName = ResolutionWithResolvedFileName> =
|
||||
(resolution: T) => R | undefined;
|
||||
|
||||
export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootDirForResolution: string, logChangesWhenResolvingModule: boolean): ResolutionCache {
|
||||
export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootDirForResolution: string | undefined, logChangesWhenResolvingModule: boolean): ResolutionCache {
|
||||
let filesWithChangedSetOfUnresolvedImports: Path[] | undefined;
|
||||
let filesWithInvalidatedResolutions: Map<true> | undefined;
|
||||
let filesWithInvalidatedNonRelativeUnresolvedImports: Map<ReadonlyArray<string>> | undefined;
|
||||
let allFilesHaveInvalidatedResolution = false;
|
||||
|
||||
const getCurrentDirectory = memoize(() => resolutionHost.getCurrentDirectory());
|
||||
const getCurrentDirectory = memoize(() => resolutionHost.getCurrentDirectory!()); // TODO: GH#18217
|
||||
const cachedDirectoryStructureHost = resolutionHost.getCachedDirectoryStructureHost();
|
||||
|
||||
// The resolvedModuleNames and resolvedTypeReferenceDirectives are the cache of resolutions per file.
|
||||
@@ -112,7 +112,7 @@ namespace ts {
|
||||
|
||||
const directoryWatchesOfFailedLookups = createMap<DirectoryWatchesOfFailedLookup>();
|
||||
const rootDir = rootDirForResolution && removeTrailingDirectorySeparator(getNormalizedAbsolutePath(rootDirForResolution, getCurrentDirectory()));
|
||||
const rootPath = rootDir && resolutionHost.toPath(rootDir);
|
||||
const rootPath = (rootDir && resolutionHost.toPath(rootDir)) as Path; // TODO: GH#18217
|
||||
|
||||
// TypeRoot watches for the types that get added as part of getAutomaticTypeDirectiveNames
|
||||
const typeRootsWatches = createMap<FileWatcher>();
|
||||
@@ -144,7 +144,7 @@ namespace ts {
|
||||
return resolution.resolvedTypeReferenceDirective;
|
||||
}
|
||||
|
||||
function isInDirectoryPath(dir: Path, file: Path) {
|
||||
function isInDirectoryPath(dir: Path | undefined, file: Path) {
|
||||
if (dir === undefined || file.length <= dir.length) {
|
||||
return false;
|
||||
}
|
||||
@@ -173,14 +173,14 @@ namespace ts {
|
||||
return collected;
|
||||
}
|
||||
|
||||
function isFileWithInvalidatedNonRelativeUnresolvedImports(path: Path) {
|
||||
function isFileWithInvalidatedNonRelativeUnresolvedImports(path: Path): boolean {
|
||||
if (!filesWithInvalidatedNonRelativeUnresolvedImports) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Invalidated if file has unresolved imports
|
||||
const value = filesWithInvalidatedNonRelativeUnresolvedImports.get(path);
|
||||
return value && !!value.length;
|
||||
return !!value && !!value.length;
|
||||
}
|
||||
|
||||
function createHasInvalidatedResolution(forceAllFilesAsInvalidated?: boolean): HasInvalidatedResolution {
|
||||
@@ -191,7 +191,7 @@ namespace ts {
|
||||
}
|
||||
const collected = filesWithInvalidatedResolutions;
|
||||
filesWithInvalidatedResolutions = undefined;
|
||||
return path => (collected && collected.has(path)) ||
|
||||
return path => (!!collected && collected.has(path)) ||
|
||||
isFileWithInvalidatedNonRelativeUnresolvedImports(path);
|
||||
}
|
||||
|
||||
@@ -247,7 +247,7 @@ namespace ts {
|
||||
logChanges: boolean): R[] {
|
||||
|
||||
const path = resolutionHost.toPath(containingFile);
|
||||
const resolutionsInFile = cache.get(path) || cache.set(path, createMap()).get(path);
|
||||
const resolutionsInFile = cache.get(path) || cache.set(path, createMap()).get(path)!;
|
||||
const dirPath = getDirectoryPath(path);
|
||||
let perDirectoryResolution = perDirectoryCache.get(dirPath);
|
||||
if (!perDirectoryResolution) {
|
||||
@@ -289,7 +289,7 @@ namespace ts {
|
||||
}
|
||||
Debug.assert(resolution !== undefined && !resolution.isInvalidated);
|
||||
seenNamesInFile.set(name, true);
|
||||
resolvedModules.push(getResolutionWithResolvedFileName(resolution));
|
||||
resolvedModules.push(getResolutionWithResolvedFileName(resolution)!); // TODO: GH#18217
|
||||
}
|
||||
|
||||
// Stop watching and remove the unused name
|
||||
@@ -302,7 +302,7 @@ namespace ts {
|
||||
|
||||
return resolvedModules;
|
||||
|
||||
function resolutionIsEqualTo(oldResolution: T, newResolution: T): boolean {
|
||||
function resolutionIsEqualTo(oldResolution: T | undefined, newResolution: T | undefined): boolean {
|
||||
if (oldResolution === newResolution) {
|
||||
return true;
|
||||
}
|
||||
@@ -381,7 +381,7 @@ namespace ts {
|
||||
|
||||
function getDirectoryToWatchFailedLookupLocation(failedLookupLocation: string, failedLookupLocationPath: Path): DirectoryOfFailedLookupWatch {
|
||||
if (isInDirectoryPath(rootPath, failedLookupLocationPath)) {
|
||||
return { dir: rootDir, dirPath: rootPath };
|
||||
return { dir: rootDir!, dirPath: rootPath }; // TODO: GH#18217
|
||||
}
|
||||
|
||||
return getDirectoryToWatchFromFailedLookupLocationDirectory(
|
||||
@@ -457,7 +457,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (setAtRoot) {
|
||||
setDirectoryWatcher(rootDir, rootPath);
|
||||
setDirectoryWatcher(rootDir!, rootPath); // TODO: GH#18217
|
||||
}
|
||||
}
|
||||
|
||||
@@ -519,14 +519,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
function removeDirectoryWatcher(dirPath: string, subDirectory?: Path) {
|
||||
const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
|
||||
const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath)!;
|
||||
if (subDirectory) {
|
||||
const existing = dirWatcher.subDirectoryMap.get(subDirectory);
|
||||
const existing = dirWatcher.subDirectoryMap!.get(subDirectory)!;
|
||||
if (existing === 1) {
|
||||
dirWatcher.subDirectoryMap.delete(subDirectory);
|
||||
dirWatcher.subDirectoryMap!.delete(subDirectory);
|
||||
}
|
||||
else {
|
||||
dirWatcher.subDirectoryMap.set(subDirectory, existing - 1);
|
||||
dirWatcher.subDirectoryMap!.set(subDirectory, existing - 1);
|
||||
}
|
||||
}
|
||||
// Do not close the watcher yet since it might be needed by other failed lookup locations.
|
||||
@@ -589,10 +589,10 @@ namespace ts {
|
||||
seen.set(dirPath, seenInDir);
|
||||
}
|
||||
resolutions.forEach((resolution, name) => {
|
||||
if (seenInDir.has(name)) {
|
||||
if (seenInDir!.has(name)) {
|
||||
return;
|
||||
}
|
||||
seenInDir.set(name, true);
|
||||
seenInDir!.set(name, true);
|
||||
if (!resolution.isInvalidated && isInvalidatedResolution(resolution, getResolutionWithResolvedFileName)) {
|
||||
// Mark the file as needing re-evaluation of module resolution instead of using it blindly.
|
||||
resolution.isInvalidated = true;
|
||||
@@ -626,7 +626,7 @@ namespace ts {
|
||||
// Resolution is invalidated if the resulting file name is same as the deleted file path
|
||||
(resolution, getResolutionWithResolvedFileName) => {
|
||||
const result = getResolutionWithResolvedFileName(resolution);
|
||||
return result && resolutionHost.toPath(result.resolvedFileName) === filePath;
|
||||
return !!result && resolutionHost.toPath(result.resolvedFileName!) === filePath; // TODO: GH#18217
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -689,7 +689,7 @@ namespace ts {
|
||||
return rootPath;
|
||||
}
|
||||
const { dirPath, ignore } = getDirectoryToWatchFromFailedLookupLocationDirectory(typeRoot, typeRootPath);
|
||||
return !ignore && directoryWatchesOfFailedLookups.has(dirPath) && dirPath;
|
||||
return !ignore && directoryWatchesOfFailedLookups.has(dirPath) ? dirPath : undefined;
|
||||
}
|
||||
|
||||
function createTypeRootsWatch(typeRootPath: Path, typeRoot: string): FileWatcher {
|
||||
|
||||
+27
-24
@@ -37,8 +37,8 @@ namespace ts {
|
||||
getText(): string;
|
||||
// Sets the text for the scanner to scan. An optional subrange starting point and length
|
||||
// can be provided to have the scanner only scan a portion of the text.
|
||||
setText(text: string, start?: number, length?: number): void;
|
||||
setOnError(onError: ErrorCallback): void;
|
||||
setText(text: string | undefined, start?: number, length?: number): void;
|
||||
setOnError(onError: ErrorCallback | undefined): void;
|
||||
setScriptTarget(scriptTarget: ScriptTarget): void;
|
||||
setLanguageVariant(variant: LanguageVariant): void;
|
||||
setTextPos(textPos: number): void;
|
||||
@@ -266,14 +266,14 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* @internal */ export function isUnicodeIdentifierStart(code: number, languageVersion: ScriptTarget) {
|
||||
return languageVersion >= ScriptTarget.ES5 ?
|
||||
/* @internal */ export function isUnicodeIdentifierStart(code: number, languageVersion: ScriptTarget | undefined) {
|
||||
return languageVersion! >= ScriptTarget.ES5 ?
|
||||
lookupInUnicodeMap(code, unicodeES5IdentifierStart) :
|
||||
lookupInUnicodeMap(code, unicodeES3IdentifierStart);
|
||||
}
|
||||
|
||||
function isUnicodeIdentifierPart(code: number, languageVersion: ScriptTarget) {
|
||||
return languageVersion >= ScriptTarget.ES5 ?
|
||||
function isUnicodeIdentifierPart(code: number, languageVersion: ScriptTarget | undefined) {
|
||||
return languageVersion! >= ScriptTarget.ES5 ?
|
||||
lookupInUnicodeMap(code, unicodeES5IdentifierPart) :
|
||||
lookupInUnicodeMap(code, unicodeES3IdentifierPart);
|
||||
}
|
||||
@@ -601,7 +601,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function scanShebangTrivia(text: string, pos: number) {
|
||||
const shebang = shebangTriviaRegex.exec(text)[0];
|
||||
const shebang = shebangTriviaRegex.exec(text)![0];
|
||||
pos = pos + shebang.length;
|
||||
return pos;
|
||||
}
|
||||
@@ -626,11 +626,11 @@ namespace ts {
|
||||
* @returns If "reduce" is true, the accumulated value. If "reduce" is false, the first truthy
|
||||
* return value of the callback.
|
||||
*/
|
||||
function iterateCommentRanges<T, U>(reduce: boolean, text: string, pos: number, trailing: boolean, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial?: U): U {
|
||||
let pendingPos: number;
|
||||
let pendingEnd: number;
|
||||
let pendingKind: CommentKind;
|
||||
let pendingHasTrailingNewLine: boolean;
|
||||
function iterateCommentRanges<T, U>(reduce: boolean, text: string, pos: number, trailing: boolean, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U | undefined) => U, state: T, initial?: U): U | undefined {
|
||||
let pendingPos!: number;
|
||||
let pendingEnd!: number;
|
||||
let pendingKind!: CommentKind;
|
||||
let pendingHasTrailingNewLine!: boolean;
|
||||
let hasPendingCommentRange = false;
|
||||
let collecting = trailing || pos === 0;
|
||||
let accumulator = initial;
|
||||
@@ -769,20 +769,20 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function isIdentifierStart(ch: number, languageVersion: ScriptTarget): boolean {
|
||||
export function isIdentifierStart(ch: number, languageVersion: ScriptTarget | undefined): boolean {
|
||||
return ch >= CharacterCodes.A && ch <= CharacterCodes.Z || ch >= CharacterCodes.a && ch <= CharacterCodes.z ||
|
||||
ch === CharacterCodes.$ || ch === CharacterCodes._ ||
|
||||
ch > CharacterCodes.maxAsciiCharacter && isUnicodeIdentifierStart(ch, languageVersion);
|
||||
}
|
||||
|
||||
export function isIdentifierPart(ch: number, languageVersion: ScriptTarget): boolean {
|
||||
export function isIdentifierPart(ch: number, languageVersion: ScriptTarget | undefined): boolean {
|
||||
return ch >= CharacterCodes.A && ch <= CharacterCodes.Z || ch >= CharacterCodes.a && ch <= CharacterCodes.z ||
|
||||
ch >= CharacterCodes._0 && ch <= CharacterCodes._9 || ch === CharacterCodes.$ || ch === CharacterCodes._ ||
|
||||
ch > CharacterCodes.maxAsciiCharacter && isUnicodeIdentifierPart(ch, languageVersion);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isIdentifierText(name: string, languageVersion: ScriptTarget): boolean {
|
||||
export function isIdentifierText(name: string, languageVersion: ScriptTarget | undefined): boolean {
|
||||
if (!isIdentifierStart(name.charCodeAt(0), languageVersion)) {
|
||||
return false;
|
||||
}
|
||||
@@ -800,13 +800,16 @@ namespace ts {
|
||||
export function createScanner(languageVersion: ScriptTarget,
|
||||
skipTrivia: boolean,
|
||||
languageVariant = LanguageVariant.Standard,
|
||||
text?: string,
|
||||
textInitial?: string,
|
||||
onError?: ErrorCallback,
|
||||
start?: number,
|
||||
length?: number): Scanner {
|
||||
let text = textInitial!;
|
||||
|
||||
// Current position (end position of text of current token)
|
||||
let pos: number;
|
||||
|
||||
|
||||
// end of text
|
||||
let end: number;
|
||||
|
||||
@@ -817,7 +820,7 @@ namespace ts {
|
||||
let tokenPos: number;
|
||||
|
||||
let token: SyntaxKind;
|
||||
let tokenValue: string;
|
||||
let tokenValue!: string;
|
||||
let tokenFlags: TokenFlags;
|
||||
|
||||
setText(text, start, length);
|
||||
@@ -907,8 +910,8 @@ namespace ts {
|
||||
function scanNumber(): string {
|
||||
const start = pos;
|
||||
const mainFragment = scanNumberFragment();
|
||||
let decimalFragment: string;
|
||||
let scientificFragment: string;
|
||||
let decimalFragment: string | undefined;
|
||||
let scientificFragment: string | undefined;
|
||||
if (text.charCodeAt(pos) === CharacterCodes.dot) {
|
||||
pos++;
|
||||
decimalFragment = scanNumberFragment();
|
||||
@@ -1285,7 +1288,7 @@ namespace ts {
|
||||
if (len >= 2 && len <= 11) {
|
||||
const ch = tokenValue.charCodeAt(0);
|
||||
if (ch >= CharacterCodes.a && ch <= CharacterCodes.z) {
|
||||
token = textToToken.get(tokenValue);
|
||||
token = textToToken.get(tokenValue)!;
|
||||
if (token !== undefined) {
|
||||
return token;
|
||||
}
|
||||
@@ -2045,13 +2048,13 @@ namespace ts {
|
||||
return text;
|
||||
}
|
||||
|
||||
function setText(newText: string, start: number, length: number) {
|
||||
function setText(newText: string | undefined, start: number | undefined, length: number | undefined) {
|
||||
text = newText || "";
|
||||
end = length === undefined ? text.length : start + length;
|
||||
end = length === undefined ? text.length : start! + length;
|
||||
setTextPos(start || 0);
|
||||
}
|
||||
|
||||
function setOnError(errorCallback: ErrorCallback) {
|
||||
function setOnError(errorCallback: ErrorCallback | undefined) {
|
||||
onError = errorCallback;
|
||||
}
|
||||
|
||||
@@ -2069,7 +2072,7 @@ namespace ts {
|
||||
startPos = textPos;
|
||||
tokenPos = textPos;
|
||||
token = SyntaxKind.Unknown;
|
||||
tokenValue = undefined;
|
||||
tokenValue = undefined!;
|
||||
tokenFlags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
+27
-27
@@ -8,7 +8,7 @@ namespace ts {
|
||||
* @param sourceMapFilePath The path to the output source map file.
|
||||
* @param sourceFileOrBundle The input source file or bundle for the program.
|
||||
*/
|
||||
initialize(filePath: string, sourceMapFilePath: string, sourceFileOrBundle: SourceFile | Bundle, sourceMapOutput?: SourceMapData[]): void;
|
||||
initialize(filePath: string, sourceMapFilePath: string | undefined, sourceFileOrBundle: SourceFile | Bundle, sourceMapOutput?: SourceMapData[]): void;
|
||||
|
||||
/**
|
||||
* Reset the SourceMapWriter to an empty state.
|
||||
@@ -90,13 +90,13 @@ namespace ts {
|
||||
let sourceMapSourceIndex: number;
|
||||
|
||||
// Last recorded and encoded spans
|
||||
let lastRecordedSourceMapSpan: SourceMapSpan;
|
||||
let lastEncodedSourceMapSpan: SourceMapSpan;
|
||||
let lastEncodedNameIndex: number;
|
||||
let lastRecordedSourceMapSpan: SourceMapSpan | undefined;
|
||||
let lastEncodedSourceMapSpan: SourceMapSpan | undefined;
|
||||
let lastEncodedNameIndex: number | undefined;
|
||||
|
||||
// Source map data
|
||||
let sourceMapData: SourceMapData;
|
||||
let sourceMapDataList: SourceMapData[];
|
||||
let sourceMapDataList: SourceMapData[] | undefined;
|
||||
let disabled: boolean = !(compilerOptions.sourceMap || compilerOptions.inlineSourceMap);
|
||||
|
||||
return {
|
||||
@@ -134,8 +134,8 @@ namespace ts {
|
||||
}
|
||||
sourceMapDataList = outputSourceMapDataList;
|
||||
|
||||
currentSource = undefined;
|
||||
currentSourceText = undefined;
|
||||
currentSource = undefined!;
|
||||
currentSourceText = undefined!;
|
||||
|
||||
// Current source map file and its index in the sources list
|
||||
sourceMapSourceIndex = -1;
|
||||
@@ -148,7 +148,7 @@ namespace ts {
|
||||
// Initialize source map data
|
||||
sourceMapData = {
|
||||
sourceMapFilePath,
|
||||
jsSourceMappingURL: !compilerOptions.inlineSourceMap ? getBaseFileName(normalizeSlashes(sourceMapFilePath)) : undefined,
|
||||
jsSourceMappingURL: !compilerOptions.inlineSourceMap ? getBaseFileName(normalizeSlashes(sourceMapFilePath)) : undefined!, // TODO: GH#18217
|
||||
sourceMapFile: getBaseFileName(normalizeSlashes(filePath)),
|
||||
sourceMapSourceRoot: compilerOptions.sourceRoot || "",
|
||||
sourceMapSources: [],
|
||||
@@ -206,14 +206,14 @@ namespace ts {
|
||||
sourceMapDataList.push(sourceMapData);
|
||||
}
|
||||
|
||||
currentSource = undefined;
|
||||
sourceMapDir = undefined;
|
||||
sourceMapSourceIndex = undefined;
|
||||
currentSource = undefined!;
|
||||
sourceMapDir = undefined!;
|
||||
sourceMapSourceIndex = undefined!;
|
||||
lastRecordedSourceMapSpan = undefined;
|
||||
lastEncodedSourceMapSpan = undefined;
|
||||
lastEncodedSourceMapSpan = undefined!;
|
||||
lastEncodedNameIndex = undefined;
|
||||
sourceMapData = undefined;
|
||||
sourceMapDataList = undefined;
|
||||
sourceMapData = undefined!;
|
||||
sourceMapDataList = undefined!;
|
||||
}
|
||||
|
||||
// Encoding for sourcemap span
|
||||
@@ -222,9 +222,9 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
|
||||
let prevEncodedEmittedColumn = lastEncodedSourceMapSpan.emittedColumn;
|
||||
let prevEncodedEmittedColumn = lastEncodedSourceMapSpan!.emittedColumn;
|
||||
// Line/Comma delimiters
|
||||
if (lastEncodedSourceMapSpan.emittedLine === lastRecordedSourceMapSpan.emittedLine) {
|
||||
if (lastEncodedSourceMapSpan!.emittedLine === lastRecordedSourceMapSpan.emittedLine) {
|
||||
// Emit comma to separate the entry
|
||||
if (sourceMapData.sourceMapMappings) {
|
||||
sourceMapData.sourceMapMappings += ",";
|
||||
@@ -232,7 +232,7 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
// Emit line delimiters
|
||||
for (let encodedLine = lastEncodedSourceMapSpan.emittedLine; encodedLine < lastRecordedSourceMapSpan.emittedLine; encodedLine++) {
|
||||
for (let encodedLine = lastEncodedSourceMapSpan!.emittedLine; encodedLine < lastRecordedSourceMapSpan.emittedLine; encodedLine++) {
|
||||
sourceMapData.sourceMapMappings += ";";
|
||||
}
|
||||
prevEncodedEmittedColumn = 1;
|
||||
@@ -242,18 +242,18 @@ namespace ts {
|
||||
sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.emittedColumn - prevEncodedEmittedColumn);
|
||||
|
||||
// 2. Relative sourceIndex
|
||||
sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceIndex - lastEncodedSourceMapSpan.sourceIndex);
|
||||
sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceIndex - lastEncodedSourceMapSpan!.sourceIndex);
|
||||
|
||||
// 3. Relative sourceLine 0 based
|
||||
sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceLine - lastEncodedSourceMapSpan.sourceLine);
|
||||
sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceLine - lastEncodedSourceMapSpan!.sourceLine);
|
||||
|
||||
// 4. Relative sourceColumn 0 based
|
||||
sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceColumn - lastEncodedSourceMapSpan.sourceColumn);
|
||||
sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceColumn - lastEncodedSourceMapSpan!.sourceColumn);
|
||||
|
||||
// 5. Relative namePosition 0 based
|
||||
if (lastRecordedSourceMapSpan.nameIndex >= 0) {
|
||||
if (lastRecordedSourceMapSpan.nameIndex! >= 0) {
|
||||
Debug.assert(false, "We do not support name index right now, Make sure to update updateLastEncodedAndRecordedSpans when we start using this");
|
||||
sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.nameIndex - lastEncodedNameIndex);
|
||||
sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.nameIndex! - lastEncodedNameIndex!);
|
||||
lastEncodedNameIndex = lastRecordedSourceMapSpan.nameIndex;
|
||||
}
|
||||
|
||||
@@ -334,7 +334,7 @@ namespace ts {
|
||||
|
||||
if (node) {
|
||||
const emitNode = node.emitNode;
|
||||
const emitFlags = emitNode && emitNode.flags;
|
||||
const emitFlags = emitNode && emitNode.flags || EmitFlags.None;
|
||||
const range = emitNode && emitNode.sourceMapRange;
|
||||
const { pos, end } = range || node;
|
||||
let source = range && range.source;
|
||||
@@ -386,7 +386,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
const emitNode = node && node.emitNode;
|
||||
const emitFlags = emitNode && emitNode.flags;
|
||||
const emitFlags = emitNode && emitNode.flags || EmitFlags.None;
|
||||
const range = emitNode && emitNode.tokenSourceMapRanges && emitNode.tokenSourceMapRanges[token];
|
||||
|
||||
tokenPos = skipSourceTrivia(range ? range.pos : tokenPos);
|
||||
@@ -437,7 +437,7 @@ namespace ts {
|
||||
sourceMapData.inputSourceFileNames.push(currentSource.fileName);
|
||||
|
||||
if (compilerOptions.inlineSources) {
|
||||
sourceMapData.sourceMapSourcesContent.push(currentSource.text);
|
||||
sourceMapData.sourceMapSourcesContent!.push(currentSource.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -447,7 +447,7 @@ namespace ts {
|
||||
*/
|
||||
function getText() {
|
||||
if (disabled) {
|
||||
return;
|
||||
return undefined!; // TODO: GH#18217
|
||||
}
|
||||
|
||||
encodeLastRecordedSourceMapSpan();
|
||||
@@ -468,7 +468,7 @@ namespace ts {
|
||||
*/
|
||||
function getSourceMappingURL() {
|
||||
if (disabled) {
|
||||
return;
|
||||
return undefined!; // TODO: GH#18217
|
||||
}
|
||||
|
||||
if (compilerOptions.inlineSourceMap) {
|
||||
|
||||
@@ -8,8 +8,8 @@ namespace ts {
|
||||
resolveStructuredTypeMembers: (type: ObjectType) => ResolvedType,
|
||||
getTypeOfSymbol: (sym: Symbol) => Type,
|
||||
getResolvedSymbol: (node: Node) => Symbol,
|
||||
getIndexTypeOfStructuredType: (type: Type, kind: IndexKind) => Type,
|
||||
getConstraintFromTypeParameter: (typeParameter: TypeParameter) => Type,
|
||||
getIndexTypeOfStructuredType: (type: Type, kind: IndexKind) => Type | undefined,
|
||||
getConstraintFromTypeParameter: (typeParameter: TypeParameter) => Type | undefined,
|
||||
getFirstIdentifier: (node: EntityNameOrEntityNameExpression) => Identifier) {
|
||||
|
||||
return getSymbolWalker;
|
||||
@@ -41,7 +41,7 @@ namespace ts {
|
||||
},
|
||||
};
|
||||
|
||||
function visitType(type: Type): void {
|
||||
function visitType(type: Type | undefined): void {
|
||||
if (!type) {
|
||||
return;
|
||||
}
|
||||
@@ -157,13 +157,13 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function visitSymbol(symbol: Symbol): boolean {
|
||||
function visitSymbol(symbol: Symbol | undefined): boolean {
|
||||
if (!symbol) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
const symbolId = getSymbolId(symbol);
|
||||
if (visitedSymbols[symbolId]) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
visitedSymbols[symbolId] = symbol;
|
||||
if (!accept(symbol)) {
|
||||
@@ -172,7 +172,7 @@ namespace ts {
|
||||
const t = getTypeOfSymbol(symbol);
|
||||
visitType(t); // Should handle members on classes and such
|
||||
if (symbol.flags & SymbolFlags.HasExports) {
|
||||
symbol.exports.forEach(visitSymbol);
|
||||
symbol.exports!.forEach(visitSymbol);
|
||||
}
|
||||
forEach(symbol.declarations, d => {
|
||||
// Type queries are too far resolved when we just visit the symbol's type
|
||||
@@ -185,6 +185,7 @@ namespace ts {
|
||||
visitSymbol(entity);
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+26
-22
@@ -50,11 +50,11 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export function watchFileUsingPriorityPollingInterval(host: System, fileName: string, callback: FileWatcherCallback, watchPriority: PollingInterval): FileWatcher {
|
||||
return host.watchFile(fileName, callback, pollingInterval(watchPriority));
|
||||
return host.watchFile!(fileName, callback, pollingInterval(watchPriority));
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export type HostWatchFile = (fileName: string, callback: FileWatcherCallback, pollingInterval: PollingInterval) => FileWatcher;
|
||||
export type HostWatchFile = (fileName: string, callback: FileWatcherCallback, pollingInterval: PollingInterval | undefined) => FileWatcher;
|
||||
/* @internal */
|
||||
export type HostWatchDirectory = (fileName: string, callback: DirectoryWatcherCallback, recursive?: boolean) => FileWatcher;
|
||||
|
||||
@@ -119,7 +119,7 @@ namespace ts {
|
||||
return false;
|
||||
|
||||
function setLevel(level: keyof Levels) {
|
||||
levels[level] = customLevels[level] || levels[level];
|
||||
levels[level] = customLevels![level] || levels[level];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function createPollingIntervalQueue(pollingInterval: PollingInterval): PollingIntervalQueue {
|
||||
const queue = [] as PollingIntervalQueue;
|
||||
const queue = [] as WatchedFile[] as PollingIntervalQueue;
|
||||
queue.pollingInterval = pollingInterval;
|
||||
queue.pollIndex = 0;
|
||||
queue.pollScheduled = false;
|
||||
@@ -203,7 +203,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function pollQueue(queue: WatchedFile[], pollingInterval: PollingInterval, pollIndex: number, chunkSize: number) {
|
||||
function pollQueue(queue: (WatchedFile | undefined)[], pollingInterval: PollingInterval, pollIndex: number, chunkSize: number) {
|
||||
// Max visit would be all elements of the queue
|
||||
let needsVisit = queue.length;
|
||||
let definedValueCopyToIndex = pollIndex;
|
||||
@@ -300,11 +300,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
function scheduleNextPoll(pollingInterval: PollingInterval) {
|
||||
pollingIntervalQueue(pollingInterval).pollScheduled = host.setTimeout(pollingInterval === PollingInterval.Low ? pollLowPollingIntervalQueue : pollPollingIntervalQueue, pollingInterval, pollingIntervalQueue(pollingInterval));
|
||||
pollingIntervalQueue(pollingInterval).pollScheduled = host.setTimeout!(pollingInterval === PollingInterval.Low ? pollLowPollingIntervalQueue : pollPollingIntervalQueue, pollingInterval, pollingIntervalQueue(pollingInterval));
|
||||
}
|
||||
|
||||
function getModifiedTime(fileName: string) {
|
||||
return host.getModifiedTime(fileName) || missingFileModifiedTime;
|
||||
return host.getModifiedTime!(fileName) || missingFileModifiedTime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -369,7 +369,7 @@ namespace ts {
|
||||
close: () => {
|
||||
watcher.close();
|
||||
result.childWatches.forEach(closeFileWatcher);
|
||||
result = undefined;
|
||||
result = undefined!;
|
||||
},
|
||||
dirName,
|
||||
childWatches: emptyArray
|
||||
@@ -423,6 +423,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: GH#18217 Methods on System are often used as if they are certainly defined
|
||||
export interface System {
|
||||
args: string[];
|
||||
newLine: string;
|
||||
@@ -480,7 +481,7 @@ namespace ts {
|
||||
declare const global: any;
|
||||
declare const __filename: string;
|
||||
|
||||
export function getNodeMajorVersion() {
|
||||
export function getNodeMajorVersion(): number | undefined {
|
||||
if (typeof process === "undefined") {
|
||||
return undefined;
|
||||
}
|
||||
@@ -517,6 +518,7 @@ namespace ts {
|
||||
getEnvironmentVariable?(name: string): string;
|
||||
};
|
||||
|
||||
// TODO: this is used as if it's certainly defined in many places.
|
||||
export let sys: System = (() => {
|
||||
// NodeJS detects "\uFEFF" at the start of the string and *replaces* it with the actual
|
||||
// byte order mark from the specified encoding. Using any other byte order mark does
|
||||
@@ -528,7 +530,7 @@ namespace ts {
|
||||
const _path = require("path");
|
||||
const _os = require("os");
|
||||
// crypto can be absent on reduced node installations
|
||||
let _crypto: typeof import("crypto");
|
||||
let _crypto: typeof import("crypto") | undefined;
|
||||
try {
|
||||
_crypto = require("crypto");
|
||||
}
|
||||
@@ -542,7 +544,7 @@ namespace ts {
|
||||
} = require("buffer").Buffer;
|
||||
|
||||
const nodeVersion = getNodeMajorVersion();
|
||||
const isNode4OrLater = nodeVersion >= 4;
|
||||
const isNode4OrLater = nodeVersion! >= 4;
|
||||
|
||||
const platform: string = _os.platform();
|
||||
const useCaseSensitiveFileNames = isFileSystemCaseSensitive();
|
||||
@@ -632,12 +634,12 @@ namespace ts {
|
||||
}
|
||||
},
|
||||
base64decode: Buffer.from ? input => {
|
||||
return Buffer.from(input, "base64").toString("utf8");
|
||||
return Buffer.from!(input, "base64").toString("utf8");
|
||||
} : input => {
|
||||
return new Buffer(input, "base64").toString("utf8");
|
||||
},
|
||||
base64encode: Buffer.from ? input => {
|
||||
return Buffer.from(input).toString("base64");
|
||||
return Buffer.from!(input).toString("base64");
|
||||
} : input => {
|
||||
return new Buffer(input).toString("base64");
|
||||
}
|
||||
@@ -712,6 +714,7 @@ namespace ts {
|
||||
return watchDirectoryRecursively(directoryName, callback);
|
||||
}
|
||||
watchDirectory(directoryName, callback);
|
||||
return undefined!; // TODO: GH#18217
|
||||
};
|
||||
}
|
||||
|
||||
@@ -748,7 +751,7 @@ namespace ts {
|
||||
(_eventName: string, relativeFileName) => {
|
||||
// When files are deleted from disk, the triggered "rename" event would have a relativefileName of "undefined"
|
||||
const fileName = !isString(relativeFileName)
|
||||
? undefined
|
||||
? undefined! // TODO: GH#18217
|
||||
: getNormalizedAbsolutePath(relativeFileName, dirName);
|
||||
// Some applications save a working file via rename operations
|
||||
const callbacks = fileWatcherCallbacks.get(toCanonicalName(fileName));
|
||||
@@ -838,7 +841,7 @@ namespace ts {
|
||||
close: () => {
|
||||
// Close the watcher (either existing file system entry watcher or missing file system entry watcher)
|
||||
watcher.close();
|
||||
watcher = undefined;
|
||||
watcher = undefined!;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -970,7 +973,7 @@ namespace ts {
|
||||
data = byteOrderMarkIndicator + data;
|
||||
}
|
||||
|
||||
let fd: number;
|
||||
let fd: number | undefined;
|
||||
|
||||
try {
|
||||
fd = _fs.openSync(fileName, "w");
|
||||
@@ -1028,6 +1031,7 @@ namespace ts {
|
||||
switch (entryKind) {
|
||||
case FileSystemEntryKind.File: return stat.isFile();
|
||||
case FileSystemEntryKind.Directory: return stat.isDirectory();
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
@@ -1075,13 +1079,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
function createMD5HashUsingNativeCrypto(data: string): string {
|
||||
const hash = _crypto.createHash("md5");
|
||||
const hash = _crypto!.createHash("md5");
|
||||
hash.update(data);
|
||||
return hash.digest("hex");
|
||||
}
|
||||
|
||||
function createSHA256Hash(data: string): string {
|
||||
const hash = _crypto.createHash("sha256");
|
||||
const hash = _crypto!.createHash("sha256");
|
||||
hash.update(data);
|
||||
return hash.digest("hex");
|
||||
}
|
||||
@@ -1134,7 +1138,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
let sys: System;
|
||||
let sys: System | undefined;
|
||||
if (typeof ChakraHost !== "undefined") {
|
||||
sys = getChakraSystem();
|
||||
}
|
||||
@@ -1148,13 +1152,13 @@ namespace ts {
|
||||
const originalWriteFile = sys.writeFile;
|
||||
sys.writeFile = (path, data, writeBom) => {
|
||||
const directoryPath = getDirectoryPath(normalizeSlashes(path));
|
||||
if (directoryPath && !sys.directoryExists(directoryPath)) {
|
||||
recursiveCreateDirectory(directoryPath, sys);
|
||||
if (directoryPath && !sys!.directoryExists(directoryPath)) {
|
||||
recursiveCreateDirectory(directoryPath, sys!);
|
||||
}
|
||||
originalWriteFile.call(sys, path, data, writeBom);
|
||||
};
|
||||
}
|
||||
return sys;
|
||||
return sys!;
|
||||
})();
|
||||
|
||||
if (sys && sys.getEnvironmentVariable) {
|
||||
|
||||
+14
-14
@@ -78,7 +78,7 @@ namespace ts {
|
||||
* @param transforms An array of `TransformerFactory` callbacks.
|
||||
* @param allowDtsFiles A value indicating whether to allow the transformation of .d.ts files.
|
||||
*/
|
||||
export function transformNodes<T extends Node>(resolver: EmitResolver, host: EmitHost, options: CompilerOptions, nodes: ReadonlyArray<T>, transformers: ReadonlyArray<TransformerFactory<T>>, allowDtsFiles: boolean): TransformationResult<T> {
|
||||
export function transformNodes<T extends Node>(resolver: EmitResolver | undefined, host: EmitHost | undefined, options: CompilerOptions, nodes: ReadonlyArray<T>, transformers: ReadonlyArray<TransformerFactory<T>>, allowDtsFiles: boolean): TransformationResult<T> {
|
||||
const enabledSyntaxKindFeatures = new Array<SyntaxKindFeatureFlags>(SyntaxKind.Count);
|
||||
let lexicalEnvironmentVariableDeclarations: VariableDeclaration[];
|
||||
let lexicalEnvironmentFunctionDeclarations: FunctionDeclaration[];
|
||||
@@ -86,7 +86,7 @@ namespace ts {
|
||||
let lexicalEnvironmentFunctionDeclarationsStack: FunctionDeclaration[][] = [];
|
||||
let lexicalEnvironmentStackOffset = 0;
|
||||
let lexicalEnvironmentSuspended = false;
|
||||
let emitHelpers: EmitHelper[];
|
||||
let emitHelpers: EmitHelper[] | undefined;
|
||||
let onSubstituteNode: TransformationContext["onSubstituteNode"] = (_, node) => node;
|
||||
let onEmitNode: TransformationContext["onEmitNode"] = (hint, node, callback) => callback(hint, node);
|
||||
let state = TransformationState.Uninitialized;
|
||||
@@ -96,8 +96,8 @@ namespace ts {
|
||||
// initialization.
|
||||
const context: TransformationContext = {
|
||||
getCompilerOptions: () => options,
|
||||
getEmitResolver: () => resolver,
|
||||
getEmitHost: () => host,
|
||||
getEmitResolver: () => resolver!, // TODO: GH#18217
|
||||
getEmitHost: () => host!, // TODO: GH#18217
|
||||
startLexicalEnvironment,
|
||||
suspendLexicalEnvironment,
|
||||
resumeLexicalEnvironment,
|
||||
@@ -270,8 +270,8 @@ namespace ts {
|
||||
lexicalEnvironmentVariableDeclarationsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentVariableDeclarations;
|
||||
lexicalEnvironmentFunctionDeclarationsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentFunctionDeclarations;
|
||||
lexicalEnvironmentStackOffset++;
|
||||
lexicalEnvironmentVariableDeclarations = undefined;
|
||||
lexicalEnvironmentFunctionDeclarations = undefined;
|
||||
lexicalEnvironmentVariableDeclarations = undefined!;
|
||||
lexicalEnvironmentFunctionDeclarations = undefined!;
|
||||
}
|
||||
|
||||
/** Suspends the current lexical environment, usually after visiting a parameter list. */
|
||||
@@ -294,12 +294,12 @@ namespace ts {
|
||||
* Ends a lexical environment. The previous set of hoisted declarations are restored and
|
||||
* any hoisted declarations added in this environment are returned.
|
||||
*/
|
||||
function endLexicalEnvironment(): Statement[] {
|
||||
function endLexicalEnvironment(): Statement[] | undefined {
|
||||
Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization.");
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed.");
|
||||
Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended.");
|
||||
|
||||
let statements: Statement[];
|
||||
let statements: Statement[] | undefined;
|
||||
if (lexicalEnvironmentVariableDeclarations || lexicalEnvironmentFunctionDeclarations) {
|
||||
if (lexicalEnvironmentFunctionDeclarations) {
|
||||
statements = [...lexicalEnvironmentFunctionDeclarations];
|
||||
@@ -354,12 +354,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Release references to external entries for GC purposes.
|
||||
lexicalEnvironmentVariableDeclarations = undefined;
|
||||
lexicalEnvironmentVariableDeclarationsStack = undefined;
|
||||
lexicalEnvironmentFunctionDeclarations = undefined;
|
||||
lexicalEnvironmentFunctionDeclarationsStack = undefined;
|
||||
onSubstituteNode = undefined;
|
||||
onEmitNode = undefined;
|
||||
lexicalEnvironmentVariableDeclarations = undefined!;
|
||||
lexicalEnvironmentVariableDeclarationsStack = undefined!;
|
||||
lexicalEnvironmentFunctionDeclarations = undefined!;
|
||||
lexicalEnvironmentFunctionDeclarationsStack = undefined!;
|
||||
onSubstituteNode = undefined!;
|
||||
onEmitNode = undefined!;
|
||||
emitHelpers = undefined;
|
||||
|
||||
// Prevent further use of the transformation result.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*@internal*/
|
||||
namespace ts {
|
||||
export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, file: SourceFile | undefined): DiagnosticWithLocation[] {
|
||||
export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, file: SourceFile | undefined): DiagnosticWithLocation[] | undefined {
|
||||
if (file && isSourceFileJavaScript(file)) {
|
||||
return []; // No declaration diagnostics for js for now
|
||||
}
|
||||
@@ -32,8 +32,8 @@ namespace ts {
|
||||
let needsScopeFixMarker = false;
|
||||
let resultHasScopeMarker = false;
|
||||
let enclosingDeclaration: Node;
|
||||
let necessaryTypeRefernces: Map<true>;
|
||||
let lateMarkedStatements: LateVisibilityPaintedStatement[];
|
||||
let necessaryTypeRefernces: Map<true> | undefined;
|
||||
let lateMarkedStatements: LateVisibilityPaintedStatement[] | undefined;
|
||||
let lateStatementReplacementMap: Map<VisitResult<LateVisibilityPaintedStatement>>;
|
||||
let suppressNewDiagnosticContexts: boolean;
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace ts {
|
||||
const { noResolve, stripInternal } = options;
|
||||
return transformRoot;
|
||||
|
||||
function recordTypeReferenceDirectivesIfNecessary(typeReferenceDirectives: string[]): void {
|
||||
function recordTypeReferenceDirectivesIfNecessary(typeReferenceDirectives: string[] | undefined): void {
|
||||
if (!typeReferenceDirectives) {
|
||||
return;
|
||||
}
|
||||
@@ -151,7 +151,7 @@ namespace ts {
|
||||
let hasNoDefaultLib = false;
|
||||
const bundle = createBundle(map(node.sourceFiles,
|
||||
sourceFile => {
|
||||
if (sourceFile.isDeclarationFile || isSourceFileJavaScript(sourceFile)) return; // Omit declaration files from bundle results, too
|
||||
if (sourceFile.isDeclarationFile || isSourceFileJavaScript(sourceFile)) return undefined!; // Omit declaration files from bundle results, too // TODO: GH#18217
|
||||
hasNoDefaultLib = hasNoDefaultLib || sourceFile.hasNoDefaultLib;
|
||||
currentSourceFile = sourceFile;
|
||||
enclosingDeclaration = sourceFile;
|
||||
@@ -186,7 +186,7 @@ namespace ts {
|
||||
bundle.syntheticFileReferences = [];
|
||||
bundle.syntheticTypeReferences = getFileReferencesForUsedTypeReferences();
|
||||
bundle.hasNoDefaultLib = hasNoDefaultLib;
|
||||
const outputFilePath = getDirectoryPath(normalizeSlashes(getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath));
|
||||
const outputFilePath = getDirectoryPath(normalizeSlashes(getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath!));
|
||||
const referenceVisitor = mapReferencesIntoArray(bundle.syntheticFileReferences as FileReference[], outputFilePath);
|
||||
refs.forEach(referenceVisitor);
|
||||
return bundle;
|
||||
@@ -207,7 +207,7 @@ namespace ts {
|
||||
necessaryTypeRefernces = undefined;
|
||||
refs = collectReferences(currentSourceFile, createMap());
|
||||
const references: FileReference[] = [];
|
||||
const outputFilePath = getDirectoryPath(normalizeSlashes(getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath));
|
||||
const outputFilePath = getDirectoryPath(normalizeSlashes(getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath!));
|
||||
const referenceVisitor = mapReferencesIntoArray(references, outputFilePath);
|
||||
const statements = visitNodes(node.statements, visitDeclarationStatements);
|
||||
let combinedStatements = setTextRange(createNodeArray(transformAndReplaceLatePaintedStatements(statements)), node.statements);
|
||||
@@ -304,7 +304,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function ensureParameter(p: ParameterDeclaration, modifierMask?: ModifierFlags): ParameterDeclaration {
|
||||
let oldDiag: typeof getSymbolAccessibilityDiagnostic;
|
||||
let oldDiag: typeof getSymbolAccessibilityDiagnostic | undefined;
|
||||
if (!suppressNewDiagnosticContexts) {
|
||||
oldDiag = getSymbolAccessibilityDiagnostic;
|
||||
getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(p);
|
||||
@@ -320,7 +320,7 @@ namespace ts {
|
||||
ensureNoInitializer(p)
|
||||
);
|
||||
if (!suppressNewDiagnosticContexts) {
|
||||
getSymbolAccessibilityDiagnostic = oldDiag;
|
||||
getSymbolAccessibilityDiagnostic = oldDiag!;
|
||||
}
|
||||
return newParam;
|
||||
}
|
||||
@@ -350,7 +350,7 @@ namespace ts {
|
||||
| PropertyDeclaration
|
||||
| PropertySignature;
|
||||
|
||||
function ensureType(node: HasInferredType, type: TypeNode, ignorePrivate?: boolean): TypeNode {
|
||||
function ensureType(node: HasInferredType, type: TypeNode | undefined, ignorePrivate?: boolean): TypeNode | undefined {
|
||||
if (!ignorePrivate && hasModifier(node, ModifierFlags.Private)) {
|
||||
// Private nodes emit no types (except private parameter properties, whose parameter types are actually visible)
|
||||
return;
|
||||
@@ -427,7 +427,7 @@ namespace ts {
|
||||
}
|
||||
if (isBindingPattern(elem.name)) {
|
||||
// If any child binding pattern element has been marked visible (usually by collect linked aliases), then this is visible
|
||||
return forEach(elem.name.elements, getBindingNameVisible);
|
||||
return some(elem.name.elements, getBindingNameVisible);
|
||||
}
|
||||
else {
|
||||
return resolver.isDeclarationVisible(elem);
|
||||
@@ -436,16 +436,16 @@ namespace ts {
|
||||
|
||||
function updateParamsList(node: Node, params: NodeArray<ParameterDeclaration>, modifierMask?: ModifierFlags) {
|
||||
if (hasModifier(node, ModifierFlags.Private)) {
|
||||
return undefined;
|
||||
return undefined!; // TODO: GH#18217
|
||||
}
|
||||
const newParams = map(params, p => ensureParameter(p, modifierMask));
|
||||
if (!newParams) {
|
||||
return undefined;
|
||||
return undefined!; // TODO: GH#18217
|
||||
}
|
||||
return createNodeArray(newParams, params.hasTrailingComma);
|
||||
}
|
||||
|
||||
function ensureTypeParams(node: Node, params: NodeArray<TypeParameterDeclaration>) {
|
||||
function ensureTypeParams(node: Node, params: NodeArray<TypeParameterDeclaration> | undefined) {
|
||||
return hasModifier(node, ModifierFlags.Private) ? undefined : visitNodes(params, visitDeclarationSubtree);
|
||||
}
|
||||
|
||||
@@ -473,8 +473,8 @@ namespace ts {
|
||||
return setCommentRange(updated, getCommentRange(original));
|
||||
}
|
||||
|
||||
function rewriteModuleSpecifier<T extends Node>(parent: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration | ImportTypeNode, input: T): T | StringLiteral {
|
||||
if (!input) return;
|
||||
function rewriteModuleSpecifier<T extends Node>(parent: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration | ImportTypeNode, input: T | undefined): T | StringLiteral {
|
||||
if (!input) return undefined!; // TODO: GH#18217
|
||||
resultHasExternalModuleIndicator = resultHasExternalModuleIndicator || (parent.kind !== SyntaxKind.ModuleDeclaration && parent.kind !== SyntaxKind.ImportType);
|
||||
if (input.kind === SyntaxKind.StringLiteral && isBundledEmit) {
|
||||
const newName = getExternalModuleNameFromDeclaration(context.getEmitHost(), resolver, parent);
|
||||
@@ -571,7 +571,7 @@ namespace ts {
|
||||
// be recorded. So while checking D's visibility we mark C as visible, then we must check C which in turn marks B, completing the chain of
|
||||
// dependent imports and allowing a valid declaration file output. Today, this dependent alias marking only happens for internal import aliases.
|
||||
while (length(lateMarkedStatements)) {
|
||||
const i = lateMarkedStatements.shift();
|
||||
const i = lateMarkedStatements!.shift()!;
|
||||
if (!isLateVisibilityPaintedStatement(i)) {
|
||||
return Debug.fail(`Late replaced statement was found which is not handled by the declaration transformer!: ${(ts as any).SyntaxKind ? (ts as any).SyntaxKind[(i as any).kind] : (i as any).kind}`);
|
||||
}
|
||||
@@ -687,7 +687,8 @@ namespace ts {
|
||||
const ctor = createSignatureDeclaration(
|
||||
SyntaxKind.Constructor,
|
||||
isPrivate ? undefined : ensureTypeParams(input, input.typeParameters),
|
||||
isPrivate ? undefined : updateParamsList(input, input.parameters, ModifierFlags.None),
|
||||
// TODO: GH#18217
|
||||
isPrivate ? undefined! : updateParamsList(input, input.parameters, ModifierFlags.None),
|
||||
/*type*/ undefined
|
||||
);
|
||||
ctor.modifiers = createNodeArray(ensureModifiers(input));
|
||||
@@ -807,7 +808,7 @@ namespace ts {
|
||||
|
||||
return cleanup(visitEachChild(input, visitDeclarationSubtree, context));
|
||||
|
||||
function cleanup<T extends Node>(returnValue: T | undefined): T {
|
||||
function cleanup<T extends Node>(returnValue: T | undefined): T | undefined {
|
||||
if (returnValue && canProdiceDiagnostic && hasDynamicName(input as Declaration)) {
|
||||
checkName(input as DeclarationDiagnosticProducing);
|
||||
}
|
||||
@@ -961,7 +962,7 @@ namespace ts {
|
||||
needsDeclare = false;
|
||||
visitNode(inner, visitDeclarationStatements);
|
||||
// eagerly transform nested namespaces (the nesting doesn't need any elision or painting done)
|
||||
const id = "" + getOriginalNodeId(inner);
|
||||
const id = "" + getOriginalNodeId(inner!); // TODO: GH#18217
|
||||
const body = lateStatementReplacementMap.get(id);
|
||||
lateStatementReplacementMap.delete(id);
|
||||
return cleanup(updateModuleDeclaration(
|
||||
@@ -977,7 +978,7 @@ namespace ts {
|
||||
const modifiers = createNodeArray(ensureModifiers(input, isPrivate));
|
||||
const typeParameters = ensureTypeParams(input, input.typeParameters);
|
||||
const ctor = getFirstConstructorWithBody(input);
|
||||
let parameterProperties: PropertyDeclaration[];
|
||||
let parameterProperties: PropertyDeclaration[] | undefined;
|
||||
if (ctor) {
|
||||
const oldDiag = getSymbolAccessibilityDiagnostic;
|
||||
parameterProperties = compact(flatMap(ctor.parameters, param => {
|
||||
@@ -998,7 +999,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function walkBindingPattern(pattern: BindingPattern) {
|
||||
let elems: PropertyDeclaration[];
|
||||
let elems: PropertyDeclaration[] | undefined;
|
||||
for (const elem of pattern.elements) {
|
||||
if (isOmittedExpression(elem)) continue;
|
||||
if (isBindingPattern(elem.name)) {
|
||||
@@ -1025,7 +1026,7 @@ namespace ts {
|
||||
if (extendsClause && !isEntityNameExpression(extendsClause.expression) && extendsClause.expression.kind !== SyntaxKind.NullKeyword) {
|
||||
// We must add a temporary declaration for the extends clause expression
|
||||
|
||||
const newId = createOptimisticUniqueName(`${unescapeLeadingUnderscores(input.name.escapedText)}_base`);
|
||||
const newId = createOptimisticUniqueName(`${unescapeLeadingUnderscores(input.name!.escapedText)}_base`); // TODO: GH#18217
|
||||
getSymbolAccessibilityDiagnostic = () => ({
|
||||
diagnosticMessage: Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1,
|
||||
errorNode: extendsClause,
|
||||
@@ -1051,7 +1052,7 @@ namespace ts {
|
||||
typeParameters,
|
||||
heritageClauses,
|
||||
members
|
||||
))];
|
||||
))!]; // TODO: GH#18217
|
||||
}
|
||||
else {
|
||||
const heritageClauses = transformHeritageClauses(input.heritageClauses);
|
||||
@@ -1081,7 +1082,7 @@ namespace ts {
|
||||
// Anything left unhandled is an error, so this should be unreachable
|
||||
return Debug.assertNever(input, `Unhandled top-level node in declaration emit: ${(ts as any).SyntaxKind[(input as any).kind]}`);
|
||||
|
||||
function cleanup<T extends Node>(node: T | undefined): T {
|
||||
function cleanup<T extends Node>(node: T | undefined): T | undefined {
|
||||
if (isEnclosingDeclaration(input)) {
|
||||
enclosingDeclaration = previousEnclosingDeclaration;
|
||||
}
|
||||
@@ -1125,7 +1126,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function checkName(node: DeclarationDiagnosticProducing) {
|
||||
let oldDiag: typeof getSymbolAccessibilityDiagnostic;
|
||||
let oldDiag: typeof getSymbolAccessibilityDiagnostic | undefined;
|
||||
if (!suppressNewDiagnosticContexts) {
|
||||
oldDiag = getSymbolAccessibilityDiagnostic;
|
||||
getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNodeName(node);
|
||||
@@ -1136,7 +1137,7 @@ namespace ts {
|
||||
const entityName = decl.name.expression;
|
||||
checkEntityNameVisibility(entityName, enclosingDeclaration);
|
||||
if (!suppressNewDiagnosticContexts) {
|
||||
getSymbolAccessibilityDiagnostic = oldDiag;
|
||||
getSymbolAccessibilityDiagnostic = oldDiag!;
|
||||
}
|
||||
errorNameNode = undefined;
|
||||
}
|
||||
@@ -1156,7 +1157,7 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function ensureModifiers(node: Node, privateDeclaration?: boolean): ReadonlyArray<Modifier> {
|
||||
function ensureModifiers(node: Node, privateDeclaration?: boolean): ReadonlyArray<Modifier> | undefined {
|
||||
const currentFlags = getModifierFlags(node);
|
||||
const newFlags = ensureModifierFlags(node, privateDeclaration);
|
||||
if (currentFlags === newFlags) {
|
||||
@@ -1211,7 +1212,7 @@ namespace ts {
|
||||
return prop;
|
||||
}
|
||||
|
||||
function transformHeritageClauses(nodes: NodeArray<HeritageClause>) {
|
||||
function transformHeritageClauses(nodes: NodeArray<HeritageClause> | undefined) {
|
||||
return createNodeArray(filter(map(nodes, clause => updateHeritageClause(clause, visitNodes(createNodeArray(filter(clause.types, t => {
|
||||
return isEntityNameExpression(t.expression) || (clause.token === SyntaxKind.ExtendsKeyword && t.expression.kind === SyntaxKind.NullKeyword);
|
||||
})), visitDeclarationSubtree))), clause => clause.types && !!clause.types.length));
|
||||
@@ -1238,7 +1239,7 @@ namespace ts {
|
||||
return flags;
|
||||
}
|
||||
|
||||
function getTypeAnnotationFromAccessor(accessor: AccessorDeclaration): TypeNode {
|
||||
function getTypeAnnotationFromAccessor(accessor: AccessorDeclaration): TypeNode | undefined {
|
||||
if (accessor) {
|
||||
return accessor.kind === SyntaxKind.GetAccessor
|
||||
? accessor.type // Getter - return type
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getMethodNameVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {
|
||||
function getMethodNameVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic | undefined {
|
||||
const diagnosticMessage = getMethodNameVisibilityDiagnosticMessage(symbolAccessibilityResult);
|
||||
return diagnosticMessage !== undefined ? {
|
||||
diagnosticMessage,
|
||||
@@ -122,7 +122,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function createGetSymbolAccessibilityDiagnosticForNode(node: DeclarationDiagnosticProducing) {
|
||||
export function createGetSymbolAccessibilityDiagnosticForNode(node: DeclarationDiagnosticProducing): (symbolAccessibilityResult: SymbolAccessibilityResult) => SymbolAccessibilityDiagnostic | undefined {
|
||||
if (isVariableDeclaration(node) || isPropertyDeclaration(node) || isPropertySignature(node) || isBindingElement(node) || isConstructorDeclaration(node)) {
|
||||
return getVariableDeclarationTypeVisibilityError;
|
||||
}
|
||||
@@ -151,7 +151,7 @@ namespace ts {
|
||||
return getTypeAliasDeclarationVisibilityError;
|
||||
}
|
||||
else {
|
||||
Debug.assertNever(node, `Attempted to set a declaration diagnostic context for unhandled node kind: ${(ts as any).SyntaxKind[(node as any).kind]}`);
|
||||
return Debug.assertNever(node, `Attempted to set a declaration diagnostic context for unhandled node kind: ${(ts as any).SyntaxKind[(node as any).kind]}`);
|
||||
}
|
||||
|
||||
function getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult: SymbolAccessibilityResult) {
|
||||
@@ -190,7 +190,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getVariableDeclarationTypeVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {
|
||||
function getVariableDeclarationTypeVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic | undefined {
|
||||
const diagnosticMessage = getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult);
|
||||
return diagnosticMessage !== undefined ? {
|
||||
diagnosticMessage,
|
||||
@@ -233,7 +233,7 @@ namespace ts {
|
||||
}
|
||||
return {
|
||||
diagnosticMessage,
|
||||
errorNode: (node as NamedDeclaration).name,
|
||||
errorNode: (node as NamedDeclaration).name!,
|
||||
typeName: (node as NamedDeclaration).name
|
||||
};
|
||||
}
|
||||
@@ -295,7 +295,7 @@ namespace ts {
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug.fail("This is unknown kind for signature: " + node.kind);
|
||||
return Debug.fail("This is unknown kind for signature: " + node.kind);
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -304,7 +304,7 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
function getParameterDeclarationTypeVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {
|
||||
function getParameterDeclarationTypeVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic | undefined {
|
||||
const diagnosticMessage: DiagnosticMessage = getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult);
|
||||
return diagnosticMessage !== undefined ? {
|
||||
diagnosticMessage,
|
||||
@@ -373,7 +373,7 @@ namespace ts {
|
||||
Diagnostics.Parameter_0_of_exported_function_has_or_is_using_private_name_1;
|
||||
|
||||
default:
|
||||
Debug.fail(`Unknown parent for parameter: ${(ts as any).SyntaxKind[node.parent.kind]}`);
|
||||
return Debug.fail(`Unknown parent for parameter: ${(ts as any).SyntaxKind[node.parent.kind]}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,7 +419,7 @@ namespace ts {
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug.fail("This is unknown parent for type parameter: " + node.parent.kind);
|
||||
return Debug.fail("This is unknown parent for type parameter: " + node.parent.kind);
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace ts {
|
||||
downlevelIteration: boolean;
|
||||
hoistTempVariables: boolean;
|
||||
emitExpression: (value: Expression) => void;
|
||||
emitBindingOrAssignment: (target: BindingOrAssignmentElementTarget, value: Expression, location: TextRange, original: Node) => void;
|
||||
emitBindingOrAssignment: (target: BindingOrAssignmentElementTarget, value: Expression, location: TextRange, original: Node | undefined) => void;
|
||||
createArrayBindingOrAssignmentPattern: (elements: BindingOrAssignmentElement[]) => ArrayBindingOrAssignmentPattern;
|
||||
createObjectBindingOrAssignmentPattern: (elements: BindingOrAssignmentElement[]) => ObjectBindingOrAssignmentPattern;
|
||||
createArrayBindingOrAssignmentElement: (node: Identifier) => BindingOrAssignmentElement;
|
||||
@@ -37,7 +37,7 @@ namespace ts {
|
||||
needsValue?: boolean,
|
||||
createAssignmentCallback?: (name: Identifier, value: Expression, location?: TextRange) => Expression): Expression {
|
||||
let location: TextRange = node;
|
||||
let value: Expression;
|
||||
let value: Expression | undefined;
|
||||
if (isDestructuringAssignment(node)) {
|
||||
value = node.right;
|
||||
while (isEmptyArrayLiteral(node.left) || isEmptyObjectLiteral(node.left)) {
|
||||
@@ -51,11 +51,11 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
let expressions: Expression[];
|
||||
let expressions: Expression[] | undefined;
|
||||
const flattenContext: FlattenContext = {
|
||||
context,
|
||||
level,
|
||||
downlevelIteration: context.getCompilerOptions().downlevelIteration,
|
||||
downlevelIteration: !!context.getCompilerOptions().downlevelIteration,
|
||||
hoistTempVariables: true,
|
||||
emitExpression,
|
||||
emitBindingOrAssignment,
|
||||
@@ -103,7 +103,7 @@ namespace ts {
|
||||
expressions.push(value);
|
||||
}
|
||||
|
||||
return aggregateTransformFlags(inlineExpressions(expressions)) || createOmittedExpression();
|
||||
return aggregateTransformFlags(inlineExpressions(expressions!)) || createOmittedExpression();
|
||||
|
||||
function emitExpression(expression: Expression) {
|
||||
// NOTE: this completely disables source maps, but aligns with the behavior of
|
||||
@@ -127,7 +127,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function bindingOrAssignmentElementAssignsToName(element: BindingOrAssignmentElement, escapedName: __String): boolean {
|
||||
const target = getTargetOfBindingOrAssignmentElement(element);
|
||||
const target = getTargetOfBindingOrAssignmentElement(element)!; // TODO: GH#18217
|
||||
if (isBindingOrAssignmentPattern(target)) {
|
||||
return bindingOrAssignmentPatternAssignsToName(target, escapedName);
|
||||
}
|
||||
@@ -164,15 +164,15 @@ namespace ts {
|
||||
context: TransformationContext,
|
||||
level: FlattenLevel,
|
||||
rval?: Expression,
|
||||
hoistTempVariables?: boolean,
|
||||
hoistTempVariables = false,
|
||||
skipInitializer?: boolean): VariableDeclaration[] {
|
||||
let pendingExpressions: Expression[];
|
||||
let pendingExpressions: Expression[] | undefined;
|
||||
const pendingDeclarations: { pendingExpressions?: Expression[], name: BindingName, value: Expression, location?: TextRange, original?: Node; }[] = [];
|
||||
const declarations: VariableDeclaration[] = [];
|
||||
const flattenContext: FlattenContext = {
|
||||
context,
|
||||
level,
|
||||
downlevelIteration: context.getCompilerOptions().downlevelIteration,
|
||||
downlevelIteration: !!context.getCompilerOptions().downlevelIteration,
|
||||
hoistTempVariables,
|
||||
emitExpression,
|
||||
emitBindingOrAssignment,
|
||||
@@ -202,7 +202,7 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
context.hoistVariableDeclaration(temp);
|
||||
const pendingDeclaration = lastOrUndefined(pendingDeclarations);
|
||||
const pendingDeclaration = last(pendingDeclarations);
|
||||
pendingDeclaration.pendingExpressions = append(
|
||||
pendingDeclaration.pendingExpressions,
|
||||
createAssignment(temp, pendingDeclaration.value)
|
||||
@@ -231,7 +231,7 @@ namespace ts {
|
||||
pendingExpressions = append(pendingExpressions, value);
|
||||
}
|
||||
|
||||
function emitBindingOrAssignment(target: BindingOrAssignmentElementTarget, value: Expression, location: TextRange, original: Node) {
|
||||
function emitBindingOrAssignment(target: BindingOrAssignmentElementTarget, value: Expression, location: TextRange | undefined, original: Node | undefined) {
|
||||
Debug.assertNode(target, isBindingName);
|
||||
if (pendingExpressions) {
|
||||
value = inlineExpressions(append(pendingExpressions, value));
|
||||
@@ -268,15 +268,15 @@ namespace ts {
|
||||
value = createVoidZero();
|
||||
}
|
||||
}
|
||||
const bindingTarget = getTargetOfBindingOrAssignmentElement(element);
|
||||
const bindingTarget = getTargetOfBindingOrAssignmentElement(element)!; // TODO: GH#18217
|
||||
if (isObjectBindingOrAssignmentPattern(bindingTarget)) {
|
||||
flattenObjectBindingOrAssignmentPattern(flattenContext, element, bindingTarget, value, location);
|
||||
flattenObjectBindingOrAssignmentPattern(flattenContext, element, bindingTarget, value!, location);
|
||||
}
|
||||
else if (isArrayBindingOrAssignmentPattern(bindingTarget)) {
|
||||
flattenArrayBindingOrAssignmentPattern(flattenContext, element, bindingTarget, value, location);
|
||||
flattenArrayBindingOrAssignmentPattern(flattenContext, element, bindingTarget, value!, location);
|
||||
}
|
||||
else {
|
||||
flattenContext.emitBindingOrAssignment(bindingTarget, value, location, /*original*/ element);
|
||||
flattenContext.emitBindingOrAssignment(bindingTarget, value!, location, /*original*/ element); // TODO: GH#18217
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,15 +300,15 @@ namespace ts {
|
||||
const reuseIdentifierExpressions = !isDeclarationBindingElement(parent) || numElements !== 0;
|
||||
value = ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location);
|
||||
}
|
||||
let bindingElements: BindingOrAssignmentElement[];
|
||||
let computedTempVariables: Expression[];
|
||||
let bindingElements: BindingOrAssignmentElement[] | undefined;
|
||||
let computedTempVariables: Expression[] | undefined;
|
||||
for (let i = 0; i < numElements; i++) {
|
||||
const element = elements[i];
|
||||
if (!getRestIndicatorOfBindingOrAssignmentElement(element)) {
|
||||
const propertyName = getPropertyNameOfBindingOrAssignmentElement(element);
|
||||
const propertyName = getPropertyNameOfBindingOrAssignmentElement(element)!;
|
||||
if (flattenContext.level >= FlattenLevel.ObjectRest
|
||||
&& !(element.transformFlags & (TransformFlags.ContainsRest | TransformFlags.ContainsObjectRest))
|
||||
&& !(getTargetOfBindingOrAssignmentElement(element).transformFlags & (TransformFlags.ContainsRest | TransformFlags.ContainsObjectRest))
|
||||
&& !(getTargetOfBindingOrAssignmentElement(element)!.transformFlags & (TransformFlags.ContainsRest | TransformFlags.ContainsObjectRest))
|
||||
&& !isComputedPropertyName(propertyName)) {
|
||||
bindingElements = append(bindingElements, element);
|
||||
}
|
||||
@@ -319,7 +319,7 @@ namespace ts {
|
||||
}
|
||||
const rhsValue = createDestructuringPropertyAccess(flattenContext, value, propertyName);
|
||||
if (isComputedPropertyName(propertyName)) {
|
||||
computedTempVariables = append(computedTempVariables, (rhsValue as ElementAccessExpression).argumentExpression);
|
||||
computedTempVariables = append<Expression>(computedTempVariables, (rhsValue as ElementAccessExpression).argumentExpression);
|
||||
}
|
||||
flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, /*location*/ element);
|
||||
}
|
||||
@@ -329,7 +329,7 @@ namespace ts {
|
||||
flattenContext.emitBindingOrAssignment(flattenContext.createObjectBindingOrAssignmentPattern(bindingElements), value, location, pattern);
|
||||
bindingElements = undefined;
|
||||
}
|
||||
const rhsValue = createRestCall(flattenContext.context, value, elements, computedTempVariables, pattern);
|
||||
const rhsValue = createRestCall(flattenContext.context, value, elements, computedTempVariables!, pattern); // TODO: GH#18217
|
||||
flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, element);
|
||||
}
|
||||
}
|
||||
@@ -377,8 +377,8 @@ namespace ts {
|
||||
const reuseIdentifierExpressions = !isDeclarationBindingElement(parent) || numElements !== 0;
|
||||
value = ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location);
|
||||
}
|
||||
let bindingElements: BindingOrAssignmentElement[];
|
||||
let restContainingElements: [Identifier, BindingOrAssignmentElement][];
|
||||
let bindingElements: BindingOrAssignmentElement[] | undefined;
|
||||
let restContainingElements: [Identifier, BindingOrAssignmentElement][] | undefined;
|
||||
for (let i = 0; i < numElements; i++) {
|
||||
const element = elements[i];
|
||||
if (flattenContext.level >= FlattenLevel.ObjectRest) {
|
||||
|
||||
+108
-110
@@ -159,7 +159,7 @@ namespace ts {
|
||||
ReplaceWithReturn,
|
||||
}
|
||||
|
||||
type LoopConverter = (node: IterationStatement, outermostLabeledStatement: LabeledStatement, convertedLoopBodyStatements: Statement[]) => Statement;
|
||||
type LoopConverter = (node: IterationStatement, outermostLabeledStatement: LabeledStatement | undefined, convertedLoopBodyStatements: Statement[] | undefined) => Statement;
|
||||
|
||||
// Facts we track as we traverse the tree
|
||||
const enum HierarchyFacts {
|
||||
@@ -286,7 +286,7 @@ namespace ts {
|
||||
/**
|
||||
* Used to track if we are emitting body of the converted loop
|
||||
*/
|
||||
let convertedLoopState: ConvertedLoopState;
|
||||
let convertedLoopState: ConvertedLoopState | undefined;
|
||||
|
||||
/**
|
||||
* Keeps track of whether substitutions have been enabled for specific cases.
|
||||
@@ -308,9 +308,9 @@ namespace ts {
|
||||
const visited = visitSourceFile(node);
|
||||
addEmitHelpers(visited, context.readEmitHelpers());
|
||||
|
||||
currentSourceFile = undefined;
|
||||
currentText = undefined;
|
||||
taggedTemplateStringDeclarations = undefined;
|
||||
currentSourceFile = undefined!;
|
||||
currentText = undefined!;
|
||||
taggedTemplateStringDeclarations = undefined!;
|
||||
hierarchyFacts = HierarchyFacts.None;
|
||||
return visited;
|
||||
}
|
||||
@@ -338,7 +338,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isReturnVoidStatementInConstructorWithCapturedSuper(node: Node): boolean {
|
||||
return hierarchyFacts & HierarchyFacts.ConstructorWithCapturedSuper
|
||||
return (hierarchyFacts & HierarchyFacts.ConstructorWithCapturedSuper) !== 0
|
||||
&& node.kind === SyntaxKind.ReturnStatement
|
||||
&& !(<ReturnStatement>node).expression;
|
||||
}
|
||||
@@ -520,7 +520,7 @@ namespace ts {
|
||||
const ancestorFacts = enterSubtree(HierarchyFacts.SourceFileExcludes, HierarchyFacts.SourceFileIncludes);
|
||||
const statements: Statement[] = [];
|
||||
startLexicalEnvironment();
|
||||
let statementOffset = addStandardPrologue(statements, node.statements, /*ensureUseStrict*/ false);
|
||||
let statementOffset: number | undefined = addStandardPrologue(statements, node.statements, /*ensureUseStrict*/ false);
|
||||
addCaptureThisForNodeIfNeeded(statements, node);
|
||||
statementOffset = addCustomPrologue(statements, node.statements, statementOffset, visitor);
|
||||
addRange(statements, visitNodes(node.statements, visitor, isStatement, statementOffset));
|
||||
@@ -541,7 +541,7 @@ namespace ts {
|
||||
if (convertedLoopState !== undefined) {
|
||||
const savedAllowedNonLabeledJumps = convertedLoopState.allowedNonLabeledJumps;
|
||||
// for switch statement allow only non-labeled break
|
||||
convertedLoopState.allowedNonLabeledJumps |= Jump.Break;
|
||||
convertedLoopState.allowedNonLabeledJumps! |= Jump.Break;
|
||||
const result = visitEachChild(node, visitor, context);
|
||||
convertedLoopState.allowedNonLabeledJumps = savedAllowedNonLabeledJumps;
|
||||
return result;
|
||||
@@ -562,7 +562,7 @@ namespace ts {
|
||||
|
||||
function visitReturnStatement(node: ReturnStatement): Statement {
|
||||
if (convertedLoopState) {
|
||||
convertedLoopState.nonLocalJumps |= Jump.Return;
|
||||
convertedLoopState.nonLocalJumps! |= Jump.Return;
|
||||
if (isReturnVoidStatementInConstructorWithCapturedSuper(node)) {
|
||||
node = returnCapturedThis(node);
|
||||
}
|
||||
@@ -619,45 +619,46 @@ namespace ts {
|
||||
const jump = node.kind === SyntaxKind.BreakStatement ? Jump.Break : Jump.Continue;
|
||||
const canUseBreakOrContinue =
|
||||
(node.label && convertedLoopState.labels && convertedLoopState.labels.get(idText(node.label))) ||
|
||||
(!node.label && (convertedLoopState.allowedNonLabeledJumps & jump));
|
||||
(!node.label && (convertedLoopState.allowedNonLabeledJumps! & jump));
|
||||
|
||||
if (!canUseBreakOrContinue) {
|
||||
let labelMarker: string;
|
||||
if (!node.label) {
|
||||
const label = node.label;
|
||||
if (!label) {
|
||||
if (node.kind === SyntaxKind.BreakStatement) {
|
||||
convertedLoopState.nonLocalJumps |= Jump.Break;
|
||||
convertedLoopState.nonLocalJumps! |= Jump.Break;
|
||||
labelMarker = "break";
|
||||
}
|
||||
else {
|
||||
convertedLoopState.nonLocalJumps |= Jump.Continue;
|
||||
convertedLoopState.nonLocalJumps! |= Jump.Continue;
|
||||
// note: return value is emitted only to simplify debugging, call to converted loop body does not do any dispatching on it.
|
||||
labelMarker = "continue";
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (node.kind === SyntaxKind.BreakStatement) {
|
||||
labelMarker = `break-${node.label.escapedText}`;
|
||||
setLabeledJump(convertedLoopState, /*isBreak*/ true, idText(node.label), labelMarker);
|
||||
labelMarker = `break-${label.escapedText}`;
|
||||
setLabeledJump(convertedLoopState, /*isBreak*/ true, idText(label), labelMarker);
|
||||
}
|
||||
else {
|
||||
labelMarker = `continue-${node.label.escapedText}`;
|
||||
setLabeledJump(convertedLoopState, /*isBreak*/ false, idText(node.label), labelMarker);
|
||||
labelMarker = `continue-${label.escapedText}`;
|
||||
setLabeledJump(convertedLoopState, /*isBreak*/ false, idText(label), labelMarker);
|
||||
}
|
||||
}
|
||||
let returnExpression: Expression = createLiteral(labelMarker);
|
||||
if (convertedLoopState.loopOutParameters.length) {
|
||||
const outParams = convertedLoopState.loopOutParameters;
|
||||
let expr: Expression;
|
||||
if (convertedLoopState.loopOutParameters!.length) {
|
||||
const outParams = convertedLoopState.loopOutParameters!;
|
||||
let expr: Expression | undefined;
|
||||
for (let i = 0; i < outParams.length; i++) {
|
||||
const copyExpr = copyOutParameter(outParams[i], CopyDirection.ToOutParameter);
|
||||
if (i === 0) {
|
||||
expr = copyExpr;
|
||||
}
|
||||
else {
|
||||
expr = createBinary(expr, SyntaxKind.CommaToken, copyExpr);
|
||||
expr = createBinary(expr!, SyntaxKind.CommaToken, copyExpr);
|
||||
}
|
||||
}
|
||||
returnExpression = createBinary(expr, SyntaxKind.CommaToken, returnExpression);
|
||||
returnExpression = createBinary(expr!, SyntaxKind.CommaToken, returnExpression);
|
||||
}
|
||||
return createReturn(returnExpression);
|
||||
}
|
||||
@@ -814,7 +815,7 @@ namespace ts {
|
||||
* @param node A ClassExpression or ClassDeclaration node.
|
||||
* @param extendsClauseElement The expression for the class `extends` clause.
|
||||
*/
|
||||
function transformClassBody(node: ClassExpression | ClassDeclaration, extendsClauseElement: ExpressionWithTypeArguments): Block {
|
||||
function transformClassBody(node: ClassExpression | ClassDeclaration, extendsClauseElement: ExpressionWithTypeArguments | undefined): Block {
|
||||
const statements: Statement[] = [];
|
||||
startLexicalEnvironment();
|
||||
addExtendsHelperIfNeeded(statements, node, extendsClauseElement);
|
||||
@@ -850,7 +851,7 @@ namespace ts {
|
||||
* @param node The ClassExpression or ClassDeclaration node.
|
||||
* @param extendsClauseElement The expression for the class `extends` clause.
|
||||
*/
|
||||
function addExtendsHelperIfNeeded(statements: Statement[], node: ClassExpression | ClassDeclaration, extendsClauseElement: ExpressionWithTypeArguments): void {
|
||||
function addExtendsHelperIfNeeded(statements: Statement[], node: ClassExpression | ClassDeclaration, extendsClauseElement: ExpressionWithTypeArguments | undefined): void {
|
||||
if (extendsClauseElement) {
|
||||
statements.push(
|
||||
setTextRange(
|
||||
@@ -870,7 +871,7 @@ namespace ts {
|
||||
* @param node The ClassExpression or ClassDeclaration node.
|
||||
* @param extendsClauseElement The expression for the class `extends` clause.
|
||||
*/
|
||||
function addConstructor(statements: Statement[], node: ClassExpression | ClassDeclaration, extendsClauseElement: ExpressionWithTypeArguments): void {
|
||||
function addConstructor(statements: Statement[], node: ClassExpression | ClassDeclaration, extendsClauseElement: ExpressionWithTypeArguments | undefined): void {
|
||||
const savedConvertedLoopState = convertedLoopState;
|
||||
convertedLoopState = undefined;
|
||||
const ancestorFacts = enterSubtree(HierarchyFacts.ConstructorExcludes, HierarchyFacts.ConstructorIncludes);
|
||||
@@ -904,13 +905,13 @@ namespace ts {
|
||||
* @param hasSynthesizedSuper A value indicating whether the constructor starts with a
|
||||
* synthesized `super` call.
|
||||
*/
|
||||
function transformConstructorParameters(constructor: ConstructorDeclaration, hasSynthesizedSuper: boolean) {
|
||||
function transformConstructorParameters(constructor: ConstructorDeclaration | undefined, hasSynthesizedSuper: boolean) {
|
||||
// If the TypeScript transformer needed to synthesize a constructor for property
|
||||
// initializers, it would have also added a synthetic `...args` parameter and
|
||||
// `super` call.
|
||||
// If this is the case, we do not include the synthetic `...args` parameter and
|
||||
// will instead use the `arguments` object in ES5/3.
|
||||
return visitParameterList(constructor && !hasSynthesizedSuper && constructor.parameters, visitor, context)
|
||||
return visitParameterList(constructor && !hasSynthesizedSuper ? constructor.parameters : undefined, visitor, context)
|
||||
|| <ParameterDeclaration[]>[];
|
||||
}
|
||||
|
||||
@@ -923,7 +924,7 @@ namespace ts {
|
||||
* @param hasSynthesizedSuper A value indicating whether the constructor starts with a
|
||||
* synthesized `super` call.
|
||||
*/
|
||||
function transformConstructorBody(constructor: ConstructorDeclaration | undefined, node: ClassDeclaration | ClassExpression, extendsClauseElement: ExpressionWithTypeArguments, hasSynthesizedSuper: boolean) {
|
||||
function transformConstructorBody(constructor: ConstructorDeclaration | undefined, node: ClassDeclaration | ClassExpression, extendsClauseElement: ExpressionWithTypeArguments | undefined, hasSynthesizedSuper: boolean) {
|
||||
const statements: Statement[] = [];
|
||||
resumeLexicalEnvironment();
|
||||
|
||||
@@ -935,7 +936,7 @@ namespace ts {
|
||||
statementOffset = 0;
|
||||
}
|
||||
else if (constructor) {
|
||||
statementOffset = addStandardPrologue(statements, constructor.body.statements, /*ensureUseStrict*/ false);
|
||||
statementOffset = addStandardPrologue(statements, constructor.body!.statements, /*ensureUseStrict*/ false);
|
||||
}
|
||||
|
||||
if (constructor) {
|
||||
@@ -943,7 +944,7 @@ namespace ts {
|
||||
addRestParameterIfNeeded(statements, constructor, hasSynthesizedSuper);
|
||||
if (!hasSynthesizedSuper) {
|
||||
// If no super call has been synthesized, emit custom prologue directives.
|
||||
statementOffset = addCustomPrologue(statements, constructor.body.statements, statementOffset, visitor);
|
||||
statementOffset = addCustomPrologue(statements, constructor.body!.statements, statementOffset, visitor);
|
||||
}
|
||||
Debug.assert(statementOffset >= 0, "statementOffset not initialized correctly!");
|
||||
|
||||
@@ -951,7 +952,7 @@ namespace ts {
|
||||
|
||||
// determine whether the class is known syntactically to be a derived class (e.g. a
|
||||
// class that extends a value that is not syntactically known to be `null`).
|
||||
const isDerivedClass = extendsClauseElement && skipOuterExpressions(extendsClauseElement.expression).kind !== SyntaxKind.NullKeyword;
|
||||
const isDerivedClass = !!extendsClauseElement && skipOuterExpressions(extendsClauseElement.expression).kind !== SyntaxKind.NullKeyword;
|
||||
const superCaptureStatus = declareOrCaptureOrReturnThisForConstructorIfNeeded(statements, constructor, isDerivedClass, hasSynthesizedSuper, statementOffset);
|
||||
|
||||
// The last statement expression was replaced. Skip it.
|
||||
@@ -964,14 +965,14 @@ namespace ts {
|
||||
hierarchyFacts |= HierarchyFacts.ConstructorWithCapturedSuper;
|
||||
}
|
||||
|
||||
addRange(statements, visitNodes(constructor.body.statements, visitor, isStatement, /*start*/ statementOffset));
|
||||
addRange(statements, visitNodes(constructor.body!.statements, visitor, isStatement, /*start*/ statementOffset));
|
||||
}
|
||||
|
||||
// Return `_this` unless we're sure enough that it would be pointless to add a return statement.
|
||||
// If there's a constructor that we can tell returns in enough places, then we *do not* want to add a return.
|
||||
if (isDerivedClass
|
||||
&& superCaptureStatus !== SuperCaptureResult.ReplaceWithReturn
|
||||
&& !(constructor && isSufficientlyCoveredByReturnStatements(constructor.body))) {
|
||||
&& !(constructor && isSufficientlyCoveredByReturnStatements(constructor.body!))) {
|
||||
statements.push(
|
||||
createReturn(
|
||||
createFileLevelUniqueName("_this")
|
||||
@@ -990,7 +991,7 @@ namespace ts {
|
||||
createNodeArray(
|
||||
statements
|
||||
),
|
||||
/*location*/ constructor ? constructor.body.statements : node.members
|
||||
/*location*/ constructor ? constructor.body!.statements : node.members
|
||||
),
|
||||
/*multiLine*/ true
|
||||
);
|
||||
@@ -1085,10 +1086,10 @@ namespace ts {
|
||||
//
|
||||
// return _super.call(...) || this;
|
||||
//
|
||||
let firstStatement: Statement;
|
||||
let superCallExpression: Expression;
|
||||
let firstStatement: Statement | undefined;
|
||||
let superCallExpression: Expression | undefined;
|
||||
|
||||
const ctorStatements = ctor.body.statements;
|
||||
const ctorStatements = ctor.body!.statements;
|
||||
if (statementOffset < ctorStatements.length) {
|
||||
firstStatement = ctorStatements[statementOffset];
|
||||
|
||||
@@ -1156,7 +1157,7 @@ namespace ts {
|
||||
*
|
||||
* @param node A ParameterDeclaration node.
|
||||
*/
|
||||
function visitParameter(node: ParameterDeclaration): ParameterDeclaration {
|
||||
function visitParameter(node: ParameterDeclaration): ParameterDeclaration | undefined {
|
||||
if (node.dotDotDotToken) {
|
||||
// rest parameters are elided
|
||||
return undefined;
|
||||
@@ -1251,7 +1252,7 @@ namespace ts {
|
||||
* @param name The name of the parameter.
|
||||
* @param initializer The initializer for the parameter.
|
||||
*/
|
||||
function addDefaultValueAssignmentForBindingPattern(statements: Statement[], parameter: ParameterDeclaration, name: BindingPattern, initializer: Expression): void {
|
||||
function addDefaultValueAssignmentForBindingPattern(statements: Statement[], parameter: ParameterDeclaration, name: BindingPattern, initializer: Expression | undefined): void {
|
||||
const temp = getGeneratedNameForNode(parameter);
|
||||
|
||||
// In cases where a binding pattern is simply '[]' or '{}',
|
||||
@@ -1339,7 +1340,7 @@ namespace ts {
|
||||
* part of a constructor declaration with a
|
||||
* synthesized call to `super`
|
||||
*/
|
||||
function shouldAddRestParameter(node: ParameterDeclaration, inConstructorWithSynthesizedSuper: boolean) {
|
||||
function shouldAddRestParameter(node: ParameterDeclaration | undefined, inConstructorWithSynthesizedSuper: boolean) {
|
||||
return node && node.dotDotDotToken && node.name.kind === SyntaxKind.Identifier && !inConstructorWithSynthesizedSuper;
|
||||
}
|
||||
|
||||
@@ -1359,11 +1360,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
// `declarationName` is the name of the local declaration for the parameter.
|
||||
const declarationName = getMutableClone(<Identifier>parameter.name);
|
||||
const declarationName = getMutableClone(<Identifier>parameter!.name);
|
||||
setEmitFlags(declarationName, EmitFlags.NoSourceMap);
|
||||
|
||||
// `expressionName` is the name of the parameter used in expressions.
|
||||
const expressionName = getSynthesizedClone(<Identifier>parameter.name);
|
||||
const expressionName = getSynthesizedClone(<Identifier>parameter!.name);
|
||||
const restIndex = node.parameters.length - 1;
|
||||
const temp = createLoopVariable();
|
||||
|
||||
@@ -1640,7 +1641,7 @@ namespace ts {
|
||||
// arguments are both mapped contiguously to the accessor name.
|
||||
const target = getMutableClone(receiver);
|
||||
setEmitFlags(target, EmitFlags.NoComments | EmitFlags.NoTrailingSourceMap);
|
||||
setSourceMapRange(target, firstAccessor.name);
|
||||
setSourceMapRange(target, firstAccessor.name); // TODO: GH#18217
|
||||
|
||||
const propertyName = createExpressionForPropertyName(visitNode(firstAccessor.name, visitor, isPropertyName));
|
||||
setEmitFlags(propertyName, EmitFlags.NoComments | EmitFlags.NoLeadingSourceMap);
|
||||
@@ -1789,7 +1790,7 @@ namespace ts {
|
||||
* @param location The source-map location for the new FunctionExpression.
|
||||
* @param name The name of the new FunctionExpression.
|
||||
*/
|
||||
function transformFunctionLikeToExpression(node: FunctionLikeDeclaration, location: TextRange, name: Identifier, container: Node): FunctionExpression {
|
||||
function transformFunctionLikeToExpression(node: FunctionLikeDeclaration, location: TextRange | undefined, name: Identifier | undefined, container: Node | undefined): FunctionExpression {
|
||||
const savedConvertedLoopState = convertedLoopState;
|
||||
convertedLoopState = undefined;
|
||||
const ancestorFacts = container && isClassLike(container) && !hasModifier(node, ModifierFlags.Static)
|
||||
@@ -1829,11 +1830,11 @@ namespace ts {
|
||||
let multiLine = false; // indicates whether the block *must* be emitted as multiple lines
|
||||
let singleLine = false; // indicates whether the block *may* be emitted as a single line
|
||||
let statementsLocation: TextRange;
|
||||
let closeBraceLocation: TextRange;
|
||||
let closeBraceLocation: TextRange | undefined;
|
||||
|
||||
const statements: Statement[] = [];
|
||||
const body = node.body;
|
||||
let statementOffset: number;
|
||||
const body = node.body!;
|
||||
let statementOffset: number | undefined;
|
||||
|
||||
resumeLexicalEnvironment();
|
||||
if (isBlock(body)) {
|
||||
@@ -1919,7 +1920,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function visitFunctionBodyDownLevel(node: FunctionDeclaration | FunctionExpression | AccessorDeclaration) {
|
||||
const updated = visitFunctionBody(node.body, functionBodyVisitor, context);
|
||||
const updated = visitFunctionBody(node.body, functionBodyVisitor, context)!;
|
||||
return updateBlock(
|
||||
updated,
|
||||
setTextRange(
|
||||
@@ -2003,12 +2004,12 @@ namespace ts {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function visitVariableStatement(node: VariableStatement): Statement {
|
||||
function visitVariableStatement(node: VariableStatement): Statement | undefined {
|
||||
const ancestorFacts = enterSubtree(HierarchyFacts.None, hasModifier(node, ModifierFlags.Export) ? HierarchyFacts.ExportedVariableStatement : HierarchyFacts.None);
|
||||
let updated: Statement;
|
||||
let updated: Statement | undefined;
|
||||
if (convertedLoopState && (node.declarationList.flags & NodeFlags.BlockScoped) === 0) {
|
||||
// we are inside a converted loop - hoist variable declarations
|
||||
let assignments: Expression[];
|
||||
let assignments: Expression[] | undefined;
|
||||
for (const decl of node.declarationList.declarations) {
|
||||
hoistVariableDeclarationDeclaredInConvertedLoop(convertedLoopState, decl);
|
||||
if (decl.initializer) {
|
||||
@@ -2066,13 +2067,12 @@ namespace ts {
|
||||
setCommentRange(declarationList, node);
|
||||
|
||||
if (node.transformFlags & TransformFlags.ContainsBindingPattern
|
||||
&& (isBindingPattern(node.declarations[0].name) || isBindingPattern(lastOrUndefined(node.declarations).name))) {
|
||||
&& (isBindingPattern(node.declarations[0].name) || isBindingPattern(last(node.declarations).name))) {
|
||||
// If the first or last declaration is a binding pattern, we need to modify
|
||||
// the source map range for the declaration list.
|
||||
const firstDeclaration = firstOrUndefined(declarations);
|
||||
if (firstDeclaration) {
|
||||
const lastDeclaration = lastOrUndefined(declarations);
|
||||
setSourceMapRange(declarationList, createRange(firstDeclaration.pos, lastDeclaration.end));
|
||||
setSourceMapRange(declarationList, createRange(firstDeclaration.pos, last(declarations).end));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2198,11 +2198,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
function recordLabel(node: LabeledStatement) {
|
||||
convertedLoopState.labels.set(idText(node.label), true);
|
||||
convertedLoopState!.labels!.set(idText(node.label), true);
|
||||
}
|
||||
|
||||
function resetLabel(node: LabeledStatement) {
|
||||
convertedLoopState.labels.set(idText(node.label), false);
|
||||
convertedLoopState!.labels!.set(idText(node.label), false);
|
||||
}
|
||||
|
||||
function visitLabeledStatement(node: LabeledStatement): VisitResult<Statement> {
|
||||
@@ -2229,14 +2229,14 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function visitIterationStatementWithFacts(excludeFacts: HierarchyFacts, includeFacts: HierarchyFacts, node: IterationStatement, outermostLabeledStatement: LabeledStatement, convert?: LoopConverter) {
|
||||
function visitIterationStatementWithFacts(excludeFacts: HierarchyFacts, includeFacts: HierarchyFacts, node: IterationStatement, outermostLabeledStatement: LabeledStatement | undefined, convert?: LoopConverter) {
|
||||
const ancestorFacts = enterSubtree(excludeFacts, includeFacts);
|
||||
const updated = convertIterationStatementBodyIfNecessary(node, outermostLabeledStatement, convert);
|
||||
exitSubtree(ancestorFacts, HierarchyFacts.None, HierarchyFacts.None);
|
||||
return updated;
|
||||
}
|
||||
|
||||
function visitDoOrWhileStatement(node: DoStatement | WhileStatement, outermostLabeledStatement: LabeledStatement) {
|
||||
function visitDoOrWhileStatement(node: DoStatement | WhileStatement, outermostLabeledStatement: LabeledStatement | undefined) {
|
||||
return visitIterationStatementWithFacts(
|
||||
HierarchyFacts.DoOrWhileStatementExcludes,
|
||||
HierarchyFacts.DoOrWhileStatementIncludes,
|
||||
@@ -2244,7 +2244,7 @@ namespace ts {
|
||||
outermostLabeledStatement);
|
||||
}
|
||||
|
||||
function visitForStatement(node: ForStatement, outermostLabeledStatement: LabeledStatement) {
|
||||
function visitForStatement(node: ForStatement, outermostLabeledStatement: LabeledStatement | undefined) {
|
||||
return visitIterationStatementWithFacts(
|
||||
HierarchyFacts.ForStatementExcludes,
|
||||
HierarchyFacts.ForStatementIncludes,
|
||||
@@ -2252,7 +2252,7 @@ namespace ts {
|
||||
outermostLabeledStatement);
|
||||
}
|
||||
|
||||
function visitForInStatement(node: ForInStatement, outermostLabeledStatement: LabeledStatement) {
|
||||
function visitForInStatement(node: ForInStatement, outermostLabeledStatement: LabeledStatement | undefined) {
|
||||
return visitIterationStatementWithFacts(
|
||||
HierarchyFacts.ForInOrForOfStatementExcludes,
|
||||
HierarchyFacts.ForInOrForOfStatementIncludes,
|
||||
@@ -2260,7 +2260,7 @@ namespace ts {
|
||||
outermostLabeledStatement);
|
||||
}
|
||||
|
||||
function visitForOfStatement(node: ForOfStatement, outermostLabeledStatement: LabeledStatement): VisitResult<Statement> {
|
||||
function visitForOfStatement(node: ForOfStatement, outermostLabeledStatement: LabeledStatement | undefined): VisitResult<Statement> {
|
||||
return visitIterationStatementWithFacts(
|
||||
HierarchyFacts.ForInOrForOfStatementExcludes,
|
||||
HierarchyFacts.ForInOrForOfStatementIncludes,
|
||||
@@ -2271,12 +2271,13 @@ namespace ts {
|
||||
|
||||
function convertForOfStatementHead(node: ForOfStatement, boundValue: Expression, convertedLoopBodyStatements: Statement[]) {
|
||||
const statements: Statement[] = [];
|
||||
if (isVariableDeclarationList(node.initializer)) {
|
||||
const initializer = node.initializer;
|
||||
if (isVariableDeclarationList(initializer)) {
|
||||
if (node.initializer.flags & NodeFlags.BlockScoped) {
|
||||
enableSubstitutionsForBlockScopedBindings();
|
||||
}
|
||||
|
||||
const firstOriginalDeclaration = firstOrUndefined(node.initializer.declarations);
|
||||
const firstOriginalDeclaration = firstOrUndefined(initializer.declarations);
|
||||
if (firstOriginalDeclaration && isBindingPattern(firstOriginalDeclaration.name)) {
|
||||
// This works whether the declaration is a var, let, or const.
|
||||
// It will use rhsIterationValue _a[_i] as the initializer.
|
||||
@@ -2293,9 +2294,7 @@ namespace ts {
|
||||
|
||||
// Adjust the source map range for the first declaration to align with the old
|
||||
// emitter.
|
||||
const firstDeclaration = declarations[0];
|
||||
const lastDeclaration = lastOrUndefined(declarations);
|
||||
setSourceMapRange(declarationList, createRange(firstDeclaration.pos, lastDeclaration.end));
|
||||
setSourceMapRange(declarationList, createRange(declarations[0].pos, last(declarations).end));
|
||||
|
||||
statements.push(
|
||||
createVariableStatement(
|
||||
@@ -2320,12 +2319,12 @@ namespace ts {
|
||||
boundValue
|
||||
)
|
||||
]),
|
||||
moveRangePos(node.initializer, -1)
|
||||
moveRangePos(initializer, -1)
|
||||
),
|
||||
node.initializer
|
||||
initializer
|
||||
)
|
||||
),
|
||||
moveRangeEnd(node.initializer, -1)
|
||||
moveRangeEnd(initializer, -1)
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -2333,14 +2332,14 @@ namespace ts {
|
||||
else {
|
||||
// Initializer is an expression. Emit the expression in the body, so that it's
|
||||
// evaluated on every iteration.
|
||||
const assignment = createAssignment(node.initializer, boundValue);
|
||||
const assignment = createAssignment(initializer, boundValue);
|
||||
if (isDestructuringAssignment(assignment)) {
|
||||
aggregateTransformFlags(assignment);
|
||||
statements.push(createStatement(visitBinaryExpression(assignment, /*needsDestructuringValue*/ false)));
|
||||
}
|
||||
else {
|
||||
assignment.end = node.initializer.end;
|
||||
statements.push(setTextRange(createStatement(visitNode(assignment, visitor, isExpression)), moveRangeEnd(node.initializer, -1)));
|
||||
assignment.end = initializer.end;
|
||||
statements.push(setTextRange(createStatement(visitNode(assignment, visitor, isExpression)), moveRangeEnd(initializer, -1)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2565,7 +2564,7 @@ namespace ts {
|
||||
&& i < numInitialPropertiesWithoutYield) {
|
||||
numInitialPropertiesWithoutYield = i;
|
||||
}
|
||||
if (property.name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
if (property.name!.kind === SyntaxKind.ComputedPropertyName) {
|
||||
numInitialProperties = i;
|
||||
break;
|
||||
}
|
||||
@@ -2625,7 +2624,7 @@ namespace ts {
|
||||
|
||||
function visit(node: Identifier | BindingPattern) {
|
||||
if (node.kind === SyntaxKind.Identifier) {
|
||||
state.hoistedLocalVariables.push(node);
|
||||
state.hoistedLocalVariables!.push(node);
|
||||
}
|
||||
else {
|
||||
for (const element of node.elements) {
|
||||
@@ -2637,9 +2636,9 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function convertIterationStatementBodyIfNecessary(node: IterationStatement, outermostLabeledStatement: LabeledStatement, convert?: LoopConverter): VisitResult<Statement> {
|
||||
function convertIterationStatementBodyIfNecessary(node: IterationStatement, outermostLabeledStatement: LabeledStatement | undefined, convert?: LoopConverter): VisitResult<Statement> {
|
||||
if (!shouldConvertIterationStatementBody(node)) {
|
||||
let saveAllowedNonLabeledJumps: Jump;
|
||||
let saveAllowedNonLabeledJumps: Jump | undefined;
|
||||
if (convertedLoopState) {
|
||||
// we get here if we are trying to emit normal loop loop inside converted loop
|
||||
// set allowedNonLabeledJumps to Break | Continue to mark that break\continue inside the loop should be emitted as is
|
||||
@@ -2658,7 +2657,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
const functionName = createUniqueName("_loop");
|
||||
let loopInitializer: VariableDeclarationList;
|
||||
let loopInitializer: VariableDeclarationList | undefined;
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ForStatement:
|
||||
case SyntaxKind.ForInStatement:
|
||||
@@ -2766,7 +2765,7 @@ namespace ts {
|
||||
|
||||
const statements: Statement[] = [convertedLoopVariable];
|
||||
|
||||
let extraVariableDeclarations: VariableDeclaration[];
|
||||
let extraVariableDeclarations: VariableDeclaration[] | undefined;
|
||||
// propagate state from the inner loop to the outer loop if necessary
|
||||
if (currentState.argumentsName) {
|
||||
// if alias for arguments is set
|
||||
@@ -2851,7 +2850,7 @@ namespace ts {
|
||||
else {
|
||||
let clone = getMutableClone(node);
|
||||
// clean statement part
|
||||
clone.statement = undefined;
|
||||
clone.statement = undefined!;
|
||||
// visit childnodes to transform initializer/condition/incrementor parts
|
||||
clone = visitEachChild(clone, visitor, context);
|
||||
// set loop statement
|
||||
@@ -2886,7 +2885,7 @@ namespace ts {
|
||||
// simple loops are emitted as just 'loop()';
|
||||
// NOTE: if loop uses only 'continue' it still will be emitted as simple loop
|
||||
const isSimpleLoop =
|
||||
!(state.nonLocalJumps & ~Jump.Continue) &&
|
||||
!(state.nonLocalJumps! & ~Jump.Continue) &&
|
||||
!state.labeledNonLocalBreaks &&
|
||||
!state.labeledNonLocalContinues;
|
||||
|
||||
@@ -2899,7 +2898,7 @@ namespace ts {
|
||||
: call;
|
||||
if (isSimpleLoop) {
|
||||
statements.push(createStatement(callResult));
|
||||
copyOutParameters(state.loopOutParameters, CopyDirection.ToOriginal, statements);
|
||||
copyOutParameters(state.loopOutParameters!, CopyDirection.ToOriginal, statements);
|
||||
}
|
||||
else {
|
||||
const loopResultName = createUniqueName("state");
|
||||
@@ -2910,12 +2909,12 @@ namespace ts {
|
||||
)
|
||||
);
|
||||
statements.push(stateVariable);
|
||||
copyOutParameters(state.loopOutParameters, CopyDirection.ToOriginal, statements);
|
||||
copyOutParameters(state.loopOutParameters!, CopyDirection.ToOriginal, statements);
|
||||
|
||||
if (state.nonLocalJumps & Jump.Return) {
|
||||
if (state.nonLocalJumps! & Jump.Return) {
|
||||
let returnStatement: ReturnStatement;
|
||||
if (outerConvertedLoopState) {
|
||||
outerConvertedLoopState.nonLocalJumps |= Jump.Return;
|
||||
outerConvertedLoopState.nonLocalJumps! |= Jump.Return;
|
||||
returnStatement = createReturn(loopResultName);
|
||||
}
|
||||
else {
|
||||
@@ -2933,7 +2932,7 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
if (state.nonLocalJumps & Jump.Break) {
|
||||
if (state.nonLocalJumps! & Jump.Break) {
|
||||
statements.push(
|
||||
createIf(
|
||||
createBinary(
|
||||
@@ -2948,8 +2947,8 @@ namespace ts {
|
||||
|
||||
if (state.labeledNonLocalBreaks || state.labeledNonLocalContinues) {
|
||||
const caseClauses: CaseClause[] = [];
|
||||
processLabeledJumps(state.labeledNonLocalBreaks, /*isBreak*/ true, loopResultName, outerConvertedLoopState, caseClauses);
|
||||
processLabeledJumps(state.labeledNonLocalContinues, /*isBreak*/ false, loopResultName, outerConvertedLoopState, caseClauses);
|
||||
processLabeledJumps(state.labeledNonLocalBreaks!, /*isBreak*/ true, loopResultName, outerConvertedLoopState, caseClauses);
|
||||
processLabeledJumps(state.labeledNonLocalContinues!, /*isBreak*/ false, loopResultName, outerConvertedLoopState, caseClauses);
|
||||
statements.push(
|
||||
createSwitch(
|
||||
loopResultName,
|
||||
@@ -2976,7 +2975,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function processLabeledJumps(table: Map<string>, isBreak: boolean, loopResultName: Identifier, outerLoop: ConvertedLoopState, caseClauses: CaseClause[]): void {
|
||||
function processLabeledJumps(table: Map<string>, isBreak: boolean, loopResultName: Identifier, outerLoop: ConvertedLoopState | undefined, caseClauses: CaseClause[]): void {
|
||||
if (!table) {
|
||||
return;
|
||||
}
|
||||
@@ -3034,21 +3033,21 @@ namespace ts {
|
||||
case SyntaxKind.SetAccessor:
|
||||
const accessors = getAllAccessorDeclarations(node.properties, property);
|
||||
if (property === accessors.firstAccessor) {
|
||||
expressions.push(transformAccessorsToExpression(receiver, accessors, node, node.multiLine));
|
||||
expressions.push(transformAccessorsToExpression(receiver, accessors, node, !!node.multiLine));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
expressions.push(transformObjectLiteralMethodDeclarationToExpression(property, receiver, node, node.multiLine));
|
||||
expressions.push(transformObjectLiteralMethodDeclarationToExpression(property, receiver, node, node.multiLine!));
|
||||
break;
|
||||
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
expressions.push(transformPropertyAssignmentToExpression(property, receiver, node.multiLine));
|
||||
expressions.push(transformPropertyAssignmentToExpression(property, receiver, node.multiLine!));
|
||||
break;
|
||||
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
expressions.push(transformShorthandPropertyAssignmentToExpression(property, receiver, node.multiLine));
|
||||
expressions.push(transformShorthandPropertyAssignmentToExpression(property, receiver, node.multiLine!));
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -3130,12 +3129,12 @@ namespace ts {
|
||||
const ancestorFacts = enterSubtree(HierarchyFacts.BlockScopeExcludes, HierarchyFacts.BlockScopeIncludes);
|
||||
let updated: CatchClause;
|
||||
Debug.assert(!!node.variableDeclaration, "Catch clause variable should always be present when downleveling ES2015.");
|
||||
if (isBindingPattern(node.variableDeclaration.name)) {
|
||||
if (isBindingPattern(node.variableDeclaration!.name)) {
|
||||
const temp = createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const newVariableDeclaration = createVariableDeclaration(temp);
|
||||
setTextRange(newVariableDeclaration, node.variableDeclaration);
|
||||
const vars = flattenDestructuringBinding(
|
||||
node.variableDeclaration,
|
||||
node.variableDeclaration!,
|
||||
visitor,
|
||||
context,
|
||||
FlattenLevel.All,
|
||||
@@ -3247,7 +3246,7 @@ namespace ts {
|
||||
function visitArrayLiteralExpression(node: ArrayLiteralExpression): Expression {
|
||||
if (node.transformFlags & TransformFlags.ES2015) {
|
||||
// We are here because we contain a SpreadElementExpression.
|
||||
return transformAndSpreadElements(node.elements, /*needsUniqueCopy*/ true, node.multiLine, /*hasTrailingComma*/ node.elements.hasTrailingComma);
|
||||
return transformAndSpreadElements(node.elements, /*needsUniqueCopy*/ true, !!node.multiLine, /*hasTrailingComma*/ !!node.elements.hasTrailingComma);
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
@@ -3312,16 +3311,16 @@ namespace ts {
|
||||
|
||||
// The class statements are the statements generated by visiting the first statement with initializer of the
|
||||
// body (1), while all other statements are added to remainingStatements (2)
|
||||
const isVariableStatementWithInitializer = (stmt: Statement) => isVariableStatement(stmt) && !!firstOrUndefined(stmt.declarationList.declarations).initializer;
|
||||
const isVariableStatementWithInitializer = (stmt: Statement) => isVariableStatement(stmt) && !!first(stmt.declarationList.declarations).initializer;
|
||||
const bodyStatements = visitNodes(body.statements, visitor, isStatement);
|
||||
const classStatements = filter(bodyStatements, isVariableStatementWithInitializer);
|
||||
const remainingStatements = filter(bodyStatements, stmt => !isVariableStatementWithInitializer(stmt));
|
||||
const varStatement = cast(firstOrUndefined(classStatements), isVariableStatement);
|
||||
const varStatement = cast(first(classStatements), isVariableStatement);
|
||||
|
||||
// We know there is only one variable declaration here as we verified this in an
|
||||
// earlier call to isTypeScriptClassWrapper
|
||||
const variable = varStatement.declarationList.declarations[0];
|
||||
const initializer = skipOuterExpressions(variable.initializer);
|
||||
const initializer = skipOuterExpressions(variable.initializer!);
|
||||
|
||||
// Under certain conditions, the 'ts' transformer may introduce a class alias, which
|
||||
// we see as an assignment, for example:
|
||||
@@ -3374,7 +3373,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Find the trailing 'return' statement (4)
|
||||
while (!isReturnStatement(elementAt(funcStatements, classBodyEnd))) {
|
||||
while (!isReturnStatement(elementAt(funcStatements, classBodyEnd)!)) {
|
||||
classBodyEnd--;
|
||||
}
|
||||
|
||||
@@ -3517,7 +3516,7 @@ namespace ts {
|
||||
createFunctionApply(
|
||||
visitNode(target, visitor, isExpression),
|
||||
thisArg,
|
||||
transformAndSpreadElements(createNodeArray([createVoidZero(), ...node.arguments]), /*needsUniqueCopy*/ false, /*multiLine*/ false, /*hasTrailingComma*/ false)
|
||||
transformAndSpreadElements(createNodeArray([createVoidZero(), ...node.arguments!]), /*needsUniqueCopy*/ false, /*multiLine*/ false, /*hasTrailingComma*/ false)
|
||||
),
|
||||
/*typeArguments*/ undefined,
|
||||
[]
|
||||
@@ -3571,7 +3570,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Rewrite using the pattern <segment0>.concat(<segment1>, <segment2>, ...)
|
||||
return createArrayConcat(segments.shift(), segments);
|
||||
return createArrayConcat(segments.shift()!, segments);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3650,7 +3649,7 @@ namespace ts {
|
||||
// Build up the template arguments and the raw and cooked strings for the template.
|
||||
// We start out with 'undefined' for the first argument and revisit later
|
||||
// to avoid walking over the template string twice and shifting all our arguments over after the fact.
|
||||
const templateArguments: Expression[] = [undefined];
|
||||
const templateArguments: Expression[] = [undefined!];
|
||||
const cookedStrings: Expression[] = [];
|
||||
const rawStrings: Expression[] = [];
|
||||
const template = node.template;
|
||||
@@ -3734,7 +3733,7 @@ namespace ts {
|
||||
// ("abc" + 1) << (2 + "")
|
||||
// rather than
|
||||
// "abc" + (1 << 2) + ""
|
||||
const expression = reduceLeft(expressions, createAdd);
|
||||
const expression = reduceLeft(expressions, createAdd)!;
|
||||
if (nodeIsSynthesized(expression)) {
|
||||
expression.pos = node.pos;
|
||||
expression.end = node.end;
|
||||
@@ -3921,14 +3920,13 @@ namespace ts {
|
||||
* @param node An original source tree node.
|
||||
*/
|
||||
function isNameOfDeclarationWithCollidingName(node: Identifier) {
|
||||
const parent = node.parent;
|
||||
switch (parent.kind) {
|
||||
switch (node.parent.kind) {
|
||||
case SyntaxKind.BindingElement:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
return (<NamedDeclaration>parent).name === node
|
||||
&& resolver.isDeclarationWithCollidingName(<Declaration>parent);
|
||||
return (<NamedDeclaration>node.parent).name === node
|
||||
&& resolver.isDeclarationWithCollidingName(<Declaration>node.parent);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -3968,7 +3966,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isPartOfClassBody(declaration: ClassLikeDeclaration, node: Identifier) {
|
||||
let currentNode = getParseTreeNode(node);
|
||||
let currentNode: Node | undefined = getParseTreeNode(node);
|
||||
if (!currentNode || currentNode === declaration || currentNode.end <= declaration.pos || currentNode.pos >= declaration.end) {
|
||||
// if the node has no correlation to a parse tree node, its definitely not
|
||||
// part of the body.
|
||||
@@ -4010,7 +4008,7 @@ namespace ts {
|
||||
: createPropertyAccess(getInternalName(node), "prototype");
|
||||
}
|
||||
|
||||
function hasSynthesizedDefaultSuperCall(constructor: ConstructorDeclaration, hasExtendsClause: boolean) {
|
||||
function hasSynthesizedDefaultSuperCall(constructor: ConstructorDeclaration | undefined, hasExtendsClause: boolean) {
|
||||
if (!constructor || !hasExtendsClause) {
|
||||
return false;
|
||||
}
|
||||
@@ -4019,7 +4017,7 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
const statement = firstOrUndefined(constructor.body.statements);
|
||||
const statement = firstOrUndefined(constructor.body!.statements);
|
||||
if (!statement || !nodeIsSynthesized(statement) || statement.kind !== SyntaxKind.ExpressionStatement) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -116,10 +116,10 @@ namespace ts {
|
||||
|
||||
function visitCatchClauseInAsyncBody(node: CatchClause) {
|
||||
const catchClauseNames = createUnderscoreEscapedMap<true>();
|
||||
recordDeclarationName(node.variableDeclaration, catchClauseNames);
|
||||
recordDeclarationName(node.variableDeclaration!, catchClauseNames); // TODO: GH#18217
|
||||
|
||||
// names declared in a catch variable are block scoped
|
||||
let catchClauseUnshadowedNames: UnderscoreEscapedMap<true>;
|
||||
let catchClauseUnshadowedNames: UnderscoreEscapedMap<true> | undefined;
|
||||
catchClauseNames.forEach((_, escapedName) => {
|
||||
if (enclosingFunctionParameterNames.has(escapedName)) {
|
||||
if (!catchClauseUnshadowedNames) {
|
||||
@@ -153,7 +153,7 @@ namespace ts {
|
||||
return updateForIn(
|
||||
node,
|
||||
isVariableDeclarationListWithCollidingName(node.initializer)
|
||||
? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ true)
|
||||
? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ true)!
|
||||
: visitNode(node.initializer, visitor, isForInitializer),
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
visitNode(node.statement, asyncBodyVisitor, isStatement, liftToBlock)
|
||||
@@ -165,7 +165,7 @@ namespace ts {
|
||||
node,
|
||||
visitNode(node.awaitModifier, visitor, isToken),
|
||||
isVariableDeclarationListWithCollidingName(node.initializer)
|
||||
? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ true)
|
||||
? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ true)!
|
||||
: visitNode(node.initializer, visitor, isForInitializer),
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
visitNode(node.statement, asyncBodyVisitor, isStatement, liftToBlock)
|
||||
@@ -173,10 +173,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
function visitForStatementInAsyncBody(node: ForStatement) {
|
||||
const initializer = node.initializer!; // TODO: GH#18217
|
||||
return updateFor(
|
||||
node,
|
||||
isVariableDeclarationListWithCollidingName(node.initializer)
|
||||
? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ false)
|
||||
isVariableDeclarationListWithCollidingName(initializer)
|
||||
? visitVariableDeclarationListWithCollidingNames(initializer, /*hasReceiver*/ false)
|
||||
: visitNode(node.initializer, visitor, isForInitializer),
|
||||
visitNode(node.condition, visitor, isExpression),
|
||||
visitNode(node.incrementor, visitor, isExpression),
|
||||
@@ -312,10 +313,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isVariableDeclarationListWithCollidingName(node: ForInitializer): node is VariableDeclarationList {
|
||||
return node
|
||||
return !!node
|
||||
&& isVariableDeclarationList(node)
|
||||
&& !(node.flags & NodeFlags.BlockScoped)
|
||||
&& forEach(node.declarations, collidesWithParameterName);
|
||||
&& node.declarations.some(collidesWithParameterName);
|
||||
}
|
||||
|
||||
function visitVariableDeclarationListWithCollidingNames(node: VariableDeclarationList, hasReceiver: boolean) {
|
||||
@@ -353,7 +354,7 @@ namespace ts {
|
||||
const converted = setSourceMapRange(
|
||||
createAssignment(
|
||||
convertToAssignmentElementTarget(node.name),
|
||||
node.initializer
|
||||
node.initializer!
|
||||
),
|
||||
node
|
||||
);
|
||||
@@ -437,7 +438,7 @@ namespace ts {
|
||||
context,
|
||||
hasLexicalArguments,
|
||||
promiseConstructor,
|
||||
transformAsyncFunctionBodyWorker(node.body)
|
||||
transformAsyncFunctionBodyWorker(node.body!)
|
||||
);
|
||||
|
||||
const declarations = endLexicalEnvironment();
|
||||
@@ -463,7 +464,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getPromiseConstructor(type: TypeNode) {
|
||||
function getPromiseConstructor(type: TypeNode | undefined) {
|
||||
const typeName = type && getEntityNameFromTypeNode(type);
|
||||
if (typeName && isEntityName(typeName)) {
|
||||
const serializationKind = resolver.getTypeReferenceSerializationKind(typeName);
|
||||
@@ -634,7 +635,7 @@ namespace ts {
|
||||
};`
|
||||
};
|
||||
|
||||
function createAwaiterHelper(context: TransformationContext, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression, body: Block) {
|
||||
function createAwaiterHelper(context: TransformationContext, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression | undefined, body: Block) {
|
||||
context.requestEmitHelper(awaiterHelper);
|
||||
|
||||
const generatorFunc = createFunctionExpression(
|
||||
@@ -648,7 +649,7 @@ namespace ts {
|
||||
);
|
||||
|
||||
// Mark this node as originally an async function
|
||||
(generatorFunc.emitNode || (generatorFunc.emitNode = {})).flags |= EmitFlags.AsyncFunctionBody | EmitFlags.ReuseTempVariableScope;
|
||||
(generatorFunc.emitNode || (generatorFunc.emitNode = {} as EmitNode)).flags |= EmitFlags.AsyncFunctionBody | EmitFlags.ReuseTempVariableScope;
|
||||
|
||||
return createCall(
|
||||
getHelperName("__awaiter"),
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace ts {
|
||||
*/
|
||||
function trySubstituteReservedName(name: Identifier) {
|
||||
const token = name.originalKeywordKind || (nodeIsSynthesized(name) ? stringToToken(idText(name)) : undefined);
|
||||
if (token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord) {
|
||||
if (token !== undefined && token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord) {
|
||||
return setTextRange(createLiteral(name), name);
|
||||
}
|
||||
return undefined;
|
||||
|
||||
@@ -294,7 +294,7 @@ namespace ts {
|
||||
*
|
||||
* @param node A ForOfStatement.
|
||||
*/
|
||||
function visitForOfStatement(node: ForOfStatement, outermostLabeledStatement: LabeledStatement): VisitResult<Statement> {
|
||||
function visitForOfStatement(node: ForOfStatement, outermostLabeledStatement: LabeledStatement | undefined): VisitResult<Statement> {
|
||||
if (node.initializer.transformFlags & TransformFlags.ContainsObjectRest) {
|
||||
node = transformForOfStatementWithObjectRest(node);
|
||||
}
|
||||
@@ -309,8 +309,8 @@ namespace ts {
|
||||
function transformForOfStatementWithObjectRest(node: ForOfStatement) {
|
||||
const initializerWithoutParens = skipParentheses(node.initializer) as ForInitializer;
|
||||
if (isVariableDeclarationList(initializerWithoutParens) || isAssignmentPattern(initializerWithoutParens)) {
|
||||
let bodyLocation: TextRange;
|
||||
let statementsLocation: TextRange;
|
||||
let bodyLocation: TextRange | undefined;
|
||||
let statementsLocation: TextRange | undefined;
|
||||
const temp = createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const statements: Statement[] = [createForOfBindingStatement(initializerWithoutParens, temp)];
|
||||
if (isBlock(node.statement)) {
|
||||
@@ -351,8 +351,8 @@ namespace ts {
|
||||
function convertForOfStatementHead(node: ForOfStatement, boundValue: Expression) {
|
||||
const binding = createForOfBindingStatement(node.initializer, boundValue);
|
||||
|
||||
let bodyLocation: TextRange;
|
||||
let statementsLocation: TextRange;
|
||||
let bodyLocation: TextRange | undefined;
|
||||
let statementsLocation: TextRange | undefined;
|
||||
const statements: Statement[] = [visitNode(binding, visitor, isStatement)];
|
||||
const statement = visitNode(node.statement, visitor, isStatement);
|
||||
if (isBlock(statement)) {
|
||||
@@ -382,7 +382,7 @@ namespace ts {
|
||||
: createAwait(expression);
|
||||
}
|
||||
|
||||
function transformForAwaitOfStatement(node: ForOfStatement, outermostLabeledStatement: LabeledStatement) {
|
||||
function transformForAwaitOfStatement(node: ForOfStatement, outermostLabeledStatement: LabeledStatement | undefined) {
|
||||
const expression = visitNode(node.expression, visitor, isExpression);
|
||||
const iterator = isIdentifier(expression) ? getGeneratedNameForNode(expression) : createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const result = isIdentifier(expression) ? getGeneratedNameForNode(iterator) : createTempVariable(/*recordTempVariable*/ undefined);
|
||||
@@ -562,7 +562,7 @@ namespace ts {
|
||||
? undefined
|
||||
: node.asteriskToken,
|
||||
visitNode(node.name, visitor, isPropertyName),
|
||||
visitNode(/*questionToken*/ undefined, visitor, isToken),
|
||||
visitNode<Token<SyntaxKind.QuestionToken>>(/*questionToken*/ undefined, visitor, isToken),
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
@@ -640,7 +640,7 @@ namespace ts {
|
||||
function transformAsyncGeneratorFunctionBody(node: MethodDeclaration | AccessorDeclaration | FunctionDeclaration | FunctionExpression): FunctionBody {
|
||||
resumeLexicalEnvironment();
|
||||
const statements: Statement[] = [];
|
||||
const statementOffset = addPrologue(statements, node.body.statements, /*ensureUseStrict*/ false, visitor);
|
||||
const statementOffset = addPrologue(statements, node.body!.statements, /*ensureUseStrict*/ false, visitor);
|
||||
appendObjectRestAssignmentsIfNeeded(statements, node);
|
||||
|
||||
statements.push(
|
||||
@@ -655,8 +655,8 @@ namespace ts {
|
||||
/*parameters*/ [],
|
||||
/*type*/ undefined,
|
||||
updateBlock(
|
||||
node.body,
|
||||
visitLexicalEnvironment(node.body.statements, visitor, context, statementOffset)
|
||||
node.body!,
|
||||
visitLexicalEnvironment(node.body!.statements, visitor, context, statementOffset)
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -664,7 +664,7 @@ namespace ts {
|
||||
);
|
||||
|
||||
prependRange(statements, endLexicalEnvironment());
|
||||
const block = updateBlock(node.body, statements);
|
||||
const block = updateBlock(node.body!, statements);
|
||||
|
||||
// Minor optimization, emit `_super` helper to capture `super` access in an arrow.
|
||||
// This step isn't needed if we eventually transform this to ES5.
|
||||
@@ -702,7 +702,7 @@ namespace ts {
|
||||
return body;
|
||||
}
|
||||
|
||||
function appendObjectRestAssignmentsIfNeeded(statements: Statement[], node: FunctionLikeDeclaration): Statement[] {
|
||||
function appendObjectRestAssignmentsIfNeeded(statements: Statement[] | undefined, node: FunctionLikeDeclaration): Statement[] | undefined {
|
||||
for (const parameter of node.parameters) {
|
||||
if (parameter.transformFlags & TransformFlags.ContainsObjectRest) {
|
||||
const temp = getGeneratedNameForNode(parameter);
|
||||
@@ -889,7 +889,7 @@ namespace ts {
|
||||
};
|
||||
|
||||
export function createAssignHelper(context: TransformationContext, attributesSegments: Expression[]) {
|
||||
if (context.getCompilerOptions().target >= ScriptTarget.ES2015) {
|
||||
if (context.getCompilerOptions().target! >= ScriptTarget.ES2015) {
|
||||
return createCall(createPropertyAccess(createIdentifier("Object"), "assign"),
|
||||
/*typeArguments*/ undefined,
|
||||
attributesSegments);
|
||||
@@ -936,7 +936,7 @@ namespace ts {
|
||||
context.requestEmitHelper(asyncGeneratorHelper);
|
||||
|
||||
// Mark this node as originally an async function
|
||||
(generatorFunc.emitNode || (generatorFunc.emitNode = {})).flags |= EmitFlags.AsyncFunctionBody;
|
||||
(generatorFunc.emitNode || (generatorFunc.emitNode = {} as EmitNode)).flags |= EmitFlags.AsyncFunctionBody;
|
||||
|
||||
return createCall(
|
||||
getHelperName("__asyncGenerator"),
|
||||
|
||||
@@ -135,7 +135,7 @@ namespace ts {
|
||||
Endfinally // Marks the end of a `finally` block
|
||||
}
|
||||
|
||||
type OperationArguments = [Label] | [Label, Expression] | [Statement] | [Expression] | [Expression, Expression];
|
||||
type OperationArguments = [Label] | [Label, Expression] | [Statement] | [Expression | undefined] | [Expression, Expression];
|
||||
|
||||
// whether a generated code block is opening or closing at the current operation for a FunctionBuilder
|
||||
const enum BlockAction {
|
||||
@@ -224,6 +224,7 @@ namespace ts {
|
||||
case Instruction.Yield: return "yield";
|
||||
case Instruction.YieldStar: return "yield*";
|
||||
case Instruction.Endfinally: return "endfinally";
|
||||
default: return undefined!; // TODO: GH#18217
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,18 +252,18 @@ namespace ts {
|
||||
// All three arrays are correlated by their index. This approach is used over allocating
|
||||
// objects to store the same information to avoid GC overhead.
|
||||
//
|
||||
let blocks: CodeBlock[]; // Information about the code block
|
||||
let blockOffsets: number[]; // The operation offset at which a code block begins or ends
|
||||
let blockActions: BlockAction[]; // Whether the code block is opened or closed
|
||||
let blockStack: CodeBlock[]; // A stack of currently open code blocks
|
||||
let blocks: CodeBlock[] | undefined; // Information about the code block
|
||||
let blockOffsets: number[] | undefined; // The operation offset at which a code block begins or ends
|
||||
let blockActions: BlockAction[] | undefined; // Whether the code block is opened or closed
|
||||
let blockStack: CodeBlock[] | undefined; // A stack of currently open code blocks
|
||||
|
||||
// Labels are used to mark locations in the code that can be the target of a Break (jump)
|
||||
// operation. These are translated into case clauses in a switch statement.
|
||||
// The following two arrays are correlated by their index. This approach is used over
|
||||
// allocating objects to store the same information to avoid GC overhead.
|
||||
//
|
||||
let labelOffsets: number[]; // The operation offset at which the label is defined.
|
||||
let labelExpressions: LiteralExpression[][]; // The NumericLiteral nodes bound to each label.
|
||||
let labelOffsets: number[] | undefined; // The operation offset at which the label is defined.
|
||||
let labelExpressions: LiteralExpression[][] | undefined; // The NumericLiteral nodes bound to each label.
|
||||
let nextLabelId = 1; // The next label id to use.
|
||||
|
||||
// Operations store information about generated code for the function body. This
|
||||
@@ -270,9 +271,9 @@ namespace ts {
|
||||
// The following three arrays are correlated by their index. This approach is used over
|
||||
// allocating objects to store the same information to avoid GC overhead.
|
||||
//
|
||||
let operations: OpCode[]; // The operation to perform.
|
||||
let operationArguments: OperationArguments[]; // The arguments to the operation.
|
||||
let operationLocations: TextRange[]; // The source map location for the operation.
|
||||
let operations: OpCode[] | undefined; // The operation to perform.
|
||||
let operationArguments: (OperationArguments | undefined)[] | undefined; // The arguments to the operation.
|
||||
let operationLocations: (TextRange | undefined)[] | undefined; // The source map location for the operation.
|
||||
|
||||
let state: Identifier; // The name of the state object used by the generator at runtime.
|
||||
|
||||
@@ -280,14 +281,14 @@ namespace ts {
|
||||
//
|
||||
let blockIndex = 0; // The index of the current block.
|
||||
let labelNumber = 0; // The current label number.
|
||||
let labelNumbers: number[][];
|
||||
let labelNumbers: number[][] | undefined;
|
||||
let lastOperationWasAbrupt: boolean; // Indicates whether the last operation was abrupt (break/continue).
|
||||
let lastOperationWasCompletion: boolean; // Indicates whether the last operation was a completion (return/throw).
|
||||
let clauses: CaseClause[]; // The case clauses generated for labels.
|
||||
let statements: Statement[]; // The statements for the current label.
|
||||
let exceptionBlockStack: ExceptionBlock[]; // A stack of containing exception blocks.
|
||||
let currentExceptionBlock: ExceptionBlock; // The current exception block.
|
||||
let withBlockStack: WithBlock[]; // A stack containing `with` blocks.
|
||||
let clauses: CaseClause[] | undefined; // The case clauses generated for labels.
|
||||
let statements: Statement[] | undefined; // The statements for the current label.
|
||||
let exceptionBlockStack: ExceptionBlock[] | undefined; // A stack of containing exception blocks.
|
||||
let currentExceptionBlock: ExceptionBlock | undefined; // The current exception block.
|
||||
let withBlockStack: WithBlock[] | undefined; // A stack containing `with` blocks.
|
||||
|
||||
return chainBundle(transformSourceFile);
|
||||
|
||||
@@ -440,7 +441,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function visitFunctionDeclaration(node: FunctionDeclaration): Statement {
|
||||
function visitFunctionDeclaration(node: FunctionDeclaration): Statement | undefined {
|
||||
// Currently, we only support generators that were originally async functions.
|
||||
if (node.asteriskToken) {
|
||||
node = setOriginalNode(
|
||||
@@ -453,7 +454,7 @@ namespace ts {
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformGeneratorFunctionBody(node.body)
|
||||
transformGeneratorFunctionBody(node.body!)
|
||||
),
|
||||
/*location*/ node
|
||||
),
|
||||
@@ -615,7 +616,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function visitVariableStatement(node: VariableStatement): Statement {
|
||||
function visitVariableStatement(node: VariableStatement): Statement | undefined {
|
||||
if (node.transformFlags & TransformFlags.ContainsYield) {
|
||||
transformAndEmitVariableDeclarationList(node.declarationList);
|
||||
return undefined;
|
||||
@@ -655,13 +656,14 @@ namespace ts {
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function visitBinaryExpression(node: BinaryExpression): Expression {
|
||||
switch (getExpressionAssociativity(node)) {
|
||||
const assoc = getExpressionAssociativity(node);
|
||||
switch (assoc) {
|
||||
case Associativity.Left:
|
||||
return visitLeftAssociativeBinaryExpression(node);
|
||||
case Associativity.Right:
|
||||
return visitRightAssociativeBinaryExpression(node);
|
||||
default:
|
||||
Debug.fail("Unknown associativity.");
|
||||
return Debug.assertNever(assoc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -934,9 +936,9 @@ namespace ts {
|
||||
// x = %sent%;
|
||||
|
||||
const resumeLabel = defineLabel();
|
||||
const expression = visitNode(node.expression, visitor, isExpression);
|
||||
const expression = visitNode(node.expression!, visitor, isExpression);
|
||||
if (node.asteriskToken) {
|
||||
const iterator = (getEmitFlags(node.expression) & EmitFlags.Iterator) === 0
|
||||
const iterator = (getEmitFlags(node.expression!) & EmitFlags.Iterator) === 0
|
||||
? createValuesHelper(context, expression, /*location*/ node)
|
||||
: expression;
|
||||
emitYieldStar(iterator, /*location*/ node);
|
||||
@@ -978,7 +980,7 @@ namespace ts {
|
||||
|
||||
const numInitialElements = countInitialNodesWithoutYield(elements);
|
||||
|
||||
let temp: Identifier;
|
||||
let temp: Identifier | undefined;
|
||||
if (numInitialElements > 0) {
|
||||
temp = declareLocal();
|
||||
const initialElements = visitNodes(elements, visitor, isExpression, 0, numInitialElements);
|
||||
@@ -1155,7 +1157,7 @@ namespace ts {
|
||||
cacheExpression(visitNode(target, visitor, isExpression)),
|
||||
thisArg,
|
||||
visitElements(
|
||||
node.arguments,
|
||||
node.arguments!,
|
||||
/*leadingElement*/ createVoidZero()
|
||||
)
|
||||
),
|
||||
@@ -1246,7 +1248,7 @@ namespace ts {
|
||||
emitStatement(visitNode(node, visitor, isStatement));
|
||||
}
|
||||
|
||||
function transformAndEmitVariableDeclarationList(node: VariableDeclarationList): VariableDeclarationList {
|
||||
function transformAndEmitVariableDeclarationList(node: VariableDeclarationList): VariableDeclarationList | undefined {
|
||||
for (const variable of node.declarations) {
|
||||
const name = getSynthesizedClone(<Identifier>variable.name);
|
||||
setCommentRange(name, variable.name);
|
||||
@@ -1260,7 +1262,7 @@ namespace ts {
|
||||
while (variablesWritten < numVariables) {
|
||||
for (let i = variablesWritten; i < numVariables; i++) {
|
||||
const variable = variables[i];
|
||||
if (containsYield(variable.initializer) && pendingExpressions.length > 0) {
|
||||
if (containsYield(variable.initializer!) && pendingExpressions.length > 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1281,7 +1283,7 @@ namespace ts {
|
||||
return setSourceMapRange(
|
||||
createAssignment(
|
||||
setSourceMapRange(<Identifier>getSynthesizedClone(node.name), node.name),
|
||||
visitNode(node.initializer, visitor, isExpression)
|
||||
visitNode(node.initializer!, visitor, isExpression)
|
||||
),
|
||||
node
|
||||
);
|
||||
@@ -1306,11 +1308,11 @@ namespace ts {
|
||||
if (containsYield(node.thenStatement) || containsYield(node.elseStatement)) {
|
||||
const endLabel = defineLabel();
|
||||
const elseLabel = node.elseStatement ? defineLabel() : undefined;
|
||||
emitBreakWhenFalse(node.elseStatement ? elseLabel : endLabel, visitNode(node.expression, visitor, isExpression), /*location*/ node.expression);
|
||||
emitBreakWhenFalse(node.elseStatement ? elseLabel! : endLabel, visitNode(node.expression, visitor, isExpression), /*location*/ node.expression);
|
||||
transformAndEmitEmbeddedStatement(node.thenStatement);
|
||||
if (node.elseStatement) {
|
||||
emitBreak(endLabel);
|
||||
markLabel(elseLabel);
|
||||
markLabel(elseLabel!);
|
||||
transformAndEmitEmbeddedStatement(node.elseStatement);
|
||||
}
|
||||
markLabel(endLabel);
|
||||
@@ -1866,7 +1868,7 @@ namespace ts {
|
||||
|
||||
function transformAndEmitThrowStatement(node: ThrowStatement): void {
|
||||
emitThrow(
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
visitNode(node.expression!, visitor, isExpression),
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
@@ -1906,7 +1908,7 @@ namespace ts {
|
||||
beginExceptionBlock();
|
||||
transformAndEmitEmbeddedStatement(node.tryBlock);
|
||||
if (node.catchClause) {
|
||||
beginCatchBlock(node.catchClause.variableDeclaration);
|
||||
beginCatchBlock(node.catchClause.variableDeclaration!); // TODO: GH#18217
|
||||
transformAndEmitEmbeddedStatement(node.catchClause.block);
|
||||
}
|
||||
|
||||
@@ -1922,8 +1924,8 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function containsYield(node: Node) {
|
||||
return node && (node.transformFlags & TransformFlags.ContainsYield) !== 0;
|
||||
function containsYield(node: Node | undefined): boolean {
|
||||
return !!node && (node.transformFlags & TransformFlags.ContainsYield) !== 0;
|
||||
}
|
||||
|
||||
function countInitialNodesWithoutYield(nodes: NodeArray<Node>) {
|
||||
@@ -2010,7 +2012,7 @@ namespace ts {
|
||||
*/
|
||||
function markLabel(label: Label): void {
|
||||
Debug.assert(labelOffsets !== undefined, "No labels were defined.");
|
||||
labelOffsets[label] = operations ? operations.length : 0;
|
||||
labelOffsets![label] = operations ? operations.length : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2026,11 +2028,11 @@ namespace ts {
|
||||
blockStack = [];
|
||||
}
|
||||
|
||||
const index = blockActions.length;
|
||||
blockActions[index] = BlockAction.Open;
|
||||
blockOffsets[index] = operations ? operations.length : 0;
|
||||
const index = blockActions!.length;
|
||||
blockActions![index] = BlockAction.Open;
|
||||
blockOffsets![index] = operations ? operations.length : 0;
|
||||
blocks[index] = block;
|
||||
blockStack.push(block);
|
||||
blockStack!.push(block);
|
||||
return index;
|
||||
}
|
||||
|
||||
@@ -2039,13 +2041,13 @@ namespace ts {
|
||||
*/
|
||||
function endBlock(): CodeBlock {
|
||||
const block = peekBlock();
|
||||
Debug.assert(block !== undefined, "beginBlock was never called.");
|
||||
if (block === undefined) return Debug.fail("beginBlock was never called.");
|
||||
|
||||
const index = blockActions.length;
|
||||
blockActions[index] = BlockAction.Close;
|
||||
blockOffsets[index] = operations ? operations.length : 0;
|
||||
blocks[index] = block;
|
||||
blockStack.pop();
|
||||
const index = blockActions!.length;
|
||||
blockActions![index] = BlockAction.Close;
|
||||
blockOffsets![index] = operations ? operations.length : 0;
|
||||
blocks![index] = block;
|
||||
blockStack!.pop();
|
||||
return block;
|
||||
}
|
||||
|
||||
@@ -2053,13 +2055,13 @@ namespace ts {
|
||||
* Gets the current open block.
|
||||
*/
|
||||
function peekBlock() {
|
||||
return lastOrUndefined(blockStack);
|
||||
return lastOrUndefined(blockStack!);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the kind of the current open block.
|
||||
*/
|
||||
function peekBlockKind(): CodeBlockKind {
|
||||
function peekBlockKind(): CodeBlockKind | undefined {
|
||||
const block = peekBlock();
|
||||
return block && block.kind;
|
||||
}
|
||||
@@ -2331,7 +2333,7 @@ namespace ts {
|
||||
|
||||
function hasImmediateContainingLabeledBlock(labelText: string, start: number) {
|
||||
for (let j = start; j >= 0; j--) {
|
||||
const containingBlock = blockStack[j];
|
||||
const containingBlock = blockStack![j];
|
||||
if (supportsLabeledBreakOrContinue(containingBlock)) {
|
||||
if (containingBlock.labelText === labelText) {
|
||||
return true;
|
||||
@@ -2407,8 +2409,8 @@ namespace ts {
|
||||
*
|
||||
* @param label A label.
|
||||
*/
|
||||
function createLabel(label: Label): Expression {
|
||||
if (label > 0) {
|
||||
function createLabel(label: Label | undefined): Expression {
|
||||
if (label !== undefined && label > 0) {
|
||||
if (labelExpressions === undefined) {
|
||||
labelExpressions = [];
|
||||
}
|
||||
@@ -2620,8 +2622,8 @@ namespace ts {
|
||||
|
||||
const operationIndex = operations.length;
|
||||
operations[operationIndex] = code;
|
||||
operationArguments[operationIndex] = args;
|
||||
operationLocations[operationIndex] = location;
|
||||
operationArguments![operationIndex] = args;
|
||||
operationLocations![operationIndex] = location;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2869,9 +2871,9 @@ namespace ts {
|
||||
*/
|
||||
function tryEnterOrLeaveBlock(operationIndex: number): void {
|
||||
if (blocks) {
|
||||
for (; blockIndex < blockActions.length && blockOffsets[blockIndex] <= operationIndex; blockIndex++) {
|
||||
for (; blockIndex < blockActions!.length && blockOffsets![blockIndex] <= operationIndex; blockIndex++) {
|
||||
const block = blocks[blockIndex];
|
||||
const blockAction = blockActions[blockIndex];
|
||||
const blockAction = blockActions![blockIndex];
|
||||
switch (block.kind) {
|
||||
case CodeBlockKind.Exception:
|
||||
if (blockAction === BlockAction.Open) {
|
||||
@@ -2883,11 +2885,11 @@ namespace ts {
|
||||
statements = [];
|
||||
}
|
||||
|
||||
exceptionBlockStack.push(currentExceptionBlock);
|
||||
exceptionBlockStack.push(currentExceptionBlock!);
|
||||
currentExceptionBlock = block;
|
||||
}
|
||||
else if (blockAction === BlockAction.Close) {
|
||||
currentExceptionBlock = exceptionBlockStack.pop();
|
||||
currentExceptionBlock = exceptionBlockStack!.pop();
|
||||
}
|
||||
break;
|
||||
case CodeBlockKind.With:
|
||||
@@ -2899,7 +2901,7 @@ namespace ts {
|
||||
withBlockStack.push(block);
|
||||
}
|
||||
else if (blockAction === BlockAction.Close) {
|
||||
withBlockStack.pop();
|
||||
withBlockStack!.pop();
|
||||
}
|
||||
break;
|
||||
// default: do nothing
|
||||
@@ -2925,7 +2927,7 @@ namespace ts {
|
||||
lastOperationWasAbrupt = false;
|
||||
lastOperationWasCompletion = false;
|
||||
|
||||
const opcode = operations[operationIndex];
|
||||
const opcode = operations![operationIndex];
|
||||
if (opcode === OpCode.Nop) {
|
||||
return;
|
||||
}
|
||||
@@ -2933,12 +2935,12 @@ namespace ts {
|
||||
return writeEndfinally();
|
||||
}
|
||||
|
||||
const args = operationArguments[operationIndex];
|
||||
const args = operationArguments![operationIndex]!;
|
||||
if (opcode === OpCode.Statement) {
|
||||
return writeStatement(<Statement>args[0]);
|
||||
}
|
||||
|
||||
const location = operationLocations[operationIndex];
|
||||
const location = operationLocations![operationIndex];
|
||||
switch (opcode) {
|
||||
case OpCode.Assign:
|
||||
return writeAssign(<Expression>args[0], <Expression>args[1], location);
|
||||
@@ -2982,7 +2984,7 @@ namespace ts {
|
||||
* @param right The right-hand side of the assignment.
|
||||
* @param operationLocation The source map location for the operation.
|
||||
*/
|
||||
function writeAssign(left: Expression, right: Expression, operationLocation: TextRange): void {
|
||||
function writeAssign(left: Expression, right: Expression, operationLocation: TextRange | undefined): void {
|
||||
writeStatement(setTextRange(createStatement(createAssignment(left, right)), operationLocation));
|
||||
}
|
||||
|
||||
@@ -2992,7 +2994,7 @@ namespace ts {
|
||||
* @param expression The value to throw.
|
||||
* @param operationLocation The source map location for the operation.
|
||||
*/
|
||||
function writeThrow(expression: Expression, operationLocation: TextRange): void {
|
||||
function writeThrow(expression: Expression, operationLocation: TextRange | undefined): void {
|
||||
lastOperationWasAbrupt = true;
|
||||
lastOperationWasCompletion = true;
|
||||
writeStatement(setTextRange(createThrow(expression), operationLocation));
|
||||
@@ -3004,7 +3006,7 @@ namespace ts {
|
||||
* @param expression The value to return.
|
||||
* @param operationLocation The source map location for the operation.
|
||||
*/
|
||||
function writeReturn(expression: Expression, operationLocation: TextRange): void {
|
||||
function writeReturn(expression: Expression | undefined, operationLocation: TextRange | undefined): void {
|
||||
lastOperationWasAbrupt = true;
|
||||
lastOperationWasCompletion = true;
|
||||
writeStatement(
|
||||
@@ -3029,7 +3031,7 @@ namespace ts {
|
||||
* @param label The label for the Break.
|
||||
* @param operationLocation The source map location for the operation.
|
||||
*/
|
||||
function writeBreak(label: Label, operationLocation: TextRange): void {
|
||||
function writeBreak(label: Label, operationLocation: TextRange | undefined): void {
|
||||
lastOperationWasAbrupt = true;
|
||||
writeStatement(
|
||||
setEmitFlags(
|
||||
@@ -3054,7 +3056,7 @@ namespace ts {
|
||||
* @param condition The condition for the Break.
|
||||
* @param operationLocation The source map location for the operation.
|
||||
*/
|
||||
function writeBreakWhenTrue(label: Label, condition: Expression, operationLocation: TextRange): void {
|
||||
function writeBreakWhenTrue(label: Label, condition: Expression, operationLocation: TextRange | undefined): void {
|
||||
writeStatement(
|
||||
setEmitFlags(
|
||||
createIf(
|
||||
@@ -3084,7 +3086,7 @@ namespace ts {
|
||||
* @param condition The condition for the Break.
|
||||
* @param operationLocation The source map location for the operation.
|
||||
*/
|
||||
function writeBreakWhenFalse(label: Label, condition: Expression, operationLocation: TextRange): void {
|
||||
function writeBreakWhenFalse(label: Label, condition: Expression, operationLocation: TextRange | undefined): void {
|
||||
writeStatement(
|
||||
setEmitFlags(
|
||||
createIf(
|
||||
@@ -3113,7 +3115,7 @@ namespace ts {
|
||||
* @param expression The expression to yield.
|
||||
* @param operationLocation The source map location for the operation.
|
||||
*/
|
||||
function writeYield(expression: Expression, operationLocation: TextRange): void {
|
||||
function writeYield(expression: Expression, operationLocation: TextRange | undefined): void {
|
||||
lastOperationWasAbrupt = true;
|
||||
writeStatement(
|
||||
setEmitFlags(
|
||||
@@ -3138,7 +3140,7 @@ namespace ts {
|
||||
* @param expression The expression to yield.
|
||||
* @param operationLocation The source map location for the operation.
|
||||
*/
|
||||
function writeYieldStar(expression: Expression, operationLocation: TextRange): void {
|
||||
function writeYieldStar(expression: Expression, operationLocation: TextRange | undefined): void {
|
||||
lastOperationWasAbrupt = true;
|
||||
writeStatement(
|
||||
setEmitFlags(
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function transformJsxChildToExpression(node: JsxChild): Expression {
|
||||
function transformJsxChildToExpression(node: JsxChild): Expression | undefined {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.JsxText:
|
||||
return visitJsxText(node);
|
||||
@@ -84,9 +84,9 @@ namespace ts {
|
||||
return visitJsxOpeningFragment(node.openingFragment, node.children, isChild, /*location*/ node);
|
||||
}
|
||||
|
||||
function visitJsxOpeningLikeElement(node: JsxOpeningLikeElement, children: ReadonlyArray<JsxChild>, isChild: boolean, location: TextRange) {
|
||||
function visitJsxOpeningLikeElement(node: JsxOpeningLikeElement, children: ReadonlyArray<JsxChild> | undefined, isChild: boolean, location: TextRange) {
|
||||
const tagName = getTagName(node);
|
||||
let objectProperties: Expression;
|
||||
let objectProperties: Expression | undefined;
|
||||
const attrs = node.attributes.properties;
|
||||
if (attrs.length === 0) {
|
||||
// When there are no attributes, React wants "null"
|
||||
@@ -118,7 +118,7 @@ namespace ts {
|
||||
|
||||
const element = createExpressionForJsxElement(
|
||||
context.getEmitResolver().getJsxFactoryEntity(currentSourceFile),
|
||||
compilerOptions.reactNamespace,
|
||||
compilerOptions.reactNamespace!, // TODO: GH#18217
|
||||
tagName,
|
||||
objectProperties,
|
||||
mapDefined(children, transformJsxChildToExpression),
|
||||
@@ -136,7 +136,7 @@ namespace ts {
|
||||
function visitJsxOpeningFragment(node: JsxOpeningFragment, children: ReadonlyArray<JsxChild>, isChild: boolean, location: TextRange) {
|
||||
const element = createExpressionForJsxFragment(
|
||||
context.getEmitResolver().getJsxFactoryEntity(currentSourceFile),
|
||||
compilerOptions.reactNamespace,
|
||||
compilerOptions.reactNamespace!, // TODO: GH#18217
|
||||
mapDefined(children, transformJsxChildToExpression),
|
||||
node,
|
||||
location
|
||||
@@ -159,7 +159,7 @@ namespace ts {
|
||||
return createPropertyAssignment(name, expression);
|
||||
}
|
||||
|
||||
function transformJsxAttributeInitializer(node: StringLiteral | JsxExpression) {
|
||||
function transformJsxAttributeInitializer(node: StringLiteral | JsxExpression | undefined): Expression {
|
||||
if (node === undefined) {
|
||||
return createTrue();
|
||||
}
|
||||
@@ -563,4 +563,4 @@ namespace ts {
|
||||
hearts: 0x2665,
|
||||
diams: 0x2666
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace ts {
|
||||
context.enableEmitNotification(SyntaxKind.SourceFile);
|
||||
context.enableSubstitution(SyntaxKind.Identifier);
|
||||
|
||||
let currentSourceFile: SourceFile;
|
||||
let currentSourceFile: SourceFile | undefined;
|
||||
return chainBundle(transformSourceFile);
|
||||
|
||||
function transformSourceFile(node: SourceFile) {
|
||||
@@ -104,7 +104,7 @@ namespace ts {
|
||||
|
||||
function substituteExpressionIdentifier(node: Identifier): Expression {
|
||||
if (getEmitFlags(node) & EmitFlags.HelperName) {
|
||||
const externalHelpersModuleName = getExternalHelpersModuleName(currentSourceFile);
|
||||
const externalHelpersModuleName = getExternalHelpersModuleName(currentSourceFile!);
|
||||
if (externalHelpersModuleName) {
|
||||
return createPropertyAccess(externalHelpersModuleName, node);
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace ts {
|
||||
context.enableEmitNotification(SyntaxKind.SourceFile); // Restore state when substituting nodes in a file.
|
||||
|
||||
const moduleInfoMap: ExternalModuleInfo[] = []; // The ExternalModuleInfo for each file.
|
||||
const deferredExports: Statement[][] = []; // Exports to defer until an EndOfDeclarationMarker is found.
|
||||
const deferredExports: (Statement[] | undefined)[] = []; // Exports to defer until an EndOfDeclarationMarker is found.
|
||||
|
||||
let currentSourceFile: SourceFile; // The current file.
|
||||
let currentModuleInfo: ExternalModuleInfo; // The ExternalModuleInfo for the current file.
|
||||
@@ -64,8 +64,8 @@ namespace ts {
|
||||
// Perform the transformation.
|
||||
const transformModule = getTransformModuleDelegate(moduleKind);
|
||||
const updated = transformModule(node);
|
||||
currentSourceFile = undefined;
|
||||
currentModuleInfo = undefined;
|
||||
currentSourceFile = undefined!;
|
||||
currentModuleInfo = undefined!;
|
||||
needUMDDynamicImportHelper = false;
|
||||
return aggregateTransformFlags(updated);
|
||||
}
|
||||
@@ -391,7 +391,7 @@ namespace ts {
|
||||
if (isImportEqualsDeclaration(node) || isExportDeclaration(node) || !getExternalModuleNameLiteral(node, currentSourceFile, host, resolver, compilerOptions)) {
|
||||
return undefined;
|
||||
}
|
||||
const name = getLocalNameForExternalImport(node, currentSourceFile);
|
||||
const name = getLocalNameForExternalImport(node, currentSourceFile)!; // TODO: GH#18217
|
||||
const expr = getHelperExpressionForImport(node, name);
|
||||
if (expr === name) {
|
||||
return undefined;
|
||||
@@ -605,7 +605,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function createImportCallExpressionUMD(arg: Expression | undefined, containsLexicalThis: boolean): Expression {
|
||||
function createImportCallExpressionUMD(arg: Expression, containsLexicalThis: boolean): Expression {
|
||||
// (function (factory) {
|
||||
// ... (regular UMD)
|
||||
// }
|
||||
@@ -762,7 +762,7 @@ namespace ts {
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function visitImportDeclaration(node: ImportDeclaration): VisitResult<Statement> {
|
||||
let statements: Statement[];
|
||||
let statements: Statement[] | undefined;
|
||||
const namespaceDeclaration = getNamespaceDeclarationNode(node);
|
||||
if (moduleKind !== ModuleKind.AMD) {
|
||||
if (!node.importClause) {
|
||||
@@ -876,7 +876,7 @@ namespace ts {
|
||||
function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult<Statement> {
|
||||
Debug.assert(isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer.");
|
||||
|
||||
let statements: Statement[];
|
||||
let statements: Statement[] | undefined;
|
||||
if (moduleKind !== ModuleKind.AMD) {
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
statements = append(statements,
|
||||
@@ -1009,7 +1009,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let statements: Statement[];
|
||||
let statements: Statement[] | undefined;
|
||||
const original = node.original;
|
||||
if (original && hasAssociatedEndOfDeclarationMarker(original)) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
@@ -1029,7 +1029,7 @@ namespace ts {
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult<Statement> {
|
||||
let statements: Statement[];
|
||||
let statements: Statement[] | undefined;
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
statements = append(statements,
|
||||
setOriginalNode(
|
||||
@@ -1072,7 +1072,7 @@ namespace ts {
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function visitClassDeclaration(node: ClassDeclaration): VisitResult<Statement> {
|
||||
let statements: Statement[];
|
||||
let statements: Statement[] | undefined;
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
statements = append(statements,
|
||||
setOriginalNode(
|
||||
@@ -1113,12 +1113,12 @@ namespace ts {
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function visitVariableStatement(node: VariableStatement): VisitResult<Statement> {
|
||||
let statements: Statement[];
|
||||
let variables: VariableDeclaration[];
|
||||
let expressions: Expression[];
|
||||
let statements: Statement[] | undefined;
|
||||
let variables: VariableDeclaration[] | undefined;
|
||||
let expressions: Expression[] | undefined;
|
||||
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
let modifiers: NodeArray<Modifier>;
|
||||
let modifiers: NodeArray<Modifier> | undefined;
|
||||
|
||||
// If we're exporting these variables, then these just become assignments to 'exports.x'.
|
||||
// We only want to emit assignments for variables with initializers.
|
||||
@@ -1219,7 +1219,7 @@ namespace ts {
|
||||
//
|
||||
// To balance the declaration, add the exports of the elided variable
|
||||
// statement.
|
||||
if (hasAssociatedEndOfDeclarationMarker(node) && node.original.kind === SyntaxKind.VariableStatement) {
|
||||
if (hasAssociatedEndOfDeclarationMarker(node) && node.original!.kind === SyntaxKind.VariableStatement) {
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], <VariableStatement>node.original);
|
||||
}
|
||||
@@ -1532,9 +1532,9 @@ namespace ts {
|
||||
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
|
||||
currentSourceFile = undefined;
|
||||
currentModuleInfo = undefined;
|
||||
noSubstitution = undefined;
|
||||
currentSourceFile = undefined!;
|
||||
currentModuleInfo = undefined!;
|
||||
noSubstitution = undefined!;
|
||||
}
|
||||
else {
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace ts {
|
||||
context.enableEmitNotification(SyntaxKind.SourceFile); // Restore state when substituting nodes in a file.
|
||||
|
||||
const moduleInfoMap: ExternalModuleInfo[] = []; // The ExternalModuleInfo for each file.
|
||||
const deferredExports: Statement[][] = []; // Exports to defer until an EndOfDeclarationMarker is found.
|
||||
const deferredExports: (Statement[] | undefined)[] = []; // Exports to defer until an EndOfDeclarationMarker is found.
|
||||
const exportFunctionsMap: Identifier[] = []; // The export function associated with a source file.
|
||||
const noSubstitutionMap: boolean[][] = []; // Set of nodes for which substitution rules should be ignored for each file.
|
||||
|
||||
@@ -35,9 +35,9 @@ namespace ts {
|
||||
let moduleInfo: ExternalModuleInfo; // ExternalModuleInfo for the current file.
|
||||
let exportFunction: Identifier; // The export function for the current file.
|
||||
let contextObject: Identifier; // The context object for the current file.
|
||||
let hoistedStatements: Statement[];
|
||||
let hoistedStatements: Statement[] | undefined;
|
||||
let enclosingBlockScopedContainer: Node;
|
||||
let noSubstitution: boolean[]; // Set of nodes for which substitution rules should be ignored.
|
||||
let noSubstitution: boolean[] | undefined; // Set of nodes for which substitution rules should be ignored.
|
||||
|
||||
return chainBundle(transformSourceFile);
|
||||
|
||||
@@ -126,12 +126,12 @@ namespace ts {
|
||||
noSubstitution = undefined;
|
||||
}
|
||||
|
||||
currentSourceFile = undefined;
|
||||
moduleInfo = undefined;
|
||||
exportFunction = undefined;
|
||||
contextObject = undefined;
|
||||
hoistedStatements = undefined;
|
||||
enclosingBlockScopedContainer = undefined;
|
||||
currentSourceFile = undefined!;
|
||||
moduleInfo = undefined!;
|
||||
exportFunction = undefined!;
|
||||
contextObject = undefined!;
|
||||
hoistedStatements = undefined!;
|
||||
enclosingBlockScopedContainer = undefined!;
|
||||
return aggregateTransformFlags(updated);
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ namespace ts {
|
||||
// - Temporary variables will appear at the top rather than at the bottom of the file
|
||||
prependRange(statements, endLexicalEnvironment());
|
||||
|
||||
const exportStarFunction = addExportStarIfNeeded(statements);
|
||||
const exportStarFunction = addExportStarIfNeeded(statements)!; // TODO: GH#18217
|
||||
const moduleObject = createObjectLiteral([
|
||||
createPropertyAssignment("setters",
|
||||
createSettersArray(exportStarFunction, dependencyGroups)
|
||||
@@ -464,7 +464,7 @@ namespace ts {
|
||||
const parameterName = localName ? getGeneratedNameForNode(localName) : createUniqueName("");
|
||||
const statements: Statement[] = [];
|
||||
for (const entry of group.externalImports) {
|
||||
const importVariableName = getLocalNameForExternalImport(entry, currentSourceFile);
|
||||
const importVariableName = getLocalNameForExternalImport(entry, currentSourceFile)!; // TODO: GH#18217
|
||||
switch (entry.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
if (!entry.importClause) {
|
||||
@@ -590,9 +590,9 @@ namespace ts {
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function visitImportDeclaration(node: ImportDeclaration): VisitResult<Statement> {
|
||||
let statements: Statement[];
|
||||
let statements: Statement[] | undefined;
|
||||
if (node.importClause) {
|
||||
hoistVariableDeclaration(getLocalNameForExternalImport(node, currentSourceFile));
|
||||
hoistVariableDeclaration(getLocalNameForExternalImport(node, currentSourceFile)!); // TODO: GH#18217
|
||||
}
|
||||
|
||||
if (hasAssociatedEndOfDeclarationMarker(node)) {
|
||||
@@ -615,13 +615,13 @@ namespace ts {
|
||||
function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult<Statement> {
|
||||
Debug.assert(isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer.");
|
||||
|
||||
let statements: Statement[];
|
||||
hoistVariableDeclaration(getLocalNameForExternalImport(node, currentSourceFile));
|
||||
let statements: Statement[] | undefined;
|
||||
hoistVariableDeclaration(getLocalNameForExternalImport(node, currentSourceFile)!); // TODO: GH#18217
|
||||
|
||||
if (hasAssociatedEndOfDeclarationMarker(node)) {
|
||||
// Defer exports until we encounter an EndOfDeclarationMarker node
|
||||
const id = getOriginalNodeId(node);
|
||||
deferredExports[id] = appendExportsOfImportEqualsDeclaration(deferredExports[id], node);
|
||||
deferredExports[id] = appendExportsOfImportEqualsDeclaration(deferredExports[id]!, node);
|
||||
}
|
||||
else {
|
||||
statements = appendExportsOfImportEqualsDeclaration(statements, node);
|
||||
@@ -694,7 +694,7 @@ namespace ts {
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function visitClassDeclaration(node: ClassDeclaration): VisitResult<Statement> {
|
||||
let statements: Statement[];
|
||||
let statements: Statement[] | undefined;
|
||||
|
||||
// Hoist the name of the class declaration to the outer module body function.
|
||||
const name = getLocalName(node);
|
||||
@@ -745,7 +745,7 @@ namespace ts {
|
||||
return visitNode(node, destructuringAndImportCallVisitor, isStatement);
|
||||
}
|
||||
|
||||
let expressions: Expression[];
|
||||
let expressions: Expression[] | undefined;
|
||||
const isExportedDeclaration = hasModifier(node, ModifierFlags.Export);
|
||||
const isMarkedDeclaration = hasAssociatedEndOfDeclarationMarker(node);
|
||||
for (const variable of node.declarationList.declarations) {
|
||||
@@ -757,7 +757,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
let statements: Statement[];
|
||||
let statements: Statement[] | undefined;
|
||||
if (expressions) {
|
||||
statements = append(statements, setTextRange(createStatement(inlineExpressions(expressions)), node));
|
||||
}
|
||||
@@ -854,7 +854,7 @@ namespace ts {
|
||||
* @param location The source map location for the assignment.
|
||||
* @param isExportedDeclaration A value indicating whether the variable is exported.
|
||||
*/
|
||||
function createVariableAssignment(name: Identifier, value: Expression, location: TextRange, isExportedDeclaration: boolean) {
|
||||
function createVariableAssignment(name: Identifier, value: Expression, location: TextRange | undefined, isExportedDeclaration: boolean) {
|
||||
hoistVariableDeclaration(getSynthesizedClone(name));
|
||||
return isExportedDeclaration
|
||||
? createExportExpression(name, preventSubstitution(setTextRange(createAssignment(name, value), location)))
|
||||
@@ -875,9 +875,9 @@ namespace ts {
|
||||
//
|
||||
// To balance the declaration, we defer the exports of the elided variable
|
||||
// statement until we visit this declaration's `EndOfDeclarationMarker`.
|
||||
if (hasAssociatedEndOfDeclarationMarker(node) && node.original.kind === SyntaxKind.VariableStatement) {
|
||||
if (hasAssociatedEndOfDeclarationMarker(node) && node.original!.kind === SyntaxKind.VariableStatement) {
|
||||
const id = getOriginalNodeId(node);
|
||||
const isExportedDeclaration = hasModifier(node.original, ModifierFlags.Export);
|
||||
const isExportedDeclaration = hasModifier(node.original!, ModifierFlags.Export);
|
||||
deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], <VariableStatement>node.original, isExportedDeclaration);
|
||||
}
|
||||
|
||||
@@ -928,7 +928,7 @@ namespace ts {
|
||||
* appended.
|
||||
* @param decl The declaration whose exports are to be recorded.
|
||||
*/
|
||||
function appendExportsOfImportDeclaration(statements: Statement[], decl: ImportDeclaration) {
|
||||
function appendExportsOfImportDeclaration(statements: Statement[] | undefined, decl: ImportDeclaration) {
|
||||
if (moduleInfo.exportEquals) {
|
||||
return statements;
|
||||
}
|
||||
@@ -970,7 +970,7 @@ namespace ts {
|
||||
* appended.
|
||||
* @param decl The declaration whose exports are to be recorded.
|
||||
*/
|
||||
function appendExportsOfImportEqualsDeclaration(statements: Statement[], decl: ImportEqualsDeclaration): Statement[] | undefined {
|
||||
function appendExportsOfImportEqualsDeclaration(statements: Statement[] | undefined, decl: ImportEqualsDeclaration): Statement[] | undefined {
|
||||
if (moduleInfo.exportEquals) {
|
||||
return statements;
|
||||
}
|
||||
@@ -1026,7 +1026,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else if (!isGeneratedIdentifier(decl.name)) {
|
||||
let excludeName: string;
|
||||
let excludeName: string | undefined;
|
||||
if (exportSelf) {
|
||||
statements = appendExportStatement(statements, decl.name, getLocalName(decl));
|
||||
excludeName = idText(decl.name);
|
||||
@@ -1052,9 +1052,9 @@ namespace ts {
|
||||
return statements;
|
||||
}
|
||||
|
||||
let excludeName: string;
|
||||
let excludeName: string | undefined;
|
||||
if (hasModifier(decl, ModifierFlags.Export)) {
|
||||
const exportName = hasModifier(decl, ModifierFlags.Default) ? createLiteral("default") : decl.name;
|
||||
const exportName = hasModifier(decl, ModifierFlags.Default) ? createLiteral("default") : decl.name!;
|
||||
statements = appendExportStatement(statements, exportName, getLocalName(decl));
|
||||
excludeName = getTextOfIdentifierOrLiteral(exportName);
|
||||
}
|
||||
@@ -1221,7 +1221,7 @@ namespace ts {
|
||||
|
||||
node = updateFor(
|
||||
node,
|
||||
visitForInitializer(node.initializer),
|
||||
node.initializer && visitForInitializer(node.initializer),
|
||||
visitNode(node.condition, destructuringAndImportCallVisitor, isExpression),
|
||||
visitNode(node.incrementor, destructuringAndImportCallVisitor, isExpression),
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement)
|
||||
@@ -1289,12 +1289,8 @@ namespace ts {
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function visitForInitializer(node: ForInitializer): ForInitializer {
|
||||
if (!node) {
|
||||
return node;
|
||||
}
|
||||
|
||||
if (shouldHoistForInitializer(node)) {
|
||||
let expressions: Expression[];
|
||||
let expressions: Expression[] | undefined;
|
||||
for (const variable of node.declarations) {
|
||||
expressions = append(expressions, transformInitializedVariable(variable, /*isExportedDeclaration*/ false));
|
||||
if (!variable.initializer) {
|
||||
@@ -1598,9 +1594,9 @@ namespace ts {
|
||||
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
|
||||
currentSourceFile = undefined;
|
||||
moduleInfo = undefined;
|
||||
exportFunction = undefined;
|
||||
currentSourceFile = undefined!;
|
||||
moduleInfo = undefined!;
|
||||
exportFunction = undefined!;
|
||||
noSubstitution = undefined;
|
||||
}
|
||||
else {
|
||||
@@ -1841,7 +1837,7 @@ namespace ts {
|
||||
* @param name The name.
|
||||
*/
|
||||
function getExports(name: Identifier) {
|
||||
let exportedNames: Identifier[];
|
||||
let exportedNames: Identifier[] | undefined;
|
||||
if (!isGeneratedIdentifier(name)) {
|
||||
const valueDeclaration = resolver.getReferencedImportDeclaration(name)
|
||||
|| resolver.getReferencedValueDeclaration(name);
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace ts {
|
||||
let currentNamespace: ModuleDeclaration;
|
||||
let currentNamespaceContainerName: Identifier;
|
||||
let currentScope: SourceFile | Block | ModuleBlock | CaseBlock;
|
||||
let currentScopeFirstDeclarationsOfName: UnderscoreEscapedMap<Node>;
|
||||
let currentScopeFirstDeclarationsOfName: UnderscoreEscapedMap<Node> | undefined;
|
||||
|
||||
/**
|
||||
* Keeps track of whether expression substitution has been enabled for specific edge cases.
|
||||
@@ -121,7 +121,7 @@ namespace ts {
|
||||
const visited = saveStateAndInvoke(node, visitSourceFile);
|
||||
addEmitHelpers(visited, context.readEmitHelpers());
|
||||
|
||||
currentSourceFile = undefined;
|
||||
currentSourceFile = undefined!;
|
||||
return visited;
|
||||
}
|
||||
|
||||
@@ -625,7 +625,7 @@ namespace ts {
|
||||
|
||||
// Write any pending expressions from elided or moved computed property names
|
||||
if (some(pendingExpressions)) {
|
||||
statements.push(createStatement(inlineExpressions(pendingExpressions)));
|
||||
statements.push(createStatement(inlineExpressions(pendingExpressions!)));
|
||||
}
|
||||
pendingExpressions = savedPendingExpressions;
|
||||
|
||||
@@ -723,7 +723,7 @@ namespace ts {
|
||||
* @param name The name of the class.
|
||||
* @param facts Precomputed facts about the class.
|
||||
*/
|
||||
function createClassDeclarationHeadWithoutDecorators(node: ClassDeclaration, name: Identifier, facts: ClassFacts) {
|
||||
function createClassDeclarationHeadWithoutDecorators(node: ClassDeclaration, name: Identifier | undefined, facts: ClassFacts) {
|
||||
// ${modifiers} class ${name} ${heritageClauses} {
|
||||
// ${members}
|
||||
// }
|
||||
@@ -759,7 +759,7 @@ namespace ts {
|
||||
* Transforms a decorated class declaration and appends the resulting statements. If
|
||||
* the class requires an alias to avoid issues with double-binding, the alias is returned.
|
||||
*/
|
||||
function createClassDeclarationHeadWithDecorators(node: ClassDeclaration, name: Identifier, facts: ClassFacts) {
|
||||
function createClassDeclarationHeadWithDecorators(node: ClassDeclaration, name: Identifier | undefined, facts: ClassFacts) {
|
||||
// When we emit an ES6 class that has a class decorator, we must tailor the
|
||||
// emit to certain specific cases.
|
||||
//
|
||||
@@ -998,7 +998,7 @@ namespace ts {
|
||||
*
|
||||
* @param constructor The constructor declaration.
|
||||
*/
|
||||
function transformConstructorParameters(constructor: ConstructorDeclaration) {
|
||||
function transformConstructorParameters(constructor: ConstructorDeclaration | undefined) {
|
||||
// The ES2015 spec specifies in 14.5.14. Runtime Semantics: ClassDefinitionEvaluation:
|
||||
// If constructor is empty, then
|
||||
// If ClassHeritag_eopt is present and protoParent is not null, then
|
||||
@@ -1026,7 +1026,7 @@ namespace ts {
|
||||
* @param constructor The current class constructor.
|
||||
* @param isDerivedClass A value indicating whether the class has an extends clause that does not extend 'null'.
|
||||
*/
|
||||
function transformConstructorBody(node: ClassExpression | ClassDeclaration, constructor: ConstructorDeclaration, isDerivedClass: boolean) {
|
||||
function transformConstructorBody(node: ClassExpression | ClassDeclaration, constructor: ConstructorDeclaration | undefined, isDerivedClass: boolean) {
|
||||
let statements: Statement[] = [];
|
||||
let indexOfFirstStatement = 0;
|
||||
|
||||
@@ -1081,7 +1081,7 @@ namespace ts {
|
||||
|
||||
if (constructor) {
|
||||
// The class already had a constructor, so we should add the existing statements, skipping the initial super call.
|
||||
addRange(statements, visitNodes(constructor.body.statements, visitor, isStatement, indexOfFirstStatement));
|
||||
addRange(statements, visitNodes(constructor.body!.statements, visitor, isStatement, indexOfFirstStatement));
|
||||
}
|
||||
|
||||
// End the lexical environment.
|
||||
@@ -1090,7 +1090,7 @@ namespace ts {
|
||||
createBlock(
|
||||
setTextRange(
|
||||
createNodeArray(statements),
|
||||
/*location*/ constructor ? constructor.body.statements : node.members
|
||||
/*location*/ constructor ? constructor.body!.statements : node.members
|
||||
),
|
||||
/*multiLine*/ true
|
||||
),
|
||||
@@ -1266,7 +1266,7 @@ namespace ts {
|
||||
const propertyName = isComputedPropertyName(property.name) && !isSimpleInlineableExpression(property.name.expression)
|
||||
? updateComputedPropertyName(property.name, getGeneratedNameForNode(property.name))
|
||||
: property.name;
|
||||
const initializer = visitNode(property.initializer, visitor, isExpression);
|
||||
const initializer = visitNode(property.initializer!, visitor, isExpression);
|
||||
const memberAccess = createMemberAccessForPropertyName(receiver, propertyName, /*location*/ propertyName);
|
||||
|
||||
return createAssignment(memberAccess, initializer);
|
||||
@@ -1319,8 +1319,8 @@ namespace ts {
|
||||
* A structure describing the decorators for a class element.
|
||||
*/
|
||||
interface AllDecorators {
|
||||
decorators: ReadonlyArray<Decorator>;
|
||||
parameters?: ReadonlyArray<ReadonlyArray<Decorator>>;
|
||||
decorators: ReadonlyArray<Decorator> | undefined;
|
||||
parameters?: ReadonlyArray<ReadonlyArray<Decorator> | undefined>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1329,8 +1329,8 @@ namespace ts {
|
||||
*
|
||||
* @param node The function-like node.
|
||||
*/
|
||||
function getDecoratorsOfParameters(node: FunctionLikeDeclaration) {
|
||||
let decorators: ReadonlyArray<Decorator>[];
|
||||
function getDecoratorsOfParameters(node: FunctionLikeDeclaration | undefined) {
|
||||
let decorators: (ReadonlyArray<Decorator> | undefined)[] | undefined;
|
||||
if (node) {
|
||||
const parameters = node.parameters;
|
||||
for (let i = 0; i < parameters.length; i++) {
|
||||
@@ -1354,7 +1354,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The class node.
|
||||
*/
|
||||
function getAllDecoratorsOfConstructor(node: ClassExpression | ClassDeclaration): AllDecorators {
|
||||
function getAllDecoratorsOfConstructor(node: ClassExpression | ClassDeclaration): AllDecorators | undefined {
|
||||
const decorators = node.decorators;
|
||||
const parameters = getDecoratorsOfParameters(getFirstConstructorWithBody(node));
|
||||
if (!decorators && !parameters) {
|
||||
@@ -1373,7 +1373,7 @@ namespace ts {
|
||||
* @param node The class node that contains the member.
|
||||
* @param member The class member.
|
||||
*/
|
||||
function getAllDecoratorsOfClassElement(node: ClassExpression | ClassDeclaration, member: ClassElement): AllDecorators {
|
||||
function getAllDecoratorsOfClassElement(node: ClassExpression | ClassDeclaration, member: ClassElement): AllDecorators | undefined {
|
||||
switch (member.kind) {
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
@@ -1396,7 +1396,7 @@ namespace ts {
|
||||
* @param node The class node that contains the accessor.
|
||||
* @param accessor The class accessor member.
|
||||
*/
|
||||
function getAllDecoratorsOfAccessors(node: ClassExpression | ClassDeclaration, accessor: AccessorDeclaration): AllDecorators {
|
||||
function getAllDecoratorsOfAccessors(node: ClassExpression | ClassDeclaration, accessor: AccessorDeclaration): AllDecorators | undefined {
|
||||
if (!accessor.body) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -1421,7 +1421,7 @@ namespace ts {
|
||||
*
|
||||
* @param method The class method member.
|
||||
*/
|
||||
function getAllDecoratorsOfMethod(method: MethodDeclaration): AllDecorators {
|
||||
function getAllDecoratorsOfMethod(method: MethodDeclaration): AllDecorators | undefined {
|
||||
if (!method.body) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -1440,7 +1440,7 @@ namespace ts {
|
||||
*
|
||||
* @param property The class property member.
|
||||
*/
|
||||
function getAllDecoratorsOfProperty(property: PropertyDeclaration): AllDecorators {
|
||||
function getAllDecoratorsOfProperty(property: PropertyDeclaration): AllDecorators | undefined {
|
||||
const decorators = property.decorators;
|
||||
if (!decorators) {
|
||||
return undefined;
|
||||
@@ -1456,7 +1456,7 @@ namespace ts {
|
||||
* @param node The declaration node.
|
||||
* @param allDecorators An object containing all of the decorators for the declaration.
|
||||
*/
|
||||
function transformAllDecoratorsOfDeclaration(node: Declaration, container: ClassLikeDeclaration, allDecorators: AllDecorators) {
|
||||
function transformAllDecoratorsOfDeclaration(node: Declaration, container: ClassLikeDeclaration, allDecorators: AllDecorators | undefined) {
|
||||
if (!allDecorators) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -1490,7 +1490,7 @@ namespace ts {
|
||||
*/
|
||||
function generateClassElementDecorationExpressions(node: ClassExpression | ClassDeclaration, isStatic: boolean) {
|
||||
const members = getDecoratedClassElements(node, isStatic);
|
||||
let expressions: Expression[];
|
||||
let expressions: Expression[] | undefined;
|
||||
for (const member of members) {
|
||||
const expression = generateClassElementDecorationExpression(node, member);
|
||||
if (expression) {
|
||||
@@ -1624,7 +1624,7 @@ namespace ts {
|
||||
* @param parameterOffset The offset of the parameter.
|
||||
*/
|
||||
function transformDecoratorsOfParameter(decorators: Decorator[], parameterOffset: number) {
|
||||
let expressions: Expression[];
|
||||
let expressions: Expression[] | undefined;
|
||||
if (decorators) {
|
||||
expressions = [];
|
||||
for (const decorator of decorators) {
|
||||
@@ -1672,7 +1672,7 @@ namespace ts {
|
||||
|
||||
function addNewTypeMetadata(node: Declaration, container: ClassLikeDeclaration, decoratorExpressions: Expression[]) {
|
||||
if (compilerOptions.emitDecoratorMetadata) {
|
||||
let properties: ObjectLiteralElementLike[];
|
||||
let properties: ObjectLiteralElementLike[] | undefined;
|
||||
if (shouldAddTypeMetadata(node)) {
|
||||
(properties || (properties = [])).push(createPropertyAssignment("type", createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, createToken(SyntaxKind.EqualsGreaterThanToken), serializeTypeOfNode(node))));
|
||||
}
|
||||
@@ -1837,7 +1837,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The type node to serialize.
|
||||
*/
|
||||
function serializeTypeNode(node: TypeNode): SerializedTypeNode {
|
||||
function serializeTypeNode(node: TypeNode | undefined): SerializedTypeNode {
|
||||
if (node === undefined) {
|
||||
return createIdentifier("Object");
|
||||
}
|
||||
@@ -1920,7 +1920,7 @@ namespace ts {
|
||||
function serializeUnionOrIntersectionType(node: UnionOrIntersectionTypeNode): SerializedTypeNode {
|
||||
// Note when updating logic here also update getEntityNameForDecoratorMetadata
|
||||
// so that aliases can be marked as referenced
|
||||
let serializedUnion: SerializedTypeNode;
|
||||
let serializedUnion: SerializedTypeNode | undefined;
|
||||
for (let typeNode of node.types) {
|
||||
while (typeNode.kind === SyntaxKind.ParenthesizedType) {
|
||||
typeNode = (typeNode as ParenthesizedTypeNode).type; // Skip parens if need be
|
||||
@@ -2102,7 +2102,7 @@ namespace ts {
|
||||
* @param member The member whose name should be converted into an expression.
|
||||
*/
|
||||
function getExpressionForPropertyName(member: ClassElement | EnumMember, generateNameForComputedPropertyName: boolean): Expression {
|
||||
const name = member.name;
|
||||
const name = member.name!;
|
||||
if (isComputedPropertyName(name)) {
|
||||
return generateNameForComputedPropertyName && !isSimpleInlineableExpression(name.expression)
|
||||
? getGeneratedNameForNode(name)
|
||||
@@ -2122,7 +2122,7 @@ namespace ts {
|
||||
* @param shouldHoist Does the expression need to be reused? (ie, for an initializer or a decorator)
|
||||
* @param omitSimple Should expressions with no observable side-effects be elided? (ie, the expression is not hoisted for a decorator or initializer and is a literal)
|
||||
*/
|
||||
function getPropertyNameExpressionIfNeeded(name: PropertyName, shouldHoist: boolean, omitSimple: boolean): Expression {
|
||||
function getPropertyNameExpressionIfNeeded(name: PropertyName, shouldHoist: boolean, omitSimple: boolean): Expression | undefined {
|
||||
if (isComputedPropertyName(name)) {
|
||||
const expression = visitNode(name.expression, visitor, isExpression);
|
||||
const innerExpression = skipPartiallyEmittedExpressions(expression);
|
||||
@@ -2144,7 +2144,7 @@ namespace ts {
|
||||
* @param member The member whose name should be visited.
|
||||
*/
|
||||
function visitPropertyNameOfClassElement(member: ClassElement): PropertyName {
|
||||
const name = member.name;
|
||||
const name = member.name!;
|
||||
let expr = getPropertyNameExpressionIfNeeded(name, some(member.decorators), /*omitSimple*/ false);
|
||||
if (expr) { // expr only exists if `name` is a computed property name
|
||||
// Inline any pending expressions from previous elided or relocated computed property name expressions in order to preserve execution order
|
||||
@@ -2168,7 +2168,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The HeritageClause to transform.
|
||||
*/
|
||||
function visitHeritageClause(node: HeritageClause): HeritageClause {
|
||||
function visitHeritageClause(node: HeritageClause): HeritageClause | undefined {
|
||||
if (node.token === SyntaxKind.ExtendsKeyword) {
|
||||
const types = visitNodes(node.types, visitor, isExpressionWithTypeArguments, 0, 1);
|
||||
return setTextRange(
|
||||
@@ -2455,7 +2455,7 @@ namespace ts {
|
||||
* This function will be called when one of the following conditions are met:
|
||||
* - The node is exported from a TypeScript namespace.
|
||||
*/
|
||||
function visitVariableStatement(node: VariableStatement): Statement {
|
||||
function visitVariableStatement(node: VariableStatement): Statement | undefined {
|
||||
if (isExportOfNamespace(node)) {
|
||||
const variables = getInitializedVariables(node.declarationList);
|
||||
if (variables.length === 0) {
|
||||
@@ -2493,7 +2493,7 @@ namespace ts {
|
||||
return setTextRange(
|
||||
createAssignment(
|
||||
getNamespaceMemberNameWithSourceMapsAndWithoutComments(name),
|
||||
visitNode(node.initializer, visitor, isExpression)
|
||||
visitNode(node.initializer!, visitor, isExpression)
|
||||
),
|
||||
/*location*/ node
|
||||
);
|
||||
@@ -2766,7 +2766,7 @@ namespace ts {
|
||||
* @param node The module declaration node.
|
||||
*/
|
||||
function shouldEmitModuleDeclaration(node: ModuleDeclaration) {
|
||||
return isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.isolatedModules);
|
||||
return isInstantiatedModule(node, !!compilerOptions.preserveConstEnums || !!compilerOptions.isolatedModules);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2984,8 +2984,8 @@ namespace ts {
|
||||
startLexicalEnvironment();
|
||||
|
||||
let statementsLocation: TextRange;
|
||||
let blockLocation: TextRange;
|
||||
const body = node.body;
|
||||
let blockLocation: TextRange | undefined;
|
||||
const body = node.body!;
|
||||
if (body.kind === SyntaxKind.ModuleBlock) {
|
||||
saveStateAndInvoke(body, body => addRange(statements, visitNodes((<ModuleBlock>body).statements, namespaceElementVisitor, isStatement)));
|
||||
statementsLocation = body.statements;
|
||||
@@ -3002,7 +3002,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
const moduleBlock = <ModuleBlock>getInnerMostModuleDeclarationFromDottedModule(node).body;
|
||||
const moduleBlock = <ModuleBlock>getInnerMostModuleDeclarationFromDottedModule(node)!.body;
|
||||
statementsLocation = moveRangePos(moduleBlock.statements, -1);
|
||||
}
|
||||
|
||||
@@ -3046,8 +3046,8 @@ namespace ts {
|
||||
return block;
|
||||
}
|
||||
|
||||
function getInnerMostModuleDeclarationFromDottedModule(moduleDeclaration: ModuleDeclaration): ModuleDeclaration {
|
||||
if (moduleDeclaration.body.kind === SyntaxKind.ModuleDeclaration) {
|
||||
function getInnerMostModuleDeclarationFromDottedModule(moduleDeclaration: ModuleDeclaration): ModuleDeclaration | undefined {
|
||||
if (moduleDeclaration.body!.kind === SyntaxKind.ModuleDeclaration) {
|
||||
const recursiveInnerModule = getInnerMostModuleDeclarationFromDottedModule(<ModuleDeclaration>moduleDeclaration.body);
|
||||
return recursiveInnerModule || <ModuleDeclaration>moduleDeclaration.body;
|
||||
}
|
||||
@@ -3138,7 +3138,7 @@ namespace ts {
|
||||
function visitExportDeclaration(node: ExportDeclaration): VisitResult<Statement> {
|
||||
if (!node.exportClause) {
|
||||
// Elide a star export if the module it references does not export a value.
|
||||
return compilerOptions.isolatedModules || resolver.moduleExportsSomeValue(node.moduleSpecifier) ? node : undefined;
|
||||
return compilerOptions.isolatedModules || resolver.moduleExportsSomeValue(node.moduleSpecifier!) ? node : undefined;
|
||||
}
|
||||
|
||||
if (!resolver.isValueAliasDeclaration(node)) {
|
||||
@@ -3494,7 +3494,7 @@ namespace ts {
|
||||
|| node;
|
||||
}
|
||||
|
||||
function trySubstituteClassAlias(node: Identifier): Expression {
|
||||
function trySubstituteClassAlias(node: Identifier): Expression | undefined {
|
||||
if (enabledSubstitutions & TypeScriptSubstitutionFlags.ClassAliases) {
|
||||
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ConstructorReferenceInClass) {
|
||||
// Due to the emit for class decorators, any reference to the class from inside of the class body
|
||||
@@ -3504,7 +3504,7 @@ namespace ts {
|
||||
// constructor references in static property initializers.
|
||||
const declaration = resolver.getReferencedValueDeclaration(node);
|
||||
if (declaration) {
|
||||
const classAlias = classAliases[declaration.id];
|
||||
const classAlias = classAliases[declaration.id!]; // TODO: GH#18217
|
||||
if (classAlias) {
|
||||
const clone = getSynthesizedClone(classAlias);
|
||||
setSourceMapRange(clone, node);
|
||||
@@ -3518,7 +3518,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function trySubstituteNamespaceExportedName(node: Identifier): Expression {
|
||||
function trySubstituteNamespaceExportedName(node: Identifier): Expression | undefined {
|
||||
// If this is explicitly a local name, do not substitute.
|
||||
if (enabledSubstitutions & applicableSubstitutions && !isGeneratedIdentifier(node) && !isLocalName(node)) {
|
||||
// If we are nested within a namespace declaration, we may need to qualifiy
|
||||
@@ -3569,7 +3569,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
function tryGetConstEnumValue(node: Node): string | number {
|
||||
function tryGetConstEnumValue(node: Node): string | number | undefined {
|
||||
if (compilerOptions.isolatedModules) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -10,19 +10,19 @@ namespace ts {
|
||||
externalHelpersImportDeclaration: ImportDeclaration | undefined; // import of external helpers
|
||||
exportSpecifiers: Map<ExportSpecifier[]>; // export specifiers by name
|
||||
exportedBindings: Identifier[][]; // exported names of local declarations
|
||||
exportedNames: Identifier[]; // all exported names local to module
|
||||
exportedNames: Identifier[] | undefined; // all exported names local to module
|
||||
exportEquals: ExportAssignment | undefined; // an export= declaration if one was present
|
||||
hasExportStarsToExportValues: boolean; // whether this module contains export*
|
||||
}
|
||||
|
||||
function containsDefaultReference(node: NamedImportBindings) {
|
||||
function containsDefaultReference(node: NamedImportBindings | undefined) {
|
||||
if (!node) return false;
|
||||
if (!isNamedImports(node)) return false;
|
||||
return some(node.elements, isNamedDefaultReference);
|
||||
}
|
||||
|
||||
function isNamedDefaultReference(e: ImportSpecifier) {
|
||||
return e.propertyName && e.propertyName.escapedText === InternalSymbolName.Default;
|
||||
function isNamedDefaultReference(e: ImportSpecifier): boolean {
|
||||
return e.propertyName !== undefined && e.propertyName.escapedText === InternalSymbolName.Default;
|
||||
}
|
||||
|
||||
export function chainBundle(transformSourceFile: (x: SourceFile) => SourceFile): (x: SourceFile | Bundle) => SourceFile | Bundle {
|
||||
@@ -37,7 +37,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function getImportNeedsImportStarHelper(node: ImportDeclaration) {
|
||||
export function getImportNeedsImportStarHelper(node: ImportDeclaration): boolean {
|
||||
if (!!getNamespaceDeclarationNode(node)) {
|
||||
return true;
|
||||
}
|
||||
@@ -56,9 +56,9 @@ namespace ts {
|
||||
return (defaultRefCount > 0 && defaultRefCount !== bindings.elements.length) || (!!(bindings.elements.length - defaultRefCount) && isDefaultImport(node));
|
||||
}
|
||||
|
||||
export function getImportNeedsImportDefaultHelper(node: ImportDeclaration) {
|
||||
export function getImportNeedsImportDefaultHelper(node: ImportDeclaration): boolean {
|
||||
// Import default is needed if there's a default import or a default ref and no other refs (meaning an import star helper wasn't requested)
|
||||
return !getImportNeedsImportStarHelper(node) && (isDefaultImport(node) || (node.importClause && isNamedImports(node.importClause.namedBindings) && containsDefaultReference(node.importClause.namedBindings)));
|
||||
return !getImportNeedsImportStarHelper(node) && (isDefaultImport(node) || (!!node.importClause && isNamedImports(node.importClause.namedBindings!) && containsDefaultReference(node.importClause.namedBindings))); // TODO: GH#18217
|
||||
}
|
||||
|
||||
export function collectExternalModuleInfo(sourceFile: SourceFile, resolver: EmitResolver, compilerOptions: CompilerOptions): ExternalModuleInfo {
|
||||
@@ -66,9 +66,9 @@ namespace ts {
|
||||
const exportSpecifiers = createMultiMap<ExportSpecifier>();
|
||||
const exportedBindings: Identifier[][] = [];
|
||||
const uniqueExports = createMap<boolean>();
|
||||
let exportedNames: Identifier[];
|
||||
let exportedNames: Identifier[] | undefined;
|
||||
let hasExportDefault = false;
|
||||
let exportEquals: ExportAssignment;
|
||||
let exportEquals: ExportAssignment | undefined;
|
||||
let hasExportStarsToExportValues = false;
|
||||
let hasImportStarOrImportDefault = false;
|
||||
|
||||
@@ -105,7 +105,7 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
// export { x, y }
|
||||
for (const specifier of (<ExportDeclaration>node).exportClause.elements) {
|
||||
for (const specifier of (<ExportDeclaration>node).exportClause!.elements) {
|
||||
if (!uniqueExports.get(idText(specifier.name))) {
|
||||
const name = specifier.propertyName || specifier.name;
|
||||
exportSpecifiers.add(idText(name), specifier);
|
||||
@@ -150,7 +150,7 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
// export function x() { }
|
||||
const name = (<FunctionDeclaration>node).name;
|
||||
const name = (<FunctionDeclaration>node).name!;
|
||||
if (!uniqueExports.get(idText(name))) {
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
|
||||
uniqueExports.set(idText(name), true);
|
||||
@@ -198,7 +198,7 @@ namespace ts {
|
||||
return { externalImports, exportSpecifiers, exportEquals, hasExportStarsToExportValues, exportedBindings, exportedNames, externalHelpersImportDeclaration };
|
||||
}
|
||||
|
||||
function collectExportedVariableInfo(decl: VariableDeclaration | BindingElement, uniqueExports: Map<boolean>, exportedNames: Identifier[]) {
|
||||
function collectExportedVariableInfo(decl: VariableDeclaration | BindingElement, uniqueExports: Map<boolean>, exportedNames: Identifier[] | undefined) {
|
||||
if (isBindingPattern(decl.name)) {
|
||||
for (const element of decl.name.elements) {
|
||||
if (!isOmittedExpression(element)) {
|
||||
|
||||
+7
-7
@@ -50,7 +50,7 @@ namespace ts {
|
||||
const commandLine = parseCommandLine(args);
|
||||
|
||||
// Configuration file name (if any)
|
||||
let configFileName: string;
|
||||
let configFileName: string | undefined;
|
||||
if (commandLine.options.locale) {
|
||||
validateLocaleAndSetLanguage(commandLine.options.locale, sys, commandLine.errors);
|
||||
}
|
||||
@@ -74,7 +74,7 @@ namespace ts {
|
||||
|
||||
if (commandLine.options.help || commandLine.options.all) {
|
||||
printVersion();
|
||||
printHelp(commandLine.options.all);
|
||||
printHelp(!!commandLine.options.all);
|
||||
return sys.exit(ExitStatus.Success);
|
||||
}
|
||||
|
||||
@@ -107,13 +107,13 @@ namespace ts {
|
||||
|
||||
if (commandLine.fileNames.length === 0 && !configFileName) {
|
||||
printVersion();
|
||||
printHelp(commandLine.options.all);
|
||||
printHelp(!!commandLine.options.all);
|
||||
return sys.exit(ExitStatus.Success);
|
||||
}
|
||||
|
||||
const commandLineOptions = commandLine.options;
|
||||
if (configFileName) {
|
||||
const configParseResult = parseConfigFileWithSystem(configFileName, commandLineOptions, sys, reportDiagnostic);
|
||||
const configParseResult = parseConfigFileWithSystem(configFileName, commandLineOptions, sys, reportDiagnostic)!; // TODO: GH#18217
|
||||
updateReportDiagnostic(configParseResult.options);
|
||||
if (isWatchSet(configParseResult.options)) {
|
||||
reportWatchModeWithoutSysSupport();
|
||||
@@ -168,7 +168,7 @@ namespace ts {
|
||||
}
|
||||
return compileUsingBuilder(rootNames, options, host, oldProgram, configFileParsingDiagnostics);
|
||||
};
|
||||
const emitFilesUsingBuilder = watchCompilerHost.afterProgramCreate;
|
||||
const emitFilesUsingBuilder = watchCompilerHost.afterProgramCreate!; // TODO: GH#18217
|
||||
watchCompilerHost.afterProgramCreate = builderProgram => {
|
||||
emitFilesUsingBuilder(builderProgram);
|
||||
reportStatistics(builderProgram.getProgram());
|
||||
@@ -180,7 +180,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function createWatchOfConfigFile(configParseResult: ParsedCommandLine, optionsToExtend: CompilerOptions) {
|
||||
const watchCompilerHost = createWatchCompilerHostOfConfigFile(configParseResult.options.configFilePath, optionsToExtend, sys, /*createProgram*/ undefined, reportDiagnostic, createWatchStatusReporter(configParseResult.options));
|
||||
const watchCompilerHost = createWatchCompilerHostOfConfigFile(configParseResult.options.configFilePath!, optionsToExtend, sys, /*createProgram*/ undefined, reportDiagnostic, createWatchStatusReporter(configParseResult.options)); // TODO: GH#18217
|
||||
updateWatchCompilationHost(watchCompilerHost);
|
||||
watchCompilerHost.configFileParsingResult = configParseResult;
|
||||
createWatchProgram(watchCompilerHost);
|
||||
@@ -302,7 +302,7 @@ namespace ts {
|
||||
// Sort our options by their names, (e.g. "--noImplicitAny" comes before "--watch")
|
||||
const optsList = showAllOptions ?
|
||||
sort(optionDeclarations, (a, b) => compareStringsCaseInsensitive(a.name, b.name)) :
|
||||
filter(optionDeclarations.slice(), v => v.showInSimplifiedHelpView);
|
||||
filter(optionDeclarations.slice(), v => !!v.showInSimplifiedHelpView);
|
||||
|
||||
// We want our descriptions to align at the same column in our output,
|
||||
// so we keep track of the longest option usage string.
|
||||
|
||||
+162
-156
@@ -574,13 +574,13 @@ namespace ts {
|
||||
kind: SyntaxKind;
|
||||
flags: NodeFlags;
|
||||
/* @internal */ modifierFlagsCache?: ModifierFlags;
|
||||
/* @internal */ transformFlags?: TransformFlags;
|
||||
/* @internal */ transformFlags: TransformFlags; // Flags for transforms, possibly undefined
|
||||
decorators?: NodeArray<Decorator>; // Array of decorators (in document order)
|
||||
modifiers?: ModifiersArray; // Array of modifiers
|
||||
/* @internal */ id?: number; // Unique id (used to look up NodeLinks)
|
||||
parent?: Node; // Parent node (initialized by binding)
|
||||
parent: Node; // Parent node (initialized by binding)
|
||||
/* @internal */ original?: Node; // The original node if this is an updated node.
|
||||
/* @internal */ symbol?: Symbol; // Symbol declared by node (initialized by binding)
|
||||
/* @internal */ symbol: Symbol; // Symbol declared by node (initialized by binding)
|
||||
/* @internal */ locals?: SymbolTable; // Locals associated with node (initialized by binding)
|
||||
/* @internal */ nextContainer?: Node; // Next container in declaration order (initialized by binding)
|
||||
/* @internal */ localSymbol?: Symbol; // Local symbol declared by node (initialized by binding only for exported nodes)
|
||||
@@ -667,7 +667,7 @@ namespace ts {
|
||||
|
||||
export interface NodeArray<T extends Node> extends ReadonlyArray<T>, TextRange {
|
||||
hasTrailingComma?: boolean;
|
||||
/* @internal */ transformFlags?: TransformFlags;
|
||||
/* @internal */ transformFlags: TransformFlags; // Flags for transforms, possibly undefined
|
||||
}
|
||||
|
||||
export interface Token<TKind extends SyntaxKind> extends Node {
|
||||
@@ -794,13 +794,13 @@ namespace ts {
|
||||
|
||||
export interface Decorator extends Node {
|
||||
kind: SyntaxKind.Decorator;
|
||||
parent?: NamedDeclaration;
|
||||
parent: NamedDeclaration;
|
||||
expression: LeftHandSideExpression;
|
||||
}
|
||||
|
||||
export interface TypeParameterDeclaration extends NamedDeclaration {
|
||||
kind: SyntaxKind.TypeParameter;
|
||||
parent?: DeclarationWithTypeParameters | InferTypeNode;
|
||||
parent: DeclarationWithTypeParameters | InferTypeNode;
|
||||
name: Identifier;
|
||||
constraint?: TypeNode;
|
||||
default?: TypeNode;
|
||||
@@ -814,7 +814,7 @@ namespace ts {
|
||||
name?: PropertyName;
|
||||
typeParameters?: NodeArray<TypeParameterDeclaration>;
|
||||
parameters: NodeArray<ParameterDeclaration>;
|
||||
type: TypeNode | undefined;
|
||||
type?: TypeNode;
|
||||
/* @internal */ typeArguments?: NodeArray<TypeNode>; // Used for quick info, replaces typeParameters for instantiated signatures
|
||||
}
|
||||
|
||||
@@ -845,7 +845,7 @@ namespace ts {
|
||||
|
||||
export interface VariableDeclaration extends NamedDeclaration {
|
||||
kind: SyntaxKind.VariableDeclaration;
|
||||
parent?: VariableDeclarationList | CatchClause;
|
||||
parent: VariableDeclarationList | CatchClause;
|
||||
name: BindingName; // Declared variable name
|
||||
exclamationToken?: ExclamationToken; // Optional definite assignment assertion
|
||||
type?: TypeNode; // Optional type annotation
|
||||
@@ -854,13 +854,13 @@ namespace ts {
|
||||
|
||||
export interface VariableDeclarationList extends Node {
|
||||
kind: SyntaxKind.VariableDeclarationList;
|
||||
parent?: VariableStatement | ForStatement | ForOfStatement | ForInStatement;
|
||||
parent: VariableStatement | ForStatement | ForOfStatement | ForInStatement;
|
||||
declarations: NodeArray<VariableDeclaration>;
|
||||
}
|
||||
|
||||
export interface ParameterDeclaration extends NamedDeclaration, JSDocContainer {
|
||||
kind: SyntaxKind.Parameter;
|
||||
parent?: SignatureDeclaration;
|
||||
parent: SignatureDeclaration;
|
||||
dotDotDotToken?: DotDotDotToken; // Present on rest parameter
|
||||
name: BindingName; // Declared parameter name.
|
||||
questionToken?: QuestionToken; // Present on optional parameter
|
||||
@@ -870,7 +870,7 @@ namespace ts {
|
||||
|
||||
export interface BindingElement extends NamedDeclaration {
|
||||
kind: SyntaxKind.BindingElement;
|
||||
parent?: BindingPattern;
|
||||
parent: BindingPattern;
|
||||
propertyName?: PropertyName; // Binding property name (in object binding pattern)
|
||||
dotDotDotToken?: DotDotDotToken; // Present on rest element (in object binding pattern)
|
||||
name: BindingName; // Declared binding element name
|
||||
@@ -955,13 +955,13 @@ namespace ts {
|
||||
|
||||
export interface ObjectBindingPattern extends Node {
|
||||
kind: SyntaxKind.ObjectBindingPattern;
|
||||
parent?: VariableDeclaration | ParameterDeclaration | BindingElement;
|
||||
parent: VariableDeclaration | ParameterDeclaration | BindingElement;
|
||||
elements: NodeArray<BindingElement>;
|
||||
}
|
||||
|
||||
export interface ArrayBindingPattern extends Node {
|
||||
kind: SyntaxKind.ArrayBindingPattern;
|
||||
parent?: VariableDeclaration | ParameterDeclaration | BindingElement;
|
||||
parent: VariableDeclaration | ParameterDeclaration | BindingElement;
|
||||
elements: NodeArray<ArrayBindingElement>;
|
||||
}
|
||||
|
||||
@@ -1004,7 +1004,7 @@ namespace ts {
|
||||
|
||||
export interface MethodSignature extends SignatureDeclarationBase, TypeElement {
|
||||
kind: SyntaxKind.MethodSignature;
|
||||
parent?: ObjectTypeDeclaration;
|
||||
parent: ObjectTypeDeclaration;
|
||||
name: PropertyName;
|
||||
}
|
||||
|
||||
@@ -1019,14 +1019,14 @@ namespace ts {
|
||||
// of the method, or use helpers like isObjectLiteralMethodDeclaration
|
||||
export interface MethodDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer {
|
||||
kind: SyntaxKind.MethodDeclaration;
|
||||
parent?: ClassLikeDeclaration | ObjectLiteralExpression;
|
||||
parent: ClassLikeDeclaration | ObjectLiteralExpression;
|
||||
name: PropertyName;
|
||||
body?: FunctionBody;
|
||||
}
|
||||
|
||||
export interface ConstructorDeclaration extends FunctionLikeDeclarationBase, ClassElement, JSDocContainer {
|
||||
kind: SyntaxKind.Constructor;
|
||||
parent?: ClassLikeDeclaration;
|
||||
parent: ClassLikeDeclaration;
|
||||
body?: FunctionBody;
|
||||
/* @internal */ returnFlowNode?: FlowNode;
|
||||
}
|
||||
@@ -1034,14 +1034,14 @@ namespace ts {
|
||||
/** For when we encounter a semicolon in a class declaration. ES6 allows these as class elements. */
|
||||
export interface SemicolonClassElement extends ClassElement {
|
||||
kind: SyntaxKind.SemicolonClassElement;
|
||||
parent?: ClassLikeDeclaration;
|
||||
parent: ClassLikeDeclaration;
|
||||
}
|
||||
|
||||
// See the comment on MethodDeclaration for the intuition behind GetAccessorDeclaration being a
|
||||
// ClassElement and an ObjectLiteralElement.
|
||||
export interface GetAccessorDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer {
|
||||
kind: SyntaxKind.GetAccessor;
|
||||
parent?: ClassLikeDeclaration | ObjectLiteralExpression;
|
||||
parent: ClassLikeDeclaration | ObjectLiteralExpression;
|
||||
name: PropertyName;
|
||||
body?: FunctionBody;
|
||||
}
|
||||
@@ -1050,7 +1050,7 @@ namespace ts {
|
||||
// ClassElement and an ObjectLiteralElement.
|
||||
export interface SetAccessorDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer {
|
||||
kind: SyntaxKind.SetAccessor;
|
||||
parent?: ClassLikeDeclaration | ObjectLiteralExpression;
|
||||
parent: ClassLikeDeclaration | ObjectLiteralExpression;
|
||||
name: PropertyName;
|
||||
body?: FunctionBody;
|
||||
}
|
||||
@@ -1059,7 +1059,7 @@ namespace ts {
|
||||
|
||||
export interface IndexSignatureDeclaration extends SignatureDeclarationBase, ClassElement, TypeElement {
|
||||
kind: SyntaxKind.IndexSignature;
|
||||
parent?: ObjectTypeDeclaration;
|
||||
parent: ObjectTypeDeclaration;
|
||||
}
|
||||
|
||||
export interface TypeNode extends Node {
|
||||
@@ -1117,7 +1117,7 @@ namespace ts {
|
||||
|
||||
export interface TypePredicateNode extends TypeNode {
|
||||
kind: SyntaxKind.TypePredicate;
|
||||
parent?: SignatureDeclaration;
|
||||
parent: SignatureDeclaration;
|
||||
parameterName: Identifier | ThisTypeNode;
|
||||
type: TypeNode;
|
||||
}
|
||||
@@ -1604,22 +1604,22 @@ namespace ts {
|
||||
export interface NumericLiteral extends LiteralExpression {
|
||||
kind: SyntaxKind.NumericLiteral;
|
||||
/* @internal */
|
||||
numericLiteralFlags?: TokenFlags;
|
||||
numericLiteralFlags: TokenFlags;
|
||||
}
|
||||
|
||||
export interface TemplateHead extends LiteralLikeNode {
|
||||
kind: SyntaxKind.TemplateHead;
|
||||
parent?: TemplateExpression;
|
||||
parent: TemplateExpression;
|
||||
}
|
||||
|
||||
export interface TemplateMiddle extends LiteralLikeNode {
|
||||
kind: SyntaxKind.TemplateMiddle;
|
||||
parent?: TemplateSpan;
|
||||
parent: TemplateSpan;
|
||||
}
|
||||
|
||||
export interface TemplateTail extends LiteralLikeNode {
|
||||
kind: SyntaxKind.TemplateTail;
|
||||
parent?: TemplateSpan;
|
||||
parent: TemplateSpan;
|
||||
}
|
||||
|
||||
export type TemplateLiteral = TemplateExpression | NoSubstitutionTemplateLiteral;
|
||||
@@ -1634,7 +1634,7 @@ namespace ts {
|
||||
// The template literal must have kind TemplateMiddleLiteral or TemplateTailLiteral.
|
||||
export interface TemplateSpan extends Node {
|
||||
kind: SyntaxKind.TemplateSpan;
|
||||
parent?: TemplateExpression;
|
||||
parent: TemplateExpression;
|
||||
expression: Expression;
|
||||
literal: TemplateMiddle | TemplateTail;
|
||||
}
|
||||
@@ -1653,7 +1653,7 @@ namespace ts {
|
||||
|
||||
export interface SpreadElement extends Expression {
|
||||
kind: SyntaxKind.SpreadElement;
|
||||
parent?: ArrayLiteralExpression | CallExpression | NewExpression;
|
||||
parent: ArrayLiteralExpression | CallExpression | NewExpression;
|
||||
expression: Expression;
|
||||
}
|
||||
|
||||
@@ -1724,7 +1724,7 @@ namespace ts {
|
||||
|
||||
export interface ExpressionWithTypeArguments extends NodeWithTypeArguments {
|
||||
kind: SyntaxKind.ExpressionWithTypeArguments;
|
||||
parent?: HeritageClause;
|
||||
parent: HeritageClause;
|
||||
expression: LeftHandSideExpression;
|
||||
}
|
||||
|
||||
@@ -1787,13 +1787,13 @@ namespace ts {
|
||||
export type JsxTagNameExpression = PrimaryExpression | PropertyAccessExpression;
|
||||
|
||||
export interface JsxAttributes extends ObjectLiteralExpressionBase<JsxAttributeLike> {
|
||||
parent?: JsxOpeningLikeElement;
|
||||
parent: JsxOpeningLikeElement;
|
||||
}
|
||||
|
||||
/// The opening element of a <Tag>...</Tag> JsxElement
|
||||
export interface JsxOpeningElement extends Expression {
|
||||
kind: SyntaxKind.JsxOpeningElement;
|
||||
parent?: JsxElement;
|
||||
parent: JsxElement;
|
||||
tagName: JsxTagNameExpression;
|
||||
typeArguments?: NodeArray<TypeNode>;
|
||||
attributes: JsxAttributes;
|
||||
@@ -1818,18 +1818,18 @@ namespace ts {
|
||||
/// The opening element of a <>...</> JsxFragment
|
||||
export interface JsxOpeningFragment extends Expression {
|
||||
kind: SyntaxKind.JsxOpeningFragment;
|
||||
parent?: JsxFragment;
|
||||
parent: JsxFragment;
|
||||
}
|
||||
|
||||
/// The closing element of a <>...</> JsxFragment
|
||||
export interface JsxClosingFragment extends Expression {
|
||||
kind: SyntaxKind.JsxClosingFragment;
|
||||
parent?: JsxFragment;
|
||||
parent: JsxFragment;
|
||||
}
|
||||
|
||||
export interface JsxAttribute extends ObjectLiteralElement {
|
||||
kind: SyntaxKind.JsxAttribute;
|
||||
parent?: JsxAttributes;
|
||||
parent: JsxAttributes;
|
||||
name: Identifier;
|
||||
/// JSX attribute initializers are optional; <X y /> is sugar for <X y={true} />
|
||||
initializer?: StringLiteral | JsxExpression;
|
||||
@@ -1837,19 +1837,19 @@ namespace ts {
|
||||
|
||||
export interface JsxSpreadAttribute extends ObjectLiteralElement {
|
||||
kind: SyntaxKind.JsxSpreadAttribute;
|
||||
parent?: JsxAttributes;
|
||||
parent: JsxAttributes;
|
||||
expression: Expression;
|
||||
}
|
||||
|
||||
export interface JsxClosingElement extends Node {
|
||||
kind: SyntaxKind.JsxClosingElement;
|
||||
parent?: JsxElement;
|
||||
parent: JsxElement;
|
||||
tagName: JsxTagNameExpression;
|
||||
}
|
||||
|
||||
export interface JsxExpression extends Expression {
|
||||
kind: SyntaxKind.JsxExpression;
|
||||
parent?: JsxElement | JsxAttributeLike;
|
||||
parent: JsxElement | JsxAttributeLike;
|
||||
dotDotDotToken?: Token<SyntaxKind.DotDotDotToken>;
|
||||
expression?: Expression;
|
||||
}
|
||||
@@ -1857,7 +1857,7 @@ namespace ts {
|
||||
export interface JsxText extends Node {
|
||||
kind: SyntaxKind.JsxText;
|
||||
containsOnlyWhiteSpaces: boolean;
|
||||
parent?: JsxElement;
|
||||
parent: JsxElement;
|
||||
}
|
||||
|
||||
export type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment;
|
||||
@@ -2009,20 +2009,20 @@ namespace ts {
|
||||
|
||||
export interface CaseBlock extends Node {
|
||||
kind: SyntaxKind.CaseBlock;
|
||||
parent?: SwitchStatement;
|
||||
parent: SwitchStatement;
|
||||
clauses: NodeArray<CaseOrDefaultClause>;
|
||||
}
|
||||
|
||||
export interface CaseClause extends Node {
|
||||
kind: SyntaxKind.CaseClause;
|
||||
parent?: CaseBlock;
|
||||
parent: CaseBlock;
|
||||
expression: Expression;
|
||||
statements: NodeArray<Statement>;
|
||||
}
|
||||
|
||||
export interface DefaultClause extends Node {
|
||||
kind: SyntaxKind.DefaultClause;
|
||||
parent?: CaseBlock;
|
||||
parent: CaseBlock;
|
||||
statements: NodeArray<Statement>;
|
||||
}
|
||||
|
||||
@@ -2036,7 +2036,7 @@ namespace ts {
|
||||
|
||||
export interface ThrowStatement extends Statement {
|
||||
kind: SyntaxKind.ThrowStatement;
|
||||
expression: Expression;
|
||||
expression?: Expression;
|
||||
}
|
||||
|
||||
export interface TryStatement extends Statement {
|
||||
@@ -2048,7 +2048,7 @@ namespace ts {
|
||||
|
||||
export interface CatchClause extends Node {
|
||||
kind: SyntaxKind.CatchClause;
|
||||
parent?: TryStatement;
|
||||
parent: TryStatement;
|
||||
variableDeclaration?: VariableDeclaration;
|
||||
block: Block;
|
||||
}
|
||||
@@ -2098,7 +2098,7 @@ namespace ts {
|
||||
|
||||
export interface HeritageClause extends Node {
|
||||
kind: SyntaxKind.HeritageClause;
|
||||
parent?: InterfaceDeclaration | ClassLikeDeclaration;
|
||||
parent: InterfaceDeclaration | ClassLikeDeclaration;
|
||||
token: SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword;
|
||||
types: NodeArray<ExpressionWithTypeArguments>;
|
||||
}
|
||||
@@ -2112,7 +2112,7 @@ namespace ts {
|
||||
|
||||
export interface EnumMember extends NamedDeclaration, JSDocContainer {
|
||||
kind: SyntaxKind.EnumMember;
|
||||
parent?: EnumDeclaration;
|
||||
parent: EnumDeclaration;
|
||||
// This does include ComputedPropertyName, but the parser will give an error
|
||||
// if it parses a ComputedPropertyName in an EnumMember
|
||||
name: PropertyName;
|
||||
@@ -2134,7 +2134,7 @@ namespace ts {
|
||||
|
||||
export interface ModuleDeclaration extends DeclarationStatement, JSDocContainer {
|
||||
kind: SyntaxKind.ModuleDeclaration;
|
||||
parent?: ModuleBody | SourceFile;
|
||||
parent: ModuleBody | SourceFile;
|
||||
name: ModuleName;
|
||||
body?: ModuleBody | JSDocNamespaceDeclaration;
|
||||
}
|
||||
@@ -2150,12 +2150,12 @@ namespace ts {
|
||||
|
||||
export interface JSDocNamespaceDeclaration extends ModuleDeclaration {
|
||||
name: Identifier;
|
||||
body: JSDocNamespaceBody;
|
||||
body?: JSDocNamespaceBody;
|
||||
}
|
||||
|
||||
export interface ModuleBlock extends Node, Statement {
|
||||
kind: SyntaxKind.ModuleBlock;
|
||||
parent?: ModuleDeclaration;
|
||||
parent: ModuleDeclaration;
|
||||
statements: NodeArray<Statement>;
|
||||
}
|
||||
|
||||
@@ -2168,7 +2168,7 @@ namespace ts {
|
||||
*/
|
||||
export interface ImportEqualsDeclaration extends DeclarationStatement, JSDocContainer {
|
||||
kind: SyntaxKind.ImportEqualsDeclaration;
|
||||
parent?: SourceFile | ModuleBlock;
|
||||
parent: SourceFile | ModuleBlock;
|
||||
name: Identifier;
|
||||
|
||||
// 'EntityName' for an internal module reference, 'ExternalModuleReference' for an external
|
||||
@@ -2178,8 +2178,8 @@ namespace ts {
|
||||
|
||||
export interface ExternalModuleReference extends Node {
|
||||
kind: SyntaxKind.ExternalModuleReference;
|
||||
parent?: ImportEqualsDeclaration;
|
||||
expression?: Expression;
|
||||
parent: ImportEqualsDeclaration;
|
||||
expression: Expression;
|
||||
}
|
||||
|
||||
// In case of:
|
||||
@@ -2188,7 +2188,7 @@ namespace ts {
|
||||
// ImportClause information is shown at its declaration below.
|
||||
export interface ImportDeclaration extends Statement {
|
||||
kind: SyntaxKind.ImportDeclaration;
|
||||
parent?: SourceFile | ModuleBlock;
|
||||
parent: SourceFile | ModuleBlock;
|
||||
importClause?: ImportClause;
|
||||
/** If this is not a StringLiteral it will be a grammar error. */
|
||||
moduleSpecifier: Expression;
|
||||
@@ -2204,14 +2204,14 @@ namespace ts {
|
||||
// import d, { a, b as x } from "mod" => name = d, namedBinding: NamedImports = { elements: [{ name: a }, { name: x, propertyName: b}]}
|
||||
export interface ImportClause extends NamedDeclaration {
|
||||
kind: SyntaxKind.ImportClause;
|
||||
parent?: ImportDeclaration;
|
||||
parent: ImportDeclaration;
|
||||
name?: Identifier; // Default binding
|
||||
namedBindings?: NamedImportBindings;
|
||||
}
|
||||
|
||||
export interface NamespaceImport extends NamedDeclaration {
|
||||
kind: SyntaxKind.NamespaceImport;
|
||||
parent?: ImportClause;
|
||||
parent: ImportClause;
|
||||
name: Identifier;
|
||||
}
|
||||
|
||||
@@ -2222,7 +2222,7 @@ namespace ts {
|
||||
|
||||
export interface ExportDeclaration extends DeclarationStatement {
|
||||
kind: SyntaxKind.ExportDeclaration;
|
||||
parent?: SourceFile | ModuleBlock;
|
||||
parent: SourceFile | ModuleBlock;
|
||||
/** Will not be assigned in the case of `export * from "foo";` */
|
||||
exportClause?: NamedExports;
|
||||
/** If this is not a StringLiteral it will be a grammar error. */
|
||||
@@ -2231,13 +2231,13 @@ namespace ts {
|
||||
|
||||
export interface NamedImports extends Node {
|
||||
kind: SyntaxKind.NamedImports;
|
||||
parent?: ImportClause;
|
||||
parent: ImportClause;
|
||||
elements: NodeArray<ImportSpecifier>;
|
||||
}
|
||||
|
||||
export interface NamedExports extends Node {
|
||||
kind: SyntaxKind.NamedExports;
|
||||
parent?: ExportDeclaration;
|
||||
parent: ExportDeclaration;
|
||||
elements: NodeArray<ExportSpecifier>;
|
||||
}
|
||||
|
||||
@@ -2245,14 +2245,14 @@ namespace ts {
|
||||
|
||||
export interface ImportSpecifier extends NamedDeclaration {
|
||||
kind: SyntaxKind.ImportSpecifier;
|
||||
parent?: NamedImports;
|
||||
parent: NamedImports;
|
||||
propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent)
|
||||
name: Identifier; // Declared name
|
||||
}
|
||||
|
||||
export interface ExportSpecifier extends NamedDeclaration {
|
||||
kind: SyntaxKind.ExportSpecifier;
|
||||
parent?: NamedExports;
|
||||
parent: NamedExports;
|
||||
propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent)
|
||||
name: Identifier; // Declared name
|
||||
}
|
||||
@@ -2265,7 +2265,7 @@ namespace ts {
|
||||
*/
|
||||
export interface ExportAssignment extends DeclarationStatement {
|
||||
kind: SyntaxKind.ExportAssignment;
|
||||
parent?: SourceFile;
|
||||
parent: SourceFile;
|
||||
isExportEquals?: boolean;
|
||||
expression: Expression;
|
||||
}
|
||||
@@ -2337,16 +2337,16 @@ namespace ts {
|
||||
|
||||
export interface JSDoc extends Node {
|
||||
kind: SyntaxKind.JSDocComment;
|
||||
parent?: HasJSDoc;
|
||||
tags: NodeArray<JSDocTag> | undefined;
|
||||
comment: string | undefined;
|
||||
parent: HasJSDoc;
|
||||
tags?: NodeArray<JSDocTag>;
|
||||
comment?: string;
|
||||
}
|
||||
|
||||
export interface JSDocTag extends Node {
|
||||
parent: JSDoc | JSDocTypeLiteral;
|
||||
atToken: AtToken;
|
||||
tagName: Identifier;
|
||||
comment: string | undefined;
|
||||
comment?: string;
|
||||
}
|
||||
|
||||
export interface JSDocUnknownTag extends JSDocTag {
|
||||
@@ -2373,12 +2373,12 @@ namespace ts {
|
||||
|
||||
export interface JSDocReturnTag extends JSDocTag {
|
||||
kind: SyntaxKind.JSDocReturnTag;
|
||||
typeExpression: JSDocTypeExpression;
|
||||
typeExpression?: JSDocTypeExpression;
|
||||
}
|
||||
|
||||
export interface JSDocTypeTag extends JSDocTag {
|
||||
kind: SyntaxKind.JSDocTypeTag;
|
||||
typeExpression: JSDocTypeExpression;
|
||||
typeExpression?: JSDocTypeExpression;
|
||||
}
|
||||
|
||||
export interface JSDocTypedefTag extends JSDocTag, NamedDeclaration {
|
||||
@@ -2475,7 +2475,7 @@ namespace ts {
|
||||
|
||||
// FlowLabel represents a junction with multiple possible preceding control flows.
|
||||
export interface FlowLabel extends FlowNodeBase {
|
||||
antecedents: FlowNode[];
|
||||
antecedents: FlowNode[] | undefined;
|
||||
}
|
||||
|
||||
// FlowAssignment represents a node that assigns a value to a narrowable reference,
|
||||
@@ -2518,7 +2518,7 @@ namespace ts {
|
||||
|
||||
export interface AmdDependency {
|
||||
path: string;
|
||||
name: string;
|
||||
name?: string;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -2557,10 +2557,10 @@ namespace ts {
|
||||
* (See `createRedirectSourceFile` in program.ts.)
|
||||
* The redirect will have this set. The redirected-to source file will be in `redirectTargetsSet`.
|
||||
*/
|
||||
/* @internal */ redirectInfo?: RedirectInfo | undefined;
|
||||
/* @internal */ redirectInfo?: RedirectInfo;
|
||||
|
||||
amdDependencies: ReadonlyArray<AmdDependency>;
|
||||
moduleName: string;
|
||||
moduleName?: string;
|
||||
referencedFiles: ReadonlyArray<FileReference>;
|
||||
typeReferenceDirectives: ReadonlyArray<FileReference>;
|
||||
languageVariant: LanguageVariant;
|
||||
@@ -2588,9 +2588,9 @@ namespace ts {
|
||||
* This is intended to be the first top-level import/export,
|
||||
* but could be arbitrarily nested (e.g. `import.meta`).
|
||||
*/
|
||||
/* @internal */ externalModuleIndicator: Node;
|
||||
/* @internal */ externalModuleIndicator?: Node;
|
||||
// The first node that causes this file to be a CommonJS module
|
||||
/* @internal */ commonJsModuleIndicator: Node;
|
||||
/* @internal */ commonJsModuleIndicator?: Node;
|
||||
|
||||
/* @internal */ identifiers: Map<string>; // Map from a string to an interned string
|
||||
/* @internal */ nodeCount: number;
|
||||
@@ -2618,7 +2618,7 @@ namespace ts {
|
||||
// Stores a mapping 'external module reference text' -> 'resolved file name' | undefined
|
||||
// It is used to resolve module names in the checker.
|
||||
// Content of this field should never be used directly - use getResolvedModuleFileName/setResolvedModuleFileName functions instead
|
||||
/* @internal */ resolvedModules: Map<ResolvedModuleFull | undefined>;
|
||||
/* @internal */ resolvedModules?: Map<ResolvedModuleFull | undefined>;
|
||||
/* @internal */ resolvedTypeReferenceDirectiveNames: Map<ResolvedTypeReferenceDirective>;
|
||||
/* @internal */ imports: ReadonlyArray<StringLiteralLike>;
|
||||
/**
|
||||
@@ -2631,7 +2631,7 @@ namespace ts {
|
||||
/* @internal */ moduleAugmentations: ReadonlyArray<StringLiteral | Identifier>;
|
||||
/* @internal */ patternAmbientModules?: PatternAmbientModule[];
|
||||
/* @internal */ ambientModuleNames: ReadonlyArray<string>;
|
||||
/* @internal */ checkJsDirective: CheckJsDirective | undefined;
|
||||
/* @internal */ checkJsDirective?: CheckJsDirective;
|
||||
/* @internal */ version: string;
|
||||
/* @internal */ pragmas: PragmaMap;
|
||||
/* @internal */ localJsxNamespace?: __String;
|
||||
@@ -2702,7 +2702,7 @@ namespace ts {
|
||||
data: string,
|
||||
writeByteOrderMark: boolean,
|
||||
onError: ((message: string) => void) | undefined,
|
||||
sourceFiles: ReadonlyArray<SourceFile>,
|
||||
sourceFiles?: ReadonlyArray<SourceFile>,
|
||||
) => void;
|
||||
|
||||
export class OperationCanceledException { }
|
||||
@@ -2714,6 +2714,7 @@ namespace ts {
|
||||
throwIfCancellationRequested(): void;
|
||||
}
|
||||
|
||||
// TODO: This should implement TypeCheckerHost but that's an internal type.
|
||||
export interface Program extends ScriptReferenceHost {
|
||||
|
||||
/**
|
||||
@@ -2861,8 +2862,8 @@ namespace ts {
|
||||
emitSkipped: boolean;
|
||||
/** Contains declaration emit diagnostics */
|
||||
diagnostics: ReadonlyArray<Diagnostic>;
|
||||
emittedFiles: string[]; // Array of files the compiler wrote to disk
|
||||
/* @internal */ sourceMaps: SourceMapData[]; // Array of sourceMapData if compiler emitted sourcemaps
|
||||
emittedFiles?: string[]; // Array of files the compiler wrote to disk
|
||||
/* @internal */ sourceMaps?: SourceMapData[]; // Array of sourceMapData if compiler emitted sourcemaps
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -2894,9 +2895,10 @@ namespace ts {
|
||||
getNullableType(type: Type, flags: TypeFlags): Type;
|
||||
getNonNullableType(type: Type): Type;
|
||||
|
||||
// TODO: GH#18217 `xToDeclaration` calls are frequently asserted as defined.
|
||||
/** Note that the resulting nodes cannot be checked. */
|
||||
typeToTypeNode(type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeNode;
|
||||
/* @internal */ typeToTypeNode(type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker): TypeNode; // tslint:disable-line unified-signatures
|
||||
typeToTypeNode(type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): TypeNode | undefined;
|
||||
/* @internal */ typeToTypeNode(type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker): TypeNode | undefined; // tslint:disable-line unified-signatures
|
||||
/** Note that the resulting nodes cannot be checked. */
|
||||
signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags): SignatureDeclaration & {typeArguments?: NodeArray<TypeNode>} | undefined;
|
||||
/** Note that the resulting nodes cannot be checked. */
|
||||
@@ -2931,7 +2933,7 @@ namespace ts {
|
||||
*/
|
||||
getExportSymbolOfSymbol(symbol: Symbol): Symbol;
|
||||
getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol | undefined;
|
||||
getTypeAtLocation(node: Node): Type;
|
||||
getTypeAtLocation(node: Node): Type | undefined;
|
||||
getTypeFromTypeNode(node: TypeNode): Type;
|
||||
|
||||
signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): string;
|
||||
@@ -2953,15 +2955,16 @@ namespace ts {
|
||||
getAugmentedPropertiesOfType(type: Type): Symbol[];
|
||||
getRootSymbols(symbol: Symbol): Symbol[];
|
||||
getContextualType(node: Expression): Type | undefined;
|
||||
/* @internal */ getContextualTypeForArgumentAtIndex(call: CallLikeExpression, argIndex: number): Type;
|
||||
/* @internal */ getContextualTypeForArgumentAtIndex(call: CallLikeExpression, argIndex: number): Type | undefined;
|
||||
/* @internal */ getContextualTypeForJsxAttribute(attribute: JsxAttribute | JsxSpreadAttribute): Type | undefined;
|
||||
/* @internal */ isContextSensitive(node: Expression | MethodDeclaration | ObjectLiteralElementLike | JsxAttributeLike): boolean;
|
||||
|
||||
/**
|
||||
* returns unknownSignature in the case of an error.
|
||||
* returns undefined if the node is not valid.
|
||||
* @param argumentCount Apparent number of arguments, passed in case of a possibly incomplete call. This should come from an ArgumentListInfo. See `signatureHelp.ts`.
|
||||
*/
|
||||
getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[], argumentCount?: number): Signature;
|
||||
getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[], argumentCount?: number): Signature | undefined;
|
||||
getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature | undefined;
|
||||
isImplementationOfOverload(node: SignatureDeclaration): boolean | undefined;
|
||||
isUndefinedSymbol(symbol: Symbol): boolean;
|
||||
@@ -2976,7 +2979,7 @@ namespace ts {
|
||||
/** Follow all aliases to get the original symbol. */
|
||||
getAliasedSymbol(symbol: Symbol): Symbol;
|
||||
/** Follow a *single* alias to get the immediately aliased symbol. */
|
||||
/* @internal */ getImmediateAliasedSymbol(symbol: Symbol): Symbol;
|
||||
/* @internal */ getImmediateAliasedSymbol(symbol: Symbol): Symbol | undefined;
|
||||
getExportsOfModule(moduleSymbol: Symbol): Symbol[];
|
||||
/** Unlike `getExportsOfModule`, this includes properties of an `export =` value. */
|
||||
/* @internal */ getExportsAndPropertiesOfModule(moduleSymbol: Symbol): Symbol[];
|
||||
@@ -3012,10 +3015,10 @@ namespace ts {
|
||||
/* @internal */ createArrayType(elementType: Type): Type;
|
||||
/* @internal */ createPromiseType(type: Type): Type;
|
||||
|
||||
/* @internal */ createAnonymousType(symbol: Symbol, members: SymbolTable, callSignatures: Signature[], constructSignatures: Signature[], stringIndexInfo: IndexInfo, numberIndexInfo: IndexInfo): Type;
|
||||
/* @internal */ createAnonymousType(symbol: Symbol, members: SymbolTable, callSignatures: Signature[], constructSignatures: Signature[], stringIndexInfo: IndexInfo | undefined, numberIndexInfo: IndexInfo | undefined): Type;
|
||||
/* @internal */ createSignature(
|
||||
declaration: SignatureDeclaration,
|
||||
typeParameters: TypeParameter[],
|
||||
typeParameters: TypeParameter[] | undefined,
|
||||
thisParameter: Symbol | undefined,
|
||||
parameters: Symbol[],
|
||||
resolvedReturnType: Type,
|
||||
@@ -3026,7 +3029,7 @@ namespace ts {
|
||||
): Signature;
|
||||
/* @internal */ createSymbol(flags: SymbolFlags, name: __String): TransientSymbol;
|
||||
/* @internal */ createIndexInfo(type: Type, isReadonly: boolean, declaration?: SignatureDeclaration): IndexInfo;
|
||||
/* @internal */ isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags, shouldComputeAliasToMarkVisible: boolean): SymbolAccessibilityResult;
|
||||
/* @internal */ isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node | undefined, meaning: SymbolFlags, shouldComputeAliasToMarkVisible: boolean): SymbolAccessibilityResult;
|
||||
/* @internal */ tryFindAmbientModuleWithoutAugmentations(moduleName: string): Symbol | undefined;
|
||||
|
||||
/* @internal */ getSymbolWalker(accept?: (symbol: Symbol) => boolean): SymbolWalker;
|
||||
@@ -3313,9 +3316,9 @@ namespace ts {
|
||||
/* @internal */
|
||||
export interface AllAccessorDeclarations {
|
||||
firstAccessor: AccessorDeclaration;
|
||||
secondAccessor: AccessorDeclaration;
|
||||
getAccessor: AccessorDeclaration;
|
||||
setAccessor: AccessorDeclaration;
|
||||
secondAccessor: AccessorDeclaration | undefined;
|
||||
getAccessor: AccessorDeclaration | undefined;
|
||||
setAccessor: AccessorDeclaration | undefined;
|
||||
}
|
||||
|
||||
/** Indicates how to serialize the name for a TypeReferenceNode when emitting decorator metadata */
|
||||
@@ -3342,9 +3345,9 @@ namespace ts {
|
||||
/* @internal */
|
||||
export interface EmitResolver {
|
||||
hasGlobalName(name: string): boolean;
|
||||
getReferencedExportContainer(node: Identifier, prefixLocals?: boolean): SourceFile | ModuleDeclaration | EnumDeclaration;
|
||||
getReferencedImportDeclaration(node: Identifier): Declaration;
|
||||
getReferencedDeclarationWithCollidingName(node: Identifier): Declaration;
|
||||
getReferencedExportContainer(node: Identifier, prefixLocals?: boolean): SourceFile | ModuleDeclaration | EnumDeclaration | undefined;
|
||||
getReferencedImportDeclaration(node: Identifier): Declaration | undefined;
|
||||
getReferencedDeclarationWithCollidingName(node: Identifier): Declaration | undefined;
|
||||
isDeclarationWithCollidingName(node: Declaration): boolean;
|
||||
isValueAliasDeclaration(node: Node): boolean;
|
||||
isReferencedAliasDeclaration(node: Node, checkChildren?: boolean): boolean;
|
||||
@@ -3352,28 +3355,28 @@ namespace ts {
|
||||
getNodeCheckFlags(node: Node): NodeCheckFlags;
|
||||
isDeclarationVisible(node: Declaration | AnyImportSyntax): boolean;
|
||||
isLateBound(node: Declaration): node is LateBoundDeclaration;
|
||||
collectLinkedAliases(node: Identifier): Node[];
|
||||
collectLinkedAliases(node: Identifier): Node[] | undefined;
|
||||
isImplementationOfOverload(node: FunctionLike): boolean | undefined;
|
||||
isRequiredInitializedParameter(node: ParameterDeclaration): boolean;
|
||||
isOptionalUninitializedParameterProperty(node: ParameterDeclaration): boolean;
|
||||
createTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker, addUndefined?: boolean): TypeNode;
|
||||
createReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker): TypeNode;
|
||||
createTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker): TypeNode;
|
||||
createTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker, addUndefined?: boolean): TypeNode | undefined;
|
||||
createReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined;
|
||||
createTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined;
|
||||
createLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): Expression;
|
||||
isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags, shouldComputeAliasToMarkVisible: boolean): SymbolAccessibilityResult;
|
||||
isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node | undefined, meaning: SymbolFlags | undefined, shouldComputeAliasToMarkVisible: boolean): SymbolAccessibilityResult;
|
||||
isEntityNameVisible(entityName: EntityNameOrEntityNameExpression, enclosingDeclaration: Node): SymbolVisibilityResult;
|
||||
// Returns the constant value this property access resolves to, or 'undefined' for a non-constant
|
||||
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): string | number;
|
||||
getReferencedValueDeclaration(reference: Identifier): Declaration;
|
||||
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): string | number | undefined;
|
||||
getReferencedValueDeclaration(reference: Identifier): Declaration | undefined;
|
||||
getTypeReferenceSerializationKind(typeName: EntityName, location?: Node): TypeReferenceSerializationKind;
|
||||
isOptionalParameter(node: ParameterDeclaration): boolean;
|
||||
moduleExportsSomeValue(moduleReferenceExpression: Expression): boolean;
|
||||
isArgumentsLocalBinding(node: Identifier): boolean;
|
||||
getExternalModuleFileFromDeclaration(declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration | ImportTypeNode): SourceFile;
|
||||
getTypeReferenceDirectivesForEntityName(name: EntityNameOrEntityNameExpression): string[];
|
||||
getTypeReferenceDirectivesForSymbol(symbol: Symbol, meaning?: SymbolFlags): string[];
|
||||
getExternalModuleFileFromDeclaration(declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration | ImportTypeNode): SourceFile | undefined;
|
||||
getTypeReferenceDirectivesForEntityName(name: EntityNameOrEntityNameExpression): string[] | undefined;
|
||||
getTypeReferenceDirectivesForSymbol(symbol: Symbol, meaning?: SymbolFlags): string[] | undefined;
|
||||
isLiteralConstDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): boolean;
|
||||
getJsxFactoryEntity(location?: Node): EntityName;
|
||||
getJsxFactoryEntity(location?: Node): EntityName | undefined;
|
||||
getAllAccessorDeclarations(declaration: AccessorDeclaration): AllAccessorDeclarations;
|
||||
}
|
||||
|
||||
@@ -3469,8 +3472,8 @@ namespace ts {
|
||||
export interface Symbol {
|
||||
flags: SymbolFlags; // Symbol flags
|
||||
escapedName: __String; // Name of symbol
|
||||
declarations?: Declaration[]; // Declarations associated with this symbol
|
||||
valueDeclaration?: Declaration; // First value declaration of the symbol
|
||||
declarations: Declaration[]; // Declarations associated with this symbol
|
||||
valueDeclaration: Declaration; // First value declaration of the symbol
|
||||
members?: SymbolTable; // Class, interface or object literal instance members
|
||||
exports?: SymbolTable; // Module exports
|
||||
globalExports?: SymbolTable; // Conditional global UMD exports
|
||||
@@ -3641,7 +3644,7 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export interface NodeLinks {
|
||||
flags?: NodeCheckFlags; // Set of flags specific to Node
|
||||
flags: NodeCheckFlags; // Set of flags specific to Node
|
||||
resolvedType?: Type; // Cached type of type node
|
||||
resolvedSignature?: Signature; // Cached signature of signature node or call expression
|
||||
resolvedSignatures?: Map<Signature[]>; // Cached signatures of jsx node
|
||||
@@ -3652,7 +3655,7 @@ namespace ts {
|
||||
isVisible?: boolean; // Is this node visible
|
||||
containsArgumentsReference?: boolean; // Whether a function-like declaration contains an 'arguments' reference
|
||||
hasReportedStatementInAmbientContext?: boolean; // Cache boolean if we report statements in ambient context
|
||||
jsxFlags?: JsxFlags; // flags for knowing what kind of element/attributes we're dealing with
|
||||
jsxFlags: JsxFlags; // flags for knowing what kind of element/attributes we're dealing with
|
||||
resolvedJsxElementAttributesType?: Type; // resolved element attributes type of a JSX openinglike element
|
||||
resolvedJsxElementAllAttributesType?: Type; // resolved all element attributes type of a JSX openinglike element
|
||||
hasSuperCall?: boolean; // recorded result when we try to find super-call. We only try to find one if this flag is undefined, indicating that we haven't made an attempt.
|
||||
@@ -3756,7 +3759,7 @@ namespace ts {
|
||||
flags: TypeFlags; // Flags
|
||||
/* @internal */ id: number; // Unique ID
|
||||
/* @internal */ checker: TypeChecker;
|
||||
symbol?: Symbol; // Symbol associated with type (if any)
|
||||
symbol: Symbol; // Symbol associated with type (if any)
|
||||
pattern?: DestructuringPattern; // Destructuring pattern represented by type (if any)
|
||||
aliasSymbol?: Symbol; // Alias associated with type
|
||||
aliasTypeArguments?: Type[]; // Alias type arguments (if any)
|
||||
@@ -3774,8 +3777,8 @@ namespace ts {
|
||||
// Numeric literal types (TypeFlags.NumberLiteral)
|
||||
export interface LiteralType extends Type {
|
||||
value: string | number; // Value of literal
|
||||
freshType?: LiteralType; // Fresh version of type
|
||||
regularType?: LiteralType; // Regular version of type
|
||||
freshType: LiteralType; // Fresh version of type
|
||||
regularType: LiteralType; // Regular version of type
|
||||
}
|
||||
|
||||
// Unique symbol types (TypeFlags.UniqueESSymbol)
|
||||
@@ -3820,25 +3823,25 @@ namespace ts {
|
||||
|
||||
/** Class and interface types (ObjectFlags.Class and ObjectFlags.Interface). */
|
||||
export interface InterfaceType extends ObjectType {
|
||||
typeParameters: TypeParameter[]; // Type parameters (undefined if non-generic)
|
||||
outerTypeParameters: TypeParameter[]; // Outer type parameters (undefined if none)
|
||||
localTypeParameters: TypeParameter[]; // Local type parameters (undefined if none)
|
||||
thisType: TypeParameter; // The "this" type (undefined if none)
|
||||
typeParameters: TypeParameter[] | undefined; // Type parameters (undefined if non-generic)
|
||||
outerTypeParameters: TypeParameter[] | undefined; // Outer type parameters (undefined if none)
|
||||
localTypeParameters: TypeParameter[] | undefined; // Local type parameters (undefined if none)
|
||||
thisType: TypeParameter | undefined; // The "this" type (undefined if none)
|
||||
/* @internal */
|
||||
resolvedBaseConstructorType?: Type; // Resolved base constructor type of class
|
||||
resolvedBaseConstructorType?: Type; // Resolved base constructor type of class
|
||||
/* @internal */
|
||||
resolvedBaseTypes: BaseType[]; // Resolved base types
|
||||
resolvedBaseTypes: BaseType[]; // Resolved base types
|
||||
}
|
||||
|
||||
// Object type or intersection of object types
|
||||
export type BaseType = ObjectType | IntersectionType;
|
||||
|
||||
export interface InterfaceTypeWithDeclaredMembers extends InterfaceType {
|
||||
declaredProperties: Symbol[]; // Declared members
|
||||
declaredCallSignatures: Signature[]; // Declared call signatures
|
||||
declaredConstructSignatures: Signature[]; // Declared construct signatures
|
||||
declaredStringIndexInfo: IndexInfo; // Declared string indexing info
|
||||
declaredNumberIndexInfo: IndexInfo; // Declared numeric indexing info
|
||||
declaredProperties: Symbol[]; // Declared members
|
||||
declaredCallSignatures: Signature[]; // Declared call signatures
|
||||
declaredConstructSignatures: Signature[]; // Declared construct signatures
|
||||
declaredStringIndexInfo?: IndexInfo; // Declared string indexing info
|
||||
declaredNumberIndexInfo?: IndexInfo; // Declared numeric indexing info
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3928,12 +3931,12 @@ namespace ts {
|
||||
/* @internal */
|
||||
// Resolved object, union, or intersection type
|
||||
export interface ResolvedType extends ObjectType, UnionOrIntersectionType {
|
||||
members: SymbolTable; // Properties by name
|
||||
properties: Symbol[]; // Properties
|
||||
callSignatures: Signature[]; // Call signatures of type
|
||||
constructSignatures: Signature[]; // Construct signatures of type
|
||||
stringIndexInfo?: IndexInfo; // String indexing info
|
||||
numberIndexInfo?: IndexInfo; // Numeric indexing info
|
||||
members: SymbolTable; // Properties by name
|
||||
properties: Symbol[]; // Properties
|
||||
callSignatures: Signature[]; // Call signatures of type
|
||||
constructSignatures: Signature[]; // Construct signatures of type
|
||||
stringIndexInfo?: IndexInfo; // String indexing info
|
||||
numberIndexInfo?: IndexInfo; // Numeric indexing info
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -4016,11 +4019,11 @@ namespace ts {
|
||||
trueType: Type;
|
||||
falseType: Type;
|
||||
isDistributive: boolean;
|
||||
inferTypeParameters: TypeParameter[];
|
||||
inferTypeParameters?: TypeParameter[];
|
||||
outerTypeParameters?: TypeParameter[];
|
||||
instantiations?: Map<Type>;
|
||||
aliasSymbol: Symbol;
|
||||
aliasTypeArguments: Type[];
|
||||
aliasSymbol?: Symbol;
|
||||
aliasTypeArguments?: Type[];
|
||||
}
|
||||
|
||||
// T extends U ? X : Y (TypeFlags.Conditional)
|
||||
@@ -4062,12 +4065,12 @@ namespace ts {
|
||||
thisParameter?: Symbol; // symbol of this-type parameter
|
||||
/* @internal */
|
||||
// See comment in `instantiateSignature` for why these are set lazily.
|
||||
resolvedReturnType: Type | undefined; // Lazily set by `getReturnTypeOfSignature`.
|
||||
resolvedReturnType?: Type; // Lazily set by `getReturnTypeOfSignature`.
|
||||
/* @internal */
|
||||
// Lazily set by `getTypePredicateOfSignature`.
|
||||
// `undefined` indicates a type predicate that has not yet been computed.
|
||||
// Uses a special `noTypePredicate` sentinel value to indicate that there is no type predicate. This looks like a TypePredicate at runtime to avoid polymorphism.
|
||||
resolvedTypePredicate: TypePredicate | undefined;
|
||||
resolvedTypePredicate?: TypePredicate;
|
||||
/* @internal */
|
||||
minArgumentCount: number; // Number of non-optional parameters
|
||||
/* @internal */
|
||||
@@ -4118,13 +4121,13 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export interface InferenceInfo {
|
||||
typeParameter: TypeParameter; // Type parameter for which inferences are being made
|
||||
candidates: Type[]; // Candidates in covariant positions (or undefined)
|
||||
contraCandidates: Type[]; // Candidates in contravariant positions (or undefined)
|
||||
inferredType: Type; // Cache for resolved inferred type
|
||||
priority: InferencePriority; // Priority of current inference set
|
||||
topLevel: boolean; // True if all inferences are to top level occurrences
|
||||
isFixed: boolean; // True if inferences are fixed
|
||||
typeParameter: TypeParameter; // Type parameter for which inferences are being made
|
||||
candidates: Type[] | undefined; // Candidates in covariant positions (or undefined)
|
||||
contraCandidates: Type[] | undefined; // Candidates in contravariant positions (or undefined)
|
||||
inferredType?: Type; // Cache for resolved inferred type
|
||||
priority?: InferencePriority; // Priority of current inference set
|
||||
topLevel: boolean; // True if all inferences are to top level occurrences
|
||||
isFixed: boolean; // True if inferences are fixed
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -4157,7 +4160,7 @@ namespace ts {
|
||||
/* @internal */
|
||||
export interface InferenceContext extends TypeMapper {
|
||||
typeParameters: TypeParameter[]; // Type parameters for which inferences are made
|
||||
signature: Signature; // Generic signature for which inferences are made (if any)
|
||||
signature?: Signature; // Generic signature for which inferences are made (if any)
|
||||
inferences: InferenceInfo[]; // Inferences made for each type parameter
|
||||
flags: InferenceFlags; // Inference flags
|
||||
compareTypes: TypeComparer; // Type comparer function
|
||||
@@ -4355,7 +4358,7 @@ namespace ts {
|
||||
suppressExcessPropertyErrors?: boolean;
|
||||
suppressImplicitAnyIndexErrors?: boolean;
|
||||
/* @internal */ suppressOutputPathCheck?: boolean;
|
||||
target?: ScriptTarget;
|
||||
target?: ScriptTarget; // TODO: GH#18217 frequently asserted as defined
|
||||
traceResolution?: boolean;
|
||||
resolveJsonModule?: boolean;
|
||||
types?: string[];
|
||||
@@ -4462,18 +4465,18 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export interface ConfigFileSpecs {
|
||||
filesSpecs: ReadonlyArray<string>;
|
||||
filesSpecs: ReadonlyArray<string> | undefined;
|
||||
referencesSpecs: ReadonlyArray<ProjectReference> | undefined;
|
||||
/**
|
||||
* Present to report errors (user specified specs), validatedIncludeSpecs are used for file name matching
|
||||
*/
|
||||
includeSpecs: ReadonlyArray<string>;
|
||||
includeSpecs?: ReadonlyArray<string>;
|
||||
/**
|
||||
* Present to report errors (user specified specs), validatedExcludeSpecs are used for file name matching
|
||||
*/
|
||||
excludeSpecs: ReadonlyArray<string>;
|
||||
validatedIncludeSpecs: ReadonlyArray<string>;
|
||||
validatedExcludeSpecs: ReadonlyArray<string>;
|
||||
excludeSpecs?: ReadonlyArray<string>;
|
||||
validatedIncludeSpecs?: ReadonlyArray<string>;
|
||||
validatedExcludeSpecs?: ReadonlyArray<string>;
|
||||
wildcardDirectories: MapLike<WatchDirectoryFlags>;
|
||||
}
|
||||
|
||||
@@ -4671,6 +4674,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
export interface ModuleResolutionHost {
|
||||
// TODO: GH#18217 Optional methods frequently used as non-optional
|
||||
|
||||
fileExists(fileName: string): boolean;
|
||||
// readFile function is used to read arbitrary text files on disk, i.e. when resolution procedure needs the content of 'package.json'
|
||||
// to determine location of bundled typings for node module
|
||||
@@ -4760,7 +4765,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export interface ResolvedTypeReferenceDirectiveWithFailedLookupLocations {
|
||||
readonly resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective;
|
||||
readonly resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective | undefined;
|
||||
readonly failedLookupLocations: ReadonlyArray<string>;
|
||||
}
|
||||
|
||||
@@ -4792,8 +4797,8 @@ namespace ts {
|
||||
/**
|
||||
* This method is a companion for 'resolveModuleNames' and is used to resolve 'types' references to actual type declaration files
|
||||
*/
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): (ResolvedTypeReferenceDirective | undefined)[];
|
||||
getEnvironmentVariable?(name: string): string;
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
getEnvironmentVariable?(name: string): string | undefined;
|
||||
/* @internal */ onReleaseOldSourceFile?(oldSourceFile: SourceFile, oldOptions: CompilerOptions): void;
|
||||
/* @internal */ hasInvalidatedResolution?: HasInvalidatedResolution;
|
||||
/* @internal */ hasChangedAutomaticTypeDirectiveNames?: boolean;
|
||||
@@ -4897,12 +4902,12 @@ namespace ts {
|
||||
/* @internal */
|
||||
export interface EmitNode {
|
||||
annotatedNodes?: Node[]; // Tracks Parse-tree nodes with EmitNodes for eventual cleanup.
|
||||
flags?: EmitFlags; // Flags that customize emit
|
||||
flags: EmitFlags; // Flags that customize emit
|
||||
leadingComments?: SynthesizedComment[]; // Synthesized leading comments
|
||||
trailingComments?: SynthesizedComment[]; // Synthesized trailing comments
|
||||
commentRange?: TextRange; // The text range to use when emitting leading or trailing comments
|
||||
sourceMapRange?: SourceMapRange; // The text range to use when emitting leading or trailing source mappings
|
||||
tokenSourceMapRanges?: SourceMapRange[]; // The text range to use when emitting source mappings for tokens
|
||||
tokenSourceMapRanges?: (SourceMapRange | undefined)[]; // The text range to use when emitting source mappings for tokens
|
||||
constantValue?: string | number; // The constant value of an expression
|
||||
externalHelpersModuleName?: Identifier; // The local name for an imported helpers module
|
||||
helpers?: EmitHelper[]; // Emit helpers for the node
|
||||
@@ -4910,6 +4915,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export const enum EmitFlags {
|
||||
None = 0,
|
||||
SingleLine = 1 << 0, // The contents of this node should be emitted on a single line.
|
||||
AdviseOnEmitNode = 1 << 1, // The printer should invoke the onEmitNode callback when printing this node.
|
||||
NoSubstitution = 1 << 2, // Disables further substitution of an expression.
|
||||
@@ -5040,7 +5046,7 @@ namespace ts {
|
||||
resumeLexicalEnvironment(): void;
|
||||
|
||||
/** Ends a lexical environment, returning any declarations. */
|
||||
endLexicalEnvironment(): Statement[];
|
||||
endLexicalEnvironment(): Statement[] | undefined;
|
||||
|
||||
/** Hoists a function declaration to the containing scope. */
|
||||
hoistFunctionDeclaration(node: FunctionDeclaration): void;
|
||||
@@ -5169,7 +5175,7 @@ namespace ts {
|
||||
*/
|
||||
printBundle(bundle: Bundle): string;
|
||||
/*@internal*/ writeNode(hint: EmitHint, node: Node, sourceFile: SourceFile | undefined, writer: EmitTextWriter): void;
|
||||
/*@internal*/ writeList<T extends Node>(format: ListFormat, list: NodeArray<T>, sourceFile: SourceFile | undefined, writer: EmitTextWriter): void;
|
||||
/*@internal*/ writeList<T extends Node>(format: ListFormat, list: NodeArray<T> | undefined, sourceFile: SourceFile | undefined, writer: EmitTextWriter): void;
|
||||
/*@internal*/ writeFile(sourceFile: SourceFile, writer: EmitTextWriter): void;
|
||||
/*@internal*/ writeBundle(bundle: Bundle, writer: EmitTextWriter, info?: BundleInfo): void;
|
||||
}
|
||||
@@ -5214,7 +5220,7 @@ namespace ts {
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
onEmitNode?(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
|
||||
onEmitNode?(hint: EmitHint, node: Node | undefined, emitCallback: (hint: EmitHint, node: Node | undefined) => void): void;
|
||||
/**
|
||||
* A hook used by the Printer to perform just-in-time substitution of a node. This is
|
||||
* primarily used by node transformations that need to substitute one node for another,
|
||||
@@ -5233,11 +5239,11 @@ namespace ts {
|
||||
*/
|
||||
substituteNode?(hint: EmitHint, node: Node): Node;
|
||||
/*@internal*/ onEmitSourceMapOfNode?: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void;
|
||||
/*@internal*/ onEmitSourceMapOfToken?: (node: Node, token: SyntaxKind, writer: (s: string) => void, pos: number, emitCallback: (token: SyntaxKind, writer: (s: string) => void, pos: number) => number) => number;
|
||||
/*@internal*/ onEmitSourceMapOfToken?: (node: Node | undefined, token: SyntaxKind, writer: (s: string) => void, pos: number, emitCallback: (token: SyntaxKind, writer: (s: string) => void, pos: number) => number) => number;
|
||||
/*@internal*/ onEmitSourceMapOfPosition?: (pos: number) => void;
|
||||
/*@internal*/ onSetSourceFile?: (node: SourceFile) => void;
|
||||
/*@internal*/ onBeforeEmitNodeArray?: (nodes: NodeArray<any>) => void;
|
||||
/*@internal*/ onAfterEmitNodeArray?: (nodes: NodeArray<any>) => void;
|
||||
/*@internal*/ onBeforeEmitNodeArray?: (nodes: NodeArray<any> | undefined) => void;
|
||||
/*@internal*/ onAfterEmitNodeArray?: (nodes: NodeArray<any> | undefined) => void;
|
||||
/*@internal*/ onBeforeEmitToken?: (node: Node) => void;
|
||||
/*@internal*/ onAfterEmitToken?: (node: Node) => void;
|
||||
}
|
||||
|
||||
+154
-137
@@ -6,7 +6,7 @@ namespace ts {
|
||||
|
||||
export const externalHelpersModuleNameText = "tslib";
|
||||
|
||||
export function getDeclarationOfKind<T extends Declaration>(symbol: Symbol, kind: T["kind"]): T {
|
||||
export function getDeclarationOfKind<T extends Declaration>(symbol: Symbol, kind: T["kind"]): T | undefined {
|
||||
const declarations = symbol.declarations;
|
||||
if (declarations) {
|
||||
for (const declaration of declarations) {
|
||||
@@ -103,7 +103,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function packageIdIsEqual(a: PackageId | undefined, b: PackageId | undefined): boolean {
|
||||
return a === b || a && b && a.name === b.name && a.subModuleName === b.subModuleName && a.version === b.version;
|
||||
return a === b || !!a && !!b && a.name === b.name && a.subModuleName === b.subModuleName && a.version === b.version;
|
||||
}
|
||||
|
||||
export function packageIdToString({ name, subModuleName, version }: PackageId): string {
|
||||
@@ -118,7 +118,7 @@ namespace ts {
|
||||
export function hasChangesInResolutions<T>(
|
||||
names: ReadonlyArray<string>,
|
||||
newResolutions: ReadonlyArray<T>,
|
||||
oldResolutions: ReadonlyMap<T>,
|
||||
oldResolutions: ReadonlyMap<T> | undefined,
|
||||
comparer: (oldResolution: T, newResolution: T) => boolean): boolean {
|
||||
Debug.assert(names.length === newResolutions.length);
|
||||
|
||||
@@ -162,6 +162,8 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function getSourceFileOfNode(node: Node): SourceFile;
|
||||
export function getSourceFileOfNode(node: Node | undefined): SourceFile | undefined;
|
||||
export function getSourceFileOfNode(node: Node): SourceFile {
|
||||
while (node && node.kind !== SyntaxKind.SourceFile) {
|
||||
node = node.parent;
|
||||
@@ -240,7 +242,7 @@ namespace ts {
|
||||
// code). So the parser will attempt to parse out a type, and will create an actual node.
|
||||
// However, this node will be 'missing' in the sense that no actual source-code/tokens are
|
||||
// contained within it.
|
||||
export function nodeIsMissing(node: Node) {
|
||||
export function nodeIsMissing(node: Node | undefined): boolean {
|
||||
if (node === undefined) {
|
||||
return true;
|
||||
}
|
||||
@@ -248,7 +250,7 @@ namespace ts {
|
||||
return node.pos === node.end && node.pos >= 0 && node.kind !== SyntaxKind.EndOfFileToken;
|
||||
}
|
||||
|
||||
export function nodeIsPresent(node: Node) {
|
||||
export function nodeIsPresent(node: Node | undefined): boolean {
|
||||
return !nodeIsMissing(node);
|
||||
}
|
||||
|
||||
@@ -290,7 +292,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (includeJsDoc && hasJSDocNodes(node)) {
|
||||
return getTokenPosOfNode(node.jsDoc[0]);
|
||||
return getTokenPosOfNode(node.jsDoc![0]);
|
||||
}
|
||||
|
||||
// For a syntax list, it is possible that one of its children has JSDocComment nodes, while
|
||||
@@ -343,9 +345,9 @@ namespace ts {
|
||||
/**
|
||||
* Gets flags that control emit behavior of a node.
|
||||
*/
|
||||
export function getEmitFlags(node: Node): EmitFlags | undefined {
|
||||
export function getEmitFlags(node: Node): EmitFlags {
|
||||
const emitNode = node.emitNode;
|
||||
return emitNode && emitNode.flags;
|
||||
return emitNode && emitNode.flags || 0;
|
||||
}
|
||||
|
||||
export function getLiteralText(node: LiteralLikeNode, sourceFile: SourceFile) {
|
||||
@@ -382,7 +384,7 @@ namespace ts {
|
||||
return node.text;
|
||||
}
|
||||
|
||||
Debug.fail(`Literal kind '${node.kind}' not accounted for.`);
|
||||
return Debug.fail(`Literal kind '${node.kind}' not accounted for.`);
|
||||
}
|
||||
|
||||
export function getTextOfConstantValue(value: string | number) {
|
||||
@@ -471,7 +473,7 @@ namespace ts {
|
||||
return isExternalModule(node) || compilerOptions.isolatedModules || ((getEmitModuleKind(compilerOptions) === ModuleKind.CommonJS) && !!node.commonJsModuleIndicator);
|
||||
}
|
||||
|
||||
export function isBlockScope(node: Node, parentNode: Node) {
|
||||
export function isBlockScope(node: Node, parentNode: Node): boolean {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.SourceFile:
|
||||
case SyntaxKind.CaseBlock:
|
||||
@@ -492,7 +494,7 @@ namespace ts {
|
||||
case SyntaxKind.Block:
|
||||
// function block is not considered block-scope container
|
||||
// see comment in binder.ts: bind(...), case for SyntaxKind.Block
|
||||
return parentNode && !isFunctionLike(parentNode);
|
||||
return !isFunctionLike(parentNode);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -564,7 +566,7 @@ namespace ts {
|
||||
// Gets the nearest enclosing block scope container that has the provided node
|
||||
// as a descendant, that is not the provided node.
|
||||
export function getEnclosingBlockScopeContainer(node: Node): Node {
|
||||
return findAncestor(node.parent, current => isBlockScope(current, current.parent));
|
||||
return findAncestor(node.parent, current => isBlockScope(current, current.parent))!;
|
||||
}
|
||||
|
||||
// Return display name of an identifier
|
||||
@@ -586,7 +588,7 @@ namespace ts {
|
||||
case SyntaxKind.NumericLiteral:
|
||||
return escapeLeadingUnderscores(name.text);
|
||||
case SyntaxKind.ComputedPropertyName:
|
||||
return isStringOrNumericLiteral(name.expression) ? escapeLeadingUnderscores(name.expression.text) : undefined;
|
||||
return isStringOrNumericLiteral(name.expression) ? escapeLeadingUnderscores(name.expression.text) : undefined!; // TODO: GH#18217 Almost all uses of this assume the result to be defined!
|
||||
default:
|
||||
Debug.assertNever(name);
|
||||
}
|
||||
@@ -600,6 +602,8 @@ namespace ts {
|
||||
return entityNameToString(name.left) + "." + entityNameToString(name.right);
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
return entityNameToString(name.expression) + "." + entityNameToString(name.name);
|
||||
default:
|
||||
throw Debug.assertNever(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -658,7 +662,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getErrorSpanForNode(sourceFile: SourceFile, node: Node): TextSpan {
|
||||
let errorNode = node;
|
||||
let errorNode: Node | undefined = node;
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.SourceFile:
|
||||
const pos = skipTrivia(sourceFile.text, 0, /*stopAfterLineBreak*/ false);
|
||||
@@ -817,8 +821,8 @@ namespace ts {
|
||||
// falls through
|
||||
case SyntaxKind.QualifiedName:
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
case SyntaxKind.ThisKeyword:
|
||||
const parent = node.parent;
|
||||
case SyntaxKind.ThisKeyword: {
|
||||
const { parent } = node;
|
||||
if (parent.kind === SyntaxKind.TypeQuery) {
|
||||
return false;
|
||||
}
|
||||
@@ -866,6 +870,7 @@ namespace ts {
|
||||
// TODO (drosen): TaggedTemplateExpressions may eventually support type arguments.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -883,11 +888,11 @@ namespace ts {
|
||||
|
||||
// Warning: This has the same semantics as the forEach family of functions,
|
||||
// in that traversal terminates in the event that 'visitor' supplies a truthy value.
|
||||
export function forEachReturnStatement<T>(body: Block, visitor: (stmt: ReturnStatement) => T): T {
|
||||
export function forEachReturnStatement<T>(body: Block, visitor: (stmt: ReturnStatement) => T): T | undefined {
|
||||
|
||||
return traverse(body);
|
||||
|
||||
function traverse(node: Node): T {
|
||||
function traverse(node: Node): T | undefined {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ReturnStatement:
|
||||
return visitor(<ReturnStatement>node);
|
||||
@@ -958,7 +963,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The type node.
|
||||
*/
|
||||
export function getRestParameterElementType(node: TypeNode) {
|
||||
export function getRestParameterElementType(node: TypeNode | undefined) {
|
||||
if (node && node.kind === SyntaxKind.ArrayType) {
|
||||
return (<ArrayTypeNode>node).elementType;
|
||||
}
|
||||
@@ -1008,7 +1013,7 @@ namespace ts {
|
||||
&& node.parent.parent.kind === SyntaxKind.VariableStatement;
|
||||
}
|
||||
|
||||
export function isValidESSymbolDeclaration(node: Node) {
|
||||
export function isValidESSymbolDeclaration(node: Node): node is VariableDeclaration | PropertyDeclaration | SignatureDeclaration {
|
||||
return isVariableDeclaration(node) ? isConst(node) && isIdentifier(node.name) && isVariableDeclarationInVariableStatement(node) :
|
||||
isPropertyDeclaration(node) ? hasReadonlyModifier(node) && hasStaticModifier(node) :
|
||||
isPropertySignature(node) && hasReadonlyModifier(node);
|
||||
@@ -1028,7 +1033,7 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function unwrapInnermostStatementOfLabel(node: LabeledStatement, beforeUnwrapLabelCallback?: (node: LabeledStatement) => void) {
|
||||
export function unwrapInnermostStatementOfLabel(node: LabeledStatement, beforeUnwrapLabelCallback?: (node: LabeledStatement) => void): Statement {
|
||||
while (true) {
|
||||
if (beforeUnwrapLabelCallback) {
|
||||
beforeUnwrapLabelCallback(node);
|
||||
@@ -1040,7 +1045,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function isFunctionBlock(node: Node) {
|
||||
export function isFunctionBlock(node: Node): boolean {
|
||||
return node && node.kind === SyntaxKind.Block && isFunctionLike(node.parent);
|
||||
}
|
||||
|
||||
@@ -1066,15 +1071,16 @@ namespace ts {
|
||||
return filter(objectLiteral.properties, (property): property is PropertyAssignment => {
|
||||
if (property.kind === SyntaxKind.PropertyAssignment) {
|
||||
const propName = getTextOfPropertyName(property.name);
|
||||
return key === propName || (key2 && key2 === propName);
|
||||
return key === propName || (!!key2 && key2 === propName);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
export function getTsConfigObjectLiteralExpression(tsConfigSourceFile: TsConfigSourceFile | undefined) {
|
||||
export function getTsConfigObjectLiteralExpression(tsConfigSourceFile: TsConfigSourceFile | undefined): ObjectLiteralExpression | undefined {
|
||||
if (tsConfigSourceFile && tsConfigSourceFile.statements.length) {
|
||||
const expression = tsConfigSourceFile.statements[0].expression;
|
||||
return isObjectLiteralExpression(expression) && expression;
|
||||
return tryCast(expression, isObjectLiteralExpression);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1087,19 +1093,20 @@ namespace ts {
|
||||
undefined);
|
||||
}
|
||||
|
||||
export function getContainingFunction(node: Node): SignatureDeclaration {
|
||||
export function getContainingFunction(node: Node): SignatureDeclaration | undefined {
|
||||
return findAncestor(node.parent, isFunctionLike);
|
||||
}
|
||||
|
||||
export function getContainingClass(node: Node): ClassLikeDeclaration {
|
||||
export function getContainingClass(node: Node): ClassLikeDeclaration | undefined {
|
||||
return findAncestor(node.parent, isClassLike);
|
||||
}
|
||||
|
||||
export function getThisContainer(node: Node, includeArrowFunctions: boolean): Node {
|
||||
Debug.assert(node.kind !== SyntaxKind.SourceFile);
|
||||
while (true) {
|
||||
node = node.parent;
|
||||
if (!node) {
|
||||
return undefined;
|
||||
return Debug.fail(); // If we never pass in a SourceFile, this should be unreachable, since we'll stop when we reach that.
|
||||
}
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ComputedPropertyName:
|
||||
@@ -1219,7 +1226,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function getImmediatelyInvokedFunctionExpression(func: Node): CallExpression {
|
||||
export function getImmediatelyInvokedFunctionExpression(func: Node): CallExpression | undefined {
|
||||
if (func.kind === SyntaxKind.FunctionExpression || func.kind === SyntaxKind.ArrowFunction) {
|
||||
let prev = func;
|
||||
let parent = func.parent;
|
||||
@@ -1251,7 +1258,7 @@ namespace ts {
|
||||
&& (<PropertyAccessExpression | ElementAccessExpression>node).expression.kind === SyntaxKind.ThisKeyword;
|
||||
}
|
||||
|
||||
export function getEntityNameFromTypeNode(node: TypeNode): EntityNameOrEntityNameExpression {
|
||||
export function getEntityNameFromTypeNode(node: TypeNode): EntityNameOrEntityNameExpression | undefined {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.TypeReference:
|
||||
return (<TypeReferenceNode>node).typeName;
|
||||
@@ -1292,22 +1299,22 @@ namespace ts {
|
||||
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
// property declarations are valid if their parent is a class declaration.
|
||||
return parent.kind === SyntaxKind.ClassDeclaration;
|
||||
return parent!.kind === SyntaxKind.ClassDeclaration;
|
||||
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
// if this method has a body and its parent is a class declaration, this is a valid target.
|
||||
return (<FunctionLikeDeclaration>node).body !== undefined
|
||||
&& parent.kind === SyntaxKind.ClassDeclaration;
|
||||
&& parent!.kind === SyntaxKind.ClassDeclaration;
|
||||
|
||||
case SyntaxKind.Parameter:
|
||||
// if the parameter's parent has a body and its grandparent is a class declaration, this is a valid target;
|
||||
return (<FunctionLikeDeclaration>parent).body !== undefined
|
||||
&& (parent.kind === SyntaxKind.Constructor
|
||||
|| parent.kind === SyntaxKind.MethodDeclaration
|
||||
|| parent.kind === SyntaxKind.SetAccessor)
|
||||
&& grandparent.kind === SyntaxKind.ClassDeclaration;
|
||||
&& (parent!.kind === SyntaxKind.Constructor
|
||||
|| parent!.kind === SyntaxKind.MethodDeclaration
|
||||
|| parent!.kind === SyntaxKind.SetAccessor)
|
||||
&& grandparent!.kind === SyntaxKind.ClassDeclaration;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -1318,14 +1325,14 @@ namespace ts {
|
||||
export function nodeIsDecorated(node: Node, parent: Node, grandparent: Node): boolean;
|
||||
export function nodeIsDecorated(node: Node, parent?: Node, grandparent?: Node): boolean {
|
||||
return node.decorators !== undefined
|
||||
&& nodeCanBeDecorated(node, parent, grandparent);
|
||||
&& nodeCanBeDecorated(node, parent!, grandparent!); // TODO: GH#18217
|
||||
}
|
||||
|
||||
export function nodeOrChildIsDecorated(node: ClassDeclaration): boolean;
|
||||
export function nodeOrChildIsDecorated(node: ClassElement, parent: Node): boolean;
|
||||
export function nodeOrChildIsDecorated(node: Node, parent: Node, grandparent: Node): boolean;
|
||||
export function nodeOrChildIsDecorated(node: Node, parent?: Node, grandparent?: Node): boolean {
|
||||
return nodeIsDecorated(node, parent, grandparent) || childIsDecorated(node, parent);
|
||||
return nodeIsDecorated(node, parent!, grandparent!) || childIsDecorated(node, parent!); // TODO: GH#18217
|
||||
}
|
||||
|
||||
export function childIsDecorated(node: ClassDeclaration): boolean;
|
||||
@@ -1333,15 +1340,17 @@ namespace ts {
|
||||
export function childIsDecorated(node: Node, parent?: Node): boolean {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
return forEach((<ClassDeclaration>node).members, m => nodeOrChildIsDecorated(m, node, parent));
|
||||
return some((<ClassDeclaration>node).members, m => nodeOrChildIsDecorated(m, node, parent!)); // TODO: GH#18217
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.SetAccessor:
|
||||
return forEach((<FunctionLikeDeclaration>node).parameters, p => nodeIsDecorated(p, node, parent));
|
||||
return some((<FunctionLikeDeclaration>node).parameters, p => nodeIsDecorated(p, node, parent!)); // TODO: GH#18217
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function isJSXTagName(node: Node) {
|
||||
const parent = node.parent;
|
||||
const { parent } = node;
|
||||
if (parent.kind === SyntaxKind.JsxOpeningElement ||
|
||||
parent.kind === SyntaxKind.JsxSelfClosingElement ||
|
||||
parent.kind === SyntaxKind.JsxClosingElement) {
|
||||
@@ -1409,7 +1418,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function isInExpressionContext(node: Node): boolean {
|
||||
const parent = node.parent;
|
||||
const { parent } = node;
|
||||
switch (parent.kind) {
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
case SyntaxKind.Parameter:
|
||||
@@ -1480,15 +1489,15 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function isInJavaScriptFile(node: Node | undefined): boolean {
|
||||
return node && !!(node.flags & NodeFlags.JavaScriptFile);
|
||||
return !!node && !!(node.flags & NodeFlags.JavaScriptFile);
|
||||
}
|
||||
|
||||
export function isInJsonFile(node: Node | undefined): boolean {
|
||||
return node && !!(node.flags & NodeFlags.JsonFile);
|
||||
return !!node && !!(node.flags & NodeFlags.JsonFile);
|
||||
}
|
||||
|
||||
export function isInJSDoc(node: Node | undefined): boolean {
|
||||
return node && !!(node.flags & NodeFlags.JSDoc);
|
||||
return !!node && !!(node.flags & NodeFlags.JSDoc);
|
||||
}
|
||||
|
||||
export function isJSDocIndexSignature(node: TypeReferenceNode | ExpressionWithTypeArguments) {
|
||||
@@ -1538,7 +1547,7 @@ namespace ts {
|
||||
* Container-like initializer behave like namespaces, so the binder needs to add contained symbols
|
||||
* to their exports. An example is a function with assignments to `this` inside.
|
||||
*/
|
||||
export function getJSInitializerSymbol(symbol: Symbol) {
|
||||
export function getJSInitializerSymbol(symbol: Symbol | undefined) {
|
||||
if (!symbol || !symbol.valueDeclaration) {
|
||||
return symbol;
|
||||
}
|
||||
@@ -1577,7 +1586,7 @@ namespace ts {
|
||||
*
|
||||
* This function returns the provided initializer, or undefined if it is not valid.
|
||||
*/
|
||||
export function getJavascriptInitializer(initializer: Node, isPrototypeAssignment: boolean): Expression {
|
||||
export function getJavascriptInitializer(initializer: Node, isPrototypeAssignment: boolean): Expression | undefined {
|
||||
if (isCallExpression(initializer)) {
|
||||
const e = skipParentheses(initializer.expression);
|
||||
return e.kind === SyntaxKind.FunctionExpression || e.kind === SyntaxKind.ArrowFunction ? initializer : undefined;
|
||||
@@ -1744,7 +1753,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function getExternalModuleName(node: AnyImportOrReExport | ImportTypeNode): Expression {
|
||||
export function getExternalModuleName(node: AnyImportOrReExport | ImportTypeNode): Expression | undefined {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
@@ -1758,7 +1767,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function getNamespaceDeclarationNode(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration): ImportEqualsDeclaration | NamespaceImport {
|
||||
export function getNamespaceDeclarationNode(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration): ImportEqualsDeclaration | NamespaceImport | undefined {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
return node.importClause && tryCast(node.importClause.namedBindings, isNamespaceImport);
|
||||
@@ -1771,8 +1780,8 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function isDefaultImport(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration) {
|
||||
return node.kind === SyntaxKind.ImportDeclaration && node.importClause && !!node.importClause.name;
|
||||
export function isDefaultImport(node: ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration): boolean {
|
||||
return node.kind === SyntaxKind.ImportDeclaration && !!node.importClause && !!node.importClause.name;
|
||||
}
|
||||
|
||||
export function hasQuestionToken(node: Node) {
|
||||
@@ -1807,20 +1816,22 @@ namespace ts {
|
||||
return isJSDocTypeAlias(node) || isTypeAliasDeclaration(node);
|
||||
}
|
||||
|
||||
function getSourceOfAssignment(node: Node): Node {
|
||||
function getSourceOfAssignment(node: Node): Node | undefined {
|
||||
return isExpressionStatement(node) &&
|
||||
node.expression && isBinaryExpression(node.expression) &&
|
||||
node.expression.operatorToken.kind === SyntaxKind.EqualsToken &&
|
||||
node.expression.right;
|
||||
node.expression.operatorToken.kind === SyntaxKind.EqualsToken
|
||||
? node.expression.right
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function getSourceOfDefaultedAssignment(node: Node): Node {
|
||||
function getSourceOfDefaultedAssignment(node: Node): Node | undefined {
|
||||
return isExpressionStatement(node) &&
|
||||
isBinaryExpression(node.expression) &&
|
||||
getSpecialPropertyAssignmentKind(node.expression) !== SpecialPropertyAssignmentKind.None &&
|
||||
isBinaryExpression(node.expression.right) &&
|
||||
node.expression.right.operatorToken.kind === SyntaxKind.BarBarToken &&
|
||||
node.expression.right.right;
|
||||
node.expression.right.operatorToken.kind === SyntaxKind.BarBarToken
|
||||
? node.expression.right.right
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function getSingleInitializerOfVariableStatementOrPropertyDeclaration(node: Node): Expression | undefined {
|
||||
@@ -1836,16 +1847,15 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getSingleVariableOfVariableStatement(node: Node): VariableDeclaration | undefined {
|
||||
return isVariableStatement(node) &&
|
||||
node.declarationList.declarations.length > 0 &&
|
||||
node.declarationList.declarations[0];
|
||||
return isVariableStatement(node) ? firstOrUndefined(node.declarationList.declarations) : undefined;
|
||||
}
|
||||
|
||||
function getNestedModuleDeclaration(node: Node): Node {
|
||||
return node.kind === SyntaxKind.ModuleDeclaration &&
|
||||
(node as ModuleDeclaration).body &&
|
||||
(node as ModuleDeclaration).body.kind === SyntaxKind.ModuleDeclaration &&
|
||||
(node as ModuleDeclaration).body;
|
||||
function getNestedModuleDeclaration(node: Node): Node | undefined {
|
||||
return isModuleDeclaration(node) &&
|
||||
node.body &&
|
||||
node.body.kind === SyntaxKind.ModuleDeclaration
|
||||
? node.body
|
||||
: undefined;
|
||||
}
|
||||
|
||||
export function getJSDocCommentsAndTags(hostNode: Node): ReadonlyArray<JSDoc | JSDocTag> {
|
||||
@@ -1885,8 +1895,8 @@ namespace ts {
|
||||
result = addRange(result, getJSDocParameterTags(node as ParameterDeclaration));
|
||||
}
|
||||
|
||||
if (isVariableLike(node) && hasInitializer(node) && node.initializer !== hostNode && hasJSDocNodes(node.initializer)) {
|
||||
result = addRange(result, node.initializer.jsDoc);
|
||||
if (isVariableLike(node) && hasInitializer(node) && node.initializer !== hostNode && hasJSDocNodes(node.initializer!)) {
|
||||
result = addRange(result, (node.initializer as HasJSDoc).jsDoc);
|
||||
}
|
||||
|
||||
if (hasJSDocNodes(node)) {
|
||||
@@ -1933,17 +1943,17 @@ namespace ts {
|
||||
export function getTypeParameterFromJsDoc(node: TypeParameterDeclaration & { parent: JSDocTemplateTag }): TypeParameterDeclaration | undefined {
|
||||
const name = node.name.escapedText;
|
||||
const { typeParameters } = (node.parent.parent.parent as SignatureDeclaration | InterfaceDeclaration | ClassDeclaration);
|
||||
return find(typeParameters, p => p.name.escapedText === name);
|
||||
return find(typeParameters!, p => p.name.escapedText === name);
|
||||
}
|
||||
|
||||
export function hasRestParameter(s: SignatureDeclaration | JSDocSignature): boolean {
|
||||
const last = lastOrUndefined<ParameterDeclaration | JSDocParameterTag>(s.parameters);
|
||||
return last && isRestParameter(last);
|
||||
return !!last && isRestParameter(last);
|
||||
}
|
||||
|
||||
export function isRestParameter(node: ParameterDeclaration | JSDocParameterTag): boolean {
|
||||
const type = isJSDocParameterTag(node) ? (node.typeExpression && node.typeExpression.type) : node.type;
|
||||
return (node as ParameterDeclaration).dotDotDotToken !== undefined || type && type.kind === SyntaxKind.JSDocVariadicType;
|
||||
return (node as ParameterDeclaration).dotDotDotToken !== undefined || !!type && type.kind === SyntaxKind.JSDocVariadicType;
|
||||
}
|
||||
|
||||
export const enum AssignmentKind {
|
||||
@@ -2108,9 +2118,10 @@ namespace ts {
|
||||
switch (name.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
if (isDeclaration(name.parent)) {
|
||||
return name.parent.name === name;
|
||||
case SyntaxKind.NumericLiteral: {
|
||||
const parent = name.parent;
|
||||
if (isDeclaration(parent)) {
|
||||
return parent.name === name;
|
||||
}
|
||||
else if (isQualifiedName(name.parent)) {
|
||||
const tag = name.parent.parent;
|
||||
@@ -2120,6 +2131,7 @@ namespace ts {
|
||||
const binExp = name.parent.parent;
|
||||
return isBinaryExpression(binExp) && getSpecialPropertyAssignmentKind(binExp) !== SpecialPropertyAssignmentKind.None && getNameOfDeclaration(binExp) === name;
|
||||
}
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -2213,7 +2225,7 @@ namespace ts {
|
||||
return heritageClause ? heritageClause.types : undefined;
|
||||
}
|
||||
|
||||
export function getHeritageClause(clauses: NodeArray<HeritageClause>, kind: SyntaxKind) {
|
||||
export function getHeritageClause(clauses: NodeArray<HeritageClause> | undefined, kind: SyntaxKind) {
|
||||
if (clauses) {
|
||||
for (const clause of clauses) {
|
||||
if (clause.token === kind) {
|
||||
@@ -2333,7 +2345,7 @@ namespace ts {
|
||||
*/
|
||||
export function hasDynamicName(declaration: Declaration): declaration is DynamicNamedDeclaration {
|
||||
const name = getNameOfDeclaration(declaration);
|
||||
return name && isDynamicName(name);
|
||||
return !!name && isDynamicName(name);
|
||||
}
|
||||
|
||||
export function isDynamicName(name: DeclarationName): boolean {
|
||||
@@ -2351,7 +2363,7 @@ namespace ts {
|
||||
return isPropertyAccessExpression(node) && isESSymbolIdentifier(node.expression);
|
||||
}
|
||||
|
||||
export function getPropertyNameForPropertyNameNode(name: DeclarationName): __String {
|
||||
export function getPropertyNameForPropertyNameNode(name: DeclarationName): __String | undefined {
|
||||
if (name.kind === SyntaxKind.Identifier) {
|
||||
return name.escapedText;
|
||||
}
|
||||
@@ -2643,8 +2655,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function createDiagnosticCollection(): DiagnosticCollection {
|
||||
let nonFileDiagnostics = [] as SortedArray<Diagnostic>;
|
||||
const filesWithDiagnostics = [] as SortedArray<string>;
|
||||
let nonFileDiagnostics = [] as Diagnostic[] as SortedArray<Diagnostic>; // See GH#19873
|
||||
const filesWithDiagnostics = [] as string[] as SortedArray<string>;
|
||||
const fileDiagnostics = createMap<SortedArray<DiagnosticWithLocation>>();
|
||||
let hasReadNonFileDiagnostics = false;
|
||||
|
||||
@@ -2660,11 +2672,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
function add(diagnostic: Diagnostic): void {
|
||||
let diagnostics: SortedArray<Diagnostic>;
|
||||
let diagnostics: SortedArray<Diagnostic> | undefined;
|
||||
if (diagnostic.file) {
|
||||
diagnostics = fileDiagnostics.get(diagnostic.file.fileName);
|
||||
if (!diagnostics) {
|
||||
diagnostics = [] as SortedArray<DiagnosticWithLocation>;
|
||||
diagnostics = [] as Diagnostic[] as SortedArray<DiagnosticWithLocation>; // See GH#19873
|
||||
fileDiagnostics.set(diagnostic.file.fileName, diagnostics as SortedArray<DiagnosticWithLocation>);
|
||||
insertSorted(filesWithDiagnostics, diagnostic.file.fileName, compareStringsCaseSensitive);
|
||||
}
|
||||
@@ -2826,7 +2838,7 @@ namespace ts {
|
||||
const lineStartsOfS = computeLineStarts(s);
|
||||
if (lineStartsOfS.length > 1) {
|
||||
lineCount = lineCount + lineStartsOfS.length - 1;
|
||||
linePos = output.length - s.length + lastOrUndefined(lineStartsOfS);
|
||||
linePos = output.length - s.length + last(lineStartsOfS);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2880,7 +2892,7 @@ namespace ts {
|
||||
return file.moduleName || getExternalModuleNameFromPath(host, file.fileName, referenceFile && referenceFile.fileName);
|
||||
}
|
||||
|
||||
export function getExternalModuleNameFromDeclaration(host: ModuleNameResolverHost, resolver: EmitResolver, declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration | ImportTypeNode): string {
|
||||
export function getExternalModuleNameFromDeclaration(host: ModuleNameResolverHost, resolver: EmitResolver, declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration | ImportTypeNode): string | undefined {
|
||||
const file = resolver.getExternalModuleFileFromDeclaration(declaration);
|
||||
if (!file || file.isDeclarationFile) {
|
||||
return undefined;
|
||||
@@ -2983,7 +2995,7 @@ namespace ts {
|
||||
return computeLineAndCharacterOfPosition(lineMap, pos).line;
|
||||
}
|
||||
|
||||
export function getFirstConstructorWithBody(node: ClassLikeDeclaration): ConstructorDeclaration {
|
||||
export function getFirstConstructorWithBody(node: ClassLikeDeclaration): ConstructorDeclaration | undefined {
|
||||
return find(node.members, (member): member is ConstructorDeclaration => isConstructorDeclaration(member) && nodeIsPresent(member.body));
|
||||
}
|
||||
|
||||
@@ -2995,7 +3007,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** Get the type annotation for the value parameter. */
|
||||
export function getSetAccessorTypeAnnotationNode(accessor: SetAccessorDeclaration): TypeNode {
|
||||
export function getSetAccessorTypeAnnotationNode(accessor: SetAccessorDeclaration): TypeNode | undefined {
|
||||
const parameter = getSetAccessorValueParameter(accessor);
|
||||
return parameter && parameter.type;
|
||||
}
|
||||
@@ -3015,7 +3027,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function isThisIdentifier(node: Node | undefined): boolean {
|
||||
return node && node.kind === SyntaxKind.Identifier && identifierIsThisKeyword(node as Identifier);
|
||||
return !!node && node.kind === SyntaxKind.Identifier && identifierIsThisKeyword(node as Identifier);
|
||||
}
|
||||
|
||||
export function identifierIsThisKeyword(id: Identifier): boolean {
|
||||
@@ -3023,10 +3035,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getAllAccessorDeclarations(declarations: NodeArray<Declaration>, accessor: AccessorDeclaration): AllAccessorDeclarations {
|
||||
let firstAccessor: AccessorDeclaration;
|
||||
let secondAccessor: AccessorDeclaration;
|
||||
let getAccessor: AccessorDeclaration;
|
||||
let setAccessor: AccessorDeclaration;
|
||||
// TODO: GH#18217
|
||||
let firstAccessor!: AccessorDeclaration;
|
||||
let secondAccessor!: AccessorDeclaration;
|
||||
let getAccessor!: AccessorDeclaration;
|
||||
let setAccessor!: AccessorDeclaration;
|
||||
if (hasDynamicName(accessor)) {
|
||||
firstAccessor = accessor;
|
||||
if (accessor.kind === SyntaxKind.GetAccessor) {
|
||||
@@ -3043,7 +3056,7 @@ namespace ts {
|
||||
forEach(declarations, (member: Declaration) => {
|
||||
if ((member.kind === SyntaxKind.GetAccessor || member.kind === SyntaxKind.SetAccessor)
|
||||
&& hasModifier(member, ModifierFlags.Static) === hasModifier(accessor, ModifierFlags.Static)) {
|
||||
const memberName = getPropertyNameForPropertyNameNode((member as NamedDeclaration).name);
|
||||
const memberName = getPropertyNameForPropertyNameNode((member as NamedDeclaration).name!);
|
||||
const accessorName = getPropertyNameForPropertyNameNode(accessor.name);
|
||||
if (memberName === accessorName) {
|
||||
if (!firstAccessor) {
|
||||
@@ -3126,16 +3139,16 @@ namespace ts {
|
||||
* Gets the effective type annotation of the value parameter of a set accessor. If the node
|
||||
* was parsed in a JavaScript file, gets the type annotation from JSDoc.
|
||||
*/
|
||||
export function getEffectiveSetAccessorTypeAnnotationNode(node: SetAccessorDeclaration): TypeNode {
|
||||
export function getEffectiveSetAccessorTypeAnnotationNode(node: SetAccessorDeclaration): TypeNode | undefined {
|
||||
const parameter = getSetAccessorValueParameter(node);
|
||||
return parameter && getEffectiveTypeAnnotationNode(parameter);
|
||||
}
|
||||
|
||||
export function emitNewLineBeforeLeadingComments(lineMap: ReadonlyArray<number>, writer: EmitTextWriter, node: TextRange, leadingComments: ReadonlyArray<CommentRange>) {
|
||||
export function emitNewLineBeforeLeadingComments(lineMap: ReadonlyArray<number>, writer: EmitTextWriter, node: TextRange, leadingComments: ReadonlyArray<CommentRange> | undefined) {
|
||||
emitNewLineBeforeLeadingCommentsOfPosition(lineMap, writer, node.pos, leadingComments);
|
||||
}
|
||||
|
||||
export function emitNewLineBeforeLeadingCommentsOfPosition(lineMap: ReadonlyArray<number>, writer: EmitTextWriter, pos: number, leadingComments: ReadonlyArray<CommentRange>) {
|
||||
export function emitNewLineBeforeLeadingCommentsOfPosition(lineMap: ReadonlyArray<number>, writer: EmitTextWriter, pos: number, leadingComments: ReadonlyArray<CommentRange> | undefined) {
|
||||
// If the leading comments start on different line than the start of node, write new line
|
||||
if (leadingComments && leadingComments.length && pos !== leadingComments[0].pos &&
|
||||
getLineOfLocalPositionFromLineMap(lineMap, pos) !== getLineOfLocalPositionFromLineMap(lineMap, leadingComments[0].pos)) {
|
||||
@@ -3155,7 +3168,7 @@ namespace ts {
|
||||
text: string,
|
||||
lineMap: ReadonlyArray<number>,
|
||||
writer: EmitTextWriter,
|
||||
comments: ReadonlyArray<CommentRange>,
|
||||
comments: ReadonlyArray<CommentRange> | undefined,
|
||||
leadingSeparator: boolean,
|
||||
trailingSeparator: boolean,
|
||||
newLine: string,
|
||||
@@ -3194,8 +3207,8 @@ namespace ts {
|
||||
export function emitDetachedComments(text: string, lineMap: ReadonlyArray<number>, writer: EmitTextWriter,
|
||||
writeComment: (text: string, lineMap: ReadonlyArray<number>, writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) => void,
|
||||
node: TextRange, newLine: string, removeComments: boolean) {
|
||||
let leadingComments: CommentRange[];
|
||||
let currentDetachedCommentInfo: { nodePos: number, detachedCommentEndPos: number };
|
||||
let leadingComments: CommentRange[] | undefined;
|
||||
let currentDetachedCommentInfo: { nodePos: number, detachedCommentEndPos: number } | undefined;
|
||||
if (removeComments) {
|
||||
// removeComments is true, only reserve pinned comment at the top of file
|
||||
// For example:
|
||||
@@ -3213,7 +3226,7 @@ namespace ts {
|
||||
|
||||
if (leadingComments) {
|
||||
const detachedComments: CommentRange[] = [];
|
||||
let lastComment: CommentRange;
|
||||
let lastComment: CommentRange | undefined;
|
||||
|
||||
for (const comment of leadingComments) {
|
||||
if (lastComment) {
|
||||
@@ -3236,13 +3249,13 @@ namespace ts {
|
||||
// All comments look like they could have been part of the copyright header. Make
|
||||
// sure there is at least one blank line between it and the node. If not, it's not
|
||||
// a copyright header.
|
||||
const lastCommentLine = getLineOfLocalPositionFromLineMap(lineMap, lastOrUndefined(detachedComments).end);
|
||||
const lastCommentLine = getLineOfLocalPositionFromLineMap(lineMap, last(detachedComments).end);
|
||||
const nodeLine = getLineOfLocalPositionFromLineMap(lineMap, skipTrivia(text, node.pos));
|
||||
if (nodeLine >= lastCommentLine + 2) {
|
||||
// Valid detachedComments
|
||||
emitNewLineBeforeLeadingComments(lineMap, writer, node, leadingComments);
|
||||
emitComments(text, lineMap, writer, detachedComments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, writeComment);
|
||||
currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: lastOrUndefined(detachedComments).end };
|
||||
currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: last(detachedComments).end };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3259,7 +3272,7 @@ namespace ts {
|
||||
if (text.charCodeAt(commentPos + 1) === CharacterCodes.asterisk) {
|
||||
const firstCommentLineAndCharacter = computeLineAndCharacterOfPosition(lineMap, commentPos);
|
||||
const lineCount = lineMap.length;
|
||||
let firstCommentLineIndent: number;
|
||||
let firstCommentLineIndent: number | undefined;
|
||||
for (let pos = commentPos, currentLine = firstCommentLineAndCharacter.line; pos < commentEnd; currentLine++) {
|
||||
const nextLineStart = (currentLine + 1) === lineCount
|
||||
? text.length + 1
|
||||
@@ -3373,8 +3386,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getModifierFlags(node: Node): ModifierFlags {
|
||||
if (node.modifierFlagsCache & ModifierFlags.HasComputedFlags) {
|
||||
return node.modifierFlagsCache & ~ModifierFlags.HasComputedFlags;
|
||||
if (node.modifierFlagsCache! & ModifierFlags.HasComputedFlags) {
|
||||
return node.modifierFlagsCache! & ~ModifierFlags.HasComputedFlags;
|
||||
}
|
||||
|
||||
const flags = getModifierFlagsNoCache(node);
|
||||
@@ -3427,8 +3440,8 @@ namespace ts {
|
||||
|
||||
/** Get `C` given `N` if `N` is in the position `class C extends N` where `N` is an ExpressionWithTypeArguments. */
|
||||
export function tryGetClassExtendingExpressionWithTypeArguments(node: Node): ClassLikeDeclaration | undefined {
|
||||
if (node.kind === SyntaxKind.ExpressionWithTypeArguments &&
|
||||
(<HeritageClause>node.parent).token === SyntaxKind.ExtendsKeyword &&
|
||||
if (isExpressionWithTypeArguments(node) &&
|
||||
node.parent.token === SyntaxKind.ExtendsKeyword &&
|
||||
isClassLike(node.parent.parent)) {
|
||||
return node.parent.parent;
|
||||
}
|
||||
@@ -3714,31 +3727,31 @@ namespace ts {
|
||||
return stableSort<[number, string]>(result, (x, y) => compareValues(x[0], y[0]));
|
||||
}
|
||||
|
||||
export function formatSyntaxKind(kind: SyntaxKind): string {
|
||||
export function formatSyntaxKind(kind: SyntaxKind | undefined): string {
|
||||
return formatEnum(kind, (<any>ts).SyntaxKind, /*isFlags*/ false);
|
||||
}
|
||||
|
||||
export function formatModifierFlags(flags: ModifierFlags): string {
|
||||
export function formatModifierFlags(flags: ModifierFlags | undefined): string {
|
||||
return formatEnum(flags, (<any>ts).ModifierFlags, /*isFlags*/ true);
|
||||
}
|
||||
|
||||
export function formatTransformFlags(flags: TransformFlags): string {
|
||||
export function formatTransformFlags(flags: TransformFlags | undefined): string {
|
||||
return formatEnum(flags, (<any>ts).TransformFlags, /*isFlags*/ true);
|
||||
}
|
||||
|
||||
export function formatEmitFlags(flags: EmitFlags): string {
|
||||
export function formatEmitFlags(flags: EmitFlags | undefined): string {
|
||||
return formatEnum(flags, (<any>ts).EmitFlags, /*isFlags*/ true);
|
||||
}
|
||||
|
||||
export function formatSymbolFlags(flags: SymbolFlags): string {
|
||||
export function formatSymbolFlags(flags: SymbolFlags | undefined): string {
|
||||
return formatEnum(flags, (<any>ts).SymbolFlags, /*isFlags*/ true);
|
||||
}
|
||||
|
||||
export function formatTypeFlags(flags: TypeFlags): string {
|
||||
export function formatTypeFlags(flags: TypeFlags | undefined): string {
|
||||
return formatEnum(flags, (<any>ts).TypeFlags, /*isFlags*/ true);
|
||||
}
|
||||
|
||||
export function formatObjectFlags(flags: ObjectFlags): string {
|
||||
export function formatObjectFlags(flags: ObjectFlags | undefined): string {
|
||||
return formatEnum(flags, (<any>ts).ObjectFlags, /*isFlags*/ true);
|
||||
}
|
||||
|
||||
@@ -3806,7 +3819,7 @@ namespace ts {
|
||||
* @param token The token.
|
||||
*/
|
||||
export function createTokenRange(pos: number, token: SyntaxKind): TextRange {
|
||||
return createRange(pos, pos + tokenToString(token).length);
|
||||
return createRange(pos, pos + tokenToString(token)!.length);
|
||||
}
|
||||
|
||||
export function rangeIsOnSingleLine(range: TextRange, sourceFile: SourceFile) {
|
||||
@@ -4055,7 +4068,7 @@ namespace ts {
|
||||
return !!forEachAncestorDirectory(directory, d => callback(d) ? true : undefined);
|
||||
}
|
||||
|
||||
export function isUMDExportSymbol(symbol: Symbol) {
|
||||
export function isUMDExportSymbol(symbol: Symbol | undefined) {
|
||||
return symbol && symbol.declarations && symbol.declarations[0] && isNamespaceExportDeclaration(symbol.declarations[0]);
|
||||
}
|
||||
|
||||
@@ -4135,7 +4148,7 @@ namespace ts {
|
||||
return textSpanOverlap(span, other) !== undefined;
|
||||
}
|
||||
|
||||
export function textSpanOverlap(span1: TextSpan, span2: TextSpan) {
|
||||
export function textSpanOverlap(span1: TextSpan, span2: TextSpan): TextSpan | undefined {
|
||||
const overlap = textSpanIntersection(span1, span2);
|
||||
return overlap && overlap.length === 0 ? undefined : overlap;
|
||||
}
|
||||
@@ -4158,7 +4171,7 @@ namespace ts {
|
||||
return position <= textSpanEnd(span) && position >= span.start;
|
||||
}
|
||||
|
||||
export function textSpanIntersection(span1: TextSpan, span2: TextSpan) {
|
||||
export function textSpanIntersection(span1: TextSpan, span2: TextSpan): TextSpan | undefined {
|
||||
const start = Math.max(span1.start, span2.start);
|
||||
const end = Math.min(textSpanEnd(span1), textSpanEnd(span2));
|
||||
return start <= end ? createTextSpanFromBounds(start, end) : undefined;
|
||||
@@ -4327,7 +4340,7 @@ namespace ts {
|
||||
return createTextChangeRange(createTextSpanFromBounds(oldStartN, oldEndN), /*newLength*/ newEndN - oldStartN);
|
||||
}
|
||||
|
||||
export function getTypeParameterOwner(d: Declaration): Declaration {
|
||||
export function getTypeParameterOwner(d: Declaration): Declaration | undefined {
|
||||
if (d && d.kind === SyntaxKind.TypeParameter) {
|
||||
for (let current: Node = d; current; current = current.parent) {
|
||||
if (isFunctionLike(current) || isClassLike(current) || current.kind === SyntaxKind.InterfaceDeclaration) {
|
||||
@@ -4439,7 +4452,7 @@ namespace ts {
|
||||
// Set the UI locale for string collation
|
||||
setUILocale(locale);
|
||||
|
||||
function trySetLanguageAndTerritory(language: string, territory: string, errors?: Push<Diagnostic>): boolean {
|
||||
function trySetLanguageAndTerritory(language: string, territory: string | undefined, errors?: Push<Diagnostic>): boolean {
|
||||
const compilerFilePath = normalizePath(sys.getExecutingFilePath());
|
||||
const containingDirectoryPath = getDirectoryPath(compilerFilePath);
|
||||
|
||||
@@ -4456,7 +4469,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// TODO: Add codePage support for readFile?
|
||||
let fileContents = "";
|
||||
let fileContents: string | undefined = "";
|
||||
try {
|
||||
fileContents = sys.readFile(filePath);
|
||||
}
|
||||
@@ -4468,9 +4481,9 @@ namespace ts {
|
||||
}
|
||||
try {
|
||||
// tslint:disable-next-line no-unnecessary-qualifier (making clear this is a global mutation!)
|
||||
ts.localizedDiagnosticMessages = JSON.parse(fileContents);
|
||||
ts.localizedDiagnosticMessages = JSON.parse(fileContents!);
|
||||
}
|
||||
catch (e) {
|
||||
catch {
|
||||
if (errors) {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Corrupted_locale_file_0, filePath));
|
||||
}
|
||||
@@ -4483,7 +4496,9 @@ namespace ts {
|
||||
|
||||
export function getOriginalNode(node: Node): Node;
|
||||
export function getOriginalNode<T extends Node>(node: Node, nodeTest: (node: Node) => node is T): T;
|
||||
export function getOriginalNode(node: Node, nodeTest?: (node: Node) => boolean): Node {
|
||||
export function getOriginalNode(node: Node | undefined): Node | undefined;
|
||||
export function getOriginalNode<T extends Node>(node: Node | undefined, nodeTest: (node: Node | undefined) => node is T): T | undefined;
|
||||
export function getOriginalNode(node: Node | undefined, nodeTest?: (node: Node | undefined) => boolean): Node | undefined {
|
||||
if (node) {
|
||||
while (node.original !== undefined) {
|
||||
node = node.original;
|
||||
@@ -4517,8 +4532,8 @@ namespace ts {
|
||||
* @param nodeTest A callback used to ensure the correct type of parse tree node is returned.
|
||||
* @returns The original parse tree node if found; otherwise, undefined.
|
||||
*/
|
||||
export function getParseTreeNode<T extends Node>(node: Node, nodeTest?: (node: Node) => node is T): T;
|
||||
export function getParseTreeNode(node: Node, nodeTest?: (node: Node) => boolean): Node {
|
||||
export function getParseTreeNode<T extends Node>(node: Node | undefined, nodeTest?: (node: Node) => node is T): T | undefined;
|
||||
export function getParseTreeNode(node: Node | undefined, nodeTest?: (node: Node) => boolean): Node | undefined {
|
||||
if (node === undefined || isParseTreeNode(node)) {
|
||||
return node;
|
||||
}
|
||||
@@ -4609,7 +4624,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getDeclarationIdentifier(node: Declaration | Expression) {
|
||||
function getDeclarationIdentifier(node: Declaration | Expression): Identifier | undefined {
|
||||
const name = getNameOfDeclaration(node);
|
||||
return isIdentifier(name) ? name : undefined;
|
||||
}
|
||||
@@ -4623,15 +4638,16 @@ namespace ts {
|
||||
return !!(node as NamedDeclaration).name; // A 'name' property should always be a DeclarationName.
|
||||
}
|
||||
|
||||
export function getNameOfDeclaration(declaration: Declaration | Expression): DeclarationName | undefined {
|
||||
// TODO: GH#18217 This is often used as if it returns a defined result
|
||||
export function getNameOfDeclaration(declaration: Declaration | Expression): DeclarationName {
|
||||
if (!declaration) {
|
||||
return undefined;
|
||||
return undefined!;
|
||||
}
|
||||
switch (declaration.kind) {
|
||||
case SyntaxKind.ClassExpression:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
if (!(declaration as ClassExpression | FunctionExpression).name) {
|
||||
return getAssignedName(declaration);
|
||||
return getAssignedName(declaration)!;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.Identifier:
|
||||
@@ -4653,22 +4669,22 @@ namespace ts {
|
||||
case SpecialPropertyAssignmentKind.PrototypeProperty:
|
||||
return (expr.left as PropertyAccessExpression).name;
|
||||
default:
|
||||
return undefined;
|
||||
return undefined!;
|
||||
}
|
||||
}
|
||||
case SyntaxKind.JSDocCallbackTag:
|
||||
return (declaration as JSDocCallbackTag).name;
|
||||
return (declaration as JSDocCallbackTag).name!;
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
return getNameOfJSDocTypedef(declaration as JSDocTypedefTag);
|
||||
return getNameOfJSDocTypedef(declaration as JSDocTypedefTag)!;
|
||||
case SyntaxKind.ExportAssignment: {
|
||||
const { expression } = declaration as ExportAssignment;
|
||||
return isIdentifier(expression) ? expression : undefined;
|
||||
return isIdentifier(expression) ? expression : undefined!;
|
||||
}
|
||||
}
|
||||
return (declaration as NamedDeclaration).name;
|
||||
return (declaration as NamedDeclaration).name!;
|
||||
}
|
||||
|
||||
function getAssignedName(node: Node): DeclarationName {
|
||||
function getAssignedName(node: Node): DeclarationName | undefined {
|
||||
if (!node.parent) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -5573,8 +5589,7 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export function isGeneratedIdentifier(node: Node): node is GeneratedIdentifier {
|
||||
// Using `>` here catches both `GeneratedIdentifierKind.None` and `undefined`.
|
||||
return isIdentifier(node) && (node.autoGenerateFlags & GeneratedIdentifierFlags.KindMask) > GeneratedIdentifierFlags.None;
|
||||
return isIdentifier(node) && (node.autoGenerateFlags! & GeneratedIdentifierFlags.KindMask) > GeneratedIdentifierFlags.None;
|
||||
}
|
||||
|
||||
// Keywords
|
||||
@@ -5785,7 +5800,7 @@ namespace ts {
|
||||
// Binding patterns
|
||||
|
||||
/* @internal */
|
||||
export function isBindingPattern(node: Node): node is BindingPattern {
|
||||
export function isBindingPattern(node: Node | undefined): node is BindingPattern {
|
||||
if (node) {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.ArrayBindingPattern
|
||||
@@ -6303,8 +6318,10 @@ namespace ts {
|
||||
|
||||
/** True if has jsdoc nodes attached to it. */
|
||||
/* @internal */
|
||||
// TODO: GH#19856 Would like to return `node is Node & { jsDoc: JSDoc[] }` but it causes long compile times
|
||||
export function hasJSDocNodes(node: Node): node is HasJSDoc {
|
||||
return !!(node as JSDocContainer).jsDoc && (node as JSDocContainer).jsDoc.length > 0;
|
||||
const { jsDoc } = node as JSDocContainer;
|
||||
return !!jsDoc && jsDoc.length > 0;
|
||||
}
|
||||
|
||||
/** True if has type node attached to it. */
|
||||
|
||||
+28
-28
@@ -9,7 +9,7 @@ namespace ts {
|
||||
* @param test A callback to execute to verify the Node is valid.
|
||||
* @param lift An optional callback to execute to lift a NodeArray into a valid Node.
|
||||
*/
|
||||
export function visitNode<T extends Node>(node: T, visitor: Visitor, test?: (node: Node) => boolean, lift?: (node: NodeArray<Node>) => T): T;
|
||||
export function visitNode<T extends Node>(node: T | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: NodeArray<Node>) => T): T;
|
||||
|
||||
/**
|
||||
* Visits a Node using the supplied visitor, possibly returning a new Node in its place.
|
||||
@@ -19,9 +19,9 @@ namespace ts {
|
||||
* @param test A callback to execute to verify the Node is valid.
|
||||
* @param lift An optional callback to execute to lift a NodeArray into a valid Node.
|
||||
*/
|
||||
export function visitNode<T extends Node>(node: T | undefined, visitor: Visitor, test?: (node: Node) => boolean, lift?: (node: NodeArray<Node>) => T): T | undefined;
|
||||
export function visitNode<T extends Node>(node: T | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: NodeArray<Node>) => T): T | undefined;
|
||||
|
||||
export function visitNode<T extends Node>(node: T | undefined, visitor: Visitor, test?: (node: Node) => boolean, lift?: (node: NodeArray<Node>) => T): T | undefined {
|
||||
export function visitNode<T extends Node>(node: T | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: NodeArray<Node>) => T): T | undefined {
|
||||
if (node === undefined || visitor === undefined) {
|
||||
return node;
|
||||
}
|
||||
@@ -32,7 +32,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
let visitedNode: Node;
|
||||
let visitedNode: Node | undefined;
|
||||
if (visited === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -44,7 +44,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
Debug.assertNode(visitedNode, test);
|
||||
aggregateTransformFlags(visitedNode);
|
||||
aggregateTransformFlags(visitedNode!);
|
||||
return <T>visitedNode;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace ts {
|
||||
* @param start An optional value indicating the starting offset at which to start visiting.
|
||||
* @param count An optional value indicating the maximum number of nodes to visit.
|
||||
*/
|
||||
export function visitNodes<T extends Node>(nodes: NodeArray<T>, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray<T>;
|
||||
export function visitNodes<T extends Node>(nodes: NodeArray<T> | undefined, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray<T>;
|
||||
|
||||
/**
|
||||
* Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place.
|
||||
@@ -84,7 +84,7 @@ namespace ts {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
let updated: MutableNodeArray<T>;
|
||||
let updated: MutableNodeArray<T> | undefined;
|
||||
|
||||
// Ensure start and count have valid values
|
||||
const length = nodes.length;
|
||||
@@ -152,7 +152,7 @@ namespace ts {
|
||||
* Starts a new lexical environment and visits a parameter list, suspending the lexical
|
||||
* environment upon completion.
|
||||
*/
|
||||
export function visitParameterList(nodes: NodeArray<ParameterDeclaration>, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes) {
|
||||
export function visitParameterList(nodes: NodeArray<ParameterDeclaration> | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes) {
|
||||
context.startLexicalEnvironment();
|
||||
const updated = nodesVisitor(nodes, visitor, isParameterDeclaration);
|
||||
context.suspendLexicalEnvironment();
|
||||
@@ -174,7 +174,7 @@ namespace ts {
|
||||
* environment and merging hoisted declarations upon completion.
|
||||
*/
|
||||
export function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext): ConciseBody;
|
||||
export function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext): ConciseBody {
|
||||
export function visitFunctionBody(node: ConciseBody | undefined, visitor: Visitor, context: TransformationContext): ConciseBody | undefined {
|
||||
context.resumeLexicalEnvironment();
|
||||
const updated = visitNode(node, visitor, isConciseBody);
|
||||
const declarations = context.endLexicalEnvironment();
|
||||
@@ -204,7 +204,7 @@ namespace ts {
|
||||
*/
|
||||
export function visitEachChild<T extends Node>(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: typeof visitNodes, tokenVisitor?: Visitor): T | undefined;
|
||||
|
||||
export function visitEachChild(node: Node, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes, tokenVisitor?: Visitor): Node {
|
||||
export function visitEachChild(node: Node | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes, tokenVisitor?: Visitor): Node | undefined {
|
||||
if (node === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -290,14 +290,14 @@ namespace ts {
|
||||
nodesVisitor((<MethodDeclaration>node).typeParameters, visitor, isTypeParameterDeclaration),
|
||||
visitParameterList((<MethodDeclaration>node).parameters, visitor, context, nodesVisitor),
|
||||
visitNode((<MethodDeclaration>node).type, visitor, isTypeNode),
|
||||
visitFunctionBody((<MethodDeclaration>node).body, visitor, context));
|
||||
visitFunctionBody((<MethodDeclaration>node).body!, visitor, context));
|
||||
|
||||
case SyntaxKind.Constructor:
|
||||
return updateConstructor(<ConstructorDeclaration>node,
|
||||
nodesVisitor((<ConstructorDeclaration>node).decorators, visitor, isDecorator),
|
||||
nodesVisitor((<ConstructorDeclaration>node).modifiers, visitor, isModifier),
|
||||
visitParameterList((<ConstructorDeclaration>node).parameters, visitor, context, nodesVisitor),
|
||||
visitFunctionBody((<ConstructorDeclaration>node).body, visitor, context));
|
||||
visitFunctionBody((<ConstructorDeclaration>node).body!, visitor, context));
|
||||
|
||||
case SyntaxKind.GetAccessor:
|
||||
return updateGetAccessor(<GetAccessorDeclaration>node,
|
||||
@@ -306,7 +306,7 @@ namespace ts {
|
||||
visitNode((<GetAccessorDeclaration>node).name, visitor, isPropertyName),
|
||||
visitParameterList((<GetAccessorDeclaration>node).parameters, visitor, context, nodesVisitor),
|
||||
visitNode((<GetAccessorDeclaration>node).type, visitor, isTypeNode),
|
||||
visitFunctionBody((<GetAccessorDeclaration>node).body, visitor, context));
|
||||
visitFunctionBody((<GetAccessorDeclaration>node).body!, visitor, context));
|
||||
|
||||
case SyntaxKind.SetAccessor:
|
||||
return updateSetAccessor(<SetAccessorDeclaration>node,
|
||||
@@ -314,7 +314,7 @@ namespace ts {
|
||||
nodesVisitor((<SetAccessorDeclaration>node).modifiers, visitor, isModifier),
|
||||
visitNode((<SetAccessorDeclaration>node).name, visitor, isPropertyName),
|
||||
visitParameterList((<SetAccessorDeclaration>node).parameters, visitor, context, nodesVisitor),
|
||||
visitFunctionBody((<SetAccessorDeclaration>node).body, visitor, context));
|
||||
visitFunctionBody((<SetAccessorDeclaration>node).body!, visitor, context));
|
||||
|
||||
case SyntaxKind.CallSignature:
|
||||
return updateCallSignature(<CallSignatureDeclaration>node,
|
||||
@@ -333,7 +333,7 @@ namespace ts {
|
||||
nodesVisitor((<IndexSignatureDeclaration>node).decorators, visitor, isDecorator),
|
||||
nodesVisitor((<IndexSignatureDeclaration>node).modifiers, visitor, isModifier),
|
||||
nodesVisitor((<IndexSignatureDeclaration>node).parameters, visitor, isParameterDeclaration),
|
||||
visitNode((<IndexSignatureDeclaration>node).type, visitor, isTypeNode));
|
||||
visitNode((<IndexSignatureDeclaration>node).type!, visitor, isTypeNode));
|
||||
|
||||
// Types
|
||||
|
||||
@@ -555,7 +555,7 @@ namespace ts {
|
||||
case SyntaxKind.YieldExpression:
|
||||
return updateYield(<YieldExpression>node,
|
||||
visitNode((<YieldExpression>node).asteriskToken, tokenVisitor, isToken),
|
||||
visitNode((<YieldExpression>node).expression, visitor, isExpression));
|
||||
visitNode((<YieldExpression>node).expression!, visitor, isExpression));
|
||||
|
||||
case SyntaxKind.SpreadElement:
|
||||
return updateSpread(<SpreadElement>node,
|
||||
@@ -674,7 +674,7 @@ namespace ts {
|
||||
|
||||
case SyntaxKind.ThrowStatement:
|
||||
return updateThrow(<ThrowStatement>node,
|
||||
visitNode((<ThrowStatement>node).expression, visitor, isExpression));
|
||||
visitNode((<ThrowStatement>node).expression!, visitor, isExpression));
|
||||
|
||||
case SyntaxKind.TryStatement:
|
||||
return updateTry(<TryStatement>node,
|
||||
@@ -848,7 +848,7 @@ namespace ts {
|
||||
case SyntaxKind.JsxAttribute:
|
||||
return updateJsxAttribute(<JsxAttribute>node,
|
||||
visitNode((<JsxAttribute>node).name, visitor, isIdentifier),
|
||||
visitNode((<JsxAttribute>node).initializer, visitor, isStringLiteralOrJsxExpression));
|
||||
visitNode((<JsxAttribute>node).initializer!, visitor, isStringLiteralOrJsxExpression));
|
||||
|
||||
case SyntaxKind.JsxAttributes:
|
||||
return updateJsxAttributes(<JsxAttributes>node,
|
||||
@@ -930,7 +930,7 @@ namespace ts {
|
||||
*
|
||||
* @param nodes The NodeArray.
|
||||
*/
|
||||
function extractSingleNode(nodes: ReadonlyArray<Node>): Node {
|
||||
function extractSingleNode(nodes: ReadonlyArray<Node>): Node | undefined {
|
||||
Debug.assert(nodes.length <= 1, "Too many nodes written to output.");
|
||||
return singleOrUndefined(nodes);
|
||||
}
|
||||
@@ -938,11 +938,11 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
function reduceNode<T>(node: Node, f: (memo: T, node: Node) => T, initial: T) {
|
||||
function reduceNode<T>(node: Node | undefined, f: (memo: T, node: Node) => T, initial: T) {
|
||||
return node ? f(initial, node) : initial;
|
||||
}
|
||||
|
||||
function reduceNodeArray<T>(nodes: NodeArray<Node>, f: (memo: T, nodes: NodeArray<Node>) => T, initial: T) {
|
||||
function reduceNodeArray<T>(nodes: NodeArray<Node> | undefined, f: (memo: T, nodes: NodeArray<Node>) => T, initial: T) {
|
||||
return nodes ? f(initial, nodes) : initial;
|
||||
}
|
||||
|
||||
@@ -954,12 +954,12 @@ namespace ts {
|
||||
* @param initial The initial value to supply to the reduction.
|
||||
* @param f The callback function
|
||||
*/
|
||||
export function reduceEachChild<T>(node: Node, initial: T, cbNode: (memo: T, node: Node) => T, cbNodeArray?: (memo: T, nodes: NodeArray<Node>) => T): T {
|
||||
export function reduceEachChild<T>(node: Node | undefined, initial: T, cbNode: (memo: T, node: Node) => T, cbNodeArray?: (memo: T, nodes: NodeArray<Node>) => T): T {
|
||||
if (node === undefined) {
|
||||
return initial;
|
||||
}
|
||||
|
||||
const reduceNodes: (nodes: NodeArray<Node>, f: ((memo: T, node: Node) => T) | ((memo: T, node: NodeArray<Node>) => T), initial: T) => T = cbNodeArray ? reduceNodeArray : reduceLeft;
|
||||
const reduceNodes: (nodes: NodeArray<Node> | undefined, f: ((memo: T, node: Node) => T) | ((memo: T, node: NodeArray<Node>) => T), initial: T) => T = cbNodeArray ? reduceNodeArray : reduceLeft;
|
||||
const cbNodes = cbNodeArray || cbNode;
|
||||
const kind = node.kind;
|
||||
|
||||
@@ -1456,13 +1456,13 @@ namespace ts {
|
||||
/**
|
||||
* Merges generated lexical declarations into a new statement list.
|
||||
*/
|
||||
export function mergeLexicalEnvironment(statements: NodeArray<Statement>, declarations: ReadonlyArray<Statement>): NodeArray<Statement>;
|
||||
export function mergeLexicalEnvironment(statements: NodeArray<Statement>, declarations: ReadonlyArray<Statement> | undefined): NodeArray<Statement>;
|
||||
|
||||
/**
|
||||
* Appends generated lexical declarations to an array of statements.
|
||||
*/
|
||||
export function mergeLexicalEnvironment(statements: Statement[], declarations: ReadonlyArray<Statement>): Statement[];
|
||||
export function mergeLexicalEnvironment(statements: Statement[] | NodeArray<Statement>, declarations: ReadonlyArray<Statement>) {
|
||||
export function mergeLexicalEnvironment(statements: Statement[], declarations: ReadonlyArray<Statement> | undefined): Statement[];
|
||||
export function mergeLexicalEnvironment(statements: Statement[] | NodeArray<Statement>, declarations: ReadonlyArray<Statement> | undefined) {
|
||||
if (!some(declarations)) {
|
||||
return statements;
|
||||
}
|
||||
@@ -1566,10 +1566,10 @@ namespace ts {
|
||||
: noop;
|
||||
|
||||
export const assertNode = shouldAssert(AssertionLevel.Normal)
|
||||
? (node: Node, test: (node: Node) => boolean, message?: string): void => assert(
|
||||
? (node: Node | undefined, test: ((node: Node | undefined) => boolean) | undefined, message?: string): void => assert(
|
||||
test === undefined || test(node),
|
||||
message || "Unexpected node.",
|
||||
() => `Node ${formatSyntaxKind(node.kind)} did not pass test '${getFunctionName(test)}'.`,
|
||||
() => `Node ${formatSyntaxKind(node!.kind)} did not pass test '${getFunctionName(test!)}'.`,
|
||||
assertNode)
|
||||
: noop;
|
||||
|
||||
|
||||
+44
-41
@@ -4,7 +4,7 @@ namespace ts {
|
||||
getCurrentDirectory: () => sys.getCurrentDirectory(),
|
||||
getNewLine: () => sys.newLine,
|
||||
getCanonicalFileName: createGetCanonicalFileName(sys.useCaseSensitiveFileNames)
|
||||
} : undefined;
|
||||
} : undefined!; // TODO: GH#18217
|
||||
|
||||
/**
|
||||
* Create a function that reports error by writing to the system and handles the formating of the diagnostic
|
||||
@@ -23,7 +23,7 @@ namespace ts {
|
||||
return diagnostic => {
|
||||
diagnostics[0] = diagnostic;
|
||||
system.write(formatDiagnosticsWithColorAndContext(diagnostics, host) + host.getNewLine());
|
||||
diagnostics[0] = undefined;
|
||||
diagnostics[0] = undefined!; // TODO: GH#18217
|
||||
};
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace ts {
|
||||
const host: ParseConfigFileHost = <any>system;
|
||||
host.onUnRecoverableConfigFileDiagnostic = diagnostic => reportUnrecoverableDiagnostic(sys, reportDiagnostic, diagnostic);
|
||||
const result = getParsedCommandLineOfConfigFile(configFileName, optionsToExtend, host);
|
||||
host.onUnRecoverableConfigFileDiagnostic = undefined;
|
||||
host.onUnRecoverableConfigFileDiagnostic = undefined!; // TODO: GH#18217
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -177,9 +177,9 @@ namespace ts {
|
||||
/**
|
||||
* Creates the watch compiler host that can be extended with config file or root file names and options host
|
||||
*/
|
||||
function createWatchCompilerHost<T extends BuilderProgram = EmitAndSemanticDiagnosticsBuilderProgram>(system = sys, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHost<T> {
|
||||
function createWatchCompilerHost<T extends BuilderProgram = EmitAndSemanticDiagnosticsBuilderProgram>(system = sys, createProgram: CreateProgram<T> | undefined, reportDiagnostic: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHost<T> {
|
||||
if (!createProgram) {
|
||||
createProgram = createEmitAndSemanticDiagnosticsBuilderProgram as any;
|
||||
createProgram = createEmitAndSemanticDiagnosticsBuilderProgram as any as CreateProgram<T>;
|
||||
}
|
||||
|
||||
let host: DirectoryStructureHost = system;
|
||||
@@ -197,18 +197,18 @@ namespace ts {
|
||||
directoryExists: path => system.directoryExists(path),
|
||||
getDirectories: path => system.getDirectories(path),
|
||||
readDirectory: (path, extensions, exclude, include, depth) => system.readDirectory(path, extensions, exclude, include, depth),
|
||||
realpath: system.realpath && (path => system.realpath(path)),
|
||||
realpath: system.realpath && (path => system.realpath!(path)),
|
||||
getEnvironmentVariable: system.getEnvironmentVariable && (name => system.getEnvironmentVariable(name)),
|
||||
watchFile: system.watchFile ? ((path, callback, pollingInterval) => system.watchFile(path, callback, pollingInterval)) : () => noopFileWatcher,
|
||||
watchDirectory: system.watchDirectory ? ((path, callback, recursive) => system.watchDirectory(path, callback, recursive)) : () => noopFileWatcher,
|
||||
setTimeout: system.setTimeout ? ((callback, ms, ...args: any[]) => system.setTimeout.call(system, callback, ms, ...args)) : noop,
|
||||
clearTimeout: system.clearTimeout ? (timeoutId => system.clearTimeout(timeoutId)) : noop,
|
||||
watchFile: system.watchFile ? ((path, callback, pollingInterval) => system.watchFile!(path, callback, pollingInterval)) : () => noopFileWatcher,
|
||||
watchDirectory: system.watchDirectory ? ((path, callback, recursive) => system.watchDirectory!(path, callback, recursive)) : () => noopFileWatcher,
|
||||
setTimeout: system.setTimeout ? ((callback, ms, ...args: any[]) => system.setTimeout!.call(system, callback, ms, ...args)) : noop,
|
||||
clearTimeout: system.clearTimeout ? (timeoutId => system.clearTimeout!(timeoutId)) : noop,
|
||||
trace: s => system.write(s),
|
||||
onWatchStatusChange,
|
||||
createDirectory: path => system.createDirectory(path),
|
||||
writeFile: (path, data, writeByteOrderMark) => system.writeFile(path, data, writeByteOrderMark),
|
||||
onCachedDirectoryStructureHostCreate: cacheHost => host = cacheHost || system,
|
||||
createHash: system.createHash && (s => system.createHash(s)),
|
||||
createHash: system.createHash && (s => system.createHash!(s)),
|
||||
createProgram,
|
||||
afterProgramCreate: emitFilesAndReportErrorUsingBuilder
|
||||
};
|
||||
@@ -246,9 +246,9 @@ namespace ts {
|
||||
* Creates the watch compiler host from system for config file in watch mode
|
||||
*/
|
||||
export function createWatchCompilerHostOfConfigFile<T extends BuilderProgram = EmitAndSemanticDiagnosticsBuilderProgram>(configFileName: string, optionsToExtend: CompilerOptions | undefined, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHostOfConfigFile<T> {
|
||||
reportDiagnostic = reportDiagnostic || createDiagnosticReporter(system);
|
||||
const host = createWatchCompilerHost(system, createProgram, reportDiagnostic, reportWatchStatus) as WatchCompilerHostOfConfigFile<T>;
|
||||
host.onUnRecoverableConfigFileDiagnostic = diagnostic => reportUnrecoverableDiagnostic(system, reportDiagnostic, diagnostic);
|
||||
const diagnosticReporter = reportDiagnostic || createDiagnosticReporter(system);
|
||||
const host = createWatchCompilerHost(system, createProgram, diagnosticReporter, reportWatchStatus) as WatchCompilerHostOfConfigFile<T>;
|
||||
host.onUnRecoverableConfigFileDiagnostic = diagnostic => reportUnrecoverableDiagnostic(system, diagnosticReporter, diagnostic);
|
||||
host.configFileName = configFileName;
|
||||
host.optionsToExtend = optionsToExtend;
|
||||
return host;
|
||||
@@ -270,6 +270,8 @@ namespace ts {
|
||||
/** Create the program with rootNames and options, if they are undefined, oldProgram and new configFile diagnostics create new program */
|
||||
export type CreateProgram<T extends BuilderProgram> = (rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: T, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>) => T;
|
||||
export interface WatchCompilerHost<T extends BuilderProgram> {
|
||||
// TODO: GH#18217 Optional methods are frequently asserted
|
||||
|
||||
/**
|
||||
* Used to create the program when need for program creation or recreation detected
|
||||
*/
|
||||
@@ -314,12 +316,12 @@ namespace ts {
|
||||
/** If provided would be used to write log about compilation */
|
||||
trace?(s: string): void;
|
||||
/** If provided is used to get the environment variable */
|
||||
getEnvironmentVariable?(name: string): string;
|
||||
getEnvironmentVariable?(name: string): string | undefined;
|
||||
|
||||
/** If provided, used to resolve the module names, otherwise typescript's default module resolution */
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[];
|
||||
/** If provided, used to resolve type reference directives, otherwise typescript's default resolution */
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): (ResolvedTypeReferenceDirective | undefined)[];
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
|
||||
/** Used to watch changes in source files, missing files needed to update the program or config file */
|
||||
watchFile(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher;
|
||||
@@ -334,6 +336,7 @@ namespace ts {
|
||||
/** Internal interface used to wire emit through same host */
|
||||
/*@internal*/
|
||||
export interface WatchCompilerHost<T extends BuilderProgram> {
|
||||
// TODO: GH#18217 Optional methods are frequently asserted
|
||||
createDirectory?(path: string): void;
|
||||
writeFile?(path: string, data: string, writeByteOrderMark?: boolean): void;
|
||||
onCachedDirectoryStructureHostCreate?(host: CachedDirectoryStructureHost): void;
|
||||
@@ -405,7 +408,7 @@ namespace ts {
|
||||
export function createWatchCompilerHost<T extends BuilderProgram>(configFileName: string, optionsToExtend: CompilerOptions | undefined, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHostOfConfigFile<T>;
|
||||
export function createWatchCompilerHost<T extends BuilderProgram>(rootFilesOrConfigFileName: string | string[], options: CompilerOptions | undefined, system: System, createProgram?: CreateProgram<T>, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHostOfFilesAndCompilerOptions<T> | WatchCompilerHostOfConfigFile<T> {
|
||||
if (isArray(rootFilesOrConfigFileName)) {
|
||||
return createWatchCompilerHostOfFilesAndCompilerOptions(rootFilesOrConfigFileName, options, system, createProgram, reportDiagnostic, reportWatchStatus);
|
||||
return createWatchCompilerHostOfFilesAndCompilerOptions(rootFilesOrConfigFileName, options!, system, createProgram, reportDiagnostic, reportWatchStatus); // TODO: GH#18217
|
||||
}
|
||||
else {
|
||||
return createWatchCompilerHostOfConfigFile(rootFilesOrConfigFileName, options, system, createProgram, reportDiagnostic, reportWatchStatus);
|
||||
@@ -442,7 +445,7 @@ namespace ts {
|
||||
let timerToUpdateProgram: any; // timer callback to recompile the program
|
||||
|
||||
const sourceFilesCache = createMap<HostFileInfo>(); // Cache that stores the source file and version info
|
||||
let missingFilePathsRequestedForRelease: Path[]; // These paths are held temparirly so that we can remove the entry from source file cache if the file is not tracked by missing files
|
||||
let missingFilePathsRequestedForRelease: Path[] | undefined; // These paths are held temparirly so that we can remove the entry from source file cache if the file is not tracked by missing files
|
||||
let hasChangedCompilerOptions = false; // True if the compiler options have changed between compilations
|
||||
let hasChangedAutomaticTypeDirectiveNames = false; // True if the automatic type directives have changed
|
||||
|
||||
@@ -456,14 +459,14 @@ namespace ts {
|
||||
let configFileParsingDiagnostics: ReadonlyArray<Diagnostic> | undefined;
|
||||
let hasChangedConfigFileParsingErrors = false;
|
||||
|
||||
const cachedDirectoryStructureHost = configFileName && createCachedDirectoryStructureHost(host, currentDirectory, useCaseSensitiveFileNames);
|
||||
const cachedDirectoryStructureHost = configFileName === undefined ? undefined : createCachedDirectoryStructureHost(host, currentDirectory, useCaseSensitiveFileNames);
|
||||
if (cachedDirectoryStructureHost && host.onCachedDirectoryStructureHostCreate) {
|
||||
host.onCachedDirectoryStructureHostCreate(cachedDirectoryStructureHost);
|
||||
}
|
||||
const directoryStructureHost: DirectoryStructureHost = cachedDirectoryStructureHost || host;
|
||||
const parseConfigFileHost: ParseConfigFileHost = {
|
||||
useCaseSensitiveFileNames,
|
||||
readDirectory: (path, extensions, exclude, include, depth) => directoryStructureHost.readDirectory(path, extensions, exclude, include, depth),
|
||||
readDirectory: (path, extensions, exclude, include, depth) => directoryStructureHost.readDirectory!(path, extensions, exclude, include, depth),
|
||||
fileExists: path => host.fileExists(path),
|
||||
readFile,
|
||||
getCurrentDirectory,
|
||||
@@ -485,10 +488,10 @@ namespace ts {
|
||||
newLine = updateNewLine();
|
||||
}
|
||||
|
||||
const trace = host.trace && ((s: string) => { host.trace(s + newLine); });
|
||||
const trace = host.trace && ((s: string) => { host.trace!(s + newLine); });
|
||||
const watchLogLevel = trace ? compilerOptions.extendedDiagnostics ? WatchLogLevel.Verbose :
|
||||
compilerOptions.diagnostis ? WatchLogLevel.TriggerOnly : WatchLogLevel.None : WatchLogLevel.None;
|
||||
const writeLog: (s: string) => void = watchLogLevel !== WatchLogLevel.None ? trace : noop;
|
||||
const writeLog: (s: string) => void = watchLogLevel !== WatchLogLevel.None ? trace! : noop; // TODO: GH#18217
|
||||
const { watchFile, watchFilePath, watchDirectory } = getWatchFactory<string>(watchLogLevel, writeLog);
|
||||
|
||||
const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
|
||||
@@ -502,7 +505,7 @@ namespace ts {
|
||||
// Members for CompilerHost
|
||||
getSourceFile: (fileName, languageVersion, onError?, shouldCreateNewSourceFile?) => getVersionedSourceFileByPath(fileName, toPath(fileName), languageVersion, onError, shouldCreateNewSourceFile),
|
||||
getSourceFileByPath: getVersionedSourceFileByPath,
|
||||
getDefaultLibLocation: host.getDefaultLibLocation && (() => host.getDefaultLibLocation()),
|
||||
getDefaultLibLocation: host.getDefaultLibLocation && (() => host.getDefaultLibLocation!()),
|
||||
getDefaultLibFileName: options => host.getDefaultLibFileName(options),
|
||||
writeFile,
|
||||
getCurrentDirectory,
|
||||
@@ -512,12 +515,12 @@ namespace ts {
|
||||
fileExists,
|
||||
readFile,
|
||||
trace,
|
||||
directoryExists: directoryStructureHost.directoryExists && (path => directoryStructureHost.directoryExists(path)),
|
||||
getDirectories: directoryStructureHost.getDirectories && (path => directoryStructureHost.getDirectories(path)),
|
||||
realpath: host.realpath && (s => host.realpath(s)),
|
||||
getEnvironmentVariable: host.getEnvironmentVariable ? (name => host.getEnvironmentVariable(name)) : (() => ""),
|
||||
directoryExists: directoryStructureHost.directoryExists && (path => directoryStructureHost.directoryExists!(path)),
|
||||
getDirectories: (directoryStructureHost.getDirectories && ((path: string) => directoryStructureHost.getDirectories!(path)))!, // TODO: GH#18217
|
||||
realpath: host.realpath && (s => host.realpath!(s)),
|
||||
getEnvironmentVariable: host.getEnvironmentVariable ? (name => host.getEnvironmentVariable!(name)) : (() => ""),
|
||||
onReleaseOldSourceFile,
|
||||
createHash: host.createHash && (data => host.createHash(data)),
|
||||
createHash: host.createHash && (data => host.createHash!(data)),
|
||||
// Members for ResolutionCacheHost
|
||||
toPath,
|
||||
getCompilationSettings: () => compilerOptions,
|
||||
@@ -541,10 +544,10 @@ namespace ts {
|
||||
);
|
||||
// Resolve module using host module resolution strategy if provided otherwise use resolution cache to resolve module names
|
||||
compilerHost.resolveModuleNames = host.resolveModuleNames ?
|
||||
((moduleNames, containingFile, reusedNames) => host.resolveModuleNames(moduleNames, containingFile, reusedNames)) :
|
||||
((moduleNames, containingFile, reusedNames) => host.resolveModuleNames!(moduleNames, containingFile, reusedNames)) :
|
||||
((moduleNames, containingFile, reusedNames) => resolutionCache.resolveModuleNames(moduleNames, containingFile, reusedNames));
|
||||
compilerHost.resolveTypeReferenceDirectives = host.resolveTypeReferenceDirectives ?
|
||||
((typeDirectiveNames, containingFile) => host.resolveTypeReferenceDirectives(typeDirectiveNames, containingFile)) :
|
||||
((typeDirectiveNames, containingFile) => host.resolveTypeReferenceDirectives!(typeDirectiveNames, containingFile)) :
|
||||
((typeDirectiveNames, containingFile) => resolutionCache.resolveTypeReferenceDirectives(typeDirectiveNames, containingFile));
|
||||
const userProvidedResolution = !!host.resolveModuleNames || !!host.resolveTypeReferenceDirectives;
|
||||
|
||||
@@ -659,15 +662,15 @@ namespace ts {
|
||||
const path = toPath(fileName);
|
||||
// If file is missing on host from cache, we can definitely say file doesnt exist
|
||||
// otherwise we need to ensure from the disk
|
||||
if (isFileMissingOnHost(sourceFilesCache.get(path))) {
|
||||
if (isFileMissingOnHost(sourceFilesCache.get(path)!)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return directoryStructureHost.fileExists(fileName);
|
||||
}
|
||||
|
||||
function getVersionedSourceFileByPath(fileName: string, path: Path, languageVersion: ScriptTarget, onError?: (message: string) => void, shouldCreateNewSourceFile?: boolean): SourceFile {
|
||||
const hostSourceFile = sourceFilesCache.get(path);
|
||||
function getVersionedSourceFileByPath(fileName: string, path: Path, languageVersion: ScriptTarget, onError?: (message: string) => void, shouldCreateNewSourceFile?: boolean): SourceFile | undefined {
|
||||
const hostSourceFile = sourceFilesCache.get(path)!;
|
||||
// No source file on the host
|
||||
if (isFileMissingOnHost(hostSourceFile)) {
|
||||
return undefined;
|
||||
@@ -712,7 +715,7 @@ namespace ts {
|
||||
return hostSourceFile.sourceFile;
|
||||
|
||||
function getNewSourceFile() {
|
||||
let text: string;
|
||||
let text: string | undefined;
|
||||
try {
|
||||
performance.mark("beforeIORead");
|
||||
text = host.readFile(fileName, compilerOptions.charset);
|
||||
@@ -742,7 +745,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getSourceVersion(path: Path): string {
|
||||
function getSourceVersion(path: Path): string | undefined {
|
||||
const hostSourceFile = sourceFilesCache.get(path);
|
||||
return !hostSourceFile || isFileMissingOnHost(hostSourceFile) ? undefined : hostSourceFile.version.toString();
|
||||
}
|
||||
@@ -843,13 +846,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
function parseConfigFile() {
|
||||
setConfigFileParsingResult(getParsedCommandLineOfConfigFile(configFileName, optionsToExtendForConfigFile, parseConfigFileHost));
|
||||
setConfigFileParsingResult(getParsedCommandLineOfConfigFile(configFileName, optionsToExtendForConfigFile, parseConfigFileHost)!); // TODO: GH#18217
|
||||
}
|
||||
|
||||
function setConfigFileParsingResult(configFileParseResult: ParsedCommandLine) {
|
||||
rootFileNames = configFileParseResult.fileNames;
|
||||
compilerOptions = configFileParseResult.options;
|
||||
configFileSpecs = configFileParseResult.configFileSpecs;
|
||||
configFileSpecs = configFileParseResult.configFileSpecs!; // TODO: GH#18217
|
||||
configFileParsingDiagnostics = getConfigFileParsingDiagnostics(configFileParseResult);
|
||||
hasChangedConfigFileParsingErrors = true;
|
||||
}
|
||||
@@ -881,7 +884,7 @@ namespace ts {
|
||||
updateCachedSystemWithFile(fileName, missingFilePath, eventKind);
|
||||
|
||||
if (eventKind === FileWatcherEventKind.Created && missingFilesMap.has(missingFilePath)) {
|
||||
missingFilesMap.get(missingFilePath).close();
|
||||
missingFilesMap.get(missingFilePath)!.close();
|
||||
missingFilesMap.delete(missingFilePath);
|
||||
|
||||
// Delete the entry in the source files cache so that new source file is created
|
||||
@@ -941,10 +944,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
function ensureDirectoriesExist(directoryPath: string) {
|
||||
if (directoryPath.length > getRootLength(directoryPath) && !host.directoryExists(directoryPath)) {
|
||||
if (directoryPath.length > getRootLength(directoryPath) && !host.directoryExists!(directoryPath)) {
|
||||
const parentDirectory = getDirectoryPath(directoryPath);
|
||||
ensureDirectoriesExist(parentDirectory);
|
||||
host.createDirectory(directoryPath);
|
||||
host.createDirectory!(directoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -953,7 +956,7 @@ namespace ts {
|
||||
performance.mark("beforeIOWrite");
|
||||
ensureDirectoriesExist(getDirectoryPath(normalizePath(fileName)));
|
||||
|
||||
host.writeFile(fileName, text, writeByteOrderMark);
|
||||
host.writeFile!(fileName, text, writeByteOrderMark);
|
||||
|
||||
performance.mark("afterIOWrite");
|
||||
performance.measure("I/O Write", "beforeIOWrite", "afterIOWrite");
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace ts {
|
||||
fileExists(path: string): boolean;
|
||||
readFile(path: string, encoding?: string): string | undefined;
|
||||
|
||||
// TODO: GH#18217 Optional methods are frequently used as non-optional
|
||||
directoryExists?(path: string): boolean;
|
||||
getDirectories?(path: string): string[];
|
||||
readDirectory?(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[];
|
||||
@@ -76,8 +77,8 @@ namespace ts {
|
||||
|
||||
function createCachedFileSystemEntries(rootDir: string, rootDirPath: Path) {
|
||||
const resultFromHost: MutableFileSystemEntries = {
|
||||
files: map(host.readDirectory(rootDir, /*extensions*/ undefined, /*exclude*/ undefined, /*include*/["*.*"]), getBaseNameOfFileName) || [],
|
||||
directories: host.getDirectories(rootDir) || []
|
||||
files: map(host.readDirectory!(rootDir, /*extensions*/ undefined, /*exclude*/ undefined, /*include*/["*.*"]), getBaseNameOfFileName) || [],
|
||||
directories: host.getDirectories!(rootDir) || []
|
||||
};
|
||||
|
||||
cachedReadDirectoryResult.set(ensureTrailingDirectorySeparator(rootDirPath), resultFromHost);
|
||||
@@ -131,7 +132,7 @@ namespace ts {
|
||||
if (result) {
|
||||
updateFilesOfFileSystemEntry(result, getBaseNameOfFileName(fileName), /*fileExists*/ true);
|
||||
}
|
||||
return host.writeFile(fileName, data, writeByteOrderMark);
|
||||
return host.writeFile!(fileName, data, writeByteOrderMark);
|
||||
}
|
||||
|
||||
function fileExists(fileName: string): boolean {
|
||||
@@ -143,7 +144,7 @@ namespace ts {
|
||||
|
||||
function directoryExists(dirPath: string): boolean {
|
||||
const path = toPath(dirPath);
|
||||
return cachedReadDirectoryResult.has(ensureTrailingDirectorySeparator(path)) || host.directoryExists(dirPath);
|
||||
return cachedReadDirectoryResult.has(ensureTrailingDirectorySeparator(path)) || host.directoryExists!(dirPath);
|
||||
}
|
||||
|
||||
function createDirectory(dirPath: string) {
|
||||
@@ -153,7 +154,7 @@ namespace ts {
|
||||
if (result) {
|
||||
updateFileSystemEntry(result.directories, baseFileName, /*isValid*/ true);
|
||||
}
|
||||
host.createDirectory(dirPath);
|
||||
host.createDirectory!(dirPath);
|
||||
}
|
||||
|
||||
function getDirectories(rootDir: string): string[] {
|
||||
@@ -162,7 +163,7 @@ namespace ts {
|
||||
if (result) {
|
||||
return result.directories.slice();
|
||||
}
|
||||
return host.getDirectories(rootDir);
|
||||
return host.getDirectories!(rootDir);
|
||||
}
|
||||
|
||||
function readDirectory(rootDir: string, extensions?: ReadonlyArray<string>, excludes?: ReadonlyArray<string>, includes?: ReadonlyArray<string>, depth?: number): string[] {
|
||||
@@ -171,12 +172,12 @@ namespace ts {
|
||||
if (result) {
|
||||
return matchFiles(rootDir, extensions, excludes, includes, useCaseSensitiveFileNames, currentDirectory, depth, getFileSystemEntries);
|
||||
}
|
||||
return host.readDirectory(rootDir, extensions, excludes, includes, depth);
|
||||
return host.readDirectory!(rootDir, extensions, excludes, includes, depth);
|
||||
|
||||
function getFileSystemEntries(dir: string) {
|
||||
function getFileSystemEntries(dir: string): FileSystemEntries {
|
||||
const path = toPath(dir);
|
||||
if (path === rootDirPath) {
|
||||
return result;
|
||||
return result!;
|
||||
}
|
||||
return tryReadDirectory(dir, path) || emptyFileSystemEntries;
|
||||
}
|
||||
@@ -387,7 +388,7 @@ namespace ts {
|
||||
|
||||
type WatchCallback<T, U> = (fileName: string, cbOptional?: T, passThrough?: U) => void;
|
||||
type AddWatch<H, T, U, V> = (host: H, file: string, cb: WatchCallback<U, V>, flags: T, passThrough?: V, detailInfo1?: undefined, detailInfo2?: undefined) => FileWatcher;
|
||||
export type GetDetailWatchInfo<X, Y> = (detailInfo1: X, detailInfo2: Y) => string;
|
||||
export type GetDetailWatchInfo<X, Y> = (detailInfo1: X, detailInfo2: Y | undefined) => string;
|
||||
|
||||
type CreateFileWatcher<H, T, U, V, X, Y> = (host: H, file: string, cb: WatchCallback<U, V>, flags: T, passThrough: V | undefined, detailInfo1: X | undefined, detailInfo2: Y | undefined, addWatch: AddWatch<H, T, U, V>, log: (s: string) => void, watchCaption: string, getDetailWatchInfo: GetDetailWatchInfo<X, Y> | undefined) => FileWatcher;
|
||||
function getCreateFileWatcher<H, T, U, V, X, Y>(watchLogLevel: WatchLogLevel, addWatch: AddWatch<H, T, U, V>): CreateFileWatcher<H, T, U, V, X, Y> {
|
||||
|
||||
@@ -182,8 +182,8 @@ namespace compiler {
|
||||
}
|
||||
|
||||
public getSourceMapRecord(): string | undefined {
|
||||
if (this.result.sourceMaps && this.result.sourceMaps.length > 0) {
|
||||
return Harness.SourceMapRecorder.getSourceMapRecord(this.result.sourceMaps, this.program, Array.from(this.js.values()), Array.from(this.dts.values()));
|
||||
if (this.result!.sourceMaps && this.result!.sourceMaps!.length > 0) {
|
||||
return Harness.SourceMapRecorder.getSourceMapRecord(this.result!.sourceMaps!, this.program!, Array.from(this.js.values()), Array.from(this.dts.values()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
private runSuite(fileName: string, test?: CompilerFileBasedTest, configuration?: Harness.FileBasedTestConfiguration) {
|
||||
// Mocha holds onto the closure environment of the describe callback even after the test is done.
|
||||
// Everything declared here should be cleared out in the "after" callback.
|
||||
let compilerTest: CompilerTest | undefined;
|
||||
let compilerTest!: CompilerTest;
|
||||
before(() => { compilerTest = new CompilerTest(fileName, test && test.payload, configuration); });
|
||||
it(`Correct errors for ${fileName}`, () => { compilerTest.verifyDiagnostics(); });
|
||||
it(`Correct module resolution tracing for ${fileName}`, () => { compilerTest.verifyModuleResolution(); });
|
||||
@@ -89,7 +89,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
it(`Correct JS output for ${fileName}`, () => { if (this.emit) compilerTest.verifyJavaScriptOutput(); });
|
||||
it(`Correct Sourcemap output for ${fileName}`, () => { compilerTest.verifySourceMapOutput(); });
|
||||
it(`Correct type/symbol baselines for ${fileName}`, () => { compilerTest.verifyTypesAndSymbols(); });
|
||||
after(() => { compilerTest = undefined; });
|
||||
after(() => { compilerTest = undefined!; });
|
||||
}
|
||||
|
||||
private parseOptions() {
|
||||
@@ -131,7 +131,7 @@ class CompilerTest {
|
||||
const rootDir = fileName.indexOf("conformance") === -1 ? "tests/cases/compiler/" : ts.getDirectoryPath(fileName) + "/";
|
||||
|
||||
if (testCaseContent === undefined) {
|
||||
testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(Harness.IO.readFile(fileName), fileName, rootDir);
|
||||
testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(Harness.IO.readFile(fileName)!, fileName, rootDir);
|
||||
}
|
||||
|
||||
if (configurationOverrides) {
|
||||
@@ -140,13 +140,13 @@ class CompilerTest {
|
||||
|
||||
const units = testCaseContent.testUnitData;
|
||||
this.harnessSettings = testCaseContent.settings;
|
||||
let tsConfigOptions: ts.CompilerOptions;
|
||||
let tsConfigOptions: ts.CompilerOptions | undefined;
|
||||
this.tsConfigFiles = [];
|
||||
if (testCaseContent.tsConfig) {
|
||||
assert.equal(testCaseContent.tsConfig.fileNames.length, 0, `list of files in tsconfig is not currently supported`);
|
||||
|
||||
tsConfigOptions = ts.cloneCompilerOptions(testCaseContent.tsConfig.options);
|
||||
this.tsConfigFiles.push(this.createHarnessTestFile(testCaseContent.tsConfigFileUnitData, rootDir, ts.combinePaths(rootDir, tsConfigOptions.configFilePath)));
|
||||
this.tsConfigFiles.push(this.createHarnessTestFile(testCaseContent.tsConfigFileUnitData!, rootDir, ts.combinePaths(rootDir, tsConfigOptions.configFilePath!)));
|
||||
}
|
||||
else {
|
||||
const baseUrl = this.harnessSettings.baseUrl;
|
||||
@@ -156,7 +156,7 @@ class CompilerTest {
|
||||
}
|
||||
|
||||
this.lastUnit = units[units.length - 1];
|
||||
this.hasNonDtsFiles = ts.forEach(units, unit => !ts.fileExtensionIs(unit.name, ts.Extension.Dts));
|
||||
this.hasNonDtsFiles = units.some(unit => !ts.fileExtensionIs(unit.name, ts.Extension.Dts));
|
||||
// We need to assemble the list of input files for the compiler and other related files on the 'filesystem' (ie in a multi-file test)
|
||||
// If the last file in a test uses require or a triple slash reference we'll assume all other files will be brought in via references,
|
||||
// otherwise, assume all files are just meant to be in the same compilation session without explicit references to one another.
|
||||
@@ -179,7 +179,7 @@ class CompilerTest {
|
||||
|
||||
if (tsConfigOptions && tsConfigOptions.configFilePath !== undefined) {
|
||||
tsConfigOptions.configFilePath = ts.combinePaths(rootDir, tsConfigOptions.configFilePath);
|
||||
tsConfigOptions.configFile.fileName = tsConfigOptions.configFilePath;
|
||||
tsConfigOptions.configFile!.fileName = tsConfigOptions.configFilePath;
|
||||
}
|
||||
|
||||
this.result = Harness.Compiler.compileFiles(
|
||||
@@ -194,7 +194,7 @@ class CompilerTest {
|
||||
|
||||
public static getConfigurations(file: string): CompilerFileBasedTest {
|
||||
// also see `parseCompilerTestConfigurations` in tests/webTestServer.ts
|
||||
const content = Harness.IO.readFile(file);
|
||||
const content = Harness.IO.readFile(file)!;
|
||||
const rootDir = file.indexOf("conformance") === -1 ? "tests/cases/compiler/" : ts.getDirectoryPath(file) + "/";
|
||||
const payload = Harness.TestCaseParser.makeUnitsFromTest(content, file, rootDir);
|
||||
const settings = Harness.TestCaseParser.extractCompilerSettings(content);
|
||||
@@ -222,7 +222,7 @@ class CompilerTest {
|
||||
public verifySourceMapRecord() {
|
||||
if (this.options.sourceMap || this.options.inlineSourceMap || this.options.declarationMap) {
|
||||
Harness.Baseline.runBaseline(this.justName.replace(/\.tsx?$/, ".sourcemap.txt"), () => {
|
||||
const record = utils.removeTestPathPrefixes(this.result.getSourceMapRecord());
|
||||
const record = utils.removeTestPathPrefixes(this.result.getSourceMapRecord()!);
|
||||
if ((this.options.noEmitOnError && this.result.diagnostics.length !== 0) || record === undefined) {
|
||||
// Because of the noEmitOnError option no files are created. We need to return null because baselining isn't required.
|
||||
/* tslint:disable:no-null-keyword */
|
||||
@@ -263,8 +263,8 @@ class CompilerTest {
|
||||
|
||||
Harness.Compiler.doTypeAndSymbolBaseline(
|
||||
this.justName,
|
||||
this.result.program,
|
||||
this.toBeCompiled.concat(this.otherFiles).filter(file => !!this.result.program.getSourceFile(file.unitName)));
|
||||
this.result.program!,
|
||||
this.toBeCompiled.concat(this.otherFiles).filter(file => !!this.result.program!.getSourceFile(file.unitName)));
|
||||
}
|
||||
|
||||
private makeUnitName(name: string, root: string) {
|
||||
|
||||
@@ -151,9 +151,9 @@ namespace documents {
|
||||
return match ? new SourceMap(/*mapFile*/ undefined, new Buffer(match[1], "base64").toString("utf8")) : undefined;
|
||||
}
|
||||
|
||||
public static fromSource(text: string) {
|
||||
public static fromSource(text: string): SourceMap | undefined {
|
||||
const url = this.getUrl(text);
|
||||
return url && this.fromUrl(url);
|
||||
return url === undefined ? undefined : this.fromUrl(url);
|
||||
}
|
||||
|
||||
public getMappingsForEmittedLine(emittedLine: number): ReadonlyArray<Mapping> | undefined {
|
||||
|
||||
@@ -16,7 +16,7 @@ interface UserConfig {
|
||||
|
||||
abstract class ExternalCompileRunnerBase extends RunnerBase {
|
||||
abstract testDir: string;
|
||||
abstract report(result: ExecResult, cwd: string): string;
|
||||
abstract report(result: ExecResult, cwd: string): string | null;
|
||||
enumerateTestFiles() {
|
||||
return Harness.IO.getDirectories(this.testDir);
|
||||
}
|
||||
@@ -48,7 +48,7 @@ abstract class ExternalCompileRunnerBase extends RunnerBase {
|
||||
let cwd = path.join(Harness.IO.getWorkspaceRoot(), cls.testDir, directoryName);
|
||||
const originalCwd = cwd;
|
||||
const stdio = isWorker ? "pipe" : "inherit";
|
||||
let types: string[];
|
||||
let types: string[] | undefined;
|
||||
if (fs.existsSync(path.join(cwd, "test.json"))) {
|
||||
const submoduleDir = path.join(cwd, directoryName);
|
||||
const reset = cp.spawnSync("git", ["reset", "HEAD", "--hard"], { cwd: submoduleDir, timeout, shell: true, stdio });
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace fakes {
|
||||
public readonly output: string[] = [];
|
||||
public readonly newLine: string;
|
||||
public readonly useCaseSensitiveFileNames: boolean;
|
||||
public exitCode: number;
|
||||
public exitCode: number | undefined;
|
||||
|
||||
private readonly _executingFilePath: string | undefined;
|
||||
private readonly _env: Record<string, string> | undefined;
|
||||
@@ -128,7 +128,7 @@ namespace fakes {
|
||||
|
||||
public getModifiedTime(path: string) {
|
||||
const stats = this._getStats(path);
|
||||
return stats ? stats.mtime : undefined;
|
||||
return stats ? stats.mtime : undefined!; // TODO: GH#18217
|
||||
}
|
||||
|
||||
public createHash(data: string): string {
|
||||
@@ -144,8 +144,8 @@ namespace fakes {
|
||||
}
|
||||
}
|
||||
|
||||
public getEnvironmentVariable(name: string): string | undefined {
|
||||
return this._env && this._env[name];
|
||||
public getEnvironmentVariable(name: string): string {
|
||||
return (this._env && this._env[name])!; // TODO: GH#18217
|
||||
}
|
||||
|
||||
private _getStats(path: string) {
|
||||
@@ -275,7 +275,7 @@ namespace fakes {
|
||||
this._outputsMap.set(document.file, this.outputs.length);
|
||||
this.outputs.push(document);
|
||||
}
|
||||
this.outputs[this._outputsMap.get(document.file)] = document;
|
||||
this.outputs[this._outputsMap.get(document.file)!] = document;
|
||||
}
|
||||
|
||||
public trace(s: string): void {
|
||||
@@ -332,7 +332,7 @@ namespace fakes {
|
||||
let fs = this.vfs;
|
||||
while (fs.shadowRoot) {
|
||||
try {
|
||||
const shadowRootStats = fs.shadowRoot.existsSync(canonicalFileName) && fs.shadowRoot.statSync(canonicalFileName);
|
||||
const shadowRootStats = fs.shadowRoot.existsSync(canonicalFileName) ? fs.shadowRoot.statSync(canonicalFileName) : undefined!; // TODO: GH#18217
|
||||
if (shadowRootStats.dev !== stats.dev ||
|
||||
shadowRootStats.ino !== stats.ino ||
|
||||
shadowRootStats.mtimeMs !== stats.mtimeMs) {
|
||||
|
||||
+117
-117
@@ -184,7 +184,7 @@ namespace FourSlash {
|
||||
|
||||
private inputFiles = ts.createMap<string>(); // Map between inputFile's fileName and its content for easily looking up when resolving references
|
||||
|
||||
private static getDisplayPartsJson(displayParts: ts.SymbolDisplayPart[]) {
|
||||
private static getDisplayPartsJson(displayParts: ts.SymbolDisplayPart[] | undefined) {
|
||||
let result = "";
|
||||
ts.forEach(displayParts, part => {
|
||||
if (result) {
|
||||
@@ -204,7 +204,7 @@ namespace FourSlash {
|
||||
|
||||
// Add input file which has matched file name with the given reference-file path.
|
||||
// This is necessary when resolveReference flag is specified
|
||||
private addMatchedInputFile(referenceFilePath: string, extensions: ReadonlyArray<string>) {
|
||||
private addMatchedInputFile(referenceFilePath: string, extensions: ReadonlyArray<string> | undefined) {
|
||||
const inputFiles = this.inputFiles;
|
||||
const languageServiceAdapterHost = this.languageServiceAdapterHost;
|
||||
const didAdd = tryAdd(referenceFilePath);
|
||||
@@ -243,16 +243,16 @@ namespace FourSlash {
|
||||
compilationOptions.skipDefaultLibCheck = true;
|
||||
|
||||
// Initialize the language service with all the scripts
|
||||
let startResolveFileRef: FourSlashFile;
|
||||
let startResolveFileRef: FourSlashFile | undefined;
|
||||
|
||||
let configFileName: string;
|
||||
let configFileName: string | undefined;
|
||||
for (const file of testData.files) {
|
||||
// Create map between fileName and its content for easily looking up when resolveReference flag is specified
|
||||
this.inputFiles.set(file.fileName, file.content);
|
||||
if (isConfig(file)) {
|
||||
const configJson = ts.parseConfigFileTextToJson(file.fileName, file.content);
|
||||
if (configJson.config === undefined) {
|
||||
throw new Error(`Failed to parse test ${file.fileName}: ${configJson.error.messageText}`);
|
||||
throw new Error(`Failed to parse test ${file.fileName}: ${configJson.error!.messageText}`);
|
||||
}
|
||||
|
||||
// Extend our existing compiler options so that we can also support tsconfig only options
|
||||
@@ -280,12 +280,12 @@ namespace FourSlash {
|
||||
const baseDir = ts.normalizePath(ts.getDirectoryPath(configFileName));
|
||||
const files: vfs.FileSet = { [baseDir]: {} };
|
||||
this.inputFiles.forEach((data, path) => {
|
||||
const scriptInfo = new Harness.LanguageService.ScriptInfo(path, undefined, /*isRootFile*/ false);
|
||||
const scriptInfo = new Harness.LanguageService.ScriptInfo(path, undefined!, /*isRootFile*/ false); // TODO: GH#18217
|
||||
files[path] = new vfs.File(data, { meta: { scriptInfo } });
|
||||
});
|
||||
const fs = new vfs.FileSystem(/*ignoreCase*/ true, { cwd: baseDir, files });
|
||||
const host = new fakes.ParseConfigHost(fs);
|
||||
const jsonSourceFile = ts.parseJsonText(configFileName, this.inputFiles.get(configFileName));
|
||||
const jsonSourceFile = ts.parseJsonText(configFileName, this.inputFiles.get(configFileName)!);
|
||||
compilationOptions = ts.parseJsonSourceFileConfigFileContent(jsonSourceFile, host, baseDir, compilationOptions, configFileName).options;
|
||||
}
|
||||
|
||||
@@ -323,7 +323,7 @@ namespace FourSlash {
|
||||
// Check if no-default-lib flag is false and if so add default library
|
||||
if (!resolvedResult.isLibFile) {
|
||||
this.languageServiceAdapterHost.addScript(Harness.Compiler.defaultLibFileName,
|
||||
Harness.Compiler.getDefaultLibrarySourceFile().text, /*isRootFile*/ false);
|
||||
Harness.Compiler.getDefaultLibrarySourceFile()!.text, /*isRootFile*/ false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -335,7 +335,7 @@ namespace FourSlash {
|
||||
});
|
||||
if (!compilationOptions.noLib) {
|
||||
this.languageServiceAdapterHost.addScript(Harness.Compiler.defaultLibFileName,
|
||||
Harness.Compiler.getDefaultLibrarySourceFile().text, /*isRootFile*/ false);
|
||||
Harness.Compiler.getDefaultLibrarySourceFile()!.text, /*isRootFile*/ false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -393,7 +393,7 @@ namespace FourSlash {
|
||||
(...args) => args.join("|,|")
|
||||
);
|
||||
proxy[key] = (...args: any[]) => memo(
|
||||
target.languageServiceAdapterHost.getScriptInfo(target.activeFile.fileName).version,
|
||||
target.languageServiceAdapterHost.getScriptInfo(target.activeFile.fileName)!.version,
|
||||
target.activeFile.fileName,
|
||||
target.currentCaretPosition,
|
||||
target.selectionEnd,
|
||||
@@ -406,7 +406,7 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
private getFileContent(fileName: string): string {
|
||||
const script = this.languageServiceAdapterHost.getScriptInfo(fileName);
|
||||
const script = this.languageServiceAdapterHost.getScriptInfo(fileName)!;
|
||||
return script.content;
|
||||
}
|
||||
|
||||
@@ -548,9 +548,9 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
private anyErrorInRange(predicate: (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) => boolean, startMarker: Marker, endMarker?: Marker): boolean {
|
||||
private anyErrorInRange(predicate: (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number | undefined) => boolean, startMarker: Marker, endMarker?: Marker): boolean {
|
||||
return this.getDiagnostics(startMarker.fileName).some(({ start, length }) =>
|
||||
predicate(start, start + length, startMarker.position, endMarker === undefined ? undefined : endMarker.position));
|
||||
predicate(start!, start! + length!, startMarker.position, endMarker === undefined ? undefined : endMarker.position)); // TODO: GH#18217
|
||||
}
|
||||
|
||||
private printErrorLog(expectErrors: boolean, errors: ts.Diagnostic[]) {
|
||||
@@ -562,12 +562,12 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
for (const { start, length, messageText, file } of errors) {
|
||||
Harness.IO.log(" " + this.formatRange(file, start, length) +
|
||||
Harness.IO.log(" " + this.formatRange(file, start!, length!) + // TODO: GH#18217
|
||||
", message: " + ts.flattenDiagnosticMessageText(messageText, Harness.IO.newLine()) + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
private formatRange(file: ts.SourceFile, start: number, length: number) {
|
||||
private formatRange(file: ts.SourceFile | undefined, start: number, length: number) {
|
||||
if (file) {
|
||||
return `from: ${this.formatLineAndCharacterOfPosition(file, start)}, to: ${this.formatLineAndCharacterOfPosition(file, start + length)}`;
|
||||
}
|
||||
@@ -597,7 +597,7 @@ namespace FourSlash {
|
||||
if (errors.length) {
|
||||
this.printErrorLog(/*expectErrors*/ false, errors);
|
||||
const error = errors[0];
|
||||
this.raiseError(`Found an error: ${this.formatPosition(error.file, error.start)}: ${error.messageText}`);
|
||||
this.raiseError(`Found an error: ${this.formatPosition(error.file!, error.start!)}: ${error.messageText}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -635,11 +635,11 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
private getGoToDefinition(): ts.DefinitionInfo[] {
|
||||
return this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
return this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition)!;
|
||||
}
|
||||
|
||||
private getGoToDefinitionAndBoundSpan(): ts.DefinitionInfoAndBoundSpan {
|
||||
return this.languageService.getDefinitionAndBoundSpan(this.activeFile.fileName, this.currentCaretPosition);
|
||||
return this.languageService.getDefinitionAndBoundSpan(this.activeFile.fileName, this.currentCaretPosition)!;
|
||||
}
|
||||
|
||||
public verifyGoToType(arg0: any, endMarkerNames?: ArrayOrSingle<string>) {
|
||||
@@ -694,9 +694,9 @@ namespace FourSlash {
|
||||
testName = "goToDefinitions";
|
||||
}
|
||||
else {
|
||||
this.verifyDefinitionTextSpan(defs, startMarkerName);
|
||||
this.verifyDefinitionTextSpan(defs, startMarkerName!);
|
||||
|
||||
definitions = defs.definitions;
|
||||
definitions = defs.definitions!; // TODO: GH#18217
|
||||
testName = "goToDefinitionsAndBoundSpan";
|
||||
}
|
||||
|
||||
@@ -713,7 +713,7 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
private verifyDefinitionTextSpan(defs: ts.DefinitionInfoAndBoundSpan, startMarkerName: string) {
|
||||
const range = this.testData.ranges.find(range => this.markerName(range.marker) === startMarkerName);
|
||||
const range = this.testData.ranges.find(range => this.markerName(range.marker!) === startMarkerName);
|
||||
|
||||
if (!range && !defs.textSpan) {
|
||||
return;
|
||||
@@ -791,7 +791,7 @@ namespace FourSlash {
|
||||
return;
|
||||
}
|
||||
|
||||
const entries = this.getCompletionListAtCaret().entries;
|
||||
const entries = this.getCompletionListAtCaret()!.entries;
|
||||
assert.isTrue(items.length <= entries.length, `Amount of expected items in completion list [ ${items.length} ] is greater than actual number of items in list [ ${entries.length} ]`);
|
||||
ts.zipWith(entries, items, (entry, item) => {
|
||||
assert.equal(entry.name, item, `Unexpected item in completion list`);
|
||||
@@ -799,7 +799,7 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
public noItemsWithSameNameButDifferentKind(): void {
|
||||
const completions = this.getCompletionListAtCaret();
|
||||
const completions = this.getCompletionListAtCaret()!;
|
||||
const uniqueItems = ts.createMap<string>();
|
||||
for (const item of completions.entries) {
|
||||
const uniqueItem = uniqueItems.get(item.name);
|
||||
@@ -854,7 +854,7 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
private verifyCompletionsWorker(options: FourSlashInterface.VerifyCompletionsOptions): void {
|
||||
const actualCompletions = this.getCompletionListAtCaret({ ...options.preferences, triggerCharacter: options.triggerCharacter });
|
||||
const actualCompletions = this.getCompletionListAtCaret({ ...options.preferences, triggerCharacter: options.triggerCharacter })!;
|
||||
if (!actualCompletions) {
|
||||
if (options.exact === undefined) return;
|
||||
this.raiseError(`No completions at position '${this.currentCaretPosition}'.`);
|
||||
@@ -877,7 +877,7 @@ namespace FourSlash {
|
||||
|
||||
if ("exact" in options) {
|
||||
ts.Debug.assert(!("includes" in options) && !("excludes" in options));
|
||||
if (options.exact === undefined) this.raiseError("Expected no completions");
|
||||
if (options.exact === undefined) throw this.raiseError("Expected no completions");
|
||||
this.verifyCompletionsAreExactly(actualCompletions.entries, toArray(options.exact));
|
||||
}
|
||||
else {
|
||||
@@ -885,7 +885,7 @@ namespace FourSlash {
|
||||
for (const include of toArray(options.includes)) {
|
||||
const name = typeof include === "string" ? include : include.name;
|
||||
const found = actualByName.get(name);
|
||||
if (!found) this.raiseError(`No completion ${name} found`);
|
||||
if (!found) throw this.raiseError(`No completion ${name} found`);
|
||||
this.verifyCompletionEntry(found, include);
|
||||
}
|
||||
}
|
||||
@@ -929,7 +929,7 @@ namespace FourSlash {
|
||||
assert.equal(actual.isRecommended, isRecommended);
|
||||
|
||||
if (text) {
|
||||
const actualDetails = this.getCompletionEntryDetails(actual.name, actual.source);
|
||||
const actualDetails = this.getCompletionEntryDetails(actual.name, actual.source)!;
|
||||
assert.equal(ts.displayPartsToString(actualDetails.displayParts), text);
|
||||
assert.equal(ts.displayPartsToString(actualDetails.documentation), documentation || "");
|
||||
// TODO: GH#23587
|
||||
@@ -962,8 +962,7 @@ namespace FourSlash {
|
||||
exact: expected,
|
||||
isNewIdentifierLocation: options && options.isNewIdentifierLocation,
|
||||
preferences: options,
|
||||
// TODO: GH#20090
|
||||
triggerCharacter: (options && options.triggerCharacter) as ts.CompletionsTriggerCharacter | undefined,
|
||||
triggerCharacter: options && options.triggerCharacter,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -989,7 +988,7 @@ namespace FourSlash {
|
||||
* @param spanIndex the index of the range that the completion item's replacement text span should match
|
||||
*/
|
||||
public verifyCompletionListDoesNotContain(entryId: ts.Completions.CompletionEntryIdentifier, expectedText?: string, expectedDocumentation?: string, expectedKind?: string | { kind?: string, kindModifiers?: string }, spanIndex?: number, options?: FourSlashInterface.CompletionsAtOptions) {
|
||||
let replacementSpan: ts.TextSpan;
|
||||
let replacementSpan: ts.TextSpan | undefined;
|
||||
if (spanIndex !== undefined) {
|
||||
replacementSpan = this.getTextSpanForRangeAtIndex(spanIndex);
|
||||
}
|
||||
@@ -1022,7 +1021,7 @@ namespace FourSlash {
|
||||
// then these symbols must meet the criterion for Not supposed to be in the list. So we
|
||||
// raise an error
|
||||
let error = `Completion list did contain '${JSON.stringify(entryId)}\'.`;
|
||||
const details = this.getCompletionEntryDetails(filterCompletions[0].name);
|
||||
const details = this.getCompletionEntryDetails(filterCompletions[0].name)!;
|
||||
if (expectedText) {
|
||||
error += "Expected text: " + expectedText + " to equal: " + ts.displayPartsToString(details.displayParts) + ".";
|
||||
}
|
||||
@@ -1045,7 +1044,7 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
public verifyCompletionEntryDetails(entryName: string, expectedText: string, expectedDocumentation?: string, kind?: string, tags?: ts.JSDocTagInfo[]) {
|
||||
const details = this.getCompletionEntryDetails(entryName);
|
||||
const details = this.getCompletionEntryDetails(entryName)!;
|
||||
|
||||
assert(details, "no completion entry available");
|
||||
|
||||
@@ -1060,8 +1059,8 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
if (tags !== undefined) {
|
||||
assert.equal(details.tags.length, tags.length, this.messageAtLastKnownMarker("QuickInfo tags"));
|
||||
ts.zipWith(tags, details.tags, (expectedTag, actualTag) => {
|
||||
assert.equal(details.tags!.length, tags.length, this.messageAtLastKnownMarker("QuickInfo tags"));
|
||||
ts.zipWith(tags, details.tags!, (expectedTag, actualTag) => {
|
||||
assert.equal(actualTag.name, expectedTag.name);
|
||||
assert.equal(actualTag.text, expectedTag.text, this.messageAtLastKnownMarker("QuickInfo tag " + actualTag.name));
|
||||
});
|
||||
@@ -1074,7 +1073,7 @@ namespace FourSlash {
|
||||
private _checker: ts.TypeChecker;
|
||||
|
||||
private getProgram(): ts.Program {
|
||||
return this._program || (this._program = this.languageService.getProgram());
|
||||
return this._program || (this._program = this.languageService.getProgram()!); // TODO: GH#18217
|
||||
}
|
||||
|
||||
private getChecker() {
|
||||
@@ -1122,7 +1121,7 @@ namespace FourSlash {
|
||||
|
||||
public verifySymbolAtLocation(startRange: Range, declarationRanges: Range[]): void {
|
||||
const node = this.goToAndGetNode(startRange);
|
||||
const symbol = this.getChecker().getSymbolAtLocation(node);
|
||||
const symbol = this.getChecker().getSymbolAtLocation(node)!;
|
||||
if (!symbol) {
|
||||
this.raiseError("Could not get symbol at location");
|
||||
}
|
||||
@@ -1153,14 +1152,14 @@ namespace FourSlash {
|
||||
const startFile = this.activeFile.fileName;
|
||||
for (const fileName of files) {
|
||||
const searchFileNames = startFile === fileName ? [startFile] : [startFile, fileName];
|
||||
const highlights = this.getDocumentHighlightsAtCurrentPosition(searchFileNames);
|
||||
const highlights = this.getDocumentHighlightsAtCurrentPosition(searchFileNames)!;
|
||||
if (!highlights.every(dh => ts.contains(searchFileNames, dh.fileName))) {
|
||||
this.raiseError(`When asking for document highlights only in files ${searchFileNames}, got document highlights in ${unique(highlights, dh => dh.fileName)}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public verifyReferenceGroups(starts: ArrayOrSingle<string> | ArrayOrSingle<Range>, parts: ReadonlyArray<FourSlashInterface.ReferenceGroup> | undefined): void {
|
||||
public verifyReferenceGroups(starts: ArrayOrSingle<string> | ArrayOrSingle<Range>, parts: ReadonlyArray<FourSlashInterface.ReferenceGroup>): void {
|
||||
interface ReferenceGroupJson {
|
||||
definition: string | { text: string, range: ts.TextSpan };
|
||||
references: ts.ReferenceEntry[];
|
||||
@@ -1220,7 +1219,7 @@ namespace FourSlash {
|
||||
// Necessary to have this function since `findReferences` isn't implemented in `client.ts`
|
||||
public verifyGetReferencesForServerTest(expected: ReadonlyArray<ts.ReferenceEntry>): void {
|
||||
const refs = this.getReferencesAtCaret();
|
||||
assert.deepEqual(refs, expected);
|
||||
assert.deepEqual<ReadonlyArray<ts.ReferenceEntry> | undefined>(refs, expected);
|
||||
}
|
||||
|
||||
public verifySingleReferenceGroup(definition: FourSlashInterface.ReferenceGroupDefinition, ranges?: Range[]) {
|
||||
@@ -1274,7 +1273,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
|
||||
public verifyDisplayPartsOfReferencedSymbol(expected: ts.SymbolDisplayPart[]) {
|
||||
const referencedSymbols = this.findReferencesAtCaret();
|
||||
const referencedSymbols = this.findReferencesAtCaret()!;
|
||||
|
||||
if (referencedSymbols.length === 0) {
|
||||
this.raiseError("No referenced symbols found at current caret position");
|
||||
@@ -1287,11 +1286,11 @@ Actual: ${stringify(fullActual)}`);
|
||||
TestState.getDisplayPartsJson(expected), this.messageAtLastKnownMarker("referenced symbol definition display parts"));
|
||||
}
|
||||
|
||||
private getCompletionListAtCaret(options?: ts.GetCompletionsAtPositionOptions): ts.CompletionInfo {
|
||||
private getCompletionListAtCaret(options?: ts.GetCompletionsAtPositionOptions): ts.CompletionInfo | undefined {
|
||||
return this.languageService.getCompletionsAtPosition(this.activeFile.fileName, this.currentCaretPosition, options);
|
||||
}
|
||||
|
||||
private getCompletionEntryDetails(entryName: string, source?: string, preferences?: ts.UserPreferences): ts.CompletionEntryDetails {
|
||||
private getCompletionEntryDetails(entryName: string, source?: string, preferences?: ts.UserPreferences): ts.CompletionEntryDetails | undefined {
|
||||
return this.languageService.getCompletionEntryDetails(this.activeFile.fileName, this.currentCaretPosition, entryName, this.formatCodeSettings, source, preferences);
|
||||
}
|
||||
|
||||
@@ -1366,14 +1365,14 @@ Actual: ${stringify(fullActual)}`);
|
||||
tags: ts.JSDocTagInfo[]
|
||||
) {
|
||||
|
||||
const actualQuickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
const actualQuickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition)!;
|
||||
assert.equal(actualQuickInfo.kind, kind, this.messageAtLastKnownMarker("QuickInfo kind"));
|
||||
assert.equal(actualQuickInfo.kindModifiers, kindModifiers, this.messageAtLastKnownMarker("QuickInfo kindModifiers"));
|
||||
assert.equal(JSON.stringify(actualQuickInfo.textSpan), JSON.stringify(textSpan), this.messageAtLastKnownMarker("QuickInfo textSpan"));
|
||||
assert.equal(TestState.getDisplayPartsJson(actualQuickInfo.displayParts), TestState.getDisplayPartsJson(displayParts), this.messageAtLastKnownMarker("QuickInfo displayParts"));
|
||||
assert.equal(TestState.getDisplayPartsJson(actualQuickInfo.documentation), TestState.getDisplayPartsJson(documentation), this.messageAtLastKnownMarker("QuickInfo documentation"));
|
||||
assert.equal(actualQuickInfo.tags.length, tags.length, this.messageAtLastKnownMarker("QuickInfo tags"));
|
||||
ts.zipWith(tags, actualQuickInfo.tags, (expectedTag, actualTag) => {
|
||||
assert.equal(actualQuickInfo.tags!.length, tags.length, this.messageAtLastKnownMarker("QuickInfo tags"));
|
||||
ts.zipWith(tags, actualQuickInfo.tags!, (expectedTag, actualTag) => {
|
||||
assert.equal(expectedTag.name, actualTag.name);
|
||||
assert.equal(expectedTag.text, actualTag.text, this.messageAtLastKnownMarker("QuickInfo tag " + actualTag.name));
|
||||
});
|
||||
@@ -1481,10 +1480,10 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
|
||||
private verifySignatureHelpWorker(options: FourSlashInterface.VerifySignatureHelpOptions) {
|
||||
const help = this.getSignatureHelp();
|
||||
const help = this.getSignatureHelp()!;
|
||||
const selectedItem = help.items[help.selectedItemIndex];
|
||||
// Argument index may exceed number of parameters
|
||||
const currentParameter: ts.SignatureHelpParameter | undefined = selectedItem.parameters[help.argumentIndex];
|
||||
const currentParameter = selectedItem.parameters[help.argumentIndex] as ts.SignatureHelpParameter | undefined;
|
||||
|
||||
assert.equal(help.items.length, options.overloadsCount || 1, this.assertionMessageAtLastKnownMarker("signature help overloads count"));
|
||||
|
||||
@@ -1539,7 +1538,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
}
|
||||
|
||||
private validate(name: string, expected: string, actual: string) {
|
||||
private validate(name: string, expected: string | undefined, actual: string | undefined) {
|
||||
if (expected && expected !== actual) {
|
||||
this.raiseError("Expected " + name + " '" + expected + "'. Got '" + actual + "' instead.");
|
||||
}
|
||||
@@ -1601,19 +1600,19 @@ Actual: ${stringify(fullActual)}`);
|
||||
let nextLine = 0;
|
||||
let resultString = "";
|
||||
let currentLine: string;
|
||||
let previousSpanInfo: string;
|
||||
let startColumn: number;
|
||||
let length: number;
|
||||
let previousSpanInfo: string | undefined;
|
||||
let startColumn: number | undefined;
|
||||
let length: number | undefined;
|
||||
const prefixString = " >";
|
||||
|
||||
let pos = 0;
|
||||
const addSpanInfoString = () => {
|
||||
if (previousSpanInfo) {
|
||||
resultString += currentLine;
|
||||
let thisLineMarker = ts.repeatString(" ", startColumn) + ts.repeatString("~", length);
|
||||
let thisLineMarker = ts.repeatString(" ", startColumn!) + ts.repeatString("~", length!);
|
||||
thisLineMarker += ts.repeatString(" ", this.alignmentForExtraInfo - thisLineMarker.length - prefixString.length + 1);
|
||||
resultString += thisLineMarker;
|
||||
resultString += "=> Pos: (" + (pos - length) + " to " + (pos - 1) + ") ";
|
||||
resultString += "=> Pos: (" + (pos - length!) + " to " + (pos - 1) + ") ";
|
||||
resultString += " " + previousSpanInfo;
|
||||
previousSpanInfo = undefined;
|
||||
}
|
||||
@@ -1634,12 +1633,12 @@ Actual: ${stringify(fullActual)}`);
|
||||
if (previousSpanInfo && previousSpanInfo !== spanInfo) {
|
||||
addSpanInfoString();
|
||||
previousSpanInfo = spanInfo;
|
||||
startColumn = startColumn + length;
|
||||
startColumn = startColumn! + length!;
|
||||
length = 1;
|
||||
}
|
||||
else {
|
||||
previousSpanInfo = spanInfo;
|
||||
length++;
|
||||
length!++;
|
||||
}
|
||||
}
|
||||
addSpanInfoString();
|
||||
@@ -1660,7 +1659,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
Harness.Baseline.runBaseline(
|
||||
baselineFile,
|
||||
() => {
|
||||
return this.baselineCurrentFileLocations(pos => this.getBreakpointStatementLocation(pos));
|
||||
return this.baselineCurrentFileLocations(pos => this.getBreakpointStatementLocation(pos)!);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1693,10 +1692,10 @@ Actual: ${stringify(fullActual)}`);
|
||||
|
||||
if (emitOutput.emitSkipped) {
|
||||
resultString += "Diagnostics:" + Harness.IO.newLine();
|
||||
const diagnostics = ts.getPreEmitDiagnostics(this.languageService.getProgram());
|
||||
const diagnostics = ts.getPreEmitDiagnostics(this.languageService.getProgram()!); // TODO: GH#18217
|
||||
for (const diagnostic of diagnostics) {
|
||||
if (!ts.isString(diagnostic.messageText)) {
|
||||
let chainedMessage = diagnostic.messageText;
|
||||
let chainedMessage: ts.DiagnosticMessageChain | undefined = diagnostic.messageText;
|
||||
let indentation = " ";
|
||||
while (chainedMessage) {
|
||||
resultString += indentation + chainedMessage.messageText + Harness.IO.newLine();
|
||||
@@ -1741,7 +1740,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
|
||||
public printBreakpointLocation(pos: number) {
|
||||
Harness.IO.log("\n**Pos: " + pos + " " + this.spanInfoToString(this.getBreakpointStatementLocation(pos), " "));
|
||||
Harness.IO.log("\n**Pos: " + pos + " " + this.spanInfoToString(this.getBreakpointStatementLocation(pos)!, " "));
|
||||
}
|
||||
|
||||
public printBreakpointAtCurrentLocation() {
|
||||
@@ -1754,8 +1753,8 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
|
||||
public printCurrentQuickInfo() {
|
||||
const quickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
Harness.IO.log("Quick Info: " + quickInfo.displayParts.map(part => part.text).join(""));
|
||||
const quickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition)!;
|
||||
Harness.IO.log("Quick Info: " + quickInfo.displayParts!.map(part => part.text).join(""));
|
||||
}
|
||||
|
||||
public printErrorList() {
|
||||
@@ -1790,7 +1789,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
|
||||
public printCurrentSignatureHelp() {
|
||||
const help = this.getSignatureHelp();
|
||||
const help = this.getSignatureHelp()!;
|
||||
Harness.IO.log(stringify(help.items[help.selectedItemIndex]));
|
||||
}
|
||||
|
||||
@@ -1803,7 +1802,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
this.printMembersOrCompletions(completions);
|
||||
}
|
||||
|
||||
private printMembersOrCompletions(info: ts.CompletionInfo) {
|
||||
private printMembersOrCompletions(info: ts.CompletionInfo | undefined) {
|
||||
if (info === undefined) { return "No completion info."; }
|
||||
const { entries } = info;
|
||||
|
||||
@@ -2087,7 +2086,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
|
||||
public goToTypeDefinition(definitionIndex: number) {
|
||||
const definitions = this.languageService.getTypeDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
const definitions = this.languageService.getTypeDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition)!;
|
||||
if (!definitions || !definitions.length) {
|
||||
this.raiseError("goToTypeDefinition failed - expected to find at least one definition location but got 0");
|
||||
}
|
||||
@@ -2130,7 +2129,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
|
||||
public goToImplementation() {
|
||||
const implementations = this.languageService.getImplementationAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
const implementations = this.languageService.getImplementationAtPosition(this.activeFile.fileName, this.currentCaretPosition)!;
|
||||
if (!implementations || !implementations.length) {
|
||||
this.raiseError("goToImplementation failed - expected to find at least one implementation location but got 0");
|
||||
}
|
||||
@@ -2145,7 +2144,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
|
||||
public verifyRangesInImplementationList(markerName: string) {
|
||||
this.goToMarker(markerName);
|
||||
const implementations: ImplementationLocationInformation[] = this.languageService.getImplementationAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
const implementations: ImplementationLocationInformation[] = this.languageService.getImplementationAtPosition(this.activeFile.fileName, this.currentCaretPosition)!;
|
||||
if (!implementations || !implementations.length) {
|
||||
this.raiseError("verifyRangesInImplementationList failed - expected to find at least one implementation location but got 0");
|
||||
}
|
||||
@@ -2321,7 +2320,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
public verifyCurrentNameOrDottedNameSpanText(text: string) {
|
||||
const span = this.languageService.getNameOrDottedNameSpan(this.activeFile.fileName, this.currentCaretPosition, this.currentCaretPosition);
|
||||
if (!span) {
|
||||
this.raiseError("verifyCurrentNameOrDottedNameSpanText\n" +
|
||||
return this.raiseError("verifyCurrentNameOrDottedNameSpanText\n" +
|
||||
"\tExpected: \"" + text + "\"\n" +
|
||||
"\t Actual: undefined");
|
||||
}
|
||||
@@ -2343,12 +2342,12 @@ Actual: ${stringify(fullActual)}`);
|
||||
this.testData.globalOptions[MetadataOptionNames.baselineFile],
|
||||
() => {
|
||||
return this.baselineCurrentFileLocations(pos =>
|
||||
this.getNameOrDottedNameSpan(pos));
|
||||
this.getNameOrDottedNameSpan(pos)!);
|
||||
});
|
||||
}
|
||||
|
||||
public printNameOrDottedNameSpans(pos: number) {
|
||||
Harness.IO.log(this.spanInfoToString(this.getNameOrDottedNameSpan(pos), "**"));
|
||||
Harness.IO.log(this.spanInfoToString(this.getNameOrDottedNameSpan(pos)!, "**"));
|
||||
}
|
||||
|
||||
private verifyClassifications(expected: { classificationType: string; text: string; textSpan?: TextSpan }[], actual: ts.ClassifiedSpan[], sourceFileText: string) {
|
||||
@@ -2407,7 +2406,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
);
|
||||
assert.equal(
|
||||
expected.join(","),
|
||||
actual.fileNames.map(file => {
|
||||
actual.fileNames!.map(file => {
|
||||
return file.replace(this.basePath + "/", "");
|
||||
}).join(",")
|
||||
);
|
||||
@@ -2482,18 +2481,19 @@ Actual: ${stringify(fullActual)}`);
|
||||
public applyCodeActionFromCompletion(markerName: string, options: FourSlashInterface.VerifyCompletionActionOptions) {
|
||||
this.goToMarker(markerName);
|
||||
|
||||
const details = this.getCompletionEntryDetails(options.name, options.source, options.preferences);
|
||||
if (details.codeActions.length !== 1) {
|
||||
this.raiseError(`Expected one code action, got ${details.codeActions.length}`);
|
||||
const details = this.getCompletionEntryDetails(options.name, options.source, options.preferences)!;
|
||||
const codeActions = details.codeActions!;
|
||||
if (codeActions.length !== 1) {
|
||||
this.raiseError(`Expected one code action, got ${codeActions.length}`);
|
||||
}
|
||||
|
||||
if (details.codeActions[0].description !== options.description) {
|
||||
this.raiseError(`Expected description to be:\n${options.description}\ngot:\n${details.codeActions[0].description}`);
|
||||
if (codeActions[0].description !== options.description) {
|
||||
this.raiseError(`Expected description to be:\n${options.description}\ngot:\n${codeActions[0].description}`);
|
||||
}
|
||||
|
||||
this.applyCodeActions(details.codeActions);
|
||||
this.applyCodeActions(codeActions);
|
||||
|
||||
this.verifyNewContent(options, ts.flatMap(details.codeActions, a => a.changes.map(c => c.fileName)));
|
||||
this.verifyNewContent(options, ts.flatMap(codeActions, a => a.changes.map(c => c.fileName)));
|
||||
}
|
||||
|
||||
public verifyRangeIs(expectedText: string, includeWhiteSpace?: boolean) {
|
||||
@@ -2527,10 +2527,10 @@ Actual: ${stringify(fullActual)}`);
|
||||
const fixWithId = ts.find(this.getCodeFixes(this.activeFile.fileName), a => a.fixId === fixId);
|
||||
ts.Debug.assert(fixWithId !== undefined, "No available code fix has that group id.", () =>
|
||||
`Expected '${fixId}'. Available action ids: ${ts.mapDefined(this.getCodeFixes(this.activeFile.fileName), a => a.fixId)}`);
|
||||
ts.Debug.assertEqual(fixWithId.fixAllDescription, fixAllDescription);
|
||||
ts.Debug.assertEqual(fixWithId!.fixAllDescription, fixAllDescription);
|
||||
|
||||
const { changes, commands } = this.languageService.getCombinedCodeFix({ type: "file", fileName: this.activeFile.fileName }, fixId, this.formatCodeSettings, ts.defaultPreferences);
|
||||
assert.deepEqual(commands, expectedCommands);
|
||||
assert.deepEqual<ReadonlyArray<{}> | undefined>(commands, expectedCommands);
|
||||
assert(changes.every(c => c.fileName === this.activeFile.fileName), "TODO: support testing codefixes that touch multiple files");
|
||||
this.applyChanges(changes);
|
||||
this.verifyCurrentFileContent(newFileContent);
|
||||
@@ -2601,7 +2601,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.verifyRangeIs(options.newRangeContent, /*includeWhitespace*/ true);
|
||||
this.verifyRangeIs(options.newRangeContent!, /*includeWhitespace*/ true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2621,7 +2621,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
return;
|
||||
}
|
||||
|
||||
return this.languageService.getCodeFixesAtPosition(fileName, diagnostic.start, diagnostic.start + diagnostic.length, [diagnostic.code], this.formatCodeSettings, preferences);
|
||||
return this.languageService.getCodeFixesAtPosition(fileName, diagnostic.start!, diagnostic.start! + diagnostic.length!, [diagnostic.code], this.formatCodeSettings, preferences);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2665,7 +2665,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
|
||||
const actualTextArray: string[] = [];
|
||||
const scriptInfo = this.languageServiceAdapterHost.getScriptInfo(fileName);
|
||||
const scriptInfo = this.languageServiceAdapterHost.getScriptInfo(fileName)!;
|
||||
const originalContent = scriptInfo.content;
|
||||
for (const codeFix of codeFixes) {
|
||||
ts.Debug.assert(codeFix.changes.length === 1);
|
||||
@@ -2688,7 +2688,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
|
||||
public verifyDocCommentTemplate(expected: ts.TextInsertion | undefined) {
|
||||
const name = "verifyDocCommentTemplate";
|
||||
const actual = this.languageService.getDocCommentTemplateAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
const actual = this.languageService.getDocCommentTemplateAtPosition(this.activeFile.fileName, this.currentCaretPosition)!;
|
||||
|
||||
if (expected === undefined) {
|
||||
if (actual) {
|
||||
@@ -2727,7 +2727,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
const charCode = openBraceMap.get(openingBrace);
|
||||
|
||||
if (!charCode) {
|
||||
this.raiseError(`Invalid openingBrace '${openingBrace}' specified.`);
|
||||
throw this.raiseError(`Invalid openingBrace '${openingBrace}' specified.`);
|
||||
}
|
||||
|
||||
const position = this.currentCaretPosition;
|
||||
@@ -2899,7 +2899,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
const occurrences = this.getOccurrencesAtCurrentPosition();
|
||||
|
||||
if (!occurrences || occurrences.length === 0) {
|
||||
this.raiseError("verifyOccurrencesAtPositionListContains failed - found 0 references, expected at least one.");
|
||||
return this.raiseError("verifyOccurrencesAtPositionListContains failed - found 0 references, expected at least one.");
|
||||
}
|
||||
|
||||
for (const occurrence of occurrences) {
|
||||
@@ -3091,13 +3091,13 @@ Actual: ${stringify(fullActual)}`);
|
||||
|
||||
const action = ts.firstDefined(refactorsWithName, refactor => refactor.actions.find(a => a.name === actionName));
|
||||
if (!action) {
|
||||
this.raiseError(`The expected action: ${actionName} is not included in: ${ts.flatMap(refactorsWithName, r => r.actions.map(a => a.name))}`);
|
||||
throw this.raiseError(`The expected action: ${actionName} is not included in: ${ts.flatMap(refactorsWithName, r => r.actions.map(a => a.name))}`);
|
||||
}
|
||||
if (action.description !== actionDescription) {
|
||||
this.raiseError(`Expected action description to be ${JSON.stringify(actionDescription)}, got: ${JSON.stringify(action.description)}`);
|
||||
}
|
||||
|
||||
const editInfo = this.languageService.getEditsForRefactor(this.activeFile.fileName, this.formatCodeSettings, range, refactorName, actionName, ts.defaultPreferences);
|
||||
const editInfo = this.languageService.getEditsForRefactor(this.activeFile.fileName, this.formatCodeSettings, range, refactorName, actionName, ts.defaultPreferences)!;
|
||||
for (const edit of editInfo.edits) {
|
||||
this.applyEdits(edit.fileName, edit.textChanges, /*isFormattingEdit*/ false);
|
||||
}
|
||||
@@ -3144,12 +3144,12 @@ Actual: ${stringify(fullActual)}`);
|
||||
public moveToNewFile(options: FourSlashInterface.MoveToNewFileOptions): void {
|
||||
assert(this.getRanges().length === 1);
|
||||
const range = this.getRanges()[0];
|
||||
const refactor = ts.find(this.getApplicableRefactors(range, { allowTextChangesInNewFiles: true }), r => r.name === "Move to a new file");
|
||||
const refactor = ts.find(this.getApplicableRefactors(range, { allowTextChangesInNewFiles: true }), r => r.name === "Move to a new file")!;
|
||||
assert(refactor.actions.length === 1);
|
||||
const action = ts.first(refactor.actions);
|
||||
assert(action.name === "Move to a new file" && action.description === "Move to a new file");
|
||||
|
||||
const editInfo = this.languageService.getEditsForRefactor(this.activeFile.fileName, this.formatCodeSettings, range, refactor.name, action.name, ts.defaultPreferences);
|
||||
const editInfo = this.languageService.getEditsForRefactor(this.activeFile.fileName, this.formatCodeSettings, range, refactor.name, action.name, ts.defaultPreferences)!;
|
||||
for (const edit of editInfo.edits) {
|
||||
const newContent = options.newFileContents[edit.fileName];
|
||||
if (newContent === undefined) {
|
||||
@@ -3190,7 +3190,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
this.raiseError(`The expected refactor: ${refactorNameToApply} is not available at the marker location.`);
|
||||
}
|
||||
|
||||
const editInfo = this.languageService.getEditsForRefactor(this.activeFile.fileName, formattingOptions, markerPos, refactorNameToApply, actionName, ts.defaultPreferences);
|
||||
const editInfo = this.languageService.getEditsForRefactor(this.activeFile.fileName, formattingOptions, markerPos, refactorNameToApply, actionName, ts.defaultPreferences)!;
|
||||
|
||||
for (const edit of editInfo.edits) {
|
||||
this.applyEdits(edit.fileName, edit.textChanges, /*isFormattingEdit*/ false);
|
||||
@@ -3260,7 +3260,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
const item = matchingItems[0];
|
||||
|
||||
if (documentation !== undefined || text !== undefined || entryId.source !== undefined) {
|
||||
const details = this.getCompletionEntryDetails(item.name, item.source);
|
||||
const details = this.getCompletionEntryDetails(item.name, item.source)!;
|
||||
|
||||
if (documentation !== undefined) {
|
||||
eq(ts.displayPartsToString(details.documentation), documentation, "completion item documentation");
|
||||
@@ -3348,11 +3348,11 @@ Actual: ${stringify(fullActual)}`);
|
||||
|
||||
private getTextSpanForRangeAtIndex(index: number): ts.TextSpan {
|
||||
const ranges = this.getRanges();
|
||||
if (ranges && ranges.length > index) {
|
||||
if (ranges.length > index) {
|
||||
return ts.createTextSpanFromRange(ranges[index]);
|
||||
}
|
||||
else {
|
||||
this.raiseError("Supplied span index: " + index + " does not exist in range list of size: " + (ranges ? 0 : ranges.length));
|
||||
throw this.raiseError("Supplied span index: " + index + " does not exist in range list of size: " + ranges.length);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3374,8 +3374,8 @@ Actual: ${stringify(fullActual)}`);
|
||||
this.cancellationToken.resetCancelled();
|
||||
}
|
||||
|
||||
private static textSpansEqual(a: ts.TextSpan, b: ts.TextSpan) {
|
||||
return a && b && a.start === b.start && a.length === b.length;
|
||||
private static textSpansEqual(a: ts.TextSpan | undefined, b: ts.TextSpan | undefined): boolean {
|
||||
return !!a && !!b && a.start === b.start && a.length === b.length;
|
||||
}
|
||||
|
||||
public getEditsForFileRename(options: FourSlashInterface.GetEditsForFileRenameOptions): void {
|
||||
@@ -3393,7 +3393,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
|
||||
export function runFourSlashTest(basePath: string, testType: FourSlashTestType, fileName: string) {
|
||||
const content = Harness.IO.readFile(fileName);
|
||||
const content = Harness.IO.readFile(fileName)!;
|
||||
runFourSlashTestContent(basePath, testType, content, fileName);
|
||||
}
|
||||
|
||||
@@ -3406,8 +3406,8 @@ Actual: ${stringify(fullActual)}`);
|
||||
const testData = parseTestData(absoluteBasePath, content, absoluteFileName);
|
||||
const state = new TestState(absoluteBasePath, testType, testData);
|
||||
const output = ts.transpileModule(content, { reportDiagnostics: true });
|
||||
if (output.diagnostics.length > 0) {
|
||||
throw new Error(`Syntax error in ${absoluteBasePath}: ${output.diagnostics[0].messageText}`);
|
||||
if (output.diagnostics!.length > 0) {
|
||||
throw new Error(`Syntax error in ${absoluteBasePath}: ${output.diagnostics![0].messageText}`);
|
||||
}
|
||||
runCode(output.outputText, state);
|
||||
}
|
||||
@@ -3558,11 +3558,11 @@ ${code}
|
||||
return Harness.getConfigNameFromFileName(file.fileName) !== undefined;
|
||||
}
|
||||
|
||||
function getNonFileNameOptionInFileList(files: FourSlashFile[]): string {
|
||||
function getNonFileNameOptionInFileList(files: FourSlashFile[]): string | undefined {
|
||||
return ts.forEach(files, f => getNonFileNameOptionInObject(f.fileOptions));
|
||||
}
|
||||
|
||||
function getNonFileNameOptionInObject(optionObject: { [s: string]: string }): string {
|
||||
function getNonFileNameOptionInObject(optionObject: { [s: string]: string }): string | undefined {
|
||||
for (const option in optionObject) {
|
||||
if (option !== MetadataOptionNames.fileName) {
|
||||
return option;
|
||||
@@ -3582,7 +3582,7 @@ ${code}
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
|
||||
function recordObjectMarker(fileName: string, location: LocationInformation, text: string, markerMap: ts.Map<Marker>, markers: Marker[]): Marker {
|
||||
function recordObjectMarker(fileName: string, location: LocationInformation, text: string, markerMap: ts.Map<Marker>, markers: Marker[]): Marker | undefined {
|
||||
let markerValue: any;
|
||||
try {
|
||||
// Attempt to parse the marker value as JSON
|
||||
@@ -3613,7 +3613,7 @@ ${code}
|
||||
return marker;
|
||||
}
|
||||
|
||||
function recordMarker(fileName: string, location: LocationInformation, name: string, markerMap: ts.Map<Marker>, markers: Marker[]): Marker {
|
||||
function recordMarker(fileName: string, location: LocationInformation, name: string, markerMap: ts.Map<Marker>, markers: Marker[]): Marker | undefined {
|
||||
const marker: Marker = {
|
||||
fileName,
|
||||
position: location.position
|
||||
@@ -3642,7 +3642,7 @@ ${code}
|
||||
let output = "";
|
||||
|
||||
/// The current marker (or maybe multi-line comment?) we're parsing, possibly
|
||||
let openMarker: LocationInformation;
|
||||
let openMarker: LocationInformation | undefined;
|
||||
|
||||
/// A stack of the open range markers that are still unclosed
|
||||
const openRanges: RangeLocationInformation[] = [];
|
||||
@@ -3663,7 +3663,7 @@ ${code}
|
||||
let line = 1;
|
||||
let column = 1;
|
||||
|
||||
const flush = (lastSafeCharIndex: number) => {
|
||||
const flush = (lastSafeCharIndex: number | undefined) => {
|
||||
output = output + content.substr(lastNormalCharPosition, lastSafeCharIndex === undefined ? undefined : lastSafeCharIndex - lastNormalCharPosition);
|
||||
};
|
||||
|
||||
@@ -3690,7 +3690,7 @@ ${code}
|
||||
// found a range end
|
||||
const rangeStart = openRanges.pop();
|
||||
if (!rangeStart) {
|
||||
reportError(fileName, line, column, "Found range end with no matching start.");
|
||||
throw reportError(fileName, line, column, "Found range end with no matching start.");
|
||||
}
|
||||
|
||||
const range: Range = {
|
||||
@@ -3733,8 +3733,8 @@ ${code}
|
||||
// Object markers are only ever terminated by |} and have no content restrictions
|
||||
if (previousChar === "|" && currentChar === "}") {
|
||||
// Record the marker
|
||||
const objectMarkerNameText = content.substring(openMarker.sourcePosition + 2, i - 1).trim();
|
||||
const marker = recordObjectMarker(fileName, openMarker, objectMarkerNameText, markerMap, markers);
|
||||
const objectMarkerNameText = content.substring(openMarker!.sourcePosition + 2, i - 1).trim();
|
||||
const marker = recordObjectMarker(fileName, openMarker!, objectMarkerNameText, markerMap, markers);
|
||||
|
||||
if (openRanges.length > 0) {
|
||||
openRanges[openRanges.length - 1].marker = marker;
|
||||
@@ -3742,7 +3742,7 @@ ${code}
|
||||
|
||||
// Set the current start to point to the end of the current marker to ignore its text
|
||||
lastNormalCharPosition = i + 1;
|
||||
difference += i + 1 - openMarker.sourcePosition;
|
||||
difference += i + 1 - openMarker!.sourcePosition;
|
||||
|
||||
// Reset the state
|
||||
openMarker = undefined;
|
||||
@@ -3754,17 +3754,17 @@ ${code}
|
||||
if (previousChar === "*" && currentChar === "/") {
|
||||
// Record the marker
|
||||
// start + 2 to ignore the */, -1 on the end to ignore the * (/ is next)
|
||||
const markerNameText = content.substring(openMarker.sourcePosition + 2, i - 1).trim();
|
||||
const marker = recordMarker(fileName, openMarker, markerNameText, markerMap, markers);
|
||||
const markerNameText = content.substring(openMarker!.sourcePosition + 2, i - 1).trim();
|
||||
const marker = recordMarker(fileName, openMarker!, markerNameText, markerMap, markers);
|
||||
|
||||
if (openRanges.length > 0) {
|
||||
openRanges[openRanges.length - 1].marker = marker;
|
||||
}
|
||||
|
||||
// Set the current start to point to the end of the current marker to ignore its text
|
||||
flush(openMarker.sourcePosition);
|
||||
flush(openMarker!.sourcePosition);
|
||||
lastNormalCharPosition = i + 1;
|
||||
difference += i + 1 - openMarker.sourcePosition;
|
||||
difference += i + 1 - openMarker!.sourcePosition;
|
||||
|
||||
// Reset the state
|
||||
openMarker = undefined;
|
||||
@@ -3865,7 +3865,7 @@ ${code}
|
||||
return s.replace(/\s/g, "");
|
||||
}
|
||||
|
||||
function findDuplicatedElement<T>(a: ReadonlyArray<T>, equal: (a: T, b: T) => boolean): T {
|
||||
function findDuplicatedElement<T>(a: ReadonlyArray<T>, equal: (a: T, b: T) => boolean): T | undefined {
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
for (let j = i + 1; j < a.length; j++) {
|
||||
if (equal(a[i], a[j])) {
|
||||
@@ -3889,7 +3889,7 @@ namespace FourSlashInterface {
|
||||
return this.state.getMarkerNames();
|
||||
}
|
||||
|
||||
public marker(name?: string): FourSlash.Marker {
|
||||
public marker(name: string): FourSlash.Marker {
|
||||
return this.state.getMarkerByName(name);
|
||||
}
|
||||
|
||||
@@ -3936,7 +3936,7 @@ namespace FourSlashInterface {
|
||||
public eachMarker(action: (marker: FourSlash.Marker, index: number) => void): void;
|
||||
public eachMarker(a: ReadonlyArray<string> | ((marker: FourSlash.Marker, index: number) => void), b?: (marker: FourSlash.Marker, index: number) => void): void {
|
||||
const markers = typeof a === "function" ? this.state.getMarkers() : a.map(m => this.state.getMarkerByName(m));
|
||||
this.state.goToEachMarker(markers, typeof a === "function" ? a : b);
|
||||
this.state.goToEachMarker(markers, typeof a === "function" ? a : b!);
|
||||
}
|
||||
|
||||
|
||||
@@ -4146,7 +4146,7 @@ namespace FourSlashInterface {
|
||||
this.state.verifyQuickInfoString(expectedText, expectedDocumentation);
|
||||
}
|
||||
|
||||
public quickInfoAt(markerName: string, expectedText?: string, expectedDocumentation?: string) {
|
||||
public quickInfoAt(markerName: string, expectedText: string, expectedDocumentation?: string) {
|
||||
this.state.verifyQuickInfoAt(markerName, expectedText, expectedDocumentation);
|
||||
}
|
||||
|
||||
@@ -4765,7 +4765,7 @@ namespace FourSlashInterface {
|
||||
readonly exact?: ArrayOrSingle<ExpectedCompletionEntry>;
|
||||
readonly includes?: ArrayOrSingle<ExpectedCompletionEntry>;
|
||||
readonly excludes?: ArrayOrSingle<string | { readonly name: string, readonly source: string }>;
|
||||
readonly preferences: ts.UserPreferences;
|
||||
readonly preferences?: ts.UserPreferences;
|
||||
readonly triggerCharacter?: ts.CompletionsTriggerCharacter;
|
||||
}
|
||||
|
||||
|
||||
+53
-54
@@ -148,7 +148,7 @@ namespace Utils {
|
||||
path = "tests/" + path;
|
||||
}
|
||||
|
||||
let content: string;
|
||||
let content: string | undefined;
|
||||
try {
|
||||
content = Harness.IO.readFile(Harness.userSpecifiedRoot + path);
|
||||
}
|
||||
@@ -177,7 +177,7 @@ namespace Utils {
|
||||
|
||||
export const canonicalizeForHarness = ts.createGetCanonicalFileName(/*caseSensitive*/ false); // This is done so tests work on windows _and_ linux
|
||||
|
||||
export function assertInvariants(node: ts.Node, parent: ts.Node): void {
|
||||
export function assertInvariants(node: ts.Node | undefined, parent: ts.Node | undefined): void {
|
||||
if (node) {
|
||||
assert.isFalse(node.pos < 0, "node.pos < 0");
|
||||
assert.isFalse(node.end < 0, "node.end < 0");
|
||||
@@ -504,11 +504,11 @@ namespace Harness {
|
||||
newLine(): string;
|
||||
getCurrentDirectory(): string;
|
||||
useCaseSensitiveFileNames(): boolean;
|
||||
resolvePath(path: string): string;
|
||||
resolvePath(path: string): string | undefined;
|
||||
getFileSize(path: string): number;
|
||||
readFile(path: string): string | undefined;
|
||||
writeFile(path: string, contents: string): void;
|
||||
directoryName(path: string): string;
|
||||
directoryName(path: string): string | undefined;
|
||||
getDirectories(path: string): string[];
|
||||
createDirectory(path: string): void;
|
||||
fileExists(fileName: string): boolean;
|
||||
@@ -525,7 +525,7 @@ namespace Harness {
|
||||
getAccessibleFileSystemEntries(dirname: string): ts.FileSystemEntries;
|
||||
tryEnableSourceMapsForHost?(): void;
|
||||
getEnvironmentVariable?(name: string): string;
|
||||
getMemoryUsage?(): number;
|
||||
getMemoryUsage?(): number | undefined;
|
||||
}
|
||||
|
||||
export let IO: IO;
|
||||
@@ -564,9 +564,7 @@ namespace Harness {
|
||||
return runner.enumerateTestFiles();
|
||||
}
|
||||
|
||||
function listFiles(path: string, spec: RegExp, options?: { recursive?: boolean }) {
|
||||
options = options || {};
|
||||
|
||||
function listFiles(path: string, spec: RegExp, options: { recursive?: boolean } = {}) {
|
||||
function filesInFolder(folder: string): string[] {
|
||||
let paths: string[] = [];
|
||||
|
||||
@@ -634,7 +632,7 @@ namespace Harness {
|
||||
getCurrentDirectory: () => ts.sys.getCurrentDirectory(),
|
||||
useCaseSensitiveFileNames: () => ts.sys.useCaseSensitiveFileNames,
|
||||
resolvePath: (path: string) => ts.sys.resolvePath(path),
|
||||
getFileSize: (path: string) => ts.sys.getFileSize(path),
|
||||
getFileSize: (path: string) => ts.sys.getFileSize!(path),
|
||||
readFile: path => ts.sys.readFile(path),
|
||||
writeFile: (path, content) => ts.sys.writeFile(path, content),
|
||||
directoryName,
|
||||
@@ -692,7 +690,7 @@ namespace Harness {
|
||||
}
|
||||
}
|
||||
|
||||
public static combine(left: HttpHeaders | undefined, right: HttpHeaders | undefined): HttpHeaders {
|
||||
public static combine(left: HttpHeaders | undefined, right: HttpHeaders | undefined): HttpHeaders | undefined {
|
||||
if (!left && !right) return undefined;
|
||||
const headers = new HttpHeaders();
|
||||
if (left) left.forEach((value, key) => { headers.set(key, value); });
|
||||
@@ -768,8 +766,8 @@ namespace Harness {
|
||||
public static readResponseContent(xhr: XMLHttpRequest) {
|
||||
if (typeof xhr.responseText === "string") {
|
||||
return new HttpContent({
|
||||
"Content-Type": xhr.getResponseHeader("Content-Type") || undefined,
|
||||
"Content-Length": xhr.getResponseHeader("Content-Length") || undefined
|
||||
"Content-Type": xhr.getResponseHeader("Content-Type") || undefined!, // TODO: GH#18217
|
||||
"Content-Length": xhr.getResponseHeader("Content-Length") || undefined!, // TODO: GH#18217
|
||||
}, xhr.responseText);
|
||||
}
|
||||
return undefined;
|
||||
@@ -888,7 +886,7 @@ namespace Harness {
|
||||
|
||||
function getFileSize(path: string): number {
|
||||
const response = send(HttpRequestMessage.head(new URL(path, serverRoot)));
|
||||
return HttpResponseMessage.hasSuccessStatusCode(response) ? +response.headers.get("Content-Length").toString() : 0;
|
||||
return HttpResponseMessage.hasSuccessStatusCode(response) ? +response.headers.get("Content-Length")!.toString() : 0;
|
||||
}
|
||||
|
||||
function readFile(path: string): string | undefined {
|
||||
@@ -998,7 +996,7 @@ namespace Harness {
|
||||
}
|
||||
}
|
||||
|
||||
if (Harness.IO.tryEnableSourceMapsForHost && /^development$/i.test(Harness.IO.getEnvironmentVariable("NODE_ENV"))) {
|
||||
if (Harness.IO.tryEnableSourceMapsForHost && /^development$/i.test(Harness.IO.getEnvironmentVariable!("NODE_ENV"))) {
|
||||
Harness.IO.tryEnableSourceMapsForHost();
|
||||
}
|
||||
|
||||
@@ -1030,7 +1028,7 @@ namespace Harness {
|
||||
*/
|
||||
export class WriterAggregator {
|
||||
public lines: string[] = [];
|
||||
public currentLine = <string>undefined;
|
||||
public currentLine: string = undefined!;
|
||||
|
||||
public Write(str: string) {
|
||||
// out of memory usage concerns avoid using + or += if we're going to do any manipulation of this string later
|
||||
@@ -1040,17 +1038,17 @@ namespace Harness {
|
||||
public WriteLine(str: string) {
|
||||
// out of memory usage concerns avoid using + or += if we're going to do any manipulation of this string later
|
||||
this.lines.push([(this.currentLine || ""), str].join(""));
|
||||
this.currentLine = undefined;
|
||||
this.currentLine = undefined!;
|
||||
}
|
||||
|
||||
public Close() {
|
||||
if (this.currentLine !== undefined) { this.lines.push(this.currentLine); }
|
||||
this.currentLine = undefined;
|
||||
this.currentLine = undefined!;
|
||||
}
|
||||
|
||||
public reset() {
|
||||
this.lines = [];
|
||||
this.currentLine = undefined;
|
||||
this.currentLine = undefined!;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1077,20 +1075,20 @@ namespace Harness {
|
||||
// Cache of lib files from "built/local"
|
||||
let libFileNameSourceFileMap: ts.Map<ts.SourceFile> | undefined;
|
||||
|
||||
export function getDefaultLibrarySourceFile(fileName = defaultLibFileName): ts.SourceFile {
|
||||
export function getDefaultLibrarySourceFile(fileName = defaultLibFileName): ts.SourceFile | undefined {
|
||||
if (!isDefaultLibraryFile(fileName)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (!libFileNameSourceFileMap) {
|
||||
libFileNameSourceFileMap = ts.createMapFromTemplate({
|
||||
[defaultLibFileName]: createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.es5.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest)
|
||||
[defaultLibFileName]: createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.es5.d.ts")!, /*languageVersion*/ ts.ScriptTarget.Latest)
|
||||
});
|
||||
}
|
||||
|
||||
let sourceFile = libFileNameSourceFileMap.get(fileName);
|
||||
if (!sourceFile) {
|
||||
libFileNameSourceFileMap.set(fileName, sourceFile = createSourceFileAndAssertInvariants(fileName, IO.readFile(libFolder + fileName), ts.ScriptTarget.Latest));
|
||||
libFileNameSourceFileMap.set(fileName, sourceFile = createSourceFileAndAssertInvariants(fileName, IO.readFile(libFolder + fileName)!, ts.ScriptTarget.Latest));
|
||||
}
|
||||
return sourceFile;
|
||||
}
|
||||
@@ -1206,10 +1204,10 @@ namespace Harness {
|
||||
export function compileFiles(
|
||||
inputFiles: TestFile[],
|
||||
otherFiles: TestFile[],
|
||||
harnessSettings: TestCaseParser.CompilerSettings,
|
||||
compilerOptions: ts.CompilerOptions,
|
||||
harnessSettings: TestCaseParser.CompilerSettings | undefined,
|
||||
compilerOptions: ts.CompilerOptions | undefined,
|
||||
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
|
||||
currentDirectory: string): compiler.CompilationResult {
|
||||
currentDirectory: string | undefined): compiler.CompilationResult {
|
||||
const options: ts.CompilerOptions & HarnessOptions = compilerOptions ? ts.cloneCompilerOptions(compilerOptions) : { noResolve: false };
|
||||
options.target = options.target || ts.ScriptTarget.ES3;
|
||||
options.newLine = options.newLine || ts.NewLineKind.CarriageReturnLineFeed;
|
||||
@@ -1225,7 +1223,7 @@ namespace Harness {
|
||||
setCompilerOptionsFromHarnessSetting(harnessSettings, options);
|
||||
}
|
||||
if (options.rootDirs) {
|
||||
options.rootDirs = ts.map(options.rootDirs, d => ts.getNormalizedAbsolutePath(d, currentDirectory));
|
||||
options.rootDirs = ts.map(options.rootDirs, d => ts.getNormalizedAbsolutePath(d, currentDirectory!));
|
||||
}
|
||||
|
||||
const useCaseSensitiveFileNames = options.useCaseSensitiveFileNames !== undefined ? options.useCaseSensitiveFileNames : true;
|
||||
@@ -1253,7 +1251,7 @@ namespace Harness {
|
||||
export interface DeclarationCompilationContext {
|
||||
declInputFiles: TestFile[];
|
||||
declOtherFiles: TestFile[];
|
||||
harnessSettings: TestCaseParser.CompilerSettings & HarnessOptions;
|
||||
harnessSettings: TestCaseParser.CompilerSettings & HarnessOptions | undefined;
|
||||
options: ts.CompilerOptions;
|
||||
currentDirectory: string;
|
||||
}
|
||||
@@ -1264,7 +1262,7 @@ namespace Harness {
|
||||
harnessSettings: TestCaseParser.CompilerSettings & HarnessOptions,
|
||||
options: ts.CompilerOptions,
|
||||
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
|
||||
currentDirectory: string): DeclarationCompilationContext | undefined {
|
||||
currentDirectory: string | undefined): DeclarationCompilationContext | undefined {
|
||||
|
||||
if (options.declaration && result.diagnostics.length === 0) {
|
||||
if (options.emitDeclarationOnly) {
|
||||
@@ -1300,7 +1298,7 @@ namespace Harness {
|
||||
}
|
||||
|
||||
function findResultCodeFile(fileName: string) {
|
||||
const sourceFile = result.program.getSourceFile(fileName);
|
||||
const sourceFile = result.program!.getSourceFile(fileName)!;
|
||||
assert(sourceFile, "Program has no source file with name '" + fileName + "'");
|
||||
// Is this file going to be emitted separately
|
||||
let sourceFileName: string;
|
||||
@@ -1308,7 +1306,7 @@ namespace Harness {
|
||||
if (!outFile) {
|
||||
if (options.outDir) {
|
||||
let sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, result.vfs.cwd());
|
||||
sourceFilePath = sourceFilePath.replace(result.program.getCommonSourceDirectory(), "");
|
||||
sourceFilePath = sourceFilePath.replace(result.program!.getCommonSourceDirectory(), "");
|
||||
sourceFileName = ts.combinePaths(options.outDir, sourceFilePath);
|
||||
}
|
||||
else {
|
||||
@@ -1408,7 +1406,7 @@ namespace Harness {
|
||||
// Filter down to the errors in the file
|
||||
const fileErrors = diagnostics.filter((e): e is ts.DiagnosticWithLocation => {
|
||||
const errFn = e.file;
|
||||
return errFn && utils.removeTestPathPrefixes(errFn.fileName) === utils.removeTestPathPrefixes(inputFile.unitName);
|
||||
return !!errFn && utils.removeTestPathPrefixes(errFn.fileName) === utils.removeTestPathPrefixes(inputFile.unitName);
|
||||
});
|
||||
|
||||
|
||||
@@ -1443,7 +1441,8 @@ namespace Harness {
|
||||
}
|
||||
// Emit this line from the original file
|
||||
outputLines += (newLine() + " " + line);
|
||||
fileErrors.forEach(err => {
|
||||
fileErrors.forEach(errDiagnostic => {
|
||||
const err = errDiagnostic as ts.TextSpan; // TODO: GH#18217
|
||||
// Does any error start or continue on to this line? Emit squiggles
|
||||
const end = ts.textSpanEnd(err);
|
||||
if ((end >= thisLineStart) && ((err.start < nextLineStart) || (lineIndex === lines.length - 1))) {
|
||||
@@ -1461,7 +1460,7 @@ namespace Harness {
|
||||
// Just like above, we need to do a split on a string instead of on a regex
|
||||
// because the JS engine does regexes wrong
|
||||
|
||||
outputErrorText(err);
|
||||
outputErrorText(errDiagnostic);
|
||||
markedErrorCount++;
|
||||
}
|
||||
}
|
||||
@@ -1476,12 +1475,12 @@ namespace Harness {
|
||||
}
|
||||
|
||||
const numLibraryDiagnostics = ts.countWhere(diagnostics, diagnostic => {
|
||||
return diagnostic.file && (isDefaultLibraryFile(diagnostic.file.fileName) || isBuiltFile(diagnostic.file.fileName));
|
||||
return !!diagnostic.file && (isDefaultLibraryFile(diagnostic.file.fileName) || isBuiltFile(diagnostic.file.fileName));
|
||||
});
|
||||
|
||||
const numTest262HarnessDiagnostics = ts.countWhere(diagnostics, diagnostic => {
|
||||
// Count an error generated from tests262-harness folder.This should only apply for test262
|
||||
return diagnostic.file && diagnostic.file.fileName.indexOf("test262-harness") >= 0;
|
||||
return !!diagnostic.file && diagnostic.file.fileName.indexOf("test262-harness") >= 0;
|
||||
});
|
||||
|
||||
// Verify we didn't miss any errors in total
|
||||
@@ -1489,7 +1488,7 @@ namespace Harness {
|
||||
}
|
||||
|
||||
export function doErrorBaseline(baselinePath: string, inputFiles: ReadonlyArray<TestFile>, errors: ReadonlyArray<ts.Diagnostic>, pretty?: boolean) {
|
||||
Baseline.runBaseline(baselinePath.replace(/\.tsx?$/, ".errors.txt"), (): string => {
|
||||
Baseline.runBaseline(baselinePath.replace(/\.tsx?$/, ".errors.txt"), (): string | null => {
|
||||
if (!errors || (errors.length === 0)) {
|
||||
/* tslint:disable:no-null-keyword */
|
||||
return null;
|
||||
@@ -1519,7 +1518,7 @@ namespace Harness {
|
||||
|
||||
// Produce baselines. The first gives the types for all expressions.
|
||||
// The second gives symbols for all identifiers.
|
||||
let typesError: Error, symbolsError: Error;
|
||||
let typesError: Error | undefined, symbolsError: Error | undefined;
|
||||
try {
|
||||
checkBaseLines(/*isSymbolBaseLine*/ false);
|
||||
}
|
||||
@@ -1567,7 +1566,7 @@ namespace Harness {
|
||||
}
|
||||
}
|
||||
|
||||
function generateBaseLine(isSymbolBaseline: boolean, skipBaseline?: boolean): string {
|
||||
function generateBaseLine(isSymbolBaseline: boolean, skipBaseline?: boolean): string | null {
|
||||
let result = "";
|
||||
const gen = iterateBaseLine(isSymbolBaseline, skipBaseline);
|
||||
for (let {done, value} = gen.next(); !done; { done, value } = gen.next()) {
|
||||
@@ -1754,7 +1753,7 @@ namespace Harness {
|
||||
resultName = sanitizeTestFilePath(resultName);
|
||||
if (dupeCase.has(resultName)) {
|
||||
// A different baseline filename should be manufactured if the names differ only in case, for windows compat
|
||||
const count = 1 + dupeCase.get(resultName);
|
||||
const count = 1 + dupeCase.get(resultName)!;
|
||||
dupeCase.set(resultName, count);
|
||||
resultName = `${resultName}.dupe${count}`;
|
||||
}
|
||||
@@ -1862,7 +1861,7 @@ namespace Harness {
|
||||
export function extractCompilerSettings(content: string): CompilerSettings {
|
||||
const opts: CompilerSettings = {};
|
||||
|
||||
let match: RegExpExecArray;
|
||||
let match: RegExpExecArray | null;
|
||||
/* tslint:disable:no-null-keyword */
|
||||
while ((match = optionRegex.exec(content)) !== null) {
|
||||
/* tslint:enable:no-null-keyword */
|
||||
@@ -1875,8 +1874,8 @@ namespace Harness {
|
||||
export interface TestCaseContent {
|
||||
settings: CompilerSettings;
|
||||
testUnitData: TestUnitData[];
|
||||
tsConfig: ts.ParsedCommandLine;
|
||||
tsConfigFileUnitData: TestUnitData;
|
||||
tsConfig: ts.ParsedCommandLine | undefined;
|
||||
tsConfigFileUnitData: TestUnitData | undefined;
|
||||
}
|
||||
|
||||
/** Given a test file containing // @FileName directives, return an array of named units of code to be added to an existing compiler instance */
|
||||
@@ -1887,7 +1886,7 @@ namespace Harness {
|
||||
const lines = Utils.splitContentByNewlines(code);
|
||||
|
||||
// Stuff related to the subfile we're parsing
|
||||
let currentFileContent: string;
|
||||
let currentFileContent: string | undefined;
|
||||
let currentFileOptions: any = {};
|
||||
let currentFileName: any;
|
||||
let refs: string[] = [];
|
||||
@@ -1907,7 +1906,7 @@ namespace Harness {
|
||||
if (currentFileName) {
|
||||
// Store result file
|
||||
const newTestFile = {
|
||||
content: currentFileContent,
|
||||
content: currentFileContent!, // TODO: GH#18217
|
||||
name: currentFileName,
|
||||
fileOptions: currentFileOptions,
|
||||
originalFilePath: fileName,
|
||||
@@ -1962,8 +1961,8 @@ namespace Harness {
|
||||
};
|
||||
|
||||
// check if project has tsconfig.json in the list of files
|
||||
let tsConfig: ts.ParsedCommandLine;
|
||||
let tsConfigFileUnitData: TestUnitData;
|
||||
let tsConfig: ts.ParsedCommandLine | undefined;
|
||||
let tsConfigFileUnitData: TestUnitData | undefined;
|
||||
for (let i = 0; i < testUnitData.length; i++) {
|
||||
const data = testUnitData[i];
|
||||
if (getConfigNameFromFileName(data.name)) {
|
||||
@@ -2024,7 +2023,7 @@ namespace Harness {
|
||||
}
|
||||
|
||||
const fileCache: { [idx: string]: boolean } = {};
|
||||
function generateActual(generateContent: () => string): string {
|
||||
function generateActual(generateContent: () => string | null): string | null {
|
||||
|
||||
const actual = generateContent();
|
||||
|
||||
@@ -2035,12 +2034,12 @@ namespace Harness {
|
||||
return actual;
|
||||
}
|
||||
|
||||
function compareToBaseline(actual: string, relativeFileName: string, opts: BaselineOptions) {
|
||||
function compareToBaseline(actual: string | null, relativeFileName: string, opts: BaselineOptions | undefined) {
|
||||
// actual is now either undefined (the generator had an error), null (no file requested),
|
||||
// or some real output of the function
|
||||
if (actual === undefined) {
|
||||
// Nothing to do
|
||||
return;
|
||||
return undefined!; // TODO: GH#18217
|
||||
}
|
||||
|
||||
const refFileName = referencePath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder);
|
||||
@@ -2053,7 +2052,7 @@ namespace Harness {
|
||||
|
||||
let expected = "<no content>";
|
||||
if (IO.fileExists(refFileName)) {
|
||||
expected = IO.readFile(refFileName);
|
||||
expected = IO.readFile(refFileName)!; // TODO: GH#18217
|
||||
}
|
||||
|
||||
return { expected, actual };
|
||||
@@ -2069,7 +2068,7 @@ namespace Harness {
|
||||
return;
|
||||
}
|
||||
|
||||
const parentDirectory = IO.directoryName(dirName);
|
||||
const parentDirectory = IO.directoryName(dirName)!; // TODO: GH#18217
|
||||
if (parentDirectory !== "" && parentDirectory !== dirName) {
|
||||
createDirectoryStructure(parentDirectory);
|
||||
}
|
||||
@@ -2078,7 +2077,7 @@ namespace Harness {
|
||||
}
|
||||
|
||||
// Create folders if needed
|
||||
createDirectoryStructure(IO.directoryName(actualFileName));
|
||||
createDirectoryStructure(IO.directoryName(actualFileName)!); // TODO: GH#18217
|
||||
|
||||
// Delete the actual file in case it fails
|
||||
if (IO.fileExists(actualFileName)) {
|
||||
@@ -2097,14 +2096,14 @@ namespace Harness {
|
||||
}
|
||||
}
|
||||
|
||||
export function runBaseline(relativeFileName: string, generateContent: () => string, opts?: BaselineOptions): void {
|
||||
export function runBaseline(relativeFileName: string, generateContent: () => string | null, opts?: BaselineOptions): void {
|
||||
const actualFileName = localPath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder);
|
||||
const actual = generateActual(generateContent);
|
||||
const comparison = compareToBaseline(actual, relativeFileName, opts);
|
||||
writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName);
|
||||
}
|
||||
|
||||
export function runMultifileBaseline(relativeFileBase: string, extension: string, generateContent: () => IterableIterator<[string, string, number]> | IterableIterator<[string, string]>, opts?: BaselineOptions, referencedExtensions?: string[]): void {
|
||||
export function runMultifileBaseline(relativeFileBase: string, extension: string, generateContent: () => IterableIterator<[string, string, number]> | IterableIterator<[string, string]> | null, opts?: BaselineOptions, referencedExtensions?: string[]): void {
|
||||
const gen = generateContent();
|
||||
const writtenFiles = ts.createMap<true>();
|
||||
const errors: Error[] = [];
|
||||
@@ -2175,7 +2174,7 @@ namespace Harness {
|
||||
|
||||
export function getDefaultLibraryFile(filePath: string, io: IO): Compiler.TestFile {
|
||||
const libFile = userSpecifiedRoot + libFolder + ts.getBaseFileName(ts.normalizeSlashes(filePath));
|
||||
return { unitName: libFile, content: io.readFile(libFile) };
|
||||
return { unitName: libFile, content: io.readFile(libFile)! };
|
||||
}
|
||||
|
||||
export function getConfigNameFromFileName(filename: string): "tsconfig.json" | "jsconfig.json" | undefined {
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Harness.LanguageService {
|
||||
export class ScriptInfo {
|
||||
public version = 1;
|
||||
public editRanges: { length: number; textChangeRange: ts.TextChangeRange; }[] = [];
|
||||
private lineMap: number[] = undefined;
|
||||
private lineMap: number[] | undefined;
|
||||
|
||||
constructor(public fileName: string, public content: string, public isRootFile: boolean) {
|
||||
this.setContent(content);
|
||||
@@ -95,7 +95,7 @@ namespace Harness.LanguageService {
|
||||
return this.scriptSnapshot.getLength();
|
||||
}
|
||||
|
||||
public getChangeRange(oldScript: ts.ScriptSnapshotShim): string {
|
||||
public getChangeRange(oldScript: ts.ScriptSnapshotShim): string | undefined {
|
||||
const range = this.scriptSnapshot.getChangeRange((oldScript as ScriptSnapshotProxy).scriptSnapshot);
|
||||
return range && JSON.stringify(range);
|
||||
}
|
||||
@@ -146,7 +146,7 @@ namespace Harness.LanguageService {
|
||||
return fileNames;
|
||||
}
|
||||
|
||||
public getScriptInfo(fileName: string): ScriptInfo {
|
||||
public getScriptInfo(fileName: string): ScriptInfo | undefined {
|
||||
return this.scriptInfos.get(vpath.resolve(this.vfs.cwd(), fileName));
|
||||
}
|
||||
|
||||
@@ -175,9 +175,8 @@ namespace Harness.LanguageService {
|
||||
* @param col 0 based index
|
||||
*/
|
||||
public positionToLineAndCharacter(fileName: string, position: number): ts.LineAndCharacter {
|
||||
const script: ScriptInfo = this.getScriptInfo(fileName);
|
||||
const script: ScriptInfo = this.getScriptInfo(fileName)!;
|
||||
assert.isOk(script);
|
||||
|
||||
return ts.computeLineAndCharacterOfPosition(script.getLineMap(), position);
|
||||
}
|
||||
}
|
||||
@@ -185,7 +184,7 @@ namespace Harness.LanguageService {
|
||||
/// Native adapter
|
||||
class NativeLanguageServiceHost extends LanguageServiceAdapterHost implements ts.LanguageServiceHost, LanguageServiceAdapterHost {
|
||||
isKnownTypesPackageName(name: string): boolean {
|
||||
return this.typesRegistry && this.typesRegistry.has(name);
|
||||
return !!this.typesRegistry && this.typesRegistry.has(name);
|
||||
}
|
||||
|
||||
installPackage = ts.notImplemented;
|
||||
@@ -206,7 +205,7 @@ namespace Harness.LanguageService {
|
||||
return this.getFilenames().filter(ts.isAnySupportedFileExtension);
|
||||
}
|
||||
|
||||
getScriptSnapshot(fileName: string): ts.IScriptSnapshot {
|
||||
getScriptSnapshot(fileName: string): ts.IScriptSnapshot | undefined {
|
||||
const script = this.getScriptInfo(fileName);
|
||||
return script ? new ScriptSnapshot(script) : undefined;
|
||||
}
|
||||
@@ -215,7 +214,7 @@ namespace Harness.LanguageService {
|
||||
|
||||
getScriptVersion(fileName: string): string {
|
||||
const script = this.getScriptInfo(fileName);
|
||||
return script ? script.version.toString() : undefined;
|
||||
return script ? script.version.toString() : undefined!; // TODO: GH#18217
|
||||
}
|
||||
|
||||
directoryExists(dirName: string): boolean {
|
||||
@@ -280,7 +279,7 @@ namespace Harness.LanguageService {
|
||||
}
|
||||
};
|
||||
this.getModuleResolutionsForFile = (fileName) => {
|
||||
const scriptInfo = this.getScriptInfo(fileName);
|
||||
const scriptInfo = this.getScriptInfo(fileName)!;
|
||||
const preprocessInfo = ts.preProcessFile(scriptInfo.content, /*readImportFiles*/ true);
|
||||
const imports: ts.MapLike<string> = {};
|
||||
for (const module of preprocessInfo.importedFiles) {
|
||||
@@ -299,8 +298,8 @@ namespace Harness.LanguageService {
|
||||
const settings = this.nativeHost.getCompilationSettings();
|
||||
for (const typeReferenceDirective of preprocessInfo.typeReferenceDirectives) {
|
||||
const resolutionInfo = ts.resolveTypeReferenceDirective(typeReferenceDirective.fileName, fileName, settings, moduleResolutionHost);
|
||||
if (resolutionInfo.resolvedTypeReferenceDirective.resolvedFileName) {
|
||||
resolutions[typeReferenceDirective.fileName] = resolutionInfo.resolvedTypeReferenceDirective;
|
||||
if (resolutionInfo.resolvedTypeReferenceDirective!.resolvedFileName) {
|
||||
resolutions[typeReferenceDirective.fileName] = resolutionInfo.resolvedTypeReferenceDirective!;
|
||||
}
|
||||
}
|
||||
return JSON.stringify(resolutions);
|
||||
@@ -313,7 +312,7 @@ namespace Harness.LanguageService {
|
||||
}
|
||||
|
||||
getFilenames(): string[] { return this.nativeHost.getFilenames(); }
|
||||
getScriptInfo(fileName: string): ScriptInfo { return this.nativeHost.getScriptInfo(fileName); }
|
||||
getScriptInfo(fileName: string): ScriptInfo | undefined { return this.nativeHost.getScriptInfo(fileName); }
|
||||
addScript(fileName: string, content: string, isRootFile: boolean): void { this.nativeHost.addScript(fileName, content, isRootFile); }
|
||||
editScript(fileName: string, start: number, end: number, newText: string): void { this.nativeHost.editScript(fileName, start, end, newText); }
|
||||
positionToLineAndCharacter(fileName: string, position: number): ts.LineAndCharacter { return this.nativeHost.positionToLineAndCharacter(fileName, position); }
|
||||
@@ -325,7 +324,7 @@ namespace Harness.LanguageService {
|
||||
getDefaultLibFileName(): string { return this.nativeHost.getDefaultLibFileName(); }
|
||||
getScriptFileNames(): string { return JSON.stringify(this.nativeHost.getScriptFileNames()); }
|
||||
getScriptSnapshot(fileName: string): ts.ScriptSnapshotShim {
|
||||
const nativeScriptSnapshot = this.nativeHost.getScriptSnapshot(fileName);
|
||||
const nativeScriptSnapshot = this.nativeHost.getScriptSnapshot(fileName)!; // TODO: GH#18217
|
||||
return nativeScriptSnapshot && new ScriptSnapshotProxy(nativeScriptSnapshot);
|
||||
}
|
||||
getScriptKind(): ts.ScriptKind { return this.nativeHost.getScriptKind(); }
|
||||
@@ -504,7 +503,7 @@ namespace Harness.LanguageService {
|
||||
getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: ts.FormatCodeOptions): ts.TextChange[] {
|
||||
return unwrapJSONCallResult(this.shim.getFormattingEditsAfterKeystroke(fileName, position, key, JSON.stringify(options)));
|
||||
}
|
||||
getDocCommentTemplateAtPosition(fileName: string, position: number): ts.TextInsertion | undefined {
|
||||
getDocCommentTemplateAtPosition(fileName: string, position: number): ts.TextInsertion {
|
||||
return unwrapJSONCallResult(this.shim.getDocCommentTemplateAtPosition(fileName, position));
|
||||
}
|
||||
isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean {
|
||||
@@ -608,7 +607,7 @@ namespace Harness.LanguageService {
|
||||
class SessionClientHost extends NativeLanguageServiceHost implements ts.server.SessionClientHost {
|
||||
private client: ts.server.SessionClient;
|
||||
|
||||
constructor(cancellationToken: ts.HostCancellationToken, settings: ts.CompilerOptions) {
|
||||
constructor(cancellationToken: ts.HostCancellationToken | undefined, settings: ts.CompilerOptions | undefined) {
|
||||
super(cancellationToken, settings);
|
||||
}
|
||||
|
||||
@@ -715,7 +714,7 @@ namespace Harness.LanguageService {
|
||||
return true;
|
||||
}
|
||||
|
||||
getLogFileName(): string {
|
||||
getLogFileName(): string | undefined {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -850,7 +849,7 @@ namespace Harness.LanguageService {
|
||||
cancellationToken: ts.server.nullCancellationToken,
|
||||
useSingleInferredProject: false,
|
||||
useInferredProjectPerProjectRoot: false,
|
||||
typingsInstaller: undefined,
|
||||
typingsInstaller: undefined!, // TODO: GH#18217
|
||||
byteLength: Utils.byteLength,
|
||||
hrtime: process.hrtime,
|
||||
logger: serverHost,
|
||||
|
||||
+38
-35
@@ -68,10 +68,10 @@ interface IoLog {
|
||||
}[];
|
||||
directoriesRead: {
|
||||
path: string,
|
||||
extensions: ReadonlyArray<string>,
|
||||
exclude: ReadonlyArray<string>,
|
||||
include: ReadonlyArray<string>,
|
||||
depth: number,
|
||||
extensions: ReadonlyArray<string> | undefined,
|
||||
exclude: ReadonlyArray<string> | undefined,
|
||||
include: ReadonlyArray<string> | undefined,
|
||||
depth: number | undefined,
|
||||
result: ReadonlyArray<string>,
|
||||
}[];
|
||||
useCaseSensitiveFileNames?: boolean;
|
||||
@@ -87,8 +87,8 @@ interface PlaybackControl {
|
||||
}
|
||||
|
||||
namespace Playback {
|
||||
let recordLog: IoLog;
|
||||
let replayLog: IoLog;
|
||||
let recordLog: IoLog | undefined;
|
||||
let replayLog: IoLog | undefined;
|
||||
let replayFilesRead: ts.Map<IoLogFile> | undefined;
|
||||
let recordLogFileNameBase = "";
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace Playback {
|
||||
return lookup[s] = func(s);
|
||||
});
|
||||
run.reset = () => {
|
||||
lookup = undefined;
|
||||
lookup = undefined!; // TODO: GH#18217
|
||||
};
|
||||
|
||||
return run;
|
||||
@@ -148,11 +148,12 @@ namespace Playback {
|
||||
}
|
||||
}
|
||||
for (const file of log.filesRead) {
|
||||
if (file.result.contentsPath) {
|
||||
const result = file.result!; // TODO: GH#18217
|
||||
if (result.contentsPath) {
|
||||
// `readFile` strips away a BOM (and actually reinerprets the file contents according to the correct encoding)
|
||||
// - but this has the unfortunate sideeffect of removing the BOM from any outputs based on the file, so we readd it here.
|
||||
file.result.contents = (file.result.bom || "") + host.readFile(ts.combinePaths(baseName, file.result.contentsPath));
|
||||
delete file.result.contentsPath;
|
||||
result.contents = (result.bom || "") + host.readFile(ts.combinePaths(baseName, result.contentsPath));
|
||||
delete result.contentsPath;
|
||||
}
|
||||
}
|
||||
return log;
|
||||
@@ -188,21 +189,22 @@ namespace Playback {
|
||||
}
|
||||
if (log.filesRead) {
|
||||
for (const file of log.filesRead) {
|
||||
const { contents } = file.result;
|
||||
const result = file.result!; // TODO: GH#18217
|
||||
const { contents } = result;
|
||||
if (contents !== undefined) {
|
||||
file.result.contentsPath = ts.combinePaths("read", sanitizeTestFilePath(file.path));
|
||||
writeFile(ts.combinePaths(baseTestName, file.result.contentsPath), contents);
|
||||
result.contentsPath = ts.combinePaths("read", sanitizeTestFilePath(file.path));
|
||||
writeFile(ts.combinePaths(baseTestName, result.contentsPath), contents);
|
||||
const len = contents.length;
|
||||
if (len >= 2 && contents.charCodeAt(0) === 0xfeff) {
|
||||
file.result.bom = "\ufeff";
|
||||
result.bom = "\ufeff";
|
||||
}
|
||||
if (len >= 2 && contents.charCodeAt(0) === 0xfffe) {
|
||||
file.result.bom = "\ufffe";
|
||||
result.bom = "\ufffe";
|
||||
}
|
||||
if (len >= 3 && contents.charCodeAt(0) === 0xefbb && contents.charCodeAt(1) === 0xbf) {
|
||||
file.result.bom = "\uefbb\xbf";
|
||||
result.bom = "\uefbb\xbf";
|
||||
}
|
||||
delete file.result.contents;
|
||||
delete result.contents;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -222,7 +224,7 @@ namespace Playback {
|
||||
wrapper.startReplayFromData = log => {
|
||||
replayLog = log;
|
||||
// Remove non-found files from the log (shouldn't really need them, but we still record them for diagnostic purposes)
|
||||
replayLog.filesRead = replayLog.filesRead.filter(f => f.result.contents !== undefined);
|
||||
replayLog.filesRead = replayLog.filesRead.filter(f => f.result!.contents !== undefined);
|
||||
replayFilesRead = ts.createMap();
|
||||
for (const file of replayLog.filesRead) {
|
||||
replayFilesRead.set(ts.normalizeSlashes(file.path).toLowerCase(), file);
|
||||
@@ -244,7 +246,7 @@ namespace Playback {
|
||||
};
|
||||
|
||||
wrapper.startReplayFromFile = logFn => {
|
||||
wrapper.startReplayFromString(underlying.readFile(logFn));
|
||||
wrapper.startReplayFromString(underlying.readFile(logFn)!);
|
||||
};
|
||||
wrapper.endRecord = () => {
|
||||
if (recordLog !== undefined) {
|
||||
@@ -267,24 +269,25 @@ namespace Playback {
|
||||
}
|
||||
const files = [];
|
||||
for (const file of newLog.filesRead) {
|
||||
if (file.result.contentsPath &&
|
||||
Harness.isDefaultLibraryFile(file.result.contentsPath) &&
|
||||
/\.[tj]s$/.test(file.result.contentsPath)) {
|
||||
files.push(file.result.contentsPath);
|
||||
const result = file.result!;
|
||||
if (result.contentsPath &&
|
||||
Harness.isDefaultLibraryFile(result.contentsPath) &&
|
||||
/\.[tj]s$/.test(result.contentsPath)) {
|
||||
files.push(result.contentsPath);
|
||||
}
|
||||
}
|
||||
return { compilerOptions: ts.parseCommandLine(newLog.arguments).options, files };
|
||||
}
|
||||
|
||||
wrapper.fileExists = recordReplay(wrapper.fileExists, underlying)(
|
||||
path => callAndRecord(underlying.fileExists(path), recordLog.fileExists, { path }),
|
||||
path => callAndRecord(underlying.fileExists(path), recordLog!.fileExists, { path }),
|
||||
memoize(path => {
|
||||
// If we read from the file, it must exist
|
||||
if (findFileByPath(path, /*throwFileNotFoundError*/ false)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return findResultByFields(replayLog.fileExists, { path }, /*defaultValue*/ false);
|
||||
return findResultByFields(replayLog!.fileExists, { path }, /*defaultValue*/ false)!;
|
||||
}
|
||||
})
|
||||
);
|
||||
@@ -314,22 +317,22 @@ namespace Playback {
|
||||
};
|
||||
|
||||
wrapper.resolvePath = recordReplay(wrapper.resolvePath, underlying)(
|
||||
path => callAndRecord(underlying.resolvePath(path), recordLog.pathsResolved, { path }),
|
||||
memoize(path => findResultByFields(replayLog.pathsResolved, { path }, !ts.isRootedDiskPath(ts.normalizeSlashes(path)) && replayLog.currentDirectory ? replayLog.currentDirectory + "/" + path : ts.normalizeSlashes(path))));
|
||||
path => callAndRecord(underlying.resolvePath(path), recordLog!.pathsResolved, { path }),
|
||||
memoize(path => findResultByFields(replayLog!.pathsResolved, { path }, !ts.isRootedDiskPath(ts.normalizeSlashes(path)) && replayLog!.currentDirectory ? replayLog!.currentDirectory + "/" + path : ts.normalizeSlashes(path))));
|
||||
|
||||
wrapper.readFile = recordReplay(wrapper.readFile, underlying)(
|
||||
(path: string) => {
|
||||
const result = underlying.readFile(path);
|
||||
const logEntry = { path, codepage: 0, result: { contents: result, codepage: 0 } };
|
||||
recordLog.filesRead.push(logEntry);
|
||||
recordLog!.filesRead.push(logEntry);
|
||||
return result;
|
||||
},
|
||||
memoize(path => findFileByPath(path, /*throwFileNotFoundError*/ true).contents));
|
||||
memoize(path => findFileByPath(path, /*throwFileNotFoundError*/ true)!.contents));
|
||||
|
||||
wrapper.readDirectory = recordReplay(wrapper.readDirectory, underlying)(
|
||||
(path, extensions, exclude, include, depth) => {
|
||||
const result = (<ts.System>underlying).readDirectory(path, extensions, exclude, include, depth);
|
||||
recordLog.directoriesRead.push({ path, extensions, exclude, include, depth, result });
|
||||
recordLog!.directoriesRead.push({ path, extensions, exclude, include, depth, result });
|
||||
return result;
|
||||
},
|
||||
path => {
|
||||
@@ -338,7 +341,7 @@ namespace Playback {
|
||||
// different entry).
|
||||
// TODO (yuisu): We can certainly remove these once we recapture the RWC using new API
|
||||
const normalizedPath = ts.normalizePath(path).toLowerCase();
|
||||
return ts.flatMap(replayLog.directoriesRead, directory => {
|
||||
return ts.flatMap(replayLog!.directoriesRead, directory => {
|
||||
if (ts.normalizeSlashes(directory.path).toLowerCase() === normalizedPath) {
|
||||
return directory.result;
|
||||
}
|
||||
@@ -346,7 +349,7 @@ namespace Playback {
|
||||
});
|
||||
|
||||
wrapper.writeFile = recordReplay(wrapper.writeFile, underlying)(
|
||||
(path: string, contents: string) => callAndRecord(underlying.writeFile(path, contents), recordLog.filesWritten, { path, contents, bom: false }),
|
||||
(path: string, contents: string) => callAndRecord(underlying.writeFile(path, contents), recordLog!.filesWritten, { path, contents, bom: false }),
|
||||
() => noOpReplay("writeFile"));
|
||||
|
||||
wrapper.exit = (exitCode) => {
|
||||
@@ -390,7 +393,7 @@ namespace Playback {
|
||||
return underlyingResult;
|
||||
}
|
||||
|
||||
function findResultByFields<T>(logArray: { result?: T }[], expectedFields: {}, defaultValue?: T): T {
|
||||
function findResultByFields<T>(logArray: { result?: T }[], expectedFields: {}, defaultValue?: T): T | undefined {
|
||||
const predicate = (entry: { result?: T }) => {
|
||||
return Object.getOwnPropertyNames(expectedFields).every((name) => (<any>entry)[name] === (<any>expectedFields)[name]);
|
||||
};
|
||||
@@ -406,10 +409,10 @@ namespace Playback {
|
||||
return results[0].result;
|
||||
}
|
||||
|
||||
function findFileByPath(expectedPath: string, throwFileNotFoundError: boolean): FileInformation {
|
||||
function findFileByPath(expectedPath: string, throwFileNotFoundError: boolean): FileInformation | undefined {
|
||||
const normalizedName = ts.normalizePath(expectedPath).toLowerCase();
|
||||
// Try to find the result through normal fileName
|
||||
const result = replayFilesRead.get(normalizedName);
|
||||
const result = replayFilesRead!.get(normalizedName);
|
||||
if (result) {
|
||||
return result.result;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// tslint:disable no-unnecessary-type-assertion (TODO: tslint can't find node types)
|
||||
|
||||
if (typeof describe === "undefined") {
|
||||
(global as any).describe = undefined; // If launched without mocha for parallel mode, we still need a global describe visible to satisfy the parsing of the unit tests
|
||||
(global as any).it = undefined;
|
||||
@@ -32,7 +34,7 @@ namespace Harness.Parallel.Host {
|
||||
function perfdataFileName(target?: string) {
|
||||
return `${perfdataFileNameFragment}${target ? `.${target}` : ""}.json`;
|
||||
}
|
||||
function readSavedPerfData(target?: string): {[testHash: string]: number} {
|
||||
function readSavedPerfData(target?: string): {[testHash: string]: number} | undefined {
|
||||
const perfDataContents = IO.readFile(perfdataFileName(target));
|
||||
if (perfDataContents) {
|
||||
return JSON.parse(perfDataContents);
|
||||
@@ -73,7 +75,7 @@ namespace Harness.Parallel.Host {
|
||||
setTimeout(() => startDelayed(perfData, totalCost), 0); // Do real startup on next tick, so all unit tests have been collected
|
||||
}
|
||||
|
||||
function startDelayed(perfData: {[testHash: string]: number}, totalCost: number) {
|
||||
function startDelayed(perfData: {[testHash: string]: number} | undefined, totalCost: number) {
|
||||
initializeProgressBarsDependencies();
|
||||
console.log(`Discovered ${tasks.length} unittest suites` + (newTasks.length ? ` and ${newTasks.length} new suites.` : "."));
|
||||
console.log("Discovering runner-based tests...");
|
||||
@@ -227,16 +229,16 @@ namespace Harness.Parallel.Host {
|
||||
return;
|
||||
}
|
||||
// Send tasks in blocks if the tasks are small
|
||||
const taskList = [tasks.pop()];
|
||||
const taskList = [tasks.pop()!];
|
||||
while (tasks.length && taskList.reduce((p, c) => p + c.size, 0) < chunkSize) {
|
||||
taskList.push(tasks.pop());
|
||||
taskList.push(tasks.pop()!);
|
||||
}
|
||||
child.currentTasks = taskList;
|
||||
if (taskList.length === 1) {
|
||||
child.send({ type: "test", payload: taskList[0] });
|
||||
child.send({ type: "test", payload: taskList[0] } as ParallelHostMessage); // TODO: GH#18217
|
||||
}
|
||||
else {
|
||||
child.send({ type: "batch", payload: taskList });
|
||||
child.send({ type: "batch", payload: taskList } as ParallelHostMessage); // TODO: GH#18217
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -268,7 +270,7 @@ namespace Harness.Parallel.Host {
|
||||
doneBatching[i] = true;
|
||||
continue;
|
||||
}
|
||||
const task = tasks.pop();
|
||||
const task = tasks.pop()!;
|
||||
batches[i].push(task);
|
||||
scheduledTotal += task.size;
|
||||
}
|
||||
@@ -293,7 +295,7 @@ namespace Harness.Parallel.Host {
|
||||
worker.send({ type: "batch", payload });
|
||||
}
|
||||
else { // Out of batches, send off just one test
|
||||
const payload = tasks.pop();
|
||||
const payload = tasks.pop()!;
|
||||
ts.Debug.assert(!!payload); // The reserve kept above should ensure there is always an initial task available, even in suboptimal scenarios
|
||||
worker.currentTasks = [payload];
|
||||
worker.send({ type: "test", payload });
|
||||
@@ -302,7 +304,7 @@ namespace Harness.Parallel.Host {
|
||||
}
|
||||
else {
|
||||
for (let i = 0; i < workerCount; i++) {
|
||||
const task = tasks.pop();
|
||||
const task = tasks.pop()!;
|
||||
workers[i].currentTasks = [task];
|
||||
workers[i].send({ type: "test", payload: task });
|
||||
}
|
||||
@@ -519,7 +521,7 @@ namespace Harness.Parallel.Host {
|
||||
this._enabled = false;
|
||||
}
|
||||
}
|
||||
update(index: number, percentComplete: number, color: string, title: string, titleColor?: string) {
|
||||
update(index: number, percentComplete: number, color: string, title: string | undefined, titleColor?: string) {
|
||||
percentComplete = minMax(percentComplete, 0, 1);
|
||||
|
||||
const progressBar = this._progressBars[index] || (this._progressBars[index] = { });
|
||||
@@ -555,7 +557,7 @@ namespace Harness.Parallel.Host {
|
||||
}
|
||||
|
||||
cursor.hide();
|
||||
readline.moveCursor(process.stdout, -process.stdout.columns, -this._lineCount);
|
||||
readline.moveCursor(process.stdout, -process.stdout.columns!, -this._lineCount);
|
||||
let lineCount = 0;
|
||||
const numProgressBars = this._progressBars.length;
|
||||
for (let i = 0; i < numProgressBars; i++) {
|
||||
@@ -564,7 +566,7 @@ namespace Harness.Parallel.Host {
|
||||
process.stdout.write(this._progressBars[i].text + os.EOL);
|
||||
}
|
||||
else {
|
||||
readline.moveCursor(process.stdout, -process.stdout.columns, +1);
|
||||
readline.moveCursor(process.stdout, -process.stdout.columns!, +1);
|
||||
}
|
||||
|
||||
lineCount++;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// tslint:disable no-unnecessary-type-assertion (TODO: tslint can't find node types)
|
||||
|
||||
namespace Harness.Parallel.Worker {
|
||||
let errors: ErrorInfo[] = [];
|
||||
let passes: TestInfo[] = [];
|
||||
@@ -35,7 +37,7 @@ namespace Harness.Parallel.Worker {
|
||||
if (!testList) {
|
||||
throw new Error("Tests must occur within a describe block");
|
||||
}
|
||||
testList.push({ name, callback, kind: "test" });
|
||||
testList.push({ name, callback: callback!, kind: "test" });
|
||||
}) as Mocha.ITestDefinition;
|
||||
(global as any).it.skip = ts.noop;
|
||||
}
|
||||
@@ -43,18 +45,18 @@ namespace Harness.Parallel.Worker {
|
||||
function setTimeoutAndExecute(timeout: number | undefined, f: () => void) {
|
||||
if (timeout !== undefined) {
|
||||
const timeoutMsg: ParallelTimeoutChangeMessage = { type: "timeout", payload: { duration: timeout } };
|
||||
process.send(timeoutMsg);
|
||||
process.send!(timeoutMsg);
|
||||
}
|
||||
f();
|
||||
if (timeout !== undefined) {
|
||||
// Reset timeout
|
||||
const timeoutMsg: ParallelTimeoutChangeMessage = { type: "timeout", payload: { duration: "reset" } };
|
||||
process.send(timeoutMsg);
|
||||
process.send!(timeoutMsg);
|
||||
}
|
||||
}
|
||||
|
||||
function executeSuiteCallback(name: string, callback: MochaCallback) {
|
||||
let timeout: number;
|
||||
let timeout: number | undefined;
|
||||
const fakeContext: Mocha.ISuiteCallbackContext = {
|
||||
retries() { return this; },
|
||||
slow() { return this; },
|
||||
@@ -64,9 +66,9 @@ namespace Harness.Parallel.Worker {
|
||||
},
|
||||
};
|
||||
namestack.push(name);
|
||||
let beforeFunc: Callable;
|
||||
let beforeFunc: Callable | undefined;
|
||||
(before as any) = (cb: Callable) => beforeFunc = cb;
|
||||
let afterFunc: Callable;
|
||||
let afterFunc: Callable | undefined;
|
||||
(after as any) = (cb: Callable) => afterFunc = cb;
|
||||
const savedBeforeEach = beforeEachFunc;
|
||||
(beforeEach as any) = (cb: Callable) => beforeEachFunc = cb;
|
||||
@@ -127,13 +129,13 @@ namespace Harness.Parallel.Worker {
|
||||
}
|
||||
|
||||
function executeTestCallback(name: string, callback: MochaCallback) {
|
||||
let timeout: number;
|
||||
let timeout: number | undefined;
|
||||
const fakeContext: Mocha.ITestCallbackContext = {
|
||||
skip() { return this; },
|
||||
timeout(n: number) {
|
||||
timeout = n;
|
||||
const timeoutMsg: ParallelTimeoutChangeMessage = { type: "timeout", payload: { duration: timeout } };
|
||||
process.send(timeoutMsg);
|
||||
process.send!(timeoutMsg);
|
||||
return this;
|
||||
},
|
||||
retries() { return this; },
|
||||
@@ -164,7 +166,7 @@ namespace Harness.Parallel.Worker {
|
||||
namestack.pop();
|
||||
if (timeout !== undefined) {
|
||||
const timeoutMsg: ParallelTimeoutChangeMessage = { type: "timeout", payload: { duration: "reset" } };
|
||||
process.send(timeoutMsg);
|
||||
process.send!(timeoutMsg);
|
||||
}
|
||||
}
|
||||
passing++;
|
||||
@@ -195,7 +197,7 @@ namespace Harness.Parallel.Worker {
|
||||
namestack.pop();
|
||||
if (timeout !== undefined) {
|
||||
const timeoutMsg: ParallelTimeoutChangeMessage = { type: "timeout", payload: { duration: "reset" } };
|
||||
process.send(timeoutMsg);
|
||||
process.send!(timeoutMsg);
|
||||
}
|
||||
}
|
||||
if (!completed) {
|
||||
@@ -219,7 +221,7 @@ namespace Harness.Parallel.Worker {
|
||||
console.error(data);
|
||||
}
|
||||
const message: ParallelResultMessage = { type: "result", payload: handleTest(runner, file) };
|
||||
process.send(message);
|
||||
process.send!(message);
|
||||
break;
|
||||
case "close":
|
||||
process.exit(0);
|
||||
@@ -239,16 +241,16 @@ namespace Harness.Parallel.Worker {
|
||||
else {
|
||||
message = { type: "progress", payload };
|
||||
}
|
||||
process.send(message);
|
||||
process.send!(message);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
process.on("uncaughtException", error => {
|
||||
const message: ParallelErrorMessage = { type: "error", payload: { error: error.message, stack: error.stack, name: [...namestack] } };
|
||||
const message: ParallelErrorMessage = { type: "error", payload: { error: error.message, stack: error.stack!, name: [...namestack] } };
|
||||
try {
|
||||
process.send(message);
|
||||
process.send!(message);
|
||||
}
|
||||
catch (e) {
|
||||
console.error(error);
|
||||
@@ -273,7 +275,7 @@ namespace Harness.Parallel.Worker {
|
||||
if (!runners.has(runner)) {
|
||||
runners.set(runner, createRunner(runner));
|
||||
}
|
||||
const instance = runners.get(runner);
|
||||
const instance = runners.get(runner)!;
|
||||
instance.tests = [file];
|
||||
return { ...resetShimHarnessAndExecute(instance), runner, file };
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ namespace project {
|
||||
this.compilerOptions = createCompilerOptions(testCase, moduleKind);
|
||||
this.sys = new fakes.System(vfs);
|
||||
|
||||
let configFileName: string;
|
||||
let configFileName: string | undefined;
|
||||
let inputFiles = testCase.inputFiles;
|
||||
if (this.compilerOptions.project) {
|
||||
// Parse project
|
||||
@@ -145,7 +145,7 @@ namespace project {
|
||||
configFileName = ts.findConfigFile("", path => this.sys.fileExists(path));
|
||||
}
|
||||
|
||||
let errors: ts.Diagnostic[];
|
||||
let errors: ts.Diagnostic[] | undefined;
|
||||
const configFileSourceFiles: ts.SourceFile[] = [];
|
||||
if (configFileName) {
|
||||
const result = ts.readJsonConfigFile(configFileName, path => this.sys.readFile(path));
|
||||
@@ -178,7 +178,7 @@ namespace project {
|
||||
public static getConfigurations(testCaseFileName: string): ProjectTestConfiguration[] {
|
||||
let testCase: ProjectRunnerTestCase & ts.CompilerOptions;
|
||||
|
||||
let testFileText: string;
|
||||
let testFileText: string | undefined;
|
||||
try {
|
||||
testFileText = Harness.IO.readFile(testCaseFileName);
|
||||
}
|
||||
@@ -187,10 +187,10 @@ namespace project {
|
||||
}
|
||||
|
||||
try {
|
||||
testCase = <ProjectRunnerTestCase & ts.CompilerOptions>JSON.parse(testFileText);
|
||||
testCase = <ProjectRunnerTestCase & ts.CompilerOptions>JSON.parse(testFileText!);
|
||||
}
|
||||
catch (e) {
|
||||
assert(false, "Testcase: " + testCaseFileName + " does not contain valid json format: " + e.message);
|
||||
throw assert(false, "Testcase: " + testCaseFileName + " does not contain valid json format: " + e.message);
|
||||
}
|
||||
|
||||
const fs = vfs.createFromFileSystem(Harness.IO, /*ignoreCase*/ false);
|
||||
@@ -209,12 +209,12 @@ namespace project {
|
||||
const cwd = this.vfs.cwd();
|
||||
const ignoreCase = this.vfs.ignoreCase;
|
||||
const resolutionInfo: ProjectRunnerTestCaseResolutionInfo & ts.CompilerOptions = JSON.parse(JSON.stringify(this.testCase));
|
||||
resolutionInfo.resolvedInputFiles = this.compilerResult.program.getSourceFiles()
|
||||
resolutionInfo.resolvedInputFiles = this.compilerResult.program!.getSourceFiles()
|
||||
.map(({ fileName: input }) => vpath.beneath(vfs.builtFolder, input, this.vfs.ignoreCase) || vpath.beneath(vfs.testLibFolder, input, this.vfs.ignoreCase) ? utils.removeTestPathPrefixes(input) :
|
||||
vpath.isAbsolute(input) ? vpath.relative(cwd, input, ignoreCase) :
|
||||
input);
|
||||
|
||||
resolutionInfo.emittedFiles = this.compilerResult.outputFiles
|
||||
resolutionInfo.emittedFiles = this.compilerResult.outputFiles!
|
||||
.map(output => output.meta.get("fileName") || output.file)
|
||||
.map(output => utils.removeTestPathPrefixes(vpath.isAbsolute(output) ? vpath.relative(cwd, output, ignoreCase) : output));
|
||||
|
||||
@@ -234,7 +234,7 @@ namespace project {
|
||||
if (this.testCase.baselineCheck) {
|
||||
const errs: Error[] = [];
|
||||
let nonSubfolderDiskFiles = 0;
|
||||
for (const output of this.compilerResult.outputFiles) {
|
||||
for (const output of this.compilerResult.outputFiles!) {
|
||||
try {
|
||||
// convert file name to rooted name
|
||||
// if filename is not rooted - concat it with project root and then expand project root relative to current directory
|
||||
@@ -252,7 +252,7 @@ namespace project {
|
||||
}
|
||||
|
||||
const content = utils.removeTestPathPrefixes(output.text, /*retainTrailingDirectorySeparator*/ true);
|
||||
Harness.Baseline.runBaseline(this.getBaselineFolder(this.compilerResult.moduleKind) + diskRelativeName, () => content);
|
||||
Harness.Baseline.runBaseline(this.getBaselineFolder(this.compilerResult.moduleKind) + diskRelativeName, () => content as string | null); // TODO: GH#18217
|
||||
}
|
||||
catch (e) {
|
||||
errs.push(e);
|
||||
@@ -292,7 +292,7 @@ namespace project {
|
||||
}
|
||||
|
||||
private cleanProjectUrl(url: string) {
|
||||
let diskProjectPath = ts.normalizeSlashes(Harness.IO.resolvePath(this.testCase.projectRoot));
|
||||
let diskProjectPath = ts.normalizeSlashes(Harness.IO.resolvePath(this.testCase.projectRoot)!);
|
||||
let projectRootUrl = "file:///" + diskProjectPath;
|
||||
const normalizedProjectRoot = ts.normalizeSlashes(this.testCase.projectRoot);
|
||||
diskProjectPath = diskProjectPath.substr(0, diskProjectPath.lastIndexOf(normalizedProjectRoot));
|
||||
@@ -362,10 +362,10 @@ namespace project {
|
||||
rootFiles.unshift(sourceFile.fileName);
|
||||
}
|
||||
else if (!(compilerOptions.outFile || compilerOptions.out)) {
|
||||
let emitOutputFilePathWithoutExtension: string;
|
||||
let emitOutputFilePathWithoutExtension: string | undefined;
|
||||
if (compilerOptions.outDir) {
|
||||
let sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, compilerResult.program.getCurrentDirectory());
|
||||
sourceFilePath = sourceFilePath.replace(compilerResult.program.getCommonSourceDirectory(), "");
|
||||
let sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, compilerResult.program!.getCurrentDirectory());
|
||||
sourceFilePath = sourceFilePath.replace(compilerResult.program!.getCommonSourceDirectory(), "");
|
||||
emitOutputFilePathWithoutExtension = ts.removeFileExtension(ts.combinePaths(compilerOptions.outDir, sourceFilePath));
|
||||
}
|
||||
else {
|
||||
@@ -380,8 +380,8 @@ namespace project {
|
||||
}
|
||||
}
|
||||
else {
|
||||
const outputDtsFileName = ts.removeFileExtension(compilerOptions.outFile || compilerOptions.out) + ts.Extension.Dts;
|
||||
const outputDtsFile = findOutputDtsFile(outputDtsFileName);
|
||||
const outputDtsFileName = ts.removeFileExtension(compilerOptions.outFile || compilerOptions.out!) + ts.Extension.Dts;
|
||||
const outputDtsFile = findOutputDtsFile(outputDtsFileName)!;
|
||||
if (!ts.contains(allInputFiles, outputDtsFile)) {
|
||||
allInputFiles.unshift(outputDtsFile);
|
||||
rootFiles.unshift(outputDtsFile.meta.get("fileName") || outputDtsFile.file);
|
||||
@@ -395,8 +395,8 @@ namespace project {
|
||||
});
|
||||
|
||||
// Dont allow config files since we are compiling existing source options
|
||||
const compilerHost = new ProjectCompilerHost(_vfs, compilerResult.compilerOptions, this.testCaseJustName, this.testCase, compilerResult.moduleKind);
|
||||
return this.compileProjectFiles(compilerResult.moduleKind, compilerResult.configFileSourceFiles, () => rootFiles, compilerHost, compilerResult.compilerOptions);
|
||||
const compilerHost = new ProjectCompilerHost(_vfs, compilerResult.compilerOptions!, this.testCaseJustName, this.testCase, compilerResult.moduleKind);
|
||||
return this.compileProjectFiles(compilerResult.moduleKind, compilerResult.configFileSourceFiles, () => rootFiles, compilerHost, compilerResult.compilerOptions!);
|
||||
|
||||
function findOutputDtsFile(fileName: string) {
|
||||
return ts.forEach(compilerResult.outputFiles, outputFile => outputFile.meta.get("fileName") === fileName ? outputFile : undefined);
|
||||
|
||||
@@ -65,7 +65,7 @@ function createRunner(kind: TestRunnerKind): RunnerBase {
|
||||
case "dt":
|
||||
return new DefinitelyTypedRunner();
|
||||
}
|
||||
ts.Debug.fail(`Unknown runner kind ${kind}`);
|
||||
return ts.Debug.fail(`Unknown runner kind ${kind}`);
|
||||
}
|
||||
|
||||
// users can define tests to run in mytest.config that will override cmd line args, otherwise use cmd line args (test.config), otherwise no options
|
||||
@@ -76,10 +76,10 @@ const testconfigFileName = "test.config";
|
||||
const customConfig = tryGetConfig(Harness.IO.args());
|
||||
let testConfigContent =
|
||||
customConfig && Harness.IO.fileExists(customConfig)
|
||||
? Harness.IO.readFile(customConfig)
|
||||
? Harness.IO.readFile(customConfig)!
|
||||
: Harness.IO.fileExists(mytestconfigFileName)
|
||||
? Harness.IO.readFile(mytestconfigFileName)
|
||||
: Harness.IO.fileExists(testconfigFileName) ? Harness.IO.readFile(testconfigFileName) : "";
|
||||
? Harness.IO.readFile(mytestconfigFileName)!
|
||||
: Harness.IO.fileExists(testconfigFileName) ? Harness.IO.readFile(testconfigFileName)! : "";
|
||||
|
||||
let taskConfigsFolder: string;
|
||||
let workerCount: number;
|
||||
@@ -131,9 +131,9 @@ function handleTestConfig() {
|
||||
(<any>Error).stackTraceLimit = Infinity;
|
||||
stackTraceLimit = testConfig.stackTraceLimit;
|
||||
}
|
||||
else if ((+testConfig.stackTraceLimit | 0) > 0) {
|
||||
(<any>Error).stackTraceLimit = +testConfig.stackTraceLimit | 0;
|
||||
stackTraceLimit = +testConfig.stackTraceLimit | 0;
|
||||
else if ((+testConfig.stackTraceLimit! | 0) > 0) {
|
||||
(<any>Error).stackTraceLimit = +testConfig.stackTraceLimit! | 0;
|
||||
stackTraceLimit = +testConfig.stackTraceLimit! | 0;
|
||||
}
|
||||
if (testConfig.listenForWork) {
|
||||
return true;
|
||||
@@ -222,6 +222,7 @@ function handleTestConfig() {
|
||||
if (runUnitTests === undefined) {
|
||||
runUnitTests = runners.length !== 1; // Don't run unit tests when running only one runner if unit tests were not explicitly asked for
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function beginTests() {
|
||||
|
||||
+15
-15
@@ -41,22 +41,22 @@ namespace RWC {
|
||||
inputFiles = [];
|
||||
otherFiles = [];
|
||||
tsconfigFiles = [];
|
||||
compilerResult = undefined;
|
||||
compilerOptions = undefined;
|
||||
currentDirectory = undefined;
|
||||
compilerResult = undefined!;
|
||||
compilerOptions = undefined!;
|
||||
currentDirectory = undefined!;
|
||||
// useCustomLibraryFile is a flag specified in the json object to indicate whether to use built/local/lib.d.ts
|
||||
// or to use lib.d.ts inside the json object. If the flag is true, use the lib.d.ts inside json file
|
||||
// otherwise use the lib.d.ts from built/local
|
||||
useCustomLibraryFile = undefined;
|
||||
useCustomLibraryFile = undefined!;
|
||||
});
|
||||
|
||||
it("can compile", function(this: Mocha.ITestCallbackContext) {
|
||||
this.timeout(800_000); // Allow long timeouts for RWC compilations
|
||||
let opts: ts.ParsedCommandLine;
|
||||
let opts!: ts.ParsedCommandLine;
|
||||
|
||||
const ioLog: IoLog = Playback.newStyleLogIntoOldStyleLog(JSON.parse(Harness.IO.readFile(`internal/cases/rwc/${jsonPath}/test.json`)), Harness.IO, `internal/cases/rwc/${baseName}`);
|
||||
const ioLog: IoLog = Playback.newStyleLogIntoOldStyleLog(JSON.parse(Harness.IO.readFile(`internal/cases/rwc/${jsonPath}/test.json`)!), Harness.IO, `internal/cases/rwc/${baseName}`);
|
||||
currentDirectory = ioLog.currentDirectory;
|
||||
useCustomLibraryFile = ioLog.useCustomLibraryFile;
|
||||
useCustomLibraryFile = !!ioLog.useCustomLibraryFile;
|
||||
runWithIOLog(ioLog, () => {
|
||||
opts = ts.parseCommandLine(ioLog.arguments, fileName => Harness.IO.readFile(fileName));
|
||||
assert.equal(opts.errors.length, 0);
|
||||
@@ -89,7 +89,7 @@ namespace RWC {
|
||||
const uniqueNames = ts.createMap<true>();
|
||||
for (const fileName of fileNames) {
|
||||
// Must maintain order, build result list while checking map
|
||||
const normalized = ts.normalizeSlashes(Harness.IO.resolvePath(fileName));
|
||||
const normalized = ts.normalizeSlashes(Harness.IO.resolvePath(fileName)!);
|
||||
if (!uniqueNames.has(normalized)) {
|
||||
uniqueNames.set(normalized, true);
|
||||
// Load the file
|
||||
@@ -99,7 +99,7 @@ namespace RWC {
|
||||
|
||||
// Add files to compilation
|
||||
for (const fileRead of ioLog.filesRead) {
|
||||
const unitName = ts.normalizeSlashes(Harness.IO.resolvePath(fileRead.path));
|
||||
const unitName = ts.normalizeSlashes(Harness.IO.resolvePath(fileRead.path)!);
|
||||
if (!uniqueNames.has(unitName) && !Harness.isDefaultLibraryFile(fileRead.path)) {
|
||||
uniqueNames.set(unitName, true);
|
||||
otherFiles.push(getHarnessCompilerInputUnit(unitName));
|
||||
@@ -134,13 +134,13 @@ namespace RWC {
|
||||
compilerOptions = compilerResult.options;
|
||||
|
||||
function getHarnessCompilerInputUnit(fileName: string): Harness.Compiler.TestFile {
|
||||
const unitName = ts.normalizeSlashes(Harness.IO.resolvePath(fileName));
|
||||
const unitName = ts.normalizeSlashes(Harness.IO.resolvePath(fileName)!);
|
||||
let content: string;
|
||||
try {
|
||||
content = Harness.IO.readFile(unitName);
|
||||
content = Harness.IO.readFile(unitName)!;
|
||||
}
|
||||
catch (e) {
|
||||
content = Harness.IO.readFile(fileName);
|
||||
content = Harness.IO.readFile(fileName)!;
|
||||
}
|
||||
return { unitName, content };
|
||||
}
|
||||
@@ -196,11 +196,11 @@ namespace RWC {
|
||||
}
|
||||
|
||||
const declContext = Harness.Compiler.prepareDeclarationCompilationContext(
|
||||
inputFiles, otherFiles, compilerResult, /*harnessSettings*/ undefined, compilerOptions, currentDirectory
|
||||
inputFiles, otherFiles, compilerResult, /*harnessSettings*/ undefined!, compilerOptions, currentDirectory // TODO: GH#18217
|
||||
);
|
||||
// Reset compilerResult before calling into `compileDeclarationFiles` so the memory from the original compilation can be freed
|
||||
compilerResult = undefined;
|
||||
const declFileCompilationResult = Harness.Compiler.compileDeclarationFiles(declContext);
|
||||
compilerResult = undefined!;
|
||||
const declFileCompilationResult = Harness.Compiler.compileDeclarationFiles(declContext)!;
|
||||
|
||||
return Harness.Compiler.iterateErrorBaseline(tsconfigFiles.concat(declFileCompilationResult.declInputFiles, declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.diagnostics);
|
||||
}, baselineOpts);
|
||||
|
||||
@@ -19,16 +19,16 @@ namespace Harness.SourceMapRecorder {
|
||||
|
||||
interface SourceMapSpanWithDecodeErrors {
|
||||
sourceMapSpan: ts.SourceMapSpan;
|
||||
decodeErrors: string[];
|
||||
decodeErrors: string[] | undefined;
|
||||
}
|
||||
|
||||
namespace SourceMapDecoder {
|
||||
let sourceMapMappings: string;
|
||||
let sourceMapNames: string[];
|
||||
let sourceMapNames: string[] | undefined;
|
||||
let decodingIndex: number;
|
||||
let prevNameIndex: number;
|
||||
let decodeOfEncodedMapping: ts.SourceMapSpan;
|
||||
let errorDecodeOfEncodedMapping: string;
|
||||
let errorDecodeOfEncodedMapping: string | undefined;
|
||||
|
||||
export function initializeSourceMapDecoding(sourceMapData: ts.SourceMapData) {
|
||||
sourceMapMappings = sourceMapData.sourceMapMappings;
|
||||
@@ -88,7 +88,7 @@ namespace Harness.SourceMapRecorder {
|
||||
|
||||
for (; moreDigits; decodingIndex++) {
|
||||
if (createErrorIfCondition(decodingIndex >= sourceMapMappings.length, "Error in decoding base64VLQFormatDecode, past the mapping string")) {
|
||||
return;
|
||||
return undefined!; // TODO: GH#18217
|
||||
}
|
||||
|
||||
// 6 digit number
|
||||
@@ -176,7 +176,7 @@ namespace Harness.SourceMapRecorder {
|
||||
prevNameIndex += base64VLQFormatDecode();
|
||||
decodeOfEncodedMapping.nameIndex = prevNameIndex;
|
||||
// Incorrect nameIndex dont support this map
|
||||
if (createErrorIfCondition(decodeOfEncodedMapping.nameIndex < 0 || decodeOfEncodedMapping.nameIndex >= sourceMapNames.length, "Invalid name index for the source map entry")) {
|
||||
if (createErrorIfCondition(decodeOfEncodedMapping.nameIndex < 0 || decodeOfEncodedMapping.nameIndex >= sourceMapNames!.length, "Invalid name index for the source map entry")) {
|
||||
return { error: errorDecodeOfEncodedMapping, sourceMapSpan: decodeOfEncodedMapping };
|
||||
}
|
||||
}
|
||||
@@ -190,6 +190,7 @@ namespace Harness.SourceMapRecorder {
|
||||
}
|
||||
|
||||
createErrorIfCondition(/*condition*/ true, "No encoded entry found");
|
||||
return undefined!; // TODO: GH#18217
|
||||
}
|
||||
|
||||
export function hasCompletedDecoding() {
|
||||
@@ -204,7 +205,7 @@ namespace Harness.SourceMapRecorder {
|
||||
namespace SourceMapSpanWriter {
|
||||
let sourceMapRecorder: Compiler.WriterAggregator;
|
||||
let sourceMapSources: string[];
|
||||
let sourceMapNames: string[];
|
||||
let sourceMapNames: string[] | undefined;
|
||||
|
||||
let jsFile: documents.TextDocument;
|
||||
let jsLineMap: ReadonlyArray<number>;
|
||||
@@ -244,8 +245,8 @@ namespace Harness.SourceMapRecorder {
|
||||
|
||||
function getSourceMapSpanString(mapEntry: ts.SourceMapSpan, getAbsentNameIndex?: boolean) {
|
||||
let mapString = "Emitted(" + mapEntry.emittedLine + ", " + mapEntry.emittedColumn + ") Source(" + mapEntry.sourceLine + ", " + mapEntry.sourceColumn + ") + SourceIndex(" + mapEntry.sourceIndex + ")";
|
||||
if (mapEntry.nameIndex >= 0 && mapEntry.nameIndex < sourceMapNames.length) {
|
||||
mapString += " name (" + sourceMapNames[mapEntry.nameIndex] + ")";
|
||||
if (mapEntry.nameIndex! >= 0 && mapEntry.nameIndex! < sourceMapNames!.length) {
|
||||
mapString += " name (" + sourceMapNames![mapEntry.nameIndex!] + ")";
|
||||
}
|
||||
else {
|
||||
if ((mapEntry.nameIndex && mapEntry.nameIndex !== -1) || getAbsentNameIndex) {
|
||||
@@ -259,7 +260,7 @@ namespace Harness.SourceMapRecorder {
|
||||
export function recordSourceMapSpan(sourceMapSpan: ts.SourceMapSpan) {
|
||||
// verify the decoded span is same as the new span
|
||||
const decodeResult = SourceMapDecoder.decodeNextEncodedSourceMapSpan();
|
||||
let decodeErrors: string[];
|
||||
let decodeErrors: string[] | undefined;
|
||||
if (decodeResult.error
|
||||
|| decodeResult.sourceMapSpan.emittedLine !== sourceMapSpan.emittedLine
|
||||
|| decodeResult.sourceMapSpan.emittedColumn !== sourceMapSpan.emittedColumn
|
||||
@@ -345,7 +346,7 @@ namespace Harness.SourceMapRecorder {
|
||||
return markerId;
|
||||
}
|
||||
|
||||
let prevEmittedCol: number;
|
||||
let prevEmittedCol!: number;
|
||||
function iterateSpans(fn: (currentSpan: SourceMapSpanWithDecodeErrors, index: number) => void) {
|
||||
prevEmittedCol = 1;
|
||||
for (let i = 0; i < spansOnSingleLine.length; i++) {
|
||||
@@ -361,7 +362,7 @@ namespace Harness.SourceMapRecorder {
|
||||
}
|
||||
}
|
||||
|
||||
function writeSourceMapMarker(currentSpan: SourceMapSpanWithDecodeErrors, index: number, endColumn = currentSpan.sourceMapSpan.emittedColumn, endContinues?: boolean) {
|
||||
function writeSourceMapMarker(currentSpan: SourceMapSpanWithDecodeErrors, index: number, endColumn = currentSpan.sourceMapSpan.emittedColumn, endContinues = false) {
|
||||
const markerId = getMarkerId(index);
|
||||
markerIds.push(markerId);
|
||||
|
||||
@@ -421,7 +422,7 @@ namespace Harness.SourceMapRecorder {
|
||||
const jsFileText = getTextOfLine(currentJsLine, jsLineMap, jsFile.text);
|
||||
if (prevEmittedCol < jsFileText.length) {
|
||||
// There is remaining text on this line that will be part of next source span so write marker that continues
|
||||
writeSourceMapMarker(/*currentSpan*/ undefined, spansOnSingleLine.length, /*endColumn*/ jsFileText.length, /*endContinues*/ true);
|
||||
writeSourceMapMarker(/*currentSpan*/ undefined!, spansOnSingleLine.length, /*endColumn*/ jsFileText.length, /*endContinues*/ true); // TODO: GH#18217
|
||||
}
|
||||
|
||||
// Emit Source text
|
||||
@@ -440,7 +441,7 @@ namespace Harness.SourceMapRecorder {
|
||||
|
||||
for (let i = 0; i < sourceMapDataList.length; i++) {
|
||||
const sourceMapData = sourceMapDataList[i];
|
||||
let prevSourceFile: ts.SourceFile;
|
||||
let prevSourceFile: ts.SourceFile | undefined;
|
||||
let currentFile: documents.TextDocument;
|
||||
if (ts.endsWith(sourceMapData.sourceMapFile, ts.Extension.Dts)) {
|
||||
if (sourceMapDataList.length > jsFiles.length) {
|
||||
@@ -461,7 +462,7 @@ namespace Harness.SourceMapRecorder {
|
||||
|
||||
SourceMapSpanWriter.initializeSourceMapSpanWriter(sourceMapRecorder, sourceMapData, currentFile);
|
||||
for (const decodedSourceMapping of sourceMapData.sourceMapDecodedMappings) {
|
||||
const currentSourceFile = program.getSourceFile(sourceMapData.inputSourceFileNames[decodedSourceMapping.sourceIndex]);
|
||||
const currentSourceFile = program.getSourceFile(sourceMapData.inputSourceFileNames[decodedSourceMapping.sourceIndex])!;
|
||||
if (currentSourceFile !== prevSourceFile) {
|
||||
SourceMapSpanWriter.recordNewSourceFileSpan(decodedSourceMapping, currentSourceFile.text);
|
||||
prevSourceFile = currentSourceFile;
|
||||
|
||||
@@ -8,7 +8,7 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
private static readonly helpersFilePath = "tests/cases/test262-harness/helpers.d.ts";
|
||||
private static readonly helperFile: Harness.Compiler.TestFile = {
|
||||
unitName: Test262BaselineRunner.helpersFilePath,
|
||||
content: Harness.IO.readFile(Test262BaselineRunner.helpersFilePath),
|
||||
content: Harness.IO.readFile(Test262BaselineRunner.helpersFilePath)!,
|
||||
};
|
||||
private static readonly testFileExtensionRegex = /\.js$/;
|
||||
private static readonly options: ts.CompilerOptions = {
|
||||
@@ -36,7 +36,7 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
};
|
||||
|
||||
before(() => {
|
||||
const content = Harness.IO.readFile(filePath);
|
||||
const content = Harness.IO.readFile(filePath)!;
|
||||
const testFilename = ts.removeFileExtension(filePath).replace(/\//g, "_") + ".test";
|
||||
const testCaseContent = Harness.TestCaseParser.makeUnitsFromTest(content, testFilename);
|
||||
|
||||
@@ -49,7 +49,7 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
testState = {
|
||||
filename: testFilename,
|
||||
inputFiles,
|
||||
compilerResult: undefined,
|
||||
compilerResult: undefined!, // TODO: GH#18217
|
||||
};
|
||||
|
||||
testState.compilerResult = Harness.Compiler.compileFiles(
|
||||
@@ -61,7 +61,7 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
});
|
||||
|
||||
after(() => {
|
||||
testState = undefined;
|
||||
testState = undefined!;
|
||||
});
|
||||
|
||||
it("has the expected emitted code", () => {
|
||||
@@ -83,13 +83,13 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
});
|
||||
|
||||
it("satisfies invariants", () => {
|
||||
const sourceFile = testState.compilerResult.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
|
||||
const sourceFile = testState.compilerResult.program!.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
|
||||
Utils.assertInvariants(sourceFile, /*parent:*/ undefined);
|
||||
});
|
||||
|
||||
it("has the expected AST", () => {
|
||||
Harness.Baseline.runBaseline(testState.filename + ".AST.txt", () => {
|
||||
const sourceFile = testState.compilerResult.program.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename));
|
||||
const sourceFile = testState.compilerResult.program!.getSourceFile(Test262BaselineRunner.getTestFilePath(testState.filename))!;
|
||||
return Utils.sourceFileToJSON(sourceFile);
|
||||
}, Test262BaselineRunner.baselineOptions);
|
||||
});
|
||||
|
||||
@@ -34,7 +34,7 @@ class TypeWriterWalker {
|
||||
}
|
||||
|
||||
public *getSymbols(fileName: string): IterableIterator<TypeWriterSymbolResult> {
|
||||
const sourceFile = this.program.getSourceFile(fileName);
|
||||
const sourceFile = this.program.getSourceFile(fileName)!;
|
||||
this.currentSourceFile = sourceFile;
|
||||
const gen = this.visitNode(sourceFile, /*isSymbolWalk*/ true);
|
||||
for (let {done, value} = gen.next(); !done; { done, value } = gen.next()) {
|
||||
@@ -43,7 +43,7 @@ class TypeWriterWalker {
|
||||
}
|
||||
|
||||
public *getTypes(fileName: string): IterableIterator<TypeWriterTypeResult> {
|
||||
const sourceFile = this.program.getSourceFile(fileName);
|
||||
const sourceFile = this.program.getSourceFile(fileName)!;
|
||||
this.currentSourceFile = sourceFile;
|
||||
const gen = this.visitNode(sourceFile, /*isSymbolWalk*/ false);
|
||||
for (let {done, value} = gen.next(); !done; { done, value } = gen.next()) {
|
||||
@@ -69,7 +69,7 @@ class TypeWriterWalker {
|
||||
}
|
||||
}
|
||||
|
||||
private writeTypeOrSymbol(node: ts.Node, isSymbolWalk: boolean): TypeWriterResult {
|
||||
private writeTypeOrSymbol(node: ts.Node, isSymbolWalk: boolean): TypeWriterResult | undefined {
|
||||
const actualPos = ts.skipTrivia(this.currentSourceFile.text, node.pos);
|
||||
const lineAndCharacter = this.currentSourceFile.getLineAndCharacterOfPosition(actualPos);
|
||||
const sourceText = ts.getSourceTextOfNodeFromSourceFile(this.currentSourceFile, node);
|
||||
|
||||
@@ -120,7 +120,7 @@ namespace ts {
|
||||
operationWasCancelled = true;
|
||||
}
|
||||
assert.equal(cancel, operationWasCancelled);
|
||||
assert.equal(operationWasCancelled, fileNames.length > cancelAfterEmitLength);
|
||||
assert.equal(operationWasCancelled, fileNames.length > cancelAfterEmitLength!);
|
||||
assert.deepEqual(outputFileNames, fileNames.slice(0, cancelAfterEmitLength));
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,21 +10,21 @@ namespace ts {
|
||||
`;
|
||||
it("can cancel signature help mid-request", () => {
|
||||
verifyOperationCancelledAfter(file, 4, service => // Two calls are top-level in services, one is the root type, and the second should be for the parameter type
|
||||
service.getSignatureHelpItems("file.ts", file.lastIndexOf("f")),
|
||||
service.getSignatureHelpItems("file.ts", file.lastIndexOf("f"))!,
|
||||
r => assert.exists(r.items[0])
|
||||
);
|
||||
});
|
||||
|
||||
it("can cancel find all references mid-request", () => {
|
||||
verifyOperationCancelledAfter(file, 3, service => // Two calls are top-level in services, one is the root type
|
||||
service.findReferences("file.ts", file.lastIndexOf("o")),
|
||||
service.findReferences("file.ts", file.lastIndexOf("o"))!,
|
||||
r => assert.exists(r[0].definition)
|
||||
);
|
||||
});
|
||||
|
||||
it("can cancel quick info mid-request", () => {
|
||||
verifyOperationCancelledAfter(file, 1, service => // The LS doesn't do any top-level checks on the token for quickinfo, so the first check is within the checker
|
||||
service.getQuickInfoAtPosition("file.ts", file.lastIndexOf("o")),
|
||||
service.getQuickInfoAtPosition("file.ts", file.lastIndexOf("o"))!,
|
||||
r => assert.exists(r.displayParts)
|
||||
);
|
||||
});
|
||||
@@ -52,7 +52,7 @@ namespace ts {
|
||||
placeOpenBraceOnNewLineForControlBlocks: false,
|
||||
};
|
||||
verifyOperationCancelledAfter(file, 1, service => // The LS doesn't do any top-level checks on the token for completion entry details, so the first check is within the checker
|
||||
service.getCompletionEntryDetails("file.ts", file.lastIndexOf("f"), "foo", options, /*content*/ undefined, {}),
|
||||
service.getCompletionEntryDetails("file.ts", file.lastIndexOf("f"), "foo", options, /*content*/ undefined, {})!,
|
||||
r => assert.exists(r.displayParts)
|
||||
);
|
||||
});
|
||||
|
||||
@@ -601,7 +601,7 @@ namespace ts.projectSystem {
|
||||
|
||||
const expectedOutFileName = "/a/b/dist.js";
|
||||
assert.isTrue(host.fileExists(expectedOutFileName));
|
||||
const outFileContent = host.readFile(expectedOutFileName);
|
||||
const outFileContent = host.readFile(expectedOutFileName)!;
|
||||
assert.isTrue(outFileContent.indexOf(file1.content) !== -1);
|
||||
assert.isTrue(outFileContent.indexOf(file2.content) === -1);
|
||||
assert.isTrue(outFileContent.indexOf(file3.content) === -1);
|
||||
@@ -635,14 +635,14 @@ namespace ts.projectSystem {
|
||||
// Verify js file
|
||||
const expectedOutFileName = "/root/TypeScriptProject3/TypeScriptProject3/" + outFileName;
|
||||
assert.isTrue(host.fileExists(expectedOutFileName));
|
||||
const outFileContent = host.readFile(expectedOutFileName);
|
||||
const outFileContent = host.readFile(expectedOutFileName)!;
|
||||
verifyContentHasString(outFileContent, file1.content);
|
||||
verifyContentHasString(outFileContent, `//# ${"sourceMappingURL"}=${outFileName}.map`); // Sometimes tools can sometimes see this line as a source mapping url comment, so we obfuscate it a little
|
||||
|
||||
// Verify map file
|
||||
const expectedMapFileName = expectedOutFileName + ".map";
|
||||
assert.isTrue(host.fileExists(expectedMapFileName));
|
||||
const mapFileContent = host.readFile(expectedMapFileName);
|
||||
const mapFileContent = host.readFile(expectedMapFileName)!;
|
||||
verifyContentHasString(mapFileContent, `"sources":["${inputFileName}"]`);
|
||||
|
||||
function verifyContentHasString(content: string, str: string) {
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace ts {
|
||||
assertTypeAcquisitionWithJsonNode(json, configFileName, expectedResult);
|
||||
}
|
||||
|
||||
function verifyAcquisition(actualTypeAcquisition: TypeAcquisition, expectedResult: ExpectedResult) {
|
||||
function verifyAcquisition(actualTypeAcquisition: TypeAcquisition | undefined, expectedResult: ExpectedResult) {
|
||||
const parsedTypeAcquisition = JSON.stringify(actualTypeAcquisition);
|
||||
const expectedTypeAcquisition = JSON.stringify(expectedResult.typeAcquisition);
|
||||
assert.equal(parsedTypeAcquisition, expectedTypeAcquisition);
|
||||
@@ -120,7 +120,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: undefined
|
||||
messageText: undefined!, // TODO: GH#18217
|
||||
}
|
||||
]
|
||||
});
|
||||
@@ -215,7 +215,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: undefined
|
||||
messageText: undefined!, // TODO: GH#18217
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace ts {
|
||||
useCaseSensitiveFileNames: () => true,
|
||||
getNewLine: () => "\n",
|
||||
fileExists: (fileName) => fileMap.has(fileName),
|
||||
readFile: (fileName) => fileMap.has(fileName) ? fileMap.get(fileName).text : undefined,
|
||||
readFile: (fileName) => fileMap.has(fileName) ? fileMap.get(fileName)!.text : undefined,
|
||||
writeFile: (fileName, text) => outputs.set(fileName, text),
|
||||
};
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace ts {
|
||||
}
|
||||
const result = refactor.extractSymbol.getRangeToExtract(file, createTextSpanFromRange(selectionRange));
|
||||
assert(result.targetRange === undefined, "failure expected");
|
||||
const sortedErrors = result.errors.map(e => <string>e.messageText).sort();
|
||||
const sortedErrors = result.errors!.map(e => <string>e.messageText).sort();
|
||||
assert.deepEqual(sortedErrors, expectedErrors.sort(), "unexpected errors");
|
||||
});
|
||||
}
|
||||
@@ -27,13 +27,14 @@ namespace ts {
|
||||
const expectedRange = t.ranges.get("extracted");
|
||||
if (expectedRange) {
|
||||
let pos: number, end: number;
|
||||
if (isArray(result.targetRange.range)) {
|
||||
pos = result.targetRange.range[0].getStart(f);
|
||||
end = lastOrUndefined(result.targetRange.range).getEnd();
|
||||
const targetRange = result.targetRange!;
|
||||
if (isArray(targetRange.range)) {
|
||||
pos = targetRange.range[0].getStart(f);
|
||||
end = last(targetRange.range).getEnd();
|
||||
}
|
||||
else {
|
||||
pos = result.targetRange.range.getStart(f);
|
||||
end = result.targetRange.range.getEnd();
|
||||
pos = targetRange.range.getStart(f);
|
||||
end = targetRange.range.getEnd();
|
||||
}
|
||||
assert.equal(pos, expectedRange.pos, "incorrect pos of range");
|
||||
assert.equal(end, expectedRange.end, "incorrect end of range");
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace ts {
|
||||
const name = s === e
|
||||
? source.charCodeAt(saved + 1) === CharacterCodes.hash ? "selection" : "extracted"
|
||||
: source.substring(s, e);
|
||||
activeRanges.push({ name, pos: text.length, end: undefined });
|
||||
activeRanges.push({ name, pos: text.length, end: undefined! }); // TODO: GH#18217
|
||||
lastPos = pos;
|
||||
continue;
|
||||
}
|
||||
@@ -45,7 +45,7 @@ namespace ts {
|
||||
else if (source.charCodeAt(pos) === CharacterCodes.bar && source.charCodeAt(pos + 1) === CharacterCodes.closeBracket) {
|
||||
text += source.substring(lastPos, pos);
|
||||
activeRanges[activeRanges.length - 1].end = text.length;
|
||||
const range = activeRanges.pop();
|
||||
const range = activeRanges.pop()!;
|
||||
if (range.name in ranges) {
|
||||
throw new Error(`Duplicate name of range ${range.name}`);
|
||||
}
|
||||
@@ -100,7 +100,7 @@ namespace ts {
|
||||
|
||||
export function testExtractSymbol(caption: string, text: string, baselineFolder: string, description: DiagnosticMessage, includeLib?: boolean) {
|
||||
const t = extractTest(text);
|
||||
const selectionRange = t.ranges.get("selection");
|
||||
const selectionRange = t.ranges.get("selection")!;
|
||||
if (!selectionRange) {
|
||||
throw new Error(`Test ${caption} does not specify selection range`);
|
||||
}
|
||||
@@ -118,7 +118,7 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
|
||||
const sourceFile = program.getSourceFile(path);
|
||||
const sourceFile = program.getSourceFile(path)!;
|
||||
const context: RefactorContext = {
|
||||
cancellationToken: { throwIfCancellationRequested: noop, isCancellationRequested: returnFalse },
|
||||
program,
|
||||
@@ -131,15 +131,15 @@ namespace ts {
|
||||
};
|
||||
const rangeToExtract = refactor.extractSymbol.getRangeToExtract(sourceFile, createTextSpanFromRange(selectionRange));
|
||||
assert.equal(rangeToExtract.errors, undefined, rangeToExtract.errors && "Range error: " + rangeToExtract.errors[0].messageText);
|
||||
const infos = refactor.extractSymbol.getAvailableActions(context);
|
||||
const actions = find(infos, info => info.description === description.message).actions;
|
||||
const infos = refactor.extractSymbol.getAvailableActions(context)!;
|
||||
const actions = find(infos, info => info.description === description.message)!.actions;
|
||||
|
||||
Harness.Baseline.runBaseline(`${baselineFolder}/${caption}${extension}`, () => {
|
||||
const data: string[] = [];
|
||||
data.push(`// ==ORIGINAL==`);
|
||||
data.push(text.replace("[#|", "/*[#|*/").replace("|]", "/*|]*/"));
|
||||
for (const action of actions) {
|
||||
const { renameLocation, edits } = refactor.extractSymbol.getEditsForAction(context, action.name);
|
||||
const { renameLocation, edits } = refactor.extractSymbol.getEditsForAction(context, action.name)!;
|
||||
assert.lengthOf(edits, 1);
|
||||
data.push(`// ==SCOPE::${action.description}==`);
|
||||
const newText = textChanges.applyChanges(sourceFile.text, edits[0].textChanges);
|
||||
@@ -157,7 +157,7 @@ namespace ts {
|
||||
const host = projectSystem.createServerHost(includeLib ? [f, projectSystem.libFile] : [f]); // libFile is expensive to parse repeatedly - only test when required
|
||||
const projectService = projectSystem.createProjectService(host);
|
||||
projectService.openClientFile(f.path);
|
||||
const program = projectService.inferredProjects[0].getLanguageService().getProgram();
|
||||
const program = projectService.inferredProjects[0].getLanguageService().getProgram()!;
|
||||
return program;
|
||||
}
|
||||
|
||||
@@ -181,8 +181,8 @@ namespace ts {
|
||||
const host = projectSystem.createServerHost([f, projectSystem.libFile]);
|
||||
const projectService = projectSystem.createProjectService(host);
|
||||
projectService.openClientFile(f.path);
|
||||
const program = projectService.inferredProjects[0].getLanguageService().getProgram();
|
||||
const sourceFile = program.getSourceFile(f.path);
|
||||
const program = projectService.inferredProjects[0].getLanguageService().getProgram()!;
|
||||
const sourceFile = program.getSourceFile(f.path)!;
|
||||
const context: RefactorContext = {
|
||||
cancellationToken: { throwIfCancellationRequested: noop, isCancellationRequested: returnFalse },
|
||||
program,
|
||||
@@ -195,7 +195,7 @@ namespace ts {
|
||||
};
|
||||
const rangeToExtract = refactor.extractSymbol.getRangeToExtract(sourceFile, createTextSpanFromRange(selectionRange));
|
||||
assert.isUndefined(rangeToExtract.errors, rangeToExtract.errors && "Range error: " + rangeToExtract.errors[0].messageText);
|
||||
const infos = refactor.extractSymbol.getAvailableActions(context);
|
||||
const infos = refactor.extractSymbol.getAvailableActions(context)!;
|
||||
assert.isUndefined(find(infos, info => info.description === description.message));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
namespace ts {
|
||||
describe("hostNewLineSupport", () => {
|
||||
function testLSWithFiles(settings: CompilerOptions, files: Harness.Compiler.TestFile[]) {
|
||||
function snapFor(path: string): IScriptSnapshot {
|
||||
function snapFor(path: string): IScriptSnapshot | undefined {
|
||||
if (path === "lib.d.ts") {
|
||||
return ScriptSnapshot.fromString("");
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace ts {
|
||||
assert.isTrue(typeAndDiagnostics && typeAndDiagnostics.diagnostics.length === 0, "no errors issued");
|
||||
|
||||
Harness.Baseline.runBaseline("JSDocParsing/TypeExpressions.parsesCorrectly." + name + ".json",
|
||||
() => Utils.sourceFileToJSON(typeAndDiagnostics.jsDocTypeExpression.type));
|
||||
() => Utils.sourceFileToJSON(typeAndDiagnostics!.jsDocTypeExpression.type));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace ts {
|
||||
describe("DocComments", () => {
|
||||
function parsesCorrectly(name: string, content: string) {
|
||||
it(name, () => {
|
||||
const comment = parseIsolatedJSDocComment(content);
|
||||
const comment = parseIsolatedJSDocComment(content)!;
|
||||
if (!comment) {
|
||||
Debug.fail("Comment failed to parse entirely");
|
||||
}
|
||||
@@ -320,7 +320,7 @@ namespace ts {
|
||||
assert.equal(root.kind, SyntaxKind.SourceFile);
|
||||
const first = root.getFirstToken();
|
||||
assert.isDefined(first);
|
||||
assert.equal(first.kind, SyntaxKind.VarKeyword);
|
||||
assert.equal(first!.kind, SyntaxKind.VarKeyword);
|
||||
});
|
||||
});
|
||||
describe("getLastToken", () => {
|
||||
@@ -329,7 +329,7 @@ namespace ts {
|
||||
assert.isDefined(root);
|
||||
const last = root.getLastToken();
|
||||
assert.isDefined(last);
|
||||
assert.equal(last.kind, SyntaxKind.EndOfFileToken);
|
||||
assert.equal(last!.kind, SyntaxKind.EndOfFileToken);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/// <reference path="..\harness.ts" />
|
||||
|
||||
namespace ts {
|
||||
export function checkResolvedModule(expected: ResolvedModuleFull, actual: ResolvedModuleFull): boolean {
|
||||
export function checkResolvedModule(expected: ResolvedModuleFull | undefined, actual: ResolvedModuleFull): boolean {
|
||||
if (!expected === !actual) {
|
||||
if (expected) {
|
||||
assert.isTrue(expected.resolvedFileName === actual.resolvedFileName, `'resolvedFileName': expected '${expected.resolvedFileName}' to be equal to '${actual.resolvedFileName}'`);
|
||||
@@ -71,7 +71,7 @@ namespace ts {
|
||||
return file && file.content;
|
||||
}
|
||||
function realpath(path: string): string {
|
||||
return map.get(path).name;
|
||||
return map.get(path)!.name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,7 +332,7 @@ namespace ts {
|
||||
getSourceFile: (fileName: string, languageVersion: ScriptTarget) => {
|
||||
const path = normalizePath(combinePaths(currentDirectory, fileName));
|
||||
const file = files.get(path);
|
||||
return file && createSourceFile(fileName, file, languageVersion);
|
||||
return file ? createSourceFile(fileName, file, languageVersion) : undefined;
|
||||
},
|
||||
getDefaultLibFileName: () => "lib.d.ts",
|
||||
writeFile: notImplemented,
|
||||
@@ -420,7 +420,7 @@ export = C;
|
||||
}
|
||||
const path = getCanonicalFileName(normalizePath(combinePaths(currentDirectory, fileName)));
|
||||
const file = files.get(path);
|
||||
return file && createSourceFile(fileName, file, languageVersion);
|
||||
return file ? createSourceFile(fileName, file, languageVersion) : undefined;
|
||||
},
|
||||
getDefaultLibFileName: () => "lib.d.ts",
|
||||
writeFile: notImplemented,
|
||||
@@ -975,9 +975,9 @@ import b = require("./moduleB");
|
||||
function test(typesRoot: string, typeDirective: string, primary: boolean, initialFile: File, targetFile: File, ...otherFiles: File[]) {
|
||||
const host = createModuleResolutionHost(/*hasDirectoryExists*/ false, ...[initialFile, targetFile].concat(...otherFiles));
|
||||
const result = resolveTypeReferenceDirective(typeDirective, initialFile.name, { typeRoots: [typesRoot] }, host);
|
||||
assert(result.resolvedTypeReferenceDirective.resolvedFileName !== undefined, "expected type directive to be resolved");
|
||||
assert.equal(result.resolvedTypeReferenceDirective.resolvedFileName, targetFile.name, "unexpected result of type reference resolution");
|
||||
assert.equal(result.resolvedTypeReferenceDirective.primary, primary, "unexpected 'primary' value");
|
||||
assert(result.resolvedTypeReferenceDirective!.resolvedFileName !== undefined, "expected type directive to be resolved");
|
||||
assert.equal(result.resolvedTypeReferenceDirective!.resolvedFileName, targetFile.name, "unexpected result of type reference resolution");
|
||||
assert.equal(result.resolvedTypeReferenceDirective!.primary, primary, "unexpected 'primary' value");
|
||||
}
|
||||
|
||||
it("Can be resolved from primary location", () => {
|
||||
@@ -1111,10 +1111,7 @@ import b = require("./moduleB");
|
||||
getNewLine: () => "\r\n",
|
||||
useCaseSensitiveFileNames: () => false,
|
||||
readFile: fileName => fileName === file.fileName ? file.text : undefined,
|
||||
resolveModuleNames() {
|
||||
assert(false, "resolveModuleNames should not be called");
|
||||
return undefined;
|
||||
}
|
||||
resolveModuleNames: notImplemented,
|
||||
};
|
||||
createProgram([f.name], {}, compilerHost);
|
||||
});
|
||||
@@ -1145,7 +1142,7 @@ import b = require("./moduleB");
|
||||
readFile: fileName => fileName === file.fileName ? file.text : undefined,
|
||||
resolveModuleNames(moduleNames: string[], _containingFile: string) {
|
||||
assert.deepEqual(moduleNames, ["fs"]);
|
||||
return [undefined];
|
||||
return [undefined!]; // TODO: GH#18217
|
||||
}
|
||||
};
|
||||
createProgram([f.name], {}, compilerHost);
|
||||
|
||||
@@ -136,7 +136,7 @@ namespace ts.projectSystem {
|
||||
projectService.openClientFile(file1.path);
|
||||
{
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
const configuredProject = forEach(projectService.synchronizeProjectList([]), f => f.info.projectName === corruptedConfig.path && f);
|
||||
const configuredProject = find(projectService.synchronizeProjectList([]), f => f.info!.projectName === corruptedConfig.path)!;
|
||||
assert.isTrue(configuredProject !== undefined, "should find configured project");
|
||||
checkProjectErrors(configuredProject, []);
|
||||
const projectErrors = configuredProjectAt(projectService, 0).getAllProjectErrors();
|
||||
@@ -144,13 +144,13 @@ namespace ts.projectSystem {
|
||||
"'{' expected."
|
||||
]);
|
||||
assert.isNotNull(projectErrors[0].file);
|
||||
assert.equal(projectErrors[0].file.fileName, corruptedConfig.path);
|
||||
assert.equal(projectErrors[0].file!.fileName, corruptedConfig.path);
|
||||
}
|
||||
// fix config and trigger watcher
|
||||
host.reloadFS([file1, file2, correctConfig]);
|
||||
{
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
const configuredProject = forEach(projectService.synchronizeProjectList([]), f => f.info.projectName === corruptedConfig.path && f);
|
||||
const configuredProject = find(projectService.synchronizeProjectList([]), f => f.info!.projectName === corruptedConfig.path)!;
|
||||
assert.isTrue(configuredProject !== undefined, "should find configured project");
|
||||
checkProjectErrors(configuredProject, []);
|
||||
const projectErrors = configuredProjectAt(projectService, 0).getAllProjectErrors();
|
||||
@@ -181,7 +181,7 @@ namespace ts.projectSystem {
|
||||
projectService.openClientFile(file1.path);
|
||||
{
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
const configuredProject = forEach(projectService.synchronizeProjectList([]), f => f.info.projectName === corruptedConfig.path && f);
|
||||
const configuredProject = find(projectService.synchronizeProjectList([]), f => f.info!.projectName === corruptedConfig.path)!;
|
||||
assert.isTrue(configuredProject !== undefined, "should find configured project");
|
||||
checkProjectErrors(configuredProject, []);
|
||||
const projectErrors = configuredProjectAt(projectService, 0).getAllProjectErrors();
|
||||
@@ -191,7 +191,7 @@ namespace ts.projectSystem {
|
||||
host.reloadFS([file1, file2, corruptedConfig]);
|
||||
{
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
const configuredProject = forEach(projectService.synchronizeProjectList([]), f => f.info.projectName === corruptedConfig.path && f);
|
||||
const configuredProject = find(projectService.synchronizeProjectList([]), f => f.info!.projectName === corruptedConfig.path)!;
|
||||
assert.isTrue(configuredProject !== undefined, "should find configured project");
|
||||
checkProjectErrors(configuredProject, []);
|
||||
const projectErrors = configuredProjectAt(projectService, 0).getAllProjectErrors();
|
||||
@@ -199,7 +199,7 @@ namespace ts.projectSystem {
|
||||
"'{' expected."
|
||||
]);
|
||||
assert.isNotNull(projectErrors[0].file);
|
||||
assert.equal(projectErrors[0].file.fileName, corruptedConfig.path);
|
||||
assert.equal(projectErrors[0].file!.fileName, corruptedConfig.path);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
const vfsys = new vfs.FileSystem(false, { files: { "/lib.d.ts": TestFSWithWatch.libFile.content! } });
|
||||
const vfsys = new vfs.FileSystem(false, { files: { "/lib.d.ts": TestFSWithWatch.libFile.content } });
|
||||
files.forEach((v, k) => {
|
||||
vfsys.mkdirpSync(getDirectoryPath(k));
|
||||
vfsys.writeFileSync(k, v);
|
||||
|
||||
@@ -6,7 +6,7 @@ describe("Public APIs", () => {
|
||||
const api = `api/${fileName}`;
|
||||
let fileContent: string;
|
||||
before(() => {
|
||||
fileContent = Harness.IO.readFile(builtFile);
|
||||
fileContent = Harness.IO.readFile(builtFile)!;
|
||||
});
|
||||
|
||||
it("should be acknowledged when they change", () => {
|
||||
|
||||
@@ -93,7 +93,7 @@ namespace ts {
|
||||
newLength = this.program.length;
|
||||
break;
|
||||
default:
|
||||
Debug.assert(false, "Unexpected change");
|
||||
return Debug.fail("Unexpected change");
|
||||
}
|
||||
|
||||
return createTextChangeRange(oldSpan, newLength);
|
||||
@@ -114,7 +114,7 @@ namespace ts {
|
||||
if (oldFile && oldFile.redirectInfo) {
|
||||
oldFile = oldFile.redirectInfo.unredirected;
|
||||
}
|
||||
if (oldFile && oldFile.sourceText.getVersion() === t.text.getVersion()) {
|
||||
if (oldFile && oldFile.sourceText!.getVersion() === t.text.getVersion()) {
|
||||
return oldFile;
|
||||
}
|
||||
}
|
||||
@@ -126,7 +126,7 @@ namespace ts {
|
||||
trace: s => trace.push(s),
|
||||
getTrace: () => trace,
|
||||
getSourceFile(fileName): SourceFile {
|
||||
return files.get(fileName);
|
||||
return files.get(fileName)!;
|
||||
},
|
||||
getDefaultLibFileName(): string {
|
||||
return "lib.d.ts";
|
||||
@@ -156,7 +156,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function newProgram(texts: NamedSourceText[], rootNames: string[], options: CompilerOptions): ProgramWithSourceTexts {
|
||||
const host = createTestCompilerHost(texts, options.target);
|
||||
const host = createTestCompilerHost(texts, options.target!);
|
||||
const program = <ProgramWithSourceTexts>createProgram(rootNames, options, host);
|
||||
program.sourceTexts = texts;
|
||||
program.host = host;
|
||||
@@ -165,10 +165,10 @@ namespace ts {
|
||||
|
||||
export function updateProgram(oldProgram: ProgramWithSourceTexts, rootNames: ReadonlyArray<string>, options: CompilerOptions, updater: (files: NamedSourceText[]) => void, newTexts?: NamedSourceText[]) {
|
||||
if (!newTexts) {
|
||||
newTexts = oldProgram.sourceTexts.slice(0);
|
||||
newTexts = oldProgram.sourceTexts!.slice(0);
|
||||
}
|
||||
updater(newTexts);
|
||||
const host = createTestCompilerHost(newTexts, options.target, oldProgram);
|
||||
const host = createTestCompilerHost(newTexts, options.target!, oldProgram);
|
||||
const program = <ProgramWithSourceTexts>createProgram(rootNames, options, host, oldProgram);
|
||||
program.sourceTexts = newTexts;
|
||||
program.host = host;
|
||||
@@ -191,16 +191,16 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkCache<T>(caption: string, program: Program, fileName: string, expectedContent: Map<T>, getCache: (f: SourceFile) => Map<T>, entryChecker: (expected: T, original: T) => boolean): void {
|
||||
function checkCache<T>(caption: string, program: Program, fileName: string, expectedContent: Map<T> | undefined, getCache: (f: SourceFile) => Map<T> | undefined, entryChecker: (expected: T, original: T) => boolean): void {
|
||||
const file = program.getSourceFile(fileName);
|
||||
assert.isTrue(file !== undefined, `cannot find file ${fileName}`);
|
||||
const cache = getCache(file);
|
||||
const cache = getCache(file!);
|
||||
if (expectedContent === undefined) {
|
||||
assert.isTrue(cache === undefined, `expected ${caption} to be undefined`);
|
||||
}
|
||||
else {
|
||||
assert.isTrue(cache !== undefined, `expected ${caption} to be set`);
|
||||
assert.isTrue(mapsAreEqual(expectedContent, cache, entryChecker), `contents of ${caption} did not match the expected contents.`);
|
||||
assert.isTrue(mapsAreEqual(expectedContent, cache!, entryChecker), `contents of ${caption} did not match the expected contents.`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ namespace ts {
|
||||
if (!left || !right) return false;
|
||||
const someInLeftHasNoMatch = forEachEntry(left, (leftValue, leftKey) => {
|
||||
if (!right.has(leftKey)) return true;
|
||||
const rightValue = right.get(leftKey);
|
||||
const rightValue = right.get(leftKey)!;
|
||||
return !(valuesAreEqual ? valuesAreEqual(leftValue, rightValue) : leftValue === rightValue);
|
||||
});
|
||||
if (someInLeftHasNoMatch) return false;
|
||||
@@ -218,11 +218,11 @@ namespace ts {
|
||||
return !someInRightHasNoMatch;
|
||||
}
|
||||
|
||||
function checkResolvedModulesCache(program: Program, fileName: string, expectedContent: Map<ResolvedModule>): void {
|
||||
function checkResolvedModulesCache(program: Program, fileName: string, expectedContent: Map<ResolvedModule | undefined> | undefined): void {
|
||||
checkCache("resolved modules", program, fileName, expectedContent, f => f.resolvedModules, checkResolvedModule);
|
||||
}
|
||||
|
||||
function checkResolvedTypeDirectivesCache(program: Program, fileName: string, expectedContent: Map<ResolvedTypeReferenceDirective>): void {
|
||||
function checkResolvedTypeDirectivesCache(program: Program, fileName: string, expectedContent: Map<ResolvedTypeReferenceDirective> | undefined): void {
|
||||
checkCache("resolved type directives", program, fileName, expectedContent, f => f.resolvedTypeReferenceDirectiveNames, checkResolvedTypeDirective);
|
||||
}
|
||||
|
||||
@@ -399,7 +399,7 @@ namespace ts {
|
||||
const program2 = updateProgram(program1, ["/a.ts"], options, files => {
|
||||
files[0].text = files[0].text.updateProgram('import * as aa from "a";');
|
||||
});
|
||||
assert.isDefined(program2.getSourceFile("/a.ts").resolvedModules.get("a"), "'a' is not an unresolved module after re-use");
|
||||
assert.isDefined(program2.getSourceFile("/a.ts")!.resolvedModules!.get("a"), "'a' is not an unresolved module after re-use");
|
||||
});
|
||||
|
||||
it("resolved type directives cache follows type directives", () => {
|
||||
@@ -896,7 +896,7 @@ namespace ts {
|
||||
) {
|
||||
const actual = isProgramUptoDate(
|
||||
program, newRootFileNames, newOptions,
|
||||
path => program.getSourceFileByPath(path).version, /*fileExists*/ returnFalse,
|
||||
path => program.getSourceFileByPath(path)!.version, /*fileExists*/ returnFalse,
|
||||
/*hasInvalidatedResolution*/ returnFalse,
|
||||
/*hasChangedAutomaticTypeDirectiveNames*/ false
|
||||
);
|
||||
@@ -916,7 +916,7 @@ namespace ts {
|
||||
|
||||
function verifyProgramWithConfigFile(system: System, configFileName: string) {
|
||||
const program = createWatchProgram(createWatchCompilerHostOfConfigFile(configFileName, {}, system)).getCurrentProgram().getProgram();
|
||||
const { fileNames, options } = parseConfigFileWithSystem(configFileName, {}, system, notImplemented);
|
||||
const { fileNames, options } = parseConfigFileWithSystem(configFileName, {}, system, notImplemented)!; // TODO: GH#18217
|
||||
verifyProgramIsUptoDate(program, fileNames, options);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ describe("Colorization", () => {
|
||||
function identifier(text: string, position?: number) { return createClassification(text, ts.TokenClass.Identifier, position); }
|
||||
function numberLiteral(text: string, position?: number) { return createClassification(text, ts.TokenClass.NumberLiteral, position); }
|
||||
function stringLiteral(text: string, position?: number) { return createClassification(text, ts.TokenClass.StringLiteral, position); }
|
||||
function finalEndOfLineState(value: number): ClassificationEntry { return { value, classification: undefined, position: 0 }; }
|
||||
function finalEndOfLineState(value: number): ClassificationEntry { return { value, classification: undefined!, position: 0 }; } // TODO: GH#18217
|
||||
function createClassification(value: string, classification: ts.TokenClass, position?: number): ClassificationEntry {
|
||||
return { value, classification, position };
|
||||
}
|
||||
@@ -48,7 +48,7 @@ describe("Colorization", () => {
|
||||
const actualEntryPosition = expectedEntry.position !== undefined ? expectedEntry.position : text.indexOf(expectedEntry.value);
|
||||
assert(actualEntryPosition >= 0, "token: '" + expectedEntry.value + "' does not exit in text: '" + text + "'.");
|
||||
|
||||
const actualEntry = getEntryAtPosition(result, actualEntryPosition);
|
||||
const actualEntry = getEntryAtPosition(result, actualEntryPosition)!;
|
||||
|
||||
assert(actualEntry, "Could not find classification entry for '" + expectedEntry.value + "' at position: " + actualEntryPosition);
|
||||
assert.equal(actualEntry.classification, expectedEntry.classification, "Classification class does not match expected. Expected: " + ts.TokenClass[expectedEntry.classification] + ", Actual: " + ts.TokenClass[actualEntry.classification]);
|
||||
@@ -351,7 +351,7 @@ describe("Colorization", () => {
|
||||
pos += lastLength;
|
||||
lastLength = val.length;
|
||||
}
|
||||
return ts.lastOrUndefined(vals);
|
||||
return ts.last(vals);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -321,7 +321,7 @@ describe("PatternMatcher", () => {
|
||||
});
|
||||
|
||||
function assertSegmentMatch(candidate: string, pattern: string, expected: ts.PatternMatch | undefined): void {
|
||||
assert.deepEqual(ts.createPatternMatcher(pattern).getMatchForLastSegmentOfPattern(candidate), expected);
|
||||
assert.deepEqual(ts.createPatternMatcher(pattern)!.getMatchForLastSegmentOfPattern(candidate), expected);
|
||||
}
|
||||
|
||||
function assertInvalidPattern(pattern: string) {
|
||||
@@ -329,7 +329,7 @@ describe("PatternMatcher", () => {
|
||||
}
|
||||
|
||||
function assertFullMatch(dottedContainer: string, candidate: string, pattern: string, expected: ts.PatternMatch | undefined): void {
|
||||
assert.deepEqual(ts.createPatternMatcher(pattern).getFullMatch(dottedContainer.split("."), candidate), expected);
|
||||
assert.deepEqual(ts.createPatternMatcher(pattern)!.getFullMatch(dottedContainer.split("."), candidate), expected);
|
||||
}
|
||||
|
||||
function spanListToSubstrings(identifier: string, spans: ts.TextSpan[]) {
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace ts.server {
|
||||
write(s): void { lastWrittenToHost = s; },
|
||||
readFile: () => undefined,
|
||||
writeFile: noop,
|
||||
resolvePath(): string { return void 0; },
|
||||
resolvePath(): string { return undefined!; }, // TODO: GH#18217
|
||||
fileExists: () => false,
|
||||
directoryExists: () => false,
|
||||
getDirectories: () => [],
|
||||
@@ -47,7 +47,7 @@ namespace ts.server {
|
||||
cancellationToken: nullCancellationToken,
|
||||
useSingleInferredProject: false,
|
||||
useInferredProjectPerProjectRoot: false,
|
||||
typingsInstaller: undefined,
|
||||
typingsInstaller: undefined!, // TODO: GH#18217
|
||||
byteLength: Utils.byteLength,
|
||||
hrtime: process.hrtime,
|
||||
logger: projectSystem.nullLogger,
|
||||
@@ -81,7 +81,7 @@ namespace ts.server {
|
||||
seq: 0,
|
||||
type: "request",
|
||||
arguments: {
|
||||
file: undefined
|
||||
file: undefined! // TODO: GH#18217
|
||||
}
|
||||
};
|
||||
|
||||
@@ -441,7 +441,7 @@ namespace ts.server {
|
||||
lastSent: protocol.Message;
|
||||
private exceptionRaisingHandler(_request: protocol.Request): { response?: any, responseRequired: boolean } {
|
||||
f1();
|
||||
return;
|
||||
return Debug.fail(); // unreachable, throw to make compiler happy
|
||||
function f1() {
|
||||
throw new Error("myMessage");
|
||||
}
|
||||
@@ -453,7 +453,7 @@ namespace ts.server {
|
||||
cancellationToken: nullCancellationToken,
|
||||
useSingleInferredProject: false,
|
||||
useInferredProjectPerProjectRoot: false,
|
||||
typingsInstaller: undefined,
|
||||
typingsInstaller: undefined!, // TODO: GH#18217
|
||||
byteLength: Utils.byteLength,
|
||||
hrtime: process.hrtime,
|
||||
logger: projectSystem.nullLogger,
|
||||
@@ -500,7 +500,7 @@ namespace ts.server {
|
||||
cancellationToken: nullCancellationToken,
|
||||
useSingleInferredProject: false,
|
||||
useInferredProjectPerProjectRoot: false,
|
||||
typingsInstaller: undefined,
|
||||
typingsInstaller: undefined!, // TODO: GH#18217
|
||||
byteLength: Utils.byteLength,
|
||||
hrtime: process.hrtime,
|
||||
logger: projectSystem.nullLogger,
|
||||
@@ -568,7 +568,7 @@ namespace ts.server {
|
||||
cancellationToken: nullCancellationToken,
|
||||
useSingleInferredProject: false,
|
||||
useInferredProjectPerProjectRoot: false,
|
||||
typingsInstaller: undefined,
|
||||
typingsInstaller: undefined!, // TODO: GH#18217
|
||||
byteLength: Utils.byteLength,
|
||||
hrtime: process.hrtime,
|
||||
logger: projectSystem.nullLogger,
|
||||
@@ -604,7 +604,7 @@ namespace ts.server {
|
||||
|
||||
consumeQueue() {
|
||||
while (this.queue.length > 0) {
|
||||
const elem = this.queue.pop();
|
||||
const elem = this.queue.pop()!;
|
||||
this.handleRequest(elem);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ namespace ts {
|
||||
unitName: "main.ts",
|
||||
content: source
|
||||
}], [], {}, {}, "/");
|
||||
const file = result.program.getSourceFile("main.ts");
|
||||
const checker = result.program.getTypeChecker();
|
||||
const file = result.program!.getSourceFile("main.ts")!;
|
||||
const checker = result.program!.getTypeChecker();
|
||||
verifier(file, checker);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
namespace ts {
|
||||
describe("textChanges", () => {
|
||||
function findChild(name: string, n: Node) {
|
||||
return find(n);
|
||||
return find(n)!;
|
||||
|
||||
function find(node: Node): Node {
|
||||
function find(node: Node): Node | undefined {
|
||||
if (isDeclaration(node) && node.name && isIdentifier(node.name) && node.name.escapedText === name) {
|
||||
return node;
|
||||
}
|
||||
@@ -88,7 +88,7 @@ namespace M
|
||||
}
|
||||
}`;
|
||||
runSingleFileTest("extractMethodLike", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
const statements = (<FunctionDeclaration>findChild("foo", sourceFile)).body.statements.slice(1);
|
||||
const statements = (<FunctionDeclaration>findChild("foo", sourceFile)).body!.statements.slice(1);
|
||||
const newFunction = createFunctionDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
@@ -105,11 +105,11 @@ namespace M
|
||||
// replace statements with return statement
|
||||
const newStatement = createReturn(
|
||||
createCall(
|
||||
/*expression*/ newFunction.name,
|
||||
/*expression*/ newFunction.name!,
|
||||
/*typeArguments*/ undefined,
|
||||
/*argumentsArray*/ emptyArray
|
||||
));
|
||||
changeTracker.replaceNodeRange(sourceFile, statements[0], lastOrUndefined(statements), newStatement, { suffix: newLineCharacter });
|
||||
changeTracker.replaceNodeRange(sourceFile, statements[0], last(statements), newStatement, { suffix: newLineCharacter });
|
||||
});
|
||||
}
|
||||
{
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace ts {
|
||||
return (sourceFile: SourceFile) => {
|
||||
const result = getMutableClone(sourceFile);
|
||||
result.statements = createNodeArray([
|
||||
createClassDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, "Foo", /*typeParameters*/ undefined, /*heritageClauses*/ undefined, /*members*/ undefined),
|
||||
createClassDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, "Foo", /*typeParameters*/ undefined, /*heritageClauses*/ undefined, /*members*/ undefined!), // TODO: GH#18217
|
||||
createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createIdentifier("Foo"), createModuleBlock([createEmptyStatement()]))
|
||||
]);
|
||||
return result;
|
||||
@@ -266,7 +266,7 @@ namespace ts {
|
||||
function baselineDeclarationTransform(text: string, opts: TranspileOptions) {
|
||||
const fs = vfs.createFromFileSystem(Harness.IO, /*caseSensitive*/ true, { documents: [new documents.TextDocument("/.src/index.ts", text)] });
|
||||
const host = new fakes.CompilerHost(fs, opts.compilerOptions);
|
||||
const program = createProgram(["/.src/index.ts"], opts.compilerOptions, host);
|
||||
const program = createProgram(["/.src/index.ts"], opts.compilerOptions!, host);
|
||||
program.emit(program.getSourceFiles()[1], (p, s, bom) => host.writeFile(p, s, bom), /*cancellationToken*/ undefined, /*onlyDts*/ true, opts.transformers);
|
||||
return fs.readFileSync("/.src/index.d.ts").toString();
|
||||
}
|
||||
|
||||
@@ -53,20 +53,20 @@ namespace ts {
|
||||
});
|
||||
|
||||
after(() => {
|
||||
transpileResult = undefined;
|
||||
oldTranspileResult = undefined;
|
||||
oldTranspileDiagnostics = undefined;
|
||||
transpileResult = undefined!;
|
||||
oldTranspileResult = undefined!;
|
||||
oldTranspileDiagnostics = undefined!;
|
||||
});
|
||||
|
||||
it("Correct errors for " + justName, () => {
|
||||
Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, ".errors.txt"), () => {
|
||||
if (transpileResult.diagnostics.length === 0) {
|
||||
if (transpileResult.diagnostics!.length === 0) {
|
||||
/* tslint:disable:no-null-keyword */
|
||||
return null;
|
||||
/* tslint:enable:no-null-keyword */
|
||||
}
|
||||
|
||||
return Harness.Compiler.getErrorBaseline(toBeCompiled, transpileResult.diagnostics);
|
||||
return Harness.Compiler.getErrorBaseline(toBeCompiled, transpileResult.diagnostics!);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ namespace ts.tscWatch {
|
||||
assert.equal(host.exitCode, expectedExitCode);
|
||||
}
|
||||
|
||||
function getDiagnosticOfFileFrom(file: SourceFile, text: string, start: number, length: number, message: DiagnosticMessage): Diagnostic {
|
||||
function getDiagnosticOfFileFrom(file: SourceFile | undefined, text: string, start: number | undefined, length: number | undefined, message: DiagnosticMessage): Diagnostic {
|
||||
return {
|
||||
file,
|
||||
start,
|
||||
@@ -205,7 +205,7 @@ namespace ts.tscWatch {
|
||||
|
||||
function getUnknownCompilerOption(program: Program, configFile: File, option: string) {
|
||||
const quotedOption = `"${option}"`;
|
||||
return getDiagnosticOfFile(program.getCompilerOptions().configFile, configFile.content.indexOf(quotedOption), quotedOption.length, Diagnostics.Unknown_compiler_option_0, option);
|
||||
return getDiagnosticOfFile(program.getCompilerOptions().configFile!, configFile.content.indexOf(quotedOption), quotedOption.length, Diagnostics.Unknown_compiler_option_0, option);
|
||||
}
|
||||
|
||||
function getDiagnosticOfFileFromProgram(program: Program, filePath: string, start: number, length: number, message: DiagnosticMessage, ..._args: (string | number)[]): Diagnostic {
|
||||
@@ -215,7 +215,7 @@ namespace ts.tscWatch {
|
||||
text = formatStringFromArgs(text, arguments, 5);
|
||||
}
|
||||
|
||||
return getDiagnosticOfFileFrom(program.getSourceFileByPath(toPath(filePath, program.getCurrentDirectory(), s => s.toLowerCase())),
|
||||
return getDiagnosticOfFileFrom(program.getSourceFileByPath(toPath(filePath, program.getCurrentDirectory(), s => s.toLowerCase()))!,
|
||||
text, start, length, message);
|
||||
}
|
||||
|
||||
@@ -1101,8 +1101,8 @@ namespace ts.tscWatch {
|
||||
const host = createWatchedSystem(files);
|
||||
const watch = createWatchOfConfigFile(configFile.path, host);
|
||||
const errors = () => [
|
||||
getDiagnosticOfFile(watch().getCompilerOptions().configFile, configFile.content.indexOf('"allowJs"'), '"allowJs"'.length, Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration"),
|
||||
getDiagnosticOfFile(watch().getCompilerOptions().configFile, configFile.content.indexOf('"declaration"'), '"declaration"'.length, Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration")
|
||||
getDiagnosticOfFile(watch().getCompilerOptions().configFile!, configFile.content.indexOf('"allowJs"'), '"allowJs"'.length, Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration"),
|
||||
getDiagnosticOfFile(watch().getCompilerOptions().configFile!, configFile.content.indexOf('"declaration"'), '"declaration"'.length, Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration")
|
||||
];
|
||||
const intialErrors = errors();
|
||||
checkOutputErrorsInitial(host, intialErrors);
|
||||
@@ -1112,8 +1112,8 @@ namespace ts.tscWatch {
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
const nowErrors = errors();
|
||||
checkOutputErrorsIncremental(host, nowErrors);
|
||||
assert.equal(nowErrors[0].start, intialErrors[0].start - configFileContentComment.length);
|
||||
assert.equal(nowErrors[1].start, intialErrors[1].start - configFileContentComment.length);
|
||||
assert.equal(nowErrors[0].start, intialErrors[0].start! - configFileContentComment.length);
|
||||
assert.equal(nowErrors[1].start, intialErrors[1].start! - configFileContentComment.length);
|
||||
});
|
||||
|
||||
it("should not trigger recompilation because of program emit", () => {
|
||||
@@ -1409,7 +1409,7 @@ namespace ts.tscWatch {
|
||||
}
|
||||
|
||||
function getFile(fileName: string) {
|
||||
return find(files, file => file.path === fileName);
|
||||
return find(files, file => file.path === fileName)!;
|
||||
}
|
||||
|
||||
function verifyAffectedAllFiles() {
|
||||
@@ -2252,7 +2252,7 @@ declare module "fs" {
|
||||
const disableConsoleClear = options.diagnostics || options.extendedDiagnostics || options.preserveWatchOutput;
|
||||
const host = createWatchedSystem(files);
|
||||
createWatchOfFilesAndCompilerOptions([file.path], host, options);
|
||||
checkOutputErrorsInitial(host, emptyArray, disableConsoleClear, options.extendedDiagnostics && [
|
||||
checkOutputErrorsInitial(host, emptyArray, disableConsoleClear, options.extendedDiagnostics ? [
|
||||
"Current directory: / CaseSensitiveFileNames: false\n",
|
||||
"Synchronizing program\n",
|
||||
"CreatingProgramWith::\n",
|
||||
@@ -2260,21 +2260,21 @@ declare module "fs" {
|
||||
" options: {\"extendedDiagnostics\":true}\n",
|
||||
"FileWatcher:: Added:: WatchInfo: f.ts 250 Source file\n",
|
||||
"FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 250 Source file\n"
|
||||
]);
|
||||
] : undefined);
|
||||
|
||||
file.content = "//";
|
||||
host.reloadFS(files);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
checkOutputErrorsIncremental(host, emptyArray, disableConsoleClear, options.extendedDiagnostics && [
|
||||
checkOutputErrorsIncremental(host, emptyArray, disableConsoleClear, options.extendedDiagnostics ? [
|
||||
"FileWatcher:: Triggered with /f.ts1:: WatchInfo: f.ts 250 Source file\n",
|
||||
"Scheduling update\n",
|
||||
"Elapsed:: 0ms FileWatcher:: Triggered with /f.ts1:: WatchInfo: f.ts 250 Source file\n"
|
||||
], options.extendedDiagnostics && [
|
||||
] : undefined, options.extendedDiagnostics ? [
|
||||
"Synchronizing program\n",
|
||||
"CreatingProgramWith::\n",
|
||||
" roots: [\"f.ts\"]\n",
|
||||
" options: {\"extendedDiagnostics\":true}\n"
|
||||
]);
|
||||
] : undefined);
|
||||
}
|
||||
|
||||
it("without --diagnostics or --extendedDiagnostics", () => {
|
||||
|
||||
@@ -135,11 +135,12 @@ namespace ts {
|
||||
const parsed = parseConfigFileTextToJson("/apath/tsconfig.json", "invalid");
|
||||
assert.deepEqual(parsed.config, { invalid: undefined });
|
||||
const expected = createCompilerDiagnostic(Diagnostics._0_expected, "{");
|
||||
assert.equal(parsed.error.messageText, expected.messageText);
|
||||
assert.equal(parsed.error.category, expected.category);
|
||||
assert.equal(parsed.error.code, expected.code);
|
||||
assert.equal(parsed.error.start, 0);
|
||||
assert.equal(parsed.error.length, "invalid".length);
|
||||
const error = parsed.error!;
|
||||
assert.equal(error.messageText, expected.messageText);
|
||||
assert.equal(error.category, expected.category);
|
||||
assert.equal(error.code, expected.code);
|
||||
assert.equal(error.start, 0);
|
||||
assert.equal(error.length, "invalid".length);
|
||||
});
|
||||
|
||||
it("returns object when users correctly specify library", () => {
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace ts.projectSystem {
|
||||
msg: noop,
|
||||
startGroup: noop,
|
||||
endGroup: noop,
|
||||
getLogFileName: (): string => undefined
|
||||
getLogFileName: () => undefined,
|
||||
};
|
||||
|
||||
export class TestTypingsInstaller extends TI.TypingsInstaller implements server.ITypingsInstaller {
|
||||
@@ -189,7 +189,7 @@ namespace ts.projectSystem {
|
||||
}
|
||||
|
||||
getEvent<T extends server.ProjectServiceEvent>(eventName: T["eventName"]): T["data"] {
|
||||
let eventData: T["data"];
|
||||
let eventData: T["data"] | undefined;
|
||||
filterMutate(this.events, e => {
|
||||
if (e.eventName === eventName) {
|
||||
if (eventData !== undefined) {
|
||||
@@ -200,8 +200,7 @@ namespace ts.projectSystem {
|
||||
}
|
||||
return true;
|
||||
});
|
||||
assert.isDefined(eventData);
|
||||
return eventData;
|
||||
return Debug.assertDefined(eventData);
|
||||
}
|
||||
|
||||
hasZeroEvent<T extends server.ProjectServiceEvent>(eventName: T["eventName"]) {
|
||||
@@ -216,7 +215,7 @@ namespace ts.projectSystem {
|
||||
|
||||
assertProjectInfoTelemetryEvent(partial: Partial<server.ProjectInfoTelemetryEventData>, configFile = "/tsconfig.json"): void {
|
||||
assert.deepEqual<server.ProjectInfoTelemetryEventData>(this.getEvent<server.ProjectInfoTelemetryEvent>(server.ProjectInfoTelemetryEvent), {
|
||||
projectId: sys.createSHA256Hash(configFile),
|
||||
projectId: sys.createSHA256Hash!(configFile),
|
||||
fileStats: fileStats({ ts: 1 }),
|
||||
compilerOptions: {},
|
||||
extends: false,
|
||||
@@ -294,7 +293,7 @@ namespace ts.projectSystem {
|
||||
cancellationToken: server.nullCancellationToken,
|
||||
useSingleInferredProject: false,
|
||||
useInferredProjectPerProjectRoot: false,
|
||||
typingsInstaller: undefined,
|
||||
typingsInstaller: undefined!, // TODO: GH#18217
|
||||
byteLength: Utils.byteLength,
|
||||
hrtime: process.hrtime,
|
||||
logger: opts.logger || nullLogger,
|
||||
@@ -336,7 +335,7 @@ namespace ts.projectSystem {
|
||||
const cancellationToken = parameters.cancellationToken || server.nullCancellationToken;
|
||||
const logger = parameters.logger || nullLogger;
|
||||
const useSingleInferredProject = parameters.useSingleInferredProject !== undefined ? parameters.useSingleInferredProject : false;
|
||||
return new TestProjectService(host, logger, cancellationToken, useSingleInferredProject, parameters.typingsInstaller, parameters.eventHandler, options);
|
||||
return new TestProjectService(host, logger, cancellationToken, useSingleInferredProject, parameters.typingsInstaller!, parameters.eventHandler!, options); // TODO: GH#18217
|
||||
}
|
||||
|
||||
export function checkNumberOfConfiguredProjects(projectService: server.ProjectService, expected: number) {
|
||||
@@ -404,7 +403,7 @@ namespace ts.projectSystem {
|
||||
}
|
||||
|
||||
function checkOpenFiles(projectService: server.ProjectService, expectedFiles: File[]) {
|
||||
checkArray("Open files", arrayFrom(projectService.openFiles.keys(), path => projectService.getScriptInfoForPath(path as Path).fileName), expectedFiles.map(file => file.path));
|
||||
checkArray("Open files", arrayFrom(projectService.openFiles.keys(), path => projectService.getScriptInfoForPath(path as Path)!.fileName), expectedFiles.map(file => file.path));
|
||||
}
|
||||
|
||||
function textSpanFromSubstring(str: string, substring: string): TextSpan {
|
||||
@@ -420,7 +419,7 @@ namespace ts.projectSystem {
|
||||
* setRequestToCancel();
|
||||
*/
|
||||
export class TestServerCancellationToken implements server.ServerCancellationToken {
|
||||
private currentId = -1;
|
||||
private currentId: number | undefined = -1;
|
||||
private requestToCancel = -1;
|
||||
private isCancellationRequestedCount = 0;
|
||||
|
||||
@@ -708,7 +707,7 @@ namespace ts.projectSystem {
|
||||
projectService.checkNumberOfProjects({ inferredProjects: 2, configuredProjects: 1 });
|
||||
assert.isTrue(projectService.inferredProjects[0].isOrphan());
|
||||
checkProjectActualFiles(projectService.inferredProjects[1], [commonFile2.path, libFile.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects.get(configFile.path), [libFile.path, commonFile1.path, configFile.path]);
|
||||
checkProjectActualFiles(projectService.configuredProjects.get(configFile.path)!, [libFile.path, commonFile1.path, configFile.path]);
|
||||
|
||||
checkWatchedFiles(host, watchedFiles);
|
||||
|
||||
@@ -1106,15 +1105,15 @@ namespace ts.projectSystem {
|
||||
const projectService = createProjectService(host);
|
||||
|
||||
projectService.openExternalProject({ rootFiles: toExternalFiles([file1.path]), options: {}, projectFileName: proj1name });
|
||||
const proj1 = projectService.findProject(proj1name);
|
||||
const proj1 = projectService.findProject(proj1name)!;
|
||||
assert.isTrue(proj1.languageServiceEnabled);
|
||||
|
||||
projectService.openExternalProject({ rootFiles: toExternalFiles([file2.path]), options: {}, projectFileName: proj2name });
|
||||
const proj2 = projectService.findProject(proj2name);
|
||||
const proj2 = projectService.findProject(proj2name)!;
|
||||
assert.isTrue(proj2.languageServiceEnabled);
|
||||
|
||||
projectService.openExternalProject({ rootFiles: toExternalFiles([file3.path]), options: {}, projectFileName: proj3name });
|
||||
const proj3 = projectService.findProject(proj3name);
|
||||
const proj3 = projectService.findProject(proj3name)!;
|
||||
assert.isFalse(proj3.languageServiceEnabled);
|
||||
});
|
||||
|
||||
@@ -1182,7 +1181,7 @@ namespace ts.projectSystem {
|
||||
const projectService = createProjectService(host, { useSingleInferredProject: true });
|
||||
projectService.openClientFile(file1.path);
|
||||
checkNumberOfConfiguredProjects(projectService, 1);
|
||||
const project = projectService.configuredProjects.get(configFile.path);
|
||||
const project = projectService.configuredProjects.get(configFile.path)!;
|
||||
assert.isTrue(project.hasOpenRef()); // file1
|
||||
|
||||
projectService.closeClientFile(file1.path);
|
||||
@@ -1216,7 +1215,7 @@ namespace ts.projectSystem {
|
||||
const projectService = createProjectService(host, { useSingleInferredProject: true });
|
||||
projectService.openClientFile(file1.path);
|
||||
checkNumberOfConfiguredProjects(projectService, 1);
|
||||
const project = projectService.configuredProjects.get(configFile.path);
|
||||
const project = projectService.configuredProjects.get(configFile.path)!;
|
||||
assert.isTrue(project.hasOpenRef()); // file1
|
||||
|
||||
projectService.closeClientFile(file1.path);
|
||||
@@ -1489,13 +1488,13 @@ namespace ts.projectSystem {
|
||||
service.checkNumberOfProjects({ externalProjects: 1 });
|
||||
checkProjectActualFiles(service.externalProjects[0], [f1.path, f2.path, libFile.path]);
|
||||
|
||||
const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, defaultPreferences);
|
||||
const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, defaultPreferences)!;
|
||||
// should contain completions for string
|
||||
assert.isTrue(completions1.entries.some(e => e.name === "charAt"), "should contain 'charAt'");
|
||||
assert.isFalse(completions1.entries.some(e => e.name === "toExponential"), "should not contain 'toExponential'");
|
||||
|
||||
service.closeClientFile(f2.path);
|
||||
const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, defaultPreferences);
|
||||
const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, defaultPreferences)!;
|
||||
// should contain completions for string
|
||||
assert.isFalse(completions2.entries.some(e => e.name === "charAt"), "should not contain 'charAt'");
|
||||
assert.isTrue(completions2.entries.some(e => e.name === "toExponential"), "should contain 'toExponential'");
|
||||
@@ -1521,13 +1520,13 @@ namespace ts.projectSystem {
|
||||
service.checkNumberOfProjects({ externalProjects: 1 });
|
||||
checkProjectActualFiles(service.externalProjects[0], [f1.path, f2.path, libFile.path]);
|
||||
|
||||
const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, defaultPreferences);
|
||||
const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, defaultPreferences)!;
|
||||
assert.isTrue(completions1.entries.some(e => e.name === "somelongname"), "should contain 'somelongname'");
|
||||
|
||||
service.closeClientFile(f2.path);
|
||||
const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, defaultPreferences);
|
||||
const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, defaultPreferences)!;
|
||||
assert.isFalse(completions2.entries.some(e => e.name === "somelongname"), "should not contain 'somelongname'");
|
||||
const sf2 = service.externalProjects[0].getLanguageService().getProgram().getSourceFile(f2.path);
|
||||
const sf2 = service.externalProjects[0].getLanguageService().getProgram()!.getSourceFile(f2.path)!;
|
||||
assert.equal(sf2.text, "");
|
||||
});
|
||||
|
||||
@@ -2048,8 +2047,8 @@ namespace ts.projectSystem {
|
||||
const projectService = createProjectService(host);
|
||||
projectService.applyChangesInOpenFiles([tsFile], [], []);
|
||||
const projs = projectService.synchronizeProjectList([]);
|
||||
projectService.findProject(projs[0].info.projectName).getLanguageService().getNavigationBarItems(tsFile.fileName);
|
||||
projectService.synchronizeProjectList([projs[0].info]);
|
||||
projectService.findProject(projs[0].info!.projectName)!.getLanguageService().getNavigationBarItems(tsFile.fileName);
|
||||
projectService.synchronizeProjectList([projs[0].info!]);
|
||||
projectService.applyChangesInOpenFiles([jsFile], [], []);
|
||||
});
|
||||
|
||||
@@ -2333,7 +2332,7 @@ namespace ts.projectSystem {
|
||||
|
||||
const project = projectService.externalProjects[0];
|
||||
|
||||
const scriptInfo = project.getScriptInfo(file1.path);
|
||||
const scriptInfo = project.getScriptInfo(file1.path)!;
|
||||
const snap = scriptInfo.getSnapshot();
|
||||
const actualText = getSnapshotText(snap);
|
||||
assert.equal(actualText, "", `expected content to be empty string, got "${actualText}"`);
|
||||
@@ -2341,12 +2340,12 @@ namespace ts.projectSystem {
|
||||
projectService.openClientFile(file1.path, `var x = 1;`);
|
||||
project.updateGraph();
|
||||
|
||||
const quickInfo = project.getLanguageService().getQuickInfoAtPosition(file1.path, 4);
|
||||
const quickInfo = project.getLanguageService().getQuickInfoAtPosition(file1.path, 4)!;
|
||||
assert.equal(quickInfo.kind, ScriptElementKind.variableElement);
|
||||
|
||||
projectService.closeClientFile(file1.path);
|
||||
|
||||
const scriptInfo2 = project.getScriptInfo(file1.path);
|
||||
const scriptInfo2 = project.getScriptInfo(file1.path)!;
|
||||
const actualText2 = getSnapshotText(scriptInfo2.getSnapshot());
|
||||
assert.equal(actualText2, "", `expected content to be empty string, got "${actualText2}"`);
|
||||
});
|
||||
@@ -2391,7 +2390,7 @@ namespace ts.projectSystem {
|
||||
projectService.openClientFile(file1.path);
|
||||
projectService.inferredProjects[0].getLanguageService(/*ensureSynchronized*/ false).getOutliningSpans(file1.path);
|
||||
projectService.setCompilerOptionsForInferredProjects({ target: ScriptTarget.ES5, allowJs: true });
|
||||
projectService.getScriptInfo(file1.path).editContent(0, 0, " ");
|
||||
projectService.getScriptInfo(file1.path)!.editContent(0, 0, " ");
|
||||
projectService.inferredProjects[0].getLanguageService(/*ensureSynchronized*/ false).getOutliningSpans(file1.path);
|
||||
projectService.closeClientFile(file1.path);
|
||||
});
|
||||
@@ -2418,9 +2417,9 @@ namespace ts.projectSystem {
|
||||
|
||||
projectService.openClientFile(file2.path);
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
const project1 = projectService.configuredProjects.get(tsconfig1.path);
|
||||
const project1 = projectService.configuredProjects.get(tsconfig1.path)!;
|
||||
assert.isTrue(project1.hasOpenRef(), "Has open ref count in project1 - 1"); // file2
|
||||
assert.equal(project1.getScriptInfo(file2.path).containingProjects.length, 1, "containing projects count");
|
||||
assert.equal(project1.getScriptInfo(file2.path)!.containingProjects.length, 1, "containing projects count");
|
||||
assert.isFalse(project1.isClosed());
|
||||
|
||||
projectService.openClientFile(file1.path);
|
||||
@@ -2429,12 +2428,12 @@ namespace ts.projectSystem {
|
||||
assert.strictEqual(projectService.configuredProjects.get(tsconfig1.path), project1);
|
||||
assert.isFalse(project1.isClosed());
|
||||
|
||||
const project2 = projectService.configuredProjects.get(tsconfig2.path);
|
||||
const project2 = projectService.configuredProjects.get(tsconfig2.path)!;
|
||||
assert.isTrue(project2.hasOpenRef(), "Has open ref count in project2 - 2"); // file1
|
||||
assert.isFalse(project2.isClosed());
|
||||
|
||||
assert.equal(project1.getScriptInfo(file1.path).containingProjects.length, 2, `${file1.path} containing projects count`);
|
||||
assert.equal(project1.getScriptInfo(file2.path).containingProjects.length, 1, `${file2.path} containing projects count`);
|
||||
assert.equal(project1.getScriptInfo(file1.path)!.containingProjects.length, 2, `${file1.path} containing projects count`);
|
||||
assert.equal(project1.getScriptInfo(file2.path)!.containingProjects.length, 1, `${file2.path} containing projects count`);
|
||||
|
||||
projectService.closeClientFile(file2.path);
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 2 });
|
||||
@@ -2494,10 +2493,10 @@ namespace ts.projectSystem {
|
||||
projectService.openClientFile(file3.path);
|
||||
projectService.openClientFile(file4.path);
|
||||
|
||||
const infos = files.map(file => projectService.getScriptInfoForPath(file.path as Path));
|
||||
const infos = files.map(file => projectService.getScriptInfoForPath(file.path as Path)!);
|
||||
checkOpenFiles(projectService, files);
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 2 });
|
||||
const configProject1 = projectService.configuredProjects.get(configFile.path);
|
||||
const configProject1 = projectService.configuredProjects.get(configFile.path)!;
|
||||
assert.isTrue(configProject1.hasOpenRef()); // file1 and file3
|
||||
checkProjectActualFiles(configProject1, [file1.path, file3.path, configFile.path]);
|
||||
const inferredProject1 = projectService.inferredProjects[0];
|
||||
@@ -2568,7 +2567,7 @@ namespace ts.projectSystem {
|
||||
|
||||
function verifyConfiguredProjectStateAfterUpdate(hasOpenRef: boolean, inferredProjects: number) {
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects });
|
||||
const configProject2 = projectService.configuredProjects.get(configFile.path);
|
||||
const configProject2 = projectService.configuredProjects.get(configFile.path)!;
|
||||
assert.strictEqual(configProject2, configProject1);
|
||||
checkProjectActualFiles(configProject2, [file1.path, file2.path, file3.path, configFile.path]);
|
||||
assert.equal(configProject2.hasOpenRef(), hasOpenRef);
|
||||
@@ -2607,7 +2606,7 @@ namespace ts.projectSystem {
|
||||
projectService.openClientFile(file3.path);
|
||||
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 1 });
|
||||
const configuredProject = projectService.configuredProjects.get(configFile.path);
|
||||
const configuredProject = projectService.configuredProjects.get(configFile.path)!;
|
||||
assert.isTrue(configuredProject.hasOpenRef()); // file1 and file3
|
||||
checkProjectActualFiles(configuredProject, [file1.path, file3.path, configFile.path]);
|
||||
const inferredProject1 = projectService.inferredProjects[0];
|
||||
@@ -2709,7 +2708,7 @@ namespace ts.projectSystem {
|
||||
const projectService = createProjectService(host);
|
||||
projectService.openClientFile(f1.path);
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
const project = projectService.configuredProjects.get(config.path);
|
||||
const project = projectService.configuredProjects.get(config.path)!;
|
||||
assert.isTrue(project.hasOpenRef()); // f1
|
||||
assert.isFalse(project.isClosed());
|
||||
|
||||
@@ -2721,7 +2720,7 @@ namespace ts.projectSystem {
|
||||
|
||||
for (const f of [f1, f2, f3]) {
|
||||
// All the script infos should be present and contain the project since it is still alive.
|
||||
const scriptInfo = projectService.getScriptInfoForNormalizedPath(server.toNormalizedPath(f.path));
|
||||
const scriptInfo = projectService.getScriptInfoForNormalizedPath(server.toNormalizedPath(f.path))!;
|
||||
assert.equal(scriptInfo.containingProjects.length, 1, `expect 1 containing projects for '${f.path}'`);
|
||||
assert.equal(scriptInfo.containingProjects[0], project, `expect configured project to be the only containing project for '${f.path}'`);
|
||||
}
|
||||
@@ -2764,7 +2763,7 @@ namespace ts.projectSystem {
|
||||
host.getFileSize = (filePath: string) =>
|
||||
filePath === f2.path ? server.maxProgramSizeForNonTsFiles + 1 : originalGetFileSize.call(host, filePath);
|
||||
|
||||
let lastEvent: server.ProjectLanguageServiceStateEvent;
|
||||
let lastEvent!: server.ProjectLanguageServiceStateEvent;
|
||||
const session = createSession(host, {
|
||||
canUseEvents: true,
|
||||
eventHandler: e => {
|
||||
@@ -2816,7 +2815,7 @@ namespace ts.projectSystem {
|
||||
const originalGetFileSize = host.getFileSize;
|
||||
host.getFileSize = (filePath: string) =>
|
||||
filePath === f2.path ? server.maxProgramSizeForNonTsFiles + 1 : originalGetFileSize.call(host, filePath);
|
||||
let lastEvent: server.ProjectLanguageServiceStateEvent;
|
||||
let lastEvent!: server.ProjectLanguageServiceStateEvent;
|
||||
const session = createSession(host, {
|
||||
canUseEvents: true,
|
||||
eventHandler: e => {
|
||||
@@ -2906,7 +2905,7 @@ namespace ts.projectSystem {
|
||||
host.reloadFS([libFile, site]);
|
||||
host.checkTimeoutQueueLengthAndRun(1);
|
||||
|
||||
knownProjects = projectService.synchronizeProjectList(map(knownProjects, proj => proj.info));
|
||||
knownProjects = projectService.synchronizeProjectList(map(knownProjects, proj => proj.info!)); // TODO: GH#18217 GH#20039
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 0, externalProjects: 0, inferredProjects: 0 });
|
||||
|
||||
externalProject.rootFiles.length = 1;
|
||||
@@ -2979,7 +2978,7 @@ namespace ts.projectSystem {
|
||||
const projectService = createProjectService(host);
|
||||
projectService.openClientFile(file1.path);
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
const project = projectService.configuredProjects.get(configFile.path);
|
||||
const project = projectService.configuredProjects.get(configFile.path)!;
|
||||
assert.isDefined(project);
|
||||
checkProjectActualFiles(project, map(files, file => file.path));
|
||||
checkWatchedFiles(host, mapDefined(files, file => file === file1 ? undefined : file.path));
|
||||
@@ -3040,7 +3039,7 @@ namespace ts.projectSystem {
|
||||
const projectService = createProjectService(host);
|
||||
projectService.openClientFile(file1.path);
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
const project = projectService.configuredProjects.get(configFile.path);
|
||||
const project = projectService.configuredProjects.get(configFile.path)!;
|
||||
assert.isDefined(project);
|
||||
checkProjectActualFiles(project, [file1.path, libFile.path, module1.path, module2.path, configFile.path]);
|
||||
checkWatchedFiles(host, [libFile.path, module1.path, module2.path, configFile.path]);
|
||||
@@ -3145,7 +3144,7 @@ namespace ts.projectSystem {
|
||||
});
|
||||
|
||||
const projectService = session.getProjectService();
|
||||
const configuredProject = projectService.configuredProjects.get(config.path);
|
||||
const configuredProject = projectService.configuredProjects.get(config.path)!;
|
||||
verifyConfiguredProject();
|
||||
|
||||
// open files/file1 = should not create another project
|
||||
@@ -3296,7 +3295,7 @@ namespace ts.projectSystem {
|
||||
const host = createServerHost(files);
|
||||
const service = createProjectService(host);
|
||||
service.openClientFile(file1.path);
|
||||
checkProjectActualFiles(service.configuredProjects.get(config.path), [file1.path, file2.path, libFile.path, config.path]);
|
||||
checkProjectActualFiles(service.configuredProjects.get(config.path)!, [file1.path, file2.path, libFile.path, config.path]);
|
||||
|
||||
const configContent2 = JSON.stringify({
|
||||
files: ["src/file1.ts"]
|
||||
@@ -3305,19 +3304,18 @@ namespace ts.projectSystem {
|
||||
host.reloadFS(files);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
|
||||
checkProjectActualFiles(service.configuredProjects.get(config.path), [file1.path, libFile.path, config.path]);
|
||||
checkProjectActualFiles(service.configuredProjects.get(config.path)!, [file1.path, libFile.path, config.path]);
|
||||
verifyFile2InfoIsOrphan();
|
||||
|
||||
file2.content += "export let z = 10;";
|
||||
host.reloadFS(files);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
|
||||
checkProjectActualFiles(service.configuredProjects.get(config.path), [file1.path, libFile.path, config.path]);
|
||||
checkProjectActualFiles(service.configuredProjects.get(config.path)!, [file1.path, libFile.path, config.path]);
|
||||
verifyFile2InfoIsOrphan();
|
||||
|
||||
function verifyFile2InfoIsOrphan() {
|
||||
const info = service.getScriptInfoForPath(file2.path as Path);
|
||||
assert.isDefined(info);
|
||||
const info = Debug.assertDefined(service.getScriptInfoForPath(file2.path as Path));
|
||||
assert.equal(info.containingProjects.length, 0);
|
||||
}
|
||||
});
|
||||
@@ -3339,7 +3337,7 @@ namespace ts.projectSystem {
|
||||
},
|
||||
startGroup: noop,
|
||||
endGroup: noop,
|
||||
getLogFileName: (): string => undefined
|
||||
getLogFileName: () => undefined
|
||||
};
|
||||
return {
|
||||
errorLogger,
|
||||
@@ -3362,7 +3360,7 @@ namespace ts.projectSystem {
|
||||
projectService.openClientFile(file1.path);
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
|
||||
const project = projectService.findProject(corruptedConfig.path);
|
||||
const project = projectService.findProject(corruptedConfig.path)!;
|
||||
checkProjectRootFiles(project, [file1.path]);
|
||||
});
|
||||
|
||||
@@ -3904,7 +3902,7 @@ namespace ts.projectSystem {
|
||||
const projectService = createProjectService(host);
|
||||
projectService.openClientFile(f.path);
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
const project = projectService.configuredProjects.get(config.path);
|
||||
const project = projectService.configuredProjects.get(config.path)!;
|
||||
assert.isTrue(project.hasOpenRef()); // f
|
||||
|
||||
projectService.closeClientFile(f.path);
|
||||
@@ -4053,7 +4051,7 @@ namespace ts.projectSystem {
|
||||
// force to load the content of the file
|
||||
p.updateGraph();
|
||||
|
||||
const scriptInfo = p.getScriptInfo(f.path);
|
||||
const scriptInfo = p.getScriptInfo(f.path)!;
|
||||
checkSnapLength(scriptInfo.getSnapshot(), f.content.length);
|
||||
|
||||
// open project and replace its content with empty string
|
||||
@@ -4137,7 +4135,7 @@ namespace ts.projectSystem {
|
||||
|
||||
function verifyProject() {
|
||||
assert.isDefined(service.configuredProjects.get(configFile.path));
|
||||
const project = service.configuredProjects.get(configFile.path);
|
||||
const project = service.configuredProjects.get(configFile.path)!;
|
||||
checkProjectActualFiles(project, files.map(f => f.path));
|
||||
}
|
||||
});
|
||||
@@ -5037,7 +5035,7 @@ namespace ts.projectSystem {
|
||||
|
||||
// verify content
|
||||
const projectServiice = session.getProjectService();
|
||||
const snap1 = projectServiice.getScriptInfo(f1.path).getSnapshot();
|
||||
const snap1 = projectServiice.getScriptInfo(f1.path)!.getSnapshot();
|
||||
assert.equal(getSnapshotText(snap1), tmp.content, "content should be equal to the content of temp file");
|
||||
|
||||
// reload from original file file
|
||||
@@ -5049,7 +5047,7 @@ namespace ts.projectSystem {
|
||||
});
|
||||
|
||||
// verify content
|
||||
const snap2 = projectServiice.getScriptInfo(f1.path).getSnapshot();
|
||||
const snap2 = projectServiice.getScriptInfo(f1.path)!.getSnapshot();
|
||||
assert.equal(getSnapshotText(snap2), f1.content, "content should be equal to the content of original file");
|
||||
|
||||
});
|
||||
@@ -5074,7 +5072,7 @@ namespace ts.projectSystem {
|
||||
|
||||
const projectService = session.getProjectService();
|
||||
checkNumberOfProjects(projectService, { inferredProjects: 1 });
|
||||
const info = projectService.getScriptInfo(f1.path);
|
||||
const info = projectService.getScriptInfo(f1.path)!;
|
||||
assert.isDefined(info);
|
||||
checkScriptInfoContents(openContent, "contents set during open request");
|
||||
|
||||
@@ -5647,8 +5645,7 @@ namespace ts.projectSystem {
|
||||
|
||||
function verifyConfiguredProject(host: TestServerHost, projectService: TestProjectService, orphanInferredProject?: boolean) {
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1, inferredProjects: orphanInferredProject ? 1 : 0 });
|
||||
const project = projectService.configuredProjects.get(tsconfig.path);
|
||||
assert.isDefined(project);
|
||||
const project = Debug.assertDefined(projectService.configuredProjects.get(tsconfig.path));
|
||||
|
||||
if (orphanInferredProject) {
|
||||
const inferredProject = projectService.inferredProjects[0];
|
||||
@@ -6240,7 +6237,7 @@ namespace ts.projectSystem {
|
||||
const calledMap = createMultiMap<[U, V, W, X]>();
|
||||
const cb = (<any>host)[prop].bind(host);
|
||||
(<any>host)[prop] = (f: string, arg1?: U, arg2?: V, arg3?: W, arg4?: X) => {
|
||||
calledMap.add(f, [arg1, arg2, arg3, arg4]);
|
||||
calledMap.add(f, [arg1!, arg2!, arg3!, arg4!]); // TODO: GH#18217
|
||||
return cb(f, arg1, arg2, arg3, arg4);
|
||||
};
|
||||
return calledMap;
|
||||
@@ -6495,7 +6492,7 @@ namespace ts.projectSystem {
|
||||
assert.isDefined(configFileName, `should find config`);
|
||||
checkNumberOfConfiguredProjects(projectService, 1);
|
||||
|
||||
const project = projectService.configuredProjects.get(tsconfigFile.path);
|
||||
const project = projectService.configuredProjects.get(tsconfigFile.path)!;
|
||||
checkProjectActualFiles(project, map(projectFiles, f => f.path));
|
||||
|
||||
const callsTrackingHost = createCallsTrackingHost(host);
|
||||
@@ -6504,8 +6501,8 @@ namespace ts.projectSystem {
|
||||
const getDefinitionRequest = makeSessionRequest<protocol.FileLocationRequestArgs>(protocol.CommandTypes.Definition, {
|
||||
file: clientFile.path,
|
||||
position: clientFile.content.indexOf("/vessel") + 1,
|
||||
line: undefined,
|
||||
offset: undefined
|
||||
line: undefined!, // TODO: GH#18217
|
||||
offset: undefined! // TODO: GH#18217
|
||||
});
|
||||
const response = session.executeCommand(getDefinitionRequest).response as server.protocol.FileSpan[];
|
||||
assert.equal(response[0].file, moduleFile.path, "Should go to definition of vessel: response: " + JSON.stringify(response));
|
||||
@@ -6581,11 +6578,11 @@ namespace ts.projectSystem {
|
||||
const projectService = createProjectService(host);
|
||||
const canonicalConfigPath = toCanonical(tsconfigFile.path);
|
||||
const { configFileName } = projectService.openClientFile(file1.path);
|
||||
assert.equal(configFileName, tsconfigFile.path, `should find config`);
|
||||
assert.equal(configFileName, tsconfigFile.path as server.NormalizedPath, `should find config`); // tslint:disable-line no-unnecessary-type-assertion (TODO: GH#18217)
|
||||
checkNumberOfConfiguredProjects(projectService, 1);
|
||||
const watchingRecursiveDirectories = [`${canonicalFrontendDir}/src`, canonicalFrontendDir].concat(getNodeModuleDirectories(getDirectoryPath(canonicalFrontendDir)));
|
||||
|
||||
const project = projectService.configuredProjects.get(canonicalConfigPath);
|
||||
const project = projectService.configuredProjects.get(canonicalConfigPath)!;
|
||||
verifyProjectAndWatchedDirectories();
|
||||
|
||||
const callsTrackingHost = createCallsTrackingHost(host);
|
||||
@@ -6664,7 +6661,7 @@ namespace ts.projectSystem {
|
||||
const service = createProjectService(host);
|
||||
service.openClientFile(file1.path);
|
||||
|
||||
const project = service.configuredProjects.get(tsconfig.path);
|
||||
const project = service.configuredProjects.get(tsconfig.path)!;
|
||||
checkProjectActualFiles(project, files.map(f => f.path));
|
||||
assert.deepEqual(project.getLanguageService().getSemanticDiagnostics(file1.path).map(diag => diag.messageText), ["Cannot find module 'debug'."]);
|
||||
assert.deepEqual(project.getLanguageService().getSemanticDiagnostics(file2.path).map(diag => diag.messageText), ["Cannot find module 'debug'."]);
|
||||
@@ -6736,7 +6733,7 @@ namespace ts.projectSystem {
|
||||
const host = createServerHost(projectFiles.concat(otherFiles));
|
||||
const projectService = createProjectService(host);
|
||||
const { configFileName } = projectService.openClientFile(app.path);
|
||||
assert.equal(configFileName, tsconfigJson.path, `should find config`);
|
||||
assert.equal(configFileName, tsconfigJson.path as server.NormalizedPath, `should find config`); // TODO: GH#18217
|
||||
const recursiveWatchedDirectories: string[] = [appFolder].concat(getNodeModuleDirectories(getDirectoryPath(appFolder)));
|
||||
verifyProject();
|
||||
|
||||
@@ -6815,7 +6812,7 @@ namespace ts.projectSystem {
|
||||
});
|
||||
|
||||
const lodashIndexPath = root + "/a/b/node_modules/@types/lodash/index.d.ts";
|
||||
projectFiles.push(find(filesAndFoldersToAdd, f => f.path === lodashIndexPath));
|
||||
projectFiles.push(find(filesAndFoldersToAdd, f => f.path === lodashIndexPath)!);
|
||||
// we would now not have failed lookup in the parent of appFolder since lodash is available
|
||||
recursiveWatchedDirectories.length = 1;
|
||||
// npm installation complete, timeout after reload fs
|
||||
@@ -6836,7 +6833,7 @@ namespace ts.projectSystem {
|
||||
function verifyProject() {
|
||||
checkNumberOfConfiguredProjects(projectService, 1);
|
||||
|
||||
const project = projectService.configuredProjects.get(tsconfigJson.path);
|
||||
const project = projectService.configuredProjects.get(tsconfigJson.path)!;
|
||||
const projectFilePaths = map(projectFiles, f => f.path);
|
||||
checkProjectActualFiles(project, projectFilePaths);
|
||||
|
||||
@@ -6872,7 +6869,7 @@ namespace ts.projectSystem {
|
||||
const service = createProjectService(host);
|
||||
service.openClientFile(app.path);
|
||||
|
||||
const project = service.configuredProjects.get(tsconfig.path);
|
||||
const project = service.configuredProjects.get(tsconfig.path)!;
|
||||
checkProjectActualFiles(project, files.map(f => f.path));
|
||||
assert.deepEqual(project.getLanguageService().getSemanticDiagnostics(app.path).map(diag => diag.messageText), ["Cannot find module 'debug'."]);
|
||||
|
||||
@@ -7071,7 +7068,7 @@ namespace ts.projectSystem {
|
||||
content: JSON.stringify(configObj || { compilerOptions: {} })
|
||||
};
|
||||
|
||||
const files = [file1Consumer1, moduleFile1, file1Consumer2, moduleFile2, ...additionalFiles, globalFile3, libFile, configFile];
|
||||
const files: File[] = [file1Consumer1, moduleFile1, file1Consumer2, moduleFile2, ...additionalFiles, globalFile3, libFile, configFile];
|
||||
|
||||
const filesToReload = firstReloadFileList && getFiles(firstReloadFileList) || files;
|
||||
const host = createServerHost([filesToReload[0], configFile]);
|
||||
@@ -7097,7 +7094,7 @@ namespace ts.projectSystem {
|
||||
}
|
||||
|
||||
function getFile(fileName: string) {
|
||||
return find(files, file => file.path === fileName);
|
||||
return find(files, file => file.path === fileName)!;
|
||||
}
|
||||
|
||||
function verifyNoProjectsUpdatedInBackgroundEvent(filesToReload?: File[]) {
|
||||
@@ -7345,7 +7342,7 @@ namespace ts.projectSystem {
|
||||
const projectService = session.getProjectService();
|
||||
verifyInitialOpen(file1);
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
const project = projectService.configuredProjects.get(configFile.path);
|
||||
const project = projectService.configuredProjects.get(configFile.path)!;
|
||||
verifyProject();
|
||||
if (limitHit) {
|
||||
(project as ResolutionCacheHost).maxNumberOfFilesToIterateForInvalidation = 1;
|
||||
@@ -7521,7 +7518,7 @@ namespace ts.projectSystem {
|
||||
const host = createServerHost(files, { useWindowsStylePaths: true });
|
||||
const projectService = createProjectService(host);
|
||||
projectService.openClientFile(file1.path);
|
||||
const project = projectService.configuredProjects.get(configFile.path);
|
||||
const project = projectService.configuredProjects.get(configFile.path)!;
|
||||
assert.isDefined(project);
|
||||
const winsowsStyleLibFilePath = "c:/" + libFile.path.substring(1);
|
||||
checkProjectActualFiles(project, files.map(f => f === libFile ? winsowsStyleLibFilePath : f.path));
|
||||
@@ -7849,7 +7846,7 @@ new C();`
|
||||
|
||||
function verifyProjectWithResolvedModule(session: TestSession) {
|
||||
const projectService = session.getProjectService();
|
||||
const project = projectService.configuredProjects.get(recognizerDateTimeTsconfigPath);
|
||||
const project = projectService.configuredProjects.get(recognizerDateTimeTsconfigPath)!;
|
||||
checkProjectActualFiles(project, filesInProjectWithResolvedModule);
|
||||
verifyWatchedFilesAndDirectories(session.host, filesInProjectWithResolvedModule, watchedDirectoriesWithResolvedModule);
|
||||
verifyErrors(session, []);
|
||||
@@ -7857,7 +7854,7 @@ new C();`
|
||||
|
||||
function verifyProjectWithUnresolvedModule(session: TestSession) {
|
||||
const projectService = session.getProjectService();
|
||||
const project = projectService.configuredProjects.get(recognizerDateTimeTsconfigPath);
|
||||
const project = projectService.configuredProjects.get(recognizerDateTimeTsconfigPath)!;
|
||||
checkProjectActualFiles(project, filesInProjectWithUnresolvedModule);
|
||||
verifyWatchedFilesAndDirectories(session.host, filesInProjectWithUnresolvedModule, watchedDirectoriesWithUnresolvedModule);
|
||||
const startOffset = recognizersDateTimeSrcFile.content.indexOf('"') + 1;
|
||||
@@ -8358,8 +8355,7 @@ new C();`
|
||||
const projectService = createProjectService(host);
|
||||
projectService.openClientFile(index.path);
|
||||
|
||||
const project = projectService.configuredProjects.get(configFile.path);
|
||||
assert.isDefined(project);
|
||||
const project = Debug.assertDefined(projectService.configuredProjects.get(configFile.path));
|
||||
verifyProjectAndCompletions();
|
||||
|
||||
// Add file2
|
||||
@@ -8377,7 +8373,7 @@ new C();`
|
||||
verifyProjectAndCompletions();
|
||||
|
||||
function verifyProjectAndCompletions() {
|
||||
const completions = project.getLanguageService().getCompletionsAtPosition(index.path, completionPosition, { includeExternalModuleExports: false, includeInsertTextCompletions: false });
|
||||
const completions = project.getLanguageService().getCompletionsAtPosition(index.path, completionPosition, { includeExternalModuleExports: false, includeInsertTextCompletions: false })!;
|
||||
checkArray("Completion Entries", completions.entries.map(e => e.name), expectedCompletions);
|
||||
|
||||
checkWatchedDirectories(host, emptyArray, /*recursive*/ true);
|
||||
@@ -8443,7 +8439,7 @@ new C();`
|
||||
};
|
||||
|
||||
function getProject(service: TestProjectService) {
|
||||
return service.configuredProjects.get(configFile.path);
|
||||
return service.configuredProjects.get(configFile.path)!;
|
||||
}
|
||||
|
||||
function checkProject(service: TestProjectService, moduleIsOrphan: boolean) {
|
||||
@@ -8451,7 +8447,7 @@ new C();`
|
||||
const project = getProject(service);
|
||||
project.getLanguageService();
|
||||
checkProjectActualFiles(project, [file.path, libFile.path, configFile.path, ...(moduleIsOrphan ? [] : [moduleFile.path])]);
|
||||
const moduleInfo = service.getScriptInfo(moduleFile.path);
|
||||
const moduleInfo = service.getScriptInfo(moduleFile.path)!;
|
||||
assert.isDefined(moduleInfo);
|
||||
assert.equal(moduleInfo.isOrphan(), moduleIsOrphan);
|
||||
const key = service.documentRegistry.getKeyForCompilationSettings(project.getCompilationSettings());
|
||||
@@ -8467,13 +8463,13 @@ new C();`
|
||||
}
|
||||
|
||||
function changeFileToNotImportModule(service: TestProjectService) {
|
||||
const info = service.getScriptInfo(file.path);
|
||||
const info = service.getScriptInfo(file.path)!;
|
||||
service.applyChangesToFile(info, [{ span: { start: 0, length: importModuleContent.length }, newText: "" }]);
|
||||
checkProject(service, /*moduleIsOrphan*/ true);
|
||||
}
|
||||
|
||||
function changeFileToImportModule(service: TestProjectService) {
|
||||
const info = service.getScriptInfo(file.path);
|
||||
const info = service.getScriptInfo(file.path)!;
|
||||
service.applyChangesToFile(info, [{ span: { start: 0, length: 0 }, newText: importModuleContent }]);
|
||||
checkProject(service, /*moduleIsOrphan*/ false);
|
||||
}
|
||||
@@ -8482,7 +8478,7 @@ new C();`
|
||||
const { service } = createServiceAndHost();
|
||||
const project = getProject(service);
|
||||
|
||||
const moduleInfo = service.getScriptInfo(moduleFile.path);
|
||||
const moduleInfo = service.getScriptInfo(moduleFile.path)!;
|
||||
const sourceFile = moduleInfo.cacheSourceFile.sourceFile;
|
||||
assert.equal(project.getSourceFile(moduleInfo.path), sourceFile);
|
||||
|
||||
@@ -8500,7 +8496,7 @@ new C();`
|
||||
const { host, service } = createServiceAndHost();
|
||||
const project = getProject(service);
|
||||
|
||||
const moduleInfo = service.getScriptInfo(moduleFile.path);
|
||||
const moduleInfo = service.getScriptInfo(moduleFile.path)!;
|
||||
const sourceFile = moduleInfo.cacheSourceFile.sourceFile;
|
||||
assert.equal(project.getSourceFile(moduleInfo.path), sourceFile);
|
||||
|
||||
|
||||
@@ -1447,7 +1447,7 @@ namespace ts.projectSystem {
|
||||
commander: { typingLocation: commander.path, version: Semver.parse("1.3.0-next.0") }
|
||||
});
|
||||
const registry = createTypesRegistry("node", "commander");
|
||||
registry.get("node")[`ts${versionMajorMinor}`] = "1.3.0-next.1";
|
||||
registry.get("node")![`ts${versionMajorMinor}`] = "1.3.0-next.1";
|
||||
const logger = trackingLogger();
|
||||
const result = JsTyping.discoverTypings(host, logger.log, [app.path], getDirectoryPath(<Path>app.path), emptySafeList, cache, { enable: true }, ["http", "commander"], registry);
|
||||
assert.deepEqual(logger.finish(), [
|
||||
@@ -1535,8 +1535,8 @@ namespace ts.projectSystem {
|
||||
content: "export let x: number"
|
||||
};
|
||||
const host = createServerHost([f1, packageFile, packageLockFile]);
|
||||
let beginEvent: server.BeginInstallTypes;
|
||||
let endEvent: server.EndInstallTypes;
|
||||
let beginEvent!: server.BeginInstallTypes;
|
||||
let endEvent!: server.EndInstallTypes;
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host, { globalTypingsCacheLocation: cachePath, typesRegistry: createTypesRegistry("commander") });
|
||||
@@ -1583,8 +1583,8 @@ namespace ts.projectSystem {
|
||||
};
|
||||
const cachePath = "/a/cache/";
|
||||
const host = createServerHost([f1, packageFile]);
|
||||
let beginEvent: server.BeginInstallTypes;
|
||||
let endEvent: server.EndInstallTypes;
|
||||
let beginEvent: server.BeginInstallTypes | undefined;
|
||||
let endEvent: server.EndInstallTypes | undefined;
|
||||
const installer: Installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host, { globalTypingsCacheLocation: cachePath, typesRegistry: createTypesRegistry("commander") });
|
||||
@@ -1611,8 +1611,8 @@ namespace ts.projectSystem {
|
||||
|
||||
assert.isTrue(!!beginEvent);
|
||||
assert.isTrue(!!endEvent);
|
||||
assert.isTrue(beginEvent.eventId === endEvent.eventId);
|
||||
assert.isFalse(endEvent.installSuccess);
|
||||
assert.isTrue(beginEvent!.eventId === endEvent!.eventId);
|
||||
assert.isFalse(endEvent!.installSuccess);
|
||||
checkNumberOfProjects(projectService, { inferredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.inferredProjects[0], [f1.path]);
|
||||
});
|
||||
@@ -1651,7 +1651,7 @@ namespace ts.projectSystem {
|
||||
const appPath = "/a/b/app.js" as Path;
|
||||
const foooPath = "/a/b/node_modules/fooo/index.d.ts";
|
||||
function verifyResolvedModuleOfFooo(project: server.Project) {
|
||||
const foooResolution = project.getLanguageService().getProgram().getSourceFileByPath(appPath).resolvedModules.get("fooo");
|
||||
const foooResolution = project.getLanguageService().getProgram()!.getSourceFileByPath(appPath)!.resolvedModules!.get("fooo")!;
|
||||
assert.equal(foooResolution.resolvedFileName, foooPath);
|
||||
return foooResolution;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ var q:Point=<Point>p;`;
|
||||
});
|
||||
|
||||
after(() => {
|
||||
validateEditAtLineCharIndex = undefined;
|
||||
validateEditAtLineCharIndex = undefined!;
|
||||
});
|
||||
|
||||
it("handles empty lines array", () => {
|
||||
@@ -105,10 +105,10 @@ and grew 1cm per day`;
|
||||
});
|
||||
|
||||
after(() => {
|
||||
validateEditAtPosition = undefined;
|
||||
testContent = undefined;
|
||||
lines = undefined;
|
||||
lineMap = undefined;
|
||||
validateEditAtPosition = undefined!;
|
||||
testContent = undefined!;
|
||||
lines = undefined!;
|
||||
lineMap = undefined!;
|
||||
});
|
||||
|
||||
it(`Insert at end of file`, () => {
|
||||
@@ -201,7 +201,7 @@ and grew 1cm per day`;
|
||||
before(() => {
|
||||
// Use scanner.ts, decent size, does not change frequently
|
||||
const testFileName = "src/compiler/scanner.ts";
|
||||
testContent = Harness.IO.readFile(testFileName);
|
||||
testContent = Harness.IO.readFile(testFileName)!;
|
||||
const totalChars = testContent.length;
|
||||
assert.isTrue(totalChars > 0, "Failed to read test file.");
|
||||
|
||||
@@ -237,16 +237,16 @@ and grew 1cm per day`;
|
||||
});
|
||||
|
||||
after(() => {
|
||||
rsa = undefined;
|
||||
la = undefined;
|
||||
las = undefined;
|
||||
elas = undefined;
|
||||
ersa = undefined;
|
||||
ela = undefined;
|
||||
lines = undefined;
|
||||
lineMap = undefined;
|
||||
lineIndex = undefined;
|
||||
testContent = undefined;
|
||||
rsa = undefined!;
|
||||
la = undefined!;
|
||||
las = undefined!;
|
||||
elas = undefined!;
|
||||
ersa = undefined!;
|
||||
ela = undefined!;
|
||||
lines = undefined!;
|
||||
lineMap = undefined!;
|
||||
lineIndex = undefined!;
|
||||
testContent = undefined!;
|
||||
});
|
||||
|
||||
it("Range (average length 1/4 file size)", () => {
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*/
|
||||
namespace utils {
|
||||
const testPathPrefixRegExp = /(?:(file:\/{3})|\/)\.(ts|lib|src)\//g;
|
||||
export function removeTestPathPrefixes(text: string, retainTrailingDirectorySeparator?: boolean) {
|
||||
return text !== undefined ? text.replace(testPathPrefixRegExp, (_, scheme) => scheme || (retainTrailingDirectorySeparator ? "/" : "")) : undefined;
|
||||
export function removeTestPathPrefixes(text: string, retainTrailingDirectorySeparator?: boolean): string {
|
||||
return text !== undefined ? text.replace(testPathPrefixRegExp, (_, scheme) => scheme || (retainTrailingDirectorySeparator ? "/" : "")) : undefined!; // TODO: GH#18217
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,7 +49,7 @@ namespace utils {
|
||||
}
|
||||
|
||||
function guessIndentation(lines: string[]) {
|
||||
let indentation: number;
|
||||
let indentation: number | undefined;
|
||||
for (const line of lines) {
|
||||
for (let i = 0; i < line.length && (indentation === undefined || i < indentation); i++) {
|
||||
if (!ts.isWhiteSpaceLike(line.charCodeAt(i))) {
|
||||
|
||||
+5
-5
@@ -935,7 +935,7 @@ namespace vfs {
|
||||
this._applyFilesWorker(value.files, path, deferred);
|
||||
}
|
||||
else {
|
||||
deferred.push([value as Symlink | Link | Mount, path]);
|
||||
deferred.push([value, path]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -998,7 +998,7 @@ namespace vfs {
|
||||
directoryExists(path: string): boolean;
|
||||
fileExists(path: string): boolean;
|
||||
getFileSize(path: string): number;
|
||||
readFile(path: string): string;
|
||||
readFile(path: string): string | undefined;
|
||||
getWorkspaceRoot(): string;
|
||||
}
|
||||
|
||||
@@ -1020,7 +1020,7 @@ namespace vfs {
|
||||
}
|
||||
},
|
||||
readFileSync(path: string): Buffer {
|
||||
return Buffer.from(host.readFile(path), "utf8");
|
||||
return Buffer.from(host.readFile(path)!, "utf8"); // TODO: GH#18217
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1241,7 +1241,7 @@ namespace vfs {
|
||||
ctimeMs: number; // status change time
|
||||
birthtimeMs: number; // creation time
|
||||
nlink: number; // number of hard links
|
||||
symlink?: string;
|
||||
symlink: string;
|
||||
shadowRoot?: SymlinkInode;
|
||||
meta?: collections.Metadata;
|
||||
}
|
||||
@@ -1262,7 +1262,7 @@ namespace vfs {
|
||||
realpath: string;
|
||||
basename: string;
|
||||
parent: DirectoryInode | undefined;
|
||||
links: collections.SortedMap<string, Inode> | undefined;
|
||||
links: collections.SortedMap<string, Inode>;
|
||||
node: Inode | undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ interface Array<T> {}`
|
||||
verifyMapSize(caption, actual, arrayFrom(expectedKeys.keys()));
|
||||
expectedKeys.forEach((count, name) => {
|
||||
assert.isTrue(actual.has(name), `${caption}: expected to contain ${name}, actual keys: ${arrayFrom(actual.keys())}`);
|
||||
assert.equal(actual.get(name).length, count, `${caption}: Expected to be have ${count} entries for ${name}. Actual entry: ${JSON.stringify(actual.get(name))}`);
|
||||
assert.equal(actual.get(name)!.length, count, `${caption}: Expected to be have ${count} entries for ${name}. Actual entry: ${JSON.stringify(actual.get(name))}`);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -322,7 +322,7 @@ interface Array<T> {}`
|
||||
readonly watchedFiles = createMultiMap<TestFileWatcher>();
|
||||
private readonly executingFilePath: string;
|
||||
private readonly currentDirectory: string;
|
||||
private readonly dynamicPriorityWatchFile: HostWatchFile;
|
||||
private readonly dynamicPriorityWatchFile: HostWatchFile | undefined;
|
||||
private readonly customRecursiveWatchDirectory: HostWatchDirectory | undefined;
|
||||
|
||||
constructor(public withSafeList: boolean, public useCaseSensitiveFileNames: boolean, executingFilePath: string, currentDirectory: string, fileOrFolderorSymLinkList: ReadonlyArray<FileOrFolderOrSymLink>, public readonly newLine = "\n", public readonly useWindowsStylePath?: boolean, private readonly environmentVariables?: Map<string>) {
|
||||
@@ -465,7 +465,7 @@ interface Array<T> {}`
|
||||
else {
|
||||
currentEntry.content = content;
|
||||
currentEntry.modifiedTime = this.now();
|
||||
this.fs.get(getDirectoryPath(currentEntry.path)).modifiedTime = this.now();
|
||||
this.fs.get(getDirectoryPath(currentEntry.path))!.modifiedTime = this.now();
|
||||
if (options && options.invokeDirectoryWatcherInsteadOfFileChanged) {
|
||||
this.invokeDirectoryWatcher(getDirectoryPath(currentEntry.fullPath), currentEntry.fullPath);
|
||||
}
|
||||
@@ -570,7 +570,7 @@ interface Array<T> {}`
|
||||
this.invokeDirectoryWatcher(folder.fullPath, fileOrDirectory.fullPath);
|
||||
}
|
||||
|
||||
private removeFileOrFolder(fileOrDirectory: FsFile | FsFolder | FsSymLink, isRemovableLeafFolder: (folder: FsFolder) => boolean, isRenaming?: boolean) {
|
||||
private removeFileOrFolder(fileOrDirectory: FsFile | FsFolder | FsSymLink, isRemovableLeafFolder: (folder: FsFolder) => boolean, isRenaming = false) {
|
||||
const basePath = getDirectoryPath(fileOrDirectory.path);
|
||||
const baseFolder = this.fs.get(basePath) as FsFolder;
|
||||
if (basePath !== fileOrDirectory.path) {
|
||||
@@ -621,15 +621,15 @@ interface Array<T> {}`
|
||||
|
||||
// For overriding the methods
|
||||
invokeWatchedDirectoriesCallback(folderFullPath: string, relativePath: string) {
|
||||
invokeWatcherCallbacks(this.watchedDirectories.get(this.toPath(folderFullPath)), cb => this.directoryCallback(cb, relativePath));
|
||||
invokeWatcherCallbacks(this.watchedDirectories.get(this.toPath(folderFullPath))!, cb => this.directoryCallback(cb, relativePath));
|
||||
}
|
||||
|
||||
invokeWatchedDirectoriesRecursiveCallback(folderFullPath: string, relativePath: string) {
|
||||
invokeWatcherCallbacks(this.watchedDirectoriesRecursive.get(this.toPath(folderFullPath)), cb => this.directoryCallback(cb, relativePath));
|
||||
invokeWatcherCallbacks(this.watchedDirectoriesRecursive.get(this.toPath(folderFullPath))!, cb => this.directoryCallback(cb, relativePath));
|
||||
}
|
||||
|
||||
invokeFileWatcher(fileFullPath: string, eventKind: FileWatcherEventKind, useFileNameInCallback?: boolean) {
|
||||
invokeWatcherCallbacks(this.watchedFiles.get(this.toPath(fileFullPath)), ({ cb, fileName }) => cb(useFileNameInCallback ? fileName : fileFullPath, eventKind));
|
||||
invokeWatcherCallbacks(this.watchedFiles.get(this.toPath(fileFullPath))!, ({ cb, fileName }) => cb(useFileNameInCallback ? fileName : fileFullPath, eventKind));
|
||||
}
|
||||
|
||||
private getRelativePathToDirectory(directoryFullPath: string, fileFullPath: string) {
|
||||
@@ -687,11 +687,11 @@ interface Array<T> {}`
|
||||
|
||||
private toFsFolder(path: string): FsFolder {
|
||||
const fsFolder = this.toFsEntry(path) as FsFolder;
|
||||
fsFolder.entries = [] as SortedArray<FSEntry>;
|
||||
fsFolder.entries = [] as FSEntry[] as SortedArray<FSEntry>; // https://github.com/Microsoft/TypeScript/issues/19873
|
||||
return fsFolder;
|
||||
}
|
||||
|
||||
private getRealFsEntry<T extends FSEntry>(isFsEntry: (fsEntry: FSEntry) => fsEntry is T, path: Path, fsEntry = this.fs.get(path)): T | undefined {
|
||||
private getRealFsEntry<T extends FSEntry>(isFsEntry: (fsEntry: FSEntry) => fsEntry is T, path: Path, fsEntry = this.fs.get(path)!): T | undefined {
|
||||
if (isFsEntry(fsEntry)) {
|
||||
return fsEntry;
|
||||
}
|
||||
@@ -737,21 +737,21 @@ interface Array<T> {}`
|
||||
getModifiedTime(s: string) {
|
||||
const path = this.toFullPath(s);
|
||||
const fsEntry = this.fs.get(path);
|
||||
return fsEntry && fsEntry.modifiedTime;
|
||||
return (fsEntry && fsEntry.modifiedTime)!; // TODO: GH#18217
|
||||
}
|
||||
|
||||
readFile(s: string): string {
|
||||
readFile(s: string): string | undefined {
|
||||
const fsEntry = this.getRealFile(this.toFullPath(s));
|
||||
return fsEntry ? fsEntry.content : undefined;
|
||||
}
|
||||
|
||||
getFileSize(s: string) {
|
||||
const path = this.toFullPath(s);
|
||||
const entry = this.fs.get(path);
|
||||
const entry = this.fs.get(path)!;
|
||||
if (isFsFile(entry)) {
|
||||
return entry.fileSize ? entry.fileSize : entry.content.length;
|
||||
}
|
||||
return undefined;
|
||||
return undefined!; // TODO: GH#18217
|
||||
}
|
||||
|
||||
directoryExists(s: string) {
|
||||
@@ -812,7 +812,7 @@ interface Array<T> {}`
|
||||
}
|
||||
|
||||
createSHA256Hash(s: string): string {
|
||||
return sys.createSHA256Hash(s);
|
||||
return sys.createSHA256Hash!(s);
|
||||
}
|
||||
|
||||
watchFile(fileName: string, cb: FileWatcherCallback, pollingInterval: number) {
|
||||
@@ -925,7 +925,7 @@ interface Array<T> {}`
|
||||
}
|
||||
const dirFullPath = this.realpath(getDirectoryPath(fullPath));
|
||||
const realFullPath = combinePaths(dirFullPath, getBaseFileName(fullPath));
|
||||
const fsEntry = this.fs.get(this.toPath(realFullPath));
|
||||
const fsEntry = this.fs.get(this.toPath(realFullPath))!;
|
||||
if (isFsSymLink(fsEntry)) {
|
||||
return this.realpath(fsEntry.symLink);
|
||||
}
|
||||
@@ -934,7 +934,7 @@ interface Array<T> {}`
|
||||
}
|
||||
|
||||
readonly exitMessage = "System Exit";
|
||||
exitCode: number;
|
||||
exitCode: number | undefined;
|
||||
readonly resolvePath = (s: string) => s;
|
||||
readonly getExecutingFilePath = () => this.executingFilePath;
|
||||
readonly getCurrentDirectory = () => this.currentDirectory;
|
||||
@@ -943,7 +943,7 @@ interface Array<T> {}`
|
||||
throw new Error(this.exitMessage);
|
||||
}
|
||||
getEnvironmentVariable(name: string) {
|
||||
return this.environmentVariables && this.environmentVariables.get(name);
|
||||
return this.environmentVariables && this.environmentVariables.get(name) || "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ function pipeExists(name: string): boolean {
|
||||
}
|
||||
|
||||
function createCancellationToken(args: string[]): ServerCancellationToken {
|
||||
let cancellationPipeName: string;
|
||||
let cancellationPipeName: string | undefined;
|
||||
for (let i = 0; i < args.length - 1; i++) {
|
||||
if (args[i] === "--cancellationPipeName") {
|
||||
cancellationPipeName = args[i + 1];
|
||||
@@ -43,7 +43,7 @@ function createCancellationToken(args: string[]): ServerCancellationToken {
|
||||
if (namePrefix.length === 0 || namePrefix.indexOf("*") >= 0) {
|
||||
throw new Error("Invalid name for template cancellation pipe: it should have length greater than 2 characters and contain only one '*'.");
|
||||
}
|
||||
let perRequestPipeName: string;
|
||||
let perRequestPipeName: string | undefined;
|
||||
let currentRequestId: number;
|
||||
return {
|
||||
isCancellationRequested: () => perRequestPipeName !== undefined && pipeExists(perRequestPipeName),
|
||||
@@ -61,7 +61,7 @@ function createCancellationToken(args: string[]): ServerCancellationToken {
|
||||
}
|
||||
else {
|
||||
return {
|
||||
isCancellationRequested: () => pipeExists(cancellationPipeName),
|
||||
isCancellationRequested: () => pipeExists(cancellationPipeName!), // TODO: GH#18217
|
||||
setRequest: (_requestId: number): void => void 0,
|
||||
resetRequest: (_requestId: number): void => void 0
|
||||
};
|
||||
|
||||
+52
-52
@@ -50,7 +50,7 @@ namespace ts.server {
|
||||
private getLineMap(fileName: string): number[] {
|
||||
let lineMap = this.lineMaps.get(fileName);
|
||||
if (!lineMap) {
|
||||
lineMap = computeLineStarts(getSnapshotText(this.host.getScriptSnapshot(fileName)));
|
||||
lineMap = computeLineStarts(getSnapshotText(this.host.getScriptSnapshot(fileName)!));
|
||||
this.lineMaps.set(fileName, lineMap);
|
||||
}
|
||||
return lineMap;
|
||||
@@ -89,10 +89,9 @@ namespace ts.server {
|
||||
|
||||
private processResponse<T extends protocol.Response>(request: protocol.Request): T {
|
||||
let foundResponseMessage = false;
|
||||
let lastMessage: string;
|
||||
let response: T;
|
||||
let response!: T;
|
||||
while (!foundResponseMessage) {
|
||||
lastMessage = this.messages.shift();
|
||||
const lastMessage = this.messages.shift()!;
|
||||
Debug.assert(!!lastMessage, "Did not receive any responses.");
|
||||
const responseBody = extractMessage(lastMessage);
|
||||
try {
|
||||
@@ -133,7 +132,7 @@ namespace ts.server {
|
||||
|
||||
changeFile(fileName: string, start: number, end: number, insertString: string): void {
|
||||
// clear the line map after an edit
|
||||
this.lineMaps.set(fileName, undefined);
|
||||
this.lineMaps.set(fileName, undefined!); // TODO: GH#18217
|
||||
|
||||
const args: protocol.ChangeRequestArgs = { ...this.createFileLocationRequestArgsWithEndLineAndOffset(fileName, start, end), insertString };
|
||||
this.processRequest(CommandNames.Change, args);
|
||||
@@ -149,14 +148,15 @@ namespace ts.server {
|
||||
|
||||
const request = this.processRequest<protocol.QuickInfoRequest>(CommandNames.Quickinfo, args);
|
||||
const response = this.processResponse<protocol.QuickInfoResponse>(request);
|
||||
const body = response.body!; // TODO: GH#18217
|
||||
|
||||
return {
|
||||
kind: response.body.kind,
|
||||
kindModifiers: response.body.kindModifiers,
|
||||
textSpan: this.decodeSpan(response.body, fileName),
|
||||
displayParts: [{ kind: "text", text: response.body.displayString }],
|
||||
documentation: [{ kind: "text", text: response.body.documentation }],
|
||||
tags: response.body.tags
|
||||
kind: body.kind,
|
||||
kindModifiers: body.kindModifiers,
|
||||
textSpan: this.decodeSpan(body, fileName),
|
||||
displayParts: [{ kind: "text", text: body.displayString }],
|
||||
documentation: [{ kind: "text", text: body.documentation }],
|
||||
tags: body.tags
|
||||
};
|
||||
}
|
||||
|
||||
@@ -167,8 +167,8 @@ namespace ts.server {
|
||||
const response = this.processResponse<protocol.ProjectInfoResponse>(request);
|
||||
|
||||
return {
|
||||
configFileName: response.body.configFileName,
|
||||
fileNames: response.body.fileNames
|
||||
configFileName: response.body!.configFileName, // TODO: GH#18217
|
||||
fileNames: response.body!.fileNames
|
||||
};
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ namespace ts.server {
|
||||
isGlobalCompletion: false,
|
||||
isMemberCompletion: false,
|
||||
isNewIdentifierLocation: false,
|
||||
entries: response.body.map<CompletionEntry>(entry => {
|
||||
entries: response.body!.map<CompletionEntry>(entry => { // TODO: GH#18217
|
||||
if (entry.replacementSpan !== undefined) {
|
||||
const { name, kind, kindModifiers, sortText, replacementSpan, hasAction, source, isRecommended } = entry;
|
||||
// TODO: GH#241
|
||||
@@ -201,10 +201,9 @@ namespace ts.server {
|
||||
|
||||
const request = this.processRequest<protocol.CompletionDetailsRequest>(CommandNames.CompletionDetails, args);
|
||||
const response = this.processResponse<protocol.CompletionDetailsResponse>(request);
|
||||
Debug.assert(response.body.length === 1, "Unexpected length of completion details response body.");
|
||||
|
||||
const convertedCodeActions = map(response.body[0].codeActions, ({ description, changes }) => ({ description, changes: this.convertChanges(changes, fileName) }));
|
||||
return { ...response.body[0], codeActions: convertedCodeActions };
|
||||
Debug.assert(response.body!.length === 1, "Unexpected length of completion details response body.");
|
||||
const convertedCodeActions = map(response.body![0].codeActions, ({ description, changes }) => ({ description, changes: this.convertChanges(changes, fileName) }));
|
||||
return { ...response.body![0], codeActions: convertedCodeActions };
|
||||
}
|
||||
|
||||
getCompletionEntrySymbol(_fileName: string, _position: number, _entryName: string): Symbol {
|
||||
@@ -220,14 +219,14 @@ namespace ts.server {
|
||||
const request = this.processRequest<protocol.NavtoRequest>(CommandNames.Navto, args);
|
||||
const response = this.processResponse<protocol.NavtoResponse>(request);
|
||||
|
||||
return response.body.map(entry => ({
|
||||
return response.body!.map(entry => ({ // TODO: GH#18217
|
||||
name: entry.name,
|
||||
containerName: entry.containerName || "",
|
||||
containerKind: entry.containerKind || ScriptElementKind.unknown,
|
||||
kind: entry.kind,
|
||||
kindModifiers: entry.kindModifiers,
|
||||
matchKind: entry.matchKind,
|
||||
isCaseSensitive: entry.isCaseSensitive,
|
||||
kindModifiers: entry.kindModifiers!, // TODO: GH#18217
|
||||
matchKind: entry.matchKind!, // TODO: GH#18217
|
||||
isCaseSensitive: entry.isCaseSensitive!, // TODO: GH#18217
|
||||
fileName: entry.file,
|
||||
textSpan: this.decodeSpan(entry),
|
||||
}));
|
||||
@@ -241,11 +240,11 @@ namespace ts.server {
|
||||
const request = this.processRequest<protocol.FormatRequest>(CommandNames.Format, args);
|
||||
const response = this.processResponse<protocol.FormatResponse>(request);
|
||||
|
||||
return response.body.map(entry => this.convertCodeEditsToTextChange(file, entry));
|
||||
return response.body!.map(entry => this.convertCodeEditsToTextChange(file, entry)); // TODO: GH#18217
|
||||
}
|
||||
|
||||
getFormattingEditsForDocument(fileName: string, options: FormatCodeOptions): TextChange[] {
|
||||
return this.getFormattingEditsForRange(fileName, 0, this.host.getScriptSnapshot(fileName).getLength(), options);
|
||||
return this.getFormattingEditsForRange(fileName, 0, this.host.getScriptSnapshot(fileName)!.getLength(), options);
|
||||
}
|
||||
|
||||
getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, _options: FormatCodeOptions): TextChange[] {
|
||||
@@ -255,7 +254,7 @@ namespace ts.server {
|
||||
const request = this.processRequest<protocol.FormatOnKeyRequest>(CommandNames.Formatonkey, args);
|
||||
const response = this.processResponse<protocol.FormatResponse>(request);
|
||||
|
||||
return response.body.map(entry => this.convertCodeEditsToTextChange(fileName, entry));
|
||||
return response.body!.map(entry => this.convertCodeEditsToTextChange(fileName, entry)); // TODO: GH#18217
|
||||
}
|
||||
|
||||
getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] {
|
||||
@@ -264,7 +263,7 @@ namespace ts.server {
|
||||
const request = this.processRequest<protocol.DefinitionRequest>(CommandNames.Definition, args);
|
||||
const response = this.processResponse<protocol.DefinitionResponse>(request);
|
||||
|
||||
return response.body.map(entry => ({
|
||||
return response.body!.map(entry => ({ // TODO: GH#18217
|
||||
containerKind: ScriptElementKind.unknown,
|
||||
containerName: "",
|
||||
fileName: entry.file,
|
||||
@@ -281,7 +280,7 @@ namespace ts.server {
|
||||
const response = this.processResponse<protocol.DefinitionInfoAndBoundSpanReponse>(request);
|
||||
|
||||
return {
|
||||
definitions: response.body.definitions.map(entry => ({
|
||||
definitions: response.body!.definitions.map(entry => ({ // TODO: GH#18217
|
||||
containerKind: ScriptElementKind.unknown,
|
||||
containerName: "",
|
||||
fileName: entry.file,
|
||||
@@ -289,7 +288,7 @@ namespace ts.server {
|
||||
kind: ScriptElementKind.unknown,
|
||||
name: ""
|
||||
})),
|
||||
textSpan: this.decodeSpan(response.body.textSpan, request.arguments.file)
|
||||
textSpan: this.decodeSpan(response.body!.textSpan, request.arguments.file)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -299,7 +298,7 @@ namespace ts.server {
|
||||
const request = this.processRequest<protocol.TypeDefinitionRequest>(CommandNames.TypeDefinition, args);
|
||||
const response = this.processResponse<protocol.TypeDefinitionResponse>(request);
|
||||
|
||||
return response.body.map(entry => ({
|
||||
return response.body!.map(entry => ({ // TODO: GH#18217
|
||||
containerKind: ScriptElementKind.unknown,
|
||||
containerName: "",
|
||||
fileName: entry.file,
|
||||
@@ -315,7 +314,7 @@ namespace ts.server {
|
||||
const request = this.processRequest<protocol.ImplementationRequest>(CommandNames.Implementation, args);
|
||||
const response = this.processResponse<protocol.ImplementationResponse>(request);
|
||||
|
||||
return response.body.map(entry => ({
|
||||
return response.body!.map(entry => ({ // TODO: GH#18217
|
||||
fileName: entry.file,
|
||||
textSpan: this.decodeSpan(entry),
|
||||
kind: ScriptElementKind.unknown,
|
||||
@@ -334,7 +333,7 @@ namespace ts.server {
|
||||
const request = this.processRequest<protocol.ReferencesRequest>(CommandNames.References, args);
|
||||
const response = this.processResponse<protocol.ReferencesResponse>(request);
|
||||
|
||||
return response.body.refs.map(entry => ({
|
||||
return response.body!.refs.map(entry => ({ // TODO: GH#18217
|
||||
fileName: entry.file,
|
||||
textSpan: this.decodeSpan(entry),
|
||||
isWriteAccess: entry.isWriteAccess,
|
||||
@@ -349,7 +348,7 @@ namespace ts.server {
|
||||
getSyntacticDiagnostics(file: string): DiagnosticWithLocation[] {
|
||||
return this.getDiagnostics(file, CommandNames.SyntacticDiagnosticsSync);
|
||||
}
|
||||
getSemanticDiagnostics(file: string): DiagnosticWithLocation[] {
|
||||
getSemanticDiagnostics(file: string): Diagnostic[] {
|
||||
return this.getDiagnostics(file, CommandNames.SemanticDiagnosticsSync);
|
||||
}
|
||||
getSuggestionDiagnostics(file: string): DiagnosticWithLocation[] {
|
||||
@@ -364,7 +363,7 @@ namespace ts.server {
|
||||
const category = firstDefined(Object.keys(DiagnosticCategory), id =>
|
||||
isString(id) && entry.category === id.toLowerCase() ? (<any>DiagnosticCategory)[id] : undefined);
|
||||
return {
|
||||
file: undefined,
|
||||
file: undefined!, // TODO: GH#18217
|
||||
start: entry.start,
|
||||
length: entry.length,
|
||||
messageText: entry.message,
|
||||
@@ -384,8 +383,9 @@ namespace ts.server {
|
||||
|
||||
const request = this.processRequest<protocol.RenameRequest>(CommandNames.Rename, args);
|
||||
const response = this.processResponse<protocol.RenameResponse>(request);
|
||||
const body = response.body!; // TODO: GH#18217
|
||||
const locations: RenameLocation[] = [];
|
||||
for (const entry of response.body.locs) {
|
||||
for (const entry of body.locs) {
|
||||
const fileName = entry.file;
|
||||
for (const loc of entry.locs) {
|
||||
locations.push({ textSpan: this.decodeSpan(loc, fileName), fileName });
|
||||
@@ -393,17 +393,17 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
return this.lastRenameEntry = {
|
||||
canRename: response.body.info.canRename,
|
||||
displayName: response.body.info.displayName,
|
||||
fullDisplayName: response.body.info.fullDisplayName,
|
||||
kind: response.body.info.kind,
|
||||
kindModifiers: response.body.info.kindModifiers,
|
||||
localizedErrorMessage: response.body.info.localizedErrorMessage,
|
||||
canRename: body.info.canRename,
|
||||
displayName: body.info.displayName,
|
||||
fullDisplayName: body.info.fullDisplayName,
|
||||
kind: body.info.kind,
|
||||
kindModifiers: body.info.kindModifiers,
|
||||
localizedErrorMessage: body.info.localizedErrorMessage,
|
||||
triggerSpan: createTextSpanFromBounds(position, position),
|
||||
fileName,
|
||||
position,
|
||||
findInStrings,
|
||||
findInComments,
|
||||
findInStrings: !!findInStrings,
|
||||
findInComments: !!findInComments,
|
||||
locations,
|
||||
};
|
||||
}
|
||||
@@ -420,7 +420,7 @@ namespace ts.server {
|
||||
return this.lastRenameEntry.locations;
|
||||
}
|
||||
|
||||
private decodeNavigationBarItems(items: protocol.NavigationBarItem[], fileName: string, lineMap: number[]): NavigationBarItem[] {
|
||||
private decodeNavigationBarItems(items: protocol.NavigationBarItem[] | undefined, fileName: string, lineMap: number[]): NavigationBarItem[] {
|
||||
if (!items) {
|
||||
return [];
|
||||
}
|
||||
@@ -460,7 +460,7 @@ namespace ts.server {
|
||||
const response = this.processResponse<protocol.NavTreeResponse>(request);
|
||||
|
||||
const lineMap = this.getLineMap(file);
|
||||
return this.decodeNavigationTree(response.body, file, lineMap);
|
||||
return this.decodeNavigationTree(response.body!, file, lineMap); // TODO: GH#18217
|
||||
}
|
||||
|
||||
private decodeSpan(span: protocol.TextSpan & { file: string }): TextSpan;
|
||||
@@ -488,7 +488,7 @@ namespace ts.server {
|
||||
const response = this.processResponse<protocol.SignatureHelpResponse>(request);
|
||||
|
||||
if (!response.body) {
|
||||
return undefined;
|
||||
return undefined!; // TODO: GH#18217
|
||||
}
|
||||
|
||||
const { items, applicableSpan: encodedApplicableSpan, selectedItemIndex, argumentIndex, argumentCount } = response.body;
|
||||
@@ -504,7 +504,7 @@ namespace ts.server {
|
||||
const request = this.processRequest<protocol.OccurrencesRequest>(CommandNames.Occurrences, args);
|
||||
const response = this.processResponse<protocol.OccurrencesResponse>(request);
|
||||
|
||||
return response.body.map(entry => ({
|
||||
return response.body!.map(entry => ({ // TODO: GH#18217
|
||||
fileName: entry.file,
|
||||
textSpan: this.decodeSpan(entry),
|
||||
isWriteAccess: entry.isWriteAccess,
|
||||
@@ -518,7 +518,7 @@ namespace ts.server {
|
||||
const request = this.processRequest<protocol.DocumentHighlightsRequest>(CommandNames.DocumentHighlights, args);
|
||||
const response = this.processResponse<protocol.DocumentHighlightsResponse>(request);
|
||||
|
||||
return response.body.map(item => ({
|
||||
return response.body!.map(item => ({ // TODO: GH#18217
|
||||
fileName: item.file,
|
||||
highlightSpans: item.highlightSpans.map(span => ({
|
||||
textSpan: this.decodeSpan(span, item.file),
|
||||
@@ -531,7 +531,7 @@ namespace ts.server {
|
||||
const request = this.processRequest<protocol.OutliningSpansRequest>(CommandNames.GetOutliningSpans, { file });
|
||||
const response = this.processResponse<protocol.OutliningSpansResponse>(request);
|
||||
|
||||
return response.body.map<OutliningSpan>(item => ({
|
||||
return response.body!.map<OutliningSpan>(item => ({
|
||||
textSpan: this.decodeSpan(item.textSpan, file),
|
||||
hintSpan: this.decodeSpan(item.hintSpan, file),
|
||||
bannerText: item.bannerText,
|
||||
@@ -562,7 +562,7 @@ namespace ts.server {
|
||||
const request = this.processRequest<protocol.CodeFixRequest>(CommandNames.GetCodeFixes, args);
|
||||
const response = this.processResponse<protocol.CodeFixResponse>(request);
|
||||
|
||||
return response.body.map<CodeFixAction>(({ fixName, description, changes, commands, fixId, fixAllDescription }) =>
|
||||
return response.body!.map<CodeFixAction>(({ fixName, description, changes, commands, fixId, fixAllDescription }) => // TODO: GH#18217
|
||||
({ fixName, description, changes: this.convertChanges(changes, file), commands: commands as CodeActionCommand[], fixId, fixAllDescription }));
|
||||
}
|
||||
|
||||
@@ -598,7 +598,7 @@ namespace ts.server {
|
||||
|
||||
const request = this.processRequest<protocol.GetApplicableRefactorsRequest>(CommandNames.GetApplicableRefactors, args);
|
||||
const response = this.processResponse<protocol.GetApplicableRefactorsResponse>(request);
|
||||
return response.body;
|
||||
return response.body!; // TODO: GH#18217
|
||||
}
|
||||
|
||||
getEditsForRefactor(
|
||||
@@ -624,7 +624,7 @@ namespace ts.server {
|
||||
const renameFilename: string | undefined = response.body.renameFilename;
|
||||
let renameLocation: number | undefined;
|
||||
if (renameFilename !== undefined) {
|
||||
renameLocation = this.lineOffsetToPosition(renameFilename, response.body.renameLocation);
|
||||
renameLocation = this.lineOffsetToPosition(renameFilename, response.body.renameLocation!); // TODO: GH#18217
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -672,7 +672,7 @@ namespace ts.server {
|
||||
const request = this.processRequest<protocol.BraceRequest>(CommandNames.Brace, args);
|
||||
const response = this.processResponse<protocol.BraceResponse>(request);
|
||||
|
||||
return response.body.map(entry => this.decodeSpan(entry, fileName));
|
||||
return response.body!.map(entry => this.decodeSpan(entry, fileName)); // TODO: GH#18217
|
||||
}
|
||||
|
||||
getIndentationAtPosition(_fileName: string, _position: number, _options: EditorOptions): number {
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
export interface ProjectInfoTypeAcquisitionData {
|
||||
readonly enable: boolean;
|
||||
readonly enable: boolean | undefined;
|
||||
// Actual values of include/exclude entries are scrubbed.
|
||||
readonly include: boolean;
|
||||
readonly exclude: boolean;
|
||||
@@ -225,13 +225,13 @@ namespace ts.server {
|
||||
interface FilePropertyReader<T> {
|
||||
getFileName(f: T): string;
|
||||
getScriptKind(f: T, extraFileExtensions?: FileExtensionInfo[]): ScriptKind;
|
||||
hasMixedContent(f: T, extraFileExtensions: FileExtensionInfo[]): boolean;
|
||||
hasMixedContent(f: T, extraFileExtensions: FileExtensionInfo[] | undefined): boolean;
|
||||
}
|
||||
|
||||
const fileNamePropertyReader: FilePropertyReader<string> = {
|
||||
getFileName: x => x,
|
||||
getScriptKind: (fileName, extraFileExtensions) => {
|
||||
let result: ScriptKind;
|
||||
let result: ScriptKind | undefined;
|
||||
if (extraFileExtensions) {
|
||||
const fileExtension = getAnyExtensionFromPath(fileName);
|
||||
if (fileExtension) {
|
||||
@@ -244,18 +244,18 @@ namespace ts.server {
|
||||
});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return result!; // TODO: GH#18217
|
||||
},
|
||||
hasMixedContent: (fileName, extraFileExtensions) => some(extraFileExtensions, ext => ext.isMixedContent && fileExtensionIs(fileName, ext.extension)),
|
||||
};
|
||||
|
||||
const externalFilePropertyReader: FilePropertyReader<protocol.ExternalFile> = {
|
||||
getFileName: x => x.fileName,
|
||||
getScriptKind: x => tryConvertScriptKindName(x.scriptKind),
|
||||
hasMixedContent: x => x.hasMixedContent,
|
||||
getScriptKind: x => tryConvertScriptKindName(x.scriptKind!), // TODO: GH#18217
|
||||
hasMixedContent: x => !!x.hasMixedContent,
|
||||
};
|
||||
|
||||
function findProjectByName<T extends Project>(projectName: string, projects: T[]): T {
|
||||
function findProjectByName<T extends Project>(projectName: string, projects: T[]): T | undefined {
|
||||
for (const proj of projects) {
|
||||
if (proj.getProjectName() === projectName) {
|
||||
return proj;
|
||||
@@ -374,7 +374,7 @@ namespace ts.server {
|
||||
/**
|
||||
* Open files: with value being project root path, and key being Path of the file that is open
|
||||
*/
|
||||
readonly openFiles = createMap<NormalizedPath>();
|
||||
readonly openFiles = createMap<NormalizedPath | undefined>();
|
||||
/**
|
||||
* Map of open files that are opened without complete path but have projectRoot as current directory
|
||||
*/
|
||||
@@ -413,7 +413,7 @@ namespace ts.server {
|
||||
public readonly useSingleInferredProject: boolean;
|
||||
public readonly useInferredProjectPerProjectRoot: boolean;
|
||||
public readonly typingsInstaller: ITypingsInstaller;
|
||||
private readonly globalCacheLocationDirectoryPath: Path;
|
||||
private readonly globalCacheLocationDirectoryPath: Path | undefined;
|
||||
public readonly throttleWaitMilliseconds?: number;
|
||||
private readonly eventHandler?: ProjectServiceEventHandler;
|
||||
private readonly suppressDiagnosticEvents?: boolean;
|
||||
@@ -453,8 +453,9 @@ namespace ts.server {
|
||||
}
|
||||
this.currentDirectory = toNormalizedPath(this.host.getCurrentDirectory());
|
||||
this.toCanonicalFileName = createGetCanonicalFileName(this.host.useCaseSensitiveFileNames);
|
||||
this.globalCacheLocationDirectoryPath = this.typingsInstaller.globalTypingsCacheLocation &&
|
||||
ensureTrailingDirectorySeparator(this.toPath(this.typingsInstaller.globalTypingsCacheLocation));
|
||||
this.globalCacheLocationDirectoryPath = this.typingsInstaller.globalTypingsCacheLocation
|
||||
? ensureTrailingDirectorySeparator(this.toPath(this.typingsInstaller.globalTypingsCacheLocation))
|
||||
: undefined;
|
||||
this.throttledOperations = new ThrottledOperations(this.host, this.logger);
|
||||
|
||||
if (this.typesMapLocation) {
|
||||
@@ -498,15 +499,14 @@ namespace ts.server {
|
||||
|
||||
/*@internal*/
|
||||
setDocument(key: DocumentRegistryBucketKey, path: Path, sourceFile: SourceFile) {
|
||||
const info = this.getScriptInfoForPath(path);
|
||||
Debug.assert(!!info);
|
||||
const info = Debug.assertDefined(this.getScriptInfoForPath(path));
|
||||
info.cacheSourceFile = { key, sourceFile };
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
getDocument(key: DocumentRegistryBucketKey, path: Path) {
|
||||
getDocument(key: DocumentRegistryBucketKey, path: Path): SourceFile | undefined {
|
||||
const info = this.getScriptInfoForPath(path);
|
||||
return info && info.cacheSourceFile && info.cacheSourceFile.key === key && info.cacheSourceFile.sourceFile;
|
||||
return info && info.cacheSourceFile && info.cacheSourceFile.key === key ? info.cacheSourceFile.sourceFile : undefined;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -533,7 +533,7 @@ namespace ts.server {
|
||||
|
||||
private loadTypesMap() {
|
||||
try {
|
||||
const fileContent = this.host.readFile(this.typesMapLocation);
|
||||
const fileContent = this.host.readFile(this.typesMapLocation!); // TODO: GH#18217
|
||||
if (fileContent === undefined) {
|
||||
this.logger.info(`Provided types map file "${this.typesMapLocation}" doesn't exist`);
|
||||
return;
|
||||
@@ -623,7 +623,7 @@ namespace ts.server {
|
||||
const event: ProjectsUpdatedInBackgroundEvent = {
|
||||
eventName: ProjectsUpdatedInBackgroundEvent,
|
||||
data: {
|
||||
openFiles: arrayFrom(this.openFiles.keys(), path => this.getScriptInfoForPath(path as Path).fileName)
|
||||
openFiles: arrayFrom(this.openFiles.keys(), path => this.getScriptInfoForPath(path as Path)!.fileName)
|
||||
}
|
||||
};
|
||||
this.eventHandler(event);
|
||||
@@ -673,7 +673,7 @@ namespace ts.server {
|
||||
project.projectRootPath === canonicalProjectRootPath :
|
||||
!project.projectRootPath || !this.compilerOptionsForInferredProjectsPerProjectRoot.has(project.projectRootPath)) {
|
||||
project.setCompilerOptions(compilerOptions);
|
||||
project.compileOnSaveEnabled = compilerOptions.compileOnSave;
|
||||
project.compileOnSaveEnabled = compilerOptions.compileOnSave!;
|
||||
project.markAsDirty();
|
||||
this.delayUpdateProjectGraph(project);
|
||||
}
|
||||
@@ -692,7 +692,7 @@ namespace ts.server {
|
||||
return this.findExternalProjectByProjectName(projectName) || this.findConfiguredProjectByProjectName(toNormalizedPath(projectName));
|
||||
}
|
||||
|
||||
getDefaultProjectForFile(fileName: NormalizedPath, ensureProject: boolean) {
|
||||
getDefaultProjectForFile(fileName: NormalizedPath, ensureProject: boolean): Project | undefined {
|
||||
let scriptInfo = this.getScriptInfoForNormalizedPath(fileName);
|
||||
if (ensureProject && (!scriptInfo || scriptInfo.isOrphan())) {
|
||||
this.ensureProjectStructuresUptoDate();
|
||||
@@ -702,7 +702,7 @@ namespace ts.server {
|
||||
}
|
||||
return scriptInfo.getDefaultProject();
|
||||
}
|
||||
return scriptInfo && !scriptInfo.isOrphan() && scriptInfo.getDefaultProject();
|
||||
return scriptInfo && !scriptInfo.isOrphan() ? scriptInfo.getDefaultProject() : undefined;
|
||||
}
|
||||
|
||||
getScriptInfoEnsuringProjectsUptoDate(uncheckedFileName: string) {
|
||||
@@ -810,7 +810,7 @@ namespace ts.server {
|
||||
/** Gets the config file existence info for the configured project */
|
||||
/*@internal*/
|
||||
getConfigFileExistenceInfo(project: ConfiguredProject) {
|
||||
return this.configFileExistenceInfoCache.get(project.canonicalConfigFilePath);
|
||||
return this.configFileExistenceInfoCache.get(project.canonicalConfigFilePath)!;
|
||||
}
|
||||
|
||||
private onConfigChangedForConfiguredProject(project: ConfiguredProject, eventKind: FileWatcherEventKind) {
|
||||
@@ -846,7 +846,7 @@ namespace ts.server {
|
||||
private onConfigFileChangeForOpenScriptInfo(configFileName: NormalizedPath, eventKind: FileWatcherEventKind) {
|
||||
// This callback is called only if we dont have config file project for this config file
|
||||
const canonicalConfigPath = normalizedPathToPath(configFileName, this.currentDirectory, this.toCanonicalFileName);
|
||||
const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigPath);
|
||||
const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigPath)!;
|
||||
configFileExistenceInfo.exists = (eventKind !== FileWatcherEventKind.Deleted);
|
||||
this.logConfigFileWatchUpdate(configFileName, canonicalConfigPath, configFileExistenceInfo, ConfigFileWatcherStatus.ReloadingFiles);
|
||||
|
||||
@@ -975,7 +975,7 @@ namespace ts.server {
|
||||
if (ensureProjectsForOpenFiles) {
|
||||
// collect orphaned files and assign them to inferred project just like we treat open of a file
|
||||
this.openFiles.forEach((projectRootPath, path) => {
|
||||
const info = this.getScriptInfoForPath(path as Path);
|
||||
const info = this.getScriptInfoForPath(path as Path)!;
|
||||
// collect all orphaned script infos from open files
|
||||
if (info.isOrphan()) {
|
||||
this.assignOrphanScriptInfoToInferredProject(info, projectRootPath);
|
||||
@@ -1001,7 +1001,7 @@ namespace ts.server {
|
||||
this.filenameToScriptInfo.delete(info.path);
|
||||
const realpath = info.getRealpathIfDifferent();
|
||||
if (realpath) {
|
||||
this.realpathToScriptInfos.remove(realpath, info);
|
||||
this.realpathToScriptInfos!.remove(realpath, info); // TODO: GH#18217
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1091,7 +1091,7 @@ namespace ts.server {
|
||||
const inferredRoots: string[] = [];
|
||||
const otherFiles: string[] = [];
|
||||
configFileExistenceInfo.openFilesImpactedByConfigFile.forEach((isRootOfInferredProject, key) => {
|
||||
const info = this.getScriptInfoForPath(key as Path);
|
||||
const info = this.getScriptInfoForPath(key as Path)!;
|
||||
(isRootOfInferredProject ? inferredRoots : otherFiles).push(info.fileName);
|
||||
});
|
||||
|
||||
@@ -1235,7 +1235,7 @@ namespace ts.server {
|
||||
const projectRootPath = this.openFiles.get(info.path);
|
||||
|
||||
let searchPath = asNormalizedPath(getDirectoryPath(info.fileName));
|
||||
const isSearchPathInProjectRoot = () => containsPath(projectRootPath, searchPath, this.currentDirectory, !this.host.useCaseSensitiveFileNames);
|
||||
const isSearchPathInProjectRoot = () => containsPath(projectRootPath!, searchPath, this.currentDirectory, !this.host.useCaseSensitiveFileNames);
|
||||
|
||||
// If projectRootPath doesnt contain info.path, then do normal search for config file
|
||||
const anySearchPathOk = !projectRootPath || !isSearchPathInProjectRoot();
|
||||
@@ -1310,7 +1310,7 @@ namespace ts.server {
|
||||
|
||||
this.logger.info("Open files: ");
|
||||
this.openFiles.forEach((projectRootPath, path) => {
|
||||
const info = this.getScriptInfoForPath(path as Path);
|
||||
const info = this.getScriptInfoForPath(path as Path)!;
|
||||
this.logger.info(`\tFileName: ${info.fileName} ProjectRootPath: ${projectRootPath}`);
|
||||
if (writeProjectFileNames) {
|
||||
this.logger.info(`\t\tProjects: ${info.containingProjects.map(p => p.getProjectName())}`);
|
||||
@@ -1337,7 +1337,7 @@ namespace ts.server {
|
||||
private convertConfigFileContentToProjectOptions(configFilename: string, cachedDirectoryStructureHost: CachedDirectoryStructureHost) {
|
||||
configFilename = normalizePath(configFilename);
|
||||
|
||||
const configFileContent = this.host.readFile(configFilename);
|
||||
const configFileContent = this.host.readFile(configFilename)!; // TODO: GH#18217
|
||||
|
||||
const result = parseJsonText(configFilename, configFileContent);
|
||||
if (!result.endOfFileToken) {
|
||||
@@ -1366,7 +1366,7 @@ namespace ts.server {
|
||||
configHasFilesProperty: parsedCommandLine.raw.files !== undefined,
|
||||
configHasIncludeProperty: parsedCommandLine.raw.include !== undefined,
|
||||
configHasExcludeProperty: parsedCommandLine.raw.exclude !== undefined,
|
||||
wildcardDirectories: createMapFromTemplate(parsedCommandLine.wildcardDirectories),
|
||||
wildcardDirectories: createMapFromTemplate(parsedCommandLine.wildcardDirectories!), // TODO: GH#18217
|
||||
typeAcquisition: parsedCommandLine.typeAcquisition,
|
||||
compileOnSave: parsedCommandLine.compileOnSave,
|
||||
projectReferences: parsedCommandLine.projectReferences
|
||||
@@ -1376,7 +1376,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
/** Get a filename if the language service exceeds the maximum allowed program size; otherwise returns undefined. */
|
||||
private getFilenameForExceededTotalSizeLimitForNonTsFiles<T>(name: string, options: CompilerOptions, fileNames: T[], propertyReader: FilePropertyReader<T>): string | undefined {
|
||||
private getFilenameForExceededTotalSizeLimitForNonTsFiles<T>(name: string, options: CompilerOptions | undefined, fileNames: T[], propertyReader: FilePropertyReader<T>): string | undefined {
|
||||
if (options && options.disableSizeLimit || !this.host.getFileSize) {
|
||||
return;
|
||||
}
|
||||
@@ -1414,7 +1414,7 @@ namespace ts.server {
|
||||
function getTop5LargestFiles({ propertyReader, hasTypeScriptFileExtension, host }: { propertyReader: FilePropertyReader<any>, hasTypeScriptFileExtension: (filename: string) => boolean, host: ServerHost }) {
|
||||
return fileNames.map(f => propertyReader.getFileName(f))
|
||||
.filter(name => hasTypeScriptFileExtension(name))
|
||||
.map(name => ({ name, size: host.getFileSize(name) }))
|
||||
.map(name => ({ name, size: host.getFileSize!(name) })) // TODO: GH#18217
|
||||
.sort((a, b) => b.size - a.size)
|
||||
.slice(0, 5);
|
||||
}
|
||||
@@ -1469,7 +1469,7 @@ namespace ts.server {
|
||||
return "other";
|
||||
}
|
||||
|
||||
const configFilePath = project instanceof ConfiguredProject && project.getConfigFilePath();
|
||||
const configFilePath = project instanceof ConfiguredProject ? project.getConfigFilePath() : undefined!; // TODO: GH#18217
|
||||
return getBaseConfigFileName(configFilePath) || "other";
|
||||
}
|
||||
|
||||
@@ -1490,16 +1490,16 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private createConfiguredProject(configFileName: NormalizedPath) {
|
||||
const cachedDirectoryStructureHost = createCachedDirectoryStructureHost(this.host, this.host.getCurrentDirectory(), this.host.useCaseSensitiveFileNames);
|
||||
const cachedDirectoryStructureHost = createCachedDirectoryStructureHost(this.host, this.host.getCurrentDirectory(), this.host.useCaseSensitiveFileNames)!; // TODO: GH#18217
|
||||
const { projectOptions, configFileErrors, configFileSpecs } = this.convertConfigFileContentToProjectOptions(configFileName, cachedDirectoryStructureHost);
|
||||
this.logger.info(`Opened configuration file ${configFileName}`);
|
||||
const lastFileExceededProgramSize = this.getFilenameForExceededTotalSizeLimitForNonTsFiles(configFileName, projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader);
|
||||
const lastFileExceededProgramSize = this.getFilenameForExceededTotalSizeLimitForNonTsFiles(configFileName, projectOptions.compilerOptions, projectOptions.files!, fileNamePropertyReader); // TODO: GH#18217
|
||||
const project = new ConfiguredProject(
|
||||
configFileName,
|
||||
this,
|
||||
this.documentRegistry,
|
||||
projectOptions.configHasFilesProperty,
|
||||
projectOptions.compilerOptions,
|
||||
projectOptions.compilerOptions!, // TODO: GH#18217
|
||||
lastFileExceededProgramSize,
|
||||
projectOptions.compileOnSave === undefined ? false : projectOptions.compileOnSave,
|
||||
cachedDirectoryStructureHost,
|
||||
@@ -1516,12 +1516,12 @@ namespace ts.server {
|
||||
project
|
||||
);
|
||||
if (!lastFileExceededProgramSize) {
|
||||
project.watchWildcards(projectOptions.wildcardDirectories);
|
||||
project.watchWildcards(projectOptions.wildcardDirectories!); // TODO: GH#18217
|
||||
}
|
||||
|
||||
project.setProjectErrors(configFileErrors);
|
||||
const filesToAdd = projectOptions.files.concat(project.getExternalFiles());
|
||||
this.addFilesToNonInferredProjectAndUpdateGraph(project, filesToAdd, fileNamePropertyReader, projectOptions.typeAcquisition);
|
||||
const filesToAdd = projectOptions.files!.concat(project.getExternalFiles());
|
||||
this.addFilesToNonInferredProjectAndUpdateGraph(project, filesToAdd, fileNamePropertyReader, projectOptions.typeAcquisition!); // TODO: GH#18217
|
||||
this.configuredProjects.set(project.canonicalConfigFilePath, project);
|
||||
this.setConfigFileExistenceByNewConfiguredProject(project);
|
||||
this.sendProjectTelemetry(configFileName, project, projectOptions);
|
||||
@@ -1541,7 +1541,7 @@ namespace ts.server {
|
||||
// Use the project's fileExists so that it can use caching instead of reaching to disk for the query
|
||||
if (!isDynamic && !project.fileExists(newRootFile)) {
|
||||
path = normalizedPathToPath(normalizedPath, this.currentDirectory, this.toCanonicalFileName);
|
||||
const existingValue = projectRootFilesMap.get(path);
|
||||
const existingValue = projectRootFilesMap.get(path)!;
|
||||
if (isScriptInfo(existingValue)) {
|
||||
project.removeFile(existingValue, /*fileExists*/ false, /*detachFromProject*/ true);
|
||||
}
|
||||
@@ -1551,7 +1551,7 @@ namespace ts.server {
|
||||
else {
|
||||
const scriptKind = propertyReader.getScriptKind(f, this.hostConfiguration.extraFileExtensions);
|
||||
const hasMixedContent = propertyReader.hasMixedContent(f, this.hostConfiguration.extraFileExtensions);
|
||||
scriptInfo = this.getOrCreateScriptInfoNotOpenedByClientForNormalizedPath(normalizedPath, project.currentDirectory, scriptKind, hasMixedContent, project.directoryStructureHost);
|
||||
scriptInfo = this.getOrCreateScriptInfoNotOpenedByClientForNormalizedPath(normalizedPath, project.currentDirectory, scriptKind, hasMixedContent, project.directoryStructureHost)!; // TODO: GH#18217
|
||||
path = scriptInfo.path;
|
||||
// If this script info is not already a root add it
|
||||
if (!project.isRoot(scriptInfo)) {
|
||||
@@ -1586,7 +1586,7 @@ namespace ts.server {
|
||||
project.markAsDirty();
|
||||
}
|
||||
|
||||
private updateNonInferredProject<T>(project: ExternalProject | ConfiguredProject, newUncheckedFiles: T[], propertyReader: FilePropertyReader<T>, newOptions: CompilerOptions, newTypeAcquisition: TypeAcquisition, compileOnSave: boolean) {
|
||||
private updateNonInferredProject<T>(project: ExternalProject | ConfiguredProject, newUncheckedFiles: T[], propertyReader: FilePropertyReader<T>, newOptions: CompilerOptions, newTypeAcquisition: TypeAcquisition, compileOnSave: boolean | undefined) {
|
||||
project.setCompilerOptions(newOptions);
|
||||
// VS only set the CompileOnSaveEnabled option in the request if the option was changed recently
|
||||
// therefore if it is undefined, it should not be updated.
|
||||
@@ -1601,7 +1601,7 @@ namespace ts.server {
|
||||
*/
|
||||
/*@internal*/
|
||||
reloadFileNamesOfConfiguredProject(project: ConfiguredProject): boolean {
|
||||
const configFileSpecs = project.configFileSpecs;
|
||||
const configFileSpecs = project.configFileSpecs!; // TODO: GH#18217
|
||||
const configFileName = project.getConfigFilePath();
|
||||
const fileNamesResult = getFileNamesFromConfigSpecs(configFileSpecs, getDirectoryPath(configFileName), project.getCompilationSettings(), project.getCachedDirectoryStructureHost(), this.hostConfiguration.extraFileExtensions);
|
||||
project.updateErrorOnNoInputFiles(fileNamesResult.fileNames.length !== 0);
|
||||
@@ -1629,16 +1629,16 @@ namespace ts.server {
|
||||
project.configFileSpecs = configFileSpecs;
|
||||
project.setProjectErrors(configFileErrors);
|
||||
project.updateReferences(projectOptions.projectReferences);
|
||||
const lastFileExceededProgramSize = this.getFilenameForExceededTotalSizeLimitForNonTsFiles(project.canonicalConfigFilePath, projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader);
|
||||
const lastFileExceededProgramSize = this.getFilenameForExceededTotalSizeLimitForNonTsFiles(project.canonicalConfigFilePath, projectOptions.compilerOptions, projectOptions.files!, fileNamePropertyReader); // TODO: GH#18217
|
||||
if (lastFileExceededProgramSize) {
|
||||
project.disableLanguageService(lastFileExceededProgramSize);
|
||||
project.stopWatchingWildCards();
|
||||
}
|
||||
else {
|
||||
project.enableLanguageService();
|
||||
project.watchWildcards(projectOptions.wildcardDirectories);
|
||||
project.watchWildcards(projectOptions.wildcardDirectories!); // TODO: GH#18217
|
||||
}
|
||||
this.updateNonInferredProject(project, projectOptions.files, fileNamePropertyReader, projectOptions.compilerOptions, projectOptions.typeAcquisition, projectOptions.compileOnSave);
|
||||
this.updateNonInferredProject(project, projectOptions.files!, fileNamePropertyReader, projectOptions.compilerOptions!, projectOptions.typeAcquisition!, projectOptions.compileOnSave!); // TODO: GH#18217
|
||||
this.sendConfigFileDiagEvent(project, configFileName);
|
||||
}
|
||||
|
||||
@@ -1671,7 +1671,7 @@ namespace ts.server {
|
||||
|
||||
// we don't have an explicit root path, so we should try to find an inferred project
|
||||
// that more closely contains the file.
|
||||
let bestMatch: InferredProject;
|
||||
let bestMatch: InferredProject | undefined;
|
||||
for (const project of this.inferredProjects) {
|
||||
// ignore single inferred projects (handled elsewhere)
|
||||
if (!project.projectRootPath) continue;
|
||||
@@ -1679,7 +1679,7 @@ namespace ts.server {
|
||||
if (!containsPath(project.projectRootPath, info.path, this.host.getCurrentDirectory(), !this.host.useCaseSensitiveFileNames)) continue;
|
||||
// ignore inferred projects that are higher up in the project root.
|
||||
// TODO(rbuckton): Should we add the file as a root to these as well?
|
||||
if (bestMatch && bestMatch.projectRootPath.length > project.projectRootPath.length) continue;
|
||||
if (bestMatch && bestMatch.projectRootPath!.length > project.projectRootPath.length) continue;
|
||||
bestMatch = project;
|
||||
}
|
||||
|
||||
@@ -1837,7 +1837,7 @@ namespace ts.server {
|
||||
if (!openedByClient && !isDynamic && !(hostToQueryFileExistsOn || this.host).fileExists(fileName)) {
|
||||
return;
|
||||
}
|
||||
info = new ScriptInfo(this.host, fileName, scriptKind, hasMixedContent, path);
|
||||
info = new ScriptInfo(this.host, fileName, scriptKind!, !!hasMixedContent, path); // TODO: GH#18217
|
||||
this.filenameToScriptInfo.set(info.path, info);
|
||||
if (!openedByClient) {
|
||||
this.watchClosedScriptInfo(info);
|
||||
@@ -1851,7 +1851,7 @@ namespace ts.server {
|
||||
// Opening closed script info
|
||||
// either it was created just now, or was part of projects but was closed
|
||||
this.stopWatchingScriptInfo(info);
|
||||
info.open(fileContent);
|
||||
info.open(fileContent!);
|
||||
if (hasMixedContent) {
|
||||
info.registerFileUpdate();
|
||||
}
|
||||
@@ -1878,7 +1878,7 @@ namespace ts.server {
|
||||
if (args.file) {
|
||||
const info = this.getScriptInfoForNormalizedPath(toNormalizedPath(args.file));
|
||||
if (info) {
|
||||
info.setOptions(convertFormatOptions(args.formatOptions), args.preferences);
|
||||
info.setOptions(convertFormatOptions(args.formatOptions!), args.preferences);
|
||||
this.logger.info(`Host configuration update for file ${args.file}`);
|
||||
}
|
||||
}
|
||||
@@ -1952,7 +1952,7 @@ namespace ts.server {
|
||||
return;
|
||||
}
|
||||
|
||||
const info = this.getScriptInfoForPath(path as Path);
|
||||
const info = this.getScriptInfoForPath(path as Path)!; // TODO: GH#18217
|
||||
Debug.assert(info.isScriptOpen());
|
||||
// This tries to search for a tsconfig.json for the given file. If we found it,
|
||||
// we first detect if there is already a configured project created for it: if so,
|
||||
@@ -2020,7 +2020,7 @@ namespace ts.server {
|
||||
this.printProjects();
|
||||
|
||||
this.openFiles.forEach((projectRootPath, path) => {
|
||||
const info = this.getScriptInfoForPath(path as Path);
|
||||
const info = this.getScriptInfoForPath(path as Path)!;
|
||||
// collect all orphaned script infos from open files
|
||||
if (info.isOrphan()) {
|
||||
this.assignOrphanScriptInfoToInferredProject(info, projectRootPath);
|
||||
@@ -2055,10 +2055,10 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
openClientFileWithNormalizedPath(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, projectRootPath?: NormalizedPath): OpenConfiguredProjectResult {
|
||||
let configFileName: NormalizedPath;
|
||||
let configFileErrors: ReadonlyArray<Diagnostic>;
|
||||
let configFileName: NormalizedPath | undefined;
|
||||
let configFileErrors: ReadonlyArray<Diagnostic> | undefined;
|
||||
|
||||
const info = this.getOrCreateScriptInfoOpenedByClientForNormalizedPath(fileName, projectRootPath ? this.getNormalizedAbsolutePath(projectRootPath) : this.currentDirectory, fileContent, scriptKind, hasMixedContent);
|
||||
const info = this.getOrCreateScriptInfoOpenedByClientForNormalizedPath(fileName, projectRootPath ? this.getNormalizedAbsolutePath(projectRootPath) : this.currentDirectory, fileContent, scriptKind, hasMixedContent)!; // TODO: GH#18217
|
||||
this.openFiles.set(info.path, projectRootPath);
|
||||
let project: ConfiguredProject | ExternalProject | undefined = this.findExternalProjectContainingOpenScriptInfo(info);
|
||||
if (!project && !this.syntaxOnly) { // Checking syntaxOnly is an optimization
|
||||
@@ -2100,7 +2100,6 @@ namespace ts.server {
|
||||
}
|
||||
Debug.assert(!info.isOrphan());
|
||||
|
||||
|
||||
// Remove the configured projects that have zero references from open files.
|
||||
// This was postponed from closeOpenFile to after opening next file,
|
||||
// so that we can reuse the project if we need to right away
|
||||
@@ -2141,7 +2140,7 @@ namespace ts.server {
|
||||
return;
|
||||
}
|
||||
|
||||
const info: OpenFileInfo = { checkJs: !!scriptInfo.getDefaultProject().getSourceFile(scriptInfo.path).checkJsDirective };
|
||||
const info: OpenFileInfo = { checkJs: !!scriptInfo.getDefaultProject().getSourceFile(scriptInfo.path)!.checkJsDirective };
|
||||
this.eventHandler({ eventName: OpenFileInfoTelemetryEvent, data: { info } });
|
||||
}
|
||||
|
||||
@@ -2159,7 +2158,7 @@ namespace ts.server {
|
||||
|
||||
private collectChanges(lastKnownProjectVersions: protocol.ProjectVersionInfo[], currentProjects: Project[], result: ProjectFilesWithTSDiagnostics[]): void {
|
||||
for (const proj of currentProjects) {
|
||||
const knownProject = forEach(lastKnownProjectVersions, p => p.projectName === proj.getProjectName() && p);
|
||||
const knownProject = find(lastKnownProjectVersions, p => p.projectName === proj.getProjectName());
|
||||
result.push(proj.getChangesSinceVersion(knownProject && knownProject.version));
|
||||
}
|
||||
}
|
||||
@@ -2174,19 +2173,19 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
applyChangesInOpenFiles(openFiles: protocol.ExternalFile[], changedFiles: protocol.ChangedOpenFile[], closedFiles: string[]): void {
|
||||
applyChangesInOpenFiles(openFiles: protocol.ExternalFile[] | undefined, changedFiles: protocol.ChangedOpenFile[] | undefined, closedFiles: string[] | undefined): void {
|
||||
if (openFiles) {
|
||||
for (const file of openFiles) {
|
||||
const scriptInfo = this.getScriptInfo(file.fileName);
|
||||
Debug.assert(!scriptInfo || !scriptInfo.isScriptOpen(), "Script should not exist and not be open already");
|
||||
const normalizedPath = scriptInfo ? scriptInfo.fileName : toNormalizedPath(file.fileName);
|
||||
this.openClientFileWithNormalizedPath(normalizedPath, file.content, tryConvertScriptKindName(file.scriptKind), file.hasMixedContent);
|
||||
this.openClientFileWithNormalizedPath(normalizedPath, file.content, tryConvertScriptKindName(file.scriptKind!), file.hasMixedContent); // TODO: GH#18217
|
||||
}
|
||||
}
|
||||
|
||||
if (changedFiles) {
|
||||
for (const file of changedFiles) {
|
||||
const scriptInfo = this.getScriptInfo(file.fileName);
|
||||
const scriptInfo = this.getScriptInfo(file.fileName)!;
|
||||
Debug.assert(!!scriptInfo);
|
||||
this.applyChangesToFile(scriptInfo, file.changes);
|
||||
}
|
||||
@@ -2267,7 +2266,8 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
applySafeList(proj: protocol.ExternalProject): NormalizedPath[] {
|
||||
const { rootFiles, typeAcquisition } = proj;
|
||||
const { rootFiles } = proj;
|
||||
const typeAcquisition = proj.typeAcquisition!;
|
||||
Debug.assert(!!typeAcquisition, "proj.typeAcquisition should be set by now");
|
||||
// If type acquisition has been explicitly disabled, do not exclude anything from the project
|
||||
if (typeAcquisition.enable === false) {
|
||||
@@ -2390,7 +2390,7 @@ namespace ts.server {
|
||||
|
||||
const excludedFiles = this.applySafeList(proj);
|
||||
|
||||
let tsConfigFiles: NormalizedPath[];
|
||||
let tsConfigFiles: NormalizedPath[] | undefined;
|
||||
const rootFiles: protocol.ExternalFile[] = [];
|
||||
for (const file of proj.rootFiles) {
|
||||
const normalized = toNormalizedPath(file.fileName);
|
||||
@@ -2410,7 +2410,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
const externalProject = this.findExternalProjectByProjectName(proj.projectFileName);
|
||||
let exisingConfigFiles: string[];
|
||||
let exisingConfigFiles: string[] | undefined;
|
||||
if (externalProject) {
|
||||
externalProject.excludedFiles = excludedFiles;
|
||||
if (!tsConfigFiles) {
|
||||
@@ -2438,7 +2438,7 @@ namespace ts.server {
|
||||
}
|
||||
else {
|
||||
// project previously had some config files - compare them with new set of files and close all configured projects that correspond to unused files
|
||||
const oldConfigFiles = this.externalProjectToConfiguredProjectMap.get(proj.projectFileName);
|
||||
const oldConfigFiles = this.externalProjectToConfiguredProjectMap.get(proj.projectFileName)!;
|
||||
let iNew = 0;
|
||||
let iOld = 0;
|
||||
while (iNew < tsConfigFiles.length && iOld < oldConfigFiles.length) {
|
||||
@@ -2487,7 +2487,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
hasDeferredExtension() {
|
||||
for (const extension of this.hostConfiguration.extraFileExtensions) {
|
||||
for (const extension of this.hostConfiguration.extraFileExtensions!) { // TODO: GH#18217
|
||||
if (extension.scriptKind === ScriptKind.Deferred) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+42
-42
@@ -103,7 +103,7 @@ namespace ts.server {
|
||||
cachedUnresolvedImportsPerFile = createMap<ReadonlyArray<string>>();
|
||||
|
||||
/*@internal*/
|
||||
lastCachedUnresolvedImportsList: SortedReadonlyArray<string>;
|
||||
lastCachedUnresolvedImportsList: SortedReadonlyArray<string> | undefined;
|
||||
/*@internal*/
|
||||
private hasAddedorRemovedFiles = false;
|
||||
|
||||
@@ -127,7 +127,7 @@ namespace ts.server {
|
||||
/**
|
||||
* Set of files names that were updated since the last call to getChangesSinceVersion.
|
||||
*/
|
||||
private updatedFileNames: Map<true>;
|
||||
private updatedFileNames: Map<true> | undefined;
|
||||
/**
|
||||
* Set of files that was returned from the last call to getChangesSinceVersion.
|
||||
*/
|
||||
@@ -173,7 +173,7 @@ namespace ts.server {
|
||||
public static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void): {} | undefined {
|
||||
const resolvedPath = normalizeSlashes(host.resolvePath(combinePaths(initialDir, "node_modules")));
|
||||
log(`Loading ${moduleName} from ${initialDir} (resolved to ${resolvedPath})`);
|
||||
const result = host.require(resolvedPath, moduleName);
|
||||
const result = host.require!(resolvedPath, moduleName); // TODO: GH#18217
|
||||
if (result.error) {
|
||||
const err = result.error.stack || result.error.message || JSON.stringify(result.error);
|
||||
log(`Failed to load module '${moduleName}': ${err}`);
|
||||
@@ -226,11 +226,11 @@ namespace ts.server {
|
||||
this.trace = s => this.writeLog(s);
|
||||
}
|
||||
else if (host.trace) {
|
||||
this.trace = s => host.trace(s);
|
||||
this.trace = s => host.trace!(s);
|
||||
}
|
||||
|
||||
if (host.realpath) {
|
||||
this.realpath = path => host.realpath(path);
|
||||
this.realpath = path => host.realpath!(path);
|
||||
}
|
||||
|
||||
// Use the current directory as resolution root only if the project created using current directory string
|
||||
@@ -307,15 +307,15 @@ namespace ts.server {
|
||||
|
||||
getScriptKind(fileName: string) {
|
||||
const info = this.getOrCreateScriptInfoAndAttachToProject(fileName);
|
||||
return info && info.scriptKind;
|
||||
return (info && info.scriptKind)!; // TODO: GH#18217
|
||||
}
|
||||
|
||||
getScriptVersion(filename: string) {
|
||||
const info = this.getOrCreateScriptInfoAndAttachToProject(filename);
|
||||
return info && info.getLatestVersion();
|
||||
return (info && info.getLatestVersion())!; // TODO: GH#18217
|
||||
}
|
||||
|
||||
getScriptSnapshot(filename: string): IScriptSnapshot {
|
||||
getScriptSnapshot(filename: string): IScriptSnapshot | undefined {
|
||||
const scriptInfo = this.getOrCreateScriptInfoAndAttachToProject(filename);
|
||||
if (scriptInfo) {
|
||||
return scriptInfo.getSnapshot();
|
||||
@@ -340,7 +340,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
readDirectory(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[] {
|
||||
return this.directoryStructureHost.readDirectory(path, extensions, exclude, include, depth);
|
||||
return this.directoryStructureHost.readDirectory!(path, extensions, exclude, include, depth);
|
||||
}
|
||||
|
||||
readFile(fileName: string): string | undefined {
|
||||
@@ -358,7 +358,7 @@ namespace ts.server {
|
||||
return this.resolutionCache.resolveModuleNames(moduleNames, containingFile, reusedNames);
|
||||
}
|
||||
|
||||
getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): ResolvedModuleWithFailedLookupLocations {
|
||||
getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): ResolvedModuleWithFailedLookupLocations | undefined {
|
||||
return this.resolutionCache.getResolvedModuleWithFailedLookupLocationsFromCache(moduleName, containingFile);
|
||||
}
|
||||
|
||||
@@ -367,16 +367,16 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
directoryExists(path: string): boolean {
|
||||
return this.directoryStructureHost.directoryExists(path);
|
||||
return this.directoryStructureHost.directoryExists!(path); // TODO: GH#18217
|
||||
}
|
||||
|
||||
getDirectories(path: string): string[] {
|
||||
return this.directoryStructureHost.getDirectories(path);
|
||||
return this.directoryStructureHost.getDirectories!(path); // TODO: GH#18217
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
getCachedDirectoryStructureHost(): CachedDirectoryStructureHost {
|
||||
return undefined;
|
||||
return undefined!; // TODO: GH#18217
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
@@ -471,8 +471,8 @@ namespace ts.server {
|
||||
}
|
||||
this.updateGraph();
|
||||
this.builderState = BuilderState.create(this.program, this.projectService.toCanonicalFileName, this.builderState);
|
||||
return mapDefined(BuilderState.getFilesAffectedBy(this.builderState, this.program, scriptInfo.path, this.cancellationToken, data => this.projectService.host.createHash(data)),
|
||||
sourceFile => this.shouldEmitFile(this.projectService.getScriptInfoForPath(sourceFile.path)) ? sourceFile.fileName : undefined);
|
||||
return mapDefined(BuilderState.getFilesAffectedBy(this.builderState, this.program, scriptInfo.path, this.cancellationToken, data => this.projectService.host.createHash!(data)), // TODO: GH#18217
|
||||
sourceFile => this.shouldEmitFile(this.projectService.getScriptInfoForPath(sourceFile.path)!) ? sourceFile.fileName : undefined);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -567,25 +567,25 @@ namespace ts.server {
|
||||
}
|
||||
this.projectService.pendingEnsureProjectForOpenFiles = true;
|
||||
|
||||
this.rootFiles = undefined;
|
||||
this.rootFilesMap = undefined;
|
||||
this.externalFiles = undefined;
|
||||
this.program = undefined;
|
||||
this.builderState = undefined;
|
||||
this.rootFiles = undefined!;
|
||||
this.rootFilesMap = undefined!;
|
||||
this.externalFiles = undefined!;
|
||||
this.program = undefined!;
|
||||
this.builderState = undefined!;
|
||||
this.resolutionCache.clear();
|
||||
this.resolutionCache = undefined;
|
||||
this.cachedUnresolvedImportsPerFile = undefined;
|
||||
this.directoryStructureHost = undefined;
|
||||
this.resolutionCache = undefined!;
|
||||
this.cachedUnresolvedImportsPerFile = undefined!;
|
||||
this.directoryStructureHost = undefined!;
|
||||
|
||||
// Clean up file watchers waiting for missing files
|
||||
if (this.missingFilesMap) {
|
||||
clearMap(this.missingFilesMap, closeFileWatcher);
|
||||
this.missingFilesMap = undefined;
|
||||
this.missingFilesMap = undefined!;
|
||||
}
|
||||
|
||||
// signal language service to release source files acquired from document registry
|
||||
this.languageService.dispose();
|
||||
this.languageService = undefined;
|
||||
this.languageService = undefined!;
|
||||
}
|
||||
|
||||
private detachScriptInfoIfNotRoot(uncheckedFilename: string) {
|
||||
@@ -623,17 +623,15 @@ namespace ts.server {
|
||||
return this.rootFiles;
|
||||
}
|
||||
|
||||
getScriptInfos() {
|
||||
getScriptInfos(): ScriptInfo[] {
|
||||
if (!this.languageServiceEnabled) {
|
||||
// if language service is not enabled - return just root files
|
||||
return this.rootFiles;
|
||||
}
|
||||
return map(this.program.getSourceFiles(), sourceFile => {
|
||||
const scriptInfo = this.projectService.getScriptInfoForPath(sourceFile.path);
|
||||
if (!scriptInfo) {
|
||||
Debug.fail(`scriptInfo for a file '${sourceFile.fileName}' Path: '${sourceFile.path}' is missing.`);
|
||||
}
|
||||
return scriptInfo;
|
||||
Debug.assert(!!scriptInfo, "getScriptInfo", () => `scriptInfo for a file '${sourceFile.fileName}' Path: '${sourceFile.path}' is missing.`);
|
||||
return scriptInfo!;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -701,11 +699,12 @@ namespace ts.server {
|
||||
return this.isRoot(info) || (this.program && this.program.getSourceFileByPath(info.path) !== undefined);
|
||||
}
|
||||
|
||||
containsFile(filename: NormalizedPath, requireOpen?: boolean) {
|
||||
containsFile(filename: NormalizedPath, requireOpen?: boolean): boolean {
|
||||
const info = this.projectService.getScriptInfoForPath(this.toPath(filename));
|
||||
if (info && (info.isScriptOpen() || !requireOpen)) {
|
||||
return this.containsScriptInfo(info);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
isRoot(info: ScriptInfo) {
|
||||
@@ -879,7 +878,7 @@ namespace ts.server {
|
||||
const start = timestamp();
|
||||
this.hasInvalidatedResolution = this.resolutionCache.createHasInvalidatedResolution();
|
||||
this.resolutionCache.startCachingPerDirectoryResolution();
|
||||
this.program = this.languageService.getProgram();
|
||||
this.program = this.languageService.getProgram()!; // TODO: GH#18217
|
||||
this.dirty = false;
|
||||
this.resolutionCache.finishCachingPerDirectoryResolution();
|
||||
|
||||
@@ -888,7 +887,7 @@ namespace ts.server {
|
||||
// bump up the version if
|
||||
// - oldProgram is not set - this is a first time updateGraph is called
|
||||
// - newProgram is different from the old program and structure of the old program was not reused.
|
||||
const hasNewProgram = this.program && (!oldProgram || (this.program !== oldProgram && !(oldProgram.structureIsReused & StructureIsReused.Completely)));
|
||||
const hasNewProgram = this.program && (!oldProgram || (this.program !== oldProgram && !(oldProgram.structureIsReused! & StructureIsReused.Completely)));
|
||||
this.hasChangedAutomaticTypeDirectiveNames = false;
|
||||
if (hasNewProgram) {
|
||||
if (oldProgram) {
|
||||
@@ -922,7 +921,7 @@ namespace ts.server {
|
||||
// by the LSHost for files in the program when the program is retrieved above but
|
||||
// the program doesn't contain external files so this must be done explicitly.
|
||||
inserted => {
|
||||
const scriptInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient(inserted, this.currentDirectory, this.directoryStructureHost);
|
||||
const scriptInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient(inserted, this.currentDirectory, this.directoryStructureHost)!;
|
||||
scriptInfo.attachToProject(this);
|
||||
},
|
||||
removed => this.detachScriptInfoFromProject(removed)
|
||||
@@ -1212,7 +1211,8 @@ namespace ts.server {
|
||||
ProjectKind.Inferred,
|
||||
projectService,
|
||||
documentRegistry,
|
||||
/*files*/ undefined,
|
||||
// TODO: GH#18217
|
||||
/*files*/ undefined!,
|
||||
/*lastFileExceededProgramSize*/ undefined,
|
||||
compilerOptions,
|
||||
/*compileOnSaveEnabled*/ false,
|
||||
@@ -1279,7 +1279,7 @@ namespace ts.server {
|
||||
export class ConfiguredProject extends Project {
|
||||
private typeAcquisition: TypeAcquisition;
|
||||
/* @internal */
|
||||
configFileWatcher: FileWatcher;
|
||||
configFileWatcher: FileWatcher | undefined;
|
||||
private directoriesWatchedForWildcards: Map<WildcardDirectoryWatcher> | undefined;
|
||||
readonly canonicalConfigFilePath: NormalizedPath;
|
||||
|
||||
@@ -1287,12 +1287,12 @@ namespace ts.server {
|
||||
pendingReload: ConfigFileProgramReloadLevel;
|
||||
|
||||
/*@internal*/
|
||||
configFileSpecs: ConfigFileSpecs;
|
||||
configFileSpecs: ConfigFileSpecs | undefined;
|
||||
|
||||
/** Ref count to the project when opened from external project */
|
||||
private externalProjectRefCount = 0;
|
||||
|
||||
private projectErrors: Diagnostic[];
|
||||
private projectErrors: Diagnostic[] | undefined;
|
||||
|
||||
/*@internal*/
|
||||
constructor(configFileName: NormalizedPath,
|
||||
@@ -1473,7 +1473,7 @@ namespace ts.server {
|
||||
// The project is referenced only if open files impacted by this project are present in this project
|
||||
return forEachEntry(
|
||||
configFileExistenceInfo.openFilesImpactedByConfigFile,
|
||||
(_value, infoPath) => this.containsScriptInfo(this.projectService.getScriptInfoForPath(infoPath as Path))
|
||||
(_value, infoPath) => this.containsScriptInfo(this.projectService.getScriptInfoForPath(infoPath as Path)!)
|
||||
) || false;
|
||||
}
|
||||
|
||||
@@ -1484,10 +1484,10 @@ namespace ts.server {
|
||||
/*@internal*/
|
||||
updateErrorOnNoInputFiles(hasFileNames: boolean) {
|
||||
if (hasFileNames) {
|
||||
filterMutate(this.projectErrors, error => !isErrorNoInputFiles(error));
|
||||
filterMutate(this.projectErrors!, error => !isErrorNoInputFiles(error)); // TODO: GH#18217
|
||||
}
|
||||
else if (!this.configFileSpecs.filesSpecs && !some(this.projectErrors, isErrorNoInputFiles)) {
|
||||
this.projectErrors.push(getErrorForNoInputFiles(this.configFileSpecs, this.getConfigFilePath()));
|
||||
else if (!this.configFileSpecs!.filesSpecs && !some(this.projectErrors, isErrorNoInputFiles)) { // TODO: GH#18217
|
||||
this.projectErrors!.push(getErrorForNoInputFiles(this.configFileSpecs!, this.getConfigFilePath()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1201,7 +1201,7 @@ namespace ts.server.protocol {
|
||||
/**
|
||||
* Filename of the last file analyzed before disabling the language service. undefined, if the language service is enabled.
|
||||
*/
|
||||
lastFileExceededProgramSize: string | undefined;
|
||||
lastFileExceededProgramSize?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1809,7 +1809,7 @@ namespace ts.server.protocol {
|
||||
|
||||
export interface CompletionEntryIdentifier {
|
||||
name: string;
|
||||
source: string;
|
||||
source?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1853,7 +1853,7 @@ namespace ts.server.protocol {
|
||||
/**
|
||||
* Optional modifiers for the kind (such as 'public').
|
||||
*/
|
||||
kindModifiers: string;
|
||||
kindModifiers?: string;
|
||||
/**
|
||||
* A string that is used for comparing completion items so that they can be ordered. This
|
||||
* is often the same as the name but may be different in certain circumstances.
|
||||
@@ -1912,12 +1912,12 @@ namespace ts.server.protocol {
|
||||
/**
|
||||
* Documentation strings for the symbol.
|
||||
*/
|
||||
documentation: SymbolDisplayPart[];
|
||||
documentation?: SymbolDisplayPart[];
|
||||
|
||||
/**
|
||||
* JSDoc tags for the symbol.
|
||||
*/
|
||||
tags: JSDocTagInfo[];
|
||||
tags?: JSDocTagInfo[];
|
||||
|
||||
/**
|
||||
* The associated code actions for this entry
|
||||
|
||||
+14
-14
@@ -14,11 +14,11 @@ namespace ts.server {
|
||||
* The script version cache is generated on demand and text is still retained.
|
||||
* Only on edits to the script version cache, the text will be set to undefined
|
||||
*/
|
||||
private text: string;
|
||||
private text: string | undefined;
|
||||
/**
|
||||
* Line map for the text when there is no script version cache present
|
||||
*/
|
||||
private lineMap: number[];
|
||||
private lineMap: number[] | undefined;
|
||||
private textVersion = 0;
|
||||
|
||||
/**
|
||||
@@ -115,7 +115,7 @@ namespace ts.server {
|
||||
|
||||
public getSnapshot(): IScriptSnapshot {
|
||||
return this.useScriptVersionCacheIfValidOrOpen()
|
||||
? this.svc.getSnapshot()
|
||||
? this.svc!.getSnapshot()
|
||||
: ScriptSnapshot.fromString(this.getOrLoadText());
|
||||
}
|
||||
|
||||
@@ -129,10 +129,10 @@ namespace ts.server {
|
||||
if (!this.useScriptVersionCacheIfValidOrOpen()) {
|
||||
const lineMap = this.getLineMap();
|
||||
const start = lineMap[line]; // -1 since line is 1-based
|
||||
const end = line + 1 < lineMap.length ? lineMap[line + 1] : this.text.length;
|
||||
const end = line + 1 < lineMap.length ? lineMap[line + 1] : this.text!.length;
|
||||
return createTextSpanFromBounds(start, end);
|
||||
}
|
||||
return this.svc.lineToTextSpan(line);
|
||||
return this.svc!.lineToTextSpan(line);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,7 +145,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
// TODO: assert this offset is actually on the line
|
||||
return this.svc.lineOffsetToPosition(line, offset);
|
||||
return this.svc!.lineOffsetToPosition(line, offset);
|
||||
}
|
||||
|
||||
positionToLineOffset(position: number): protocol.Location {
|
||||
@@ -153,7 +153,7 @@ namespace ts.server {
|
||||
const { line, character } = computeLineAndCharacterOfPosition(this.getLineMap(), position);
|
||||
return { line: line + 1, offset: character + 1 };
|
||||
}
|
||||
return this.svc.positionToLineOffset(position);
|
||||
return this.svc!.positionToLineOffset(position);
|
||||
}
|
||||
|
||||
private getFileText(tempFileName?: string) {
|
||||
@@ -188,7 +188,7 @@ namespace ts.server {
|
||||
Debug.assert(!this.svc || this.pendingReloadFromDisk, "ScriptVersionCache should not be set when reloading from disk");
|
||||
this.reloadWithFileText();
|
||||
}
|
||||
return this.text;
|
||||
return this.text!;
|
||||
}
|
||||
|
||||
private getLineMap() {
|
||||
@@ -217,7 +217,7 @@ namespace ts.server {
|
||||
private preferences: UserPreferences | undefined;
|
||||
|
||||
/* @internal */
|
||||
fileWatcher: FileWatcher;
|
||||
fileWatcher: FileWatcher | undefined;
|
||||
private textStorage: TextStorage;
|
||||
|
||||
/*@internal*/
|
||||
@@ -294,7 +294,7 @@ namespace ts.server {
|
||||
this.realpath = project.toPath(realpath);
|
||||
// If it is different from this.path, add to the map
|
||||
if (this.realpath !== this.path) {
|
||||
project.projectService.realpathToScriptInfos.add(this.realpath, this);
|
||||
project.projectService.realpathToScriptInfos!.add(this.realpath, this); // TODO: GH#18217
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -306,8 +306,8 @@ namespace ts.server {
|
||||
return this.realpath && this.realpath !== this.path ? this.realpath : undefined;
|
||||
}
|
||||
|
||||
getFormatCodeSettings(): FormatCodeSettings { return this.formatSettings; }
|
||||
getPreferences(): UserPreferences { return this.preferences; }
|
||||
getFormatCodeSettings(): FormatCodeSettings | undefined { return this.formatSettings; }
|
||||
getPreferences(): UserPreferences | undefined { return this.preferences; }
|
||||
|
||||
attachToProject(project: Project): boolean {
|
||||
const isNew = !this.isAttached(project);
|
||||
@@ -345,7 +345,7 @@ namespace ts.server {
|
||||
case 2:
|
||||
if (this.containingProjects[0] === project) {
|
||||
project.onFileAddedOrRemoved();
|
||||
this.containingProjects[0] = this.containingProjects.pop();
|
||||
this.containingProjects[0] = this.containingProjects.pop()!;
|
||||
}
|
||||
else if (this.containingProjects[1] === project) {
|
||||
project.onFileAddedOrRemoved();
|
||||
@@ -406,7 +406,7 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
setOptions(formatSettings: FormatCodeSettings, preferences: UserPreferences): void {
|
||||
setOptions(formatSettings: FormatCodeSettings, preferences: UserPreferences | undefined): void {
|
||||
if (formatSettings) {
|
||||
if (!this.formatSettings) {
|
||||
this.formatSettings = getDefaultFormatCodeSettings(this.host);
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace ts.server {
|
||||
this.stack = [this.lineIndex.root];
|
||||
}
|
||||
|
||||
insertLines(insertedText: string, suppressTrailingText: boolean) {
|
||||
insertLines(insertedText: string | undefined, suppressTrailingText: boolean) {
|
||||
if (suppressTrailingText) {
|
||||
this.trailingText = "";
|
||||
}
|
||||
@@ -72,8 +72,8 @@ namespace ts.server {
|
||||
lines.pop();
|
||||
}
|
||||
}
|
||||
let branchParent: LineNode;
|
||||
let lastZeroCount: LineCollection;
|
||||
let branchParent: LineNode | undefined;
|
||||
let lastZeroCount: LineCollection | undefined;
|
||||
|
||||
for (let k = this.endBranch.length - 1; k >= 0; k--) {
|
||||
(<LineNode>this.endBranch[k]).updateCounts();
|
||||
@@ -88,7 +88,7 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
if (lastZeroCount) {
|
||||
branchParent.remove(lastZeroCount);
|
||||
branchParent!.remove(lastZeroCount);
|
||||
}
|
||||
|
||||
// path at least length two (root and leaf)
|
||||
@@ -159,7 +159,7 @@ namespace ts.server {
|
||||
this.lineCollectionAtBranch = lineCollection;
|
||||
}
|
||||
|
||||
let child: LineCollection;
|
||||
let child: LineCollection | undefined;
|
||||
function fresh(node: LineCollection): LineCollection {
|
||||
if (node.isLeaf()) {
|
||||
return new LineLeaf("");
|
||||
@@ -332,7 +332,7 @@ namespace ts.server {
|
||||
if (oldVersion >= this.minVersion) {
|
||||
const textChangeRanges: TextChangeRange[] = [];
|
||||
for (let i = oldVersion + 1; i <= newVersion; i++) {
|
||||
const snap = this.versions[this.versionToIndex(i)];
|
||||
const snap = this.versions[this.versionToIndex(i)!]; // TODO: GH#18217
|
||||
for (const textChange of snap.changesSincePreviousVersion) {
|
||||
textChangeRanges.push(textChange.getTextChangeRange());
|
||||
}
|
||||
@@ -370,7 +370,7 @@ namespace ts.server {
|
||||
return this.index.getLength();
|
||||
}
|
||||
|
||||
getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange {
|
||||
getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange | undefined {
|
||||
if (oldSnapshot instanceof LineIndexSnapshot && this.cache === oldSnapshot.cache) {
|
||||
if (this.version <= oldSnapshot.version) {
|
||||
return unchangedTextChangeRange;
|
||||
@@ -397,7 +397,7 @@ namespace ts.server {
|
||||
return { line: oneBasedLine, offset: zeroBasedColumn + 1 };
|
||||
}
|
||||
|
||||
private positionToColumnAndLineText(position: number): { zeroBasedColumn: number, lineText: string } {
|
||||
private positionToColumnAndLineText(position: number): { zeroBasedColumn: number, lineText: string | undefined } {
|
||||
return this.root.charOffsetToLineInfo(1, position);
|
||||
}
|
||||
|
||||
@@ -471,9 +471,10 @@ namespace ts.server {
|
||||
this.load(LineIndex.linesFromText(newText).lines);
|
||||
return this;
|
||||
}
|
||||
return undefined!; // TODO: GH#18217
|
||||
}
|
||||
else {
|
||||
let checkText: string;
|
||||
let checkText: string | undefined;
|
||||
if (this.checkEdits) {
|
||||
const source = this.getText(0, this.root.charCount());
|
||||
checkText = source.slice(0, pos) + newText + source.slice(pos + deleteLength);
|
||||
@@ -499,7 +500,7 @@ namespace ts.server {
|
||||
const { zeroBasedColumn, lineText } = this.positionToColumnAndLineText(e);
|
||||
if (zeroBasedColumn === 0) {
|
||||
// move range end just past line that will merge with previous line
|
||||
deleteLength += lineText.length;
|
||||
deleteLength += lineText!.length; // TODO: GH#18217
|
||||
// store text by appending to end of insertedText
|
||||
newText = newText ? newText + lineText : lineText;
|
||||
}
|
||||
@@ -700,7 +701,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private splitAfter(childIndex: number) {
|
||||
let splitNode: LineNode;
|
||||
let splitNode: LineNode | undefined;
|
||||
const clen = this.children.length;
|
||||
childIndex++;
|
||||
const endLength = childIndex;
|
||||
|
||||
+20
-19
@@ -1,3 +1,5 @@
|
||||
// tslint:disable no-unnecessary-type-assertion (TODO: tslint can't find node types)
|
||||
|
||||
namespace ts.server {
|
||||
const childProcess: {
|
||||
fork(modulePath: string, args: string[], options?: { execArgv: string[], env?: MapLike<string> }): NodeChildProcess;
|
||||
@@ -38,8 +40,7 @@ namespace ts.server {
|
||||
return combinePaths(combinePaths(cacheLocation, "typescript"), versionMajorMinor);
|
||||
}
|
||||
default:
|
||||
Debug.fail(`unsupported platform '${process.platform}'`);
|
||||
return;
|
||||
return Debug.fail(`unsupported platform '${process.platform}'`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,7 +201,7 @@ namespace ts.server {
|
||||
if (this.fd >= 0) {
|
||||
const buf = new Buffer(s);
|
||||
// tslint:disable-next-line no-null-keyword
|
||||
fs.writeSync(this.fd, buf, 0, buf.length, /*position*/ null);
|
||||
fs.writeSync(this.fd, buf, 0, buf.length, /*position*/ null!); // TODO: GH#18217
|
||||
}
|
||||
if (this.traceToConsole) {
|
||||
console.warn(s);
|
||||
@@ -230,7 +231,7 @@ namespace ts.server {
|
||||
// buffer, but we have yet to find a way to retrieve that value.
|
||||
private static readonly maxActiveRequestCount = 10;
|
||||
private static readonly requestDelayMillis = 100;
|
||||
private packageInstalledPromise: { resolve(value: ApplyCodeActionCommandResult): void, reject(reason: any): void };
|
||||
private packageInstalledPromise: { resolve(value: ApplyCodeActionCommandResult): void, reject(reason: any): void } | undefined;
|
||||
|
||||
constructor(
|
||||
private readonly telemetryEnabled: boolean,
|
||||
@@ -364,10 +365,10 @@ namespace ts.server {
|
||||
case ActionPackageInstalled: {
|
||||
const { success, message } = response;
|
||||
if (success) {
|
||||
this.packageInstalledPromise.resolve({ successMessage: message });
|
||||
this.packageInstalledPromise!.resolve({ successMessage: message });
|
||||
}
|
||||
else {
|
||||
this.packageInstalledPromise.reject(message);
|
||||
this.packageInstalledPromise!.reject(message);
|
||||
}
|
||||
this.packageInstalledPromise = undefined;
|
||||
|
||||
@@ -435,7 +436,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
while (this.requestQueue.length > 0) {
|
||||
const queuedRequest = this.requestQueue.shift();
|
||||
const queuedRequest = this.requestQueue.shift()!;
|
||||
if (this.requestMap.get(queuedRequest.operationId) === queuedRequest) {
|
||||
this.requestMap.delete(queuedRequest.operationId);
|
||||
this.scheduleRequest(queuedRequest);
|
||||
@@ -468,7 +469,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
class IOSession extends Session {
|
||||
private eventPort: number;
|
||||
private eventPort: number | undefined;
|
||||
private eventSocket: NodeSocket | undefined;
|
||||
private socketEventQueue: { body: any, eventName: string }[] | undefined;
|
||||
private constructed: boolean | undefined;
|
||||
@@ -529,7 +530,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
event<T extends object>(body: T, eventName: string): void {
|
||||
Debug.assert(this.constructed, "Should only call `IOSession.prototype.event` on an initialized IOSession");
|
||||
Debug.assert(!!this.constructed, "Should only call `IOSession.prototype.event` on an initialized IOSession");
|
||||
|
||||
if (this.canUseEvents && this.eventPort) {
|
||||
if (!this.eventSocket) {
|
||||
@@ -550,7 +551,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private writeToEventSocket(body: object, eventName: string): void {
|
||||
this.eventSocket.write(formatMessage(toEvent(eventName, body), this.logger, this.byteLength, this.host.newLine), "utf8");
|
||||
this.eventSocket!.write(formatMessage(toEvent(eventName, body), this.logger, this.byteLength, this.host.newLine), "utf8");
|
||||
}
|
||||
|
||||
exit() {
|
||||
@@ -578,7 +579,7 @@ namespace ts.server {
|
||||
logToFile?: boolean;
|
||||
}
|
||||
|
||||
function parseLoggingEnvironmentString(logEnvStr: string): LogOptions {
|
||||
function parseLoggingEnvironmentString(logEnvStr: string | undefined): LogOptions {
|
||||
if (!logEnvStr) {
|
||||
return {};
|
||||
}
|
||||
@@ -625,7 +626,7 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
function getLogLevel(level: string) {
|
||||
function getLogLevel(level: string | undefined) {
|
||||
if (level) {
|
||||
const l = level.toLowerCase();
|
||||
for (const name in LogLevel) {
|
||||
@@ -650,7 +651,7 @@ namespace ts.server {
|
||||
: undefined;
|
||||
|
||||
const logVerbosity = cmdLineVerbosity || envLogOptions.detailLevel;
|
||||
return new Logger(logFileName, envLogOptions.traceToConsole, logVerbosity);
|
||||
return new Logger(logFileName!, envLogOptions.traceToConsole!, logVerbosity!); // TODO: GH#18217
|
||||
}
|
||||
// This places log file in the directory containing editorServices.js
|
||||
// TODO: check that this location is writable
|
||||
@@ -765,11 +766,11 @@ namespace ts.server {
|
||||
function setCanWriteFlagAndWriteMessageIfNecessary() {
|
||||
canWrite = true;
|
||||
if (pending.length) {
|
||||
writeMessage(pending.shift());
|
||||
writeMessage(pending.shift()!);
|
||||
}
|
||||
}
|
||||
|
||||
function extractWatchDirectoryCacheKey(path: string, currentDriveKey: string) {
|
||||
function extractWatchDirectoryCacheKey(path: string, currentDriveKey: string | undefined) {
|
||||
path = normalizeSlashes(path);
|
||||
if (isUNCPath(path)) {
|
||||
// UNC path: extract server name
|
||||
@@ -804,7 +805,7 @@ namespace ts.server {
|
||||
const sys = <ServerHost>ts.sys;
|
||||
const nodeVersion = getNodeMajorVersion();
|
||||
// use watchGuard process on Windows when node version is 4 or later
|
||||
const useWatchGuard = process.platform === "win32" && nodeVersion >= 4;
|
||||
const useWatchGuard = process.platform === "win32" && nodeVersion! >= 4;
|
||||
const originalWatchDirectory: ServerHost["watchDirectory"] = sys.watchDirectory.bind(sys);
|
||||
const noopWatcher: FileWatcher = { close: noop };
|
||||
// This is the function that catches the exceptions when watching directory, and yet lets project service continue to function
|
||||
@@ -905,8 +906,8 @@ namespace ts.server {
|
||||
let eventPort: number | undefined;
|
||||
{
|
||||
const str = findArgument("--eventPort");
|
||||
const v = str && parseInt(str);
|
||||
if (!isNaN(v)) {
|
||||
const v = str === undefined ? undefined : parseInt(str);
|
||||
if (v !== undefined && !isNaN(v)) {
|
||||
eventPort = v;
|
||||
}
|
||||
}
|
||||
@@ -918,7 +919,7 @@ namespace ts.server {
|
||||
|
||||
setStackTraceLimit();
|
||||
|
||||
const typingSafeListLocation = findArgument(Arguments.TypingSafeListLocation);
|
||||
const typingSafeListLocation = findArgument(Arguments.TypingSafeListLocation)!; // TODO: GH#18217
|
||||
const typesMapLocation = findArgument(Arguments.TypesMapLocation) || combinePaths(sys.getExecutingFilePath(), "../typesMap.json");
|
||||
const npmLocation = findArgument(Arguments.NpmLocation);
|
||||
|
||||
|
||||
+105
-105
@@ -68,10 +68,10 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
function formatDiag(fileName: NormalizedPath, project: Project, diag: Diagnostic): protocol.Diagnostic {
|
||||
const scriptInfo = project.getScriptInfoForNormalizedPath(fileName);
|
||||
const scriptInfo = project.getScriptInfoForNormalizedPath(fileName)!; // TODO: GH#18217
|
||||
return {
|
||||
start: scriptInfo.positionToLineOffset(diag.start),
|
||||
end: scriptInfo.positionToLineOffset(diag.start + diag.length),
|
||||
start: scriptInfo.positionToLineOffset(diag.start!),
|
||||
end: scriptInfo.positionToLineOffset(diag.start! + diag.length!), // TODO: GH#18217
|
||||
text: flattenDiagnosticMessageText(diag.messageText, "\n"),
|
||||
code: diag.code,
|
||||
category: diagnosticCategoryName(diag),
|
||||
@@ -87,8 +87,8 @@ namespace ts.server {
|
||||
function formatConfigFileDiag(diag: Diagnostic, includeFileName: true): protocol.DiagnosticWithFileName;
|
||||
function formatConfigFileDiag(diag: Diagnostic, includeFileName: false): protocol.Diagnostic;
|
||||
function formatConfigFileDiag(diag: Diagnostic, includeFileName: boolean): protocol.Diagnostic | protocol.DiagnosticWithFileName {
|
||||
const start = diag.file && convertToLocation(getLineAndCharacterOfPosition(diag.file, diag.start));
|
||||
const end = diag.file && convertToLocation(getLineAndCharacterOfPosition(diag.file, diag.start + diag.length));
|
||||
const start = (diag.file && convertToLocation(getLineAndCharacterOfPosition(diag.file, diag.start!)))!; // TODO: GH#18217
|
||||
const end = (diag.file && convertToLocation(getLineAndCharacterOfPosition(diag.file, diag.start! + diag.length!)))!; // TODO: GH#18217
|
||||
const text = flattenDiagnosticMessageText(diag.messageText, "\n");
|
||||
const { code, source } = diag;
|
||||
const category = diagnosticCategoryName(diag);
|
||||
@@ -177,7 +177,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
public immediate(action: () => void) {
|
||||
const requestId = this.requestId;
|
||||
const requestId = this.requestId!;
|
||||
Debug.assert(requestId === this.operationHost.getCurrentRequestId(), "immediate: incorrect request id");
|
||||
this.setImmediateId(this.operationHost.getServerHost().setImmediate(() => {
|
||||
this.immediateId = undefined;
|
||||
@@ -186,7 +186,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
public delay(ms: number, action: () => void) {
|
||||
const requestId = this.requestId;
|
||||
const requestId = this.requestId!;
|
||||
Debug.assert(requestId === this.operationHost.getCurrentRequestId(), "delay: incorrect request id");
|
||||
this.setTimerHandle(this.operationHost.getServerHost().setTimeout(() => {
|
||||
this.timerHandle = undefined;
|
||||
@@ -223,7 +223,7 @@ namespace ts.server {
|
||||
this.timerHandle = timerHandle;
|
||||
}
|
||||
|
||||
private setImmediateId(immediateId: number) {
|
||||
private setImmediateId(immediateId: number | undefined) {
|
||||
if (this.immediateId !== undefined) {
|
||||
this.operationHost.getServerHost().clearImmediate(this.immediateId);
|
||||
}
|
||||
@@ -319,7 +319,7 @@ namespace ts.server {
|
||||
|
||||
protected canUseEvents: boolean;
|
||||
private suppressDiagnosticEvents?: boolean;
|
||||
private eventHandler: ProjectServiceEventHandler;
|
||||
private eventHandler: ProjectServiceEventHandler | undefined;
|
||||
private readonly noGetErrOnBackgroundUpdate?: boolean;
|
||||
|
||||
constructor(opts: SessionOptions) {
|
||||
@@ -426,7 +426,7 @@ namespace ts.server {
|
||||
if (err.message) {
|
||||
msg += ":\n" + indent(err.message);
|
||||
if ((<StackTraceError>err).stack) {
|
||||
msg += "\n" + indent((<StackTraceError>err).stack);
|
||||
msg += "\n" + indent((<StackTraceError>err).stack!);
|
||||
}
|
||||
}
|
||||
this.logger.msg(msg, Msg.Err);
|
||||
@@ -449,7 +449,7 @@ namespace ts.server {
|
||||
// For backwards-compatibility only.
|
||||
/** @deprecated */
|
||||
public output(info: any, cmdName: string, reqSeq?: number, errorMsg?: string): void {
|
||||
this.doOutput(info, cmdName, reqSeq, /*success*/ !errorMsg, errorMsg);
|
||||
this.doOutput(info, cmdName, reqSeq!, /*success*/ !errorMsg, errorMsg); // TODO: GH#18217
|
||||
}
|
||||
|
||||
private doOutput(info: {} | undefined, cmdName: string, reqSeq: number, success: boolean, message?: string): void {
|
||||
@@ -573,16 +573,16 @@ namespace ts.server {
|
||||
return project.getLanguageService().getEncodedSemanticClassifications(file, args);
|
||||
}
|
||||
|
||||
private getProject(projectFileName: string) {
|
||||
return projectFileName && this.projectService.findProject(projectFileName);
|
||||
private getProject(projectFileName: string | undefined): Project | undefined {
|
||||
return projectFileName === undefined ? undefined : this.projectService.findProject(projectFileName);
|
||||
}
|
||||
|
||||
private getConfigFileAndProject(args: protocol.FileRequestArgs) {
|
||||
private getConfigFileAndProject(args: protocol.FileRequestArgs): { configFile: NormalizedPath | undefined, project: Project | undefined } {
|
||||
const project = this.getProject(args.projectFileName);
|
||||
const file = toNormalizedPath(args.file);
|
||||
|
||||
return {
|
||||
configFile: project && project.hasConfigFile(file) && file,
|
||||
configFile: project && project.hasConfigFile(file) ? file : undefined,
|
||||
project
|
||||
};
|
||||
}
|
||||
@@ -592,7 +592,7 @@ namespace ts.server {
|
||||
const optionsErrors = project.getLanguageService().getCompilerOptionsDiagnostics();
|
||||
const diagnosticsForConfigFile = filter(
|
||||
concatenate(projectErrors, optionsErrors),
|
||||
diagnostic => diagnostic.file && diagnostic.file.fileName === configFile
|
||||
diagnostic => !!diagnostic.file && diagnostic.file.fileName === configFile
|
||||
);
|
||||
return includeLinePosition ?
|
||||
this.convertToDiagnosticsWithLinePositionFromDiagnosticFile(diagnosticsForConfigFile) :
|
||||
@@ -605,17 +605,17 @@ namespace ts.server {
|
||||
private convertToDiagnosticsWithLinePositionFromDiagnosticFile(diagnostics: ReadonlyArray<Diagnostic>): protocol.DiagnosticWithLinePosition[] {
|
||||
return diagnostics.map<protocol.DiagnosticWithLinePosition>(d => ({
|
||||
message: flattenDiagnosticMessageText(d.messageText, this.host.newLine),
|
||||
start: d.start,
|
||||
length: d.length,
|
||||
start: d.start!, // TODO: GH#18217
|
||||
length: d.length!, // TODO: GH#18217
|
||||
category: diagnosticCategoryName(d),
|
||||
code: d.code,
|
||||
startLocation: d.file && convertToLocation(getLineAndCharacterOfPosition(d.file, d.start)),
|
||||
endLocation: d.file && convertToLocation(getLineAndCharacterOfPosition(d.file, d.start + d.length))
|
||||
startLocation: (d.file && convertToLocation(getLineAndCharacterOfPosition(d.file, d.start!)))!, // TODO: GH#18217
|
||||
endLocation: (d.file && convertToLocation(getLineAndCharacterOfPosition(d.file, d.start! + d.length!)))! // TODO: GH#18217
|
||||
}));
|
||||
}
|
||||
|
||||
private getCompilerOptionsDiagnostics(args: protocol.CompilerOptionsDiagnosticsRequestArgs) {
|
||||
const project = this.getProject(args.projectFileName);
|
||||
const project = this.getProject(args.projectFileName)!;
|
||||
// Get diagnostics that dont have associated file with them
|
||||
// The diagnostics which have file would be in config file and
|
||||
// would be reported as part of configFileDiagnostics
|
||||
@@ -628,7 +628,7 @@ namespace ts.server {
|
||||
);
|
||||
}
|
||||
|
||||
private convertToDiagnosticsWithLinePosition(diagnostics: ReadonlyArray<Diagnostic>, scriptInfo: ScriptInfo): protocol.DiagnosticWithLinePosition[] {
|
||||
private convertToDiagnosticsWithLinePosition(diagnostics: ReadonlyArray<Diagnostic>, scriptInfo: ScriptInfo | undefined): protocol.DiagnosticWithLinePosition[] {
|
||||
return diagnostics.map(d => <protocol.DiagnosticWithLinePosition>{
|
||||
message: flattenDiagnosticMessageText(d.messageText, this.host.newLine),
|
||||
start: d.start,
|
||||
@@ -636,8 +636,8 @@ namespace ts.server {
|
||||
category: diagnosticCategoryName(d),
|
||||
code: d.code,
|
||||
source: d.source,
|
||||
startLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start),
|
||||
endLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start + d.length),
|
||||
startLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start!), // TODO: GH#18217
|
||||
endLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start! + d.length!),
|
||||
reportsUnnecessary: d.reportsUnnecessary
|
||||
});
|
||||
}
|
||||
@@ -675,14 +675,14 @@ namespace ts.server {
|
||||
private getDefinitionAndBoundSpan(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.DefinitionInfoAndBoundSpan | DefinitionInfoAndBoundSpan {
|
||||
const { file, project } = this.getFileAndProject(args);
|
||||
const position = this.getPositionInFile(args, file);
|
||||
const scriptInfo = project.getScriptInfo(file);
|
||||
const scriptInfo = project.getScriptInfo(file)!;
|
||||
|
||||
const definitionAndBoundSpan = project.getLanguageService().getDefinitionAndBoundSpan(file, position);
|
||||
|
||||
if (!definitionAndBoundSpan || !definitionAndBoundSpan.definitions) {
|
||||
return {
|
||||
definitions: emptyArray,
|
||||
textSpan: undefined
|
||||
textSpan: undefined! // TODO: GH#18217
|
||||
};
|
||||
}
|
||||
|
||||
@@ -726,8 +726,8 @@ namespace ts.server {
|
||||
|
||||
private toFileSpan(fileName: string, textSpan: TextSpan, project: Project): protocol.FileSpan {
|
||||
const ls = project.getLanguageService();
|
||||
const start = ls.toLineColumnOffset(fileName, textSpan.start);
|
||||
const end = ls.toLineColumnOffset(fileName, textSpanEnd(textSpan));
|
||||
const start = ls.toLineColumnOffset!(fileName, textSpan.start); // TODO: GH#18217
|
||||
const end = ls.toLineColumnOffset!(fileName, textSpanEnd(textSpan));
|
||||
|
||||
return {
|
||||
file: fileName,
|
||||
@@ -775,7 +775,7 @@ namespace ts.server {
|
||||
|
||||
return occurrences.map(occurrence => {
|
||||
const { fileName, isWriteAccess, textSpan, isInString } = occurrence;
|
||||
const scriptInfo = project.getScriptInfo(fileName);
|
||||
const scriptInfo = project.getScriptInfo(fileName)!;
|
||||
const result: protocol.OccurrencesResponseItem = {
|
||||
start: scriptInfo.positionToLineOffset(textSpan.start),
|
||||
end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan)),
|
||||
@@ -797,15 +797,15 @@ namespace ts.server {
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
return this.getDiagnosticsWorker(args, /*isSemantic*/ false, (project, file) => project.getLanguageService().getSyntacticDiagnostics(file), args.includeLinePosition);
|
||||
return this.getDiagnosticsWorker(args, /*isSemantic*/ false, (project, file) => project.getLanguageService().getSyntacticDiagnostics(file), !!args.includeLinePosition);
|
||||
}
|
||||
|
||||
private getSemanticDiagnosticsSync(args: protocol.SemanticDiagnosticsSyncRequestArgs): ReadonlyArray<protocol.Diagnostic> | ReadonlyArray<protocol.DiagnosticWithLinePosition> {
|
||||
const { configFile, project } = this.getConfigFileAndProject(args);
|
||||
if (configFile) {
|
||||
return this.getConfigFileDiagnostics(configFile, project, args.includeLinePosition);
|
||||
return this.getConfigFileDiagnostics(configFile, project!, !!args.includeLinePosition); // TODO: GH#18217
|
||||
}
|
||||
return this.getDiagnosticsWorker(args, /*isSemantic*/ true, (project, file) => project.getLanguageService().getSemanticDiagnostics(file), args.includeLinePosition);
|
||||
return this.getDiagnosticsWorker(args, /*isSemantic*/ true, (project, file) => project.getLanguageService().getSemanticDiagnostics(file), !!args.includeLinePosition);
|
||||
}
|
||||
|
||||
private getSuggestionDiagnosticsSync(args: protocol.SuggestionDiagnosticsSyncRequestArgs): ReadonlyArray<protocol.Diagnostic> | ReadonlyArray<protocol.DiagnosticWithLinePosition> {
|
||||
@@ -815,7 +815,7 @@ namespace ts.server {
|
||||
return emptyArray;
|
||||
}
|
||||
// isSemantic because we don't want to info diagnostics in declaration files for JS-only users
|
||||
return this.getDiagnosticsWorker(args, /*isSemantic*/ true, (project, file) => project.getLanguageService().getSuggestionDiagnostics(file), args.includeLinePosition);
|
||||
return this.getDiagnosticsWorker(args, /*isSemantic*/ true, (project, file) => project.getLanguageService().getSuggestionDiagnostics(file), !!args.includeLinePosition);
|
||||
}
|
||||
|
||||
private getDocumentHighlights(args: protocol.DocumentHighlightsRequestArgs, simplifiedResult: boolean): ReadonlyArray<protocol.DocumentHighlightsItem> | ReadonlyArray<DocumentHighlights> {
|
||||
@@ -837,7 +837,7 @@ namespace ts.server {
|
||||
function convertToDocumentHighlightsItem(documentHighlights: DocumentHighlights): protocol.DocumentHighlightsItem {
|
||||
const { fileName, highlightSpans } = documentHighlights;
|
||||
|
||||
const scriptInfo = project.getScriptInfo(fileName);
|
||||
const scriptInfo = project.getScriptInfo(fileName)!;
|
||||
return {
|
||||
file: fileName,
|
||||
highlightSpans: highlightSpans.map(convertHighlightSpan)
|
||||
@@ -860,7 +860,7 @@ namespace ts.server {
|
||||
return this.getProjectInfoWorker(args.file, args.projectFileName, args.needFileNameList, /*excludeConfigFiles*/ false);
|
||||
}
|
||||
|
||||
private getProjectInfoWorker(uncheckedFileName: string, projectFileName: string, needFileNameList: boolean, excludeConfigFiles: boolean) {
|
||||
private getProjectInfoWorker(uncheckedFileName: string, projectFileName: string | undefined, needFileNameList: boolean, excludeConfigFiles: boolean) {
|
||||
const { project } = this.getFileAndProjectWorker(uncheckedFileName, projectFileName);
|
||||
project.updateGraph();
|
||||
const projectInfo = {
|
||||
@@ -878,7 +878,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private getProjects(args: protocol.FileRequestArgs): Projects {
|
||||
let projects: ReadonlyArray<Project>;
|
||||
let projects: ReadonlyArray<Project> | undefined;
|
||||
let symLinkedProjects: MultiMap<Project> | undefined;
|
||||
if (args.projectFileName) {
|
||||
const project = this.getProject(args.projectFileName);
|
||||
@@ -887,7 +887,7 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
else {
|
||||
const scriptInfo = this.projectService.getScriptInfo(args.file);
|
||||
const scriptInfo = this.projectService.getScriptInfo(args.file)!;
|
||||
projects = scriptInfo.containingProjects;
|
||||
symLinkedProjects = this.projectService.getSymlinkedProjects(scriptInfo);
|
||||
}
|
||||
@@ -896,7 +896,7 @@ namespace ts.server {
|
||||
if ((!projects || !projects.length) && !symLinkedProjects) {
|
||||
return Errors.ThrowNoProject();
|
||||
}
|
||||
return symLinkedProjects ? { projects, symLinkedProjects } : projects;
|
||||
return symLinkedProjects ? { projects: projects!, symLinkedProjects } : projects!; // TODO: GH#18217
|
||||
}
|
||||
|
||||
private getDefaultProject(args: protocol.FileRequestArgs) {
|
||||
@@ -906,11 +906,11 @@ namespace ts.server {
|
||||
return project;
|
||||
}
|
||||
}
|
||||
const info = this.projectService.getScriptInfo(args.file);
|
||||
const info = this.projectService.getScriptInfo(args.file)!;
|
||||
return info.getDefaultProject();
|
||||
}
|
||||
|
||||
private getRenameLocations(args: protocol.RenameRequestArgs, simplifiedResult: boolean): protocol.RenameResponseBody | ReadonlyArray<RenameLocation> {
|
||||
private getRenameLocations(args: protocol.RenameRequestArgs, simplifiedResult: boolean): protocol.RenameResponseBody | ReadonlyArray<RenameLocation> | undefined {
|
||||
const file = toNormalizedPath(args.file);
|
||||
const position = this.getPositionInFile(args, file);
|
||||
const projects = this.getProjects(args);
|
||||
@@ -932,16 +932,16 @@ namespace ts.server {
|
||||
|
||||
const fileSpans = combineProjectOutput(
|
||||
file,
|
||||
path => this.projectService.getScriptInfoForPath(path).fileName,
|
||||
path => this.projectService.getScriptInfoForPath(path)!.fileName,
|
||||
projects,
|
||||
(project, file) => {
|
||||
const renameLocations = project.getLanguageService().findRenameLocations(file, position, args.findInStrings, args.findInComments);
|
||||
const renameLocations = project.getLanguageService().findRenameLocations(file, position, args.findInStrings!, args.findInComments!);
|
||||
if (!renameLocations) {
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
return renameLocations.map(location => {
|
||||
const locationScriptInfo = project.getScriptInfo(location.fileName);
|
||||
const locationScriptInfo = project.getScriptInfo(location.fileName)!;
|
||||
return {
|
||||
file: location.fileName,
|
||||
start: locationScriptInfo.positionToLineOffset(location.textSpan.start),
|
||||
@@ -955,7 +955,7 @@ namespace ts.server {
|
||||
|
||||
const locs: protocol.SpanGroup[] = [];
|
||||
for (const cur of fileSpans) {
|
||||
let curFileAccum: protocol.SpanGroup;
|
||||
let curFileAccum: protocol.SpanGroup | undefined;
|
||||
if (locs.length > 0) {
|
||||
curFileAccum = locs[locs.length - 1];
|
||||
if (curFileAccum.file !== cur.file) {
|
||||
@@ -974,9 +974,9 @@ namespace ts.server {
|
||||
else {
|
||||
return combineProjectOutput(
|
||||
file,
|
||||
path => this.projectService.getScriptInfoForPath(path).fileName,
|
||||
path => this.projectService.getScriptInfoForPath(path)!.fileName,
|
||||
projects,
|
||||
(p, file) => p.getLanguageService().findRenameLocations(file, position, args.findInStrings, args.findInComments),
|
||||
(p, file) => p.getLanguageService().findRenameLocations(file, position, args.findInStrings!, args.findInComments!),
|
||||
/*comparer*/ undefined,
|
||||
renameLocationIsEqualTo
|
||||
);
|
||||
@@ -1021,7 +1021,7 @@ namespace ts.server {
|
||||
const projects = this.getProjects(args);
|
||||
|
||||
const defaultProject = this.getDefaultProject(args);
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
|
||||
const position = this.getPosition(args, scriptInfo);
|
||||
if (simplifiedResult) {
|
||||
const nameInfo = defaultProject.getLanguageService().getQuickInfoAtPosition(file, position);
|
||||
@@ -1034,7 +1034,7 @@ namespace ts.server {
|
||||
const nameText = scriptInfo.getSnapshot().getText(nameSpan.start, textSpanEnd(nameSpan));
|
||||
const refs = combineProjectOutput<NormalizedPath, protocol.ReferencesResponseItem>(
|
||||
file,
|
||||
path => this.projectService.getScriptInfoForPath(path).fileName,
|
||||
path => this.projectService.getScriptInfoForPath(path)!.fileName,
|
||||
projects,
|
||||
(project, file) => {
|
||||
const references = project.getLanguageService().getReferencesAtPosition(file, position);
|
||||
@@ -1043,7 +1043,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
return references.map(ref => {
|
||||
const refScriptInfo = project.getScriptInfo(ref.fileName);
|
||||
const refScriptInfo = project.getScriptInfo(ref.fileName)!;
|
||||
const start = refScriptInfo.positionToLineOffset(ref.textSpan.start);
|
||||
const refLineSpan = refScriptInfo.lineToTextSpan(start.line - 1);
|
||||
const lineText = refScriptInfo.getSnapshot().getText(refLineSpan.start, textSpanEnd(refLineSpan)).replace(/\r|\n/g, "");
|
||||
@@ -1071,7 +1071,7 @@ namespace ts.server {
|
||||
else {
|
||||
return combineProjectOutput(
|
||||
file,
|
||||
path => this.projectService.getScriptInfoForPath(path).fileName,
|
||||
path => this.projectService.getScriptInfoForPath(path)!.fileName,
|
||||
projects,
|
||||
(project, file) => project.getLanguageService().findReferences(file, position),
|
||||
/*comparer*/ undefined,
|
||||
@@ -1102,11 +1102,11 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private getPositionInFile(args: protocol.FileLocationRequestArgs, file: NormalizedPath): number {
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
|
||||
return this.getPosition(args, scriptInfo);
|
||||
}
|
||||
|
||||
private getFileAndProject(args: protocol.FileRequestArgs) {
|
||||
private getFileAndProject(args: protocol.FileRequestArgs): { file: NormalizedPath, project: Project } {
|
||||
return this.getFileAndProjectWorker(args.file, args.projectFileName);
|
||||
}
|
||||
|
||||
@@ -1124,9 +1124,9 @@ namespace ts.server {
|
||||
};
|
||||
}
|
||||
|
||||
private getFileAndProjectWorker(uncheckedFileName: string, projectFileName: string) {
|
||||
private getFileAndProjectWorker(uncheckedFileName: string, projectFileName: string | undefined): { file: NormalizedPath, project: Project } {
|
||||
const file = toNormalizedPath(uncheckedFileName);
|
||||
const project: Project = this.getProject(projectFileName) || this.projectService.getDefaultProjectForFile(file, /*ensureProject*/ true);
|
||||
const project = this.getProject(projectFileName) || this.projectService.getDefaultProjectForFile(file, /*ensureProject*/ true)!; // TODO: GH#18217
|
||||
return { file, project };
|
||||
}
|
||||
|
||||
@@ -1134,7 +1134,7 @@ namespace ts.server {
|
||||
const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
|
||||
const spans = languageService.getOutliningSpans(file);
|
||||
if (simplifiedResult) {
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
|
||||
return spans.map(s => ({
|
||||
textSpan: this.toLocationTextSpan(s.textSpan, scriptInfo),
|
||||
hintSpan: this.toLocationTextSpan(s.hintSpan, scriptInfo),
|
||||
@@ -1192,9 +1192,9 @@ namespace ts.server {
|
||||
return languageService.isValidBraceCompletionAtPosition(file, position, args.openingBrace.charCodeAt(0));
|
||||
}
|
||||
|
||||
private getQuickInfoWorker(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.QuickInfoResponseBody | QuickInfo {
|
||||
private getQuickInfoWorker(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.QuickInfoResponseBody | QuickInfo | undefined {
|
||||
const { file, project } = this.getFileAndProject(args);
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
|
||||
const quickInfo = project.getLanguageService().getQuickInfoAtPosition(file, this.getPosition(args, scriptInfo));
|
||||
if (!quickInfo) {
|
||||
return undefined;
|
||||
@@ -1219,9 +1219,9 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
private getFormattingEditsForRange(args: protocol.FormatRequestArgs): protocol.CodeEdit[] {
|
||||
private getFormattingEditsForRange(args: protocol.FormatRequestArgs): protocol.CodeEdit[] | undefined {
|
||||
const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
|
||||
|
||||
const startPosition = scriptInfo.lineOffsetToPosition(args.line, args.offset);
|
||||
const endPosition = scriptInfo.lineOffsetToPosition(args.endLine, args.endOffset);
|
||||
@@ -1238,7 +1238,7 @@ namespace ts.server {
|
||||
private getFormattingEditsForRangeFull(args: protocol.FormatRequestArgs) {
|
||||
const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
|
||||
const options = args.options ? convertFormatOptions(args.options) : this.getFormatOptions(file);
|
||||
return languageService.getFormattingEditsForRange(file, args.position, args.endPosition, options);
|
||||
return languageService.getFormattingEditsForRange(file, args.position!, args.endPosition!, options); // TODO: GH#18217
|
||||
}
|
||||
|
||||
private getFormattingEditsForDocumentFull(args: protocol.FormatRequestArgs) {
|
||||
@@ -1250,12 +1250,12 @@ namespace ts.server {
|
||||
private getFormattingEditsAfterKeystrokeFull(args: protocol.FormatOnKeyRequestArgs) {
|
||||
const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
|
||||
const options = args.options ? convertFormatOptions(args.options) : this.getFormatOptions(file);
|
||||
return languageService.getFormattingEditsAfterKeystroke(file, args.position, args.key, options);
|
||||
return languageService.getFormattingEditsAfterKeystroke(file, args.position!, args.key, options); // TODO: GH#18217
|
||||
}
|
||||
|
||||
private getFormattingEditsAfterKeystroke(args: protocol.FormatOnKeyRequestArgs): protocol.CodeEdit[] {
|
||||
private getFormattingEditsAfterKeystroke(args: protocol.FormatOnKeyRequestArgs): protocol.CodeEdit[] | undefined {
|
||||
const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
|
||||
const position = scriptInfo.lineOffsetToPosition(args.line, args.offset);
|
||||
const formatOptions = this.getFormatOptions(file);
|
||||
const edits = languageService.getFormattingEditsAfterKeystroke(file, position, args.key,
|
||||
@@ -1277,7 +1277,7 @@ namespace ts.server {
|
||||
hasIndent++;
|
||||
}
|
||||
else if (lineText.charAt(i) === "\t") {
|
||||
hasIndent += formatOptions.tabSize;
|
||||
hasIndent += formatOptions.tabSize!; // TODO: GH#18217
|
||||
}
|
||||
else {
|
||||
break;
|
||||
@@ -1310,7 +1310,7 @@ namespace ts.server {
|
||||
private getCompletions(args: protocol.CompletionsRequestArgs, simplifiedResult: boolean): ReadonlyArray<protocol.CompletionEntry> | CompletionInfo | undefined {
|
||||
const prefix = args.prefix || "";
|
||||
const { file, project } = this.getFileAndProject(args);
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
|
||||
const position = this.getPosition(args, scriptInfo);
|
||||
|
||||
const completions = project.getLanguageService().getCompletionsAtPosition(file, position, {
|
||||
@@ -1321,7 +1321,7 @@ namespace ts.server {
|
||||
});
|
||||
if (simplifiedResult) {
|
||||
return mapDefined<CompletionEntry, protocol.CompletionEntry>(completions && completions.entries, entry => {
|
||||
if (completions.isMemberCompletion || startsWith(entry.name.toLowerCase(), prefix.toLowerCase())) {
|
||||
if (completions!.isMemberCompletion || startsWith(entry.name.toLowerCase(), prefix.toLowerCase())) {
|
||||
const { name, kind, kindModifiers, sortText, insertText, replacementSpan, hasAction, source, isRecommended } = entry;
|
||||
const convertedSpan = replacementSpan ? this.toLocationTextSpan(replacementSpan, scriptInfo) : undefined;
|
||||
// Use `hasAction || undefined` to avoid serializing `false`.
|
||||
@@ -1336,7 +1336,7 @@ namespace ts.server {
|
||||
|
||||
private getCompletionEntryDetails(args: protocol.CompletionDetailsRequestArgs, simplifiedResult: boolean): ReadonlyArray<protocol.CompletionEntryDetails> | ReadonlyArray<CompletionEntryDetails> {
|
||||
const { file, project } = this.getFileAndProject(args);
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
|
||||
const position = this.getPosition(args, scriptInfo);
|
||||
const formattingOptions = project.projectService.getFormatCodeOptions(file);
|
||||
|
||||
@@ -1356,14 +1356,14 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
// if specified a project, we only return affected file list in this project
|
||||
const projects = args.projectFileName ? [this.projectService.findProject(args.projectFileName)] : info.containingProjects;
|
||||
const projects = args.projectFileName ? [this.projectService.findProject(args.projectFileName)!] : info.containingProjects;
|
||||
const symLinkedProjects = !args.projectFileName && this.projectService.getSymlinkedProjects(info);
|
||||
return combineProjectOutput(
|
||||
info,
|
||||
path => this.projectService.getScriptInfoForPath(path),
|
||||
path => this.projectService.getScriptInfoForPath(path)!,
|
||||
symLinkedProjects ? { projects, symLinkedProjects } : projects,
|
||||
(project, info) => {
|
||||
let result: protocol.CompileOnSaveAffectedFileListSingleProject;
|
||||
let result: protocol.CompileOnSaveAffectedFileListSingleProject | undefined;
|
||||
if (project.compileOnSaveEnabled && project.languageServiceEnabled && !project.isOrphan() && !project.getCompilationSettings().noEmit) {
|
||||
result = {
|
||||
projectFileName: project.getProjectName(),
|
||||
@@ -1384,13 +1384,13 @@ namespace ts.server {
|
||||
if (!project.languageServiceEnabled) {
|
||||
return false;
|
||||
}
|
||||
const scriptInfo = project.getScriptInfo(file);
|
||||
const scriptInfo = project.getScriptInfo(file)!;
|
||||
return project.emitFile(scriptInfo, (path, data, writeByteOrderMark) => this.host.writeFile(path, data, writeByteOrderMark));
|
||||
}
|
||||
|
||||
private getSignatureHelpItems(args: protocol.SignatureHelpRequestArgs, simplifiedResult: boolean): protocol.SignatureHelpItems | SignatureHelpItems {
|
||||
private getSignatureHelpItems(args: protocol.SignatureHelpRequestArgs, simplifiedResult: boolean): protocol.SignatureHelpItems | SignatureHelpItems | undefined {
|
||||
const { file, project } = this.getFileAndProject(args);
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
|
||||
const position = this.getPosition(args, scriptInfo);
|
||||
const helpItems = project.getLanguageService().getSignatureHelpItems(file, position);
|
||||
if (!helpItems) {
|
||||
@@ -1435,7 +1435,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private change(args: protocol.ChangeRequestArgs) {
|
||||
const scriptInfo = this.projectService.getScriptInfo(args.file);
|
||||
const scriptInfo = this.projectService.getScriptInfo(args.file)!;
|
||||
Debug.assert(!!scriptInfo);
|
||||
const start = scriptInfo.lineOffsetToPosition(args.line, args.offset);
|
||||
const end = scriptInfo.lineOffsetToPosition(args.endLine, args.endOffset);
|
||||
@@ -1443,14 +1443,14 @@ namespace ts.server {
|
||||
this.changeSeq++;
|
||||
this.projectService.applyChangesToFile(scriptInfo, [{
|
||||
span: { start, length: end - start },
|
||||
newText: args.insertString
|
||||
newText: args.insertString! // TODO: GH#18217
|
||||
}]);
|
||||
}
|
||||
}
|
||||
|
||||
private reload(args: protocol.ReloadRequestArgs, reqSeq: number) {
|
||||
const file = toNormalizedPath(args.file);
|
||||
const tempFileName = args.tmpfile && toNormalizedPath(args.tmpfile);
|
||||
const tempFileName = args.tmpfile === undefined ? undefined : toNormalizedPath(args.tmpfile);
|
||||
const info = this.projectService.getScriptInfoForNormalizedPath(file);
|
||||
if (info) {
|
||||
this.changeSeq++;
|
||||
@@ -1487,13 +1487,13 @@ namespace ts.server {
|
||||
}));
|
||||
}
|
||||
|
||||
private getNavigationBarItems(args: protocol.FileRequestArgs, simplifiedResult: boolean): protocol.NavigationBarItem[] | NavigationBarItem[] {
|
||||
private getNavigationBarItems(args: protocol.FileRequestArgs, simplifiedResult: boolean): protocol.NavigationBarItem[] | NavigationBarItem[] | undefined {
|
||||
const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
|
||||
const items = languageService.getNavigationBarItems(file);
|
||||
return !items
|
||||
? undefined
|
||||
: simplifiedResult
|
||||
? this.mapLocationNavigationBarItems(items, this.projectService.getScriptInfoForNormalizedPath(file))
|
||||
? this.mapLocationNavigationBarItems(items, this.projectService.getScriptInfoForNormalizedPath(file)!)
|
||||
: items;
|
||||
}
|
||||
|
||||
@@ -1514,13 +1514,13 @@ namespace ts.server {
|
||||
};
|
||||
}
|
||||
|
||||
private getNavigationTree(args: protocol.FileRequestArgs, simplifiedResult: boolean): protocol.NavigationTree | NavigationTree {
|
||||
private getNavigationTree(args: protocol.FileRequestArgs, simplifiedResult: boolean): protocol.NavigationTree | NavigationTree | undefined {
|
||||
const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
|
||||
const tree = languageService.getNavigationTree(file);
|
||||
return !tree
|
||||
? undefined
|
||||
: simplifiedResult
|
||||
? this.toLocationNavigationTree(tree, this.projectService.getScriptInfoForNormalizedPath(file))
|
||||
? this.toLocationNavigationTree(tree, this.projectService.getScriptInfoForNormalizedPath(file)!)
|
||||
: tree;
|
||||
}
|
||||
|
||||
@@ -1544,7 +1544,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
return navItems.map((navItem) => {
|
||||
const scriptInfo = project.getScriptInfo(navItem.fileName);
|
||||
const scriptInfo = project.getScriptInfo(navItem.fileName)!;
|
||||
const bakedItem: protocol.NavtoItem = {
|
||||
name: navItem.name,
|
||||
kind: navItem.kind,
|
||||
@@ -1624,8 +1624,8 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private extractPositionAndRange(args: protocol.FileLocationOrRangeRequestArgs, scriptInfo: ScriptInfo): { position: number, textRange: TextRange } {
|
||||
let position: number;
|
||||
let textRange: TextRange;
|
||||
let position: number | undefined;
|
||||
let textRange: TextRange | undefined;
|
||||
if (this.isLocation(args)) {
|
||||
position = getPosition(args);
|
||||
}
|
||||
@@ -1633,7 +1633,7 @@ namespace ts.server {
|
||||
const { startPosition, endPosition } = this.getStartAndEndPosition(args, scriptInfo);
|
||||
textRange = { pos: startPosition, end: endPosition };
|
||||
}
|
||||
return { position, textRange };
|
||||
return { position: position!, textRange: textRange! }; // TODO: GH#18217
|
||||
|
||||
function getPosition(loc: protocol.FileLocationRequestArgs) {
|
||||
return loc.position !== undefined ? loc.position : scriptInfo.lineOffsetToPosition(loc.line, loc.offset);
|
||||
@@ -1642,14 +1642,14 @@ namespace ts.server {
|
||||
|
||||
private getApplicableRefactors(args: protocol.GetApplicableRefactorsRequestArgs): protocol.ApplicableRefactorInfo[] {
|
||||
const { file, project } = this.getFileAndProject(args);
|
||||
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
|
||||
const scriptInfo = project.getScriptInfoForNormalizedPath(file)!;
|
||||
const { position, textRange } = this.extractPositionAndRange(args, scriptInfo);
|
||||
return project.getLanguageService().getApplicableRefactors(file, position || textRange, this.getPreferences(file));
|
||||
}
|
||||
|
||||
private getEditsForRefactor(args: protocol.GetEditsForRefactorRequestArgs, simplifiedResult: boolean): RefactorEditInfo | protocol.RefactorEditInfo {
|
||||
const { file, project } = this.getFileAndProject(args);
|
||||
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
|
||||
const scriptInfo = project.getScriptInfoForNormalizedPath(file)!;
|
||||
const { position, textRange } = this.extractPositionAndRange(args, scriptInfo);
|
||||
|
||||
const result = project.getLanguageService().getEditsForRefactor(
|
||||
@@ -1671,7 +1671,7 @@ namespace ts.server {
|
||||
const { renameFilename, renameLocation, edits } = result;
|
||||
let mappedRenameLocation: protocol.Location | undefined;
|
||||
if (renameFilename !== undefined && renameLocation !== undefined) {
|
||||
const renameScriptInfo = project.getScriptInfoForNormalizedPath(toNormalizedPath(renameFilename));
|
||||
const renameScriptInfo = project.getScriptInfoForNormalizedPath(toNormalizedPath(renameFilename))!;
|
||||
mappedRenameLocation = getLocationInNewDocument(getSnapshotText(renameScriptInfo.getSnapshot()), renameFilename, renameLocation, edits);
|
||||
}
|
||||
return { renameLocation: mappedRenameLocation, renameFilename, edits: this.mapTextChangesToCodeEdits(project, edits) };
|
||||
@@ -1699,16 +1699,16 @@ namespace ts.server {
|
||||
return simplifiedResult ? this.mapTextChangesToCodeEdits(project, changes) : changes;
|
||||
}
|
||||
|
||||
private getCodeFixes(args: protocol.CodeFixRequestArgs, simplifiedResult: boolean): ReadonlyArray<protocol.CodeFixAction> | ReadonlyArray<CodeFixAction> {
|
||||
if (args.errorCodes.length === 0) {
|
||||
private getCodeFixes(args: protocol.CodeFixRequestArgs, simplifiedResult: boolean): ReadonlyArray<protocol.CodeFixAction> | ReadonlyArray<CodeFixAction> | undefined {
|
||||
if (args.errorCodes!.length === 0) { // TODO: GH#18217
|
||||
return undefined;
|
||||
}
|
||||
const { file, project } = this.getFileAndProject(args);
|
||||
|
||||
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
|
||||
const scriptInfo = project.getScriptInfoForNormalizedPath(file)!;
|
||||
const { startPosition, endPosition } = this.getStartAndEndPosition(args, scriptInfo);
|
||||
|
||||
const codeActions = project.getLanguageService().getCodeFixesAtPosition(file, startPosition, endPosition, args.errorCodes, this.getFormatOptions(file), this.getPreferences(file));
|
||||
const codeActions = project.getLanguageService().getCodeFixesAtPosition(file, startPosition, endPosition, args.errorCodes!, this.getFormatOptions(file), this.getPreferences(file));
|
||||
return simplifiedResult ? codeActions.map(codeAction => this.mapCodeFixAction(project, codeAction)) : codeActions;
|
||||
}
|
||||
|
||||
@@ -1736,7 +1736,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private getStartAndEndPosition(args: protocol.FileRangeRequestArgs, scriptInfo: ScriptInfo) {
|
||||
let startPosition: number, endPosition: number;
|
||||
let startPosition: number | undefined, endPosition: number | undefined;
|
||||
if (args.startPosition !== undefined) {
|
||||
startPosition = args.startPosition;
|
||||
}
|
||||
@@ -1766,7 +1766,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private mapTextChangesToCodeEdits(project: Project, textChanges: ReadonlyArray<FileTextChanges>): protocol.FileCodeEdits[] {
|
||||
return textChanges.map(change => this.mapTextChangesToCodeEditsUsingScriptinfo(change, project.getScriptInfoForNormalizedPath(toNormalizedPath(change.fileName))));
|
||||
return textChanges.map(change => this.mapTextChangesToCodeEditsUsingScriptinfo(change, project.getScriptInfoForNormalizedPath(toNormalizedPath(change.fileName))!));
|
||||
}
|
||||
|
||||
private mapTextChangesToCodeEditsUsingScriptinfo(textChanges: FileTextChanges, scriptInfo: ScriptInfo | undefined): protocol.FileCodeEdits {
|
||||
@@ -1797,9 +1797,9 @@ namespace ts.server {
|
||||
return { fileName: textChanges.fileName, textChanges: [{ start: { line: 0, offset: 0 }, end: { line: 0, offset: 0 }, newText: change.newText }] };
|
||||
}
|
||||
|
||||
private getBraceMatching(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.TextSpan[] | TextSpan[] {
|
||||
private getBraceMatching(args: protocol.FileLocationRequestArgs, simplifiedResult: boolean): protocol.TextSpan[] | TextSpan[] | undefined {
|
||||
const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
|
||||
const position = this.getPosition(args, scriptInfo);
|
||||
|
||||
const spans = languageService.getBraceMatchingAtPosition(file, position);
|
||||
@@ -1821,7 +1821,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
// No need to analyze lib.d.ts
|
||||
const fileNamesInProject = fileNames.filter(value => !stringContains(value, "lib.d.ts"));
|
||||
const fileNamesInProject = fileNames!.filter(value => !stringContains(value, "lib.d.ts")); // TODO: GH#18217
|
||||
if (fileNamesInProject.length === 0) {
|
||||
return;
|
||||
}
|
||||
@@ -1832,13 +1832,13 @@ namespace ts.server {
|
||||
const lowPriorityFiles: NormalizedPath[] = [];
|
||||
const veryLowPriorityFiles: NormalizedPath[] = [];
|
||||
const normalizedFileName = toNormalizedPath(fileName);
|
||||
const project = this.projectService.getDefaultProjectForFile(normalizedFileName, /*ensureProject*/ true);
|
||||
const project = this.projectService.getDefaultProjectForFile(normalizedFileName, /*ensureProject*/ true)!;
|
||||
for (const fileNameInProject of fileNamesInProject) {
|
||||
if (this.getCanonicalFileName(fileNameInProject) === this.getCanonicalFileName(fileName)) {
|
||||
highPriorityFiles.push(fileNameInProject);
|
||||
}
|
||||
else {
|
||||
const info = this.projectService.getScriptInfo(fileNameInProject);
|
||||
const info = this.projectService.getScriptInfo(fileNameInProject)!; // TODO: GH#18217
|
||||
if (!info.isScriptOpen()) {
|
||||
if (fileExtensionIs(fileNameInProject, Extension.Dts)) {
|
||||
veryLowPriorityFiles.push(fileNameInProject);
|
||||
@@ -1871,7 +1871,7 @@ namespace ts.server {
|
||||
return { responseRequired: false };
|
||||
}
|
||||
|
||||
private requiredResponse(response: {}): HandlerResponse {
|
||||
private requiredResponse(response: {} | undefined): HandlerResponse {
|
||||
return { response, responseRequired: true };
|
||||
}
|
||||
|
||||
@@ -1915,7 +1915,7 @@ namespace ts.server {
|
||||
},
|
||||
[CommandNames.ApplyChangedToOpenFiles]: (request: protocol.ApplyChangedToOpenFilesRequest) => {
|
||||
this.changeSeq++;
|
||||
this.projectService.applyChangesInOpenFiles(request.arguments.openFiles, request.arguments.changedFiles, request.arguments.closedFiles);
|
||||
this.projectService.applyChangesInOpenFiles(request.arguments.openFiles, request.arguments.changedFiles!, request.arguments.closedFiles!); // TODO: GH#18217
|
||||
// TODO: report errors
|
||||
return this.requiredResponse(/*response*/ true);
|
||||
},
|
||||
@@ -1963,7 +1963,7 @@ namespace ts.server {
|
||||
this.openClientFile(
|
||||
toNormalizedPath(request.arguments.file),
|
||||
request.arguments.fileContent,
|
||||
convertScriptKindName(request.arguments.scriptKindName),
|
||||
convertScriptKindName(request.arguments.scriptKindName!), // TODO: GH#18217
|
||||
request.arguments.projectRootPath ? toNormalizedPath(request.arguments.projectRootPath) : undefined);
|
||||
return this.notRequired();
|
||||
},
|
||||
@@ -2189,7 +2189,7 @@ namespace ts.server {
|
||||
|
||||
private resetCurrentRequest(requestId: number): void {
|
||||
Debug.assert(this.currentRequestId === requestId);
|
||||
this.currentRequestId = undefined;
|
||||
this.currentRequestId = undefined!; // TODO: GH#18217
|
||||
this.cancellationToken.resetRequest(requestId);
|
||||
}
|
||||
|
||||
@@ -2217,7 +2217,7 @@ namespace ts.server {
|
||||
|
||||
public onMessage(message: string) {
|
||||
this.gcTimer.scheduleCollect();
|
||||
let start: number[];
|
||||
let start: number[] | undefined;
|
||||
if (this.logger.hasLevel(LogLevel.requestTime)) {
|
||||
start = this.hrtime();
|
||||
if (this.logger.hasLevel(LogLevel.verbose)) {
|
||||
@@ -2225,7 +2225,7 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
let request: protocol.Request;
|
||||
let request: protocol.Request | undefined;
|
||||
try {
|
||||
request = <protocol.Request>JSON.parse(message);
|
||||
const { response, responseRequired } = this.executeCommand(request);
|
||||
@@ -2250,7 +2250,7 @@ namespace ts.server {
|
||||
catch (err) {
|
||||
if (err instanceof OperationCanceledException) {
|
||||
// Handle cancellation exceptions
|
||||
this.doOutput({ canceled: true }, request.command, request.seq, /*success*/ true);
|
||||
this.doOutput({ canceled: true }, request!.command, request!.seq, /*success*/ true);
|
||||
return;
|
||||
}
|
||||
this.logError(err, message);
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace ts.server {
|
||||
export interface ITypingsInstaller {
|
||||
isKnownTypesPackageName(name: string): boolean;
|
||||
installPackage(options: InstallPackageOptionsWithProject): Promise<ApplyCodeActionCommandResult>;
|
||||
enqueueInstallTypingsRequest(p: Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string>): void;
|
||||
enqueueInstallTypingsRequest(p: Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string> | undefined): void;
|
||||
attach(projectService: ProjectService): void;
|
||||
onProjectClosed(p: Project): void;
|
||||
readonly globalTypingsCacheLocation: string | undefined;
|
||||
@@ -21,19 +21,19 @@ namespace ts.server {
|
||||
enqueueInstallTypingsRequest: noop,
|
||||
attach: noop,
|
||||
onProjectClosed: noop,
|
||||
globalTypingsCacheLocation: undefined
|
||||
globalTypingsCacheLocation: undefined! // TODO: GH#18217
|
||||
};
|
||||
|
||||
interface TypingsCacheEntry {
|
||||
readonly typeAcquisition: TypeAcquisition;
|
||||
readonly compilerOptions: CompilerOptions;
|
||||
readonly typings: SortedReadonlyArray<string>;
|
||||
readonly unresolvedImports: SortedReadonlyArray<string>;
|
||||
readonly unresolvedImports: SortedReadonlyArray<string> | undefined;
|
||||
/* mainly useful for debugging */
|
||||
poisoned: boolean;
|
||||
}
|
||||
|
||||
function setIsEqualTo(arr1: string[], arr2: string[]): boolean {
|
||||
function setIsEqualTo(arr1: string[] | undefined, arr2: string[] | undefined): boolean {
|
||||
if (arr1 === arr2) {
|
||||
return true;
|
||||
}
|
||||
@@ -43,13 +43,13 @@ namespace ts.server {
|
||||
const set: Map<boolean> = createMap<boolean>();
|
||||
let unique = 0;
|
||||
|
||||
for (const v of arr1) {
|
||||
for (const v of arr1!) {
|
||||
if (set.get(v) !== true) {
|
||||
set.set(v, true);
|
||||
unique++;
|
||||
}
|
||||
}
|
||||
for (const v of arr2) {
|
||||
for (const v of arr2!) {
|
||||
const isSet = set.get(v);
|
||||
if (isSet === undefined) {
|
||||
return false;
|
||||
@@ -73,7 +73,7 @@ namespace ts.server {
|
||||
return opt1.allowJs !== opt2.allowJs;
|
||||
}
|
||||
|
||||
function unresolvedImportsChanged(imports1: SortedReadonlyArray<string>, imports2: SortedReadonlyArray<string>): boolean {
|
||||
function unresolvedImportsChanged(imports1: SortedReadonlyArray<string> | undefined, imports2: SortedReadonlyArray<string> | undefined): boolean {
|
||||
if (imports1 === imports2) {
|
||||
return false;
|
||||
}
|
||||
@@ -95,7 +95,7 @@ namespace ts.server {
|
||||
return this.installer.installPackage(options);
|
||||
}
|
||||
|
||||
enqueueInstallTypingsForProject(project: Project, unresolvedImports: SortedReadonlyArray<string>, forceRefresh: boolean) {
|
||||
enqueueInstallTypingsForProject(project: Project, unresolvedImports: SortedReadonlyArray<string> | undefined, forceRefresh: boolean) {
|
||||
const typeAcquisition = project.getTypeAcquisition();
|
||||
|
||||
if (!typeAcquisition || !typeAcquisition.enable) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference types="node" />
|
||||
// tslint:disable no-unnecessary-type-assertion (TODO: tslint can't find node types)
|
||||
|
||||
namespace ts.server.typingsInstaller {
|
||||
const fs: {
|
||||
@@ -22,7 +22,7 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
writeLine = (text: string) => {
|
||||
try {
|
||||
fs.appendFileSync(this.logFile, `[${nowString()}] ${text}${sys.newLine}`);
|
||||
fs.appendFileSync(this.logFile!, `[${nowString()}] ${text}${sys.newLine}`); // TODO: GH#18217
|
||||
}
|
||||
catch (e) {
|
||||
this.logEnabled = false;
|
||||
@@ -53,7 +53,7 @@ namespace ts.server.typingsInstaller {
|
||||
return createMap<MapLike<string>>();
|
||||
}
|
||||
try {
|
||||
const content = <TypesRegistryFile>JSON.parse(host.readFile(typesRegistryFilePath));
|
||||
const content = <TypesRegistryFile>JSON.parse(host.readFile(typesRegistryFilePath)!);
|
||||
return createMapFromTemplate(content.entries);
|
||||
}
|
||||
catch (e) {
|
||||
@@ -176,7 +176,7 @@ namespace ts.server.typingsInstaller {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Sending response:\n ${JSON.stringify(response)}`);
|
||||
}
|
||||
process.send(response);
|
||||
process.send!(response); // TODO: GH#18217
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Response has been sent.`);
|
||||
}
|
||||
@@ -240,7 +240,7 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
process.exit(0);
|
||||
});
|
||||
const installer = new NodeTypingsInstaller(globalTypingsCacheLocation, typingSafeListLocation, typesMapLocation, npmLocation, /*throttleLimit*/5, log);
|
||||
const installer = new NodeTypingsInstaller(globalTypingsCacheLocation!, typingSafeListLocation!, typesMapLocation!, npmLocation, /*throttleLimit*/5, log); // TODO: GH#18217
|
||||
installer.listen();
|
||||
|
||||
function indent(newline: string, str: string): string {
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace ts.server.typingsInstaller {
|
||||
writeLine: noop
|
||||
};
|
||||
|
||||
function typingToFileName(cachePath: string, packageName: string, installTypingHost: InstallTypingHost, log: Log): string {
|
||||
function typingToFileName(cachePath: string, packageName: string, installTypingHost: InstallTypingHost, log: Log): string | undefined {
|
||||
try {
|
||||
const result = resolveModuleName(packageName, combinePaths(cachePath, "index.d.ts"), { moduleResolution: ModuleResolutionKind.NodeJs }, installTypingHost);
|
||||
return result.resolvedModule && result.resolvedModule.resolvedFileName;
|
||||
@@ -154,7 +154,7 @@ namespace ts.server.typingsInstaller {
|
||||
this.log.isEnabled() ? (s => this.log.writeLine(s)) : undefined,
|
||||
req.fileNames,
|
||||
req.projectRootPath,
|
||||
this.safeList,
|
||||
this.safeList!,
|
||||
this.packageNameToTypingLocation,
|
||||
req.typeAcquisition,
|
||||
req.unresolvedImports,
|
||||
@@ -209,8 +209,8 @@ namespace ts.server.typingsInstaller {
|
||||
this.log.writeLine(`Trying to find '${packageJson}'...`);
|
||||
}
|
||||
if (this.installTypingHost.fileExists(packageJson) && this.installTypingHost.fileExists(packageLockJson)) {
|
||||
const npmConfig = <NpmConfig>JSON.parse(this.installTypingHost.readFile(packageJson));
|
||||
const npmLock = <NpmLock>JSON.parse(this.installTypingHost.readFile(packageLockJson));
|
||||
const npmConfig = <NpmConfig>JSON.parse(this.installTypingHost.readFile(packageJson)!); // TODO: GH#18217
|
||||
const npmLock = <NpmLock>JSON.parse(this.installTypingHost.readFile(packageLockJson)!); // TODO: GH#18217
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Loaded content of '${packageJson}': ${JSON.stringify(npmConfig)}`);
|
||||
this.log.writeLine(`Loaded content of '${packageLockJson}'`);
|
||||
@@ -246,7 +246,7 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
const info = getProperty(npmLock.dependencies, key);
|
||||
const version = info && info.version;
|
||||
const semver = Semver.parse(version);
|
||||
const semver = Semver.parse(version!); // TODO: GH#18217
|
||||
const newTyping: JsTyping.CachedTyping = { typingLocation: typingFile, version: semver };
|
||||
this.packageNameToTypingLocation.set(packageName, newTyping);
|
||||
}
|
||||
@@ -275,7 +275,7 @@ namespace ts.server.typingsInstaller {
|
||||
if (this.log.isEnabled()) this.log.writeLine(`Entry for package '${typing}' does not exist in local types registry - skipping...`);
|
||||
return false;
|
||||
}
|
||||
if (this.packageNameToTypingLocation.get(typing) && JsTyping.isTypingUpToDate(this.packageNameToTypingLocation.get(typing), this.typesRegistry.get(typing))) {
|
||||
if (this.packageNameToTypingLocation.get(typing) && JsTyping.isTypingUpToDate(this.packageNameToTypingLocation.get(typing)!, this.typesRegistry.get(typing)!)) {
|
||||
if (this.log.isEnabled()) this.log.writeLine(`'${typing}' already has an up-to-date typing - skipping...`);
|
||||
return false;
|
||||
}
|
||||
@@ -349,7 +349,7 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
|
||||
// packageName is guaranteed to exist in typesRegistry by filterTypings
|
||||
const distTags = this.typesRegistry.get(packageName);
|
||||
const distTags = this.typesRegistry.get(packageName)!;
|
||||
const newVersion = Semver.parse(distTags[`ts${versionMajorMinor}`] || distTags[latestDistTag]);
|
||||
const newTyping: JsTyping.CachedTyping = { typingLocation: typingFile, version: newVersion };
|
||||
this.packageNameToTypingLocation.set(packageName, newTyping);
|
||||
@@ -392,7 +392,7 @@ namespace ts.server.typingsInstaller {
|
||||
return;
|
||||
}
|
||||
|
||||
let watchers = this.projectWatchers.get(projectName);
|
||||
let watchers = this.projectWatchers.get(projectName)!;
|
||||
const toRemove = createMap<FileWatcher>();
|
||||
if (!watchers) {
|
||||
watchers = createMap();
|
||||
@@ -418,7 +418,7 @@ namespace ts.server.typingsInstaller {
|
||||
if (isLoggingEnabled) {
|
||||
this.log.writeLine(`FileWatcher:: Added:: WatchInfo: ${file}`);
|
||||
}
|
||||
const watcher = this.installTypingHost.watchFile(file, (f, eventKind) => {
|
||||
const watcher = this.installTypingHost.watchFile!(file, (f, eventKind) => { // TODO: GH#18217
|
||||
if (isLoggingEnabled) {
|
||||
this.log.writeLine(`FileWatcher:: Triggered with ${f} eventKind: ${FileWatcherEventKind[eventKind]}:: WatchInfo: ${file}:: handler is already invoked '${watchers.isInvoked}'`);
|
||||
}
|
||||
@@ -439,7 +439,7 @@ namespace ts.server.typingsInstaller {
|
||||
if (isLoggingEnabled) {
|
||||
this.log.writeLine(`DirectoryWatcher:: Added:: WatchInfo: ${dir} recursive`);
|
||||
}
|
||||
const watcher = this.installTypingHost.watchDirectory(dir, f => {
|
||||
const watcher = this.installTypingHost.watchDirectory!(dir, f => { // TODO: GH#18217
|
||||
if (isLoggingEnabled) {
|
||||
this.log.writeLine(`DirectoryWatcher:: Triggered with ${f} :: WatchInfo: ${dir} recursive :: handler is already invoked '${watchers.isInvoked}'`);
|
||||
}
|
||||
@@ -512,7 +512,7 @@ namespace ts.server.typingsInstaller {
|
||||
private executeWithThrottling() {
|
||||
while (this.inFlightRequestCount < this.throttleLimit && this.pendingRunRequests.length) {
|
||||
this.inFlightRequestCount++;
|
||||
const request = this.pendingRunRequests.pop();
|
||||
const request = this.pendingRunRequests.pop()!;
|
||||
this.installWorker(request.requestId, request.packageNames, request.cwd, ok => {
|
||||
this.inFlightRequestCount--;
|
||||
request.onRequestCompleted(ok);
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace ts.server {
|
||||
startGroup(): void;
|
||||
endGroup(): void;
|
||||
msg(s: string, type?: Msg): void;
|
||||
getLogFileName(): string;
|
||||
getLogFileName(): string | undefined;
|
||||
}
|
||||
|
||||
// TODO: Use a const enum (https://github.com/Microsoft/TypeScript/issues/16804)
|
||||
@@ -96,7 +96,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
export interface NormalizedPathMap<T> {
|
||||
get(path: NormalizedPath): T;
|
||||
get(path: NormalizedPath): T | undefined;
|
||||
set(path: NormalizedPath, value: T): void;
|
||||
contains(path: NormalizedPath): boolean;
|
||||
remove(path: NormalizedPath): void;
|
||||
@@ -150,7 +150,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
export function createSortedArray<T>(): SortedArray<T> {
|
||||
return [] as SortedArray<T>;
|
||||
return [] as any as SortedArray<T>; // TODO: GH#19873
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ namespace ts.server {
|
||||
private readonly pendingTimeouts: Map<any> = createMap<any>();
|
||||
private readonly logger?: Logger | undefined;
|
||||
constructor(private readonly host: ServerHost, logger: Logger) {
|
||||
this.logger = logger.hasLevel(LogLevel.verbose) && logger;
|
||||
this.logger = logger.hasLevel(LogLevel.verbose) ? logger : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -208,11 +208,11 @@ namespace ts.server {
|
||||
self.timerId = undefined;
|
||||
|
||||
const log = self.logger.hasLevel(LogLevel.requestTime);
|
||||
const before = log && self.host.getMemoryUsage();
|
||||
const before = log && self.host.getMemoryUsage!(); // TODO: GH#18217
|
||||
|
||||
self.host.gc();
|
||||
self.host.gc!(); // TODO: GH#18217
|
||||
if (log) {
|
||||
const after = self.host.getMemoryUsage();
|
||||
const after = self.host.getMemoryUsage!(); // TODO: GH#18217
|
||||
self.logger.perftrc(`GC::before ${before}, after ${after}`);
|
||||
}
|
||||
}
|
||||
|
||||
+33
-30
@@ -17,12 +17,13 @@ namespace ts.BreakpointResolver {
|
||||
// let y = 10;
|
||||
// token at position will return let keyword on second line as the token but we would like to use
|
||||
// token on same line if trailing trivia (comments or white spaces on same line) part of the last token on that line
|
||||
tokenAtLocation = findPrecedingToken(tokenAtLocation.pos, sourceFile);
|
||||
const preceding = findPrecedingToken(tokenAtLocation.pos, sourceFile);
|
||||
|
||||
// It's a blank line
|
||||
if (!tokenAtLocation || sourceFile.getLineAndCharacterOfPosition(tokenAtLocation.getEnd()).line !== lineOfPosition) {
|
||||
if (!preceding || sourceFile.getLineAndCharacterOfPosition(preceding.getEnd()).line !== lineOfPosition) {
|
||||
return undefined;
|
||||
}
|
||||
tokenAtLocation = preceding;
|
||||
}
|
||||
|
||||
// Cannot set breakpoint in ambient declarations
|
||||
@@ -44,7 +45,7 @@ namespace ts.BreakpointResolver {
|
||||
return textSpan(startNode, findNextToken(previousTokenToFindNextEndToken, previousTokenToFindNextEndToken.parent, sourceFile));
|
||||
}
|
||||
|
||||
function spanInNodeIfStartsOnSameLine(node: Node, otherwiseOnNode?: Node): TextSpan {
|
||||
function spanInNodeIfStartsOnSameLine(node: Node | undefined, otherwiseOnNode?: Node): TextSpan | undefined {
|
||||
if (node && lineOfPosition === sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line) {
|
||||
return spanInNode(node);
|
||||
}
|
||||
@@ -55,16 +56,17 @@ namespace ts.BreakpointResolver {
|
||||
return createTextSpanFromBounds(skipTrivia(sourceFile.text, nodeArray.pos), nodeArray.end);
|
||||
}
|
||||
|
||||
function spanInPreviousNode(node: Node): TextSpan {
|
||||
function spanInPreviousNode(node: Node): TextSpan | undefined {
|
||||
return spanInNode(findPrecedingToken(node.pos, sourceFile));
|
||||
}
|
||||
|
||||
function spanInNextNode(node: Node): TextSpan {
|
||||
function spanInNextNode(node: Node): TextSpan | undefined {
|
||||
return spanInNode(findNextToken(node, node.parent, sourceFile));
|
||||
}
|
||||
|
||||
function spanInNode(node: Node): TextSpan {
|
||||
function spanInNode(node: Node | undefined): TextSpan | undefined {
|
||||
if (node) {
|
||||
const { parent } = node;
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.VariableStatement:
|
||||
// Span on first variable declaration
|
||||
@@ -195,7 +197,7 @@ namespace ts.BreakpointResolver {
|
||||
return spanInNode((<WithStatement>node).statement);
|
||||
|
||||
case SyntaxKind.Decorator:
|
||||
return spanInNodeArray(node.parent.decorators);
|
||||
return spanInNodeArray(parent.decorators!);
|
||||
|
||||
case SyntaxKind.ObjectBindingPattern:
|
||||
case SyntaxKind.ArrayBindingPattern:
|
||||
@@ -263,7 +265,7 @@ namespace ts.BreakpointResolver {
|
||||
node.kind === SyntaxKind.SpreadElement ||
|
||||
node.kind === SyntaxKind.PropertyAssignment ||
|
||||
node.kind === SyntaxKind.ShorthandPropertyAssignment) &&
|
||||
isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent)) {
|
||||
isArrayLiteralOrObjectLiteralDestructuringPattern(parent)) {
|
||||
return textSpan(node);
|
||||
}
|
||||
|
||||
@@ -292,7 +294,7 @@ namespace ts.BreakpointResolver {
|
||||
}
|
||||
|
||||
if (isExpressionNode(node)) {
|
||||
switch (node.parent.kind) {
|
||||
switch (parent.kind) {
|
||||
case SyntaxKind.DoStatement:
|
||||
// Set span as if on while keyword
|
||||
return spanInPreviousNode(node);
|
||||
@@ -367,7 +369,7 @@ namespace ts.BreakpointResolver {
|
||||
function textSpanFromVariableDeclaration(variableDeclaration: VariableDeclaration | PropertyDeclaration | PropertySignature): TextSpan {
|
||||
if (isVariableDeclarationList(variableDeclaration.parent) && variableDeclaration.parent.declarations[0] === variableDeclaration) {
|
||||
// First declaration - include let keyword
|
||||
return textSpan(findPrecedingToken(variableDeclaration.pos, sourceFile, variableDeclaration.parent), variableDeclaration);
|
||||
return textSpan(findPrecedingToken(variableDeclaration.pos, sourceFile, variableDeclaration.parent)!, variableDeclaration);
|
||||
}
|
||||
else {
|
||||
// Span only on this declaration
|
||||
@@ -375,12 +377,13 @@ namespace ts.BreakpointResolver {
|
||||
}
|
||||
}
|
||||
|
||||
function spanInVariableDeclaration(variableDeclaration: VariableDeclaration | PropertyDeclaration | PropertySignature): TextSpan {
|
||||
function spanInVariableDeclaration(variableDeclaration: VariableDeclaration | PropertyDeclaration | PropertySignature): TextSpan | undefined {
|
||||
// If declaration of for in statement, just set the span in parent
|
||||
if (variableDeclaration.parent.parent.kind === SyntaxKind.ForInStatement) {
|
||||
return spanInNode(variableDeclaration.parent.parent);
|
||||
}
|
||||
|
||||
const parent = variableDeclaration.parent;
|
||||
// If this is a destructuring pattern, set breakpoint in binding pattern
|
||||
if (isBindingPattern(variableDeclaration.name)) {
|
||||
return spanInBindingPattern(variableDeclaration.name);
|
||||
@@ -390,7 +393,7 @@ namespace ts.BreakpointResolver {
|
||||
// or its declaration from 'for of'
|
||||
if (variableDeclaration.initializer ||
|
||||
hasModifier(variableDeclaration, ModifierFlags.Export) ||
|
||||
variableDeclaration.parent.parent.kind === SyntaxKind.ForOfStatement) {
|
||||
parent.parent.kind === SyntaxKind.ForOfStatement) {
|
||||
return textSpanFromVariableDeclaration(variableDeclaration);
|
||||
}
|
||||
|
||||
@@ -410,7 +413,7 @@ namespace ts.BreakpointResolver {
|
||||
hasModifier(parameter, ModifierFlags.Public | ModifierFlags.Private);
|
||||
}
|
||||
|
||||
function spanInParameterDeclaration(parameter: ParameterDeclaration): TextSpan {
|
||||
function spanInParameterDeclaration(parameter: ParameterDeclaration): TextSpan | undefined {
|
||||
if (isBindingPattern(parameter.name)) {
|
||||
// Set breakpoint in binding pattern
|
||||
return spanInBindingPattern(parameter.name);
|
||||
@@ -438,7 +441,7 @@ namespace ts.BreakpointResolver {
|
||||
(functionDeclaration.parent.kind === SyntaxKind.ClassDeclaration && functionDeclaration.kind !== SyntaxKind.Constructor);
|
||||
}
|
||||
|
||||
function spanInFunctionDeclaration(functionDeclaration: FunctionLikeDeclaration): TextSpan {
|
||||
function spanInFunctionDeclaration(functionDeclaration: FunctionLikeDeclaration): TextSpan | undefined {
|
||||
// No breakpoints in the function signature
|
||||
if (!functionDeclaration.body) {
|
||||
return undefined;
|
||||
@@ -453,7 +456,7 @@ namespace ts.BreakpointResolver {
|
||||
return spanInNode(functionDeclaration.body);
|
||||
}
|
||||
|
||||
function spanInFunctionBlock(block: Block): TextSpan {
|
||||
function spanInFunctionBlock(block: Block): TextSpan | undefined {
|
||||
const nodeForSpanInBlock = block.statements.length ? block.statements[0] : block.getLastToken();
|
||||
if (canFunctionHaveSpanInWholeDeclaration(<FunctionLikeDeclaration>block.parent)) {
|
||||
return spanInNodeIfStartsOnSameLine(block.parent, nodeForSpanInBlock);
|
||||
@@ -462,7 +465,7 @@ namespace ts.BreakpointResolver {
|
||||
return spanInNode(nodeForSpanInBlock);
|
||||
}
|
||||
|
||||
function spanInBlock(block: Block): TextSpan {
|
||||
function spanInBlock(block: Block): TextSpan | undefined {
|
||||
switch (block.parent.kind) {
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
if (getModuleInstanceState(block.parent as ModuleDeclaration) !== ModuleInstanceState.Instantiated) {
|
||||
@@ -486,8 +489,8 @@ namespace ts.BreakpointResolver {
|
||||
return spanInNode(block.statements[0]);
|
||||
}
|
||||
|
||||
function spanInInitializerOfForLike(forLikeStatement: ForStatement | ForOfStatement | ForInStatement): TextSpan {
|
||||
if (forLikeStatement.initializer.kind === SyntaxKind.VariableDeclarationList) {
|
||||
function spanInInitializerOfForLike(forLikeStatement: ForStatement | ForOfStatement | ForInStatement): TextSpan | undefined {
|
||||
if (forLikeStatement.initializer!.kind === SyntaxKind.VariableDeclarationList) {
|
||||
// Declaration list - set breakpoint in first declaration
|
||||
const variableDeclarationList = <VariableDeclarationList>forLikeStatement.initializer;
|
||||
if (variableDeclarationList.declarations.length > 0) {
|
||||
@@ -500,7 +503,7 @@ namespace ts.BreakpointResolver {
|
||||
}
|
||||
}
|
||||
|
||||
function spanInForStatement(forStatement: ForStatement): TextSpan {
|
||||
function spanInForStatement(forStatement: ForStatement): TextSpan | undefined {
|
||||
if (forStatement.initializer) {
|
||||
return spanInInitializerOfForLike(forStatement);
|
||||
}
|
||||
@@ -513,7 +516,7 @@ namespace ts.BreakpointResolver {
|
||||
}
|
||||
}
|
||||
|
||||
function spanInBindingPattern(bindingPattern: BindingPattern): TextSpan {
|
||||
function spanInBindingPattern(bindingPattern: BindingPattern): TextSpan | undefined {
|
||||
// Set breakpoint in first binding element
|
||||
const firstBindingElement = forEach(bindingPattern.elements,
|
||||
element => element.kind !== SyntaxKind.OmittedExpression ? element : undefined);
|
||||
@@ -531,7 +534,7 @@ namespace ts.BreakpointResolver {
|
||||
return textSpanFromVariableDeclaration(<VariableDeclaration>bindingPattern.parent);
|
||||
}
|
||||
|
||||
function spanInArrayLiteralOrObjectLiteralDestructuringPattern(node: DestructuringPattern): TextSpan {
|
||||
function spanInArrayLiteralOrObjectLiteralDestructuringPattern(node: DestructuringPattern): TextSpan | undefined {
|
||||
Debug.assert(node.kind !== SyntaxKind.ArrayBindingPattern && node.kind !== SyntaxKind.ObjectBindingPattern);
|
||||
const elements: NodeArray<Expression | ObjectLiteralElement> = node.kind === SyntaxKind.ArrayLiteralExpression ? node.elements : (node as ObjectLiteralExpression).properties;
|
||||
|
||||
@@ -550,7 +553,7 @@ namespace ts.BreakpointResolver {
|
||||
}
|
||||
|
||||
// Tokens:
|
||||
function spanInOpenBraceToken(node: Node): TextSpan {
|
||||
function spanInOpenBraceToken(node: Node): TextSpan | undefined {
|
||||
switch (node.parent.kind) {
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
const enumDeclaration = <EnumDeclaration>node.parent;
|
||||
@@ -568,7 +571,7 @@ namespace ts.BreakpointResolver {
|
||||
return spanInNode(node.parent);
|
||||
}
|
||||
|
||||
function spanInCloseBraceToken(node: Node): TextSpan {
|
||||
function spanInCloseBraceToken(node: Node): TextSpan | undefined {
|
||||
switch (node.parent.kind) {
|
||||
case SyntaxKind.ModuleBlock:
|
||||
// If this is not an instantiated module block, no bp span
|
||||
@@ -617,7 +620,7 @@ namespace ts.BreakpointResolver {
|
||||
}
|
||||
}
|
||||
|
||||
function spanInCloseBracketToken(node: Node): TextSpan {
|
||||
function spanInCloseBracketToken(node: Node): TextSpan | undefined {
|
||||
switch (node.parent.kind) {
|
||||
case SyntaxKind.ArrayBindingPattern:
|
||||
// Breakpoint in last binding element or binding pattern if it contains no elements
|
||||
@@ -636,7 +639,7 @@ namespace ts.BreakpointResolver {
|
||||
}
|
||||
}
|
||||
|
||||
function spanInOpenParenToken(node: Node): TextSpan {
|
||||
function spanInOpenParenToken(node: Node): TextSpan | undefined {
|
||||
if (node.parent.kind === SyntaxKind.DoStatement || // Go to while keyword and do action instead
|
||||
node.parent.kind === SyntaxKind.CallExpression ||
|
||||
node.parent.kind === SyntaxKind.NewExpression) {
|
||||
@@ -651,7 +654,7 @@ namespace ts.BreakpointResolver {
|
||||
return spanInNode(node.parent);
|
||||
}
|
||||
|
||||
function spanInCloseParenToken(node: Node): TextSpan {
|
||||
function spanInCloseParenToken(node: Node): TextSpan | undefined {
|
||||
// Is this close paren token of parameter list, set span in previous token
|
||||
switch (node.parent.kind) {
|
||||
case SyntaxKind.FunctionExpression:
|
||||
@@ -677,7 +680,7 @@ namespace ts.BreakpointResolver {
|
||||
}
|
||||
}
|
||||
|
||||
function spanInColonToken(node: Node): TextSpan {
|
||||
function spanInColonToken(node: Node): TextSpan | undefined {
|
||||
// Is this : specifying return annotation of the function declaration
|
||||
if (isFunctionLike(node.parent) ||
|
||||
node.parent.kind === SyntaxKind.PropertyAssignment ||
|
||||
@@ -688,7 +691,7 @@ namespace ts.BreakpointResolver {
|
||||
return spanInNode(node.parent);
|
||||
}
|
||||
|
||||
function spanInGreaterThanOrLessThanToken(node: Node): TextSpan {
|
||||
function spanInGreaterThanOrLessThanToken(node: Node): TextSpan | undefined {
|
||||
if (node.parent.kind === SyntaxKind.TypeAssertionExpression) {
|
||||
return spanInNextNode(node);
|
||||
}
|
||||
@@ -696,7 +699,7 @@ namespace ts.BreakpointResolver {
|
||||
return spanInNode(node.parent);
|
||||
}
|
||||
|
||||
function spanInWhileKeyword(node: Node): TextSpan {
|
||||
function spanInWhileKeyword(node: Node): TextSpan | undefined {
|
||||
if (node.parent.kind === SyntaxKind.DoStatement) {
|
||||
// Set span on while expression
|
||||
return textSpanEndingAtNextToken(node, (<DoStatement>node.parent).expression);
|
||||
@@ -706,7 +709,7 @@ namespace ts.BreakpointResolver {
|
||||
return spanInNode(node.parent);
|
||||
}
|
||||
|
||||
function spanInOfKeyword(node: Node): TextSpan {
|
||||
function spanInOfKeyword(node: Node): TextSpan | undefined {
|
||||
if (node.parent.kind === SyntaxKind.ForOfStatement) {
|
||||
// Set using next token
|
||||
return spanInNextNode(node);
|
||||
|
||||
+17
-12
@@ -300,6 +300,8 @@ namespace ts {
|
||||
case ClassificationType.text:
|
||||
case ClassificationType.parameterName:
|
||||
return TokenClass.Identifier;
|
||||
default:
|
||||
return undefined!; // TODO: GH#18217 Debug.assertNever(type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -559,6 +561,7 @@ namespace ts {
|
||||
case ClassificationType.jsxAttribute: return ClassificationTypeNames.jsxAttribute;
|
||||
case ClassificationType.jsxText: return ClassificationTypeNames.jsxText;
|
||||
case ClassificationType.jsxAttributeStringLiteralValue: return ClassificationTypeNames.jsxAttributeStringLiteralValue;
|
||||
default: return undefined!; // TODO: GH#18217 throw Debug.assertNever(type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -813,7 +816,7 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
|
||||
function tryClassifyJsxElementName(token: Node): ClassificationType {
|
||||
function tryClassifyJsxElementName(token: Node): ClassificationType | undefined {
|
||||
switch (token.parent && token.parent.kind) {
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
if ((<JsxOpeningElement>token.parent).tagName === token) {
|
||||
@@ -842,7 +845,7 @@ namespace ts {
|
||||
// for accurate classification, the actual token should be passed in. however, for
|
||||
// cases like 'disabled merge code' classification, we just get the token kind and
|
||||
// classify based on that instead.
|
||||
function classifyTokenType(tokenKind: SyntaxKind, token?: Node): ClassificationType {
|
||||
function classifyTokenType(tokenKind: SyntaxKind, token?: Node): ClassificationType | undefined {
|
||||
if (isKeyword(tokenKind)) {
|
||||
return ClassificationType.keyword;
|
||||
}
|
||||
@@ -859,20 +862,21 @@ namespace ts {
|
||||
|
||||
if (isPunctuation(tokenKind)) {
|
||||
if (token) {
|
||||
const parent = token.parent;
|
||||
if (tokenKind === SyntaxKind.EqualsToken) {
|
||||
// the '=' in a variable declaration is special cased here.
|
||||
if (token.parent.kind === SyntaxKind.VariableDeclaration ||
|
||||
token.parent.kind === SyntaxKind.PropertyDeclaration ||
|
||||
token.parent.kind === SyntaxKind.Parameter ||
|
||||
token.parent.kind === SyntaxKind.JsxAttribute) {
|
||||
if (parent.kind === SyntaxKind.VariableDeclaration ||
|
||||
parent.kind === SyntaxKind.PropertyDeclaration ||
|
||||
parent.kind === SyntaxKind.Parameter ||
|
||||
parent.kind === SyntaxKind.JsxAttribute) {
|
||||
return ClassificationType.operator;
|
||||
}
|
||||
}
|
||||
|
||||
if (token.parent.kind === SyntaxKind.BinaryExpression ||
|
||||
token.parent.kind === SyntaxKind.PrefixUnaryExpression ||
|
||||
token.parent.kind === SyntaxKind.PostfixUnaryExpression ||
|
||||
token.parent.kind === SyntaxKind.ConditionalExpression) {
|
||||
if (parent.kind === SyntaxKind.BinaryExpression ||
|
||||
parent.kind === SyntaxKind.PrefixUnaryExpression ||
|
||||
parent.kind === SyntaxKind.PostfixUnaryExpression ||
|
||||
parent.kind === SyntaxKind.ConditionalExpression) {
|
||||
return ClassificationType.operator;
|
||||
}
|
||||
}
|
||||
@@ -883,7 +887,8 @@ namespace ts {
|
||||
return ClassificationType.numericLiteral;
|
||||
}
|
||||
else if (tokenKind === SyntaxKind.StringLiteral) {
|
||||
return token.parent.kind === SyntaxKind.JsxAttribute ? ClassificationType.jsxAttributeStringLiteralValue : ClassificationType.stringLiteral;
|
||||
// TODO: GH#18217
|
||||
return token!.parent.kind === SyntaxKind.JsxAttribute ? ClassificationType.jsxAttributeStringLiteralValue : ClassificationType.stringLiteral;
|
||||
}
|
||||
else if (tokenKind === SyntaxKind.RegularExpressionLiteral) {
|
||||
// TODO: we should get another classification type for these literals.
|
||||
@@ -935,7 +940,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function processElement(element: Node) {
|
||||
function processElement(element: Node | undefined) {
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user