Merge branch 'master' into release-3.0

This commit is contained in:
Mohamed Hegazy
2018-07-16 13:18:08 -07:00
52 changed files with 659 additions and 190 deletions
+26 -30
View File
@@ -336,8 +336,8 @@ namespace ts {
}
function addUnusedDiagnostics() {
checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(file), (kind, diag) => {
if (!unusedIsError(kind)) {
checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(file), (containingNode, kind, diag) => {
if (!containsParseError(containingNode) && !unusedIsError(kind)) {
(diagnostics || (diagnostics = [])).push({ ...diag, category: DiagnosticCategory.Suggestion });
}
});
@@ -646,7 +646,8 @@ namespace ts {
Local,
Parameter,
}
type AddUnusedDiagnostic = (type: UnusedKind, diagnostic: DiagnosticWithLocation) => void;
/** @param containingNode Node to check for parse error */
type AddUnusedDiagnostic = (containingNode: Node, type: UnusedKind, diagnostic: DiagnosticWithLocation) => void;
const builtinGlobals = createSymbolTable();
builtinGlobals.set(undefinedSymbol.escapedName, undefinedSymbol);
@@ -4682,13 +4683,7 @@ namespace ts {
}
}
// Use contextual parameter type if one is available
let type: Type | undefined;
if (declaration.symbol.escapedName === "this") {
type = getContextualThisParameterType(func);
}
else {
type = getContextuallyTypedParameterType(declaration);
}
const type = declaration.symbol.escapedName === "this" ? getContextualThisParameterType(func) : getContextuallyTypedParameterType(declaration);
if (type) {
return addOptionality(type, isOptional);
}
@@ -16209,7 +16204,7 @@ namespace ts {
// If the given type is an object or union type with a single signature, and if that signature has at
// least as many parameters as the given function, return the signature. Otherwise return undefined.
function getContextualCallSignature(type: Type, node: FunctionExpression | ArrowFunction | MethodDeclaration): Signature | undefined {
function getContextualCallSignature(type: Type, node: SignatureDeclaration): Signature | undefined {
const signatures = getSignaturesOfType(type, SignatureKind.Call);
if (signatures.length === 1) {
const signature = signatures[0];
@@ -16220,7 +16215,7 @@ namespace ts {
}
/** If the contextual signature has fewer parameters than the function expression, do not use it */
function isAritySmaller(signature: Signature, target: FunctionExpression | ArrowFunction | MethodDeclaration) {
function isAritySmaller(signature: Signature, target: SignatureDeclaration) {
let targetParameterCount = 0;
for (; targetParameterCount < target.parameters.length; targetParameterCount++) {
const param = target.parameters[targetParameterCount];
@@ -23538,12 +23533,13 @@ namespace ts {
// yielded values. The only way to trigger these errors is to try checking its return type.
getReturnTypeOfSignature(getSignatureFromDeclaration(node));
}
// A js function declaration can have a @type tag instead of a return type node, but that type must have a call signature
if (isInJavaScriptFile(node)) {
const typeTag = getJSDocTypeTag(node);
if (typeTag && typeTag.typeExpression && !getSignaturesOfType(getTypeFromTypeNode(typeTag.typeExpression), SignatureKind.Call).length) {
error(typeTag, Diagnostics.The_type_of_a_function_declaration_must_be_callable);
}
}
// A js function declaration can have a @type tag instead of a return type node, but that type must have a call signature
if (isInJavaScriptFile(node)) {
const typeTag = getJSDocTypeTag(node);
if (typeTag && typeTag.typeExpression && !getContextualCallSignature(getTypeFromTypeNode(typeTag.typeExpression), node)) {
error(typeTag, Diagnostics.The_type_of_a_function_declaration_must_match_the_function_s_signature);
}
}
}
@@ -23617,7 +23613,7 @@ namespace ts {
function errorUnusedLocal(declaration: Declaration, name: string, addDiagnostic: AddUnusedDiagnostic) {
const node = getNameOfDeclaration(declaration) || declaration;
const message = isTypeDeclaration(declaration) ? Diagnostics._0_is_declared_but_never_used : Diagnostics._0_is_declared_but_its_value_is_never_read;
addDiagnostic(UnusedKind.Local, createDiagnosticForNode(node, message, name));
addDiagnostic(declaration, UnusedKind.Local, createDiagnosticForNode(node, message, name));
}
function isIdentifierThatStartsWithUnderscore(node: Node) {
@@ -23638,13 +23634,13 @@ namespace ts {
}
const symbol = getSymbolOfNode(member);
if (!symbol.isReferenced && hasModifier(member, ModifierFlags.Private)) {
addDiagnostic(UnusedKind.Local, createDiagnosticForNode(member.name!, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolToString(symbol)));
addDiagnostic(member, UnusedKind.Local, createDiagnosticForNode(member.name!, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolToString(symbol)));
}
break;
case SyntaxKind.Constructor:
for (const parameter of (<ConstructorDeclaration>member).parameters) {
if (!parameter.symbol.isReferenced && hasModifier(parameter, ModifierFlags.Private)) {
addDiagnostic(UnusedKind.Local, createDiagnosticForNode(parameter.name, Diagnostics.Property_0_is_declared_but_its_value_is_never_read, symbolName(parameter.symbol)));
addDiagnostic(parameter, UnusedKind.Local, createDiagnosticForNode(parameter.name, Diagnostics.Property_0_is_declared_but_its_value_is_never_read, symbolName(parameter.symbol)));
}
}
break;
@@ -23669,7 +23665,7 @@ namespace ts {
if (!(node.flags & NodeFlags.Ambient) && last(getSymbolOfNode(node).declarations) === node) {
for (const typeParameter of typeParameters) {
if (!(getMergedSymbol(typeParameter.symbol).isReferenced! & SymbolFlags.TypeParameter) && !isIdentifierThatStartsWithUnderscore(typeParameter.name)) {
addDiagnostic(UnusedKind.Parameter, createDiagnosticForNode(typeParameter.name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(typeParameter.symbol)));
addDiagnostic(typeParameter, UnusedKind.Parameter, createDiagnosticForNode(typeParameter.name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(typeParameter.symbol)));
}
}
}
@@ -23728,7 +23724,7 @@ namespace ts {
const name = local.valueDeclaration && getNameOfDeclaration(local.valueDeclaration);
if (parameter && name) {
if (!isParameterPropertyDeclaration(parameter) && !parameterIsThisKeyword(parameter) && !isIdentifierThatStartsWithUnderscore(name)) {
addDiagnostic(UnusedKind.Parameter, createDiagnosticForNode(name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(local)));
addDiagnostic(parameter, UnusedKind.Parameter, createDiagnosticForNode(name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(local)));
}
}
else {
@@ -23744,7 +23740,7 @@ namespace ts {
(importClause.namedBindings.kind === SyntaxKind.NamespaceImport ? 1 : importClause.namedBindings.elements.length)
: 0);
if (nDeclarations === unuseds.length) {
addDiagnostic(UnusedKind.Local, unuseds.length === 1
addDiagnostic(importDecl, UnusedKind.Local, unuseds.length === 1
? createDiagnosticForNode(importDecl, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(first(unuseds).name!))
: createDiagnosticForNode(importDecl, Diagnostics.All_imports_in_import_declaration_are_unused));
}
@@ -23759,26 +23755,26 @@ namespace ts {
addToGroup(unusedVariables, bindingPattern.parent.parent, bindingPattern.parent, getNodeId);
}
else {
addDiagnostic(kind, bindingElements.length === 1
addDiagnostic(bindingPattern, kind, bindingElements.length === 1
? createDiagnosticForNode(bindingPattern, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(cast(first(bindingElements).name, isIdentifier)))
: createDiagnosticForNode(bindingPattern, Diagnostics.All_destructured_elements_are_unused));
}
}
else {
for (const e of bindingElements) {
addDiagnostic(kind, createDiagnosticForNode(e, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(cast(e.name, isIdentifier))));
addDiagnostic(e, kind, createDiagnosticForNode(e, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(cast(e.name, isIdentifier))));
}
}
});
unusedVariables.forEach(([declarationList, declarations]) => {
if (declarationList.declarations.length === declarations.length) {
addDiagnostic(UnusedKind.Local, declarations.length === 1
addDiagnostic(declarationList, UnusedKind.Local, declarations.length === 1
? createDiagnosticForNode(first(declarations).name, Diagnostics._0_is_declared_but_its_value_is_never_read, bindingNameText(first(declarations).name))
: createDiagnosticForNode(declarationList.parent.kind === SyntaxKind.VariableStatement ? declarationList.parent : declarationList, Diagnostics.All_variables_are_unused));
}
else {
for (const decl of declarations) {
addDiagnostic(UnusedKind.Local, createDiagnosticForNode(decl, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(cast(decl.name, isIdentifier))));
addDiagnostic(decl, UnusedKind.Local, createDiagnosticForNode(decl, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(cast(decl.name, isIdentifier))));
}
}
});
@@ -26631,8 +26627,8 @@ namespace ts {
}
if (!node.isDeclarationFile && (compilerOptions.noUnusedLocals || compilerOptions.noUnusedParameters)) {
checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(node), (kind, diag) => {
if (unusedIsError(kind)) {
checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(node), (containingNode, kind, diag) => {
if (!containsParseError(containingNode) && unusedIsError(kind)) {
diagnostics.add(diag);
}
});
+1 -1
View File
@@ -4021,7 +4021,7 @@
"category": "Error",
"code": 8029
},
"The type of a function declaration must be callable.": {
"The type of a function declaration must match the function's signature.": {
"category": "Error",
"code": 8030
},
+5
View File
@@ -4355,6 +4355,11 @@ namespace ts {
case SyntaxKind.ConditionalExpression:
node = (<ConditionalExpression>node).condition;
continue;
case SyntaxKind.TaggedTemplateExpression:
node = (<TaggedTemplateExpression>node).tag;
continue;
case SyntaxKind.CallExpression:
if (stopAtCallExpressions) {
return node;
+2 -1
View File
@@ -592,6 +592,7 @@ namespace ts {
const programDiagnostics = createDiagnosticCollection();
const currentDirectory = host.getCurrentDirectory();
const supportedExtensions = getSupportedExtensions(options);
const supportedExtensionsWithJsonIfResolveJsonModule = options.resolveJsonModule ? [...supportedExtensions, Extension.Json] : undefined;
// Map storing if there is emit blocking diagnostics for given input
const hasEmitBlockingDiagnostics = createMap<boolean>();
@@ -1925,7 +1926,7 @@ namespace ts {
refFile?: SourceFile): SourceFile | undefined {
if (hasExtension(fileName)) {
if (!options.allowNonTsExtensions && !forEach(supportedExtensions, extension => fileExtensionIs(host.getCanonicalFileName(fileName), extension))) {
if (!options.allowNonTsExtensions && !forEach(supportedExtensionsWithJsonIfResolveJsonModule || supportedExtensions, extension => fileExtensionIs(host.getCanonicalFileName(fileName), extension))) {
if (fail) fail(Diagnostics.File_0_has_unsupported_extension_The_only_supported_extensions_are_1, fileName, "'" + supportedExtensions.join("', '") + "'");
return undefined;
}
+12 -11
View File
@@ -503,6 +503,7 @@ namespace ts {
/*@internal*/ setBlocking?(): void;
base64decode?(input: string): string;
base64encode?(input: string): string;
/*@internal*/ bufferFrom?(input: string, encoding?: string): Buffer;
}
export interface FileWatcher {
@@ -558,7 +559,7 @@ namespace ts {
getEnvironmentVariable?(name: string): string;
};
// TODO: this is used as if it's certainly defined in many places.
// TODO: GH#18217 this is used as if it's certainly defined in many places.
export let sys: System = (() => {
// NodeJS detects "\uFEFF" at the start of the string and *replaces* it with the actual
// byte order mark from the specified encoding. Using any other byte order mark does
@@ -675,19 +676,19 @@ namespace ts {
process.stdout._handle.setBlocking(true);
}
},
base64decode: Buffer.from ? input => {
return Buffer.from!(input, "base64").toString("utf8");
} : input => {
return new Buffer(input, "base64").toString("utf8");
},
base64encode: Buffer.from ? input => {
return Buffer.from!(input).toString("base64");
} : input => {
return new Buffer(input).toString("base64");
}
bufferFrom,
base64decode: input => bufferFrom(input, "base64").toString("utf8"),
base64encode: input => bufferFrom(input).toString("base64"),
};
return nodeSystem;
function bufferFrom(input: string, encoding?: string): Buffer {
// See https://github.com/Microsoft/TypeScript/issues/25652
return Buffer.from && (Buffer.from as Function) !== Int8Array.from
? Buffer.from(input, encoding)
: new Buffer(input, encoding);
}
function isFileSystemCaseSensitive(): boolean {
// win32\win64 are case insensitive platforms
if (platform === "win32" || platform === "win64") {
+1
View File
@@ -488,6 +488,7 @@ namespace ts {
}
if (watch) {
builder.buildAllProjects();
builder.startWatching();
return undefined;
}
+7 -8
View File
@@ -475,16 +475,15 @@ namespace ts {
// From tsc we want to get already parsed result and hence check for rootFileNames
let newLine = updateNewLine();
if (configFileName && host.configFileParsingResult) {
setConfigFileParsingResult(host.configFileParsingResult);
newLine = updateNewLine();
}
reportWatchDiagnostic(Diagnostics.Starting_compilation_in_watch_mode);
if (configFileName) {
if (configFileName && !host.configFileParsingResult) {
newLine = getNewLineCharacter(optionsToExtendForConfigFile, () => host.getNewLine());
if (host.configFileParsingResult) {
setConfigFileParsingResult(host.configFileParsingResult);
}
else {
Debug.assert(!rootFileNames);
parseConfigFile();
}
Debug.assert(!rootFileNames);
parseConfigFile();
newLine = updateNewLine();
}
+1 -1
View File
@@ -434,7 +434,7 @@ namespace ts {
function createFileWatcherWithTriggerLogging<H, T, U, V, X, Y>(host: H, file: string, cb: WatchCallback<U, V>, flags: T, passThrough: V | undefined, detailInfo1: X | undefined, detailInfo2: Y | undefined, addWatch: AddWatch<H, T, U, undefined>, log: (s: string) => void, watchCaption: string, getDetailWatchInfo: GetDetailWatchInfo<X, Y> | undefined): FileWatcher {
return addWatch(host, file, (fileName, cbOptional) => {
const triggerredInfo = `${watchCaption}:: Triggered with ${fileName}${cbOptional !== undefined ? cbOptional : ""}:: ${getWatchInfo(file, flags, detailInfo1, detailInfo2, getDetailWatchInfo)}`;
const triggerredInfo = `${watchCaption}:: Triggered with ${fileName} ${cbOptional !== undefined ? cbOptional : ""}:: ${getWatchInfo(file, flags, detailInfo1, detailInfo2, getDetailWatchInfo)}`;
log(triggerredInfo);
const start = timestamp();
cb(fileName, cbOptional, passThrough);
+1 -1
View File
@@ -148,7 +148,7 @@ namespace documents {
public static fromUrl(url: string) {
const match = SourceMap._dataURLRegExp.exec(url);
return match ? new SourceMap(/*mapFile*/ undefined, (Buffer.from ? Buffer.from(match[1], "base64") : new Buffer(match[1], "base64")).toString("utf8")) : undefined;
return match ? new SourceMap(/*mapFile*/ undefined, ts.sys.base64decode!(match[1])) : undefined;
}
public static fromSource(text: string): SourceMap | undefined {
+1 -4
View File
@@ -66,11 +66,8 @@ namespace Utils {
export let currentExecutionEnvironment = getExecutionEnvironment();
// Thanks to browserify, Buffer is always available nowadays
const Buffer: typeof global.Buffer = require("buffer").Buffer;
export function encodeString(s: string): string {
return Buffer.from(s).toString("utf8");
return ts.sys.bufferFrom!(s).toString("utf8");
}
export function byteLength(s: string, encoding?: string): number {
+2 -2
View File
@@ -683,7 +683,7 @@ namespace vfs {
if (isDirectory(node)) throw createIOError("EISDIR");
if (!isFile(node)) throw createIOError("EBADF");
node.buffer = Buffer.isBuffer(data) ? data.slice() : Buffer.from("" + data, encoding || "utf8");
node.buffer = Buffer.isBuffer(data) ? data.slice() : ts.sys.bufferFrom!("" + data, encoding || "utf8");
node.size = node.buffer.byteLength;
node.mtimeMs = time;
node.ctimeMs = time;
@@ -1204,7 +1204,7 @@ namespace vfs {
}
},
readFileSync(path: string): Buffer {
return Buffer.from(host.readFile(path)!, "utf8"); // TODO: GH#18217
return ts.sys.bufferFrom!(host.readFile(path)!, "utf8"); // TODO: GH#18217
}
};
}
+4 -4
View File
@@ -1125,15 +1125,15 @@ interface Array<T> {
* Returns a string representation of an array. The elements are converted to string using their toLocalString methods.
*/
toLocaleString(): string;
/**
* Removes the last element from an array and returns it.
*/
pop(): T | undefined;
/**
* Appends new elements to an array, and returns the new length of the array.
* @param items New elements of the Array.
*/
push(...items: T[]): number;
/**
* Removes the last element from an array and returns it.
*/
pop(): T | undefined;
/**
* Combines two or more arrays.
* @param items Additional items to add to the end of array1.
+26 -24
View File
@@ -18,31 +18,33 @@ namespace ts.codefix {
Debug.assert(statement.getStart(sourceFile) === token.getStart(sourceFile));
const container = (isBlock(statement.parent) ? statement.parent : statement).parent;
switch (container.kind) {
case SyntaxKind.IfStatement:
if ((container as IfStatement).elseStatement) {
if (isBlock(statement.parent)) {
changes.deleteNodeRange(sourceFile, first(statement.parent.statements), last(statement.parent.statements));
if (!isBlock(statement.parent) || statement === first(statement.parent.statements)) {
switch (container.kind) {
case SyntaxKind.IfStatement:
if ((container as IfStatement).elseStatement) {
if (isBlock(statement.parent)) {
break;
}
else {
changes.replaceNode(sourceFile, statement, createBlock(emptyArray));
}
return;
}
else {
changes.replaceNode(sourceFile, statement, createBlock(emptyArray));
}
break;
}
// falls through
case SyntaxKind.WhileStatement:
case SyntaxKind.ForStatement:
changes.delete(sourceFile, container);
break;
default:
if (isBlock(statement.parent)) {
const end = start + length;
const lastStatement = Debug.assertDefined(lastWhere(sliceAfter(statement.parent.statements, statement), s => s.pos < end));
changes.deleteNodeRange(sourceFile, statement, lastStatement);
}
else {
changes.delete(sourceFile, statement);
}
// falls through
case SyntaxKind.WhileStatement:
case SyntaxKind.ForStatement:
changes.delete(sourceFile, container);
return;
}
}
if (isBlock(statement.parent)) {
const end = start + length;
const lastStatement = Debug.assertDefined(lastWhere(sliceAfter(statement.parent.statements, statement), s => s.pos < end));
changes.deleteNodeRange(sourceFile, statement, lastStatement);
}
else {
changes.delete(sourceFile, statement);
}
}
+12 -12
View File
@@ -975,7 +975,6 @@ namespace ts.formatting {
// split comment in lines
let startLine = sourceFile.getLineAndCharacterOfPosition(commentRange.pos).line;
const endLine = sourceFile.getLineAndCharacterOfPosition(commentRange.end).line;
let parts: TextRange[];
if (startLine === endLine) {
if (!firstLineIsIndented) {
// treat as single line comment
@@ -983,20 +982,21 @@ namespace ts.formatting {
}
return;
}
else {
parts = [];
let startPos = commentRange.pos;
for (let line = startLine; line < endLine; line++) {
const endOfLine = getEndLinePosition(line, sourceFile);
parts.push({ pos: startPos, end: endOfLine });
startPos = getStartPositionOfLine(line + 1, sourceFile);
}
if (indentFinalLine) {
parts.push({ pos: startPos, end: commentRange.end });
}
const parts: TextRange[] = [];
let startPos = commentRange.pos;
for (let line = startLine; line < endLine; line++) {
const endOfLine = getEndLinePosition(line, sourceFile);
parts.push({ pos: startPos, end: endOfLine });
startPos = getStartPositionOfLine(line + 1, sourceFile);
}
if (indentFinalLine) {
parts.push({ pos: startPos, end: commentRange.end });
}
if (parts.length === 0) return;
const startLinePos = getStartPositionOfLine(startLine, sourceFile);
const nonWhitespaceColumnInFirstPart =
+6 -10
View File
@@ -351,7 +351,10 @@ namespace ts.formatting {
getListIfStartEndIsInListRange((<SignatureDeclaration>node.parent).parameters, start, end);
}
case SyntaxKind.ClassDeclaration:
return getListIfStartEndIsInListRange((<ClassDeclaration>node.parent).typeParameters, node.getStart(sourceFile), end);
case SyntaxKind.ClassExpression:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.TypeAliasDeclaration:
return getListIfStartEndIsInListRange((<ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeAliasDeclaration>node.parent).typeParameters, node.getStart(sourceFile), end);
case SyntaxKind.NewExpression:
case SyntaxKind.CallExpression: {
const start = node.getStart(sourceFile);
@@ -576,17 +579,10 @@ namespace ts.formatting {
function isControlFlowEndingStatement(kind: SyntaxKind, parent: TextRangeWithKind): boolean {
switch (kind) {
case SyntaxKind.ReturnStatement:
case SyntaxKind.ThrowStatement: {
if (parent.kind !== SyntaxKind.Block) {
return true;
}
const grandParent = (parent as Node).parent;
// In a function, we may want to write inner functions after this.
return !(grandParent && grandParent.kind === SyntaxKind.FunctionExpression || grandParent.kind === SyntaxKind.FunctionDeclaration);
}
case SyntaxKind.ThrowStatement:
case SyntaxKind.ContinueStatement:
case SyntaxKind.BreakStatement:
return true;
return parent.kind !== SyntaxKind.Block;
default:
return false;
}
+5 -5
View File
@@ -11,7 +11,7 @@ namespace ts.JsDoc {
"borrows",
"callback",
"class",
"classDesc",
"classdesc",
"constant",
"constructor",
"constructs",
@@ -28,16 +28,16 @@ namespace ts.JsDoc {
"external",
"field",
"file",
"fileOverview",
"fileoverview",
"fires",
"function",
"generator",
"global",
"hideConstructor",
"hideconstructor",
"host",
"ignore",
"implements",
"inheritDoc",
"inheritdoc",
"inner",
"instance",
"interface",
@@ -46,7 +46,7 @@ namespace ts.JsDoc {
"license",
"listens",
"member",
"memberOf",
"memberof",
"method",
"mixes",
"module",
+16 -9
View File
@@ -133,7 +133,7 @@ namespace ts.NavigationBar {
/** Call after calling `startNode` and adding children to it. */
function endNode(): void {
if (parent.children) {
mergeChildren(parent.children);
mergeChildren(parent.children, parent);
sortChildren(parent.children);
}
parent = parentsStack.pop()!;
@@ -304,7 +304,7 @@ namespace ts.NavigationBar {
}
/** Merge declarations of the same kind. */
function mergeChildren(children: NavigationBarNode[]): void {
function mergeChildren(children: NavigationBarNode[], node: NavigationBarNode): void {
const nameToItems = createMap<NavigationBarNode | NavigationBarNode[]>();
filterMutate(children, child => {
const declName = getNameOfDeclaration(<Declaration>child.node);
@@ -322,7 +322,7 @@ namespace ts.NavigationBar {
if (itemsWithSameName instanceof Array) {
for (const itemWithSameName of itemsWithSameName) {
if (tryMerge(itemWithSameName, child)) {
if (tryMerge(itemWithSameName, child, node)) {
return false;
}
}
@@ -331,7 +331,7 @@ namespace ts.NavigationBar {
}
else {
const itemWithSameName = itemsWithSameName;
if (tryMerge(itemWithSameName, child)) {
if (tryMerge(itemWithSameName, child, node)) {
return false;
}
nameToItems.set(name, [itemWithSameName, child]);
@@ -340,8 +340,8 @@ namespace ts.NavigationBar {
});
}
function tryMerge(a: NavigationBarNode, b: NavigationBarNode): boolean {
if (shouldReallyMerge(a.node, b.node)) {
function tryMerge(a: NavigationBarNode, b: NavigationBarNode, parent: NavigationBarNode): boolean {
if (shouldReallyMerge(a.node, b.node, parent)) {
merge(a, b);
return true;
}
@@ -349,8 +349,8 @@ namespace ts.NavigationBar {
}
/** a and b have the same name, but they may not be mergeable. */
function shouldReallyMerge(a: Node, b: Node): boolean {
if (a.kind !== b.kind) {
function shouldReallyMerge(a: Node, b: Node, parent: NavigationBarNode): boolean {
if (a.kind !== b.kind || a.parent !== b.parent && !(isOwnChild(a, parent) && isOwnChild(b, parent))) {
return false;
}
switch (a.kind) {
@@ -366,6 +366,13 @@ namespace ts.NavigationBar {
}
}
// We want to merge own children like `I` in in `module A { interface I {} } module A { interface I {} }`
// We don't want to merge unrelated children like `m` in `const o = { a: { m() {} }, b: { m() {} } };`
function isOwnChild(n: Node, parent: NavigationBarNode): boolean {
const par = isModuleBlock(n.parent) ? n.parent.parent : n.parent;
return par === parent.node || contains(parent.additionalNodes, par);
}
// We use 1 NavNode to represent 'A.B.C', but there are multiple source nodes.
// Only merge module nodes that have the same chain. Don't merge 'A.B.C' with 'A'!
function areSameModule(a: ModuleDeclaration, b: ModuleDeclaration): boolean {
@@ -383,7 +390,7 @@ namespace ts.NavigationBar {
target.children = concatenate(target.children, source.children);
if (target.children) {
mergeChildren(target.children);
mergeChildren(target.children, target);
sortChildren(target.children);
}
}
+1 -1
View File
@@ -2,7 +2,7 @@ namespace ts {
describe("convertToBase64", () => {
function runTest(input: string): void {
const actual = convertToBase64(input);
const expected = (Buffer.from ? Buffer.from(input) : new Buffer(input)).toString("base64");
const expected = sys.base64encode!(input);
assert.equal(actual, expected, "Encoded string using convertToBase64 does not match buffer.toString('base64')");
}
+1
View File
@@ -21,6 +21,7 @@ namespace ts {
const func = createFunctionExpression(/*modifiers*/ undefined, /*asteriskToken*/ undefined, "fn", /*typeParameters*/ undefined, /*parameters*/ undefined, /*type*/ undefined, createBlock([]));
checkExpression(func);
checkExpression(createCall(func, /*typeArguments*/ undefined, /*argumentsArray*/ undefined));
checkExpression(createTaggedTemplate(func, createNoSubstitutionTemplateLiteral("")));
checkExpression(createBinary(createLiteral("a"), SyntaxKind.CommaToken, createLiteral("b")));
checkExpression(createCommaList([createLiteral("a"), createLiteral("b")]));
+33 -1
View File
@@ -233,6 +233,38 @@ namespace ts {
assert.isBelow(fs.statSync("/src/core/index.js").mtimeMs, time(), "Upstream JS file should not have been rebuilt");
});
});
describe("tsbuild - with resolveJsonModule option", () => {
const projFs = loadProjectFromDisk("tests/projects/resolveJsonModuleAndComposite");
const allExpectedOutputs = ["/src/tests/dist/src/index.js", "/src/tests/dist/src/index.d.ts", "/src/tests/dist/src/hello.json"];
function verifyProjectWithResolveJsonModule(configFile: string, ...expectedDiagnosticMessages: DiagnosticMessage[]) {
const fs = projFs.shadow();
const host = new fakes.CompilerHost(fs);
const builder = createSolutionBuilder(host, buildHost, [configFile], { dry: false, force: false, verbose: false });
clearDiagnostics();
builder.buildAllProjects();
assertDiagnosticMessages(...expectedDiagnosticMessages);
if (!expectedDiagnosticMessages.length) {
// Check for outputs. Not an exhaustive list
for (const output of allExpectedOutputs) {
assert(fs.existsSync(output), `Expect file ${output} to exist`);
}
}
}
it("with resolveJsonModule and include only", () => {
verifyProjectWithResolveJsonModule("/src/tests/tsconfig_withInclude.json", Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern);
});
it("with resolveJsonModule and files containing json file", () => {
verifyProjectWithResolveJsonModule("/src/tests/tsconfig_withFiles.json");
});
it("with resolveJsonModule and include and files", () => {
verifyProjectWithResolveJsonModule("/src/tests/tsconfig_withIncludeAndFiles.json");
});
});
}
export namespace OutFile {
@@ -427,4 +459,4 @@ namespace ts {
fs.makeReadonly();
return fs;
}
}
}
+55 -21
View File
@@ -2315,63 +2315,97 @@ declare module "fs" {
describe("tsc-watch console clearing", () => {
const currentDirectoryLog = "Current directory: / CaseSensitiveFileNames: false\n";
const fileWatcherAddedLog = [
"FileWatcher:: Added:: WatchInfo: f.ts 250 Source file\n",
"FileWatcher:: Added:: WatchInfo: /f.ts 250 Source file\n",
"FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 250 Source file\n"
];
const file: File = {
path: "/f.ts",
content: ""
};
function getProgramSynchronizingLog(options: CompilerOptions) {
return [
"Synchronizing program\n",
"CreatingProgramWith::\n",
" roots: [\"f.ts\"]\n",
" roots: [\"/f.ts\"]\n",
` options: ${JSON.stringify(options)}\n`
];
}
function checkConsoleClearing(options: CompilerOptions = {}) {
const file = {
path: "f.ts",
content: ""
};
const files = [file, libFile];
const disableConsoleClear = options.diagnostics || options.extendedDiagnostics || options.preserveWatchOutput;
function isConsoleClearDisabled(options: CompilerOptions) {
return options.diagnostics || options.extendedDiagnostics || options.preserveWatchOutput;
}
function verifyCompilation(host: WatchedSystem, options: CompilerOptions, initialDisableOptions?: CompilerOptions) {
const disableConsoleClear = isConsoleClearDisabled(options);
const hasLog = options.extendedDiagnostics || options.diagnostics;
const host = createWatchedSystem(files);
createWatchOfFilesAndCompilerOptions([file.path], host, options);
checkOutputErrorsInitial(host, emptyArray, disableConsoleClear, hasLog ? [
checkOutputErrorsInitial(host, emptyArray, initialDisableOptions ? isConsoleClearDisabled(initialDisableOptions) : disableConsoleClear, hasLog ? [
currentDirectoryLog,
...getProgramSynchronizingLog(options),
...(options.extendedDiagnostics ? fileWatcherAddedLog : emptyArray)
] : undefined);
file.content = "//";
host.reloadFS(files);
host.modifyFile(file.path, "//");
host.runQueuedTimeoutCallbacks();
checkOutputErrorsIncremental(host, emptyArray, disableConsoleClear, hasLog ? [
"FileWatcher:: Triggered with /f.ts1:: WatchInfo: f.ts 250 Source file\n",
"FileWatcher:: Triggered with /f.ts 1:: WatchInfo: /f.ts 250 Source file\n",
"Scheduling update\n",
"Elapsed:: 0ms FileWatcher:: Triggered with /f.ts1:: WatchInfo: f.ts 250 Source file\n"
"Elapsed:: 0ms FileWatcher:: Triggered with /f.ts 1:: WatchInfo: /f.ts 250 Source file\n"
] : undefined, hasLog ? getProgramSynchronizingLog(options) : undefined);
}
function checkConsoleClearingUsingCommandLineOptions(options: CompilerOptions = {}) {
const files = [file, libFile];
const host = createWatchedSystem(files);
createWatchOfFilesAndCompilerOptions([file.path], host, options);
verifyCompilation(host, options);
}
it("without --diagnostics or --extendedDiagnostics", () => {
checkConsoleClearing();
checkConsoleClearingUsingCommandLineOptions();
});
it("with --diagnostics", () => {
checkConsoleClearing({
checkConsoleClearingUsingCommandLineOptions({
diagnostics: true,
});
});
it("with --extendedDiagnostics", () => {
checkConsoleClearing({
checkConsoleClearingUsingCommandLineOptions({
extendedDiagnostics: true,
});
});
it("with --preserveWatchOutput", () => {
checkConsoleClearing({
checkConsoleClearingUsingCommandLineOptions({
preserveWatchOutput: true,
});
});
describe("when preserveWatchOutput is true in config file", () => {
const compilerOptions: CompilerOptions = {
preserveWatchOutput: true
};
const configFile: File = {
path: "/tsconfig.json",
content: JSON.stringify({ compilerOptions })
};
const files = [file, configFile, libFile];
it("using createWatchOfConfigFile ", () => {
const host = createWatchedSystem(files);
createWatchOfConfigFile(configFile.path, host);
// Initially console is cleared if --preserveOutput is not provided since the config file is yet to be parsed
verifyCompilation(host, compilerOptions, {});
});
it("when createWatchProgram is invoked with configFileParseResult on WatchCompilerHostOfConfigFile", () => {
const host = createWatchedSystem(files);
const reportDiagnostic = createDiagnosticReporter(host);
const optionsToExtend: CompilerOptions = {};
const configParseResult = parseConfigFileWithSystem(configFile.path, optionsToExtend, host, reportDiagnostic)!;
const watchCompilerHost = createWatchCompilerHostOfConfigFile(configParseResult.options.configFilePath!, optionsToExtend, host, /*createProgram*/ undefined, reportDiagnostic, createWatchStatusReporter(host));
watchCompilerHost.configFileParsingResult = configParseResult;
createWatchProgram(watchCompilerHost);
verifyCompilation(host, compilerOptions);
});
});
});
describe("tsc-watch with different polling/non polling options", () => {
+2 -2
View File
@@ -199,7 +199,7 @@ namespace ts.server {
private write(s: string) {
if (this.fd >= 0) {
const buf = Buffer.from ? Buffer.from(s) : new Buffer(s);
const buf = sys.bufferFrom!(s);
// tslint:disable-next-line no-null-keyword
fs.writeSync(this.fd, buf, 0, buf.length, /*position*/ null!); // TODO: GH#18217
}
@@ -869,7 +869,7 @@ namespace ts.server {
}
// Override sys.write because fs.writeSync is not reliable on Node 4
sys.write = (s: string) => writeMessage(Buffer.from ? Buffer.from(s, "utf8") : new Buffer(s, "utf8"));
sys.write = (s: string) => writeMessage(sys.bufferFrom!(s, "utf8"));
sys.watchFile = (fileName, callback) => {
const watchedFile = pollingWatchedFileSet.addFile(fileName, callback);
return {
@@ -21,7 +21,7 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(25,5): error
Types of property '0' are incompatible.
Type 'string' is not assignable to type 'number'.
tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(26,5): error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[number]'.
Property 'push' is missing in type '{ 0: string; 1: number; length: 2; }'.
Property 'pop' is missing in type '{ 0: string; 1: number; length: 2; }'.
tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(27,5): error TS2322: Type '[string, number]' is not assignable to type '[string]'.
Types of property 'length' are incompatible.
Type '2' is not assignable to type '1'.
@@ -29,14 +29,14 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(28,5): error
Types of property 'length' are incompatible.
Type '2' is not assignable to type '1'.
tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(29,5): error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[string]'.
Property 'push' is missing in type '{ 0: string; 1: number; length: 2; }'.
Property 'pop' is missing in type '{ 0: string; 1: number; length: 2; }'.
tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(30,5): error TS2322: Type '[string, number]' is not assignable to type '[number, string]'.
Type 'string' is not assignable to type 'number'.
tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(31,5): error TS2322: Type 'StrNum' is not assignable to type '[number, string]'.
Types of property '0' are incompatible.
Type 'string' is not assignable to type 'number'.
tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(32,5): error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[number, string]'.
Property 'push' is missing in type '{ 0: string; 1: number; length: 2; }'.
Property 'pop' is missing in type '{ 0: string; 1: number; length: 2; }'.
==== tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts (19 errors) ====
@@ -102,7 +102,7 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(32,5): error
var l3: [number] = z;
~~
!!! error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[number]'.
!!! error TS2322: Property 'push' is missing in type '{ 0: string; 1: number; length: 2; }'.
!!! error TS2322: Property 'pop' is missing in type '{ 0: string; 1: number; length: 2; }'.
var m1: [string] = x;
~~
!!! error TS2322: Type '[string, number]' is not assignable to type '[string]'.
@@ -116,7 +116,7 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(32,5): error
var m3: [string] = z;
~~
!!! error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[string]'.
!!! error TS2322: Property 'push' is missing in type '{ 0: string; 1: number; length: 2; }'.
!!! error TS2322: Property 'pop' is missing in type '{ 0: string; 1: number; length: 2; }'.
var n1: [number, string] = x;
~~
!!! error TS2322: Type '[string, number]' is not assignable to type '[number, string]'.
@@ -129,7 +129,7 @@ tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(32,5): error
var n3: [number, string] = z;
~~
!!! error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[number, string]'.
!!! error TS2322: Property 'push' is missing in type '{ 0: string; 1: number; length: 2; }'.
!!! error TS2322: Property 'pop' is missing in type '{ 0: string; 1: number; length: 2; }'.
var o1: [string, number] = x;
var o2: [string, number] = y;
var o3: [string, number] = y;
@@ -34,7 +34,7 @@ tests/cases/compiler/arrayAssignmentTest1.ts(77,1): error TS2322: Type 'I1[]' is
Type 'I1' is not assignable to type 'C3'.
Property 'CM3M1' is missing in type 'I1'.
tests/cases/compiler/arrayAssignmentTest1.ts(79,1): error TS2322: Type '() => C1' is not assignable to type 'any[]'.
Property 'push' is missing in type '() => C1'.
Property 'pop' is missing in type '() => C1'.
tests/cases/compiler/arrayAssignmentTest1.ts(80,1): error TS2322: Type '{ one: number; }' is not assignable to type 'any[]'.
Property 'length' is missing in type '{ one: number; }'.
tests/cases/compiler/arrayAssignmentTest1.ts(82,1): error TS2322: Type 'C1' is not assignable to type 'any[]'.
@@ -177,7 +177,7 @@ tests/cases/compiler/arrayAssignmentTest1.ts(85,1): error TS2322: Type 'I1' is n
arr_any = f1; // should be an error - is
~~~~~~~
!!! error TS2322: Type '() => C1' is not assignable to type 'any[]'.
!!! error TS2322: Property 'push' is missing in type '() => C1'.
!!! error TS2322: Property 'pop' is missing in type '() => C1'.
arr_any = o1; // should be an error - is
~~~~~~~
!!! error TS2322: Type '{ one: number; }' is not assignable to type 'any[]'.
@@ -8,9 +8,9 @@ tests/cases/compiler/arrayAssignmentTest2.ts(49,1): error TS2322: Type 'I1[]' is
Type 'I1' is not assignable to type 'C3'.
Property 'CM3M1' is missing in type 'I1'.
tests/cases/compiler/arrayAssignmentTest2.ts(51,1): error TS2322: Type '() => C1' is not assignable to type 'any[]'.
Property 'push' is missing in type '() => C1'.
Property 'pop' is missing in type '() => C1'.
tests/cases/compiler/arrayAssignmentTest2.ts(52,1): error TS2322: Type '() => any' is not assignable to type 'any[]'.
Property 'push' is missing in type '() => any'.
Property 'pop' is missing in type '() => any'.
tests/cases/compiler/arrayAssignmentTest2.ts(53,1): error TS2322: Type '{ one: number; }' is not assignable to type 'any[]'.
Property 'length' is missing in type '{ one: number; }'.
tests/cases/compiler/arrayAssignmentTest2.ts(55,1): error TS2322: Type 'C1' is not assignable to type 'any[]'.
@@ -89,11 +89,11 @@ tests/cases/compiler/arrayAssignmentTest2.ts(58,1): error TS2322: Type 'I1' is n
arr_any = f1; // should be an error - is
~~~~~~~
!!! error TS2322: Type '() => C1' is not assignable to type 'any[]'.
!!! error TS2322: Property 'push' is missing in type '() => C1'.
!!! error TS2322: Property 'pop' is missing in type '() => C1'.
arr_any = function () { return null;} // should be an error - is
~~~~~~~
!!! error TS2322: Type '() => any' is not assignable to type 'any[]'.
!!! error TS2322: Property 'push' is missing in type '() => any'.
!!! error TS2322: Property 'pop' is missing in type '() => any'.
arr_any = o1; // should be an error - is
~~~~~~~
!!! error TS2322: Type '{ one: number; }' is not assignable to type 'any[]'.
@@ -1,5 +1,5 @@
tests/cases/compiler/arrayAssignmentTest4.ts(22,1): error TS2322: Type '() => any' is not assignable to type 'any[]'.
Property 'push' is missing in type '() => any'.
Property 'pop' is missing in type '() => any'.
tests/cases/compiler/arrayAssignmentTest4.ts(23,1): error TS2322: Type 'C3' is not assignable to type 'any[]'.
Property 'length' is missing in type 'C3'.
@@ -29,7 +29,7 @@ tests/cases/compiler/arrayAssignmentTest4.ts(23,1): error TS2322: Type 'C3' is n
arr_any = function () { return null;} // should be an error - is
~~~~~~~
!!! error TS2322: Type '() => any' is not assignable to type 'any[]'.
!!! error TS2322: Property 'push' is missing in type '() => any'.
!!! error TS2322: Property 'pop' is missing in type '() => any'.
arr_any = c3; // should be an error - is
~~~~~~~
!!! error TS2322: Type 'C3' is not assignable to type 'any[]'.
@@ -11,12 +11,10 @@ tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(32,5): error
tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(33,5): error TS2322: Type 'number[]' is not assignable to type '[number, number, number]'.
Property '0' is missing in type 'number[]'.
tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(34,5): error TS2322: Type '(string | number)[]' is not assignable to type 'myArray'.
Types of property 'push' are incompatible.
Type '(...items: (string | number)[]) => number' is not assignable to type '(...items: Number[]) => number'.
Types of parameters 'items' and 'items' are incompatible.
Type 'Number' is not assignable to type 'string | number'.
Type 'Number' is not assignable to type 'number'.
'number' is a primitive, but 'Number' is a wrapper object. Prefer using 'number' when possible.
Types of property 'pop' are incompatible.
Type '() => string | number' is not assignable to type '() => Number'.
Type 'string | number' is not assignable to type 'Number'.
Type 'string' is not assignable to type 'Number'.
==== tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts (8 errors) ====
@@ -75,10 +73,8 @@ tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(34,5): error
var c2: myArray = [...temp1, ...temp]; // Error cannot assign (number|string)[] to number[]
~~
!!! error TS2322: Type '(string | number)[]' is not assignable to type 'myArray'.
!!! error TS2322: Types of property 'push' are incompatible.
!!! error TS2322: Type '(...items: (string | number)[]) => number' is not assignable to type '(...items: Number[]) => number'.
!!! error TS2322: Types of parameters 'items' and 'items' are incompatible.
!!! error TS2322: Type 'Number' is not assignable to type 'string | number'.
!!! error TS2322: Type 'Number' is not assignable to type 'number'.
!!! error TS2322: 'number' is a primitive, but 'Number' is a wrapper object. Prefer using 'number' when possible.
!!! error TS2322: Types of property 'pop' are incompatible.
!!! error TS2322: Type '() => string | number' is not assignable to type '() => Number'.
!!! error TS2322: Type 'string | number' is not assignable to type 'Number'.
!!! error TS2322: Type 'string' is not assignable to type 'Number'.
@@ -4,11 +4,12 @@ tests/cases/conformance/jsdoc/test.js(7,24): error TS2322: Type 'number' is not
tests/cases/conformance/jsdoc/test.js(10,17): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/conformance/jsdoc/test.js(12,14): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/conformance/jsdoc/test.js(14,24): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/conformance/jsdoc/test.js(28,5): error TS8030: The type of a function declaration must match the function's signature.
tests/cases/conformance/jsdoc/test.js(34,5): error TS2322: Type '1 | 2' is not assignable to type '2 | 3'.
Type '1' is not assignable to type '2 | 3'.
==== tests/cases/conformance/jsdoc/test.js (7 errors) ====
==== tests/cases/conformance/jsdoc/test.js (8 errors) ====
// all 6 should error on return statement/expression
/** @type {(x: number) => string} */
function h(x) { return x }
@@ -49,6 +50,8 @@ tests/cases/conformance/jsdoc/test.js(34,5): error TS2322: Type '1 | 2' is not a
/** @typedef {{(s: string): 0 | 1; (b: boolean): 2 | 3 }} Gioconda */
/** @type {Gioconda} */
~~~~~~~~~~~~~~~~
!!! error TS8030: The type of a function declaration must match the function's signature.
function monaLisa(sb) {
return typeof sb === 'string' ? 1 : 2;
}
@@ -1,12 +1,13 @@
tests/cases/conformance/jsdoc/test.js(1,5): error TS8030: The type of a function declaration must be callable.
tests/cases/conformance/jsdoc/test.js(1,5): error TS8030: The type of a function declaration must match the function's signature.
tests/cases/conformance/jsdoc/test.js(7,5): error TS2322: Type '(prop: any) => void' is not assignable to type '{ prop: string; }'.
Property 'prop' is missing in type '(prop: any) => void'.
tests/cases/conformance/jsdoc/test.js(10,5): error TS8030: The type of a function declaration must match the function's signature.
==== tests/cases/conformance/jsdoc/test.js (2 errors) ====
==== tests/cases/conformance/jsdoc/test.js (3 errors) ====
/** @type {number} */
~~~~~~~~~~~~~~
!!! error TS8030: The type of a function declaration must be callable.
!!! error TS8030: The type of a function declaration must match the function's signature.
function f() {
return 1
}
@@ -17,4 +18,16 @@ tests/cases/conformance/jsdoc/test.js(7,5): error TS2322: Type '(prop: any) => v
!!! error TS2322: Type '(prop: any) => void' is not assignable to type '{ prop: string; }'.
!!! error TS2322: Property 'prop' is missing in type '(prop: any) => void'.
}
/** @type {(a: number) => number} */
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS8030: The type of a function declaration must match the function's signature.
function add1(a, b) { return a + b; }
/** @type {(a: number, b: number) => number} */
function add2(a, b) { return a + b; }
// TODO: Should be an error since signature doesn't match.
/** @type {(a: number, b: number, c: number) => number} */
function add3(a, b) { return a + b; }
@@ -12,3 +12,28 @@ var g = function (prop) {
>prop : Symbol(prop, Decl(test.js, 6, 18))
}
/** @type {(a: number) => number} */
function add1(a, b) { return a + b; }
>add1 : Symbol(add1, Decl(test.js, 7, 1))
>a : Symbol(a, Decl(test.js, 10, 14))
>b : Symbol(b, Decl(test.js, 10, 16))
>a : Symbol(a, Decl(test.js, 10, 14))
>b : Symbol(b, Decl(test.js, 10, 16))
/** @type {(a: number, b: number) => number} */
function add2(a, b) { return a + b; }
>add2 : Symbol(add2, Decl(test.js, 10, 37))
>a : Symbol(a, Decl(test.js, 13, 14))
>b : Symbol(b, Decl(test.js, 13, 16))
>a : Symbol(a, Decl(test.js, 13, 14))
>b : Symbol(b, Decl(test.js, 13, 16))
// TODO: Should be an error since signature doesn't match.
/** @type {(a: number, b: number, c: number) => number} */
function add3(a, b) { return a + b; }
>add3 : Symbol(add3, Decl(test.js, 13, 37))
>a : Symbol(a, Decl(test.js, 17, 14))
>b : Symbol(b, Decl(test.js, 17, 16))
>a : Symbol(a, Decl(test.js, 17, 14))
>b : Symbol(b, Decl(test.js, 17, 16))
@@ -14,3 +14,31 @@ var g = function (prop) {
>prop : any
}
/** @type {(a: number) => number} */
function add1(a, b) { return a + b; }
>add1 : (a: any, b: any) => number
>a : any
>b : any
>a + b : any
>a : any
>b : any
/** @type {(a: number, b: number) => number} */
function add2(a, b) { return a + b; }
>add2 : (a: number, b: number) => number
>a : number
>b : number
>a + b : number
>a : number
>b : number
// TODO: Should be an error since signature doesn't match.
/** @type {(a: number, b: number, c: number) => number} */
function add3(a, b) { return a + b; }
>add3 : (a: number, b: number) => number
>a : number
>b : number
>a + b : number
>a : number
>b : number
@@ -88,7 +88,7 @@ type K10 = keyof Shape; // "name" | "width" | "height" | "visible"
>Shape : Shape
type K11 = keyof Shape[]; // "length" | "toString" | ...
>K11 : number | "length" | "toString" | "toLocaleString" | "push" | "pop" | "concat" | "join" | "reverse" | "shift" | "slice" | "sort" | "splice" | "unshift" | "indexOf" | "lastIndexOf" | "every" | "some" | "forEach" | "map" | "filter" | "reduce" | "reduceRight"
>K11 : number | "length" | "toString" | "toLocaleString" | "pop" | "push" | "concat" | "join" | "reverse" | "shift" | "slice" | "sort" | "splice" | "unshift" | "indexOf" | "lastIndexOf" | "every" | "some" | "forEach" | "map" | "filter" | "reduce" | "reduceRight"
>Shape : Shape
type K12 = keyof Dictionary<Shape>; // string
@@ -108,7 +108,7 @@ type K15 = keyof E; // "toString" | "toFixed" | "toExponential" | ...
>E : E
type K16 = keyof [string, number]; // "0" | "1" | "length" | "toString" | ...
>K16 : number | "0" | "1" | "length" | "toString" | "toLocaleString" | "push" | "pop" | "concat" | "join" | "reverse" | "shift" | "slice" | "sort" | "splice" | "unshift" | "indexOf" | "lastIndexOf" | "every" | "some" | "forEach" | "map" | "filter" | "reduce" | "reduceRight"
>K16 : number | "0" | "1" | "length" | "toString" | "toLocaleString" | "pop" | "push" | "concat" | "join" | "reverse" | "shift" | "slice" | "sort" | "splice" | "unshift" | "indexOf" | "lastIndexOf" | "every" | "some" | "forEach" | "map" | "filter" | "reduce" | "reduceRight"
type K17 = keyof (Shape | Item); // "name"
>K17 : "name"
@@ -0,0 +1,46 @@
tests/cases/compiler/nestedRecursiveArraysOrObjectsError01.ts(10,9): error TS2322: Type '{ foo: string; jj: number; }[][][]' is not assignable to type 'Style'.
Type '{ foo: string; jj: number; }[][][]' is not assignable to type 'StyleArray'.
Types of property 'pop' are incompatible.
Type '() => { foo: string; jj: number; }[][]' is not assignable to type '() => Style'.
Type '{ foo: string; jj: number; }[][]' is not assignable to type 'Style'.
Type '{ foo: string; jj: number; }[][]' is not assignable to type 'StyleArray'.
Types of property 'pop' are incompatible.
Type '() => { foo: string; jj: number; }[]' is not assignable to type '() => Style'.
Type '{ foo: string; jj: number; }[]' is not assignable to type 'Style'.
Type '{ foo: string; jj: number; }[]' is not assignable to type 'StyleArray'.
Types of property 'pop' are incompatible.
Type '() => { foo: string; jj: number; }' is not assignable to type '() => Style'.
Type '{ foo: string; jj: number; }' is not assignable to type 'Style'.
Object literal may only specify known properties, and 'jj' does not exist in type 'Style'.
==== tests/cases/compiler/nestedRecursiveArraysOrObjectsError01.ts (1 errors) ====
type Style = StyleBase | StyleArray;
interface StyleArray extends Array<Style> {}
interface StyleBase {
foo: string;
}
const blah: Style = [
[[{
foo: 'asdf',
jj: 1 // intentional error
~~~~~
!!! error TS2322: Type '{ foo: string; jj: number; }[][][]' is not assignable to type 'Style'.
!!! error TS2322: Type '{ foo: string; jj: number; }[][][]' is not assignable to type 'StyleArray'.
!!! error TS2322: Types of property 'pop' are incompatible.
!!! error TS2322: Type '() => { foo: string; jj: number; }[][]' is not assignable to type '() => Style'.
!!! error TS2322: Type '{ foo: string; jj: number; }[][]' is not assignable to type 'Style'.
!!! error TS2322: Type '{ foo: string; jj: number; }[][]' is not assignable to type 'StyleArray'.
!!! error TS2322: Types of property 'pop' are incompatible.
!!! error TS2322: Type '() => { foo: string; jj: number; }[]' is not assignable to type '() => Style'.
!!! error TS2322: Type '{ foo: string; jj: number; }[]' is not assignable to type 'Style'.
!!! error TS2322: Type '{ foo: string; jj: number; }[]' is not assignable to type 'StyleArray'.
!!! error TS2322: Types of property 'pop' are incompatible.
!!! error TS2322: Type '() => { foo: string; jj: number; }' is not assignable to type '() => Style'.
!!! error TS2322: Type '{ foo: string; jj: number; }' is not assignable to type 'Style'.
!!! error TS2322: Object literal may only specify known properties, and 'jj' does not exist in type 'Style'.
}]]
];
@@ -0,0 +1,23 @@
//// [nestedRecursiveArraysOrObjectsError01.ts]
type Style = StyleBase | StyleArray;
interface StyleArray extends Array<Style> {}
interface StyleBase {
foo: string;
}
const blah: Style = [
[[{
foo: 'asdf',
jj: 1 // intentional error
}]]
];
//// [nestedRecursiveArraysOrObjectsError01.js]
var blah = [
[[{
foo: 'asdf',
jj: 1 // intentional error
}]]
];
@@ -0,0 +1,33 @@
=== tests/cases/compiler/nestedRecursiveArraysOrObjectsError01.ts ===
type Style = StyleBase | StyleArray;
>Style : Symbol(Style, Decl(nestedRecursiveArraysOrObjectsError01.ts, 0, 0))
>StyleBase : Symbol(StyleBase, Decl(nestedRecursiveArraysOrObjectsError01.ts, 1, 44))
>StyleArray : Symbol(StyleArray, Decl(nestedRecursiveArraysOrObjectsError01.ts, 0, 36))
interface StyleArray extends Array<Style> {}
>StyleArray : Symbol(StyleArray, Decl(nestedRecursiveArraysOrObjectsError01.ts, 0, 36))
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>Style : Symbol(Style, Decl(nestedRecursiveArraysOrObjectsError01.ts, 0, 0))
interface StyleBase {
>StyleBase : Symbol(StyleBase, Decl(nestedRecursiveArraysOrObjectsError01.ts, 1, 44))
foo: string;
>foo : Symbol(StyleBase.foo, Decl(nestedRecursiveArraysOrObjectsError01.ts, 2, 21))
}
const blah: Style = [
>blah : Symbol(blah, Decl(nestedRecursiveArraysOrObjectsError01.ts, 6, 5))
>Style : Symbol(Style, Decl(nestedRecursiveArraysOrObjectsError01.ts, 0, 0))
[[{
foo: 'asdf',
>foo : Symbol(foo, Decl(nestedRecursiveArraysOrObjectsError01.ts, 7, 7))
jj: 1 // intentional error
>jj : Symbol(jj, Decl(nestedRecursiveArraysOrObjectsError01.ts, 8, 20))
}]]
];
@@ -0,0 +1,40 @@
=== tests/cases/compiler/nestedRecursiveArraysOrObjectsError01.ts ===
type Style = StyleBase | StyleArray;
>Style : Style
>StyleBase : StyleBase
>StyleArray : StyleArray
interface StyleArray extends Array<Style> {}
>StyleArray : StyleArray
>Array : T[]
>Style : Style
interface StyleBase {
>StyleBase : StyleBase
foo: string;
>foo : string
}
const blah: Style = [
>blah : Style
>Style : Style
>[ [[{ foo: 'asdf', jj: 1 // intentional error }]]] : { foo: string; jj: number; }[][][]
[[{
>[[{ foo: 'asdf', jj: 1 // intentional error }]] : { foo: string; jj: number; }[][]
>[{ foo: 'asdf', jj: 1 // intentional error }] : { foo: string; jj: number; }[]
>{ foo: 'asdf', jj: 1 // intentional error } : { foo: string; jj: number; }
foo: 'asdf',
>foo : string
>'asdf' : "asdf"
jj: 1 // intentional error
>jj : number
>1 : 1
}]]
];
@@ -87,7 +87,7 @@ function f<T extends { b: string }>(p1: T, p2: T[]) {
>p1 : T
var {...r2} = p2; // OK
>r2 : { [n: number]: T; length: number; toString(): string; toLocaleString(): string; push(...items: T[]): number; pop(): T; concat(...items: ConcatArray<T>[]): T[]; concat(...items: (T | ConcatArray<T>)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter<S extends T>(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; }
>r2 : { [n: number]: T; length: number; toString(): string; toLocaleString(): string; pop(): T; push(...items: T[]): number; concat(...items: ConcatArray<T>[]): T[]; concat(...items: (T | ConcatArray<T>)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter<S extends T>(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; }
>p2 : T[]
var {...r3} = t; // Error, generic type paramter
@@ -89,8 +89,8 @@ function f<T extends { b: string }>(p1: T, p2: T[]) {
>p1 : T
var o2 = { ...p2 }; // OK
>o2 : { [x: number]: T; length: number; toString(): string; toLocaleString(): string; push(...items: T[]): number; pop(): T; concat(...items: ConcatArray<T>[]): T[]; concat(...items: (T | ConcatArray<T>)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter<S extends T>(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; }
>{ ...p2 } : { [n: number]: T; length: number; toString(): string; toLocaleString(): string; push(...items: T[]): number; pop(): T; concat(...items: ConcatArray<T>[]): T[]; concat(...items: (T | ConcatArray<T>)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter<S extends T>(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; }
>o2 : { [x: number]: T; length: number; toString(): string; toLocaleString(): string; pop(): T; push(...items: T[]): number; concat(...items: ConcatArray<T>[]): T[]; concat(...items: (T | ConcatArray<T>)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter<S extends T>(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; }
>{ ...p2 } : { [n: number]: T; length: number; toString(): string; toLocaleString(): string; pop(): T; push(...items: T[]): number; concat(...items: ConcatArray<T>[]): T[]; concat(...items: (T | ConcatArray<T>)[]): T[]; join(separator?: string): string; reverse(): T[]; shift(): T; slice(start?: number, end?: number): T[]; sort(compareFn?: (a: T, b: T) => number): T[]; splice(start: number, deleteCount?: number): T[]; splice(start: number, deleteCount: number, ...items: T[]): T[]; unshift(...items: T[]): number; indexOf(searchElement: T, fromIndex?: number): number; lastIndexOf(searchElement: T, fromIndex?: number): number; every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; filter<S extends T>(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T; reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T; reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U; }
>p2 : T[]
var o3 = { ...t }; // Error, generic type paramter
@@ -0,0 +1,13 @@
type Style = StyleBase | StyleArray;
interface StyleArray extends Array<Style> {}
interface StyleBase {
foo: string;
}
const blah: Style = [
[[{
foo: 'asdf',
jj: 1 // intentional error
}]]
];
@@ -11,3 +11,13 @@ function f() {
/** @type {{ prop: string }} */
var g = function (prop) {
}
/** @type {(a: number) => number} */
function add1(a, b) { return a + b; }
/** @type {(a: number, b: number) => number} */
function add2(a, b) { return a + b; }
// TODO: Should be an error since signature doesn't match.
/** @type {(a: number, b: number, c: number) => number} */
function add3(a, b) { return a + b; }
@@ -22,6 +22,20 @@
////for (let x = 0; false; ++x) {
//// a;
////}
////
////while (true) {
//// 1;
//// break;
//// 2;
////}
////
////function f() {
//// if (true) {
//// 1;
//// return;
//// 2;
//// }
////}
verify.codeFixAll({
fixId: "fixUnreachableCode",
@@ -36,5 +50,16 @@ if (false) {
}
`,
while (true) {
1;
break;
}
function f() {
if (true) {
1;
return;
}
}`,
});
@@ -37,6 +37,10 @@
////for (let i = 0, j = 0; ;) {}
////for (const x of []) {}
////for (const y in {}) {}
////
////export type First<T, U> = T;
////export interface ISecond<T, U> { u: U; }
////export const cls = class<T, U> { u: U; };
verify.codeFixAll({
fixId: "unusedIdentifier_delete",
@@ -70,5 +74,9 @@ takesCb((x, y) => { y; });
}
for (; ;) {}
for (const {} of []) {}
for (const {} in {}) {}`,
for (const {} in {}) {}
export type First<T> = T;
export interface ISecond<U> { u: U; }
export const cls = class<U> { u: U; };`,
});
@@ -3,8 +3,4 @@
// @noImplicitAny: true
////function f(new C(100, 3, undefined)
verify.codeFix({
description: "Prefix 'C' with an underscore",
index: 2,
newFileContent: "function f(new _C(100, 3, undefined)",
});
verify.codeFixAvailable([]); // Parse error, so no unused diagnostics
@@ -0,0 +1,44 @@
/// <reference path="fourslash.ts"/>
////const o = {
//// a: {
//// m() {},
//// },
//// b: {
//// m() {},
//// },
////}
verify.navigationTree({
text: "<global>",
kind: "script",
childItems: [
{
text: "o",
kind: "const",
childItems: [
{ text: "m", kind: "method" },
{ text: "m", kind: "method" },
],
},
]
});
verify.navigationBar([
{
text: "<global>",
kind: "script",
childItems: [
{ text: "o", kind: "const" },
],
},
{
text: "o",
kind: "const",
childItems: [
{ text: "m", kind: "method" },
{ text: "m", kind: "method" },
],
indent: 1,
},
]);
@@ -0,0 +1,7 @@
/// <reference path='fourslash.ts' />
// @Filename: /a.ts
////export {};
////const a = 1 d;
verify.getSuggestionDiagnostics([]);
@@ -0,0 +1,20 @@
/// <reference path='fourslash.ts' />
// @Filename: /a.tsx
////const x = () /*a*/=>/*b*/
//// <div>:</div>
// This code with this exact indent level used to crash in `indentMultilineCommentOrJsxText`.
goTo.select("a", "b");
edit.applyRefactor({
refactorName: "Add or remove braces in an arrow function",
actionName: "Add braces to arrow function",
actionDescription: "Add braces to arrow function",
newContent:
`const x = () =>
{
return <div>:</div>;
}`,
});
@@ -0,0 +1,13 @@
/// <reference path='fourslash.ts'/>
//// function foo() {
//// if (true) {
//// {| "indentation": 8|}
//// return;
//// {| "indentation": 8|}
//// }
//// }
for (const marker of test.markers()) {
verify.indentationAtPositionIs(marker.fileName, marker.position, marker.data.indentation);
}
@@ -0,0 +1,3 @@
{
"hello": "world"
}
@@ -0,0 +1,3 @@
import hello from "./hello.json"
export default hello.hello
@@ -0,0 +1,15 @@
{
"compilerOptions": {
"composite": true,
"target": "esnext",
"moduleResolution": "node",
"module": "commonjs",
"resolveJsonModule": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"outDir": "dist"
},
"files": [
"src/index.ts", "src/hello.json"
]
}
@@ -0,0 +1,15 @@
{
"compilerOptions": {
"composite": true,
"target": "esnext",
"moduleResolution": "node",
"module": "commonjs",
"resolveJsonModule": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"outDir": "dist"
},
"include": [
"src/**/*"
]
}
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"composite": true,
"target": "esnext",
"moduleResolution": "node",
"module": "commonjs",
"resolveJsonModule": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"outDir": "dist"
},
"files": [
"src/hello.json"
],
"include": [
"src/**/*"
]
}