Merge branch 'master' into tsserverVS-WIP

This commit is contained in:
Vladimir Matveev 2016-06-07 11:27:18 -07:00
commit c84aef39d1
73 changed files with 1042 additions and 292 deletions

View file

@ -210,7 +210,7 @@ var librarySourceMap = [
{ target: "lib.es2015.d.ts", sources: ["header.d.ts", "es2015.d.ts"] },
{ target: "lib.es2016.d.ts", sources: ["header.d.ts", "es2016.d.ts"] },
{ target: "lib.es2017.d.ts", sources: ["header.d.ts", "es2017.d.ts"] },
// JavaScript + all host library
{ target: "lib.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(hostsLibrarySources) },
{ target: "lib.es6.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts") }
@ -523,7 +523,7 @@ compileFile(servicesFileInBrowserTest, servicesSources,[builtLocalDirectory, cop
var i = content.lastIndexOf("\n");
fs.writeFileSync(servicesFileInBrowserTest, content.substring(0, i) + "\r\n//# sourceURL=../built/local/typeScriptServices.js" + content.substring(i));
});
var serverFile = path.join(builtLocalDirectory, "tsserver.js");
compileFile(serverFile, serverSources,[builtLocalDirectory, copyright].concat(serverSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true);
@ -743,10 +743,10 @@ function runConsoleTests(defaultReporter, runInParallel) {
}, function(e, status) {
finish(status);
});
}
else {
// run task to load all tests and partition them between workers
// run task to load all tests and partition them between workers
var cmd = "mocha " + " -R min " + colors + run;
console.log(cmd);
exec(cmd, function() {
@ -759,9 +759,9 @@ function runConsoleTests(defaultReporter, runInParallel) {
var configPath = path.join(taskConfigsFolder, f);
var workerCmd = "mocha" + " -t " + testTimeout + " -R " + reporter + " " + colors + " " + run + " --config='" + configPath + "'";
console.log(workerCmd);
exec(workerCmd, finishWorker, finishWorker)
exec(workerCmd, finishWorker, finishWorker)
});
function finishWorker(e, errorStatus) {
counter--;
if (firstErrorStatus === undefined && errorStatus !== undefined) {
@ -785,11 +785,11 @@ function runConsoleTests(defaultReporter, runInParallel) {
}
});
}
function failWithStatus(status) {
fail("Process exited with code " + status);
}
function finish(errorStatus) {
deleteTemporaryProjectOutput();
if (errorStatus !== undefined) {
@ -857,7 +857,7 @@ task("runtests-browser", ["tests", "browserify", builtLocalDirectory, servicesFi
}
tests = tests ? tests : '';
var cmd = host + " tests/webTestServer.js " + port + " " + browser + " " + tests;
var cmd = host + " tests/webTestServer.js " + port + " " + browser + " " + JSON.stringify(tests);
console.log(cmd);
exec(cmd);
}, {async: true});

View file

@ -8091,13 +8091,22 @@ namespace ts {
return expression;
}
function getControlFlowContainer(node: Node): Node {
while (true) {
node = node.parent;
if (isFunctionLike(node) || node.kind === SyntaxKind.ModuleBlock || node.kind === SyntaxKind.SourceFile || node.kind === SyntaxKind.PropertyDeclaration) {
return node;
}
}
}
function isDeclarationIncludedInFlow(reference: Node, declaration: Declaration, includeOuterFunctions: boolean) {
const declarationContainer = getContainingFunctionOrModule(declaration);
let container = getContainingFunctionOrModule(reference);
const declarationContainer = getControlFlowContainer(declaration);
let container = getControlFlowContainer(reference);
while (container !== declarationContainer &&
(container.kind === SyntaxKind.FunctionExpression || container.kind === SyntaxKind.ArrowFunction) &&
(includeOuterFunctions || getImmediatelyInvokedFunctionExpression(<FunctionExpression>container))) {
container = getContainingFunctionOrModule(container);
container = getControlFlowContainer(container);
}
return container === declarationContainer;
}
@ -9991,24 +10000,14 @@ namespace ts {
}
const propType = getTypeOfSymbol(prop);
// Only compute control flow type if this is a property access expression that isn't an
// assignment target, and the referenced property was declared as a variable, property,
// accessor, or optional method.
if (node.kind !== SyntaxKind.PropertyAccessExpression || isAssignmentTarget(node) ||
!(propType.flags & TypeFlags.Union) && !(prop.flags & (SymbolFlags.Variable | SymbolFlags.Property | SymbolFlags.Accessor))) {
!(prop.flags & (SymbolFlags.Variable | SymbolFlags.Property | SymbolFlags.Accessor)) &&
!(prop.flags & SymbolFlags.Method && propType.flags & TypeFlags.Union)) {
return propType;
}
const leftmostNode = getLeftmostIdentifierOrThis(node);
if (!leftmostNode) {
return propType;
}
if (leftmostNode.kind === SyntaxKind.Identifier) {
const leftmostSymbol = getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(<Identifier>leftmostNode));
if (!leftmostSymbol) {
return propType;
}
const declaration = leftmostSymbol.valueDeclaration;
if (!declaration || declaration.kind !== SyntaxKind.VariableDeclaration && declaration.kind !== SyntaxKind.Parameter && declaration.kind !== SyntaxKind.BindingElement) {
return propType;
}
}
return getFlowTypeOfReference(node, propType, /*assumeInitialized*/ true, /*includeOuterFunctions*/ false);
}
@ -10323,8 +10322,8 @@ namespace ts {
return -1;
}
function hasCorrectArity(node: CallLikeExpression, args: Expression[], signature: Signature) {
let adjustedArgCount: number; // Apparent number of arguments we will have in this call
function hasCorrectArity(node: CallLikeExpression, args: Expression[], signature: Signature, signatureHelpTrailingComma = false) {
let argCount: number; // Apparent number of arguments we will have in this call
let typeArguments: NodeArray<TypeNode>; // Type arguments (undefined if none)
let callIsIncomplete: boolean; // In incomplete call we want to be lenient when we have too few arguments
let isDecorator: boolean;
@ -10335,7 +10334,7 @@ namespace ts {
// Even if the call is incomplete, we'll have a missing expression as our last argument,
// so we can say the count is just the arg list length
adjustedArgCount = args.length;
argCount = args.length;
typeArguments = undefined;
if (tagExpression.template.kind === SyntaxKind.TemplateExpression) {
@ -10358,7 +10357,7 @@ namespace ts {
else if (node.kind === SyntaxKind.Decorator) {
isDecorator = true;
typeArguments = undefined;
adjustedArgCount = getEffectiveArgumentCount(node, /*args*/ undefined, signature);
argCount = getEffectiveArgumentCount(node, /*args*/ undefined, signature);
}
else {
const callExpression = <CallExpression>node;
@ -10369,8 +10368,7 @@ namespace ts {
return signature.minArgumentCount === 0;
}
// For IDE scenarios we may have an incomplete call, so a trailing comma is tantamount to adding another argument.
adjustedArgCount = callExpression.arguments.hasTrailingComma ? args.length + 1 : args.length;
argCount = signatureHelpTrailingComma ? args.length + 1 : args.length;
// If we are missing the close paren, the call is incomplete.
callIsIncomplete = (<CallExpression>callExpression).arguments.end === callExpression.end;
@ -10394,12 +10392,12 @@ namespace ts {
}
// Too many arguments implies incorrect arity.
if (!signature.hasRestParameter && adjustedArgCount > signature.parameters.length) {
if (!signature.hasRestParameter && argCount > signature.parameters.length) {
return false;
}
// If the call is incomplete, we should skip the lower bound check.
const hasEnoughArguments = adjustedArgCount >= signature.minArgumentCount;
const hasEnoughArguments = argCount >= signature.minArgumentCount;
return callIsIncomplete || hasEnoughArguments;
}
@ -10971,6 +10969,11 @@ namespace ts {
let resultOfFailedInference: InferenceContext;
let result: Signature;
// If we are in signature help, a trailing comma indicates that we intend to provide another argument,
// so we will only accept overloads with arity at least 1 higher than the current number of provided arguments.
const signatureHelpTrailingComma =
candidatesOutArray && node.kind === SyntaxKind.CallExpression && (<CallExpression>node).arguments.hasTrailingComma;
// Section 4.12.1:
// if the candidate list contains one or more signatures for which the type of each argument
// expression is a subtype of each corresponding parameter type, the return type of the first
@ -10982,14 +10985,14 @@ namespace ts {
// is just important for choosing the best signature. So in the case where there is only one
// signature, the subtype pass is useless. So skipping it is an optimization.
if (candidates.length > 1) {
result = chooseOverload(candidates, subtypeRelation);
result = chooseOverload(candidates, subtypeRelation, signatureHelpTrailingComma);
}
if (!result) {
// Reinitialize these pointers for round two
candidateForArgumentError = undefined;
candidateForTypeArgumentError = undefined;
resultOfFailedInference = undefined;
result = chooseOverload(candidates, assignableRelation);
result = chooseOverload(candidates, assignableRelation, signatureHelpTrailingComma);
}
if (result) {
return result;
@ -11060,9 +11063,9 @@ namespace ts {
diagnostics.add(createDiagnosticForNodeFromMessageChain(node, errorInfo));
}
function chooseOverload(candidates: Signature[], relation: Map<RelationComparisonResult>) {
function chooseOverload(candidates: Signature[], relation: Map<RelationComparisonResult>, signatureHelpTrailingComma = false) {
for (const originalCandidate of candidates) {
if (!hasCorrectArity(node, args, originalCandidate)) {
if (!hasCorrectArity(node, args, originalCandidate, signatureHelpTrailingComma)) {
continue;
}
@ -11279,7 +11282,7 @@ namespace ts {
const declaringClassDeclaration = <ClassLikeDeclaration>getClassLikeDeclarationOfSymbol(declaration.parent.symbol);
const declaringClass = <InterfaceType>getDeclaredTypeOfSymbol(declaration.parent.symbol);
// A private or protected constructor can only be instantiated within it's own class
// A private or protected constructor can only be instantiated within it's own class
if (!isNodeWithinClass(node, declaringClassDeclaration)) {
if (flags & NodeFlags.Private) {
error(node, Diagnostics.Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration, typeToString(declaringClass));
@ -15107,7 +15110,7 @@ namespace ts {
// In a 'switch' statement, each 'case' expression must be of a type that is comparable
// to or from the type of the 'switch' expression.
const caseType = checkExpression(caseClause.expression);
if (!isTypeComparableTo(expressionType, caseType)) {
if (!isTypeEqualityComparableTo(expressionType, caseType)) {
// expressionType is not comparable to caseType, try the reversed check and report errors if it fails
checkTypeComparableTo(caseType, expressionType, caseClause.expression, /*headMessage*/ undefined);
}
@ -16142,12 +16145,12 @@ namespace ts {
const symbol = getSymbolOfNode(node);
const target = resolveAlias(symbol);
if (target !== unknownSymbol) {
// For external modules symbol represent local symbol for an alias.
// For external modules symbol represent local symbol for an alias.
// This local symbol will merge any other local declarations (excluding other aliases)
// and symbol.flags will contains combined representation for all merged declaration.
// Based on symbol.flags we can compute a set of excluded meanings (meaning that resolved alias should not have,
// otherwise it will conflict with some local declaration). Note that in addition to normal flags we include matching SymbolFlags.Export*
// in order to prevent collisions with declarations that were exported from the current module (they still contribute to local names).
// otherwise it will conflict with some local declaration). Note that in addition to normal flags we include matching SymbolFlags.Export*
// in order to prevent collisions with declarations that were exported from the current module (they still contribute to local names).
const excludedMeanings =
(symbol.flags & (SymbolFlags.Value | SymbolFlags.ExportValue) ? SymbolFlags.Value : 0) |
(symbol.flags & SymbolFlags.Type ? SymbolFlags.Type : 0) |
@ -16346,7 +16349,7 @@ namespace ts {
continue;
}
const { declarations, flags } = exports[id];
// ECMA262: 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries.
// ECMA262: 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries.
// (TS Exceptions: namespaces, function overloads, enums, and interfaces)
if (flags & (SymbolFlags.Namespace | SymbolFlags.Interface | SymbolFlags.Enum)) {
continue;
@ -17051,10 +17054,10 @@ namespace ts {
}
// Gets the type of object literal or array literal of destructuring assignment.
// { a } from
// { a } from
// for ( { a } of elems) {
// }
// [ a ] from
// [ a ] from
// [a] = [ some array ...]
function getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(expr: Expression): Type {
Debug.assert(expr.kind === SyntaxKind.ObjectLiteralExpression || expr.kind === SyntaxKind.ArrayLiteralExpression);
@ -17087,10 +17090,10 @@ namespace ts {
}
// Gets the property symbol corresponding to the property in destructuring assignment
// 'property1' from
// 'property1' from
// for ( { property1: a } of elems) {
// }
// 'property1' at location 'a' from:
// 'property1' at location 'a' from:
// [a] = [ property1, property2 ]
function getPropertySymbolOfDestructuringAssignment(location: Identifier) {
// Get the type of the object or array literal and then look for property of given name in the type
@ -18029,10 +18032,6 @@ namespace ts {
}
function checkGrammarParameterList(parameters: NodeArray<ParameterDeclaration>) {
if (checkGrammarForDisallowedTrailingComma(parameters)) {
return true;
}
let seenOptionalParameter = false;
const parameterCount = parameters.length;
@ -18151,8 +18150,7 @@ namespace ts {
}
function checkGrammarArguments(node: CallExpression, args: NodeArray<Expression>): boolean {
return checkGrammarForDisallowedTrailingComma(args) ||
checkGrammarForOmittedArgument(node, args);
return checkGrammarForOmittedArgument(node, args);
}
function checkGrammarHeritageClause(node: HeritageClause): boolean {

View file

@ -95,7 +95,7 @@ namespace ts {
// Emit reference in dts, if the file reference was not already emitted
if (referencedFile && !contains(emittedReferencedFiles, referencedFile)) {
// Add a reference to generated dts file,
// global file reference is added only
// global file reference is added only
// - if it is not bundled emit (because otherwise it would be self reference)
// - and it is not already added
if (writeReferencePath(referencedFile, !isBundledEmit && !addedGlobalFileReference)) {
@ -148,7 +148,7 @@ namespace ts {
if (!isBundledEmit && isExternalModule(sourceFile) && sourceFile.moduleAugmentations.length && !resultHasExternalModuleIndicator) {
// if file was external module with augmentations - this fact should be preserved in .d.ts as well.
// in case if we didn't write any external module specifiers in .d.ts we need to emit something
// in case if we didn't write any external module specifiers in .d.ts we need to emit something
// that will force compiler to think that this file is an external module - 'export {}' is a reasonable choice here.
write("export {};");
writeLine();
@ -766,7 +766,7 @@ namespace ts {
function emitExternalModuleSpecifier(parent: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration) {
// emitExternalModuleSpecifier is usually called when we emit something in the.d.ts file that will make it an external module (i.e. import/export declarations).
// the only case when it is not true is when we call it to emit correct name for module augmentation - d.ts files with just module augmentations are not considered
// the only case when it is not true is when we call it to emit correct name for module augmentation - d.ts files with just module augmentations are not considered
// external modules since they are indistinguishable from script files with ambient modules. To fix this in such d.ts files we'll emit top level 'export {}'
// so compiler will treat them as external modules.
resultHasExternalModuleIndicator = resultHasExternalModuleIndicator || parent.kind !== SyntaxKind.ModuleDeclaration;

View file

@ -168,7 +168,7 @@ namespace ts {
sourceMapData.sourceMapDecodedMappings[sourceMapData.sourceMapDecodedMappings.length - 1] :
defaultLastEncodedSourceMapSpan;
// TODO: Update lastEncodedNameIndex
// TODO: Update lastEncodedNameIndex
// Since we dont support this any more, lets not worry about it right now.
// When we start supporting nameIndex, we will get back to this

View file

@ -2218,7 +2218,10 @@ namespace ts {
ObjectType = Class | Interface | Reference | Tuple | Anonymous,
UnionOrIntersection = Union | Intersection,
StructuredType = ObjectType | Union | Intersection,
Narrowable = Any | ObjectType | Union | TypeParameter,
// 'Narrowable' types are types where narrowing actually narrows.
// This *should* be every type other than null, undefined, void, and never
Narrowable = Any | StructuredType | TypeParameter | StringLike | NumberLike | Boolean | ESSymbol,
/* @internal */
RequiresWidening = ContainsWideningType | ContainsObjectLiteral,
/* @internal */

View file

@ -302,8 +302,8 @@ namespace ts {
return getTokenPosOfNode(node.jsDocComments[0]);
}
// For a syntax list, it is possible that one of its children has JSDocComment nodes, while
// the syntax list itself considers them as normal trivia. Therefore if we simply skip
// For a syntax list, it is possible that one of its children has JSDocComment nodes, while
// the syntax list itself considers them as normal trivia. Therefore if we simply skip
// trivia for the list, we may have skipped the JSDocComment as well. So we should process its
// first child to determine the actual position of its first token.
if (node.kind === SyntaxKind.SyntaxList && (<SyntaxList>node)._children.length > 0) {
@ -880,15 +880,6 @@ namespace ts {
}
}
export function getContainingFunctionOrModule(node: Node): Node {
while (true) {
node = node.parent;
if (isFunctionLike(node) || node.kind === SyntaxKind.ModuleDeclaration || node.kind === SyntaxKind.SourceFile) {
return node;
}
}
}
export function getContainingClass(node: Node): ClassLikeDeclaration {
while (true) {
node = node.parent;

View file

@ -154,7 +154,7 @@ class CompilerBaselineRunner extends RunnerBase {
it (`Correct module resolution tracing for ${fileName}`, () => {
if (options.traceResolution) {
Harness.Baseline.runBaseline("Correct sourcemap content for " + fileName, justName.replace(/\.tsx?$/, ".trace.json"), () => {
Harness.Baseline.runBaseline("Correct module resolution tracing for " + fileName, justName.replace(/\.tsx?$/, ".trace.json"), () => {
return JSON.stringify(result.traceResults || [], undefined, 4);
});
}

View file

@ -746,7 +746,7 @@ namespace FourSlash {
}
const missingItem = { fileName: fileName, start: start, end: end, isWriteAccess: isWriteAccess };
this.raiseError(`verifyReferencesAtPositionListContains failed - could not find the item: ${JSON.stringify(missingItem, undefined, 2)} in the returned list: (${JSON.stringify(references, undefined, 2)})`);
this.raiseError(`verifyReferencesAtPositionListContains failed - could not find the item: ${stringify(missingItem)} in the returned list: (${stringify(references)})`);
}
public verifyReferencesCountIs(count: number, localFilesOnly = true) {
@ -800,7 +800,7 @@ namespace FourSlash {
private testDiagnostics(expected: string, diagnostics: ts.Diagnostic[]) {
const realized = ts.realizeDiagnostics(diagnostics, "\r\n");
const actual = JSON.stringify(realized, undefined, 2);
const actual = stringify(realized);
assert.equal(actual, expected);
}
@ -875,7 +875,7 @@ namespace FourSlash {
}
if (ranges.length !== references.length) {
this.raiseError("Rename location count does not match result.\n\nExpected: " + JSON.stringify(ranges, undefined, 2) + "\n\nActual:" + JSON.stringify(references, undefined, 2));
this.raiseError("Rename location count does not match result.\n\nExpected: " + stringify(ranges) + "\n\nActual:" + stringify(references));
}
ranges = ranges.sort((r1, r2) => r1.start - r2.start);
@ -888,7 +888,7 @@ namespace FourSlash {
if (reference.textSpan.start !== range.start ||
ts.textSpanEnd(reference.textSpan) !== range.end) {
this.raiseError("Rename location results do not match.\n\nExpected: " + JSON.stringify(ranges, undefined, 2) + "\n\nActual:" + JSON.stringify(references, undefined, 2));
this.raiseError("Rename location results do not match.\n\nExpected: " + stringify(ranges) + "\n\nActual:" + JSON.stringify(references));
}
}
}
@ -972,7 +972,7 @@ namespace FourSlash {
}
else {
if (actual) {
this.raiseError(`Expected no signature help, but got "${JSON.stringify(actual, undefined, 2)}"`);
this.raiseError(`Expected no signature help, but got "${stringify(actual)}"`);
}
}
}
@ -1176,7 +1176,7 @@ namespace FourSlash {
public printCurrentParameterHelp() {
const help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition);
Harness.IO.log(JSON.stringify(help, undefined, 2));
Harness.IO.log(stringify(help));
}
public printCurrentQuickInfo() {
@ -1218,7 +1218,7 @@ namespace FourSlash {
public printCurrentSignatureHelp() {
const sigHelp = this.getActiveSignatureHelpItem();
Harness.IO.log(JSON.stringify(sigHelp, undefined, 2));
Harness.IO.log(stringify(sigHelp));
}
public printMemberListMembers() {
@ -1248,7 +1248,7 @@ namespace FourSlash {
public printReferences() {
const references = this.getReferencesAtCaret();
ts.forEach(references, entry => {
Harness.IO.log(JSON.stringify(entry, undefined, 2));
Harness.IO.log(stringify(entry));
});
}
@ -1745,8 +1745,8 @@ namespace FourSlash {
function jsonMismatchString() {
return Harness.IO.newLine() +
"expected: '" + Harness.IO.newLine() + JSON.stringify(expected, undefined, 2) + "'" + Harness.IO.newLine() +
"actual: '" + Harness.IO.newLine() + JSON.stringify(actual, undefined, 2) + "'";
"expected: '" + Harness.IO.newLine() + stringify(expected) + "'" + Harness.IO.newLine() +
"actual: '" + Harness.IO.newLine() + stringify(actual) + "'";
}
}
@ -1961,14 +1961,14 @@ namespace FourSlash {
// if there was an explicit match kind specified, then it should be validated.
if (matchKind !== undefined) {
const missingItem = { name: name, kind: kind, searchValue: searchValue, matchKind: matchKind, fileName: fileName, parentName: parentName };
this.raiseError(`verifyNavigationItemsListContains failed - could not find the item: ${JSON.stringify(missingItem, undefined, 2)} in the returned list: (${JSON.stringify(items, undefined, 2)})`);
this.raiseError(`verifyNavigationItemsListContains failed - could not find the item: ${stringify(missingItem)} in the returned list: (${stringify(items)})`);
}
}
public verifyNavigationBar(json: any) {
const items = this.languageService.getNavigationBarItems(this.activeFile.fileName);
if (JSON.stringify(items, replacer) !== JSON.stringify(json)) {
this.raiseError(`verifyNavigationBar failed - expected: ${JSON.stringify(json, undefined, 2)}, got: ${JSON.stringify(items, replacer, 2)}`);
this.raiseError(`verifyNavigationBar failed - expected: ${stringify(json)}, got: ${stringify(items, replacer)}`);
}
// Make the data easier to read.
@ -2031,7 +2031,7 @@ namespace FourSlash {
}
const missingItem = { fileName: fileName, start: start, end: end, isWriteAccess: isWriteAccess };
this.raiseError(`verifyOccurrencesAtPositionListContains failed - could not find the item: ${JSON.stringify(missingItem, undefined, 2)} in the returned list: (${JSON.stringify(occurrences, undefined, 2)})`);
this.raiseError(`verifyOccurrencesAtPositionListContains failed - could not find the item: ${stringify(missingItem)} in the returned list: (${stringify(occurrences)})`);
}
public verifyOccurrencesAtPositionListCount(expectedCount: number) {
@ -2070,7 +2070,7 @@ namespace FourSlash {
}
const missingItem = { fileName: fileName, start: start, end: end, kind: kind };
this.raiseError(`verifyDocumentHighlightsAtPositionListContains failed - could not find the item: ${JSON.stringify(missingItem, undefined, 2)} in the returned list: (${JSON.stringify(documentHighlights, undefined, 2)})`);
this.raiseError(`verifyDocumentHighlightsAtPositionListContains failed - could not find the item: ${stringify(missingItem)} in the returned list: (${stringify(documentHighlights)})`);
}
public verifyDocumentHighlightsAtPositionListCount(expectedCount: number, fileNamesToSearch: string[]) {
@ -2136,9 +2136,9 @@ namespace FourSlash {
}
}
const itemsString = items.map((item) => JSON.stringify({ name: item.name, kind: item.kind }, undefined, 2)).join(",\n");
const itemsString = items.map(item => stringify({ name: item.name, kind: item.kind })).join(",\n");
this.raiseError(`Expected "${JSON.stringify({ name, text, documentation, kind }, undefined, 2)}" to be in list [${itemsString}]`);
this.raiseError(`Expected "${stringify({ name, text, documentation, kind })}" to be in list [${itemsString}]`);
}
private findFile(indexOrName: any) {
@ -2701,6 +2701,10 @@ ${code}
}
return result;
}
function stringify(data: any, replacer?: (key: string, value: any) => any): string {
return JSON.stringify(data, replacer, 2);
}
}
namespace FourSlashInterface {

View file

@ -244,7 +244,7 @@ class ProjectRunner extends RunnerBase {
mapRoot: testCase.resolveMapRoot && testCase.mapRoot ? Harness.IO.resolvePath(testCase.mapRoot) : testCase.mapRoot,
sourceRoot: testCase.resolveSourceRoot && testCase.sourceRoot ? Harness.IO.resolvePath(testCase.sourceRoot) : testCase.sourceRoot,
module: moduleKind,
moduleResolution: ts.ModuleResolutionKind.Classic, // currently all tests use classic module resolution kind, this will change in the future
moduleResolution: ts.ModuleResolutionKind.Classic, // currently all tests use classic module resolution kind, this will change in the future
};
// Set the values specified using json
const optionNameMap: ts.Map<ts.CommandLineOption> = {};

View file

@ -24,7 +24,7 @@ abstract class RunnerBase {
abstract enumerateTestFiles(): string[];
/** Setup the runner's tests so that they are ready to be executed by the harness
/** Setup the runner's tests so that they are ready to be executed by the harness
* The first test should be a describe/it block that sets up the harness's compiler instance appropriately
*/
public abstract initializeTests(): void;

14
src/lib/es5.d.ts vendored
View file

@ -136,12 +136,24 @@ interface ObjectConstructor {
*/
getOwnPropertyNames(o: any): string[];
/**
* Creates an object that has null prototype.
* @param o Object to use as a prototype. May be null
*/
create(o: null): any;
/**
* Creates an object that has the specified prototype, and that optionally contains specified properties.
* @param o Object to use as a prototype. May be null
*/
create<T>(o: T): T;
/**
* Creates an object that has the specified prototype, and that optionally contains specified properties.
* @param o Object to use as a prototype. May be null
* @param properties JavaScript object that contains one or more property descriptors.
*/
create(o: any, properties?: PropertyDescriptorMap): any;
create(o: any, properties: PropertyDescriptorMap): any;
/**
* Adds a property to an object, or modifies attributes of an existing property.

View file

@ -459,7 +459,7 @@ namespace ts.server {
kindModifiers: item.kindModifiers || "",
spans: item.spans.map(span => createTextSpanFromBounds(this.lineOffsetToPosition(fileName, span.start), this.lineOffsetToPosition(fileName, span.end))),
childItems: this.decodeNavigationBarItems(item.childItems, fileName),
indent: 0,
indent: item.indent,
bolded: false,
grayed: false
}));

View file

@ -1263,6 +1263,11 @@ declare namespace ts.server.protocol {
* Optional children.
*/
childItems?: NavigationBarItem[];
/**
* Number of levels deep this item should appear.
*/
indent: number;
}
export interface NavBarResponse extends Response {

View file

@ -879,7 +879,8 @@ namespace ts.server {
start: scriptInfo.positionToLineOffset(span.start),
end: scriptInfo.positionToLineOffset(ts.textSpanEnd(span))
})),
childItems: this.decorateNavigationBarItem(project, fileName, item.childItems)
childItems: this.decorateNavigationBarItem(project, fileName, item.childItems),
indent: item.indent
}));
}

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved. Licensed under the Apache License, Version 2.0.
// Copyright (c) Microsoft. All rights reserved. Licensed under the Apache License, Version 2.0.
// See LICENSE.txt in the project root for complete license information.
/// <reference path='services.ts' />
@ -19,8 +19,8 @@ namespace ts.BreakpointResolver {
if (sourceFile.getLineAndCharacterOfPosition(tokenAtLocation.getStart(sourceFile)).line > lineOfPosition) {
// Get previous token if the token is returned starts on new line
// eg: let x =10; |--- cursor is here
// let y = 10;
// token at position will return let keyword on second line as the token but we would like to use
// let y = 10;
// token at position will return let keyword on second line as the token but we would like to use
// token on same line if trailing trivia (comments or white spaces on same line) part of the last token on that line
tokenAtLocation = findPrecedingToken(tokenAtLocation.pos, sourceFile);
@ -261,7 +261,7 @@ namespace ts.BreakpointResolver {
}
// Set breakpoint on identifier element of destructuring pattern
// a or ...c or d: x from
// a or ...c or d: x from
// [a, b, ...c] or { a, b } or { d: x } from destructuring pattern
if ((node.kind === SyntaxKind.Identifier ||
node.kind == SyntaxKind.SpreadElementExpression ||
@ -275,7 +275,7 @@ namespace ts.BreakpointResolver {
const binaryExpression = <BinaryExpression>node;
// Set breakpoint in destructuring pattern if its destructuring assignment
// [a, b, c] or {a, b, c} of
// [a, b, c] = expression or
// [a, b, c] = expression or
// {a, b, c} = expression
if (isArrayLiteralOrObjectLiteralDestructuringPattern(binaryExpression.left)) {
return spanInArrayLiteralOrObjectLiteralDestructuringPattern(
@ -285,8 +285,8 @@ namespace ts.BreakpointResolver {
if (binaryExpression.operatorToken.kind === SyntaxKind.EqualsToken &&
isArrayLiteralOrObjectLiteralDestructuringPattern(binaryExpression.parent)) {
// Set breakpoint on assignment expression element of destructuring pattern
// a = expression of
// [a = expression, b, c] = someExpression or
// a = expression of
// [a = expression, b, c] = someExpression or
// { a = expression, b, c } = someExpression
return textSpan(node);
}
@ -403,7 +403,7 @@ namespace ts.BreakpointResolver {
const declarations = variableDeclaration.parent.declarations;
if (declarations && declarations[0] !== variableDeclaration) {
// If we cannot set breakpoint on this declaration, set it on previous one
// Because the variable declaration may be binding pattern and
// Because the variable declaration may be binding pattern and
// we would like to set breakpoint in last binding element if that's the case,
// use preceding token instead
return spanInNode(findPrecedingToken(variableDeclaration.pos, sourceFile, variableDeclaration.parent));
@ -549,7 +549,7 @@ namespace ts.BreakpointResolver {
return spanInNode(firstBindingElement);
}
// Could be ArrayLiteral from destructuring assignment or
// Could be ArrayLiteral from destructuring assignment or
// just nested element in another destructuring assignment
// set breakpoint on assignment when parent is destructuring assignment
// Otherwise set breakpoint for this element

View file

@ -268,9 +268,9 @@ namespace ts.formatting {
return startPos < endPos && current !== SyntaxKind.EndOfFileToken && !isTrivia(current);
}
// when containing node in the tree is token
// when containing node in the tree is token
// but its kind differs from the kind that was returned by the scanner,
// then kind needs to be fixed. This might happen in cases
// then kind needs to be fixed. This might happen in cases
// when parser interprets token differently, i.e keyword treated as identifier
function fixTokenKind(tokenInfo: TokenInfo, container: Node): TokenInfo {
if (isToken(container) && tokenInfo.token.kind !== container.kind) {

View file

@ -554,17 +554,17 @@ namespace ts.formatting {
static IsSameLineTokenOrBeforeMultilineBlockContext(context: FormattingContext): boolean {
//// This check is mainly used inside SpaceBeforeOpenBraceInControl and SpaceBeforeOpenBraceInFunction.
////
//// Ex:
//// Ex:
//// if (1) { ....
//// * ) and { are on the same line so apply the rule. Here we don't care whether it's same or multi block context
////
//// Ex:
//// Ex:
//// if (1)
//// { ... }
//// * ) and { are on different lines. We only need to format if the block is multiline context. So in this case we don't format.
////
//// Ex:
//// if (1)
//// if (1)
//// { ...
//// }
//// * ) and { are on different lines. We only need to format if the block is multiline context. So in this case we format.

View file

@ -95,9 +95,9 @@ namespace ts.formatting {
//// 4- Context rules with any token combination
//// 5- Non-context rules with specific token combination
//// 6- Non-context rules with any token combination
////
////
//// The member rulesInsertionIndexBitmap is used to describe the number of rules
//// in each sub-bucket (above) hence can be used to know the index of where to insert
//// in each sub-bucket (above) hence can be used to know the index of where to insert
//// the next rule. It's a bitmap which contains 6 different sections each is given 5 bits.
////
//// Example:

View file

@ -9,7 +9,7 @@ namespace ts.NavigateTo {
// This means "compare in a case insensitive manner."
const baseSensitivity: Intl.CollatorOptions = { sensitivity: "base" };
// Search the declarations in all files and output matched NavigateToItem into array of NavigateToItem[]
// Search the declarations in all files and output matched NavigateToItem into array of NavigateToItem[]
forEach(program.getSourceFiles(), sourceFile => {
cancellationToken.throwIfCancellationRequested();
@ -17,7 +17,7 @@ namespace ts.NavigateTo {
for (const name in nameToDeclarations) {
const declarations = getProperty(nameToDeclarations, name);
if (declarations) {
// First do a quick check to see if the name of the declaration matches the
// First do a quick check to see if the name of the declaration matches the
// last portion of the (possibly) dotted name they're searching for.
let matches = patternMatcher.getMatchesForLastSegmentOfPattern(name);
@ -26,7 +26,7 @@ namespace ts.NavigateTo {
}
for (const declaration of declarations) {
// It was a match! If the pattern has dots in it, then also see if the
// It was a match! If the pattern has dots in it, then also see if the
// declaration container matches as well.
if (patternMatcher.patternContainsDots) {
const containers = getContainers(declaration);

View file

@ -2657,7 +2657,7 @@ namespace ts {
return false;
}
/**
/**
* Returns the containing object literal property declaration given a possible name node, e.g. "a" in x = { "a": 1 }
*/
function getContainingObjectLiteralElement(node: Node): ObjectLiteralElement {
@ -7606,11 +7606,11 @@ namespace ts {
function isValidBraceCompletionAtPostion(fileName: string, position: number, openingBrace: number): boolean {
// '<' is currently not supported, figuring out if we're in a Generic Type vs. a comparison is too
// '<' is currently not supported, figuring out if we're in a Generic Type vs. a comparison is too
// expensive to do during typing scenarios
// i.e. whether we're dealing with:
// var x = new foo<| ( with class foo<T>{} )
// or
// or
// var y = 3 <|
if (openingBrace === CharacterCodes.lessThan) {
return false;

View file

@ -295,7 +295,7 @@ namespace ts {
constructor(private shimHost: LanguageServiceShimHost) {
// if shimHost is a COM object then property check will become method call with no arguments.
// 'in' does not have this effect.
// 'in' does not have this effect.
if ("getModuleResolutionsForFile" in this.shimHost) {
this.resolveModuleNames = (moduleNames: string[], containingFile: string) => {
const resolutionsInFile = <Map<string>>JSON.parse(this.shimHost.getModuleResolutionsForFile(containingFile));
@ -966,7 +966,7 @@ namespace ts {
return this.forwardJSONCall(
"getPreProcessedFileInfo('" + fileName + "')",
() => {
// for now treat files as JavaScript
// for now treat files as JavaScript
const result = preProcessFile(sourceTextSnapshot.getText(0, sourceTextSnapshot.getLength()), /* readImportFiles */ true, /* detectJavaScriptImports */ true);
return {
referencedFiles: this.convertFileReferences(result.referencedFiles),

View file

@ -3,9 +3,9 @@
namespace ts.SignatureHelp {
// A partially written generic type expression is not guaranteed to have the correct syntax tree. the expression could be parsed as less than/greater than expression or a comma expression
// or some other combination depending on what the user has typed so far. For the purposes of signature help we need to consider any location after "<" as a possible generic type reference.
// To do this, the method will back parse the expression starting at the position required. it will try to parse the current expression as a generic type expression, if it did succeed it
// will return the generic identifier that started the expression (e.g. "foo" in "foo<any, |"). It is then up to the caller to ensure that this is a valid generic expression through
// or some other combination depending on what the user has typed so far. For the purposes of signature help we need to consider any location after "<" as a possible generic type reference.
// To do this, the method will back parse the expression starting at the position required. it will try to parse the current expression as a generic type expression, if it did succeed it
// will return the generic identifier that started the expression (e.g. "foo" in "foo<any, |"). It is then up to the caller to ensure that this is a valid generic expression through
// looking up the type. The method will also keep track of the parameter index inside the expression.
// public static isInPartiallyWrittenTypeArgumentList(syntaxTree: TypeScript.SyntaxTree, position: number): any {
// let token = Syntax.findTokenOnLeft(syntaxTree.sourceUnit(), position, /*includeSkippedTokens*/ true);
@ -202,7 +202,7 @@ namespace ts.SignatureHelp {
cancellationToken.throwIfCancellationRequested();
if (!candidates.length) {
// We didn't have any sig help items produced by the TS compiler. If this is a JS
// We didn't have any sig help items produced by the TS compiler. If this is a JS
// file, then see if we can figure out anything better.
if (isSourceFileJavaScript(sourceFile)) {
return createJavaScriptSignatureHelpItems(argumentInfo);
@ -353,8 +353,8 @@ namespace ts.SignatureHelp {
}
function getArgumentIndex(argumentsList: Node, node: Node) {
// The list we got back can include commas. In the presence of errors it may
// also just have nodes without commas. For example "Foo(a b c)" will have 3
// The list we got back can include commas. In the presence of errors it may
// also just have nodes without commas. For example "Foo(a b c)" will have 3
// args without commas. We want to find what index we're at. So we count
// forward until we hit ourselves, only incrementing the index if it isn't a
// comma.
@ -386,8 +386,8 @@ namespace ts.SignatureHelp {
// 'a' '<comma>'. So, in the case where the last child is a comma, we increase the
// arg count by one to compensate.
//
// Note: this subtlety only applies to the last comma. If you had "Foo(a,," then
// we'll have: 'a' '<comma>' '<missing>'
// Note: this subtlety only applies to the last comma. If you had "Foo(a,," then
// we'll have: 'a' '<comma>' '<missing>'
// That will give us 2 non-commas. We then add one for the last comma, givin us an
// arg count of 3.
const listChildren = argumentsList.getChildren();

View file

@ -1,12 +0,0 @@
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/ArrowFunction2.ts(1,13): error TS2304: Cannot find name 'b'.
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/ArrowFunction2.ts(1,14): error TS1009: Trailing comma not allowed.
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/ArrowFunction2.ts (2 errors) ====
var v = (a: b,) => {
~
!!! error TS2304: Cannot find name 'b'.
~
!!! error TS1009: Trailing comma not allowed.
};

View file

@ -1,8 +0,0 @@
//// [ArrowFunction2.ts]
var v = (a: b,) => {
};
//// [ArrowFunction2.js]
var v = function (a) {
};

View file

@ -0,0 +1,32 @@
//// [classStaticPropertyTypeGuard.ts]
// Repro from #8923
class A {
private static _a: string | undefined;
public get a(): string {
if (A._a) {
return A._a; // is possibly null or undefined.
}
return A._a = 'helloworld';
}
}
//// [classStaticPropertyTypeGuard.js]
// Repro from #8923
var A = (function () {
function A() {
}
Object.defineProperty(A.prototype, "a", {
get: function () {
if (A._a) {
return A._a; // is possibly null or undefined.
}
return A._a = 'helloworld';
},
enumerable: true,
configurable: true
});
return A;
}());

View file

@ -0,0 +1,29 @@
=== tests/cases/compiler/classStaticPropertyTypeGuard.ts ===
// Repro from #8923
class A {
>A : Symbol(A, Decl(classStaticPropertyTypeGuard.ts, 0, 0))
private static _a: string | undefined;
>_a : Symbol(A._a, Decl(classStaticPropertyTypeGuard.ts, 3, 9))
public get a(): string {
>a : Symbol(A.a, Decl(classStaticPropertyTypeGuard.ts, 4, 42))
if (A._a) {
>A._a : Symbol(A._a, Decl(classStaticPropertyTypeGuard.ts, 3, 9))
>A : Symbol(A, Decl(classStaticPropertyTypeGuard.ts, 0, 0))
>_a : Symbol(A._a, Decl(classStaticPropertyTypeGuard.ts, 3, 9))
return A._a; // is possibly null or undefined.
>A._a : Symbol(A._a, Decl(classStaticPropertyTypeGuard.ts, 3, 9))
>A : Symbol(A, Decl(classStaticPropertyTypeGuard.ts, 0, 0))
>_a : Symbol(A._a, Decl(classStaticPropertyTypeGuard.ts, 3, 9))
}
return A._a = 'helloworld';
>A._a : Symbol(A._a, Decl(classStaticPropertyTypeGuard.ts, 3, 9))
>A : Symbol(A, Decl(classStaticPropertyTypeGuard.ts, 0, 0))
>_a : Symbol(A._a, Decl(classStaticPropertyTypeGuard.ts, 3, 9))
}
}

View file

@ -0,0 +1,31 @@
=== tests/cases/compiler/classStaticPropertyTypeGuard.ts ===
// Repro from #8923
class A {
>A : A
private static _a: string | undefined;
>_a : string | undefined
public get a(): string {
>a : string
if (A._a) {
>A._a : string | undefined
>A : typeof A
>_a : string | undefined
return A._a; // is possibly null or undefined.
>A._a : string
>A : typeof A
>_a : string
}
return A._a = 'helloworld';
>A._a = 'helloworld' : string
>A._a : string | undefined
>A : typeof A
>_a : string | undefined
>'helloworld' : string
}
}

View file

@ -0,0 +1,19 @@
//// [controlFlowPropertyInitializer.ts]
// Repro from #8967
const LANG = "Turbo Pascal"
class BestLanguage {
name = LANG;
}
//// [controlFlowPropertyInitializer.js]
// Repro from #8967
var LANG = "Turbo Pascal";
var BestLanguage = (function () {
function BestLanguage() {
this.name = LANG;
}
return BestLanguage;
}());

View file

@ -0,0 +1,14 @@
=== tests/cases/compiler/controlFlowPropertyInitializer.ts ===
// Repro from #8967
const LANG = "Turbo Pascal"
>LANG : Symbol(LANG, Decl(controlFlowPropertyInitializer.ts, 3, 5))
class BestLanguage {
>BestLanguage : Symbol(BestLanguage, Decl(controlFlowPropertyInitializer.ts, 3, 27))
name = LANG;
>name : Symbol(BestLanguage.name, Decl(controlFlowPropertyInitializer.ts, 5, 20))
>LANG : Symbol(LANG, Decl(controlFlowPropertyInitializer.ts, 3, 5))
}

View file

@ -0,0 +1,15 @@
=== tests/cases/compiler/controlFlowPropertyInitializer.ts ===
// Repro from #8967
const LANG = "Turbo Pascal"
>LANG : string
>"Turbo Pascal" : string
class BestLanguage {
>BestLanguage : BestLanguage
name = LANG;
>name : string
>LANG : string
}

View file

@ -81,4 +81,14 @@ tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.t
!!! error TS2365: Operator '<=' cannot be applied to types 'number' and 'undefined'.
}
}
function f5(x: string) {
switch(x) {
case null:
break;
case undefined:
break;
default:
return;
}
}

View file

@ -67,6 +67,16 @@ function f4(x: number) {
if (x <= undefined) {
}
}
function f5(x: string) {
switch(x) {
case null:
break;
case undefined:
break;
default:
return;
}
}
//// [equalityStrictNulls.js]
@ -134,3 +144,13 @@ function f4(x) {
if (x <= undefined) {
}
}
function f5(x) {
switch (x) {
case null:
break;
case undefined:
break;
default:
return;
}
}

View file

@ -1,16 +0,0 @@
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList5.ts(2,4): error TS2304: Cannot find name 'bar'.
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList5.ts(2,8): error TS2304: Cannot find name 'a'.
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList5.ts(2,9): error TS1009: Trailing comma not allowed.
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArgumentLists/parserErrorRecovery_ArgumentList5.ts (3 errors) ====
function foo() {
bar(a,)
~~~
!!! error TS2304: Cannot find name 'bar'.
~
!!! error TS2304: Cannot find name 'a'.
~
!!! error TS1009: Trailing comma not allowed.
return;
}

View file

@ -1,11 +0,0 @@
//// [parserErrorRecovery_ArgumentList5.ts]
function foo() {
bar(a,)
return;
}
//// [parserErrorRecovery_ArgumentList5.js]
function foo() {
bar(a);
return;
}

View file

@ -1,8 +0,0 @@
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList3.ts(1,13): error TS1009: Trailing comma not allowed.
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ParameterLists/parserErrorRecovery_ParameterList3.ts (1 errors) ====
function f(a,) {
~
!!! error TS1009: Trailing comma not allowed.
}

View file

@ -1,7 +0,0 @@
//// [parserErrorRecovery_ParameterList3.ts]
function f(a,) {
}
//// [parserErrorRecovery_ParameterList3.js]
function f(a) {
}

View file

@ -1,8 +0,0 @@
tests/cases/conformance/parser/ecmascript5/ParameterLists/parserParameterList12.ts(1,13): error TS1009: Trailing comma not allowed.
==== tests/cases/conformance/parser/ecmascript5/ParameterLists/parserParameterList12.ts (1 errors) ====
function F(a,) {
~
!!! error TS1009: Trailing comma not allowed.
}

View file

@ -0,0 +1,5 @@
=== tests/cases/conformance/parser/ecmascript5/ParameterLists/parserParameterList12.ts ===
function F(a,) {
>F : Symbol(F, Decl(parserParameterList12.ts, 0, 0))
>a : Symbol(a, Decl(parserParameterList12.ts, 0, 11))
}

View file

@ -0,0 +1,5 @@
=== tests/cases/conformance/parser/ecmascript5/ParameterLists/parserParameterList12.ts ===
function F(a,) {
>F : (a: any) => void
>a : any
}

View file

@ -1,12 +0,0 @@
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/parserX_ArrowFunction2.ts(1,13): error TS2304: Cannot find name 'b'.
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/parserX_ArrowFunction2.ts(1,14): error TS1009: Trailing comma not allowed.
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ArrowFunctions/parserX_ArrowFunction2.ts (2 errors) ====
var v = (a: b,) => {
~
!!! error TS2304: Cannot find name 'b'.
~
!!! error TS1009: Trailing comma not allowed.
};

View file

@ -1,8 +0,0 @@
//// [parserX_ArrowFunction2.ts]
var v = (a: b,) => {
};
//// [parserX_ArrowFunction2.js]
var v = function (a) {
};

View file

@ -0,0 +1,56 @@
//// [trailingCommasInFunctionParametersAndArguments.ts]
function f1(x,) {}
f1(1,);
function f2(...args,) {}
f2(...[],);
// Not confused by overloads
declare function f3(x, ): number;
declare function f3(x, y,): string;
<number>f3(1,);
<string>f3(1, 2,);
// Works for constructors too
class X {
constructor(a,) { }
// See trailingCommasInGetter.ts
set x(value,) { }
}
interface Y {
new(x,);
(x,);
}
new X(1,);
//// [trailingCommasInFunctionParametersAndArguments.js]
function f1(x) { }
f1(1);
function f2() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i - 0] = arguments[_i];
}
}
f2.apply(void 0, []);
f3(1);
f3(1, 2);
// Works for constructors too
var X = (function () {
function X(a) {
}
Object.defineProperty(X.prototype, "x", {
// See trailingCommasInGetter.ts
set: function (value) { },
enumerable: true,
configurable: true
});
return X;
}());
new X(1);

View file

@ -0,0 +1,57 @@
=== tests/cases/conformance/es7/trailingCommasInFunctionParametersAndArguments.ts ===
function f1(x,) {}
>f1 : Symbol(f1, Decl(trailingCommasInFunctionParametersAndArguments.ts, 0, 0))
>x : Symbol(x, Decl(trailingCommasInFunctionParametersAndArguments.ts, 1, 12))
f1(1,);
>f1 : Symbol(f1, Decl(trailingCommasInFunctionParametersAndArguments.ts, 0, 0))
function f2(...args,) {}
>f2 : Symbol(f2, Decl(trailingCommasInFunctionParametersAndArguments.ts, 3, 7))
>args : Symbol(args, Decl(trailingCommasInFunctionParametersAndArguments.ts, 5, 12))
f2(...[],);
>f2 : Symbol(f2, Decl(trailingCommasInFunctionParametersAndArguments.ts, 3, 7))
// Not confused by overloads
declare function f3(x, ): number;
>f3 : Symbol(f3, Decl(trailingCommasInFunctionParametersAndArguments.ts, 7, 11), Decl(trailingCommasInFunctionParametersAndArguments.ts, 10, 33))
>x : Symbol(x, Decl(trailingCommasInFunctionParametersAndArguments.ts, 10, 20))
declare function f3(x, y,): string;
>f3 : Symbol(f3, Decl(trailingCommasInFunctionParametersAndArguments.ts, 7, 11), Decl(trailingCommasInFunctionParametersAndArguments.ts, 10, 33))
>x : Symbol(x, Decl(trailingCommasInFunctionParametersAndArguments.ts, 11, 20))
>y : Symbol(y, Decl(trailingCommasInFunctionParametersAndArguments.ts, 11, 22))
<number>f3(1,);
>f3 : Symbol(f3, Decl(trailingCommasInFunctionParametersAndArguments.ts, 7, 11), Decl(trailingCommasInFunctionParametersAndArguments.ts, 10, 33))
<string>f3(1, 2,);
>f3 : Symbol(f3, Decl(trailingCommasInFunctionParametersAndArguments.ts, 7, 11), Decl(trailingCommasInFunctionParametersAndArguments.ts, 10, 33))
// Works for constructors too
class X {
>X : Symbol(X, Decl(trailingCommasInFunctionParametersAndArguments.ts, 14, 18))
constructor(a,) { }
>a : Symbol(a, Decl(trailingCommasInFunctionParametersAndArguments.ts, 18, 16))
// See trailingCommasInGetter.ts
set x(value,) { }
>x : Symbol(X.x, Decl(trailingCommasInFunctionParametersAndArguments.ts, 18, 23))
>value : Symbol(value, Decl(trailingCommasInFunctionParametersAndArguments.ts, 20, 10))
}
interface Y {
>Y : Symbol(Y, Decl(trailingCommasInFunctionParametersAndArguments.ts, 21, 1))
new(x,);
>x : Symbol(x, Decl(trailingCommasInFunctionParametersAndArguments.ts, 23, 8))
(x,);
>x : Symbol(x, Decl(trailingCommasInFunctionParametersAndArguments.ts, 24, 5))
}
new X(1,);
>X : Symbol(X, Decl(trailingCommasInFunctionParametersAndArguments.ts, 14, 18))

View file

@ -0,0 +1,71 @@
=== tests/cases/conformance/es7/trailingCommasInFunctionParametersAndArguments.ts ===
function f1(x,) {}
>f1 : (x: any) => void
>x : any
f1(1,);
>f1(1,) : void
>f1 : (x: any) => void
>1 : number
function f2(...args,) {}
>f2 : (...args: any[]) => void
>args : any[]
f2(...[],);
>f2(...[],) : void
>f2 : (...args: any[]) => void
>...[] : undefined
>[] : undefined[]
// Not confused by overloads
declare function f3(x, ): number;
>f3 : { (x: any): number; (x: any, y: any): string; }
>x : any
declare function f3(x, y,): string;
>f3 : { (x: any): number; (x: any, y: any): string; }
>x : any
>y : any
<number>f3(1,);
><number>f3(1,) : number
>f3(1,) : number
>f3 : { (x: any): number; (x: any, y: any): string; }
>1 : number
<string>f3(1, 2,);
><string>f3(1, 2,) : string
>f3(1, 2,) : string
>f3 : { (x: any): number; (x: any, y: any): string; }
>1 : number
>2 : number
// Works for constructors too
class X {
>X : X
constructor(a,) { }
>a : any
// See trailingCommasInGetter.ts
set x(value,) { }
>x : any
>value : any
}
interface Y {
>Y : Y
new(x,);
>x : any
(x,);
>x : any
}
new X(1,);
>new X(1,) : X
>X : typeof X
>1 : number

View file

@ -0,0 +1,10 @@
tests/cases/conformance/es7/trailingCommasInGetter.ts(2,11): error TS1138: Parameter declaration expected.
==== tests/cases/conformance/es7/trailingCommasInGetter.ts (1 errors) ====
class X {
get x(,) { return 0; }
~
!!! error TS1138: Parameter declaration expected.
}

View file

@ -0,0 +1,17 @@
//// [trailingCommasInGetter.ts]
class X {
get x(,) { return 0; }
}
//// [trailingCommasInGetter.js]
var X = (function () {
function X() {
}
Object.defineProperty(X.prototype, "x", {
get: function () { return 0; },
enumerable: true,
configurable: true
});
return X;
}());

View file

@ -1,24 +0,0 @@
tests/cases/compiler/trailingSeparatorInFunctionCall.ts(4,1): error TS2346: Supplied parameters do not match any signature of call target.
tests/cases/compiler/trailingSeparatorInFunctionCall.ts(4,7): error TS1009: Trailing comma not allowed.
tests/cases/compiler/trailingSeparatorInFunctionCall.ts(9,1): error TS2346: Supplied parameters do not match any signature of call target.
tests/cases/compiler/trailingSeparatorInFunctionCall.ts(9,8): error TS1009: Trailing comma not allowed.
==== tests/cases/compiler/trailingSeparatorInFunctionCall.ts (4 errors) ====
function f(x, y) {
}
f(1, 2, );
~~~~~~~~~
!!! error TS2346: Supplied parameters do not match any signature of call target.
~
!!! error TS1009: Trailing comma not allowed.
function f2<T>(x: T, y: T) {
}
f2(1, 2, );
~~~~~~~~~~
!!! error TS2346: Supplied parameters do not match any signature of call target.
~
!!! error TS1009: Trailing comma not allowed.

View file

@ -1,18 +0,0 @@
//// [trailingSeparatorInFunctionCall.ts]
function f(x, y) {
}
f(1, 2, );
function f2<T>(x: T, y: T) {
}
f2(1, 2, );
//// [trailingSeparatorInFunctionCall.js]
function f(x, y) {
}
f(1, 2);
function f2(x, y) {
}
f2(1, 2);

View file

@ -0,0 +1,38 @@
//// [typeGuardNarrowsPrimitiveIntersection.ts]
type Tag = {__tag: any};
declare function isNonBlank(value: string) : value is (string & Tag);
declare function doThis(value: string & Tag): void;
declare function doThat(value: string) : void;
let value: string;
if (isNonBlank(value)) {
doThis(value);
} else {
doThat(value);
}
const enum Tag2 {}
declare function isNonBlank2(value: string) : value is (string & Tag2);
declare function doThis2(value: string & Tag2): void;
declare function doThat2(value: string) : void;
if (isNonBlank2(value)) {
doThis2(value);
} else {
doThat2(value);
}
//// [typeGuardNarrowsPrimitiveIntersection.js]
var value;
if (isNonBlank(value)) {
doThis(value);
}
else {
doThat(value);
}
if (isNonBlank2(value)) {
doThis2(value);
}
else {
doThat2(value);
}

View file

@ -0,0 +1,70 @@
=== tests/cases/conformance/expressions/typeGuards/typeGuardNarrowsPrimitiveIntersection.ts ===
type Tag = {__tag: any};
>Tag : Symbol(Tag, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 0, 0))
>__tag : Symbol(__tag, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 0, 12))
declare function isNonBlank(value: string) : value is (string & Tag);
>isNonBlank : Symbol(isNonBlank, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 0, 24))
>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 1, 28))
>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 1, 28))
>Tag : Symbol(Tag, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 0, 0))
declare function doThis(value: string & Tag): void;
>doThis : Symbol(doThis, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 1, 69))
>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 2, 24))
>Tag : Symbol(Tag, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 0, 0))
declare function doThat(value: string) : void;
>doThat : Symbol(doThat, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 2, 51))
>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 3, 24))
let value: string;
>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 4, 3))
if (isNonBlank(value)) {
>isNonBlank : Symbol(isNonBlank, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 0, 24))
>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 4, 3))
doThis(value);
>doThis : Symbol(doThis, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 1, 69))
>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 4, 3))
} else {
doThat(value);
>doThat : Symbol(doThat, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 2, 51))
>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 4, 3))
}
const enum Tag2 {}
>Tag2 : Symbol(Tag2, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 9, 1))
declare function isNonBlank2(value: string) : value is (string & Tag2);
>isNonBlank2 : Symbol(isNonBlank2, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 12, 18))
>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 13, 29))
>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 13, 29))
>Tag2 : Symbol(Tag2, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 9, 1))
declare function doThis2(value: string & Tag2): void;
>doThis2 : Symbol(doThis2, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 13, 71))
>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 14, 25))
>Tag2 : Symbol(Tag2, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 9, 1))
declare function doThat2(value: string) : void;
>doThat2 : Symbol(doThat2, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 14, 53))
>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 15, 25))
if (isNonBlank2(value)) {
>isNonBlank2 : Symbol(isNonBlank2, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 12, 18))
>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 4, 3))
doThis2(value);
>doThis2 : Symbol(doThis2, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 13, 71))
>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 4, 3))
} else {
doThat2(value);
>doThat2 : Symbol(doThat2, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 14, 53))
>value : Symbol(value, Decl(typeGuardNarrowsPrimitiveIntersection.ts, 4, 3))
}

View file

@ -0,0 +1,76 @@
=== tests/cases/conformance/expressions/typeGuards/typeGuardNarrowsPrimitiveIntersection.ts ===
type Tag = {__tag: any};
>Tag : { __tag: any; }
>__tag : any
declare function isNonBlank(value: string) : value is (string & Tag);
>isNonBlank : (value: string) => value is string & { __tag: any; }
>value : string
>value : any
>Tag : { __tag: any; }
declare function doThis(value: string & Tag): void;
>doThis : (value: string & { __tag: any; }) => void
>value : string & { __tag: any; }
>Tag : { __tag: any; }
declare function doThat(value: string) : void;
>doThat : (value: string) => void
>value : string
let value: string;
>value : string
if (isNonBlank(value)) {
>isNonBlank(value) : boolean
>isNonBlank : (value: string) => value is string & { __tag: any; }
>value : string
doThis(value);
>doThis(value) : void
>doThis : (value: string & { __tag: any; }) => void
>value : string & { __tag: any; }
} else {
doThat(value);
>doThat(value) : void
>doThat : (value: string) => void
>value : string
}
const enum Tag2 {}
>Tag2 : Tag2
declare function isNonBlank2(value: string) : value is (string & Tag2);
>isNonBlank2 : (value: string) => value is string & Tag2
>value : string
>value : any
>Tag2 : Tag2
declare function doThis2(value: string & Tag2): void;
>doThis2 : (value: string & Tag2) => void
>value : string & Tag2
>Tag2 : Tag2
declare function doThat2(value: string) : void;
>doThat2 : (value: string) => void
>value : string
if (isNonBlank2(value)) {
>isNonBlank2(value) : boolean
>isNonBlank2 : (value: string) => value is string & Tag2
>value : string
doThis2(value);
>doThis2(value) : void
>doThis2 : (value: string & Tag2) => void
>value : string & Tag2
} else {
doThat2(value);
>doThat2(value) : void
>doThat2 : (value: string) => void
>value : string
}

View file

@ -0,0 +1,21 @@
//// [typeGuardNarrowsToLiteralType.ts]
declare function isFoo(value: string) : value is "foo";
declare function doThis(value: "foo"): void;
declare function doThat(value: string) : void;
let value: string;
if (isFoo(value)) {
doThis(value);
} else {
doThat(value);
}
//// [typeGuardNarrowsToLiteralType.js]
var value;
if (isFoo(value)) {
doThis(value);
}
else {
doThat(value);
}

View file

@ -0,0 +1,32 @@
=== tests/cases/conformance/expressions/typeGuards/typeGuardNarrowsToLiteralType.ts ===
declare function isFoo(value: string) : value is "foo";
>isFoo : Symbol(isFoo, Decl(typeGuardNarrowsToLiteralType.ts, 0, 0))
>value : Symbol(value, Decl(typeGuardNarrowsToLiteralType.ts, 0, 23))
>value : Symbol(value, Decl(typeGuardNarrowsToLiteralType.ts, 0, 23))
declare function doThis(value: "foo"): void;
>doThis : Symbol(doThis, Decl(typeGuardNarrowsToLiteralType.ts, 0, 55))
>value : Symbol(value, Decl(typeGuardNarrowsToLiteralType.ts, 1, 24))
declare function doThat(value: string) : void;
>doThat : Symbol(doThat, Decl(typeGuardNarrowsToLiteralType.ts, 1, 44))
>value : Symbol(value, Decl(typeGuardNarrowsToLiteralType.ts, 2, 24))
let value: string;
>value : Symbol(value, Decl(typeGuardNarrowsToLiteralType.ts, 3, 3))
if (isFoo(value)) {
>isFoo : Symbol(isFoo, Decl(typeGuardNarrowsToLiteralType.ts, 0, 0))
>value : Symbol(value, Decl(typeGuardNarrowsToLiteralType.ts, 3, 3))
doThis(value);
>doThis : Symbol(doThis, Decl(typeGuardNarrowsToLiteralType.ts, 0, 55))
>value : Symbol(value, Decl(typeGuardNarrowsToLiteralType.ts, 3, 3))
} else {
doThat(value);
>doThat : Symbol(doThat, Decl(typeGuardNarrowsToLiteralType.ts, 1, 44))
>value : Symbol(value, Decl(typeGuardNarrowsToLiteralType.ts, 3, 3))
}

View file

@ -0,0 +1,35 @@
=== tests/cases/conformance/expressions/typeGuards/typeGuardNarrowsToLiteralType.ts ===
declare function isFoo(value: string) : value is "foo";
>isFoo : (value: string) => value is "foo"
>value : string
>value : any
declare function doThis(value: "foo"): void;
>doThis : (value: "foo") => void
>value : "foo"
declare function doThat(value: string) : void;
>doThat : (value: string) => void
>value : string
let value: string;
>value : string
if (isFoo(value)) {
>isFoo(value) : boolean
>isFoo : (value: string) => value is "foo"
>value : string
doThis(value);
>doThis(value) : void
>doThis : (value: "foo") => void
>value : "foo"
} else {
doThat(value);
>doThat(value) : void
>doThat : (value: string) => void
>value : string
}

View file

@ -0,0 +1,21 @@
//// [typeGuardNarrowsToLiteralTypeUnion.ts]
declare function isFoo(value: string) : value is ("foo" | "bar");
declare function doThis(value: "foo" | "bar"): void;
declare function doThat(value: string) : void;
let value: string;
if (isFoo(value)) {
doThis(value);
} else {
doThat(value);
}
//// [typeGuardNarrowsToLiteralTypeUnion.js]
var value;
if (isFoo(value)) {
doThis(value);
}
else {
doThat(value);
}

View file

@ -0,0 +1,32 @@
=== tests/cases/conformance/expressions/typeGuards/typeGuardNarrowsToLiteralTypeUnion.ts ===
declare function isFoo(value: string) : value is ("foo" | "bar");
>isFoo : Symbol(isFoo, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 0, 0))
>value : Symbol(value, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 0, 23))
>value : Symbol(value, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 0, 23))
declare function doThis(value: "foo" | "bar"): void;
>doThis : Symbol(doThis, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 0, 65))
>value : Symbol(value, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 1, 24))
declare function doThat(value: string) : void;
>doThat : Symbol(doThat, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 1, 52))
>value : Symbol(value, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 2, 24))
let value: string;
>value : Symbol(value, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 3, 3))
if (isFoo(value)) {
>isFoo : Symbol(isFoo, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 0, 0))
>value : Symbol(value, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 3, 3))
doThis(value);
>doThis : Symbol(doThis, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 0, 65))
>value : Symbol(value, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 3, 3))
} else {
doThat(value);
>doThat : Symbol(doThat, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 1, 52))
>value : Symbol(value, Decl(typeGuardNarrowsToLiteralTypeUnion.ts, 3, 3))
}

View file

@ -0,0 +1,35 @@
=== tests/cases/conformance/expressions/typeGuards/typeGuardNarrowsToLiteralTypeUnion.ts ===
declare function isFoo(value: string) : value is ("foo" | "bar");
>isFoo : (value: string) => value is "foo" | "bar"
>value : string
>value : any
declare function doThis(value: "foo" | "bar"): void;
>doThis : (value: "foo" | "bar") => void
>value : "foo" | "bar"
declare function doThat(value: string) : void;
>doThat : (value: string) => void
>value : string
let value: string;
>value : string
if (isFoo(value)) {
>isFoo(value) : boolean
>isFoo : (value: string) => value is "foo" | "bar"
>value : string
doThis(value);
>doThis(value) : void
>doThis : (value: "foo" | "bar") => void
>value : "foo" | "bar"
} else {
doThat(value);
>doThat(value) : void
>doThat : (value: string) => void
>value : string
}

View file

@ -0,0 +1,15 @@
// @strictNullChecks: true
// @target: ES5
// Repro from #8923
class A {
private static _a: string | undefined;
public get a(): string {
if (A._a) {
return A._a; // is possibly null or undefined.
}
return A._a = 'helloworld';
}
}

View file

@ -0,0 +1,9 @@
// @strictNullChecks: true
// Repro from #8967
const LANG = "Turbo Pascal"
class BestLanguage {
name = LANG;
}

View file

@ -1,9 +0,0 @@
function f(x, y) {
}
f(1, 2, );
function f2<T>(x: T, y: T) {
}
f2(1, 2, );

View file

@ -0,0 +1,29 @@
// @target: es5
function f1(x,) {}
f1(1,);
function f2(...args,) {}
f2(...[],);
// Not confused by overloads
declare function f3(x, ): number;
declare function f3(x, y,): string;
<number>f3(1,);
<string>f3(1, 2,);
// Works for constructors too
class X {
constructor(a,) { }
// See trailingCommasInGetter.ts
set x(value,) { }
}
interface Y {
new(x,);
(x,);
}
new X(1,);

View file

@ -0,0 +1,3 @@
class X {
get x(,) { return 0; }
}

View file

@ -0,0 +1,21 @@
type Tag = {__tag: any};
declare function isNonBlank(value: string) : value is (string & Tag);
declare function doThis(value: string & Tag): void;
declare function doThat(value: string) : void;
let value: string;
if (isNonBlank(value)) {
doThis(value);
} else {
doThat(value);
}
const enum Tag2 {}
declare function isNonBlank2(value: string) : value is (string & Tag2);
declare function doThis2(value: string & Tag2): void;
declare function doThat2(value: string) : void;
if (isNonBlank2(value)) {
doThis2(value);
} else {
doThat2(value);
}

View file

@ -0,0 +1,10 @@
declare function isFoo(value: string) : value is "foo";
declare function doThis(value: "foo"): void;
declare function doThat(value: string) : void;
let value: string;
if (isFoo(value)) {
doThis(value);
} else {
doThat(value);
}

View file

@ -0,0 +1,10 @@
declare function isFoo(value: string) : value is ("foo" | "bar");
declare function doThis(value: "foo" | "bar"): void;
declare function doThat(value: string) : void;
let value: string;
if (isFoo(value)) {
doThis(value);
} else {
doThat(value);
}

View file

@ -67,3 +67,13 @@ function f4(x: number) {
if (x <= undefined) {
}
}
function f5(x: string) {
switch(x) {
case null:
break;
case undefined:
break;
default:
return;
}
}

View file

@ -50,14 +50,26 @@ goTo.marker('6');
verify.quickInfoIs('var m.exportedStrOrNum: string');
verify.completionListContains("exportedStrOrNum", "var m.exportedStrOrNum: string");
['7', '8', '9'].forEach((marker, index, arr) => {
goTo.marker(marker);
verify.quickInfoIs('var m.exportedStrOrNum: string | number');
verify.completionListContains("exportedStrOrNum", "var m.exportedStrOrNum: string | number");
});
goTo.marker('7');
verify.quickInfoIs('var m.exportedStrOrNum: string | number');
verify.completionListContains("exportedStrOrNum", "var m.exportedStrOrNum: string | number");
['7', '8', '9'].forEach((marker, index, arr) => {
goTo.marker(marker);
verify.quickInfoIs('var m.exportedStrOrNum: string | number');
verify.memberListContains("exportedStrOrNum", "var m.exportedStrOrNum: string | number");
});
goTo.marker('8');
verify.quickInfoIs('var m.exportedStrOrNum: number');
verify.completionListContains("exportedStrOrNum", "var m.exportedStrOrNum: number");
goTo.marker('9');
verify.quickInfoIs('var m.exportedStrOrNum: string');
verify.completionListContains("exportedStrOrNum", "var m.exportedStrOrNum: string");
goTo.marker('7');
verify.quickInfoIs('var m.exportedStrOrNum: string | number');
verify.memberListContains("exportedStrOrNum", "var m.exportedStrOrNum: string | number");
goTo.marker('8');
verify.quickInfoIs('var m.exportedStrOrNum: number');
verify.memberListContains("exportedStrOrNum", "var m.exportedStrOrNum: number");
goTo.marker('9');
verify.quickInfoIs('var m.exportedStrOrNum: string');
verify.memberListContains("exportedStrOrNum", "var m.exportedStrOrNum: string");

View file

@ -85,7 +85,8 @@ verify.navigationBar([
"text": "prop",
"kind": "property"
}
]
],
"indent": 1
},
{
"text": "Shapes",
@ -100,7 +101,8 @@ verify.navigationBar([
"text": "Values",
"kind": "enum"
}
]
],
"indent": 1
},
{
"text": "Point",
@ -143,7 +145,8 @@ verify.navigationBar([
"kind": "property",
"kindModifiers": "public"
}
]
],
"indent": 2
},
{
"text": "Values",
@ -161,6 +164,7 @@ verify.navigationBar([
"text": "value3",
"kind": "property"
}
]
],
"indent": 2
}
]);

View file

@ -0,0 +1,15 @@
/// <reference path="fourslash.ts" />
////function str(n: number): string;
/////**
//// * Stringifies a number with radix
//// * @param radix The radix
//// */
////function str(n: number, radix: number): string;
////function str(n: number, radix?: number): string { return ""; }
edit.insert("str(1,");
verify.currentParameterHelpArgumentNameIs("radix");
verify.currentParameterHelpArgumentDocCommentIs("The radix");
verify.currentSignatureHelpIs("str(n: number, radix: number): string");
verify.currentSignatureHelpDocCommentIs("Stringifies a number with radix");