Merge branch 'master' into MergeMaster5-22-2

This commit is contained in:
Mohamed Hegazy
2018-05-22 12:21:45 -07:00
134 changed files with 1257 additions and 944 deletions
+32 -21
View File
@@ -158,7 +158,7 @@ namespace ts {
* If so, the node _must_ be in the current file (as that's the only way anything could have traversed to it to yield it as the error node)
* This version of `createDiagnosticForNode` uses the binder's context to account for this, and always yields correct diagnostics even in these situations.
*/
function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): Diagnostic {
function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): DiagnosticWithLocation {
return createDiagnosticForNodeInSourceFile(getSourceFileOfNode(node) || file, node, message, arg0, arg1, arg2);
}
@@ -1208,7 +1208,7 @@ namespace ts {
bind(node.statement);
popActiveLabel();
if (!activeLabel.referenced && !options.allowUnusedLabels) {
file.bindDiagnostics.push(createDiagnosticForNode(node.label, Diagnostics.Unused_label));
errorOrSuggestionOnFirstToken(unusedLabelIsError(options), node, Diagnostics.Unused_label);
}
if (!node.statement || node.statement.kind !== SyntaxKind.DoStatement) {
// do statement sets current flow inside bindDoStatement
@@ -1914,6 +1914,17 @@ namespace ts {
file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2));
}
function errorOrSuggestionOnFirstToken(isError: boolean, node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any) {
const span = getSpanOfTokenAtPosition(file, node.pos);
const diag = createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2);
if (isError) {
file.bindDiagnostics.push(diag);
}
else {
file.bindSuggestionDiagnostics = append(file.bindSuggestionDiagnostics, { ...diag, category: DiagnosticCategory.Suggestion });
}
}
function bind(node: Node): void {
if (!node) {
return;
@@ -2730,26 +2741,26 @@ namespace ts {
if (reportError) {
currentFlow = reportedUnreachableFlow;
// unreachable code is reported if
// - user has explicitly asked about it AND
// - statement is in not ambient context (statements in ambient context is already an error
// so we should not report extras) AND
// - node is not variable statement OR
// - node is block scoped variable statement OR
// - node is not block scoped variable statement and at least one variable declaration has initializer
// Rationale: we don't want to report errors on non-initialized var's since they are hoisted
// On the other side we do want to report errors on non-initialized 'lets' because of TDZ
const reportUnreachableCode =
!options.allowUnreachableCode &&
!(node.flags & NodeFlags.Ambient) &&
(
node.kind !== SyntaxKind.VariableStatement ||
getCombinedNodeFlags((<VariableStatement>node).declarationList) & NodeFlags.BlockScoped ||
forEach((<VariableStatement>node).declarationList.declarations, d => d.initializer)
);
if (!options.allowUnreachableCode) {
// unreachable code is reported if
// - user has explicitly asked about it AND
// - statement is in not ambient context (statements in ambient context is already an error
// so we should not report extras) AND
// - node is not variable statement OR
// - node is block scoped variable statement OR
// - node is not block scoped variable statement and at least one variable declaration has initializer
// Rationale: we don't want to report errors on non-initialized var's since they are hoisted
// On the other side we do want to report errors on non-initialized 'lets' because of TDZ
const isError =
unreachableCodeIsError(options) &&
!(node.flags & NodeFlags.Ambient) &&
(
!isVariableStatement(node) ||
!!(getCombinedNodeFlags(node.declarationList) & NodeFlags.BlockScoped) ||
node.declarationList.declarations.some(d => !!d.initializer)
);
if (reportUnreachableCode) {
errorOnFirstToken(node, Diagnostics.Unreachable_code_detected);
errorOrSuggestionOnFirstToken(isError, node, Diagnostics.Unreachable_code_detected);
}
}
}
+36 -12
View File
@@ -313,11 +313,11 @@ namespace ts {
getSuggestionDiagnostics: file => {
return (suggestionDiagnostics.get(file.fileName) || emptyArray).concat(getUnusedDiagnostics());
function getUnusedDiagnostics(): ReadonlyArray<Diagnostic> {
function getUnusedDiagnostics(): ReadonlyArray<DiagnosticWithLocation> {
if (file.isDeclarationFile) return emptyArray;
checkSourceFile(file);
const diagnostics: Diagnostic[] = [];
const diagnostics: DiagnosticWithLocation[] = [];
Debug.assert(!!(getNodeLinks(file).flags & NodeCheckFlags.TypeChecked));
checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(file), (kind, diag) => {
if (!unusedIsError(kind)) {
@@ -481,7 +481,7 @@ namespace ts {
const diagnostics = createDiagnosticCollection();
// Suggestion diagnostics must have a file. Keyed by source file name.
const suggestionDiagnostics = createMultiMap<Diagnostic>();
const suggestionDiagnostics = createMultiMap<DiagnosticWithLocation>();
const enum TypeFacts {
None = 0,
@@ -628,7 +628,7 @@ namespace ts {
Local,
Parameter,
}
type AddUnusedDiagnostic = (type: UnusedKind, diagnostic: Diagnostic) => void;
type AddUnusedDiagnostic = (type: UnusedKind, diagnostic: DiagnosticWithLocation) => void;
const builtinGlobals = createSymbolTable();
builtinGlobals.set(undefinedSymbol.escapedName, undefinedSymbol);
@@ -824,7 +824,7 @@ namespace ts {
diagnostics.add(diagnostic);
}
function addErrorOrSuggestion(isError: boolean, diagnostic: Diagnostic) {
function addErrorOrSuggestion(isError: boolean, diagnostic: DiagnosticWithLocation) {
if (isError) {
diagnostics.add(diagnostic);
}
@@ -9286,8 +9286,10 @@ namespace ts {
return type;
}
function getRegularTypeOfLiteralType(type: Type) {
return type.flags & TypeFlags.StringOrNumberLiteral && type.flags & TypeFlags.FreshLiteral ? (<LiteralType>type).regularType : type;
function getRegularTypeOfLiteralType(type: Type): Type {
return type.flags & TypeFlags.StringOrNumberLiteral && type.flags & TypeFlags.FreshLiteral ? (<LiteralType>type).regularType :
type.flags & TypeFlags.Union ? getUnionType(sameMap((<UnionType>type).types, getRegularTypeOfLiteralType)) :
type;
}
function getLiteralType(value: string | number, enumId?: number, symbol?: Symbol) {
@@ -12774,10 +12776,12 @@ namespace ts {
// all inferences were made to top-level occurrences of the type parameter, and
// the type parameter has no constraint or its constraint includes no primitive or literal types, and
// the type parameter was fixed during inference or does not occur at top-level in the return type.
const widenLiteralTypes = inference.topLevel &&
!hasPrimitiveConstraint(inference.typeParameter) &&
const primitiveConstraint = hasPrimitiveConstraint(inference.typeParameter);
const widenLiteralTypes = !primitiveConstraint && inference.topLevel &&
(inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter));
const baseCandidates = widenLiteralTypes ? sameMap(candidates, getWidenedLiteralType) : candidates;
const baseCandidates = primitiveConstraint ? sameMap(candidates, getRegularTypeOfLiteralType) :
widenLiteralTypes ? sameMap(candidates, getWidenedLiteralType) :
candidates;
// If all inferences were made from contravariant positions, infer a common subtype. Otherwise, if
// union types were requested or if all inferences were made from the return type position, infer a
// union type. Otherwise, infer a common supertype.
@@ -15303,6 +15307,26 @@ namespace ts {
}
}
// Return true if the given expression is possibly a discriminant value. We limit the kinds of
// expressions we check to those that don't depend on their contextual type in order not to cause
// recursive (and possibly infinite) invocations of getContextualType.
function isPossiblyDiscriminantValue(node: Expression): boolean {
switch (node.kind) {
case SyntaxKind.StringLiteral:
case SyntaxKind.NumericLiteral:
case SyntaxKind.NoSubstitutionTemplateLiteral:
case SyntaxKind.TrueKeyword:
case SyntaxKind.FalseKeyword:
case SyntaxKind.NullKeyword:
case SyntaxKind.Identifier:
return true;
case SyntaxKind.PropertyAccessExpression:
case SyntaxKind.ParenthesizedExpression:
return isPossiblyDiscriminantValue((<PropertyAccessExpression | ParenthesizedExpression>node).expression);
}
return false;
}
// Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily
// be "pushed" onto a node using the contextualType property.
function getApparentTypeOfContextualType(node: Expression): Type {
@@ -15316,8 +15340,8 @@ namespace ts {
propLoop: for (const prop of node.properties) {
if (!prop.symbol) continue;
if (prop.kind !== SyntaxKind.PropertyAssignment) continue;
if (isDiscriminantProperty(contextualType, prop.symbol.escapedName)) {
const discriminatingType = getTypeOfNode(prop.initializer);
if (isPossiblyDiscriminantValue(prop.initializer) && isDiscriminantProperty(contextualType, prop.symbol.escapedName)) {
const discriminatingType = checkExpression(prop.initializer);
for (const type of (contextualType as UnionType).types) {
const targetType = getTypeOfPropertyOfType(type, prop.symbol.escapedName);
if (targetType && checkTypeAssignableTo(discriminatingType, targetType, /*errorNode*/ undefined)) {
+12 -4
View File
@@ -14,8 +14,8 @@ namespace ts {
return pathIsRelative(moduleName) || isRootedDiskPath(moduleName);
}
export function sortAndDeduplicateDiagnostics(diagnostics: ReadonlyArray<Diagnostic>): Diagnostic[] {
return sortAndDeduplicate(diagnostics, compareDiagnostics);
export function sortAndDeduplicateDiagnostics<T extends Diagnostic>(diagnostics: ReadonlyArray<T>): T[] {
return sortAndDeduplicate<T>(diagnostics, compareDiagnostics);
}
}
@@ -1619,8 +1619,8 @@ namespace ts {
return localizedDiagnosticMessages && localizedDiagnosticMessages[message.key] || message.message;
}
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: (string | number)[]): Diagnostic;
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage): Diagnostic {
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): DiagnosticWithLocation {
Debug.assertGreaterThanOrEqual(start, 0);
Debug.assertGreaterThanOrEqual(length, 0);
@@ -1991,6 +1991,14 @@ namespace ts {
return moduleResolution;
}
export function unreachableCodeIsError(options: CompilerOptions): boolean {
return options.allowUnreachableCode === false;
}
export function unusedLabelIsError(options: CompilerOptions): boolean {
return options.allowUnusedLabels === false;
}
export function getAreDeclarationMapsEnabled(options: CompilerOptions) {
return !!(options.declaration && options.declarationMap);
}
+4 -2
View File
@@ -2238,7 +2238,8 @@
},
"Left side of comma operator is unused and has no side effects.": {
"category": "Error",
"code": 2695
"code": 2695,
"reportsUnnecessary": true
},
"The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead?": {
"category": "Error",
@@ -3673,7 +3674,8 @@
},
"Unreachable code detected.": {
"category": "Error",
"code": 7027
"code": 7027,
"reportsUnnecessary": true
},
"Unused label.": {
"category": "Error",
+1
View File
@@ -2463,6 +2463,7 @@ namespace ts {
if (node.symbolCount !== undefined) updated.symbolCount = node.symbolCount;
if (node.parseDiagnostics !== undefined) updated.parseDiagnostics = node.parseDiagnostics;
if (node.bindDiagnostics !== undefined) updated.bindDiagnostics = node.bindDiagnostics;
if (node.bindSuggestionDiagnostics !== undefined) updated.bindSuggestionDiagnostics = node.bindSuggestionDiagnostics;
if (node.lineMap !== undefined) updated.lineMap = node.lineMap;
if (node.classifiableNames !== undefined) updated.classifiableNames = node.classifiableNames;
if (node.resolvedModules !== undefined) updated.resolvedModules = node.resolvedModules;
+2 -1
View File
@@ -595,7 +595,7 @@ namespace ts {
// tslint:enable variable-name
let sourceFile: SourceFile;
let parseDiagnostics: Diagnostic[];
let parseDiagnostics: DiagnosticWithLocation[];
let syntaxCursor: IncrementalParser.SyntaxCursor;
let currentToken: SyntaxKind;
@@ -912,6 +912,7 @@ namespace ts {
sourceFile.text = sourceText;
sourceFile.bindDiagnostics = [];
sourceFile.bindSuggestionDiagnostics = undefined;
sourceFile.languageVersion = languageVersion;
sourceFile.fileName = normalizePath(fileName);
sourceFile.languageVariant = getLanguageVariant(scriptKind);
+36 -28
View File
@@ -394,8 +394,8 @@ namespace ts {
return resolutions;
}
interface DiagnosticCache {
perFile?: Map<Diagnostic[]>;
interface DiagnosticCache<T extends Diagnostic> {
perFile?: Map<T[]>;
allDiagnostics?: Diagnostic[];
}
@@ -454,7 +454,7 @@ namespace ts {
export function getConfigFileParsingDiagnostics(configFileParseResult: ParsedCommandLine): ReadonlyArray<Diagnostic> {
return configFileParseResult.options.configFile ?
configFileParseResult.options.configFile.parseDiagnostics.concat(configFileParseResult.errors) :
[...configFileParseResult.options.configFile.parseDiagnostics, ...configFileParseResult.errors] :
configFileParseResult.errors;
}
@@ -517,8 +517,8 @@ namespace ts {
let classifiableNames: UnderscoreEscapedMap<true>;
let modifiedFilePaths: Path[] | undefined;
const cachedSemanticDiagnosticsForFile: DiagnosticCache = {};
const cachedDeclarationDiagnosticsForFile: DiagnosticCache = {};
const cachedSemanticDiagnosticsForFile: DiagnosticCache<Diagnostic> = {};
const cachedDeclarationDiagnosticsForFile: DiagnosticCache<DiagnosticWithLocation> = {};
let resolvedTypeReferenceDirectives = createMap<ResolvedTypeReferenceDirective>();
let fileProcessingDiagnostics = createDiagnosticCollection();
@@ -1313,10 +1313,10 @@ namespace ts {
return filesByName.get(path);
}
function getDiagnosticsHelper(
function getDiagnosticsHelper<T extends Diagnostic>(
sourceFile: SourceFile,
getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationToken) => ReadonlyArray<Diagnostic>,
cancellationToken: CancellationToken): ReadonlyArray<Diagnostic> {
getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationToken) => ReadonlyArray<T>,
cancellationToken: CancellationToken): ReadonlyArray<T> {
if (sourceFile) {
return getDiagnostics(sourceFile, cancellationToken);
}
@@ -1328,7 +1328,7 @@ namespace ts {
}));
}
function getSyntacticDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): ReadonlyArray<Diagnostic> {
function getSyntacticDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): ReadonlyArray<DiagnosticWithLocation> {
return getDiagnosticsHelper(sourceFile, getSyntacticDiagnosticsForFile, cancellationToken);
}
@@ -1336,7 +1336,7 @@ namespace ts {
return getDiagnosticsHelper(sourceFile, getSemanticDiagnosticsForFile, cancellationToken);
}
function getDeclarationDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): ReadonlyArray<Diagnostic> {
function getDeclarationDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): ReadonlyArray<DiagnosticWithLocation> {
const options = program.getCompilerOptions();
// collect diagnostics from the program only once if either no source file was specified or out/outFile is set (bundled emit)
if (!sourceFile || options.out || options.outFile) {
@@ -1347,7 +1347,7 @@ namespace ts {
}
}
function getSyntacticDiagnosticsForFile(sourceFile: SourceFile): ReadonlyArray<Diagnostic> {
function getSyntacticDiagnosticsForFile(sourceFile: SourceFile): ReadonlyArray<DiagnosticWithLocation> {
// For JavaScript files, we report semantic errors for using TypeScript-only
// constructs from within a JavaScript file as syntactic errors.
if (isSourceFileJavaScript(sourceFile)) {
@@ -1382,7 +1382,7 @@ namespace ts {
}
}
function getSemanticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
function getSemanticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): ReadonlyArray<Diagnostic> {
return getAndCacheDiagnostics(sourceFile, cancellationToken, cachedSemanticDiagnosticsForFile, getSemanticDiagnosticsForFileNoCache);
}
@@ -1403,15 +1403,22 @@ namespace ts {
// By default, only type-check .ts, .tsx, 'Deferred' and 'External' files (external files are added by plugins)
const includeBindAndCheckDiagnostics = sourceFile.scriptKind === ScriptKind.TS || sourceFile.scriptKind === ScriptKind.TSX ||
sourceFile.scriptKind === ScriptKind.External || isCheckJs || sourceFile.scriptKind === ScriptKind.Deferred;
const bindDiagnostics = includeBindAndCheckDiagnostics ? sourceFile.bindDiagnostics : emptyArray;
const bindDiagnostics: ReadonlyArray<Diagnostic> = includeBindAndCheckDiagnostics ? sourceFile.bindDiagnostics : emptyArray;
const checkDiagnostics = includeBindAndCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : emptyArray;
const fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName);
const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName);
let diagnostics = bindDiagnostics.concat(checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile);
if (isCheckJs) {
diagnostics = concatenate(diagnostics, sourceFile.jsDocDiagnostics);
let diagnostics: Diagnostic[] | undefined;
for (const diags of [bindDiagnostics, checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile, isCheckJs ? sourceFile.jsDocDiagnostics : undefined]) {
if (diags) {
for (const diag of diags) {
if (shouldReportDiagnostic(diag)) {
diagnostics = append(diagnostics, diag);
}
}
}
}
return filter(diagnostics, shouldReportDiagnostic);
return diagnostics;
});
}
@@ -1440,9 +1447,9 @@ namespace ts {
return true;
}
function getJavaScriptSyntacticDiagnosticsForFile(sourceFile: SourceFile): Diagnostic[] {
function getJavaScriptSyntacticDiagnosticsForFile(sourceFile: SourceFile): DiagnosticWithLocation[] {
return runWithCancellationToken(() => {
const diagnostics: Diagnostic[] = [];
const diagnostics: DiagnosticWithLocation[] = [];
let parent: Node = sourceFile;
walk(sourceFile);
@@ -1610,20 +1617,20 @@ namespace ts {
}
}
function createDiagnosticForNodeArray(nodes: NodeArray<Node>, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): Diagnostic {
function createDiagnosticForNodeArray(nodes: NodeArray<Node>, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): DiagnosticWithLocation {
const start = nodes.pos;
return createFileDiagnostic(sourceFile, start, nodes.end - start, message, arg0, arg1, arg2);
}
// Since these are syntactic diagnostics, parent might not have been set
// this means the sourceFile cannot be infered from the node
function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): Diagnostic {
function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): DiagnosticWithLocation {
return createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2);
}
});
}
function getDeclarationDiagnosticsWorker(sourceFile: SourceFile | undefined, cancellationToken: CancellationToken): Diagnostic[] {
function getDeclarationDiagnosticsWorker(sourceFile: SourceFile, cancellationToken: CancellationToken): ReadonlyArray<DiagnosticWithLocation> {
return getAndCacheDiagnostics(sourceFile, cancellationToken, cachedDeclarationDiagnosticsForFile, getDeclarationDiagnosticsForFileNoCache);
}
@@ -1635,15 +1642,16 @@ namespace ts {
});
}
function getAndCacheDiagnostics(
function getAndCacheDiagnostics<T extends Diagnostic>(
sourceFile: SourceFile | undefined,
cancellationToken: CancellationToken,
cache: DiagnosticCache,
getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationToken) => Diagnostic[]) {
cache: DiagnosticCache<T>,
getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationToken) => T[],
): ReadonlyArray<T> {
const cachedResult = sourceFile
? cache.perFile && cache.perFile.get(sourceFile.path)
: cache.allDiagnostics;
: cache.allDiagnostics as T[];
if (cachedResult) {
return cachedResult;
@@ -1651,7 +1659,7 @@ namespace ts {
const result = getDiagnostics(sourceFile, cancellationToken) || emptyArray;
if (sourceFile) {
if (!cache.perFile) {
cache.perFile = createMap<Diagnostic[]>();
cache.perFile = createMap<T[]>();
}
cache.perFile.set(sourceFile.path, result);
}
@@ -1661,7 +1669,7 @@ namespace ts {
return result;
}
function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): ReadonlyArray<DiagnosticWithLocation> {
return sourceFile.isDeclarationFile ? [] : getDeclarationDiagnosticsWorker(sourceFile, cancellationToken);
}
+1 -1
View File
@@ -90,7 +90,7 @@ namespace ts {
let onSubstituteNode: TransformationContext["onSubstituteNode"] = (_, node) => node;
let onEmitNode: TransformationContext["onEmitNode"] = (hint, node, callback) => callback(hint, node);
let state = TransformationState.Uninitialized;
const diagnostics: Diagnostic[] = [];
const diagnostics: DiagnosticWithLocation[] = [];
// The transformation context is provided to each transformer as part of transformer
// initialization.
+1 -1
View File
@@ -1,6 +1,6 @@
/*@internal*/
namespace ts {
export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, file: SourceFile | undefined): Diagnostic[] {
export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, file: SourceFile | undefined): DiagnosticWithLocation[] {
if (file && isSourceFileJavaScript(file)) {
return []; // No declaration diagnostics for js for now
}
+18 -10
View File
@@ -2599,16 +2599,17 @@ namespace ts {
// File-level diagnostics reported by the parser (includes diagnostics about /// references
// as well as code diagnostics).
/* @internal */ parseDiagnostics: Diagnostic[];
/* @internal */ parseDiagnostics: DiagnosticWithLocation[];
// File-level diagnostics reported by the binder.
/* @internal */ bindDiagnostics: Diagnostic[];
/* @internal */ bindDiagnostics: DiagnosticWithLocation[];
/* @internal */ bindSuggestionDiagnostics?: DiagnosticWithLocation[];
// File-level JSDoc diagnostics reported by the JSDoc parser
/* @internal */ jsDocDiagnostics?: Diagnostic[];
/* @internal */ jsDocDiagnostics?: DiagnosticWithLocation[];
// Stores additional file-level diagnostics reported by the program
/* @internal */ additionalSyntacticDiagnostics?: ReadonlyArray<Diagnostic>;
/* @internal */ additionalSyntacticDiagnostics?: ReadonlyArray<DiagnosticWithLocation>;
// Stores a line map for the file.
// This field should never be used directly to obtain line map, use getLineMap function instead.
@@ -2746,9 +2747,10 @@ namespace ts {
getOptionsDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
getGlobalDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<DiagnosticWithLocation>;
/** The first time this is called, it will return global diagnostics (no location). */
getSemanticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<DiagnosticWithLocation>;
getConfigFileParsingDiagnostics(): ReadonlyArray<Diagnostic>;
/**
@@ -3069,7 +3071,7 @@ namespace ts {
* Does *not* get *all* suggestion diagnostics, just the ones that were convenient to report in the checker.
* Others are added in computeSuggestionDiagnostics.
*/
/* @internal */ getSuggestionDiagnostics(file: SourceFile): ReadonlyArray<Diagnostic>;
/* @internal */ getSuggestionDiagnostics(file: SourceFile): ReadonlyArray<DiagnosticWithLocation>;
/**
* Depending on the operation performed, it may be appropriate to throw away the checker
@@ -4227,6 +4229,11 @@ namespace ts {
code: number;
source?: string;
}
export interface DiagnosticWithLocation extends Diagnostic {
file: SourceFile;
start: number;
length: number;
}
export enum DiagnosticCategory {
Warning,
@@ -5083,7 +5090,7 @@ namespace ts {
*/
onEmitNode: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void;
/* @internal */ addDiagnostic(diag: Diagnostic): void;
/* @internal */ addDiagnostic(diag: DiagnosticWithLocation): void;
}
export interface TransformationResult<T extends Node> {
@@ -5091,7 +5098,7 @@ namespace ts {
transformed: T[];
/** Gets diagnostics for the transformation. */
diagnostics?: Diagnostic[];
diagnostics?: DiagnosticWithLocation[];
/**
* Gets a substitute for a node, if one is available; otherwise, returns the original node.
@@ -5309,7 +5316,8 @@ namespace ts {
// If fileName is provided, gets all the diagnostics associated with that file name.
// Otherwise, returns all the diagnostics (global and file associated) in this collection.
getDiagnostics(fileName?: string): Diagnostic[];
getDiagnostics(fileName: string): DiagnosticWithLocation[];
getDiagnostics(): Diagnostic[];
reattachFileDiagnostics(newFile: SourceFile): void;
}
+10 -8
View File
@@ -603,7 +603,7 @@ namespace ts {
}
}
export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): Diagnostic {
export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): DiagnosticWithLocation {
const sourceFile = getSourceFileOfNode(node);
return createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2, arg3);
}
@@ -613,17 +613,17 @@ namespace ts {
return createFileDiagnostic(sourceFile, start, nodes.end - start, message, arg0, arg1, arg2, arg3);
}
export function createDiagnosticForNodeInSourceFile(sourceFile: SourceFile, node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): Diagnostic {
export function createDiagnosticForNodeInSourceFile(sourceFile: SourceFile, node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): DiagnosticWithLocation {
const span = getErrorSpanForNode(sourceFile, node);
return createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2, arg3);
}
export function createDiagnosticForNodeSpan(sourceFile: SourceFile, startNode: Node, endNode: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): Diagnostic {
export function createDiagnosticForNodeSpan(sourceFile: SourceFile, startNode: Node, endNode: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): DiagnosticWithLocation {
const start = skipTrivia(sourceFile.text, startNode.pos);
return createFileDiagnostic(sourceFile, start, endNode.end - start, message, arg0, arg1, arg2, arg3);
}
export function createDiagnosticForNodeFromMessageChain(node: Node, messageChain: DiagnosticMessageChain): Diagnostic {
export function createDiagnosticForNodeFromMessageChain(node: Node, messageChain: DiagnosticMessageChain): DiagnosticWithLocation {
const sourceFile = getSourceFileOfNode(node);
const span = getErrorSpanForNode(sourceFile, node);
return {
@@ -2645,7 +2645,7 @@ namespace ts {
export function createDiagnosticCollection(): DiagnosticCollection {
let nonFileDiagnostics = [] as SortedArray<Diagnostic>;
const filesWithDiagnostics = [] as SortedArray<string>;
const fileDiagnostics = createMap<SortedArray<Diagnostic>>();
const fileDiagnostics = createMap<SortedArray<DiagnosticWithLocation>>();
let hasReadNonFileDiagnostics = false;
return {
@@ -2664,8 +2664,8 @@ namespace ts {
if (diagnostic.file) {
diagnostics = fileDiagnostics.get(diagnostic.file.fileName);
if (!diagnostics) {
diagnostics = [] as SortedArray<Diagnostic>;
fileDiagnostics.set(diagnostic.file.fileName, diagnostics);
diagnostics = [] as SortedArray<DiagnosticWithLocation>;
fileDiagnostics.set(diagnostic.file.fileName, diagnostics as SortedArray<DiagnosticWithLocation>);
insertSorted(filesWithDiagnostics, diagnostic.file.fileName, compareStringsCaseSensitive);
}
}
@@ -2687,12 +2687,14 @@ namespace ts {
return nonFileDiagnostics;
}
function getDiagnostics(fileName: string): DiagnosticWithLocation[];
function getDiagnostics(): Diagnostic[];
function getDiagnostics(fileName?: string): Diagnostic[] {
if (fileName) {
return fileDiagnostics.get(fileName) || [];
}
const fileDiags = flatMap(filesWithDiagnostics, f => fileDiagnostics.get(f));
const fileDiags: Diagnostic[] = flatMap(filesWithDiagnostics, f => fileDiagnostics.get(f));
if (!nonFileDiagnostics.length) {
return fileDiags;
}
+11 -5
View File
@@ -1317,8 +1317,13 @@ Actual: ${stringify(fullActual)}`);
}
private testDiagnostics(expected: ReadonlyArray<FourSlashInterface.Diagnostic>, diagnostics: ReadonlyArray<ts.Diagnostic>, category: string) {
assert.deepEqual(ts.realizeDiagnostics(diagnostics, ts.newLineCharacter), expected.map<ts.RealizedDiagnostic>(e => (
{ message: e.message, category, code: e.code, ...ts.createTextSpanFromRange(e.range || this.getRanges()[0]) })));
assert.deepEqual(ts.realizeDiagnostics(diagnostics, ts.newLineCharacter), expected.map((e): ts.RealizedDiagnostic => ({
message: e.message,
category,
code: e.code,
...ts.createTextSpanFromRange(e.range || this.getRanges()[0]),
reportsUnnecessary: e.reportsUnnecessary,
})));
}
public verifyQuickInfoAt(markerName: string, expectedText: string, expectedDocumentation?: string) {
@@ -4422,15 +4427,15 @@ namespace FourSlashInterface {
this.state.verifyQuickInfoDisplayParts(kind, kindModifiers, textSpan, displayParts, documentation, tags);
}
public getSyntacticDiagnostics(expected: ReadonlyArray<ts.RealizedDiagnostic>) {
public getSyntacticDiagnostics(expected: ReadonlyArray<Diagnostic>) {
this.state.getSyntacticDiagnostics(expected);
}
public getSemanticDiagnostics(expected: ReadonlyArray<ts.RealizedDiagnostic>) {
public getSemanticDiagnostics(expected: ReadonlyArray<Diagnostic>) {
this.state.getSemanticDiagnostics(expected);
}
public getSuggestionDiagnostics(expected: ReadonlyArray<ts.RealizedDiagnostic>) {
public getSuggestionDiagnostics(expected: ReadonlyArray<Diagnostic>) {
this.state.getSuggestionDiagnostics(expected);
}
@@ -4837,6 +4842,7 @@ namespace FourSlashInterface {
message: string;
range?: FourSlash.Range;
code: number;
reportsUnnecessary?: true;
}
export interface GetEditsForFileRenameOptions {
+1 -1
View File
@@ -1406,7 +1406,7 @@ namespace Harness {
const dupeCase = ts.createMap<number>();
for (const inputFile of inputFiles.filter(f => f.content !== undefined)) {
// Filter down to the errors in the file
const fileErrors = diagnostics.filter(e => {
const fileErrors = diagnostics.filter((e): e is ts.DiagnosticWithLocation => {
const errFn = e.file;
return errFn && utils.removeTestPathPrefixes(errFn.fileName) === utils.removeTestPathPrefixes(inputFile.unitName);
});
+3 -3
View File
@@ -398,13 +398,13 @@ namespace Harness.LanguageService {
cleanupSemanticCache(): void {
this.shim.cleanupSemanticCache();
}
getSyntacticDiagnostics(fileName: string): ts.Diagnostic[] {
getSyntacticDiagnostics(fileName: string): ts.DiagnosticWithLocation[] {
return unwrapJSONCallResult(this.shim.getSyntacticDiagnostics(fileName));
}
getSemanticDiagnostics(fileName: string): ts.Diagnostic[] {
getSemanticDiagnostics(fileName: string): ts.DiagnosticWithLocation[] {
return unwrapJSONCallResult(this.shim.getSemanticDiagnostics(fileName));
}
getSuggestionDiagnostics(fileName: string): ts.Diagnostic[] {
getSuggestionDiagnostics(fileName: string): ts.DiagnosticWithLocation[] {
return unwrapJSONCallResult(this.shim.getSuggestionDiagnostics(fileName));
}
getCompilerOptionsDiagnostics(): ts.Diagnostic[] {
+1 -1
View File
@@ -154,7 +154,7 @@ namespace project {
const configParseResult = ts.parseJsonSourceFileConfigFileContent(result, configParseHost, ts.getDirectoryPath(configFileName), this.compilerOptions);
inputFiles = configParseResult.fileNames;
this.compilerOptions = configParseResult.options;
errors = result.parseDiagnostics.concat(configParseResult.errors);
errors = [...result.parseDiagnostics, ...configParseResult.errors];
}
const compilerHost = new ProjectCompilerHost(this.sys, this.compilerOptions, this.testCaseJustName, this.testCase, moduleKind);
+56 -2
View File
@@ -506,7 +506,29 @@ D();
},
libFile);
testOrganizeImports("JsxFactoryUsed",
testOrganizeImports("JsxFactoryUsedJsx",
{
path: "/test.jsx",
content: `
import { React, Other } from "react";
<div/>;
`,
},
reactLibFile);
testOrganizeImports("JsxFactoryUsedJs",
{
path: "/test.js",
content: `
import { React, Other } from "react";
<div/>;
`,
},
reactLibFile);
testOrganizeImports("JsxFactoryUsedTsx",
{
path: "/test.tsx",
content: `
@@ -517,7 +539,39 @@ import { React, Other } from "react";
},
reactLibFile);
// This is descriptive, rather than normative
// TS files are not JSX contexts, so the parser does not treat
// `<div/>` as a JSX element.
testOrganizeImports("JsxFactoryUsedTs",
{
path: "/test.ts",
content: `
import { React, Other } from "react";
<div/>;
`,
},
reactLibFile);
testOrganizeImports("JsxFactoryUnusedJsx",
{
path: "/test.jsx",
content: `
import { React, Other } from "react";
`,
},
reactLibFile);
// Note: Since the file extension does not end with "x", the jsx compiler option
// will not be enabled. The import should be retained regardless.
testOrganizeImports("JsxFactoryUnusedJs",
{
path: "/test.js",
content: `
import { React, Other } from "react";
`,
},
reactLibFile);
testOrganizeImports("JsxFactoryUnusedTsx",
{
path: "/test.tsx",
+112 -8
View File
@@ -407,6 +407,12 @@ namespace ts.projectSystem {
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 {
const start = str.indexOf(substring);
Debug.assert(start !== -1);
return createTextSpan(start, substring.length);
}
/**
* Test server cancellation token used to mock host token cancellation requests.
* The cancelAfterRequest constructor param specifies how many isCancellationRequested() calls
@@ -7445,10 +7451,17 @@ namespace ts.projectSystem {
});
describe("when event handler is not set but session is created with canUseEvents = true", () => {
verifyProjectsUpdatedInBackgroundEvent(createSessionThatUsesEvents);
describe("without noGetErrOnBackgroundUpdate, diagnostics for open files are queued", () => {
verifyProjectsUpdatedInBackgroundEvent(createSessionThatUsesEvents);
});
function createSessionThatUsesEvents(host: TestServerHost): ProjectsUpdatedInBackgroundEventVerifier {
const session = createSession(host, { canUseEvents: true });
describe("with noGetErrOnBackgroundUpdate, diagnostics for open file are not queued", () => {
verifyProjectsUpdatedInBackgroundEvent(host => createSessionThatUsesEvents(host, /*noGetErrOnBackgroundUpdate*/ true));
});
function createSessionThatUsesEvents(host: TestServerHost, noGetErrOnBackgroundUpdate?: boolean): ProjectsUpdatedInBackgroundEventVerifier {
const session = createSession(host, { canUseEvents: true, noGetErrOnBackgroundUpdate });
return {
session,
@@ -7480,6 +7493,10 @@ namespace ts.projectSystem {
// Verified the events, reset them
session.clearMessages();
if (events.length) {
host.checkTimeoutQueueLength(noGetErrOnBackgroundUpdate ? 0 : 1); // Error checking queued only if not noGetErrOnBackgroundUpdate
}
}
}
});
@@ -8409,9 +8426,96 @@ new C();`
});
});
function textSpanFromSubstring(str: string, substring: string): TextSpan {
const start = str.indexOf(substring);
Debug.assert(start !== -1);
return createTextSpan(start, substring.length);
}
describe("document registry in project service", () => {
const projectRootPath = "/user/username/projects/project";
const importModuleContent = `import {a} from "./module1"`;
const file: File = {
path: `${projectRootPath}/index.ts`,
content: importModuleContent
};
const moduleFile: File = {
path: `${projectRootPath}/module1.d.ts`,
content: "export const a: number;"
};
const configFile: File = {
path: `${projectRootPath}/tsconfig.json`,
content: JSON.stringify({ files: ["index.ts"] })
};
function getProject(service: TestProjectService) {
return service.configuredProjects.get(configFile.path);
}
function checkProject(service: TestProjectService, moduleIsOrphan: boolean) {
// Update the project
const project = getProject(service);
project.getLanguageService();
checkProjectActualFiles(project, [file.path, libFile.path, configFile.path, ...(moduleIsOrphan ? [] : [moduleFile.path])]);
const moduleInfo = service.getScriptInfo(moduleFile.path);
assert.isDefined(moduleInfo);
assert.equal(moduleInfo.isOrphan(), moduleIsOrphan);
const key = service.documentRegistry.getKeyForCompilationSettings(project.getCompilationSettings());
assert.deepEqual(service.documentRegistry.getLanguageServiceRefCounts(moduleInfo.path), [[key, moduleIsOrphan ? undefined : 1]]);
}
function createServiceAndHost() {
const host = createServerHost([file, moduleFile, libFile, configFile]);
const service = createProjectService(host);
service.openClientFile(file.path);
checkProject(service, /*moduleIsOrphan*/ false);
return { host, service };
}
function changeFileToNotImportModule(service: TestProjectService) {
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);
service.applyChangesToFile(info, [{ span: { start: 0, length: 0 }, newText: importModuleContent }]);
checkProject(service, /*moduleIsOrphan*/ false);
}
it("Caches the source file if script info is orphan", () => {
const { service } = createServiceAndHost();
const project = getProject(service);
const moduleInfo = service.getScriptInfo(moduleFile.path);
const sourceFile = moduleInfo.cacheSourceFile.sourceFile;
assert.equal(project.getSourceFile(moduleInfo.path), sourceFile);
// edit file
changeFileToNotImportModule(service);
assert.equal(moduleInfo.cacheSourceFile.sourceFile, sourceFile);
// write content back
changeFileToImportModule(service);
assert.equal(moduleInfo.cacheSourceFile.sourceFile, sourceFile);
assert.equal(project.getSourceFile(moduleInfo.path), sourceFile);
});
it("Caches the source file if script info is orphan, and orphan script info changes", () => {
const { host, service } = createServiceAndHost();
const project = getProject(service);
const moduleInfo = service.getScriptInfo(moduleFile.path);
const sourceFile = moduleInfo.cacheSourceFile.sourceFile;
assert.equal(project.getSourceFile(moduleInfo.path), sourceFile);
// edit file
changeFileToNotImportModule(service);
assert.equal(moduleInfo.cacheSourceFile.sourceFile, sourceFile);
const updatedModuleContent = moduleFile.content + "\nexport const b: number;";
host.writeFile(moduleFile.path, updatedModuleContent);
// write content back
changeFileToImportModule(service);
assert.notEqual(moduleInfo.cacheSourceFile.sourceFile, sourceFile);
assert.equal(project.getSourceFile(moduleInfo.path), moduleInfo.cacheSourceFile.sourceFile);
assert.equal(moduleInfo.cacheSourceFile.sourceFile.text, updatedModuleContent);
});
});
}
+5 -5
View File
@@ -346,21 +346,21 @@ namespace ts.server {
return notImplemented();
}
getSyntacticDiagnostics(file: string): Diagnostic[] {
getSyntacticDiagnostics(file: string): DiagnosticWithLocation[] {
return this.getDiagnostics(file, CommandNames.SyntacticDiagnosticsSync);
}
getSemanticDiagnostics(file: string): Diagnostic[] {
getSemanticDiagnostics(file: string): DiagnosticWithLocation[] {
return this.getDiagnostics(file, CommandNames.SemanticDiagnosticsSync);
}
getSuggestionDiagnostics(file: string): Diagnostic[] {
getSuggestionDiagnostics(file: string): DiagnosticWithLocation[] {
return this.getDiagnostics(file, CommandNames.SuggestionDiagnosticsSync);
}
private getDiagnostics(file: string, command: CommandNames): Diagnostic[] {
private getDiagnostics(file: string, command: CommandNames): DiagnosticWithLocation[] {
const request = this.processRequest<protocol.SyntacticDiagnosticsSyncRequest | protocol.SemanticDiagnosticsSyncRequest | protocol.SuggestionDiagnosticsSyncRequest>(command, { file, includeLinePosition: true });
const response = this.processResponse<protocol.SyntacticDiagnosticsSyncResponse | protocol.SemanticDiagnosticsSyncResponse | protocol.SuggestionDiagnosticsSyncResponse>(request);
return (<protocol.DiagnosticWithLinePosition[]>response.body).map((entry): Diagnostic => {
return (<protocol.DiagnosticWithLinePosition[]>response.body).map((entry): DiagnosticWithLocation => {
const category = firstDefined(Object.keys(DiagnosticCategory), id =>
isString(id) && entry.category === id.toLowerCase() ? (<any>DiagnosticCategory)[id] : undefined);
return {
+19 -5
View File
@@ -339,7 +339,8 @@ namespace ts.server {
/*@internal*/
readonly typingsCache: TypingsCache;
private readonly documentRegistry: DocumentRegistry;
/*@internal*/
readonly documentRegistry: DocumentRegistry;
/**
* Container of all known scripts
@@ -403,7 +404,7 @@ namespace ts.server {
/* @internal */
pendingEnsureProjectForOpenFiles: boolean;
readonly currentDirectory: string;
readonly currentDirectory: NormalizedPath;
readonly toCanonicalFileName: (f: string) => string;
public readonly host: ServerHost;
@@ -450,7 +451,7 @@ namespace ts.server {
if (this.host.realpath) {
this.realpathToScriptInfos = createMultiMap();
}
this.currentDirectory = this.host.getCurrentDirectory();
this.currentDirectory = toNormalizedPath(this.host.getCurrentDirectory());
this.toCanonicalFileName = createGetCanonicalFileName(this.host.useCaseSensitiveFileNames);
this.globalCacheLocationDirectoryPath = this.typingsInstaller.globalTypingsCacheLocation &&
ensureTrailingDirectorySeparator(this.toPath(this.typingsInstaller.globalTypingsCacheLocation));
@@ -474,7 +475,7 @@ namespace ts.server {
extraFileExtensions: []
};
this.documentRegistry = createDocumentRegistry(this.host.useCaseSensitiveFileNames, this.currentDirectory);
this.documentRegistry = createDocumentRegistryInternal(this.host.useCaseSensitiveFileNames, this.currentDirectory, this);
const watchLogLevel = this.logger.hasLevel(LogLevel.verbose) ? WatchLogLevel.Verbose :
this.logger.loggingEnabled() ? WatchLogLevel.TriggerOnly : WatchLogLevel.None;
const log: (s: string) => void = watchLogLevel !== WatchLogLevel.None ? (s => this.logger.info(s)) : noop;
@@ -495,6 +496,19 @@ namespace ts.server {
return getNormalizedAbsolutePath(fileName, this.host.getCurrentDirectory());
}
/*@internal*/
setDocument(key: DocumentRegistryBucketKey, path: Path, sourceFile: SourceFile) {
const info = this.getScriptInfoForPath(path);
Debug.assert(!!info);
info.cacheSourceFile = { key, sourceFile };
}
/*@internal*/
getDocument(key: DocumentRegistryBucketKey, path: Path) {
const info = this.getScriptInfoForPath(path);
return info && info.cacheSourceFile && info.cacheSourceFile.key === key && info.cacheSourceFile.sourceFile;
}
/* @internal */
ensureInferredProjectsUpToDate_TestOnly() {
this.ensureProjectStructuresUptoDate();
@@ -1329,7 +1343,7 @@ namespace ts.server {
if (!result.endOfFileToken) {
result.endOfFileToken = <EndOfFileToken>{ kind: SyntaxKind.EndOfFileToken };
}
const errors = result.parseDiagnostics;
const errors = result.parseDiagnostics as Diagnostic[];
const parsedCommandLine = parseJsonSourceFileConfigFileContent(
result,
cachedDirectoryStructureHost,
+9
View File
@@ -202,6 +202,12 @@ namespace ts.server {
return fileName[0] === "^" || getBaseFileName(fileName)[0] === "^";
}
/*@internal*/
export interface DocumentRegistrySourceFileCache {
key: DocumentRegistryBucketKey;
sourceFile: SourceFile;
}
export class ScriptInfo {
/**
* All projects that include this file
@@ -221,6 +227,9 @@ namespace ts.server {
/** Set to real path if path is different from info.path */
private realpath: Path | undefined;
/*@internal*/
cacheSourceFile: DocumentRegistrySourceFileCache;
constructor(
private readonly host: ServerHost,
readonly fileName: NormalizedPath,
+2
View File
@@ -505,6 +505,7 @@ namespace ts.server {
canUseEvents: true,
suppressDiagnosticEvents,
syntaxOnly,
noGetErrOnBackgroundUpdate,
globalPlugins,
pluginProbeLocations,
allowLocalPluginLoads,
@@ -939,6 +940,7 @@ namespace ts.server {
const suppressDiagnosticEvents = hasArgument("--suppressDiagnosticEvents");
const syntaxOnly = hasArgument("--syntaxOnly");
const telemetryEnabled = hasArgument(Arguments.EnableTelemetry);
const noGetErrOnBackgroundUpdate = hasArgument("--noGetErrOnBackgroundUpdate");
logger.info(`Starting TS Server`);
logger.info(`Version: ${version}`);
+4 -1
View File
@@ -295,6 +295,7 @@ namespace ts.server {
suppressDiagnosticEvents?: boolean;
syntaxOnly?: boolean;
throttleWaitMilliseconds?: number;
noGetErrOnBackgroundUpdate?: boolean;
globalPlugins?: ReadonlyArray<string>;
pluginProbeLocations?: ReadonlyArray<string>;
@@ -319,6 +320,7 @@ namespace ts.server {
protected canUseEvents: boolean;
private suppressDiagnosticEvents?: boolean;
private eventHandler: ProjectServiceEventHandler;
private readonly noGetErrOnBackgroundUpdate?: boolean;
constructor(opts: SessionOptions) {
this.host = opts.host;
@@ -329,6 +331,7 @@ namespace ts.server {
this.logger = opts.logger;
this.canUseEvents = opts.canUseEvents;
this.suppressDiagnosticEvents = opts.suppressDiagnosticEvents;
this.noGetErrOnBackgroundUpdate = opts.noGetErrOnBackgroundUpdate;
const { throttleWaitMilliseconds } = opts;
@@ -404,7 +407,7 @@ namespace ts.server {
private projectsUpdatedInBackgroundEvent(openFiles: string[]): void {
this.projectService.logger.info(`got projects updated in background, updating diagnostics for ${openFiles}`);
if (openFiles.length) {
if (!this.suppressDiagnosticEvents) {
if (!this.suppressDiagnosticEvents && !this.noGetErrOnBackgroundUpdate) {
const checkList = this.createCheckList(openFiles);
// For now only queue error checking for open files. We can change this to include non open files as well
+3 -3
View File
@@ -79,17 +79,17 @@ namespace ts {
return { fileName, textChanges };
}
export function codeFixAll(context: CodeFixAllContext, errorCodes: number[], use: (changes: textChanges.ChangeTracker, error: Diagnostic, commands: Push<CodeActionCommand>) => void): CombinedCodeActions {
export function codeFixAll(context: CodeFixAllContext, errorCodes: number[], use: (changes: textChanges.ChangeTracker, error: DiagnosticWithLocation, commands: Push<CodeActionCommand>) => void): CombinedCodeActions {
const commands: CodeActionCommand[] = [];
const changes = textChanges.ChangeTracker.with(context, t =>
eachDiagnostic(context, errorCodes, diag => use(t, diag, commands)));
return createCombinedCodeActions(changes, commands.length === 0 ? undefined : commands);
}
function eachDiagnostic({ program, sourceFile }: CodeFixAllContext, errorCodes: number[], cb: (diag: Diagnostic) => void): void {
function eachDiagnostic({ program, sourceFile }: CodeFixAllContext, errorCodes: number[], cb: (diag: DiagnosticWithLocation) => void): void {
for (const diag of program.getSemanticDiagnostics(sourceFile).concat(computeSuggestionDiagnostics(sourceFile, program))) {
if (contains(errorCodes, diag.code)) {
cb(diag);
cb(diag as DiagnosticWithLocation);
}
}
}
@@ -9,7 +9,7 @@ namespace ts.codefix {
return [createCodeFixAction(fixId, changes, Diagnostics.Call_decorator_expression, fixId, Diagnostics.Add_to_all_uncalled_decorators)];
},
fixIds: [fixId],
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => makeChange(changes, diag.file!, diag.start!)),
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => makeChange(changes, diag.file, diag.start)),
});
function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number) {
@@ -12,8 +12,8 @@ namespace ts.codefix {
},
fixIds: [fixId],
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => {
const decl = getDeclaration(diag.file!, diag.start!);
if (decl) doChange(changes, diag.file!, decl);
const decl = getDeclaration(diag.file, diag.start);
if (decl) doChange(changes, diag.file, decl);
}),
});
@@ -38,8 +38,8 @@ namespace ts.codefix {
getAllCodeActions: context => {
const seenLines = createMap<true>();
return codeFixAll(context, errorCodes, (changes, diag) => {
if (textChanges.isValidLocationToAddComment(diag.file!, diag.start!)) {
makeChange(changes, diag.file!, diag.start!, seenLines);
if (textChanges.isValidLocationToAddComment(diag.file, diag.start)) {
makeChange(changes, diag.file, diag.start, seenLines);
}
});
},
@@ -23,7 +23,7 @@ namespace ts.codefix {
const seenNames = createMap<true>();
return codeFixAll(context, errorCodes, (changes, diag) => {
const { program, preferences } = context;
const info = getInfo(diag.file!, diag.start!, program.getTypeChecker());
const info = getInfo(diag.file, diag.start, program.getTypeChecker());
if (!info) return;
const { classDeclaration, classDeclarationSourceFile, inJs, makeStatic, token, call } = info;
if (!addToSeen(seenNames, token.text)) {
@@ -17,7 +17,7 @@ namespace ts.codefix {
getAllCodeActions: context => {
const seenClassDeclarations = createMap<true>();
return codeFixAll(context, errorCodes, (changes, diag) => {
const classDeclaration = getClass(diag.file!, diag.start!);
const classDeclaration = getClass(diag.file, diag.start);
if (addToSeen(seenClassDeclarations, getNodeId(classDeclaration))) {
addMissingMembers(classDeclaration, context.sourceFile, context.program.getTypeChecker(), changes, context.preferences);
}
@@ -18,10 +18,10 @@ namespace ts.codefix {
getAllCodeActions(context) {
const seenClassDeclarations = createMap<true>();
return codeFixAll(context, errorCodes, (changes, diag) => {
const classDeclaration = getClass(diag.file!, diag.start!);
const classDeclaration = getClass(diag.file, diag.start);
if (addToSeen(seenClassDeclarations, getNodeId(classDeclaration))) {
for (const implementedTypeNode of getClassImplementsHeritageClauseElements(classDeclaration)) {
addMissingDeclarations(context.program.getTypeChecker(), implementedTypeNode, diag.file!, classDeclaration, changes, context.preferences);
addMissingDeclarations(context.program.getTypeChecker(), implementedTypeNode, diag.file, classDeclaration, changes, context.preferences);
}
}
});
@@ -17,7 +17,7 @@ namespace ts.codefix {
const { sourceFile } = context;
const seenClasses = createMap<true>(); // Ensure we only do this once per class.
return codeFixAll(context, errorCodes, (changes, diag) => {
const nodes = getNodes(diag.file!, diag.start!);
const nodes = getNodes(diag.file, diag.start);
if (!nodes) return;
const { constructor, superCall } = nodes;
if (addToSeen(seenClasses, getNodeId(constructor.parent))) {
@@ -12,7 +12,7 @@ namespace ts.codefix {
},
fixIds: [fixId],
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) =>
doChange(changes, context.sourceFile, getNode(diag.file, diag.start!))),
doChange(changes, context.sourceFile, getNode(diag.file, diag.start))),
});
function getNode(sourceFile: SourceFile, pos: number): ConstructorDeclaration {
@@ -14,7 +14,7 @@ namespace ts.codefix {
},
fixIds: [fixId],
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => {
const nodes = getNodes(diag.file, diag.start!);
const nodes = getNodes(diag.file, diag.start);
if (nodes) doChanges(changes, diag.file, nodes.extendsToken, nodes.heritageClauses);
}),
});
@@ -19,7 +19,7 @@ namespace ts.codefix {
},
fixIds: [fixId],
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => {
doChange(changes, context.sourceFile, getInfo(diag.file, diag.start!, diag.code));
doChange(changes, context.sourceFile, getInfo(diag.file, diag.start, diag.code));
}),
});
+1 -1
View File
@@ -19,7 +19,7 @@ namespace ts.codefix {
},
fixIds: [fixId],
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => {
const info = getInfo(diag.file!, diag.start!, context);
const info = getInfo(diag.file, diag.start, context);
const { target } = context.host.getCompilationSettings();
if (info) doChange(changes, context.sourceFile, info.node, info.suggestion, target);
}),
@@ -53,7 +53,7 @@ namespace ts.codefix {
return codeFixAll(context, errorCodes, (changes, diag) => {
const { sourceFile } = context;
const startToken = getTokenAtPosition(sourceFile, diag.start, /*includeJsDocComment*/ false);
const token = findPrecedingToken(textSpanEnd(diag), diag.file!);
const token = findPrecedingToken(textSpanEnd(diag), diag.file);
switch (context.fixId) {
case fixIdPrefix:
if (isIdentifier(token) && canPrefix(token)) {
@@ -62,7 +62,7 @@ namespace ts.codefix {
break;
case fixIdDelete:
// Ignore if this range was already deleted.
if (deleted.some(d => rangeContainsPosition(d, diag.start!))) break;
if (deleted.some(d => rangeContainsPosition(d, diag.start))) break;
const importDecl = tryGetFullImport(startToken);
if (importDecl) {
+2 -2
View File
@@ -13,8 +13,8 @@ namespace ts.codefix {
},
fixIds: [fixId],
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => {
const info = getInfo(diag.file!, diag.start!);
if (info) doChange(changes, diag.file!, info);
const info = getInfo(diag.file, diag.start);
if (info) doChange(changes, diag.file, info);
}),
});
+44 -7
View File
@@ -87,9 +87,18 @@ namespace ts {
releaseDocumentWithKey(path: Path, key: DocumentRegistryBucketKey): void;
/*@internal*/
getLanguageServiceRefCounts(path: Path): [string, number | undefined][];
reportStats(): string;
}
/*@internal*/
export interface ExternalDocumentCache {
setDocument(key: DocumentRegistryBucketKey, path: Path, sourceFile: SourceFile): void;
getDocument(key: DocumentRegistryBucketKey, path: Path): SourceFile | undefined;
}
export type DocumentRegistryBucketKey = string & { __bucketKey: any };
interface DocumentRegistryEntry {
@@ -99,10 +108,14 @@ namespace ts {
// language services are referencing the file, then the file can be removed from the
// registry.
languageServiceRefCount: number;
owners: string[];
}
export function createDocumentRegistry(useCaseSensitiveFileNames?: boolean, currentDirectory = ""): DocumentRegistry {
export function createDocumentRegistry(useCaseSensitiveFileNames?: boolean, currentDirectory?: string): DocumentRegistry {
return createDocumentRegistryInternal(useCaseSensitiveFileNames, currentDirectory);
}
/*@internal*/
export function createDocumentRegistryInternal(useCaseSensitiveFileNames?: boolean, currentDirectory = "", externalCache?: ExternalDocumentCache): DocumentRegistry {
// Maps from compiler setting target (ES3, ES5, etc.) to all the cached documents we have
// for those settings.
const buckets = createMap<Map<DocumentRegistryEntry>>();
@@ -123,12 +136,11 @@ namespace ts {
function reportStats() {
const bucketInfoArray = arrayFrom(buckets.keys()).filter(name => name && name.charAt(0) === "_").map(name => {
const entries = buckets.get(name);
const sourceFiles: { name: string; refCount: number; references: string[]; }[] = [];
const sourceFiles: { name: string; refCount: number; }[] = [];
entries.forEach((entry, name) => {
sourceFiles.push({
name,
refCount: entry.languageServiceRefCount,
references: entry.owners.slice(0)
refCount: entry.languageServiceRefCount
});
});
sourceFiles.sort((x, y) => y.refCount - x.refCount);
@@ -173,14 +185,27 @@ namespace ts {
const bucket = getBucketForCompilationSettings(key, /*createIfMissing*/ true);
let entry = bucket.get(path);
const scriptTarget = scriptKind === ScriptKind.JSON ? ScriptTarget.JSON : compilationSettings.target;
if (!entry && externalCache) {
const sourceFile = externalCache.getDocument(key, path);
if (sourceFile) {
Debug.assert(acquiring);
entry = {
sourceFile,
languageServiceRefCount: 0
};
bucket.set(path, entry);
}
}
if (!entry) {
// Have never seen this file with these settings. Create a new source file for it.
const sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, scriptTarget, version, /*setNodeParents*/ false, scriptKind);
if (externalCache) {
externalCache.setDocument(key, path, sourceFile);
}
entry = {
sourceFile,
languageServiceRefCount: 1,
owners: []
};
bucket.set(path, entry);
}
@@ -191,6 +216,9 @@ namespace ts {
if (entry.sourceFile.version !== version) {
entry.sourceFile = updateLanguageServiceSourceFile(entry.sourceFile, scriptSnapshot, version,
scriptSnapshot.getChangeRange(entry.sourceFile.scriptSnapshot));
if (externalCache) {
externalCache.setDocument(key, path, entry.sourceFile);
}
}
// If we're acquiring, then this is the first time this LS is asking for this document.
@@ -202,6 +230,7 @@ namespace ts {
entry.languageServiceRefCount++;
}
}
Debug.assert(entry.languageServiceRefCount !== 0);
return entry.sourceFile;
}
@@ -225,6 +254,13 @@ namespace ts {
}
}
function getLanguageServiceRefCounts(path: Path) {
return arrayFrom(buckets.entries(), ([key, bucket]): [string, number | undefined] => {
const entry = bucket.get(path);
return [key, entry && entry.languageServiceRefCount];
});
}
return {
acquireDocument,
acquireDocumentWithKey,
@@ -232,6 +268,7 @@ namespace ts {
updateDocumentWithKey,
releaseDocument,
releaseDocumentWithKey,
getLanguageServiceRefCounts,
reportStats,
getKeyForCompilationSettings
};
+1 -1
View File
@@ -228,7 +228,7 @@ namespace ts.formatting {
* This function will return a predicate that for a given text range will tell
* if there are any parse errors that overlap with the range.
*/
function prepareRangeContainsErrorFunction(errors: Diagnostic[], originalRange: TextRange): (r: TextRange) => boolean {
function prepareRangeContainsErrorFunction(errors: ReadonlyArray<Diagnostic>, originalRange: TextRange): (r: TextRange) => boolean {
if (!errors.length) {
return rangeHasNoErrors;
}
+6
View File
@@ -569,6 +569,12 @@ namespace ts.formatting {
return childKind !== SyntaxKind.JsxClosingElement;
case SyntaxKind.JsxFragment:
return childKind !== SyntaxKind.JsxClosingFragment;
case SyntaxKind.IntersectionType:
case SyntaxKind.UnionType:
if (childKind === SyntaxKind.TypeLiteral) {
return false;
}
// falls through
}
// No explicit rule for given nodes so the result will follow the default value argument
return indentByDefault;
+3 -3
View File
@@ -92,7 +92,7 @@ namespace ts.OrganizeImports {
function removeUnusedImports(oldImports: ReadonlyArray<ImportDeclaration>, sourceFile: SourceFile, program: Program) {
const typeChecker = program.getTypeChecker();
const jsxNamespace = typeChecker.getJsxNamespace();
const jsxContext = sourceFile.languageVariant === LanguageVariant.JSX && program.getCompilerOptions().jsx;
const jsxElementsPresent = !!(sourceFile.transformFlags & TransformFlags.ContainsJsx);
const usedImports: ImportDeclaration[] = [];
@@ -138,8 +138,8 @@ namespace ts.OrganizeImports {
return usedImports;
function isDeclarationUsed(identifier: Identifier) {
// The JSX factory symbol is always used.
return jsxContext && (identifier.text === jsxNamespace) || FindAllReferences.Core.isSymbolReferencedInFile(identifier, typeChecker, sourceFile);
// The JSX factory symbol is always used if JSX elements are present - even if they are not allowed.
return jsxElementsPresent && (identifier.text === jsxNamespace) || FindAllReferences.Core.isSymbolReferencedInFile(identifier, typeChecker, sourceFile);
}
}
+6 -5
View File
@@ -545,9 +545,10 @@ namespace ts {
public referencedFiles: FileReference[];
public typeReferenceDirectives: FileReference[];
public syntacticDiagnostics: Diagnostic[];
public parseDiagnostics: Diagnostic[];
public bindDiagnostics: Diagnostic[];
public syntacticDiagnostics: DiagnosticWithLocation[];
public parseDiagnostics: DiagnosticWithLocation[];
public bindDiagnostics: DiagnosticWithLocation[];
public bindSuggestionDiagnostics?: DiagnosticWithLocation[];
public isDeclarationFile: boolean;
public isDefaultLib: boolean;
@@ -1376,7 +1377,7 @@ namespace ts {
}
/// Diagnostics
function getSyntacticDiagnostics(fileName: string): Diagnostic[] {
function getSyntacticDiagnostics(fileName: string): DiagnosticWithLocation[] {
synchronizeHostData();
return program.getSyntacticDiagnostics(getValidSourceFile(fileName), cancellationToken).slice();
@@ -1404,7 +1405,7 @@ namespace ts {
return [...semanticDiagnostics, ...declarationDiagnostics];
}
function getSuggestionDiagnostics(fileName: string): Diagnostic[] {
function getSuggestionDiagnostics(fileName: string): DiagnosticWithLocation[] {
synchronizeHostData();
return computeSuggestionDiagnostics(getValidSourceFile(fileName), program);
}
+4 -3
View File
@@ -586,7 +586,7 @@ namespace ts {
length: number;
category: string;
code: number;
unused?: {};
reportsUnnecessary?: {};
}
export function realizeDiagnostics(diagnostics: ReadonlyArray<Diagnostic>, newLine: string): RealizedDiagnostic[] {
return diagnostics.map(d => realizeDiagnostic(d, newLine));
@@ -598,7 +598,8 @@ namespace ts {
start: diagnostic.start,
length: diagnostic.length,
category: diagnosticCategoryName(diagnostic),
code: diagnostic.code
code: diagnostic.code,
reportsUnnecessary: diagnostic.reportsUnnecessary,
};
}
@@ -1146,7 +1147,7 @@ namespace ts {
typeAcquisition: configFile.typeAcquisition,
files: configFile.fileNames,
raw: configFile.raw,
errors: realizeDiagnostics(result.parseDiagnostics.concat(configFile.errors), "\r\n")
errors: realizeDiagnostics([...result.parseDiagnostics, ...configFile.errors], "\r\n")
};
});
}
+3 -2
View File
@@ -1,9 +1,9 @@
/* @internal */
namespace ts {
export function computeSuggestionDiagnostics(sourceFile: SourceFile, program: Program): Diagnostic[] {
export function computeSuggestionDiagnostics(sourceFile: SourceFile, program: Program): DiagnosticWithLocation[] {
program.getSemanticDiagnostics(sourceFile);
const checker = program.getDiagnosticsProducingTypeChecker();
const diags: Diagnostic[] = [];
const diags: DiagnosticWithLocation[] = [];
if (sourceFile.commonJsModuleIndicator &&
(programContainsEs6Modules(program) || compilerOptionsIndicateEs6Modules(program.getCompilerOptions())) &&
@@ -60,6 +60,7 @@ namespace ts {
}
}
addRange(diags, sourceFile.bindSuggestionDiagnostics);
return diags.concat(checker.getSuggestionDiagnostics(sourceFile)).sort((d1, d2) => d1.start - d2.start);
}
+1 -1
View File
@@ -6,7 +6,7 @@ namespace ts {
* @param compilerOptions Optional compiler options.
*/
export function transform<T extends Node>(source: T | T[], transformers: TransformerFactory<T>[], compilerOptions?: CompilerOptions) {
const diagnostics: Diagnostic[] = [];
const diagnostics: DiagnosticWithLocation[] = [];
compilerOptions = fixupCompilerOptions(compilerOptions, diagnostics);
const nodes = isArray(source) ? source : [source];
const result = transformNodes(/*resolver*/ undefined, /*emitHost*/ undefined, compilerOptions, nodes, transformers, /*allowDtsFiles*/ true);
+3 -2
View File
@@ -249,9 +249,10 @@ namespace ts {
export interface LanguageService {
cleanupSemanticCache(): void;
getSyntacticDiagnostics(fileName: string): Diagnostic[];
getSyntacticDiagnostics(fileName: string): DiagnosticWithLocation[];
/** The first time this is called, it will return global diagnostics (no location). */
getSemanticDiagnostics(fileName: string): Diagnostic[];
getSuggestionDiagnostics(fileName: string): Diagnostic[];
getSuggestionDiagnostics(fileName: string): DiagnosticWithLocation[];
// TODO: Rename this to getProgramDiagnostics to better indicate that these are any
// diagnostics present for the program level, and not just 'options' diagnostics.
+17 -9
View File
@@ -1734,9 +1734,10 @@ declare namespace ts {
emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult;
getOptionsDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
getGlobalDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<DiagnosticWithLocation>;
/** The first time this is called, it will return global diagnostics (no location). */
getSemanticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<DiagnosticWithLocation>;
getConfigFileParsingDiagnostics(): ReadonlyArray<Diagnostic>;
/**
* Gets a type checker that can be used to semantically analyze source files in the program.
@@ -2359,6 +2360,11 @@ declare namespace ts {
code: number;
source?: string;
}
interface DiagnosticWithLocation extends Diagnostic {
file: SourceFile;
start: number;
length: number;
}
enum DiagnosticCategory {
Warning = 0,
Error = 1,
@@ -2754,7 +2760,7 @@ declare namespace ts {
/** Gets the transformed source files. */
transformed: T[];
/** Gets diagnostics for the transformation. */
diagnostics?: Diagnostic[];
diagnostics?: DiagnosticWithLocation[];
/**
* Gets a substitute for a node, if one is available; otherwise, returns the original node.
*
@@ -2954,13 +2960,13 @@ declare namespace ts {
}
}
declare namespace ts {
const versionMajorMinor = "2.9";
const versionMajorMinor = "3.0";
/** The version of the TypeScript compiler release */
const version: string;
}
declare namespace ts {
function isExternalModuleNameRelative(moduleName: string): boolean;
function sortAndDeduplicateDiagnostics(diagnostics: ReadonlyArray<Diagnostic>): Diagnostic[];
function sortAndDeduplicateDiagnostics<T extends Diagnostic>(diagnostics: ReadonlyArray<T>): T[];
}
declare function setTimeout(handler: (...args: any[]) => void, timeout: number): any;
declare function clearTimeout(handle: any): void;
@@ -4497,9 +4503,10 @@ declare namespace ts {
}
interface LanguageService {
cleanupSemanticCache(): void;
getSyntacticDiagnostics(fileName: string): Diagnostic[];
getSyntacticDiagnostics(fileName: string): DiagnosticWithLocation[];
/** The first time this is called, it will return global diagnostics (no location). */
getSemanticDiagnostics(fileName: string): Diagnostic[];
getSuggestionDiagnostics(fileName: string): Diagnostic[];
getSuggestionDiagnostics(fileName: string): DiagnosticWithLocation[];
getCompilerOptionsDiagnostics(): Diagnostic[];
/**
* @deprecated Use getEncodedSyntacticClassifications instead.
@@ -8127,7 +8134,6 @@ declare namespace ts.server {
syntaxOnly?: boolean;
}
class ProjectService {
private readonly documentRegistry;
/**
* Container of all known scripts
*/
@@ -8176,7 +8182,7 @@ declare namespace ts.server {
private safelist;
private legacySafelist;
private pendingProjectUpdates;
readonly currentDirectory: string;
readonly currentDirectory: NormalizedPath;
readonly toCanonicalFileName: (f: string) => string;
readonly host: ServerHost;
readonly logger: Logger;
@@ -8391,6 +8397,7 @@ declare namespace ts.server {
suppressDiagnosticEvents?: boolean;
syntaxOnly?: boolean;
throttleWaitMilliseconds?: number;
noGetErrOnBackgroundUpdate?: boolean;
globalPlugins?: ReadonlyArray<string>;
pluginProbeLocations?: ReadonlyArray<string>;
allowLocalPluginLoads?: boolean;
@@ -8410,6 +8417,7 @@ declare namespace ts.server {
protected canUseEvents: boolean;
private suppressDiagnosticEvents?;
private eventHandler;
private readonly noGetErrOnBackgroundUpdate?;
constructor(opts: SessionOptions);
private sendRequestCompletedEvent;
private defaultEventHandler;
+14 -7
View File
@@ -1734,9 +1734,10 @@ declare namespace ts {
emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult;
getOptionsDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
getGlobalDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<DiagnosticWithLocation>;
/** The first time this is called, it will return global diagnostics (no location). */
getSemanticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<DiagnosticWithLocation>;
getConfigFileParsingDiagnostics(): ReadonlyArray<Diagnostic>;
/**
* Gets a type checker that can be used to semantically analyze source files in the program.
@@ -2359,6 +2360,11 @@ declare namespace ts {
code: number;
source?: string;
}
interface DiagnosticWithLocation extends Diagnostic {
file: SourceFile;
start: number;
length: number;
}
enum DiagnosticCategory {
Warning = 0,
Error = 1,
@@ -2754,7 +2760,7 @@ declare namespace ts {
/** Gets the transformed source files. */
transformed: T[];
/** Gets diagnostics for the transformation. */
diagnostics?: Diagnostic[];
diagnostics?: DiagnosticWithLocation[];
/**
* Gets a substitute for a node, if one is available; otherwise, returns the original node.
*
@@ -2954,13 +2960,13 @@ declare namespace ts {
}
}
declare namespace ts {
const versionMajorMinor = "2.9";
const versionMajorMinor = "3.0";
/** The version of the TypeScript compiler release */
const version: string;
}
declare namespace ts {
function isExternalModuleNameRelative(moduleName: string): boolean;
function sortAndDeduplicateDiagnostics(diagnostics: ReadonlyArray<Diagnostic>): Diagnostic[];
function sortAndDeduplicateDiagnostics<T extends Diagnostic>(diagnostics: ReadonlyArray<T>): T[];
}
declare function setTimeout(handler: (...args: any[]) => void, timeout: number): any;
declare function clearTimeout(handle: any): void;
@@ -4497,9 +4503,10 @@ declare namespace ts {
}
interface LanguageService {
cleanupSemanticCache(): void;
getSyntacticDiagnostics(fileName: string): Diagnostic[];
getSyntacticDiagnostics(fileName: string): DiagnosticWithLocation[];
/** The first time this is called, it will return global diagnostics (no location). */
getSemanticDiagnostics(fileName: string): Diagnostic[];
getSuggestionDiagnostics(fileName: string): Diagnostic[];
getSuggestionDiagnostics(fileName: string): DiagnosticWithLocation[];
getCompilerOptionsDiagnostics(): Diagnostic[];
/**
* @deprecated Use getEncodedSyntacticClassifications instead.
@@ -13,7 +13,6 @@ tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(2
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(30,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access.
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(31,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access.
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(32,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access.
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(35,3): error TS7028: Unused label.
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(35,9): error TS1128: Declaration or statement expected.
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(38,2): error TS2364: The left-hand side of an assignment expression must be a variable or a property access.
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(38,6): error TS2364: The left-hand side of an assignment expression must be a variable or a property access.
@@ -39,7 +38,7 @@ tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(6
tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(70,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access.
==== tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts (39 errors) ====
==== tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts (38 errors) ====
// expected error for all the LHS of assignments
var value: any;
@@ -105,8 +104,6 @@ tests/cases/conformance/expressions/assignmentOperator/assignmentLHSIsValue.ts(7
// object literals
{ a: 0} = value;
~
!!! error TS7028: Unused label.
~
!!! error TS1128: Declaration or statement expected.
@@ -30,7 +30,7 @@ var derived2: Derived2;
var r2 = true ? 1 : '';
>r2 : string | number
>true ? 1 : '' : 1 | ""
>true ? 1 : '' : "" | 1
>true : true
>1 : 1
>'' : ""
@@ -1,10 +1,9 @@
tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(2,12): error TS2448: Block-scoped variable 'a' used before its declaration.
tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(5,12): error TS2448: Block-scoped variable 'a' used before its declaration.
tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(5,35): error TS7027: Unreachable code detected.
tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(8,7): error TS2448: Block-scoped variable 'b' used before its declaration.
==== tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts (4 errors) ====
==== tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts (3 errors) ====
// 1:
for (let {[a]: a} of [{ }]) continue;
~
@@ -14,8 +13,6 @@ tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(8,7): error TS2448: Bloc
for (let {[a]: a} = { }; false; ) continue;
~
!!! error TS2448: Block-scoped variable 'a' used before its declaration.
~~~~~~~~
!!! error TS7027: Unreachable code detected.
// 3:
let {[b]: b} = { };
@@ -15,7 +15,7 @@ var i: I<string>;
>I : I<T>
var y = i(""); // y should be string
>y : string
>y : ""
>i("") : ""
>i : I<string>
>"" : ""
+1 -1
View File
@@ -53,7 +53,7 @@ tests/cases/compiler/cf.ts(36,13): error TS7027: Unreachable code detected.
}
catch (e) {
x++;
}
}
finally {
x+=3;
}
+1 -1
View File
@@ -39,7 +39,7 @@ function f() {
}
catch (e) {
x++;
}
}
finally {
x+=3;
}
+1 -1
View File
@@ -77,7 +77,7 @@ function f() {
x++;
>x : Symbol(x, Decl(cf.ts, 2, 7))
}
}
finally {
x+=3;
>x : Symbol(x, Decl(cf.ts, 2, 7))
+1 -1
View File
@@ -121,7 +121,7 @@ function f() {
x++;
>x++ : number
>x : number
}
}
finally {
x+=3;
>x+=3 : number
@@ -14,7 +14,6 @@ tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignm
tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(38,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access.
tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(39,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.
tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(40,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.
tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(43,3): error TS7028: Unused label.
tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(43,10): error TS1128: Declaration or statement expected.
tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(46,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.
tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(52,15): error TS1034: 'super' must be followed by an argument list or member access.
@@ -40,7 +39,7 @@ tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignm
tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts(85,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.
==== tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts (40 errors) ====
==== tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignmentLHSIsValue.ts (39 errors) ====
// expected error for all the LHS of compound assignments (arithmetic and addition)
var value: any;
@@ -116,8 +115,6 @@ tests/cases/conformance/es7/exponentiationOperator/compoundExponentiationAssignm
// object literals
{ a: 0 } **= value;
~
!!! error TS7028: Unused label.
~~~
!!! error TS1128: Declaration or statement expected.
@@ -1,8 +1,8 @@
=== tests/cases/compiler/conditionalExpression1.ts ===
var x: boolean = (true ? 1 : ""); // should be an error
>x : boolean
>(true ? 1 : "") : 1 | ""
>true ? 1 : "" : 1 | ""
>(true ? 1 : "") : "" | 1
>true ? 1 : "" : "" | 1
>true : true
>1 : 1
>"" : ""
@@ -15,7 +15,7 @@ var b = false ? undefined : 0;
var c = false ? 1 : 0;
>c : number
>false ? 1 : 0 : 1 | 0
>false ? 1 : 0 : 0 | 1
>false : false
>1 : 1
>0 : 0
@@ -218,7 +218,7 @@ var result10: (t: X) => any = true ? (m) => m.propertyX1 : (n) => n.propertyX2;
//Expr1 and Expr2 are literals
var result11: any = true ? 1 : 'string';
>result11 : any
>true ? 1 : 'string' : 1 | "string"
>true ? 1 : 'string' : "string" | 1
>true : true
>1 : 1
>'string' : "string"
@@ -589,8 +589,8 @@ function zeroOf<T extends number | string | boolean>(value: T) {
><ZeroOf<T>>(typeof value === "number" ? 0 : typeof value === "string" ? "" : false) : ZeroOf<T>
>ZeroOf : ZeroOf<T>
>T : T
>(typeof value === "number" ? 0 : typeof value === "string" ? "" : false) : false | 0 | ""
>typeof value === "number" ? 0 : typeof value === "string" ? "" : false : false | 0 | ""
>(typeof value === "number" ? 0 : typeof value === "string" ? "" : false) : false | "" | 0
>typeof value === "number" ? 0 : typeof value === "string" ? "" : false : false | "" | 0
>typeof value === "number" : boolean
>typeof value : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
>value : T
@@ -1,9 +1,7 @@
tests/cases/compiler/constDeclarations-scopes.ts(12,5): error TS7027: Unreachable code detected.
tests/cases/compiler/constDeclarations-scopes.ts(21,1): error TS7027: Unreachable code detected.
tests/cases/compiler/constDeclarations-scopes.ts(27,1): error TS2410: The 'with' statement is not supported. All symbols in a 'with' block will have type 'any'.
==== tests/cases/compiler/constDeclarations-scopes.ts (3 errors) ====
==== tests/cases/compiler/constDeclarations-scopes.ts (1 errors) ====
// global
const c = "string";
@@ -16,8 +14,6 @@ tests/cases/compiler/constDeclarations-scopes.ts(27,1): error TS2410: The 'with'
}
else {
const c = 0;
~~~~~
!!! error TS7027: Unreachable code detected.
n = c;
}
@@ -27,8 +23,6 @@ tests/cases/compiler/constDeclarations-scopes.ts(27,1): error TS2410: The 'with'
}
do {
~~
!!! error TS7027: Unreachable code detected.
const c = 0;
n = c;
} while (true);
@@ -24,7 +24,7 @@ var y = [() => new c()];
var k: (() => c) | string = (() => new c()) || "";
>k : string | (() => c)
>c : c
>(() => new c()) || "" : (() => c) | ""
>(() => new c()) || "" : "" | (() => c)
>(() => new c()) : () => c
>() => new c() : () => c
>new c() : c
@@ -1,13 +1,10 @@
tests/cases/compiler/declarationEmitInvalidExport.ts(2,3): error TS7027: Unreachable code detected.
tests/cases/compiler/declarationEmitInvalidExport.ts(4,30): error TS4081: Exported type alias 'MyClass' has or is using private name 'myClass'.
tests/cases/compiler/declarationEmitInvalidExport.ts(5,1): error TS1128: Declaration or statement expected.
==== tests/cases/compiler/declarationEmitInvalidExport.ts (3 errors) ====
==== tests/cases/compiler/declarationEmitInvalidExport.ts (2 errors) ====
if (false) {
export var myClass = 0;
~~~~~~
!!! error TS7027: Unreachable code detected.
}
export type MyClass = typeof myClass;
~~~~~~~
@@ -10,7 +10,6 @@ tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassS
tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassSuperCallsInNonConstructorMembers.ts(12,13): error TS1005: ';' expected.
tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassSuperCallsInNonConstructorMembers.ts(13,9): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors.
tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassSuperCallsInNonConstructorMembers.ts(16,5): error TS2304: Cannot find name 'set'.
tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassSuperCallsInNonConstructorMembers.ts(16,5): error TS7027: Unreachable code detected.
tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassSuperCallsInNonConstructorMembers.ts(16,9): error TS1005: ';' expected.
tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassSuperCallsInNonConstructorMembers.ts(16,9): error TS2304: Cannot find name 'C'.
tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassSuperCallsInNonConstructorMembers.ts(16,11): error TS2304: Cannot find name 'v'.
@@ -38,7 +37,7 @@ tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassS
tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassSuperCallsInNonConstructorMembers.ts(31,1): error TS1128: Declaration or statement expected.
==== tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassSuperCallsInNonConstructorMembers.ts (38 errors) ====
==== tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassSuperCallsInNonConstructorMembers.ts (37 errors) ====
// error to use super calls outside a constructor
class Base {
@@ -79,8 +78,6 @@ tests/cases/conformance/classes/constructorDeclarations/superCalls/derivedClassS
set C(v) {
~~~
!!! error TS2304: Cannot find name 'set'.
~~~
!!! error TS7027: Unreachable code detected.
~
!!! error TS1005: ';' expected.
~
@@ -1,8 +1,7 @@
tests/cases/compiler/invalidContinueInDownlevelAsync.ts(3,9): error TS1107: Jump target cannot cross function boundary.
tests/cases/compiler/invalidContinueInDownlevelAsync.ts(6,9): error TS7027: Unreachable code detected.
==== tests/cases/compiler/invalidContinueInDownlevelAsync.ts (2 errors) ====
==== tests/cases/compiler/invalidContinueInDownlevelAsync.ts (1 errors) ====
async function func() {
if (true) {
continue;
@@ -11,7 +10,5 @@ tests/cases/compiler/invalidContinueInDownlevelAsync.ts(6,9): error TS7027: Unre
}
else {
await 1;
~~~~~
!!! error TS7027: Unreachable code detected.
}
}
@@ -1,14 +1,12 @@
tests/cases/conformance/statements/breakStatements/invalidWhileBreakStatements.ts(4,1): error TS1105: A 'break' statement can only be used within an enclosing iteration or switch statement.
tests/cases/conformance/statements/breakStatements/invalidWhileBreakStatements.ts(7,1): error TS7028: Unused label.
tests/cases/conformance/statements/breakStatements/invalidWhileBreakStatements.ts(8,14): error TS1116: A 'break' statement can only jump to a label of an enclosing statement.
tests/cases/conformance/statements/breakStatements/invalidWhileBreakStatements.ts(11,1): error TS7027: Unreachable code detected.
tests/cases/conformance/statements/breakStatements/invalidWhileBreakStatements.ts(14,9): error TS1107: Jump target cannot cross function boundary.
tests/cases/conformance/statements/breakStatements/invalidWhileBreakStatements.ts(21,9): error TS1107: Jump target cannot cross function boundary.
tests/cases/conformance/statements/breakStatements/invalidWhileBreakStatements.ts(27,5): error TS1116: A 'break' statement can only jump to a label of an enclosing statement.
tests/cases/conformance/statements/breakStatements/invalidWhileBreakStatements.ts(37,5): error TS1116: A 'break' statement can only jump to a label of an enclosing statement.
==== tests/cases/conformance/statements/breakStatements/invalidWhileBreakStatements.ts (8 errors) ====
==== tests/cases/conformance/statements/breakStatements/invalidWhileBreakStatements.ts (6 errors) ====
// All errors
// naked break not allowed
@@ -18,16 +16,12 @@ tests/cases/conformance/statements/breakStatements/invalidWhileBreakStatements.t
// non-existent label
ONE:
~~~
!!! error TS7028: Unused label.
while (true) break TWO;
~~~~~~~~~~
!!! error TS1116: A 'break' statement can only jump to a label of an enclosing statement.
// break from inside function
TWO:
~~~
!!! error TS7027: Unreachable code detected.
while (true){
var x = () => {
break TWO;
@@ -60,6 +60,18 @@ function f5() {
let v4 = c4;
}
declare function widening<T>(x: T): T;
declare function nonWidening<T extends string | number | symbol>(x: T): T;
function f6(cond: boolean) {
let x1 = widening('a');
let x2 = widening(10);
let x3 = widening(cond ? 'a' : 10);
let y1 = nonWidening('a');
let y2 = nonWidening(10);
let y3 = nonWidening(cond ? 'a' : 10);
}
// Repro from #10898
type FAILURE = "FAILURE";
@@ -95,10 +107,33 @@ type TestEvent = "onmouseover" | "onmouseout";
function onMouseOver(): TestEvent { return "onmouseover"; }
let x = onMouseOver();
let x = onMouseOver();
// Repro from #23649
export function Set<K extends string>(...keys: K[]): Record<K, true | undefined> {
const result = {} as Record<K, true | undefined>
keys.forEach(key => result[key] = true)
return result
}
export function keys<K extends string, V>(obj: Record<K, V>): K[] {
return Object.keys(obj) as K[]
}
type Obj = { code: LangCode }
const langCodeSet = Set('fr', 'en', 'es', 'it', 'nl')
export type LangCode = keyof typeof langCodeSet
export const langCodes = keys(langCodeSet)
const arr: Obj[] = langCodes.map(code => ({ code }))
//// [literalTypeWidening.js]
"use strict";
// Widening vs. non-widening literal types
exports.__esModule = true;
function f1() {
var c1 = "hello"; // Widening type "hello"
var v1 = c1; // Type string
@@ -153,6 +188,14 @@ function f5() {
var c4 = "foo";
var v4 = c4;
}
function f6(cond) {
var x1 = widening('a');
var x2 = widening(10);
var x3 = widening(cond ? 'a' : 10);
var y1 = nonWidening('a');
var y2 = nonWidening(10);
var y3 = nonWidening(cond ? 'a' : 10);
}
var FAILURE = "FAILURE";
function doWork() {
return FAILURE;
@@ -172,3 +215,21 @@ if (isSuccess(result)) {
}
function onMouseOver() { return "onmouseover"; }
var x = onMouseOver();
// Repro from #23649
function Set() {
var keys = [];
for (var _i = 0; _i < arguments.length; _i++) {
keys[_i] = arguments[_i];
}
var result = {};
keys.forEach(function (key) { return result[key] = true; });
return result;
}
exports.Set = Set;
function keys(obj) {
return Object.keys(obj);
}
exports.keys = keys;
var langCodeSet = Set('fr', 'en', 'es', 'it', 'nl');
exports.langCodes = keys(langCodeSet);
var arr = exports.langCodes.map(function (code) { return ({ code: code }); });
@@ -197,89 +197,206 @@ function f5() {
>c4 : Symbol(c4, Decl(literalTypeWidening.ts, 57, 9))
}
declare function widening<T>(x: T): T;
>widening : Symbol(widening, Decl(literalTypeWidening.ts, 59, 1))
>T : Symbol(T, Decl(literalTypeWidening.ts, 61, 26))
>x : Symbol(x, Decl(literalTypeWidening.ts, 61, 29))
>T : Symbol(T, Decl(literalTypeWidening.ts, 61, 26))
>T : Symbol(T, Decl(literalTypeWidening.ts, 61, 26))
declare function nonWidening<T extends string | number | symbol>(x: T): T;
>nonWidening : Symbol(nonWidening, Decl(literalTypeWidening.ts, 61, 38))
>T : Symbol(T, Decl(literalTypeWidening.ts, 62, 29))
>x : Symbol(x, Decl(literalTypeWidening.ts, 62, 65))
>T : Symbol(T, Decl(literalTypeWidening.ts, 62, 29))
>T : Symbol(T, Decl(literalTypeWidening.ts, 62, 29))
function f6(cond: boolean) {
>f6 : Symbol(f6, Decl(literalTypeWidening.ts, 62, 74))
>cond : Symbol(cond, Decl(literalTypeWidening.ts, 64, 12))
let x1 = widening('a');
>x1 : Symbol(x1, Decl(literalTypeWidening.ts, 65, 7))
>widening : Symbol(widening, Decl(literalTypeWidening.ts, 59, 1))
let x2 = widening(10);
>x2 : Symbol(x2, Decl(literalTypeWidening.ts, 66, 7))
>widening : Symbol(widening, Decl(literalTypeWidening.ts, 59, 1))
let x3 = widening(cond ? 'a' : 10);
>x3 : Symbol(x3, Decl(literalTypeWidening.ts, 67, 7))
>widening : Symbol(widening, Decl(literalTypeWidening.ts, 59, 1))
>cond : Symbol(cond, Decl(literalTypeWidening.ts, 64, 12))
let y1 = nonWidening('a');
>y1 : Symbol(y1, Decl(literalTypeWidening.ts, 68, 7))
>nonWidening : Symbol(nonWidening, Decl(literalTypeWidening.ts, 61, 38))
let y2 = nonWidening(10);
>y2 : Symbol(y2, Decl(literalTypeWidening.ts, 69, 7))
>nonWidening : Symbol(nonWidening, Decl(literalTypeWidening.ts, 61, 38))
let y3 = nonWidening(cond ? 'a' : 10);
>y3 : Symbol(y3, Decl(literalTypeWidening.ts, 70, 7))
>nonWidening : Symbol(nonWidening, Decl(literalTypeWidening.ts, 61, 38))
>cond : Symbol(cond, Decl(literalTypeWidening.ts, 64, 12))
}
// Repro from #10898
type FAILURE = "FAILURE";
>FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 59, 1), Decl(literalTypeWidening.ts, 64, 5))
>FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 71, 1), Decl(literalTypeWidening.ts, 76, 5))
const FAILURE = "FAILURE";
>FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 59, 1), Decl(literalTypeWidening.ts, 64, 5))
>FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 71, 1), Decl(literalTypeWidening.ts, 76, 5))
type Result<T> = T | FAILURE;
>Result : Symbol(Result, Decl(literalTypeWidening.ts, 64, 26))
>T : Symbol(T, Decl(literalTypeWidening.ts, 66, 12))
>T : Symbol(T, Decl(literalTypeWidening.ts, 66, 12))
>FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 59, 1), Decl(literalTypeWidening.ts, 64, 5))
>Result : Symbol(Result, Decl(literalTypeWidening.ts, 76, 26))
>T : Symbol(T, Decl(literalTypeWidening.ts, 78, 12))
>T : Symbol(T, Decl(literalTypeWidening.ts, 78, 12))
>FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 71, 1), Decl(literalTypeWidening.ts, 76, 5))
function doWork<T>(): Result<T> {
>doWork : Symbol(doWork, Decl(literalTypeWidening.ts, 66, 29))
>T : Symbol(T, Decl(literalTypeWidening.ts, 68, 16))
>Result : Symbol(Result, Decl(literalTypeWidening.ts, 64, 26))
>T : Symbol(T, Decl(literalTypeWidening.ts, 68, 16))
>doWork : Symbol(doWork, Decl(literalTypeWidening.ts, 78, 29))
>T : Symbol(T, Decl(literalTypeWidening.ts, 80, 16))
>Result : Symbol(Result, Decl(literalTypeWidening.ts, 76, 26))
>T : Symbol(T, Decl(literalTypeWidening.ts, 80, 16))
return FAILURE;
>FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 59, 1), Decl(literalTypeWidening.ts, 64, 5))
>FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 71, 1), Decl(literalTypeWidening.ts, 76, 5))
}
function isSuccess<T>(result: Result<T>): result is T {
>isSuccess : Symbol(isSuccess, Decl(literalTypeWidening.ts, 70, 1))
>T : Symbol(T, Decl(literalTypeWidening.ts, 72, 19))
>result : Symbol(result, Decl(literalTypeWidening.ts, 72, 22))
>Result : Symbol(Result, Decl(literalTypeWidening.ts, 64, 26))
>T : Symbol(T, Decl(literalTypeWidening.ts, 72, 19))
>result : Symbol(result, Decl(literalTypeWidening.ts, 72, 22))
>T : Symbol(T, Decl(literalTypeWidening.ts, 72, 19))
>isSuccess : Symbol(isSuccess, Decl(literalTypeWidening.ts, 82, 1))
>T : Symbol(T, Decl(literalTypeWidening.ts, 84, 19))
>result : Symbol(result, Decl(literalTypeWidening.ts, 84, 22))
>Result : Symbol(Result, Decl(literalTypeWidening.ts, 76, 26))
>T : Symbol(T, Decl(literalTypeWidening.ts, 84, 19))
>result : Symbol(result, Decl(literalTypeWidening.ts, 84, 22))
>T : Symbol(T, Decl(literalTypeWidening.ts, 84, 19))
return !isFailure(result);
>isFailure : Symbol(isFailure, Decl(literalTypeWidening.ts, 74, 1))
>result : Symbol(result, Decl(literalTypeWidening.ts, 72, 22))
>isFailure : Symbol(isFailure, Decl(literalTypeWidening.ts, 86, 1))
>result : Symbol(result, Decl(literalTypeWidening.ts, 84, 22))
}
function isFailure<T>(result: Result<T>): result is FAILURE {
>isFailure : Symbol(isFailure, Decl(literalTypeWidening.ts, 74, 1))
>T : Symbol(T, Decl(literalTypeWidening.ts, 76, 19))
>result : Symbol(result, Decl(literalTypeWidening.ts, 76, 22))
>Result : Symbol(Result, Decl(literalTypeWidening.ts, 64, 26))
>T : Symbol(T, Decl(literalTypeWidening.ts, 76, 19))
>result : Symbol(result, Decl(literalTypeWidening.ts, 76, 22))
>FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 59, 1), Decl(literalTypeWidening.ts, 64, 5))
>isFailure : Symbol(isFailure, Decl(literalTypeWidening.ts, 86, 1))
>T : Symbol(T, Decl(literalTypeWidening.ts, 88, 19))
>result : Symbol(result, Decl(literalTypeWidening.ts, 88, 22))
>Result : Symbol(Result, Decl(literalTypeWidening.ts, 76, 26))
>T : Symbol(T, Decl(literalTypeWidening.ts, 88, 19))
>result : Symbol(result, Decl(literalTypeWidening.ts, 88, 22))
>FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 71, 1), Decl(literalTypeWidening.ts, 76, 5))
return result === FAILURE;
>result : Symbol(result, Decl(literalTypeWidening.ts, 76, 22))
>FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 59, 1), Decl(literalTypeWidening.ts, 64, 5))
>result : Symbol(result, Decl(literalTypeWidening.ts, 88, 22))
>FAILURE : Symbol(FAILURE, Decl(literalTypeWidening.ts, 71, 1), Decl(literalTypeWidening.ts, 76, 5))
}
function increment(x: number): number {
>increment : Symbol(increment, Decl(literalTypeWidening.ts, 78, 1))
>x : Symbol(x, Decl(literalTypeWidening.ts, 80, 19))
>increment : Symbol(increment, Decl(literalTypeWidening.ts, 90, 1))
>x : Symbol(x, Decl(literalTypeWidening.ts, 92, 19))
return x + 1;
>x : Symbol(x, Decl(literalTypeWidening.ts, 80, 19))
>x : Symbol(x, Decl(literalTypeWidening.ts, 92, 19))
}
let result = doWork<number>();
>result : Symbol(result, Decl(literalTypeWidening.ts, 84, 3))
>doWork : Symbol(doWork, Decl(literalTypeWidening.ts, 66, 29))
>result : Symbol(result, Decl(literalTypeWidening.ts, 96, 3))
>doWork : Symbol(doWork, Decl(literalTypeWidening.ts, 78, 29))
if (isSuccess(result)) {
>isSuccess : Symbol(isSuccess, Decl(literalTypeWidening.ts, 70, 1))
>result : Symbol(result, Decl(literalTypeWidening.ts, 84, 3))
>isSuccess : Symbol(isSuccess, Decl(literalTypeWidening.ts, 82, 1))
>result : Symbol(result, Decl(literalTypeWidening.ts, 96, 3))
increment(result);
>increment : Symbol(increment, Decl(literalTypeWidening.ts, 78, 1))
>result : Symbol(result, Decl(literalTypeWidening.ts, 84, 3))
>increment : Symbol(increment, Decl(literalTypeWidening.ts, 90, 1))
>result : Symbol(result, Decl(literalTypeWidening.ts, 96, 3))
}
// Repro from #10898
type TestEvent = "onmouseover" | "onmouseout";
>TestEvent : Symbol(TestEvent, Decl(literalTypeWidening.ts, 88, 1))
>TestEvent : Symbol(TestEvent, Decl(literalTypeWidening.ts, 100, 1))
function onMouseOver(): TestEvent { return "onmouseover"; }
>onMouseOver : Symbol(onMouseOver, Decl(literalTypeWidening.ts, 92, 46))
>TestEvent : Symbol(TestEvent, Decl(literalTypeWidening.ts, 88, 1))
>onMouseOver : Symbol(onMouseOver, Decl(literalTypeWidening.ts, 104, 46))
>TestEvent : Symbol(TestEvent, Decl(literalTypeWidening.ts, 100, 1))
let x = onMouseOver();
>x : Symbol(x, Decl(literalTypeWidening.ts, 96, 3))
>onMouseOver : Symbol(onMouseOver, Decl(literalTypeWidening.ts, 92, 46))
>x : Symbol(x, Decl(literalTypeWidening.ts, 108, 3))
>onMouseOver : Symbol(onMouseOver, Decl(literalTypeWidening.ts, 104, 46))
// Repro from #23649
export function Set<K extends string>(...keys: K[]): Record<K, true | undefined> {
>Set : Symbol(Set, Decl(literalTypeWidening.ts, 108, 22))
>K : Symbol(K, Decl(literalTypeWidening.ts, 112, 20))
>keys : Symbol(keys, Decl(literalTypeWidening.ts, 112, 38))
>K : Symbol(K, Decl(literalTypeWidening.ts, 112, 20))
>Record : Symbol(Record, Decl(lib.d.ts, --, --))
>K : Symbol(K, Decl(literalTypeWidening.ts, 112, 20))
const result = {} as Record<K, true | undefined>
>result : Symbol(result, Decl(literalTypeWidening.ts, 113, 7))
>Record : Symbol(Record, Decl(lib.d.ts, --, --))
>K : Symbol(K, Decl(literalTypeWidening.ts, 112, 20))
keys.forEach(key => result[key] = true)
>keys.forEach : Symbol(Array.forEach, Decl(lib.d.ts, --, --))
>keys : Symbol(keys, Decl(literalTypeWidening.ts, 112, 38))
>forEach : Symbol(Array.forEach, Decl(lib.d.ts, --, --))
>key : Symbol(key, Decl(literalTypeWidening.ts, 114, 15))
>result : Symbol(result, Decl(literalTypeWidening.ts, 113, 7))
>key : Symbol(key, Decl(literalTypeWidening.ts, 114, 15))
return result
>result : Symbol(result, Decl(literalTypeWidening.ts, 113, 7))
}
export function keys<K extends string, V>(obj: Record<K, V>): K[] {
>keys : Symbol(keys, Decl(literalTypeWidening.ts, 116, 1))
>K : Symbol(K, Decl(literalTypeWidening.ts, 118, 21))
>V : Symbol(V, Decl(literalTypeWidening.ts, 118, 38))
>obj : Symbol(obj, Decl(literalTypeWidening.ts, 118, 42))
>Record : Symbol(Record, Decl(lib.d.ts, --, --))
>K : Symbol(K, Decl(literalTypeWidening.ts, 118, 21))
>V : Symbol(V, Decl(literalTypeWidening.ts, 118, 38))
>K : Symbol(K, Decl(literalTypeWidening.ts, 118, 21))
return Object.keys(obj) as K[]
>Object.keys : Symbol(ObjectConstructor.keys, Decl(lib.d.ts, --, --))
>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>keys : Symbol(ObjectConstructor.keys, Decl(lib.d.ts, --, --))
>obj : Symbol(obj, Decl(literalTypeWidening.ts, 118, 42))
>K : Symbol(K, Decl(literalTypeWidening.ts, 118, 21))
}
type Obj = { code: LangCode }
>Obj : Symbol(Obj, Decl(literalTypeWidening.ts, 120, 1))
>code : Symbol(code, Decl(literalTypeWidening.ts, 122, 12))
>LangCode : Symbol(LangCode, Decl(literalTypeWidening.ts, 124, 53))
const langCodeSet = Set('fr', 'en', 'es', 'it', 'nl')
>langCodeSet : Symbol(langCodeSet, Decl(literalTypeWidening.ts, 124, 5))
>Set : Symbol(Set, Decl(literalTypeWidening.ts, 108, 22))
export type LangCode = keyof typeof langCodeSet
>LangCode : Symbol(LangCode, Decl(literalTypeWidening.ts, 124, 53))
>langCodeSet : Symbol(langCodeSet, Decl(literalTypeWidening.ts, 124, 5))
export const langCodes = keys(langCodeSet)
>langCodes : Symbol(langCodes, Decl(literalTypeWidening.ts, 126, 12))
>keys : Symbol(keys, Decl(literalTypeWidening.ts, 116, 1))
>langCodeSet : Symbol(langCodeSet, Decl(literalTypeWidening.ts, 124, 5))
const arr: Obj[] = langCodes.map(code => ({ code }))
>arr : Symbol(arr, Decl(literalTypeWidening.ts, 128, 5))
>Obj : Symbol(Obj, Decl(literalTypeWidening.ts, 120, 1))
>langCodes.map : Symbol(Array.map, Decl(lib.d.ts, --, --))
>langCodes : Symbol(langCodes, Decl(literalTypeWidening.ts, 126, 12))
>map : Symbol(Array.map, Decl(lib.d.ts, --, --))
>code : Symbol(code, Decl(literalTypeWidening.ts, 128, 33))
>code : Symbol(code, Decl(literalTypeWidening.ts, 128, 43))
@@ -219,6 +219,67 @@ function f5() {
>c4 : "foo"
}
declare function widening<T>(x: T): T;
>widening : <T>(x: T) => T
>T : T
>x : T
>T : T
>T : T
declare function nonWidening<T extends string | number | symbol>(x: T): T;
>nonWidening : <T extends string | number | symbol>(x: T) => T
>T : T
>x : T
>T : T
>T : T
function f6(cond: boolean) {
>f6 : (cond: boolean) => void
>cond : boolean
let x1 = widening('a');
>x1 : string
>widening('a') : "a"
>widening : <T>(x: T) => T
>'a' : "a"
let x2 = widening(10);
>x2 : number
>widening(10) : 10
>widening : <T>(x: T) => T
>10 : 10
let x3 = widening(cond ? 'a' : 10);
>x3 : string | number
>widening(cond ? 'a' : 10) : "a" | 10
>widening : <T>(x: T) => T
>cond ? 'a' : 10 : "a" | 10
>cond : boolean
>'a' : "a"
>10 : 10
let y1 = nonWidening('a');
>y1 : "a"
>nonWidening('a') : "a"
>nonWidening : <T extends string | number | symbol>(x: T) => T
>'a' : "a"
let y2 = nonWidening(10);
>y2 : 10
>nonWidening(10) : 10
>nonWidening : <T extends string | number | symbol>(x: T) => T
>10 : 10
let y3 = nonWidening(cond ? 'a' : 10);
>y3 : "a" | 10
>nonWidening(cond ? 'a' : 10) : "a" | 10
>nonWidening : <T extends string | number | symbol>(x: T) => T
>cond ? 'a' : 10 : "a" | 10
>cond : boolean
>'a' : "a"
>10 : 10
}
// Repro from #10898
type FAILURE = "FAILURE";
@@ -316,3 +377,97 @@ let x = onMouseOver();
>onMouseOver() : TestEvent
>onMouseOver : () => TestEvent
// Repro from #23649
export function Set<K extends string>(...keys: K[]): Record<K, true | undefined> {
>Set : <K extends string>(...keys: K[]) => Record<K, true>
>K : K
>keys : K[]
>K : K
>Record : Record<K, T>
>K : K
>true : true
const result = {} as Record<K, true | undefined>
>result : Record<K, true>
>{} as Record<K, true | undefined> : Record<K, true>
>{} : {}
>Record : Record<K, T>
>K : K
>true : true
keys.forEach(key => result[key] = true)
>keys.forEach(key => result[key] = true) : void
>keys.forEach : (callbackfn: (value: K, index: number, array: K[]) => void, thisArg?: any) => void
>keys : K[]
>forEach : (callbackfn: (value: K, index: number, array: K[]) => void, thisArg?: any) => void
>key => result[key] = true : (key: K) => boolean
>key : K
>result[key] = true : true
>result[key] : Record<K, true>[K]
>result : Record<K, true>
>key : K
>true : true
return result
>result : Record<K, true>
}
export function keys<K extends string, V>(obj: Record<K, V>): K[] {
>keys : <K extends string, V>(obj: Record<K, V>) => K[]
>K : K
>V : V
>obj : Record<K, V>
>Record : Record<K, T>
>K : K
>V : V
>K : K
return Object.keys(obj) as K[]
>Object.keys(obj) as K[] : K[]
>Object.keys(obj) : string[]
>Object.keys : (o: {}) => string[]
>Object : ObjectConstructor
>keys : (o: {}) => string[]
>obj : Record<K, V>
>K : K
}
type Obj = { code: LangCode }
>Obj : Obj
>code : "fr" | "en" | "es" | "it" | "nl"
>LangCode : "fr" | "en" | "es" | "it" | "nl"
const langCodeSet = Set('fr', 'en', 'es', 'it', 'nl')
>langCodeSet : Record<"fr" | "en" | "es" | "it" | "nl", true>
>Set('fr', 'en', 'es', 'it', 'nl') : Record<"fr" | "en" | "es" | "it" | "nl", true>
>Set : <K extends string>(...keys: K[]) => Record<K, true>
>'fr' : "fr"
>'en' : "en"
>'es' : "es"
>'it' : "it"
>'nl' : "nl"
export type LangCode = keyof typeof langCodeSet
>LangCode : "fr" | "en" | "es" | "it" | "nl"
>langCodeSet : Record<"fr" | "en" | "es" | "it" | "nl", true>
export const langCodes = keys(langCodeSet)
>langCodes : ("fr" | "en" | "es" | "it" | "nl")[]
>keys(langCodeSet) : ("fr" | "en" | "es" | "it" | "nl")[]
>keys : <K extends string, V>(obj: Record<K, V>) => K[]
>langCodeSet : Record<"fr" | "en" | "es" | "it" | "nl", true>
const arr: Obj[] = langCodes.map(code => ({ code }))
>arr : Obj[]
>Obj : Obj
>langCodes.map(code => ({ code })) : { code: "fr" | "en" | "es" | "it" | "nl"; }[]
>langCodes.map : <U>(callbackfn: (value: "fr" | "en" | "es" | "it" | "nl", index: number, array: ("fr" | "en" | "es" | "it" | "nl")[]) => U, thisArg?: any) => U[]
>langCodes : ("fr" | "en" | "es" | "it" | "nl")[]
>map : <U>(callbackfn: (value: "fr" | "en" | "es" | "it" | "nl", index: number, array: ("fr" | "en" | "es" | "it" | "nl")[]) => U, thisArg?: any) => U[]
>code => ({ code }) : (code: "fr" | "en" | "es" | "it" | "nl") => { code: "fr" | "en" | "es" | "it" | "nl"; }
>code : "fr" | "en" | "es" | "it" | "nl"
>({ code }) : { code: "fr" | "en" | "es" | "it" | "nl"; }
>{ code } : { code: "fr" | "en" | "es" | "it" | "nl"; }
>code : "fr" | "en" | "es" | "it" | "nl"
@@ -555,7 +555,7 @@ class C2 {
>bar : () => 1 | 0
return cond ? 0 : 1;
>cond ? 0 : 1 : 1 | 0
>cond ? 0 : 1 : 0 | 1
>cond : boolean
>0 : 0
>1 : 1
@@ -107,7 +107,7 @@ function f5(x: number, y: 1 | 2) {
>y : 1 | 2
x; // 0 | 1 | 2
>x : 1 | 2 | 0
>x : 0 | 1 | 2
}
}
@@ -126,7 +126,7 @@ function f6(x: number, y: 1 | 2) {
>x : number
x; // 0 | 1 | 2
>x : 1 | 2 | 0
>x : 0 | 1 | 2
}
}
@@ -1,18 +0,0 @@
tests/cases/compiler/nestedBlockScopedBindings13.ts(2,5): error TS7027: Unreachable code detected.
tests/cases/compiler/nestedBlockScopedBindings13.ts(7,5): error TS7027: Unreachable code detected.
==== tests/cases/compiler/nestedBlockScopedBindings13.ts (2 errors) ====
for (; false;) {
let x;
~~~
!!! error TS7027: Unreachable code detected.
() => x;
}
for (; false;) {
let y;
~~~
!!! error TS7027: Unreachable code detected.
y = 1;
}
@@ -1,20 +0,0 @@
tests/cases/compiler/nestedBlockScopedBindings14.ts(3,5): error TS7027: Unreachable code detected.
tests/cases/compiler/nestedBlockScopedBindings14.ts(9,5): error TS7027: Unreachable code detected.
==== tests/cases/compiler/nestedBlockScopedBindings14.ts (2 errors) ====
var x;
for (; false;) {
let x;
~~~
!!! error TS7027: Unreachable code detected.
() => x;
}
var y;
for (; false;) {
let y;
~~~
!!! error TS7027: Unreachable code detected.
y = 1;
}
@@ -1,46 +0,0 @@
tests/cases/compiler/nestedBlockScopedBindings15.ts(3,9): error TS7027: Unreachable code detected.
tests/cases/compiler/nestedBlockScopedBindings15.ts(10,9): error TS7027: Unreachable code detected.
tests/cases/compiler/nestedBlockScopedBindings15.ts(16,5): error TS7027: Unreachable code detected.
tests/cases/compiler/nestedBlockScopedBindings15.ts(25,5): error TS7027: Unreachable code detected.
==== tests/cases/compiler/nestedBlockScopedBindings15.ts (4 errors) ====
for (; false;) {
{
let x;
~~~
!!! error TS7027: Unreachable code detected.
() => x;
}
}
for (; false;) {
{
let y;
~~~
!!! error TS7027: Unreachable code detected.
y = 1;
}
}
for (; false;) {
switch (1){
~~~~~~
!!! error TS7027: Unreachable code detected.
case 1:
let z0;
() => z0;
break;
}
}
for (; false;) {
switch (1){
~~~~~~
!!! error TS7027: Unreachable code detected.
case 1:
let z;
z = 1;
break;
}
}
@@ -1,50 +0,0 @@
tests/cases/compiler/nestedBlockScopedBindings16.ts(4,9): error TS7027: Unreachable code detected.
tests/cases/compiler/nestedBlockScopedBindings16.ts(12,9): error TS7027: Unreachable code detected.
tests/cases/compiler/nestedBlockScopedBindings16.ts(19,5): error TS7027: Unreachable code detected.
tests/cases/compiler/nestedBlockScopedBindings16.ts(29,5): error TS7027: Unreachable code detected.
==== tests/cases/compiler/nestedBlockScopedBindings16.ts (4 errors) ====
var x;
for (; false;) {
{
let x;
~~~
!!! error TS7027: Unreachable code detected.
() => x;
}
}
var y;
for (; false;) {
{
let y;
~~~
!!! error TS7027: Unreachable code detected.
y = 1;
}
}
var z0;
for (; false;) {
switch (1){
~~~~~~
!!! error TS7027: Unreachable code detected.
case 1:
let z0;
() => z0;
break;
}
}
var z;
for (; false;) {
switch (1){
~~~~~~
!!! error TS7027: Unreachable code detected.
case 1:
let z;
z = 1;
break;
}
}
@@ -1,92 +0,0 @@
tests/cases/compiler/nestedBlockScopedBindings5.ts(37,9): error TS7027: Unreachable code detected.
tests/cases/compiler/nestedBlockScopedBindings5.ts(54,9): error TS7027: Unreachable code detected.
tests/cases/compiler/nestedBlockScopedBindings5.ts(71,9): error TS7027: Unreachable code detected.
==== tests/cases/compiler/nestedBlockScopedBindings5.ts (3 errors) ====
function a0() {
for (let x in []) {
x = x + 1;
}
for (let x;;) {
x = x + 2;
}
}
function a1() {
for (let x in []) {
x = x + 1;
() => x;
}
for (let x;;) {
x = x + 2;
}
}
function a2() {
for (let x in []) {
x = x + 1;
}
for (let x;;) {
x = x + 2;
() => x;
}
}
function a3() {
for (let x in []) {
x = x + 1;
() => x;
}
for (let x;false;) {
x = x + 2;
~
!!! error TS7027: Unreachable code detected.
() => x;
}
switch (1) {
case 1:
let x;
() => x;
break;
}
}
function a4() {
for (let x in []) {
x = x + 1;
}
for (let x;false;) {
x = x + 2;
~
!!! error TS7027: Unreachable code detected.
}
switch (1) {
case 1:
let x;
() => x;
break;
}
}
function a5() {
let y;
for (let x in []) {
x = x + 1;
}
for (let x;false;) {
x = x + 2;
~
!!! error TS7027: Unreachable code detected.
() => x;
}
switch (1) {
case 1:
let x;
break;
}
}
@@ -1,16 +0,0 @@
tests/cases/compiler/nestedBlockScopedBindings7.ts(2,5): error TS7027: Unreachable code detected.
tests/cases/compiler/nestedBlockScopedBindings7.ts(6,5): error TS7027: Unreachable code detected.
==== tests/cases/compiler/nestedBlockScopedBindings7.ts (2 errors) ====
for (let x; false;) {
() => x;
~
!!! error TS7027: Unreachable code detected.
}
for (let y; false;) {
y = 1;
~
!!! error TS7027: Unreachable code detected.
}
@@ -1,18 +0,0 @@
tests/cases/compiler/nestedBlockScopedBindings8.ts(3,5): error TS7027: Unreachable code detected.
tests/cases/compiler/nestedBlockScopedBindings8.ts(8,5): error TS7027: Unreachable code detected.
==== tests/cases/compiler/nestedBlockScopedBindings8.ts (2 errors) ====
var x;
for (let x; false; ) {
() => x;
~
!!! error TS7027: Unreachable code detected.
}
var y;
for (let y; false; ) {
y = 1;
~
!!! error TS7027: Unreachable code detected.
}
@@ -15,7 +15,7 @@ var i: I<string>;
>I : I<T>
var y = new i(""); // y should be string
>y : string
>y : ""
>new i("") : ""
>i : I<string>
>"" : ""
@@ -0,0 +1,6 @@
// ==ORIGINAL==
import { React, Other } from "react";
// ==ORGANIZED==
@@ -0,0 +1,6 @@
// ==ORIGINAL==
import { React, Other } from "react";
// ==ORGANIZED==
@@ -4,4 +4,3 @@ import { React, Other } from "react";
// ==ORGANIZED==
import { React } from "react";
@@ -0,0 +1,11 @@
// ==ORIGINAL==
import { React, Other } from "react";
<div/>;
// ==ORGANIZED==
import { React } from "react";
<div/>;
@@ -0,0 +1,10 @@
// ==ORIGINAL==
import { React, Other } from "react";
<div/>;
// ==ORGANIZED==
<div/>;
@@ -0,0 +1,11 @@
// ==ORIGINAL==
import { React, Other } from "react";
<div/>;
// ==ORGANIZED==
import { React } from "react";
<div/>;
@@ -26,7 +26,7 @@ export function removeClass (node:HTMLElement, className:string) {
>rightDelimiter : any
return leftDelimiter.length + rightDelimiter.length === 2 ? ' ' : '';
>leftDelimiter.length + rightDelimiter.length === 2 ? ' ' : '' : " " | ""
>leftDelimiter.length + rightDelimiter.length === 2 ? ' ' : '' : "" | " "
>leftDelimiter.length + rightDelimiter.length === 2 : boolean
>leftDelimiter.length + rightDelimiter.length : any
>leftDelimiter.length : any
@@ -1,16 +1,13 @@
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ModuleElements/parserErrorRecovery_ModuleElement1.ts(2,1): error TS1128: Declaration or statement expected.
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ModuleElements/parserErrorRecovery_ModuleElement1.ts(3,1): error TS7027: Unreachable code detected.
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ModuleElements/parserErrorRecovery_ModuleElement1.ts(4,1): error TS1128: Declaration or statement expected.
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ModuleElements/parserErrorRecovery_ModuleElement1.ts (3 errors) ====
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ModuleElements/parserErrorRecovery_ModuleElement1.ts (2 errors) ====
return foo;
}
~
!!! error TS1128: Declaration or statement expected.
return bar;
~~~~~~
!!! error TS7027: Unreachable code detected.
}
~
!!! error TS1128: Declaration or statement expected.
@@ -1,14 +1,11 @@
tests/cases/conformance/parser/ecmascript5/Statements/parserLabeledStatement1.d.ts(1,1): error TS1036: Statements are not allowed in ambient contexts.
tests/cases/conformance/parser/ecmascript5/Statements/parserLabeledStatement1.d.ts(1,1): error TS7028: Unused label.
tests/cases/conformance/parser/ecmascript5/Statements/parserLabeledStatement1.d.ts(2,3): error TS2304: Cannot find name 'bar'.
==== tests/cases/conformance/parser/ecmascript5/Statements/parserLabeledStatement1.d.ts (3 errors) ====
==== tests/cases/conformance/parser/ecmascript5/Statements/parserLabeledStatement1.d.ts (2 errors) ====
foo:
~~~
!!! error TS1036: Statements are not allowed in ambient contexts.
~~~
!!! error TS7028: Unused label.
bar();
~~~
!!! error TS2304: Cannot find name 'bar'.
@@ -1,11 +1,8 @@
tests/cases/conformance/parser/ecmascript5/Statements/BreakStatements/parser_breakTarget5.ts(1,1): error TS7028: Unused label.
tests/cases/conformance/parser/ecmascript5/Statements/BreakStatements/parser_breakTarget5.ts(5,7): error TS1107: Jump target cannot cross function boundary.
==== tests/cases/conformance/parser/ecmascript5/Statements/BreakStatements/parser_breakTarget5.ts (2 errors) ====
==== tests/cases/conformance/parser/ecmascript5/Statements/BreakStatements/parser_breakTarget5.ts (1 errors) ====
target:
~~~~~~
!!! error TS7028: Unused label.
while (true) {
function f() {
while (true) {
@@ -1,11 +1,8 @@
tests/cases/conformance/parser/ecmascript5/Statements/ContinueStatements/parser_continueNotInIterationStatement4.ts(1,1): error TS7028: Unused label.
tests/cases/conformance/parser/ecmascript5/Statements/ContinueStatements/parser_continueNotInIterationStatement4.ts(4,5): error TS1107: Jump target cannot cross function boundary.
==== tests/cases/conformance/parser/ecmascript5/Statements/ContinueStatements/parser_continueNotInIterationStatement4.ts (2 errors) ====
==== tests/cases/conformance/parser/ecmascript5/Statements/ContinueStatements/parser_continueNotInIterationStatement4.ts (1 errors) ====
TWO:
~~~
!!! error TS7028: Unused label.
while (true){
var x = () => {
continue TWO;
@@ -1,11 +1,8 @@
tests/cases/conformance/parser/ecmascript5/Statements/ContinueStatements/parser_continueTarget5.ts(1,1): error TS7028: Unused label.
tests/cases/conformance/parser/ecmascript5/Statements/ContinueStatements/parser_continueTarget5.ts(5,7): error TS1107: Jump target cannot cross function boundary.
==== tests/cases/conformance/parser/ecmascript5/Statements/ContinueStatements/parser_continueTarget5.ts (2 errors) ====
==== tests/cases/conformance/parser/ecmascript5/Statements/ContinueStatements/parser_continueTarget5.ts (1 errors) ====
target:
~~~~~~
!!! error TS7028: Unused label.
while (true) {
function f() {
while (true) {
@@ -1,16 +1,10 @@
tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel1.ts(1,1): error TS7028: Unused label.
tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel1.ts(2,1): error TS1114: Duplicate label 'target'.
tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel1.ts(2,1): error TS7028: Unused label.
==== tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel1.ts (3 errors) ====
==== tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel1.ts (1 errors) ====
target:
~~~~~~
!!! error TS7028: Unused label.
target:
~~~~~~
!!! error TS1114: Duplicate label 'target'.
~~~~~~
!!! error TS7028: Unused label.
while (true) {
}
@@ -1,18 +1,12 @@
tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel2.ts(1,1): error TS7028: Unused label.
tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel2.ts(3,3): error TS1114: Duplicate label 'target'.
tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel2.ts(3,3): error TS7028: Unused label.
==== tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel2.ts (3 errors) ====
==== tests/cases/conformance/parser/ecmascript5/Statements/LabeledStatements/parser_duplicateLabel2.ts (1 errors) ====
target:
~~~~~~
!!! error TS7028: Unused label.
while (true) {
target:
~~~~~~
!!! error TS1114: Duplicate label 'target'.
~~~~~~
!!! error TS7028: Unused label.
while (true) {
}
}
@@ -3,7 +3,6 @@ tests/cases/compiler/recursiveLetConst.ts(3,12): error TS2448: Block-scoped vari
tests/cases/compiler/recursiveLetConst.ts(4,11): error TS2448: Block-scoped variable 'y' used before its declaration.
tests/cases/compiler/recursiveLetConst.ts(5,14): error TS2448: Block-scoped variable 'y1' used before its declaration.
tests/cases/compiler/recursiveLetConst.ts(6,14): error TS2448: Block-scoped variable 'v' used before its declaration.
tests/cases/compiler/recursiveLetConst.ts(7,1): error TS7027: Unreachable code detected.
tests/cases/compiler/recursiveLetConst.ts(7,16): error TS2448: Block-scoped variable 'v' used before its declaration.
tests/cases/compiler/recursiveLetConst.ts(8,15): error TS2448: Block-scoped variable 'v' used before its declaration.
tests/cases/compiler/recursiveLetConst.ts(9,15): error TS2448: Block-scoped variable 'v' used before its declaration.
@@ -11,7 +10,7 @@ tests/cases/compiler/recursiveLetConst.ts(10,17): error TS2448: Block-scoped var
tests/cases/compiler/recursiveLetConst.ts(11,11): error TS2448: Block-scoped variable 'x2' used before its declaration.
==== tests/cases/compiler/recursiveLetConst.ts (11 errors) ====
==== tests/cases/compiler/recursiveLetConst.ts (10 errors) ====
'use strict'
let x = x + 1;
~
@@ -29,8 +28,6 @@ tests/cases/compiler/recursiveLetConst.ts(11,11): error TS2448: Block-scoped var
~
!!! error TS2448: Block-scoped variable 'v' used before its declaration.
for (let [v] = v; ;) { }
~~~
!!! error TS7027: Unreachable code detected.
~
!!! error TS2448: Block-scoped variable 'v' used before its declaration.
for (let v in v) { }
@@ -1,12 +1,11 @@
tests/cases/compiler/recursiveNamedLambdaCall.ts(3,8): error TS2304: Cannot find name 'top'.
tests/cases/compiler/recursiveNamedLambdaCall.ts(3,15): error TS2304: Cannot find name 'top'.
tests/cases/compiler/recursiveNamedLambdaCall.ts(7,6): error TS7027: Unreachable code detected.
tests/cases/compiler/recursiveNamedLambdaCall.ts(8,7): error TS2304: Cannot find name 'top'.
tests/cases/compiler/recursiveNamedLambdaCall.ts(10,14): error TS2304: Cannot find name 'setTimeout'.
tests/cases/compiler/recursiveNamedLambdaCall.ts(14,6): error TS2304: Cannot find name 'detach'.
==== tests/cases/compiler/recursiveNamedLambdaCall.ts (6 errors) ====
==== tests/cases/compiler/recursiveNamedLambdaCall.ts (5 errors) ====
var promise = function( obj ) {
if ( top && top.doScroll ) {
@@ -18,8 +17,6 @@ tests/cases/compiler/recursiveNamedLambdaCall.ts(14,6): error TS2304: Cannot fin
if ( false ) {
try {
~~~
!!! error TS7027: Unreachable code detected.
top.doScroll("left");
~~~
!!! error TS2304: Cannot find name 'top'.
@@ -15,7 +15,6 @@ tests/cases/compiler/reservedWords2.ts(5,9): error TS2567: Enum declarations can
tests/cases/compiler/reservedWords2.ts(5,10): error TS1003: Identifier expected.
tests/cases/compiler/reservedWords2.ts(5,18): error TS1005: '=>' expected.
tests/cases/compiler/reservedWords2.ts(6,1): error TS2304: Cannot find name 'module'.
tests/cases/compiler/reservedWords2.ts(6,1): error TS7027: Unreachable code detected.
tests/cases/compiler/reservedWords2.ts(6,8): error TS1005: ';' expected.
tests/cases/compiler/reservedWords2.ts(7,11): error TS2300: Duplicate identifier '(Missing)'.
tests/cases/compiler/reservedWords2.ts(7,11): error TS1005: ':' expected.
@@ -33,7 +32,7 @@ tests/cases/compiler/reservedWords2.ts(10,5): error TS2567: Enum declarations ca
tests/cases/compiler/reservedWords2.ts(10,6): error TS1003: Identifier expected.
==== tests/cases/compiler/reservedWords2.ts (33 errors) ====
==== tests/cases/compiler/reservedWords2.ts (32 errors) ====
import while = require("dfdf");
~~~~~
!!! error TS1109: Expression expected.
@@ -74,8 +73,6 @@ tests/cases/compiler/reservedWords2.ts(10,6): error TS1003: Identifier expected.
module void {}
~~~~~~
!!! error TS2304: Cannot find name 'module'.
~~~~~~
!!! error TS7027: Unreachable code detected.
~~~~
!!! error TS1005: ';' expected.
var {while, return} = { while: 1, return: 2 };
@@ -1,9 +1,8 @@
tests/cases/conformance/scanner/ecmascript5/scanner10.1.1-8gs.ts(16,7): error TS2304: Cannot find name 'NotEarlyError'.
tests/cases/conformance/scanner/ecmascript5/scanner10.1.1-8gs.ts(17,1): error TS7027: Unreachable code detected.
tests/cases/conformance/scanner/ecmascript5/scanner10.1.1-8gs.ts(17,5): error TS1212: Identifier expected. 'public' is a reserved word in strict mode.
==== tests/cases/conformance/scanner/ecmascript5/scanner10.1.1-8gs.ts (3 errors) ====
==== tests/cases/conformance/scanner/ecmascript5/scanner10.1.1-8gs.ts (2 errors) ====
/// Copyright (c) 2012 Ecma International. All rights reserved.
/// Ecma International makes this code available under the terms and conditions set
/// forth on http://hg.ecmascript.org/tests/test262/raw-file/tip/LICENSE (the
@@ -23,8 +22,6 @@ tests/cases/conformance/scanner/ecmascript5/scanner10.1.1-8gs.ts(17,5): error TS
~~~~~~~~~~~~~
!!! error TS2304: Cannot find name 'NotEarlyError'.
var public = 1;
~~~
!!! error TS7027: Unreachable code detected.
~~~~~~
!!! error TS1212: Identifier expected. 'public' is a reserved word in strict mode.
@@ -1,10 +1,9 @@
tests/cases/compiler/setterWithReturn.ts(2,16): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
tests/cases/compiler/setterWithReturn.ts(4,13): error TS2408: Setters cannot return a value.
tests/cases/compiler/setterWithReturn.ts(7,13): error TS7027: Unreachable code detected.
tests/cases/compiler/setterWithReturn.ts(7,13): error TS2408: Setters cannot return a value.
==== tests/cases/compiler/setterWithReturn.ts (4 errors) ====
==== tests/cases/compiler/setterWithReturn.ts (3 errors) ====
class C234 {
public set p1(arg1) {
~~
@@ -16,8 +15,6 @@ tests/cases/compiler/setterWithReturn.ts(7,13): error TS2408: Setters cannot ret
}
else {
return 0;
~~~~~~
!!! error TS7027: Unreachable code detected.
~~~~~~~~~
!!! error TS2408: Setters cannot return a value.
}
@@ -1,8 +1,7 @@
tests/cases/compiler/sourceMapValidationFor.ts(20,1): error TS7027: Unreachable code detected.
tests/cases/compiler/sourceMapValidationFor.ts(32,21): error TS2695: Left side of comma operator is unused and has no side effects.
==== tests/cases/compiler/sourceMapValidationFor.ts (2 errors) ====
==== tests/cases/compiler/sourceMapValidationFor.ts (1 errors) ====
for (var i = 0; i < 10; i++) {
WScript.Echo("i: " + i);
}
@@ -23,8 +22,6 @@ tests/cases/compiler/sourceMapValidationFor.ts(32,21): error TS2695: Left side o
for (var k = 0;; k++) {
}
for (k = 0;; k++)
~~~
!!! error TS7027: Unreachable code detected.
{
}
for (; k < 10; k++) {

Some files were not shown because too many files have changed in this diff Show More