diff --git a/Jakefile b/Jakefile index f76110bb5f2..207cfce2e7f 100644 --- a/Jakefile +++ b/Jakefile @@ -1,6 +1,7 @@ // This file contains the build logic for the public repo var fs = require("fs"); +var os = require("os"); var path = require("path"); var child_process = require("child_process"); @@ -148,7 +149,7 @@ var compilerFilename = "tsc.js"; * @param useBuiltCompiler: true to use the built compiler, false to use the LKG * @param noOutFile: true to compile without using --out */ -function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, noOutFile, generateDeclarations) { +function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, noOutFile, generateDeclarations, callback) { file(outFile, prereqs, function() { var dir = useBuiltCompiler ? builtLocalDirectory : LKGDirectory; var options = "-removeComments --module commonjs -noImplicitAny "; @@ -180,6 +181,11 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, noOu prependFile(prefixes[i], outFile); } } + + if (callback) { + callback(); + } + complete(); }); ex.addListener("error", function() { @@ -224,7 +230,7 @@ compileFile(processDiagnosticMessagesJs, [processDiagnosticMessagesTs], [processDiagnosticMessagesTs], [], - false); + /*useBuiltCompiler*/ false); // The generated diagnostics map; built for the compiler and for the 'generate-diagnostics' task file(diagnosticInfoMapTs, [processDiagnosticMessagesJs, diagnosticMessagesJson], function () { @@ -244,7 +250,6 @@ file(diagnosticInfoMapTs, [processDiagnosticMessagesJs, diagnosticMessagesJson], ex.run(); }, {async: true}) - desc("Generates a diagnostic file in TypeScript based on an input JSON file"); task("generate-diagnostics", [diagnosticInfoMapTs]) @@ -255,13 +260,24 @@ compileFile(tscFile, compilerSources, [builtLocalDirectory, copyright].concat(co var servicesFile = path.join(builtLocalDirectory, "typescriptServices.js"); var servicesDefinitionsFile = path.join(builtLocalDirectory, "typescriptServices.d.ts"); -compileFile(servicesFile, servicesSources, [builtLocalDirectory, copyright].concat(servicesSources), [copyright], /*useBuiltCompiler:*/ true, /*noOutFile:*/ false, /*generateDeclarations:*/ true); + +compileFile(servicesFile, + servicesSources, + [builtLocalDirectory, copyright].concat(servicesSources), + [copyright], + /*useBuiltCompiler*/ true, + /*noOutFile*/ false, + /*generateDeclarations*/ true, + /*callback*/ fixDeclarationFile); + +function fixDeclarationFile() { + fs.appendFileSync(servicesDefinitionsFile, os.EOL + "export = ts;") +} // Local target to build the compiler and services desc("Builds the full compiler and services"); task("local", ["generate-diagnostics", "lib", tscFile, servicesFile]); - // Local target to build the compiler and services desc("Sets release mode flag"); task("release", function() { @@ -278,7 +294,6 @@ task("clean", function() { jake.rmRf(builtDirectory); }); - // Generate Markdown spec var word2mdJs = path.join(scriptsDirectory, "word2md.js"); var word2mdTs = path.join(scriptsDirectory, "word2md.ts"); @@ -292,7 +307,7 @@ compileFile(word2mdJs, [word2mdTs], [word2mdTs], [], - false); + /*useBuiltCompiler*/ false); // The generated spec.md; built for the 'generate-spec' task file(specMd, [word2mdJs, specWord], function () { @@ -444,7 +459,7 @@ task("generate-code-coverage", ["tests", builtLocalDirectory], function () { // Browser tests var nodeServerOutFile = 'tests/webTestServer.js' var nodeServerInFile = 'tests/webTestServer.ts' -compileFile(nodeServerOutFile, [nodeServerInFile], [builtLocalDirectory, tscFile], [], true, true); +compileFile(nodeServerOutFile, [nodeServerInFile], [builtLocalDirectory, tscFile], [], /*useBuiltCompiler:*/ true, /*noOutFile*/ true); desc("Runs browserify on run.js to produce a file suitable for running tests in the browser"); task("browserify", ["tests", builtLocalDirectory, nodeServerOutFile], function() { @@ -525,7 +540,7 @@ task("baseline-accept-test262", function() { // Webhost var webhostPath = "tests/webhost/webtsc.ts"; var webhostJsPath = "tests/webhost/webtsc.js"; -compileFile(webhostJsPath, [webhostPath], [tscFile, webhostPath].concat(libraryTargets), [], true); +compileFile(webhostJsPath, [webhostPath], [tscFile, webhostPath].concat(libraryTargets), [], /*useBuiltCompiler*/true); desc("Builds the tsc web host"); task("webhost", [webhostJsPath], function() { @@ -535,7 +550,7 @@ task("webhost", [webhostJsPath], function() { // Perf compiler var perftscPath = "tests/perftsc.ts"; var perftscJsPath = "built/local/perftsc.js"; -compileFile(perftscJsPath, [perftscPath], [tscFile, perftscPath, "tests/perfsys.ts"].concat(libraryTargets), [], true); +compileFile(perftscJsPath, [perftscPath], [tscFile, perftscPath, "tests/perfsys.ts"].concat(libraryTargets), [], /*useBuiltCompiler*/ true); desc("Builds augmented version of the compiler for perf tests"); task("perftsc", [perftscJsPath]); @@ -559,7 +574,7 @@ file(loggedIOJsPath, [builtLocalDirectory, loggedIOpath], function() { var instrumenterPath = harnessDirectory + 'instrumenter.ts'; var instrumenterJsPath = builtLocalDirectory + 'instrumenter.js'; -compileFile(instrumenterJsPath, [instrumenterPath], [tscFile, instrumenterPath], [], true); +compileFile(instrumenterJsPath, [instrumenterPath], [tscFile, instrumenterPath], [], /*useBuiltCompiler*/ true); desc("Builds an instrumented tsc.js"); task('tsc-instrumented', [loggedIOJsPath, instrumenterJsPath, tscFile], function() { diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 469a794d13d..a45561e7ed6 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -348,8 +348,8 @@ module ts { bindChildren(node, symbolKind, isBlockScopeContainer); } - function bindCatchVariableDeclaration(node: CatchBlock) { - var symbol = createSymbol(SymbolFlags.FunctionScopedVariable, node.variable.text || "__missing"); + function bindCatchVariableDeclaration(node: CatchClause) { + var symbol = createSymbol(SymbolFlags.FunctionScopedVariable, node.name.text || "__missing"); addDeclarationToSymbol(symbol, node, SymbolFlags.FunctionScopedVariable); var saveParent = parent; var savedBlockScopeContainer = blockScopeContainer; @@ -444,8 +444,8 @@ module ts { case SyntaxKind.ArrowFunction: bindAnonymousDeclaration(node, SymbolFlags.Function, "__function", /*isBlockScopeContainer*/ true); break; - case SyntaxKind.CatchBlock: - bindCatchVariableDeclaration(node); + case SyntaxKind.CatchClause: + bindCatchVariableDeclaration(node); break; case SyntaxKind.ClassDeclaration: bindDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes, /*isBlockScopeContainer*/ false); @@ -478,7 +478,7 @@ module ts { case SyntaxKind.Block: case SyntaxKind.TryBlock: - case SyntaxKind.CatchBlock: + case SyntaxKind.CatchClause: case SyntaxKind.FinallyBlock: case SyntaxKind.ForStatement: case SyntaxKind.ForInStatement: diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a663b038844..0e428b4a4e0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -85,7 +85,6 @@ module ts { getDiagnostics, getDeclarationDiagnostics, getGlobalDiagnostics, - checkProgram, getParentOfSymbol, getNarrowedTypeOfSymbol, getDeclaredTypeOfSymbol, @@ -415,8 +414,8 @@ module ts { break loop; } break; - case SyntaxKind.CatchBlock: - var id = (location).variable; + case SyntaxKind.CatchClause: + var id = (location).name; if (name === id.text) { result = location.symbol; break loop; @@ -546,14 +545,18 @@ module ts { return moduleName.substr(0, 2) === "./" || moduleName.substr(0, 3) === "../" || moduleName.substr(0, 2) === ".\\" || moduleName.substr(0, 3) === "..\\"; } - function resolveExternalModuleName(location: Node, moduleExpression: Expression): Symbol { - if (moduleExpression.kind !== SyntaxKind.StringLiteral) { + function resolveExternalModuleName(location: Node, moduleReferenceExpression: Expression): Symbol { + if (moduleReferenceExpression.kind !== SyntaxKind.StringLiteral) { return; } - var moduleLiteral = moduleExpression; + var moduleReferenceLiteral = moduleReferenceExpression; var searchPath = getDirectoryPath(getSourceFile(location).filename); - var moduleName = moduleLiteral.text; + + // Module names are escaped in our symbol table. However, string literal values aren't. + // Escape the name in the "require(...)" clause to ensure we find the right symbol. + var moduleName = escapeIdentifier(moduleReferenceLiteral.text); + if (!moduleName) return; var isRelative = isExternalModuleNameRelative(moduleName); if (!isRelative) { @@ -574,10 +577,10 @@ module ts { if (sourceFile.symbol) { return getResolvedExportSymbol(sourceFile.symbol); } - error(moduleLiteral, Diagnostics.File_0_is_not_an_external_module, sourceFile.filename); + error(moduleReferenceLiteral, Diagnostics.File_0_is_not_an_external_module, sourceFile.filename); return; } - error(moduleLiteral, Diagnostics.Cannot_find_external_module_0, moduleName); + error(moduleReferenceLiteral, Diagnostics.Cannot_find_external_module_0, moduleName); } function getResolvedExportSymbol(moduleSymbol: Symbol): Symbol { @@ -756,7 +759,7 @@ module ts { // // x is an optional parameter, but it is a required property. return propertySymbol.valueDeclaration && - propertySymbol.valueDeclaration.flags & NodeFlags.QuestionMark && + hasQuestionToken(propertySymbol.valueDeclaration) && propertySymbol.valueDeclaration.kind !== SyntaxKind.Parameter; } @@ -1437,11 +1440,11 @@ module ts { } function buildParameterDisplay(p: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, typeStack?: Type[]) { - if (getDeclarationFlagsFromSymbol(p) & NodeFlags.Rest) { + if (hasDotDotDotToken(p.valueDeclaration)) { writePunctuation(writer, SyntaxKind.DotDotDotToken); } appendSymbolNameOnly(p, writer); - if (p.valueDeclaration.flags & NodeFlags.QuestionMark || (p.valueDeclaration).initializer) { + if (hasQuestionToken(p.valueDeclaration) || (p.valueDeclaration).initializer) { writePunctuation(writer, SyntaxKind.QuestionToken); } writePunctuation(writer, SyntaxKind.ColonToken); @@ -1711,7 +1714,7 @@ module ts { } // Rest parameters default to type any[], other parameters default to type any - var type = declaration.flags & NodeFlags.Rest ? createArrayType(anyType) : anyType; + var type = hasDotDotDotToken(declaration) ? createArrayType(anyType) : anyType; checkImplicitAny(type); return type; @@ -1733,9 +1736,9 @@ module ts { var diagnostic = Diagnostics.Member_0_implicitly_has_an_1_type; break; case SyntaxKind.Parameter: - var diagnostic = declaration.flags & NodeFlags.Rest ? - Diagnostics.Rest_parameter_0_implicitly_has_an_any_type : - Diagnostics.Parameter_0_implicitly_has_an_1_type; + var diagnostic = hasDotDotDotToken(declaration) + ? Diagnostics.Rest_parameter_0_implicitly_has_an_any_type + : Diagnostics.Parameter_0_implicitly_has_an_1_type; break; default: var diagnostic = Diagnostics.Variable_0_implicitly_has_an_1_type; @@ -1753,7 +1756,7 @@ module ts { } // Handle catch clause variables var declaration = symbol.valueDeclaration; - if (declaration.kind === SyntaxKind.CatchBlock) { + if (declaration.kind === SyntaxKind.CatchClause) { return links.type = anyType; } // Handle variable, parameter or property @@ -2527,7 +2530,7 @@ module ts { hasStringLiterals = true; } if (minArgumentCount < 0) { - if (param.initializer || param.flags & (NodeFlags.QuestionMark | NodeFlags.Rest)) { + if (param.initializer || param.questionToken || param.dotDotDotToken) { minArgumentCount = i; } } @@ -4375,7 +4378,7 @@ module ts { case SyntaxKind.ThrowStatement: case SyntaxKind.TryStatement: case SyntaxKind.TryBlock: - case SyntaxKind.CatchBlock: + case SyntaxKind.CatchClause: case SyntaxKind.FinallyBlock: return forEachChild(node, isAssignedIn); } @@ -6673,7 +6676,7 @@ module ts { !(parameterDeclaration.parent.kind === SyntaxKind.Constructor && (parameterDeclaration.parent).body)) { error(parameterDeclaration, Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation); } - if (parameterDeclaration.flags & NodeFlags.Rest) { + if (parameterDeclaration.dotDotDotToken) { if (!isArrayType(getTypeOfSymbol(parameterDeclaration.symbol))) { error(parameterDeclaration, Diagnostics.A_rest_parameter_must_be_of_an_array_type); } @@ -7020,20 +7023,23 @@ module ts { return; } + function getCanonicalOverload(overloads: Declaration[], implementation: FunctionLikeDeclaration) { + // Consider the canonical set of flags to be the flags of the bodyDeclaration or the first declaration + // Error on all deviations from this canonical set of flags + // The caveat is that if some overloads are defined in lib.d.ts, we don't want to + // report the errors on those. To achieve this, we will say that the implementation is + // the canonical signature only if it is in the same container as the first overload + var implementationSharesContainerWithFirstOverload = implementation !== undefined && implementation.parent === overloads[0].parent; + return implementationSharesContainerWithFirstOverload ? implementation : overloads[0]; + } + function checkFlagAgreementBetweenOverloads(overloads: Declaration[], implementation: FunctionLikeDeclaration, flagsToCheck: NodeFlags, someOverloadFlags: NodeFlags, allOverloadFlags: NodeFlags): void { // Error if some overloads have a flag that is not shared by all overloads. To find the // deviations, we XOR someOverloadFlags with allOverloadFlags var someButNotAllOverloadFlags = someOverloadFlags ^ allOverloadFlags; if (someButNotAllOverloadFlags !== 0) { - // Consider the canonical set of flags to be the flags of the bodyDeclaration or the first declaration - // Error on all deviations from this canonical set of flags - // The caveat is that if some overloads are defined in lib.d.ts, we don't want to - // report the errors on those. To achieve this, we will say that the implementation is - // the canonical signature only if it is in the same container as the first overload - var implementationSharesContainerWithFirstOverload = implementation !== undefined && implementation.parent === overloads[0].parent; - var canonicalFlags = implementationSharesContainerWithFirstOverload - ? getEffectiveDeclarationFlags(implementation, flagsToCheck) - : getEffectiveDeclarationFlags(overloads[0], flagsToCheck); + var canonicalFlags = getEffectiveDeclarationFlags(getCanonicalOverload(overloads, implementation), flagsToCheck); + forEach(overloads, o => { var deviation = getEffectiveDeclarationFlags(o, flagsToCheck) ^ canonicalFlags; if (deviation & NodeFlags.Export) { @@ -7045,16 +7051,27 @@ module ts { else if (deviation & (NodeFlags.Private | NodeFlags.Protected)) { error(o.name, Diagnostics.Overload_signatures_must_all_be_public_private_or_protected); } - else if (deviation & NodeFlags.QuestionMark) { + }); + } + } + + function checkQuestionTokenAgreementBetweenOverloads(overloads: Declaration[], implementation: FunctionLikeDeclaration, someHaveQuestionToken: boolean, allHaveQuestionToken: boolean): void { + if (someHaveQuestionToken !== allHaveQuestionToken) { + var canonicalHasQuestionToken = hasQuestionToken(getCanonicalOverload(overloads, implementation)); + forEach(overloads, o => { + var deviation = hasQuestionToken(o) !== canonicalHasQuestionToken; + if (deviation) { error(o.name, Diagnostics.Overload_signatures_must_all_be_optional_or_required); } }); } } - var flagsToCheck: NodeFlags = NodeFlags.Export | NodeFlags.Ambient | NodeFlags.Private | NodeFlags.Protected | NodeFlags.QuestionMark; + var flagsToCheck: NodeFlags = NodeFlags.Export | NodeFlags.Ambient | NodeFlags.Private | NodeFlags.Protected; var someNodeFlags: NodeFlags = 0; var allNodeFlags = flagsToCheck; + var someHaveQuestionToken = false; + var allHaveQuestionToken = true; var hasOverloads = false; var bodyDeclaration: FunctionLikeDeclaration; var lastSeenNonAmbientDeclaration: FunctionLikeDeclaration; @@ -7128,6 +7145,8 @@ module ts { var currentNodeFlags = getEffectiveDeclarationFlags(node, flagsToCheck); someNodeFlags |= currentNodeFlags; allNodeFlags &= currentNodeFlags; + someHaveQuestionToken = someHaveQuestionToken || hasQuestionToken(node); + allHaveQuestionToken = allHaveQuestionToken && hasQuestionToken(node); if (node.body && bodyDeclaration) { if (isConstructor) { @@ -7176,6 +7195,8 @@ module ts { if (hasOverloads) { checkFlagAgreementBetweenOverloads(declarations, bodyDeclaration, flagsToCheck, someNodeFlags, allNodeFlags); + checkQuestionTokenAgreementBetweenOverloads(declarations, bodyDeclaration, someHaveQuestionToken, allHaveQuestionToken); + if (bodyDeclaration) { var signatures = getSignaturesOfSymbol(symbol); var bodySignature = getSignatureFromDeclaration(bodyDeclaration); @@ -7725,13 +7746,14 @@ module ts { function checkSwitchStatement(node: SwitchStatement) { var expressionType = checkExpression(node.expression); forEach(node.clauses, clause => { - if (fullTypeCheck && clause.expression) { + if (fullTypeCheck && clause.kind === SyntaxKind.CaseClause) { + var caseClause = clause; // TypeScript 1.0 spec (April 2014):5.9 // In a 'switch' statement, each 'case' expression must be of a type that is assignable to or from the type of the 'switch' expression. - var caseType = checkExpression(clause.expression); + var caseType = checkExpression(caseClause.expression); if (!isTypeAssignableTo(expressionType, caseType)) { // check 'expressionType isAssignableTo caseType' failed, try the reversed check and report errors if it fails - checkTypeAssignableTo(caseType, expressionType, clause.expression, /*headMessage*/ undefined); + checkTypeAssignableTo(caseType, expressionType, caseClause.expression, /*headMessage*/ undefined); } } forEach(clause.statements, checkSourceElement); @@ -7748,7 +7770,7 @@ module ts { function checkTryStatement(node: TryStatement) { checkBlock(node.tryBlock); - if (node.catchBlock) checkBlock(node.catchBlock); + if (node.catchClause) checkBlock(node.catchClause.block); if (node.finallyBlock) checkBlock(node.finallyBlock); } @@ -8586,7 +8608,7 @@ module ts { case SyntaxKind.ThrowStatement: case SyntaxKind.TryStatement: case SyntaxKind.TryBlock: - case SyntaxKind.CatchBlock: + case SyntaxKind.CatchClause: case SyntaxKind.FinallyBlock: case SyntaxKind.VariableDeclaration: case SyntaxKind.ClassDeclaration: @@ -8634,10 +8656,6 @@ module ts { } } - function checkProgram() { - forEach(program.getSourceFiles(), checkSourceFile); - } - function getSortedDiagnostics(): Diagnostic[]{ Debug.assert(fullTypeCheck, "diagnostics are available only in the full typecheck mode"); @@ -8650,12 +8668,11 @@ module ts { } function getDiagnostics(sourceFile?: SourceFile): Diagnostic[]{ - if (sourceFile) { checkSourceFile(sourceFile); return filter(getSortedDiagnostics(), d => d.file === sourceFile); } - checkProgram(); + forEach(program.getSourceFiles(), checkSourceFile); return getSortedDiagnostics(); } @@ -8748,8 +8765,8 @@ module ts { copySymbol(location.symbol, meaning); } break; - case SyntaxKind.CatchBlock: - if ((location).variable.text) { + case SyntaxKind.CatchClause: + if ((location).name.text) { copySymbol(location.symbol, meaning); } break; @@ -9005,7 +9022,7 @@ module ts { // This is necessary as an identifier in short-hand property assignment can contains two meaning: // property name and property value. if (location && location.kind === SyntaxKind.ShorthandPropertyAssignment) { - return resolveEntityName(location, (location).name, SymbolFlags.Value); + return resolveEntityName(location, (location).name, SymbolFlags.Value); } return undefined; } @@ -9173,9 +9190,9 @@ module ts { return isImportResolvedToValue(getSymbolOfNode(node)); } - function hasSemanticErrors() { + function hasSemanticErrors(sourceFile?: SourceFile) { // Return true if there is any semantic error in a file or globally - return getDiagnostics().length > 0 || getGlobalDiagnostics().length > 0; + return getDiagnostics(sourceFile).length > 0 || getGlobalDiagnostics().length > 0; } function isEmitBlocked(sourceFile?: SourceFile): boolean { @@ -9293,7 +9310,6 @@ module ts { function invokeEmitter(targetSourceFile?: SourceFile) { var resolver = createResolver(); - checkProgram(); return emitFiles(resolver, targetSourceFile); } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index fab0433890a..7193523bf96 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -943,7 +943,7 @@ module ts { if (node.kind !== SyntaxKind.VariableDeclaration || resolver.isDeclarationVisible(node)) { writeTextOfNode(currentSourceFile, node.name); // If optional property emit ? - if (node.kind === SyntaxKind.Property && (node.flags & NodeFlags.QuestionMark)) { + if (node.kind === SyntaxKind.Property && hasQuestionToken(node)) { write("?"); } if (node.kind === SyntaxKind.Property && node.parent.kind === SyntaxKind.TypeLiteral) { @@ -1124,7 +1124,7 @@ module ts { } else { writeTextOfNode(currentSourceFile, node.name); - if (node.flags & NodeFlags.QuestionMark) { + if (hasQuestionToken(node)) { write("?"); } } @@ -1252,11 +1252,11 @@ module ts { function emitParameterDeclaration(node: ParameterDeclaration) { increaseIndent(); emitJsDocComments(node); - if (node.flags & NodeFlags.Rest) { + if (node.dotDotDotToken) { write("..."); } writeTextOfNode(currentSourceFile, node.name); - if (node.initializer || (node.flags & NodeFlags.QuestionMark)) { + if (node.initializer || hasQuestionToken(node)) { write("?"); } decreaseIndent(); @@ -2142,8 +2142,8 @@ module ts { return false; case SyntaxKind.LabeledStatement: return (node.parent).label === node; - case SyntaxKind.CatchBlock: - return (node.parent).variable === node; + case SyntaxKind.CatchClause: + return (node.parent).name === node; } } @@ -2236,33 +2236,35 @@ module ts { emitTrailingComments(node); } - function emitShortHandPropertyAssignment(node: ShortHandPropertyDeclaration) { - function emitAsNormalPropertyAssignment() { - emitLeadingComments(node); - // Emit identifier as an identifier - emit(node.name); - write(": "); - // Even though this is stored as identified because it is in short-hand property assignment, - // treated it as expression - emitExpressionIdentifier(node.name); - emitTrailingComments(node); - } + function emitDownlevelShorthandPropertyAssignment(node: ShorthandPropertyDeclaration) { + emitLeadingComments(node); + // Emit identifier as an identifier + emit(node.name); + write(": "); + // Even though this is stored as identifier treat it as an expression + // Short-hand, { x }, is equivalent of normal form { x: x } + emitExpressionIdentifier(node.name); + emitTrailingComments(node); + } - if (compilerOptions.target < ScriptTarget.ES6) { - emitAsNormalPropertyAssignment(); + function emitShorthandPropertyAssignment(node: ShorthandPropertyDeclaration) { + // If short-hand property has a prefix, then regardless of the target version, we will emit it as normal property assignment. For example: + // module m { + // export var y; + // } + // module m { + // export var obj = { y }; + // } + // The short-hand property in obj need to emit as such ... = { y : m.y } regardless of the TargetScript version + var prefix = resolver.getExpressionNamePrefix(node.name); + if (prefix) { + emitDownlevelShorthandPropertyAssignment(node); } - else if (compilerOptions.target >= ScriptTarget.ES6) { - // If short-hand property has a prefix, then regardless of the target version, we will emit it as normal property assignment - var prefix = resolver.getExpressionNamePrefix(node.name); - if (prefix) { - emitAsNormalPropertyAssignment(); - } - // If short-hand property has no prefix, emit it as short-hand. - else { - emitLeadingComments(node); - emit(node.name); - emitTrailingComments(node); - } + // If short-hand property has no prefix, emit it as short-hand. + else { + emitLeadingComments(node); + emit(node.name); + emitTrailingComments(node); } } @@ -2624,7 +2626,7 @@ module ts { function emitCaseOrDefaultClause(node: CaseOrDefaultClause) { if (node.kind === SyntaxKind.CaseClause) { write("case "); - emit(node.expression); + emit((node).expression); write(":"); } else { @@ -2650,7 +2652,7 @@ module ts { function emitTryStatement(node: TryStatement) { write("try "); emit(node.tryBlock); - emit(node.catchBlock); + emit(node.catchClause); if (node.finallyBlock) { writeLine(); write("finally "); @@ -2658,15 +2660,15 @@ module ts { } } - function emitCatchBlock(node: CatchBlock) { + function emitCatchClause(node: CatchClause) { writeLine(); var endPos = emitToken(SyntaxKind.CatchKeyword, node.pos); write(" "); emitToken(SyntaxKind.OpenParenToken, endPos); - emit(node.variable); - emitToken(SyntaxKind.CloseParenToken, node.variable.end); + emit(node.name); + emitToken(SyntaxKind.CloseParenToken, node.name.end); write(" "); - emitBlock(node); + emitBlock(node.block); } function emitDebuggerStatement(node: Node) { @@ -3441,6 +3443,7 @@ module ts { // Start new file on new line writeLine(); emitDetachedComments(node); + // emit prologue directives prior to __extends var startIndex = emitDirectivePrologues(node.statements, /*startWithNewLine*/ false); if (!extendsEmitted && resolver.getNodeCheckFlags(node) & NodeCheckFlags.EmitExtends) { @@ -3472,6 +3475,8 @@ module ts { emitCaptureThisForNodeIfNecessary(node); emitLinesStartingAt(node.statements, startIndex); } + + emitLeadingComments(node.endOfFileToken); } function emitNode(node: Node): void { @@ -3483,6 +3488,7 @@ module ts { return emitPinnedOrTripleSlashComments(node); } + // Check if the node can be emitted regardless of the ScriptTarget switch (node.kind) { case SyntaxKind.Identifier: return emitIdentifier(node); @@ -3521,8 +3527,6 @@ module ts { return emitObjectLiteral(node); case SyntaxKind.PropertyAssignment: return emitPropertyAssignment(node); - case SyntaxKind.ShorthandPropertyAssignment: - return emitShortHandPropertyAssignment(node); case SyntaxKind.ComputedPropertyName: return emitComputedPropertyName(node); case SyntaxKind.PropertyAccessExpression: @@ -3599,8 +3603,8 @@ module ts { return emitThrowStatement(node); case SyntaxKind.TryStatement: return emitTryStatement(node); - case SyntaxKind.CatchBlock: - return emitCatchBlock(node); + case SyntaxKind.CatchClause: + return emitCatchClause(node); case SyntaxKind.DebuggerStatement: return emitDebuggerStatement(node); case SyntaxKind.VariableDeclaration: @@ -3618,6 +3622,23 @@ module ts { case SyntaxKind.SourceFile: return emitSourceFile(node); } + + // Emit node which needs to be emitted differently depended on ScriptTarget + if (compilerOptions.target < ScriptTarget.ES6) { + // Emit node down-level + switch (node.kind) { + case SyntaxKind.ShorthandPropertyAssignment: + return emitDownlevelShorthandPropertyAssignment(node); + } + } + else { + // Emit node natively + Debug.assert(compilerOptions.target >= ScriptTarget.ES6, "Invalid ScriptTarget. We should emit as ES6 or above"); + switch (node.kind) { + case SyntaxKind.ShorthandPropertyAssignment: + return emitShorthandPropertyAssignment(node); + } + } } function hasDetachedComments(pos: number) { @@ -3791,20 +3812,14 @@ module ts { } } - var hasSemanticErrors = resolver.hasSemanticErrors(); - var isEmitBlocked = resolver.isEmitBlocked(targetSourceFile); - - function emitFile(jsFilePath: string, sourceFile?: SourceFile) { - if (!isEmitBlocked) { - emitJavaScript(jsFilePath, sourceFile); - if (!hasSemanticErrors && compilerOptions.declaration) { - writeDeclarationFile(jsFilePath, sourceFile); - } - } - } + var hasSemanticErrors: boolean = false; + var isEmitBlocked: boolean = false; if (targetSourceFile === undefined) { // No targetSourceFile is specified (e.g. calling emitter from batch compiler) + hasSemanticErrors = resolver.hasSemanticErrors(); + isEmitBlocked = resolver.isEmitBlocked(); + forEach(program.getSourceFiles(), sourceFile => { if (shouldEmitToOwnFile(sourceFile, compilerOptions)) { var jsFilePath = getOwnEmitOutputFilePath(sourceFile, program, ".js"); @@ -3820,16 +3835,35 @@ module ts { // targetSourceFile is specified (e.g calling emitter from language service or calling getSemanticDiagnostic from language service) if (shouldEmitToOwnFile(targetSourceFile, compilerOptions)) { // If shouldEmitToOwnFile returns true or targetSourceFile is an external module file, then emit targetSourceFile in its own output file + hasSemanticErrors = resolver.hasSemanticErrors(targetSourceFile); + isEmitBlocked = resolver.isEmitBlocked(targetSourceFile); + var jsFilePath = getOwnEmitOutputFilePath(targetSourceFile, program, ".js"); emitFile(jsFilePath, targetSourceFile); } else if (!isDeclarationFile(targetSourceFile) && compilerOptions.out) { // Otherwise, if --out is specified and targetSourceFile is not a declaration file, // Emit all, non-external-module file, into one single output file + forEach(program.getSourceFiles(), sourceFile => { + if (!shouldEmitToOwnFile(sourceFile, compilerOptions)) { + hasSemanticErrors = hasSemanticErrors || resolver.hasSemanticErrors(sourceFile); + isEmitBlocked = isEmitBlocked || resolver.isEmitBlocked(sourceFile); + } + }); + emitFile(compilerOptions.out); } } + function emitFile(jsFilePath: string, sourceFile?: SourceFile) { + if (!isEmitBlocked) { + emitJavaScript(jsFilePath, sourceFile); + if (!hasSemanticErrors && compilerOptions.declaration) { + writeDeclarationFile(jsFilePath, sourceFile); + } + } + } + // Sort and make the unique list of diagnostics diagnostics.sort(compareDiagnostics); diagnostics = deduplicateSortedDiagnostics(diagnostics); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 687eab878f3..b36ded65dc4 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -216,13 +216,18 @@ module ts { return child((node).name) || child((node).constraint); case SyntaxKind.Parameter: - return child((node).name) || + return children(node.modifiers) || + child((node).dotDotDotToken) || + child((node).name) || + child((node).questionToken) || child((node).type) || child((node).initializer); case SyntaxKind.Property: case SyntaxKind.PropertyAssignment: case SyntaxKind.ShorthandPropertyAssignment: - return child((node).name) || + return children(node.modifiers) || + child((node).name) || + child((node).questionToken) || child((node).type) || child((node).initializer); case SyntaxKind.FunctionType: @@ -230,7 +235,8 @@ module ts { case SyntaxKind.CallSignature: case SyntaxKind.ConstructSignature: case SyntaxKind.IndexSignature: - return children((node).typeParameters) || + return children(node.modifiers) || + children((node).typeParameters) || children((node).parameters) || child((node).type); case SyntaxKind.Method: @@ -240,7 +246,9 @@ module ts { case SyntaxKind.FunctionExpression: case SyntaxKind.FunctionDeclaration: case SyntaxKind.ArrowFunction: - return child((node).name) || + return children(node.modifiers) || + child((node).name) || + child((node).questionToken) || children((node).typeParameters) || children((node).parameters) || child((node).type) || @@ -305,10 +313,13 @@ module ts { case SyntaxKind.FinallyBlock: case SyntaxKind.FunctionBlock: case SyntaxKind.ModuleBlock: - case SyntaxKind.SourceFile: return children((node).statements); + case SyntaxKind.SourceFile: + return children((node).statements) || + child((node).endOfFileToken); case SyntaxKind.VariableStatement: - return children((node).declarations); + return children(node.modifiers) || + children((node).declarations); case SyntaxKind.ExpressionStatement: return child((node).expression); case SyntaxKind.IfStatement: @@ -344,9 +355,10 @@ module ts { return child((node).expression) || children((node).clauses); case SyntaxKind.CaseClause: + return child((node).expression) || + children((node).statements); case SyntaxKind.DefaultClause: - return child((node).expression) || - children((node).statements); + return children((node).statements); case SyntaxKind.LabeledStatement: return child((node).label) || child((node).statement); @@ -354,42 +366,51 @@ module ts { return child((node).expression); case SyntaxKind.TryStatement: return child((node).tryBlock) || - child((node).catchBlock) || + child((node).catchClause) || child((node).finallyBlock); - case SyntaxKind.CatchBlock: - return child((node).variable) || - children((node).statements); + case SyntaxKind.CatchClause: + return child((node).name) || + child((node).type) || + child((node).block); case SyntaxKind.VariableDeclaration: - return child((node).name) || + return children(node.modifiers) || + child((node).name) || child((node).type) || child((node).initializer); case SyntaxKind.ClassDeclaration: - return child((node).name) || + return children(node.modifiers) || + child((node).name) || children((node).typeParameters) || children((node).heritageClauses) || children((node).members); case SyntaxKind.InterfaceDeclaration: - return child((node).name) || - children((node).typeParameters) || - children((node).heritageClauses) || + return children(node.modifiers) || + child((node).name) || + children((node).typeParameters) || + children((node).heritageClauses) || children((node).members); case SyntaxKind.TypeAliasDeclaration: - return child((node).name) || + return children(node.modifiers) || + child((node).name) || child((node).type); case SyntaxKind.EnumDeclaration: - return child((node).name) || + return children(node.modifiers) || + child((node).name) || children((node).members); case SyntaxKind.EnumMember: return child((node).name) || child((node).initializer); case SyntaxKind.ModuleDeclaration: - return child((node).name) || + return children(node.modifiers) || + child((node).name) || child((node).body); case SyntaxKind.ImportDeclaration: - return child((node).name) || + return children(node.modifiers) || + child((node).name) || child((node).moduleReference); case SyntaxKind.ExportAssignment: - return child((node).exportName); + return children(node.modifiers) || + child((node).exportName); case SyntaxKind.TemplateExpression: return child((node).head) || children((node).templateSpans); case SyntaxKind.TemplateSpan: @@ -427,7 +448,7 @@ module ts { case SyntaxKind.LabeledStatement: case SyntaxKind.TryStatement: case SyntaxKind.TryBlock: - case SyntaxKind.CatchBlock: + case SyntaxKind.CatchClause: case SyntaxKind.FinallyBlock: return forEachChild(node, traverse); } @@ -608,8 +629,29 @@ module ts { return node.kind === SyntaxKind.ImportDeclaration && (node).moduleReference.kind !== SyntaxKind.ExternalModuleReference; } + export function hasDotDotDotToken(node: Node) { + return node && node.kind === SyntaxKind.Parameter && (node).dotDotDotToken !== undefined; + } + + export function hasQuestionToken(node: Node) { + if (node) { + switch (node.kind) { + case SyntaxKind.Parameter: + return (node).questionToken !== undefined; + case SyntaxKind.Method: + return (node).questionToken !== undefined; + case SyntaxKind.ShorthandPropertyAssignment: + case SyntaxKind.PropertyAssignment: + case SyntaxKind.Property: + return (node).questionToken !== undefined; + } + } + + return false; + } + export function hasRestParameters(s: SignatureDeclaration): boolean { - return s.parameters.length > 0 && (s.parameters[s.parameters.length - 1].flags & NodeFlags.Rest) !== 0; + return s.parameters.length > 0 && s.parameters[s.parameters.length - 1].dotDotDotToken !== undefined; } export function isLiteralKind(kind: SyntaxKind): boolean { @@ -694,8 +736,8 @@ module ts { return (parent).name === name; } - if (parent.kind === SyntaxKind.CatchBlock) { - return (parent).variable === name; + if (parent.kind === SyntaxKind.CatchClause) { + return (parent).name === name; } return false; @@ -903,7 +945,6 @@ module ts { } export function createSourceFile(filename: string, sourceText: string, languageVersion: ScriptTarget, version: string, isOpen: boolean = false): SourceFile { - var file: SourceFile; var scanner: Scanner; var token: SyntaxKind; var parsingContext: ParsingContext; @@ -1061,22 +1102,22 @@ module ts { return getPositionFromLineAndCharacter(getLineStarts(), line, character); } - function error(message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): void { + function parseErrorAtCurrentToken(message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): void { var start = scanner.getTokenPos(); var length = scanner.getTextPos() - start; - errorAtPosition(start, length, message, arg0, arg1, arg2); + parseErrorAtPosition(start, length, message, arg0, arg1, arg2); } - function errorAtPosition(start: number, length: number, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): void { - var lastErrorPosition = file.parseDiagnostics.length - ? file.parseDiagnostics[file.parseDiagnostics.length - 1].start + function parseErrorAtPosition(start: number, length: number, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): void { + var lastErrorPosition = sourceFile.parseDiagnostics.length + ? sourceFile.parseDiagnostics[sourceFile.parseDiagnostics.length - 1].start : -1; // Don't report another error if it would just be at the same position as the last error. if (start !== lastErrorPosition) { - var diagnostic = createFileDiagnostic(file, start, length, message, arg0, arg1, arg2); - file.parseDiagnostics.push(diagnostic); + var diagnostic = createFileDiagnostic(sourceFile, start, length, message, arg0, arg1, arg2); + sourceFile.parseDiagnostics.push(diagnostic); } if (lookAheadMode === LookAheadMode.NoErrorYet) { @@ -1086,7 +1127,7 @@ module ts { function scanError(message: DiagnosticMessage) { var pos = scanner.getTextPos(); - errorAtPosition(pos, 0, message); + parseErrorAtPosition(pos, 0, message); } function onComment(pos: number, end: number) { @@ -1125,7 +1166,7 @@ module ts { // Keep track of the state we'll need to rollback to if lookahead fails (or if the // caller asked us to always reset our state). var saveToken = token; - var saveSyntacticErrorsLength = file.parseDiagnostics.length; + var saveSyntacticErrorsLength = sourceFile.parseDiagnostics.length; // Keep track of the current look ahead mode (this matters if we have nested // speculative parsing). @@ -1147,7 +1188,7 @@ module ts { lookAheadMode = saveLookAheadMode; if (!result || alwaysResetState) { token = saveToken; - file.parseDiagnostics.length = saveSyntacticErrorsLength; + sourceFile.parseDiagnostics.length = saveSyntacticErrorsLength; } return result; @@ -1196,10 +1237,10 @@ module ts { // Report specific message if provided with one. Otherwise, report generic fallback message. if (diagnosticMessage) { - error(diagnosticMessage, arg0); + parseErrorAtCurrentToken(diagnosticMessage, arg0); } else { - error(Diagnostics._0_expected, tokenToString(kind)); + parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(kind)); } return false; } @@ -1267,10 +1308,10 @@ module ts { function createMissingNode(kind: SyntaxKind, reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): Node { if (reportAtCurrentPosition) { - errorAtPosition(scanner.getStartPos(), 0, diagnosticMessage, arg0); + parseErrorAtPosition(scanner.getStartPos(), 0, diagnosticMessage, arg0); } else { - error(diagnosticMessage, arg0); + parseErrorAtCurrentToken(diagnosticMessage, arg0); } return createMissingNodeWithoutError(kind); @@ -1307,11 +1348,11 @@ module ts { } function parseIdentifierName(): Identifier { - return createIdentifier(token >= SyntaxKind.Identifier); + return createIdentifier(isIdentifierOrKeyword()); } function isLiteralPropertyName(): boolean { - return token >= SyntaxKind.Identifier || + return isIdentifierOrKeyword() || token === SyntaxKind.StringLiteral || token === SyntaxKind.NumericLiteral; } @@ -1345,6 +1386,7 @@ module ts { if (inGeneratorParameterContext()) { setYieldContext(false); } + node.expression = allowInAnd(parseExpression); if (inGeneratorParameterContext()) { setYieldContext(yieldContext); @@ -1355,22 +1397,26 @@ module ts { } function parseContextualModifier(t: SyntaxKind): boolean { - return token === t && tryParse(() => { - nextToken(); - return canFollowModifier(); - }); + return token === t && tryParse(nextTokenCanFollowModifier); + } + + function nextTokenCanFollowModifier() { + nextToken(); + return canFollowModifier(); } function parseAnyContextualModifier(): boolean { - return isModifier(token) && tryParse(() => { - if (token === SyntaxKind.ConstKeyword) { - // 'const' is only a modifier if followed by 'enum'. - return nextToken() === SyntaxKind.EnumKeyword; - } + return isModifier(token) && tryParse(nextTokenCanFollowContextualModifier); + } - nextToken(); - return canFollowModifier(); - }); + function nextTokenCanFollowContextualModifier() { + if (token === SyntaxKind.ConstKeyword) { + // 'const' is only a modifier if followed by 'enum'. + return nextToken() === SyntaxKind.EnumKeyword; + } + + nextToken(); + return canFollowModifier(); } function canFollowModifier(): boolean { @@ -1399,7 +1445,9 @@ module ts { case ParsingContext.ObjectLiteralMembers: return token === SyntaxKind.OpenBracketToken || token === SyntaxKind.AsteriskToken || isLiteralPropertyName(); case ParsingContext.TypeReferences: - return isIdentifier() && ((token !== SyntaxKind.ExtendsKeyword && token !== SyntaxKind.ImplementsKeyword) || !lookAhead(() => (nextToken(), isIdentifier()))); + // We want to make sure that the "extends" in "extends foo" or the "implements" in + // "implements foo" is not considered a type name. + return isIdentifier() && !isNotHeritageClauseTypeName(); case ParsingContext.VariableDeclarations: case ParsingContext.TypeParameters: return isIdentifier(); @@ -1419,6 +1467,21 @@ module ts { Debug.fail("Non-exhaustive case in 'isListElement'."); } + function nextTokenIsIdentifier() { + nextToken(); + return isIdentifier(); + } + + function isNotHeritageClauseTypeName(): boolean { + if (token === SyntaxKind.ImplementsKeyword || + token === SyntaxKind.ExtendsKeyword) { + + return lookAhead(nextTokenIsIdentifier); + } + + return false; + } + // True if positioned at a list terminator function isListTerminator(kind: ParsingContext): boolean { if (token === SyntaxKind.EndOfFileToken) { @@ -1542,7 +1605,7 @@ module ts { // Returns true if we should abort parsing. function abortParsingListOrMoveToNextToken(kind: ParsingContext) { - error(parsingContextErrors(kind)); + parseErrorAtCurrentToken(parsingContextErrors(kind)); if (isInSomeParsingContext()) { return true; } @@ -1649,10 +1712,7 @@ module ts { // In the first case though, ASI will not take effect because there is not a // line terminator after the keyword. if (scanner.hasPrecedingLineBreak() && scanner.isReservedWord()) { - var matchesPattern = lookAhead(() => { - nextToken(); - return !scanner.hasPrecedingLineBreak() && (scanner.isIdentifier() || scanner.isReservedWord()); - }); + var matchesPattern = lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine); if (matchesPattern) { // Report that we need an identifier. However, report it right after the dot, @@ -1665,6 +1725,8 @@ module ts { return allowIdentifierNames ? parseIdentifierName() : parseIdentifier(); } + + function parseTokenNode(): T { var node = createNode(token); nextToken(); @@ -1812,11 +1874,8 @@ module ts { function parseParameter(): ParameterDeclaration { var node = createNode(SyntaxKind.Parameter); - var modifiers = parseModifiers(); - setModifiers(node, modifiers); - if (parseOptional(SyntaxKind.DotDotDotToken)) { - node.flags |= NodeFlags.Rest; - } + setModifiers(node, parseModifiers()); + node.dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); // SingleNameBinding[Yield,GeneratorParameter] : See 13.2.3 // [+GeneratorParameter]BindingIdentifier[Yield]Initializer[In]opt @@ -1838,9 +1897,7 @@ module ts { nextToken(); } - if (parseOptional(SyntaxKind.QuestionToken)) { - node.flags |= NodeFlags.QuestionMark; - } + node.questionToken = parseOptionalToken(SyntaxKind.QuestionToken); node.type = parseParameterType(); node.initializer = inGeneratorParameterContext() ? doOutsideOfYieldContext(parseParameterInitializer) @@ -1861,22 +1918,17 @@ module ts { return parseInitializer(/*inParameter*/ true); } - function parseSignature(kind: SyntaxKind, returnToken: SyntaxKind, returnTokenRequired: boolean, yieldAndGeneratorParameterContext: boolean): ParsedSignature { + function parseSignature(yieldAndGeneratorParameterContext: boolean): ParsedSignature { var signature = {}; - fillSignature(kind, returnToken, returnTokenRequired, yieldAndGeneratorParameterContext, signature); + fillSignature(SyntaxKind.ColonToken, yieldAndGeneratorParameterContext, signature); return signature; } function fillSignature( - kind: SyntaxKind, returnToken: SyntaxKind, - returnTokenRequired: boolean, yieldAndGeneratorParameterContext: boolean, signature: ParsedSignature): void { - - if (kind === SyntaxKind.ConstructSignature) { - parseExpected(SyntaxKind.NewKeyword); - } + var returnTokenRequired = returnToken === SyntaxKind.EqualsGreaterThanToken; signature.typeParameters = parseTypeParameters(); signature.parameters = parseParameterList(yieldAndGeneratorParameterContext); @@ -1927,9 +1979,12 @@ module ts { return createMissingList(); } - function parseSignatureMember(kind: SyntaxKind, returnToken: SyntaxKind): SignatureDeclaration { + function parseSignatureMember(kind: SyntaxKind): SignatureDeclaration { var node = createNode(kind); - fillSignature(kind, returnToken, /* returnTokenRequired */ false, /*yieldAndGeneratorParameterContext:*/ false, node); + if (kind === SyntaxKind.ConstructSignature) { + parseExpected(SyntaxKind.NewKeyword); + } + fillSignature(SyntaxKind.ColonToken, /*yieldAndGeneratorParameterContext:*/ false, node); parseSemicolon(); return finishNode(node); } @@ -1939,58 +1994,62 @@ module ts { return false; } - return lookAhead(() => { - // The only allowed sequence is: - // - // [id: - // - // However, for error recovery, we also check the following cases: - // - // [... - // [id, - // [id?, - // [id?: - // [id?] - // [public id - // [private id - // [protected id - // [] - // - if (nextToken() === SyntaxKind.DotDotDotToken || token === SyntaxKind.CloseBracketToken) { + return lookAhead(isUnambiguouslyIndexSignature); + } + + function isUnambiguouslyIndexSignature() { + // The only allowed sequence is: + // + // [id: + // + // However, for error recovery, we also check the following cases: + // + // [... + // [id, + // [id?, + // [id?: + // [id?] + // [public id + // [private id + // [protected id + // [] + // + nextToken(); + if (token === SyntaxKind.DotDotDotToken || token === SyntaxKind.CloseBracketToken) { + return true; + } + + if (isModifier(token)) { + nextToken(); + if (isIdentifier()) { return true; } + } + else if (!isIdentifier()) { + return false; + } + else { + // Skip the identifier + nextToken(); + } - if (isModifier(token)) { - nextToken(); - if (isIdentifier()) { - return true; - } - } - else if (!isIdentifier()) { - return false; - } - else { - // Skip the identifier - nextToken(); - } + // A colon signifies a well formed indexer + // A comma should be a badly formed indexer because comma expressions are not allowed + // in computed properties. + if (token === SyntaxKind.ColonToken || token === SyntaxKind.CommaToken) { + return true; + } - // A colon signifies a well formed indexer - // A comma should be a badly formed indexer because comma expressions are not allowed - // in computed properties. - if (token === SyntaxKind.ColonToken || token === SyntaxKind.CommaToken) { - return true; - } + // Question mark could be an indexer with an optional property, + // or it could be a conditional expression in a computed property. + if (token !== SyntaxKind.QuestionToken) { + return false; + } - // Question mark could be an indexer with an optional property, - // or it could be a conditional expression in a computed property. - if (token !== SyntaxKind.QuestionToken) { - return false; - } - - // If any of the following tokens are after the question mark, it cannot - // be a conditional expression, so treat it as an indexer. - return nextToken() === SyntaxKind.ColonToken || token === SyntaxKind.CommaToken || token === SyntaxKind.CloseBracketToken; - }); + // If any of the following tokens are after the question mark, it cannot + // be a conditional expression, so treat it as an indexer. + nextToken(); + return token === SyntaxKind.ColonToken || token === SyntaxKind.CommaToken || token === SyntaxKind.CloseBracketToken; } function parseIndexSignatureDeclaration(fullStart: number, modifiers: ModifiersArray): IndexSignatureDeclaration { @@ -2005,19 +2064,16 @@ module ts { function parsePropertyOrMethod(): Declaration { var fullStart = scanner.getStartPos(); var name = parsePropertyName(); - var flags = 0; - if (parseOptional(SyntaxKind.QuestionToken)) { - flags = NodeFlags.QuestionMark; - } + var questionToken = parseOptionalToken(SyntaxKind.QuestionToken); if (token === SyntaxKind.OpenParenToken || token === SyntaxKind.LessThanToken) { var method = createNode(SyntaxKind.Method, fullStart); method.name = name; - method.flags = flags; + method.questionToken = questionToken; // Method signatues don't exist in expression contexts. So they have neither // [Yield] nor [GeneratorParameter] - fillSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false, /*yieldAndGeneratorParameterContext:*/ false, method); + fillSignature(SyntaxKind.ColonToken, /*yieldAndGeneratorParameterContext:*/ false, method); parseSemicolon(); return finishNode(method); @@ -2025,7 +2081,7 @@ module ts { else { var property = createNode(SyntaxKind.Property, fullStart); property.name = name; - property.flags = flags; + property.questionToken = questionToken; property.type = parseTypeAnnotation(); parseSemicolon(); return finishNode(property); @@ -2039,40 +2095,54 @@ module ts { case SyntaxKind.OpenBracketToken: // Both for indexers and computed properties return true; default: - return isLiteralPropertyName() && lookAhead(() => nextToken() === SyntaxKind.OpenParenToken || token === SyntaxKind.LessThanToken || token === SyntaxKind.QuestionToken || - token === SyntaxKind.ColonToken || canParseSemicolon()); + return isLiteralPropertyName() && lookAhead(isTypeMemberWithLiteralPropertyName); } } + function isTypeMemberWithLiteralPropertyName() { + nextToken(); + return token === SyntaxKind.OpenParenToken || + token === SyntaxKind.LessThanToken || + token === SyntaxKind.QuestionToken || + token === SyntaxKind.ColonToken || + canParseSemicolon(); + } + function parseTypeMember(): Declaration { switch (token) { case SyntaxKind.OpenParenToken: case SyntaxKind.LessThanToken: - return parseSignatureMember(SyntaxKind.CallSignature, SyntaxKind.ColonToken); + return parseSignatureMember(SyntaxKind.CallSignature); case SyntaxKind.OpenBracketToken: // Indexer or computed property return isIndexSignature() ? parseIndexSignatureDeclaration(scanner.getStartPos(), /*modifiers:*/ undefined) : parsePropertyOrMethod(); case SyntaxKind.NewKeyword: - if (lookAhead(() => nextToken() === SyntaxKind.OpenParenToken || token === SyntaxKind.LessThanToken)) { - return parseSignatureMember(SyntaxKind.ConstructSignature, SyntaxKind.ColonToken); + if (lookAhead(isStartOfConstructSignature)) { + return parseSignatureMember(SyntaxKind.ConstructSignature); } + // fall through. case SyntaxKind.StringLiteral: case SyntaxKind.NumericLiteral: return parsePropertyOrMethod(); default: - if (token >= SyntaxKind.Identifier) { + if (isIdentifierOrKeyword()) { return parsePropertyOrMethod(); } } } + function isStartOfConstructSignature() { + nextToken(); + return token === SyntaxKind.OpenParenToken || token === SyntaxKind.LessThanToken; + } + function parseTypeLiteral(): TypeLiteralNode { var node = createNode(SyntaxKind.TypeLiteral); - node.members = parseObjectType(); + node.members = parseObjectTypeMembers(); return finishNode(node); } - function parseObjectType(): NodeArray { + function parseObjectTypeMembers(): NodeArray { var members: NodeArray; if (parseExpected(SyntaxKind.OpenBraceToken)) { members = parseList(ParsingContext.TypeMembers, /*checkForStrictMode*/ false, parseTypeMember); @@ -2091,7 +2161,7 @@ module ts { return finishNode(node); } - function parseParenType(): ParenthesizedTypeNode { + function parseParenthesizedType(): ParenthesizedTypeNode { var node = createNode(SyntaxKind.ParenthesizedType); parseExpected(SyntaxKind.OpenParenToken); node.type = parseType(); @@ -2099,10 +2169,12 @@ module ts { return finishNode(node); } - function parseFunctionType(typeKind: SyntaxKind): FunctionOrConstructorTypeNode { - var node = createNode(typeKind); - fillSignature(typeKind === SyntaxKind.FunctionType ? SyntaxKind.CallSignature : SyntaxKind.ConstructSignature, - SyntaxKind.EqualsGreaterThanToken, /* returnTokenRequired */ true, /*yieldAndGeneratorParameterContext:*/ false, node); + function parseFunctionOrConstructorType(kind: SyntaxKind): FunctionOrConstructorTypeNode { + var node = createNode(kind); + if (kind === SyntaxKind.ConstructorType) { + parseExpected(SyntaxKind.NewKeyword); + } + fillSignature(SyntaxKind.EqualsGreaterThanToken, /*yieldAndGeneratorParameterContext:*/ false, node); return finishNode(node); } @@ -2129,7 +2201,7 @@ module ts { case SyntaxKind.OpenBracketToken: return parseTupleType(); case SyntaxKind.OpenParenToken: - return parseParenType(); + return parseParenthesizedType(); default: return parseTypeReference(); } @@ -2151,16 +2223,18 @@ module ts { case SyntaxKind.OpenParenToken: // Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier, // or something that starts a type. We don't want to consider things like '(1)' a type. - return lookAhead(() => { - nextToken(); - return token === SyntaxKind.CloseParenToken || isStartOfParameter() || isStartOfType(); - }); + return lookAhead(isStartOfParenthesizedOrFunctionType); default: return isIdentifier(); } } - function parsePrimaryType(): TypeNode { + function isStartOfParenthesizedOrFunctionType() { + nextToken(); + return token === SyntaxKind.CloseParenToken || isStartOfParameter() || isStartOfType(); + } + + function parseArrayTypeOrHigher(): TypeNode { var type = parseNonArrayType(); while (!scanner.hasPrecedingLineBreak() && parseOptional(SyntaxKind.OpenBracketToken)) { parseExpected(SyntaxKind.CloseBracketToken); @@ -2171,13 +2245,13 @@ module ts { return type; } - function parseUnionType(): TypeNode { - var type = parsePrimaryType(); + function parseUnionTypeOrHigher(): TypeNode { + var type = parseArrayTypeOrHigher(); if (token === SyntaxKind.BarToken) { var types = >[type]; types.pos = type.pos; while (parseOptional(SyntaxKind.BarToken)) { - types.push(parsePrimaryType()); + types.push(parseArrayTypeOrHigher()); } types.end = getNodeEnd(); var node = createNode(SyntaxKind.UnionType, type.pos); @@ -2188,35 +2262,41 @@ module ts { } function isStartOfFunctionType(): boolean { - return token === SyntaxKind.LessThanToken || token === SyntaxKind.OpenParenToken && lookAhead(() => { + if (token === SyntaxKind.LessThanToken) { + return true; + } + + return token === SyntaxKind.OpenParenToken && lookAhead(isUnambiguouslyStartOfFunctionType); + } + + function isUnambiguouslyStartOfFunctionType() { + nextToken(); + if (token === SyntaxKind.CloseParenToken || token === SyntaxKind.DotDotDotToken) { + // ( ) + // ( ... + return true; + } + if (isIdentifier() || isModifier(token)) { nextToken(); - if (token === SyntaxKind.CloseParenToken || token === SyntaxKind.DotDotDotToken) { - // ( ) - // ( ... + if (token === SyntaxKind.ColonToken || token === SyntaxKind.CommaToken || + token === SyntaxKind.QuestionToken || token === SyntaxKind.EqualsToken || + isIdentifier() || isModifier(token)) { + // ( id : + // ( id , + // ( id ? + // ( id = + // ( modifier id return true; } - if (isIdentifier() || isModifier(token)) { + if (token === SyntaxKind.CloseParenToken) { nextToken(); - if (token === SyntaxKind.ColonToken || token === SyntaxKind.CommaToken || - token === SyntaxKind.QuestionToken || token === SyntaxKind.EqualsToken || - isIdentifier() || isModifier(token)) { - // ( id : - // ( id , - // ( id ? - // ( id = - // ( modifier id + if (token === SyntaxKind.EqualsGreaterThanToken) { + // ( id ) => return true; } - if (token === SyntaxKind.CloseParenToken) { - nextToken(); - if (token === SyntaxKind.EqualsGreaterThanToken) { - // ( id ) => - return true; - } - } } - return false; - }); + } + return false; } function parseType(): TypeNode { @@ -2238,12 +2318,12 @@ module ts { function parseTypeWorker(): TypeNode { if (isStartOfFunctionType()) { - return parseFunctionType(SyntaxKind.FunctionType); + return parseFunctionOrConstructorType(SyntaxKind.FunctionType); } if (token === SyntaxKind.NewKeyword) { - return parseFunctionType(SyntaxKind.ConstructorType); + return parseFunctionOrConstructorType(SyntaxKind.ConstructorType); } - return parseUnionType(); + return parseUnionTypeOrHigher(); } function parseTypeAnnotation(): TypeNode { @@ -2419,15 +2499,17 @@ module ts { // for now we just check if the next token is an identifier. More heuristics // can be added here later as necessary. We just need to make sure that we // don't accidently consume something legal. - return lookAhead(() => { - nextToken(); - return !scanner.hasPrecedingLineBreak() && isIdentifier(); - }); + return lookAhead(nextTokenIsIdentifierOnSameLine); } return false; } + function nextTokenIsIdentifierOnSameLine() { + nextToken(); + return !scanner.hasPrecedingLineBreak() && isIdentifier() + } + function parseYieldExpression(): YieldExpression { var node = createNode(SyntaxKind.YieldExpression); @@ -2452,57 +2534,55 @@ module ts { function parseSimpleArrowFunctionExpression(identifier: Identifier): Expression { Debug.assert(token === SyntaxKind.EqualsGreaterThanToken, "parseSimpleArrowFunctionExpression should only have been called if we had a =>"); - parseExpected(SyntaxKind.EqualsGreaterThanToken); + + var node = createNode(SyntaxKind.ArrowFunction, identifier.pos); var parameter = createNode(SyntaxKind.Parameter, identifier.pos); parameter.name = identifier; finishNode(parameter); - var parameters = >[]; - parameters.push(parameter); - parameters.pos = parameter.pos; - parameters.end = parameter.end; + node.parameters = >[parameter]; + node.parameters.pos = parameter.pos; + node.parameters.end = parameter.end; - var signature = { parameters: parameters }; + parseExpected(SyntaxKind.EqualsGreaterThanToken); + node.body = parseArrowFunctionExpressionBody(); - return parseArrowExpressionTail(identifier.pos, signature); + return finishNode(node); } function tryParseParenthesizedArrowFunctionExpression(): Expression { - // Indicates whether we are certain that we should parse an arrow expression. var triState = isParenthesizedArrowFunctionExpression(); if (triState === Tristate.False) { + // It's definitely not a parenthesized arrow function expression. return undefined; } - var pos = getNodePos(); + // If we definitely have an arrow function, then we can just parse one, not requiring a + // following => or { token. Otherwise, we *might* have an arrow function. Try to parse + // it out, but don't allow any ambiguity, and return 'undefined' if this could be an + // expression instead. + var arrowFunction = triState === Tristate.True + ? parseParenthesizedArrowFunctionExpressionHead(/*allowAmbiguity:*/ true) + : tryParse(parsePossibleParenthesizedArrowFunctionExpressionHead); - if (triState === Tristate.True) { - // Arrow function are never generators. - var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /*returnTokenRequired:*/ false, /*yieldAndGeneratorParameterContext:*/ false); - - // If we have an arrow, then try to parse the body. - // Even if not, try to parse if we have an opening brace, just in case we're in an error state. - if (parseExpected(SyntaxKind.EqualsGreaterThanToken) || token === SyntaxKind.OpenBraceToken) { - return parseArrowExpressionTail(pos, sig); - } - else { - // If not, we're probably better off bailing out and returning a bogus function expression. - return makeFunctionExpression(SyntaxKind.ArrowFunction, pos, /*asteriskToken:*/ undefined, /*name:*/ undefined, sig, parseIdentifier(Diagnostics.Expression_expected)); - } + if (!arrowFunction) { + // Didn't appear to actually be a parenthesized arrow function. Just bail out. + return undefined; } - - // *Maybe* we had an arrow function and we need to try to parse it out, - // rolling back and trying other parses if we fail. - var sig = tryParseSignatureIfArrowOrBraceFollows(); - if (sig) { - parseExpected(SyntaxKind.EqualsGreaterThanToken); - return parseArrowExpressionTail(pos, sig); + + // If we have an arrow, then try to parse the body. Even if not, try to parse if we + // have an opening brace, just in case we're in an error state. + if (parseExpected(SyntaxKind.EqualsGreaterThanToken) || token === SyntaxKind.OpenBraceToken) { + arrowFunction.body = parseArrowFunctionExpressionBody(); } else { - return undefined; + // If not, we're probably better off bailing out and returning a bogus function expression. + arrowFunction.body = parseIdentifier(); } + + return finishNode(arrowFunction); } // True -> We definitely expect a parenthesized arrow function here. @@ -2511,66 +2591,9 @@ module ts { // Speculatively look ahead to be sure, and rollback if not. function isParenthesizedArrowFunctionExpression(): Tristate { if (token === SyntaxKind.OpenParenToken || token === SyntaxKind.LessThanToken) { - return lookAhead(() => { - var first = token; - var second = nextToken(); - - if (first === SyntaxKind.OpenParenToken) { - if (second === SyntaxKind.CloseParenToken) { - // Simple cases: "() =>", "(): ", and "() {". - // This is an arrow function with no parameters. - // The last one is not actually an arrow function, - // but this is probably what the user intended. - var third = nextToken(); - switch (third) { - case SyntaxKind.EqualsGreaterThanToken: - case SyntaxKind.ColonToken: - case SyntaxKind.OpenBraceToken: - return Tristate.True; - default: - return Tristate.False; - } - } - - // Simple case: "(..." - // This is an arrow function with a rest parameter. - if (second === SyntaxKind.DotDotDotToken) { - return Tristate.True; - } - - // If we had "(" followed by something that's not an identifier, - // then this definitely doesn't look like a lambda. - // Note: we could be a little more lenient and allow - // "(public" or "(private". These would not ever actually be allowed, - // but we could provide a good error message instead of bailing out. - if (!isIdentifier()) { - return Tristate.False; - } - - // If we have something like "(a:", then we must have a - // type-annotated parameter in an arrow function expression. - if (nextToken() === SyntaxKind.ColonToken) { - return Tristate.True; - } - - // This *could* be a parenthesized arrow function. - // Return Unknown to let the caller know. - return Tristate.Unknown; - } - else { - Debug.assert(first === SyntaxKind.LessThanToken); - - // If we have "<" not followed by an identifier, - // then this definitely is not an arrow function. - if (!isIdentifier()) { - return Tristate.False; - } - - // This *could* be a parenthesized arrow function. - return Tristate.Unknown; - } - }); + return lookAhead(isParenthesizedArrowFunctionExpressionWorker); } + if (token === SyntaxKind.EqualsGreaterThanToken) { // ERROR RECOVERY TWEAK: // If we see a standalone => try to parse it as an arrow function expression as that's @@ -2581,34 +2604,97 @@ module ts { return Tristate.False; } - function tryParseSignatureIfArrowOrBraceFollows(): ParsedSignature { - return tryParse(() => { - // Arrow functions are never generators. - var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false, /*yieldAndGeneratorParameterContext:*/ false); + function isParenthesizedArrowFunctionExpressionWorker() { + var first = token; + var second = nextToken(); - // Parsing a signature isn't enough. - // Parenthesized arrow signatures often look like other valid expressions. - // For instance: - // - "(x = 10)" is an assignment expression parsed as a signature with a default parameter value. - // - "(x,y)" is a comma expression parsed as a signature with two parameters. - // - "a ? (b): c" will have "(b):" parsed as a signature with a return type annotation. - // - // So we need just a bit of lookahead to ensure that it can only be a signature. - if (token === SyntaxKind.EqualsGreaterThanToken || token === SyntaxKind.OpenBraceToken) { - return sig; + if (first === SyntaxKind.OpenParenToken) { + if (second === SyntaxKind.CloseParenToken) { + // Simple cases: "() =>", "(): ", and "() {". + // This is an arrow function with no parameters. + // The last one is not actually an arrow function, + // but this is probably what the user intended. + var third = nextToken(); + switch (third) { + case SyntaxKind.EqualsGreaterThanToken: + case SyntaxKind.ColonToken: + case SyntaxKind.OpenBraceToken: + return Tristate.True; + default: + return Tristate.False; + } } - return undefined; - }); + // Simple case: "(..." + // This is an arrow function with a rest parameter. + if (second === SyntaxKind.DotDotDotToken) { + return Tristate.True; + } + + // If we had "(" followed by something that's not an identifier, + // then this definitely doesn't look like a lambda. + // Note: we could be a little more lenient and allow + // "(public" or "(private". These would not ever actually be allowed, + // but we could provide a good error message instead of bailing out. + if (!isIdentifier()) { + return Tristate.False; + } + + // If we have something like "(a:", then we must have a + // type-annotated parameter in an arrow function expression. + if (nextToken() === SyntaxKind.ColonToken) { + return Tristate.True; + } + + // This *could* be a parenthesized arrow function. + // Return Unknown to let the caller know. + return Tristate.Unknown; + } + else { + Debug.assert(first === SyntaxKind.LessThanToken); + + // If we have "<" not followed by an identifier, + // then this definitely is not an arrow function. + if (!isIdentifier()) { + return Tristate.False; + } + + // This *could* be a parenthesized arrow function. + return Tristate.Unknown; + } } - function parseArrowExpressionTail(pos: number, sig: ParsedSignature): FunctionExpression { - var body: Block | Expression; + function parsePossibleParenthesizedArrowFunctionExpressionHead() { + return parseParenthesizedArrowFunctionExpressionHead(/*allowAmbiguity:*/ false); + } - if (token === SyntaxKind.OpenBraceToken) { - body = parseFunctionBlock(/*allowYield:*/ false, /* ignoreMissingOpenBrace */ false); + function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity: boolean): FunctionExpression { + var node = createNode(SyntaxKind.ArrowFunction); + // Arrow functions are never generators. + fillSignature(SyntaxKind.ColonToken, /*yieldAndGeneratorParameterContext:*/ false, node); + + // Parsing a signature isn't enough. + // Parenthesized arrow signatures often look like other valid expressions. + // For instance: + // - "(x = 10)" is an assignment expression parsed as a signature with a default parameter value. + // - "(x,y)" is a comma expression parsed as a signature with two parameters. + // - "a ? (b): c" will have "(b):" parsed as a signature with a return type annotation. + // + // So we need just a bit of lookahead to ensure that it can only be a signature. + if (!allowAmbiguity && token !== SyntaxKind.EqualsGreaterThanToken && token !== SyntaxKind.OpenBraceToken) { + // Returning undefined here will cause our caller to rewind to where we started from. + return undefined; } - else if (isStatement(/* inErrorRecovery */ true) && !isStartOfExpressionStatement() && token !== SyntaxKind.FunctionKeyword) { + + return node; + } + + function parseArrowFunctionExpressionBody(): Block | Expression { + if (token === SyntaxKind.OpenBraceToken) { + return parseFunctionBlock(/*allowYield:*/ false, /* ignoreMissingOpenBrace */ false); + } + + if (isStatement(/* inErrorRecovery */ true) && !isStartOfExpressionStatement() && token !== SyntaxKind.FunctionKeyword) { // Check if we got a plain statement (i.e. no expression-statements, no functions expressions/declarations) // // Here we try to recover from a potential error situation in the case where the @@ -2623,13 +2709,10 @@ module ts { // up preemptively closing the containing construct. // // Note: even when 'ignoreMissingOpenBrace' is passed as true, parseBody will still error. - body = parseFunctionBlock(/*allowYield:*/ false, /* ignoreMissingOpenBrace */ true); - } - else { - body = parseAssignmentExpressionOrHigher(); + return parseFunctionBlock(/*allowYield:*/ false, /* ignoreMissingOpenBrace */ true); } - return makeFunctionExpression(SyntaxKind.ArrowFunction, pos, /*asteriskToken:*/ undefined, /*name:*/ undefined, sig, body); + return parseAssignmentExpressionOrHigher(); } function parseConditionalExpressionRest(leftOperand: Expression): Expression { @@ -2730,9 +2813,8 @@ module ts { function parsePrefixUnaryExpression() { var node = createNode(SyntaxKind.PrefixUnaryExpression); - var operator = token; + node.operator = token; nextToken(); - node.operator = operator; node.operand = parseUnaryExpressionOrHigher(); return finishNode(node); } @@ -2826,13 +2908,9 @@ module ts { // the last two CallExpression productions. Or we have a MemberExpression which either // completes the LeftHandSideExpression, or starts the beginning of the first four // CallExpression productions. - var expression: MemberExpression; - if (token === SyntaxKind.SuperKeyword) { - expression = parseSuperExpression(); - } - else { - expression = parseMemberExpressionOrHigher(); - } + var expression = token === SyntaxKind.SuperKeyword + ? parseSuperExpression() + : parseMemberExpressionOrHigher(); // Now, we *may* be complete. However, we might have consumed the start of a // CallExpression. As such, we need to consume the rest of it here to be complete. @@ -3098,7 +3176,7 @@ module ts { if (asteriskToken || token === SyntaxKind.OpenParenToken || token === SyntaxKind.LessThanToken) { node = createNode(SyntaxKind.PropertyAssignment, nodePos); node.name = propertyName; - var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false, /*yieldAndGeneratorParameterContext:*/ !!asteriskToken); + var sig = parseSignature(/*yieldAndGeneratorParameterContext:*/ !!asteriskToken); var body = parseFunctionBlock(!!asteriskToken, /* ignoreMissingOpenBrace */ false); // do not propagate property name as name for function expression @@ -3110,28 +3188,24 @@ module ts { return finishNode(node); } - var flags: NodeFlags = 0; - // Disallowing of optional property assignments happens in the grammar checker. - if (token === SyntaxKind.QuestionToken) { - flags |= NodeFlags.QuestionMark; - nextToken(); - } + var questionToken = parseOptionalToken(SyntaxKind.QuestionToken); // Parse to check if it is short-hand property assignment or normal property assignment if ((token === SyntaxKind.CommaToken || token === SyntaxKind.CloseBraceToken) && tokenIsIdentifier) { - node = createNode(SyntaxKind.ShorthandPropertyAssignment, nodePos); - node.name = propertyName; + var shorthandDeclaration = createNode(SyntaxKind.ShorthandPropertyAssignment, nodePos); + shorthandDeclaration.name = propertyName; + shorthandDeclaration.questionToken = questionToken; + return finishNode(shorthandDeclaration); } else { - node = createNode(SyntaxKind.PropertyAssignment, nodePos); - node.name = propertyName; + var propertyDeclaration = createNode(SyntaxKind.PropertyAssignment, nodePos); + propertyDeclaration.name = propertyName; + propertyDeclaration.questionToken = questionToken; parseExpected(SyntaxKind.ColonToken); - (node).initializer = allowInAnd(parseAssignmentExpressionOrHigher); + propertyDeclaration.initializer = allowInAnd(parseAssignmentExpressionOrHigher); + return finishNode(propertyDeclaration); } - - node.flags = flags; - return finishNode(node); } function parseObjectLiteralMember(): Declaration { @@ -3161,15 +3235,13 @@ module ts { // function * BindingIdentifier[Yield]opt (FormalParameters[Yield, GeneratorParameter]) { GeneratorBody[Yield] } // FunctionExpression: // function BindingIdentifieropt(FormalParameters) { FunctionBody } - - var pos = getNodePos(); + var node = createNode(SyntaxKind.FunctionExpression); parseExpected(SyntaxKind.FunctionKeyword); - var asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); - var name = asteriskToken ? doInYieldContext(parseOptionalIdentifier) : parseOptionalIdentifier(); - var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false, /*yieldAndGeneratorParameterContext:*/ !!asteriskToken); - - var body = parseFunctionBlock(/*allowYield:*/ !!asteriskToken, /* ignoreMissingOpenBrace */ false); - return makeFunctionExpression(SyntaxKind.FunctionExpression, pos, asteriskToken, name, sig, body); + node.asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); + node.name = node.asteriskToken ? doInYieldContext(parseOptionalIdentifier) : parseOptionalIdentifier(); + fillSignature(SyntaxKind.ColonToken, /*yieldAndGeneratorParameterContext:*/ !!node.asteriskToken, node); + node.body = parseFunctionBlock(/*allowYield:*/ !!node.asteriskToken, /* ignoreMissingOpenBrace */ false); + return finishNode(node); } function parseOptionalIdentifier() { @@ -3191,7 +3263,11 @@ module ts { var node = createNode(SyntaxKind.NewExpression); parseExpected(SyntaxKind.NewKeyword); node.expression = parseMemberExpressionOrHigher(); - if (parseOptional(SyntaxKind.OpenParenToken) || (token === SyntaxKind.LessThanToken && (node.typeArguments = tryParse(parseTypeArgumentsAndOpenParen)))) { + if (token === SyntaxKind.LessThanToken) { + node.typeArguments = tryParse(parseTypeArgumentsAndOpenParen); + } + + if (node.typeArguments || parseOptional(SyntaxKind.OpenParenToken)) { node.arguments = parseDelimitedList(ParsingContext.ArgumentExpressions, parseArgumentExpression); parseExpected(SyntaxKind.CloseParenToken); } @@ -3357,8 +3433,8 @@ module ts { return finishNode(node); } - function parseCaseClause(): CaseOrDefaultClause { - var node = createNode(SyntaxKind.CaseClause); + function parseCaseClause(): CaseClause { + var node = createNode(SyntaxKind.CaseClause); parseExpected(SyntaxKind.CaseKeyword); node.expression = allowInAnd(parseExpression); parseExpected(SyntaxKind.ColonToken); @@ -3366,8 +3442,8 @@ module ts { return finishNode(node); } - function parseDefaultClause(): CaseOrDefaultClause { - var node = createNode(SyntaxKind.DefaultClause); + function parseDefaultClause(): DefaultClause { + var node = createNode(SyntaxKind.DefaultClause); parseExpected(SyntaxKind.DefaultKeyword); parseExpected(SyntaxKind.ColonToken); node.statements = parseList(ParsingContext.SwitchClauseStatements, /*checkForStrictMode*/ false, parseStatement); @@ -3385,9 +3461,7 @@ module ts { node.expression = allowInAnd(parseExpression); parseExpected(SyntaxKind.CloseParenToken); parseExpected(SyntaxKind.OpenBraceToken); - node.clauses = parseList(ParsingContext.SwitchClauses, /*checkForStrictMode*/ false, parseCaseOrDefaultClause); - parseExpected(SyntaxKind.CloseBraceToken); return finishNode(node); } @@ -3412,11 +3486,11 @@ module ts { function parseTryStatement(): TryStatement { var node = createNode(SyntaxKind.TryStatement); node.tryBlock = parseTokenAndBlock(SyntaxKind.TryKeyword); - node.catchBlock = token === SyntaxKind.CatchKeyword ? parseCatchBlock() : undefined; + node.catchClause = token === SyntaxKind.CatchKeyword ? parseCatchClause() : undefined; // If we don't have a catch clause, then we must have a finally clause. Try to parse // one out no matter what. - node.finallyBlock = !node.catchBlock || token === SyntaxKind.FinallyKeyword + node.finallyBlock = !node.catchClause || token === SyntaxKind.FinallyKeyword ? parseTokenAndBlock(SyntaxKind.FinallyKeyword) : undefined; return finishNode(node); @@ -3432,19 +3506,15 @@ module ts { return result; } - function parseCatchBlock(): CatchBlock { - var pos = getNodePos(); + function parseCatchClause(): CatchClause { + var result = createNode(SyntaxKind.CatchClause); parseExpected(SyntaxKind.CatchKeyword); parseExpected(SyntaxKind.OpenParenToken); - var variable = parseIdentifier(); - var typeAnnotation = parseTypeAnnotation(); + result.name = parseIdentifier(); + result.type = parseTypeAnnotation(); parseExpected(SyntaxKind.CloseParenToken); - var result = parseBlock(SyntaxKind.CatchBlock, /* ignoreMissingOpenBrace */ false, /*checkForStrictMode*/ false); - result.pos = pos; - result.variable = variable; - result.type = typeAnnotation; - - return result; + result.block = parseBlock(SyntaxKind.Block, /* ignoreMissingOpenBrace */ false, /*checkForStrictMode*/ false); + return finishNode(result); } function parseDebuggerStatement(): Statement { @@ -3455,7 +3525,11 @@ module ts { } function isLabel(): boolean { - return isIdentifier() && lookAhead(() => nextToken() === SyntaxKind.ColonToken); + return isIdentifier() && lookAhead(nextTokenIsColonToken); + } + + function nextTokenIsColonToken() { + return nextToken() === SyntaxKind.ColonToken; } function parseLabeledStatement(): LabeledStatement { @@ -3508,7 +3582,7 @@ module ts { // const keyword can precede enum keyword when defining constant enums // 'const enum' do not start statement. // In ES 6 'enum' is a future reserved keyword, so it should not be used as identifier - var isConstEnum = lookAhead(() => nextToken() === SyntaxKind.EnumKeyword); + var isConstEnum = lookAhead(nextTokenIsEnumKeyword); return !isConstEnum; case SyntaxKind.InterfaceKeyword: case SyntaxKind.ClassKeyword: @@ -3527,7 +3601,7 @@ module ts { case SyntaxKind.StaticKeyword: // When followed by an identifier or keyword, these do not start a statement but // might instead be following type members - if (lookAhead(() => nextToken() >= SyntaxKind.Identifier)) { + if (lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine)) { return false; } default: @@ -3535,6 +3609,16 @@ module ts { } } + function nextTokenIsEnumKeyword() { + nextToken(); + return token === SyntaxKind.EnumKeyword + } + + function nextTokenIsIdentifierOrKeywordOnSameLine() { + nextToken(); + return isIdentifierOrKeyword() && !scanner.hasPrecedingLineBreak(); + } + function parseStatement(): Statement { switch (token) { case SyntaxKind.OpenBraceToken: @@ -3641,7 +3725,7 @@ module ts { parseExpected(SyntaxKind.FunctionKeyword); node.asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); node.name = parseIdentifier(); - fillSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false, /*yieldAndGeneratorParameterContext:*/ !!node.asteriskToken, node); + fillSignature(SyntaxKind.ColonToken, /*yieldAndGeneratorParameterContext:*/ !!node.asteriskToken, node); node.body = parseFunctionBlockOrSemicolon(!!node.asteriskToken); return finishNode(node); } @@ -3650,52 +3734,49 @@ module ts { var node = createNode(SyntaxKind.Constructor, pos); setModifiers(node, modifiers); parseExpected(SyntaxKind.ConstructorKeyword); - fillSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false, /*yieldAndGeneratorParameterContext:*/ false, node); + fillSignature(SyntaxKind.ColonToken, /*yieldAndGeneratorParameterContext:*/ false, node); node.body = parseFunctionBlockOrSemicolon(/*isGenerator:*/ false); return finishNode(node); } function parsePropertyMemberDeclaration(fullStart: number, modifiers: ModifiersArray): ClassElement { - var flags = modifiers ? modifiers.flags : 0; var asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); var name = parsePropertyName(); - if (parseOptional(SyntaxKind.QuestionToken)) { - // Note: this is not legal as per the grammar. But we allow it in the parser and - // report an error in the grammar checker. - flags |= NodeFlags.QuestionMark; - } + // Note: this is not legal as per the grammar. But we allow it in the parser and + // report an error in the grammar checker. + var questionToken = parseOptionalToken(SyntaxKind.QuestionToken); if (asteriskToken || token === SyntaxKind.OpenParenToken || token === SyntaxKind.LessThanToken) { var method = createNode(SyntaxKind.Method, fullStart); setModifiers(method, modifiers); - if (flags) { - method.flags = flags; - } method.asteriskToken = asteriskToken; method.name = name; - fillSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false, /*yieldAndGeneratorParameterContext:*/ !!asteriskToken, method); + method.questionToken = questionToken; + fillSignature(SyntaxKind.ColonToken, /*yieldAndGeneratorParameterContext:*/ !!asteriskToken, method); method.body = parseFunctionBlockOrSemicolon(!!asteriskToken); return finishNode(method); } else { var property = createNode(SyntaxKind.Property, fullStart); setModifiers(property, modifiers); - if (flags) { - property.flags = flags; - } property.name = name; + property.questionToken = questionToken; property.type = parseTypeAnnotation(); - property.initializer = allowInAnd(() => parseInitializer(/*inParameter*/ false)); + property.initializer = allowInAnd(parseNonParameterInitializer); parseSemicolon(); return finishNode(property); } } + function parseNonParameterInitializer() { + return parseInitializer(/*inParameter*/ false); + } + function parseMemberAccessorDeclaration(kind: SyntaxKind, fullStart: number, modifiers: ModifiersArray): MethodDeclaration { var node = createNode(kind, fullStart); setModifiers(node, modifiers); node.name = parsePropertyName(); - fillSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false, /*yieldAndGeneratorParameterContext:*/ false, node); + fillSignature(SyntaxKind.ColonToken, /*yieldAndGeneratorParameterContext:*/ false, node); node.body = parseFunctionBlockOrSemicolon(/*isGenerator:*/ false); return finishNode(node); } @@ -3758,7 +3839,7 @@ module ts { var flags = 0; var modifiers: ModifiersArray; while (true) { - var modifierStart = scanner.getTokenPos(); + var modifierStart = scanner.getStartPos(); var modifierKind = token; if (!parseAnyContextualModifier()) { @@ -3767,12 +3848,14 @@ module ts { if (!modifiers) { modifiers = []; + modifiers.pos = modifierStart; } flags |= modifierToFlag(modifierKind); modifiers.push(finishNode(createNode(modifierKind, modifierStart))); } if (modifiers) { modifiers.flags = flags; + modifiers.end = scanner.getStartPos(); } return modifiers; } @@ -3794,7 +3877,7 @@ module ts { } // It is very important that we check this *after* checking indexers because // the [ token can start an index signature or a computed property name - if (token >= SyntaxKind.Identifier || token === SyntaxKind.StringLiteral || token === SyntaxKind.NumericLiteral || + if (isIdentifierOrKeyword() || token === SyntaxKind.StringLiteral || token === SyntaxKind.NumericLiteral || token === SyntaxKind.AsteriskToken || token === SyntaxKind.OpenBracketToken) { return parsePropertyMemberDeclaration(fullStart, modifiers); } @@ -3872,7 +3955,7 @@ module ts { node.name = parseIdentifier(); node.typeParameters = parseTypeParameters(); node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause:*/ false); - node.members = parseObjectType(); + node.members = parseObjectTypeMembers(); return finishNode(node); } @@ -3894,11 +3977,11 @@ module ts { function parseEnumMember(): EnumMember { var node = createNode(SyntaxKind.EnumMember, scanner.getStartPos()); node.name = parsePropertyName(); - node.initializer = allowInAnd(() => parseInitializer(/*inParameter*/ false)); + node.initializer = allowInAnd(parseNonParameterInitializer); return finishNode(node); } - function parseAndCheckEnumDeclaration(fullStart: number, modifiers: ModifiersArray, flags: NodeFlags): EnumDeclaration { + function parseEnumDeclaration(fullStart: number, modifiers: ModifiersArray): EnumDeclaration { var node = createNode(SyntaxKind.EnumDeclaration, fullStart); setModifiers(node, modifiers); parseExpected(SyntaxKind.EnumKeyword); @@ -3916,7 +3999,7 @@ module ts { function parseModuleBlock(): ModuleBlock { var node = createNode(SyntaxKind.ModuleBlock, scanner.getStartPos()); if (parseExpected(SyntaxKind.OpenBraceToken)) { - node.statements = parseList(ParsingContext.ModuleElements, /*checkForStrictMode*/ false, parseModuleElement); + node.statements = parseList(ParsingContext.ModuleElements, /*checkForStrictMode*/false, parseModuleElement); parseExpected(SyntaxKind.CloseBraceToken); } else { @@ -3936,31 +4019,28 @@ module ts { return finishNode(node); } - function parseAmbientExternalModuleDeclaration(fullStart: number, modifiers: ModifiersArray, flags: NodeFlags): ModuleDeclaration { + function parseAmbientExternalModuleDeclaration(fullStart: number, modifiers: ModifiersArray): ModuleDeclaration { var node = createNode(SyntaxKind.ModuleDeclaration, fullStart); setModifiers(node, modifiers); - node.flags |= flags; node.name = parseLiteralNode(/*internName:*/ true); node.body = parseModuleBlock(); return finishNode(node); } - function parseModuleDeclaration(fullStart: number, modifiers: ModifiersArray, flags: NodeFlags): ModuleDeclaration { + function parseModuleDeclaration(fullStart: number, modifiers: ModifiersArray): ModuleDeclaration { parseExpected(SyntaxKind.ModuleKeyword); return token === SyntaxKind.StringLiteral - ? parseAmbientExternalModuleDeclaration(fullStart, modifiers, flags) - : parseInternalModuleTail(fullStart, modifiers, flags); + ? parseAmbientExternalModuleDeclaration(fullStart, modifiers) + : parseInternalModuleTail(fullStart, modifiers, modifiers? modifiers.flags : 0); } function isExternalModuleReference() { - if (token === SyntaxKind.RequireKeyword) { - return lookAhead(() => { - nextToken(); - return token === SyntaxKind.OpenParenToken; - }); - } + return token === SyntaxKind.RequireKeyword && + lookAhead(nextTokenIsOpenParen); + } - return false; + function nextTokenIsOpenParen() { + return nextToken() === SyntaxKind.OpenParenToken; } function parseImportDeclaration(fullStart: number, modifiers: ModifiersArray): ImportDeclaration { @@ -3989,9 +4069,13 @@ module ts { // literals. We check to ensure that it is only a string literal later in the grammar // walker. node.expression = parseExpression(); + + // Ensure the string being required is in our 'identifier' table. This will ensure + // that features like 'find refs' will look inside this file when search for its name. if (node.expression.kind === SyntaxKind.StringLiteral) { internIdentifier((node.expression).text); } + parseExpected(SyntaxKind.CloseParenToken); return finishNode(node); } @@ -4017,23 +4101,47 @@ module ts { case SyntaxKind.ImportKeyword: case SyntaxKind.TypeKeyword: // Not true keywords so ensure an identifier follows - return lookAhead(() => nextToken() >= SyntaxKind.Identifier); + return lookAhead(nextTokenIsIdentifierOrKeyword); case SyntaxKind.ModuleKeyword: // Not a true keyword so ensure an identifier or string literal follows - return lookAhead(() => nextToken() >= SyntaxKind.Identifier || token === SyntaxKind.StringLiteral); + return lookAhead(nextTokenIsIdentifierOrKeywordOrStringLiteral); case SyntaxKind.ExportKeyword: // Check for export assignment or modifier on source element - return lookAhead(() => nextToken() === SyntaxKind.EqualsToken || isDeclarationStart()); + return lookAhead(nextTokenIsEqualsTokenOrDeclarationStart); case SyntaxKind.DeclareKeyword: case SyntaxKind.PublicKeyword: case SyntaxKind.PrivateKeyword: case SyntaxKind.ProtectedKeyword: case SyntaxKind.StaticKeyword: // Check for modifier on source element - return lookAhead(() => { nextToken(); return isDeclarationStart(); }); + return lookAhead(nextTokenIsDeclarationStart); } } + function isIdentifierOrKeyword() { + return token >= SyntaxKind.Identifier; + } + + function nextTokenIsIdentifierOrKeyword() { + nextToken(); + return isIdentifierOrKeyword(); + } + + function nextTokenIsIdentifierOrKeywordOrStringLiteral() { + nextToken(); + return isIdentifierOrKeyword() || token === SyntaxKind.StringLiteral; + } + + function nextTokenIsEqualsTokenOrDeclarationStart() { + nextToken(); + return token === SyntaxKind.EqualsToken || isDeclarationStart(); + } + + function nextTokenIsDeclarationStart() { + nextToken(); + return isDeclarationStart(); + } + function parseDeclaration(): ModuleElement { var fullStart = getNodePos(); var modifiers = parseModifiers(); @@ -4044,11 +4152,9 @@ module ts { } } - var flags = modifiers ? modifiers.flags : 0; switch (token) { case SyntaxKind.VarKeyword: case SyntaxKind.LetKeyword: - return parseVariableStatement(fullStart, modifiers); case SyntaxKind.ConstKeyword: return parseVariableStatement(fullStart, modifiers); case SyntaxKind.FunctionKeyword: @@ -4060,9 +4166,9 @@ module ts { case SyntaxKind.TypeKeyword: return parseTypeAliasDeclaration(fullStart, modifiers); case SyntaxKind.EnumKeyword: - return parseAndCheckEnumDeclaration(fullStart, modifiers, flags); + return parseEnumDeclaration(fullStart, modifiers); case SyntaxKind.ModuleKeyword: - return parseModuleDeclaration(fullStart, modifiers, flags); + return parseModuleDeclaration(fullStart, modifiers); case SyntaxKind.ImportKeyword: return parseImportDeclaration(fullStart, modifiers); default: @@ -4101,13 +4207,13 @@ module ts { var referencePathMatchResult = getFileReferenceFromReferencePath(comment, range); if (referencePathMatchResult) { var fileReference = referencePathMatchResult.fileReference; - file.hasNoDefaultLib = referencePathMatchResult.isNoDefaultLib; + sourceFile.hasNoDefaultLib = referencePathMatchResult.isNoDefaultLib; var diagnosticMessage = referencePathMatchResult.diagnosticMessage; if (fileReference) { referencedFiles.push(fileReference); } if (diagnosticMessage) { - file.parseDiagnostics.push(createFileDiagnostic(file, range.pos, range.end - range.pos, diagnosticMessage)); + sourceFile.referenceDiagnostics.push(createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, diagnosticMessage)); } } else { @@ -4115,7 +4221,7 @@ module ts { var amdModuleNameMatchResult = amdModuleNameRegEx.exec(comment); if(amdModuleNameMatchResult) { if(amdModuleName) { - file.parseDiagnostics.push(createFileDiagnostic(file, range.pos, range.end - range.pos, Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments)); + sourceFile.referenceDiagnostics.push(createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments)); } amdModuleName = amdModuleNameMatchResult[2]; } @@ -4136,7 +4242,7 @@ module ts { } function getExternalModuleIndicator() { - return forEach(file.statements, node => + return forEach(sourceFile.statements, node => node.flags & NodeFlags.Export || node.kind === SyntaxKind.ImportDeclaration && (node).moduleReference.kind === SyntaxKind.ExternalModuleReference || node.kind === SyntaxKind.ExportAssignment @@ -4147,15 +4253,15 @@ module ts { var syntacticDiagnostics: Diagnostic[]; function getSyntacticDiagnostics() { if (syntacticDiagnostics === undefined) { - if (file.parseDiagnostics.length > 0) { + if (sourceFile.parseDiagnostics.length > 0) { // Don't bother doing any grammar checks if there are already parser errors. // Otherwise we may end up with too many cascading errors. - syntacticDiagnostics = file.parseDiagnostics; + syntacticDiagnostics = sourceFile.referenceDiagnostics.concat(sourceFile.parseDiagnostics); } else { // No parser errors were reported. Perform our stricter grammar checks. - syntacticDiagnostics = file.grammarDiagnostics; - checkGrammar(sourceText, languageVersion, file); + checkGrammar(sourceText, languageVersion, sourceFile); + syntacticDiagnostics = sourceFile.referenceDiagnostics.concat(sourceFile.grammarDiagnostics); } } @@ -4168,32 +4274,40 @@ module ts { if (fileExtensionIs(filename, ".d.ts")) { rootNodeFlags = NodeFlags.DeclarationFile; } - file = createRootNode(SyntaxKind.SourceFile, 0, sourceText.length, rootNodeFlags); - file.filename = normalizePath(filename); - file.text = sourceText; - file.getLineAndCharacterFromPosition = getLineAndCharacterFromSourcePosition; - file.getPositionFromLineAndCharacter = getPositionFromSourceLineAndCharacter; - file.getLineStarts = getLineStarts; - file.getSyntacticDiagnostics = getSyntacticDiagnostics; - file.parseDiagnostics = []; - file.grammarDiagnostics = []; - file.semanticDiagnostics = []; + + var sourceFile = createRootNode(SyntaxKind.SourceFile, 0, sourceText.length, rootNodeFlags); + + sourceFile.getLineAndCharacterFromPosition = getLineAndCharacterFromSourcePosition; + sourceFile.getPositionFromLineAndCharacter = getPositionFromSourceLineAndCharacter; + sourceFile.getLineStarts = getLineStarts; + sourceFile.getSyntacticDiagnostics = getSyntacticDiagnostics; + + sourceFile.filename = normalizePath(filename); + sourceFile.text = sourceText; + + sourceFile.referenceDiagnostics = []; + sourceFile.parseDiagnostics = []; + sourceFile.grammarDiagnostics = []; + sourceFile.semanticDiagnostics = []; var referenceComments = processReferenceComments(); - file.referencedFiles = referenceComments.referencedFiles; - file.amdDependencies = referenceComments.amdDependencies; - file.amdModuleName = referenceComments.amdModuleName; + sourceFile.referencedFiles = referenceComments.referencedFiles; + sourceFile.amdDependencies = referenceComments.amdDependencies; + sourceFile.amdModuleName = referenceComments.amdModuleName; - file.statements = parseList(ParsingContext.SourceElements, /*checkForStrictMode*/ true, parseSourceElement); - file.externalModuleIndicator = getExternalModuleIndicator(); + sourceFile.statements = parseList(ParsingContext.SourceElements, /*checkForStrictMode*/ true, parseSourceElement); + Debug.assert(token === SyntaxKind.EndOfFileToken); + sourceFile.endOfFileToken = parseTokenNode(); - file.nodeCount = nodeCount; - file.identifierCount = identifierCount; - file.version = version; - file.isOpen = isOpen; - file.languageVersion = languageVersion; - file.identifiers = identifiers; - return file; + sourceFile.externalModuleIndicator = getExternalModuleIndicator(); + + sourceFile.nodeCount = nodeCount; + sourceFile.identifierCount = identifierCount; + sourceFile.version = version; + sourceFile.isOpen = isOpen; + sourceFile.languageVersion = languageVersion; + sourceFile.identifiers = identifiers; + return sourceFile; } function isLeftHandSideExpression(expr: Expression): boolean { @@ -4304,7 +4418,7 @@ module ts { case SyntaxKind.EnumDeclaration: return checkEnumDeclaration(node); case SyntaxKind.BinaryExpression: return checkBinaryExpression(node); - case SyntaxKind.CatchBlock: return checkCatchBlock(node); + case SyntaxKind.CatchClause: return checkCatchClause(node); case SyntaxKind.ClassDeclaration: return checkClassDeclaration(node); case SyntaxKind.ComputedPropertyName: return checkComputedPropertyName(node); case SyntaxKind.Constructor: return checkConstructor(node); @@ -4333,7 +4447,7 @@ module ts { case SyntaxKind.ReturnStatement: return checkReturnStatement(node); case SyntaxKind.SetAccessor: return checkSetAccessor(node); case SyntaxKind.SourceFile: return checkSourceFile(node); - case SyntaxKind.ShorthandPropertyAssignment: return checkShorthandPropertyAssignment(node); + case SyntaxKind.ShorthandPropertyAssignment: return checkShorthandPropertyAssignment(node); case SyntaxKind.SwitchStatement: return checkSwitchStatement(node); case SyntaxKind.TaggedTemplateExpression: return checkTaggedTemplateExpression(node); case SyntaxKind.ThrowStatement: return checkThrowStatement(node); @@ -4562,15 +4676,15 @@ module ts { } } - function checkCatchBlock(node: CatchBlock) { + function checkCatchClause(node: CatchClause) { if (node.type) { - var colonStart = skipTrivia(sourceText, node.variable.end); + var colonStart = skipTrivia(sourceText, node.name.end); return grammarErrorAtPos(colonStart, ":".length, Diagnostics.Catch_clause_parameter_cannot_have_a_type_annotation); } - if (node.parserContextFlags & ParserContextFlags.StrictMode && isEvalOrArgumentsIdentifier(node.variable)) { + if (node.parserContextFlags & ParserContextFlags.StrictMode && isEvalOrArgumentsIdentifier(node.name)) { // It is a SyntaxError if a TryStatement with a Catch occurs within strict code and the Identifier of the // Catch production is eval or arguments - return reportInvalidUseInStrictMode(node.variable); + return reportInvalidUseInStrictMode(node.name); } } @@ -4803,14 +4917,14 @@ module ts { return grammarErrorOnNode(node, Diagnostics.An_index_signature_must_have_exactly_one_parameter); } } - else if (parameter.flags & NodeFlags.Rest) { - return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_cannot_have_a_rest_parameter); + else if (parameter.dotDotDotToken) { + return grammarErrorOnNode(parameter.dotDotDotToken, Diagnostics.An_index_signature_cannot_have_a_rest_parameter); } else if (parameter.flags & NodeFlags.Modifier) { return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_cannot_have_an_accessibility_modifier); } - else if (parameter.flags & NodeFlags.QuestionMark) { - return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_cannot_have_a_question_mark); + else if (parameter.questionToken) { + return grammarErrorOnNode(parameter.questionToken, Diagnostics.An_index_signature_parameter_cannot_have_a_question_mark); } else if (parameter.initializer) { return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_cannot_have_an_initializer); @@ -4862,7 +4976,7 @@ module ts { return true; } if (node.parent.kind === SyntaxKind.ClassDeclaration) { - if (checkForInvalidQuestionMark(node, Diagnostics.A_class_member_cannot_be_declared_optional)) { + if (checkForInvalidQuestionMark(node, node.questionToken, Diagnostics.A_class_member_cannot_be_declared_optional)) { return true; } // Technically, computed properties in ambient contexts is disallowed @@ -5160,23 +5274,23 @@ module ts { for (var i = 0; i < parameterCount; i++) { var parameter = parameters[i]; - if (parameter.flags & NodeFlags.Rest) { + if (parameter.dotDotDotToken) { if (i !== (parameterCount - 1)) { - return grammarErrorOnNode(parameter.name, Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list); + return grammarErrorOnNode(parameter.dotDotDotToken, Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list); } - if (parameter.flags & NodeFlags.QuestionMark) { - return grammarErrorOnNode(parameter.name, Diagnostics.A_rest_parameter_cannot_be_optional); + if (parameter.questionToken) { + return grammarErrorOnNode(parameter.questionToken, Diagnostics.A_rest_parameter_cannot_be_optional); } if (parameter.initializer) { return grammarErrorOnNode(parameter.name, Diagnostics.A_rest_parameter_cannot_have_an_initializer); } } - else if (parameter.flags & NodeFlags.QuestionMark || parameter.initializer) { + else if (parameter.questionToken || parameter.initializer) { seenOptionalParameter = true; - if (parameter.flags & NodeFlags.QuestionMark && parameter.initializer) { + if (parameter.questionToken && parameter.initializer) { return grammarErrorOnNode(parameter.name, Diagnostics.Parameter_cannot_have_question_mark_and_initializer); } } @@ -5210,7 +5324,7 @@ module ts { function checkProperty(node: PropertyDeclaration) { if (node.parent.kind === SyntaxKind.ClassDeclaration) { - if (checkForInvalidQuestionMark(node, Diagnostics.A_class_member_cannot_be_declared_optional) || + if (checkForInvalidQuestionMark(node, node.questionToken, Diagnostics.A_class_member_cannot_be_declared_optional) || checkForDisallowedComputedProperty(node.name, Diagnostics.Computed_property_names_are_not_allowed_in_class_property_declarations)) { return true; } @@ -5251,13 +5365,12 @@ module ts { } function checkPropertyAssignment(node: PropertyDeclaration) { - return checkForInvalidQuestionMark(node, Diagnostics.An_object_member_cannot_be_declared_optional); + return checkForInvalidQuestionMark(node, node.questionToken, Diagnostics.An_object_member_cannot_be_declared_optional); } - function checkForInvalidQuestionMark(node: Declaration, message: DiagnosticMessage) { - if (node.flags & NodeFlags.QuestionMark) { - var pos = skipTrivia(sourceText, node.name.end); - return grammarErrorAtPos(pos, "?".length, message); + function checkForInvalidQuestionMark(node: Declaration, questionToken: Node, message: DiagnosticMessage) { + if (questionToken) { + return grammarErrorOnNode(questionToken, message); } } @@ -5298,14 +5411,14 @@ module ts { } else { var parameter = accessor.parameters[0]; - if (parameter.flags & NodeFlags.Rest) { - return grammarErrorOnNode(accessor.name, Diagnostics.A_set_accessor_cannot_have_rest_parameter); + if (parameter.dotDotDotToken) { + return grammarErrorOnNode(parameter.dotDotDotToken, Diagnostics.A_set_accessor_cannot_have_rest_parameter); } else if (parameter.flags & NodeFlags.Modifier) { return grammarErrorOnNode(accessor.name, Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation); } - else if (parameter.flags & NodeFlags.QuestionMark) { - return grammarErrorOnNode(accessor.name, Diagnostics.A_set_accessor_cannot_have_an_optional_parameter); + else if (parameter.questionToken) { + return grammarErrorOnNode(parameter.questionToken, Diagnostics.A_set_accessor_cannot_have_an_optional_parameter); } else if (parameter.initializer) { return grammarErrorOnNode(accessor.name, Diagnostics.A_set_accessor_parameter_cannot_have_an_initializer); @@ -5351,8 +5464,8 @@ module ts { return grammarErrorOnFirstToken(node, Diagnostics.A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file); } - function checkShorthandPropertyAssignment(node: ShortHandPropertyDeclaration): boolean { - return checkForInvalidQuestionMark(node, Diagnostics.An_object_member_cannot_be_declared_optional); + function checkShorthandPropertyAssignment(node: ShorthandPropertyDeclaration): boolean { + return checkForInvalidQuestionMark(node, node.questionToken, Diagnostics.An_object_member_cannot_be_declared_optional); } function checkSwitchStatement(node: SwitchStatement) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 277e2cce5ff..edf052a8876 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -208,7 +208,6 @@ module ts { ThrowStatement, TryStatement, TryBlock, - CatchBlock, FinallyBlock, DebuggerStatement, VariableDeclaration, @@ -222,12 +221,16 @@ module ts { ModuleBlock, ImportDeclaration, ExportAssignment, + // Module references ExternalModuleReference, + // Clauses CaseClause, DefaultClause, HeritageClause, + CatchClause, + // Property assignments PropertyAssignment, ShorthandPropertyAssignment, @@ -254,7 +257,7 @@ module ts { LastTypeNode = ParenthesizedType, FirstPunctuation = OpenBraceToken, LastPunctuation = CaretEqualsToken, - FirstToken = EndOfFileToken, + FirstToken = Unknown, LastToken = TypeKeyword, FirstTriviaToken = SingleLineCommentTrivia, LastTriviaToken = WhitespaceTrivia, @@ -272,8 +275,6 @@ module ts { export const enum NodeFlags { Export = 0x00000001, // Declarations Ambient = 0x00000002, // Declarations - QuestionMark = 0x00000004, // Parameter/Property/Method - Rest = 0x00000008, // Parameter Public = 0x00000010, // Property/Method Private = 0x00000020, // Property/Method Protected = 0x00000040, // Property/Method @@ -318,7 +319,7 @@ module ts { hasTrailingComma?: boolean; } - export interface ModifiersArray extends Array { + export interface ModifiersArray extends NodeArray { flags: number; } @@ -369,12 +370,15 @@ module ts { } export interface ParameterDeclaration extends Declaration { + dotDotDotToken?: Node; name: Identifier; + questionToken?: Node; type?: TypeNode | StringLiteralExpression; initializer?: Expression; } export interface PropertyDeclaration extends Declaration, ClassElement { + questionToken?: Node; type?: TypeNode; initializer?: Expression; } @@ -382,8 +386,9 @@ module ts { export type VariableOrParameterDeclaration = VariableDeclaration | ParameterDeclaration; export type VariableOrParameterOrPropertyDeclaration = VariableOrParameterDeclaration | PropertyDeclaration; - export interface ShortHandPropertyDeclaration extends Declaration { + export interface ShorthandPropertyDeclaration extends Declaration { name: Identifier; + questionToken?: Node; } /** @@ -398,6 +403,7 @@ module ts { _functionLikeDeclarationBrand: any; asteriskToken?: Node; + questionToken?: Node; body?: Block | Expression; } @@ -668,11 +674,17 @@ module ts { clauses: NodeArray; } - export interface CaseOrDefaultClause extends Node { + export interface CaseClause extends Node { expression?: Expression; statements: NodeArray; } + export interface DefaultClause extends Node { + statements: NodeArray; + } + + export type CaseOrDefaultClause = CaseClause | DefaultClause; + export interface LabeledStatement extends Statement { label: Identifier; statement: Statement; @@ -684,13 +696,14 @@ module ts { export interface TryStatement extends Statement { tryBlock: Block; - catchBlock?: CatchBlock; + catchClause?: CatchClause; finallyBlock?: Block; } - export interface CatchBlock extends Block, Declaration { - variable: Identifier; + export interface CatchClause extends Declaration { + name: Identifier; type?: TypeNode; + block: Block; } export interface ModuleElement extends Node { @@ -773,6 +786,7 @@ module ts { // Source files are declarations when they are external modules. export interface SourceFile extends Declaration { statements: NodeArray; + endOfFileToken: Node; filename: string; text: string; @@ -782,17 +796,24 @@ module ts { amdDependencies: string[]; amdModuleName: string; referencedFiles: FileReference[]; - semanticDiagnostics: Diagnostic[]; + + // Diagnostics reported about the "/// 0) { - throw new Error('Error compiling ' + fileName + ': ' + errs.map(e => e.messageText).join('\r\n')); + var errors = program.getDiagnostics().concat(checker.getDiagnostics()); + if (errors.length > 0) { + throw new Error('Error compiling ' + fileName + ': ' + errors.map(e => e.messageText).join('\r\n')); } checker.emitFiles(); result = result || ''; // Might have an empty fourslash file diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 640d5f0ae53..c0d3ddedce3 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -801,7 +801,6 @@ module Harness { useCaseSensitiveFileNames)); var checker = program.getTypeChecker(/*fullTypeCheckMode*/ true); - checker.checkProgram(); var isEmitBlocked = checker.isEmitBlocked(); diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index 6cf775487fa..a67a89dd82f 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -106,11 +106,13 @@ module ts.BreakpointResolver { case SyntaxKind.Block: case SyntaxKind.TryBlock: - case SyntaxKind.CatchBlock: case SyntaxKind.FinallyBlock: case SyntaxKind.ModuleBlock: return spanInBlock(node); + case SyntaxKind.CatchClause: + return spanInBlock((node).block); + case SyntaxKind.ExpressionStatement: // span on the expression return textSpan((node).expression); @@ -297,7 +299,7 @@ module ts.BreakpointResolver { function canHaveSpanInParameterDeclaration(parameter: ParameterDeclaration): boolean { // Breakpoint is possible on parameter only if it has initializer, is a rest parameter, or has public or private modifier - return !!parameter.initializer || !!(parameter.flags & NodeFlags.Rest) || + return !!parameter.initializer || parameter.dotDotDotToken !== undefined || !!(parameter.flags & NodeFlags.Public) || !!(parameter.flags & NodeFlags.Private); } @@ -420,7 +422,7 @@ module ts.BreakpointResolver { case SyntaxKind.Block: case SyntaxKind.TryBlock: - case SyntaxKind.CatchBlock: + case SyntaxKind.CatchClause: case SyntaxKind.FinallyBlock: return spanInNode((node.parent).statements[(node.parent).statements.length - 1]);; diff --git a/src/services/formatting.ts b/src/services/formatting.ts index 741b853b7ba..3322ea1e65b 100644 --- a/src/services/formatting.ts +++ b/src/services/formatting.ts @@ -155,10 +155,11 @@ module ts.formatting { case SyntaxKind.SourceFile: case SyntaxKind.Block: case SyntaxKind.TryBlock: - case SyntaxKind.CatchBlock: case SyntaxKind.FinallyBlock: case SyntaxKind.ModuleBlock: - return rangeContainsRange((parent).statements, node) + return rangeContainsRange((parent).statements, node); + case SyntaxKind.CatchClause: + return rangeContainsRange((parent).block.statements, node); } return false; @@ -898,7 +899,6 @@ module ts.formatting { case SyntaxKind.Block: case SyntaxKind.FunctionBlock: case SyntaxKind.TryBlock: - case SyntaxKind.CatchBlock: case SyntaxKind.FinallyBlock: case SyntaxKind.ModuleBlock: return true; diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 7de7baee6ca..2723b50af7b 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -525,7 +525,6 @@ module ts.formatting { case SyntaxKind.SwitchStatement: case SyntaxKind.ObjectLiteralExpression: case SyntaxKind.TryBlock: - case SyntaxKind.CatchBlock: case SyntaxKind.FinallyBlock: case SyntaxKind.FunctionBlock: case SyntaxKind.ModuleBlock: @@ -581,7 +580,7 @@ module ts.formatting { case SyntaxKind.EnumDeclaration: case SyntaxKind.Block: case SyntaxKind.TryBlock: - case SyntaxKind.CatchBlock: + case SyntaxKind.CatchClause: case SyntaxKind.FinallyBlock: case SyntaxKind.FunctionBlock: case SyntaxKind.ModuleBlock: @@ -603,7 +602,7 @@ module ts.formatting { case SyntaxKind.WithStatement: // TODO // case SyntaxKind.ElseClause: - case SyntaxKind.CatchBlock: + case SyntaxKind.CatchClause: case SyntaxKind.FinallyBlock: return true; diff --git a/src/services/outliningElementsCollector.ts b/src/services/outliningElementsCollector.ts index 7f071e5c224..68f30bee781 100644 --- a/src/services/outliningElementsCollector.ts +++ b/src/services/outliningElementsCollector.ts @@ -79,7 +79,8 @@ module ts { parent.kind === SyntaxKind.ForStatement || parent.kind === SyntaxKind.IfStatement || parent.kind === SyntaxKind.WhileStatement || - parent.kind === SyntaxKind.WithStatement) { + parent.kind === SyntaxKind.WithStatement || + parent.kind === SyntaxKind.CatchClause) { addOutliningSpan(parent, openBrace, closeBrace, autoCollapse(n)); } @@ -100,7 +101,6 @@ module ts { case SyntaxKind.FunctionBlock: case SyntaxKind.ModuleBlock: case SyntaxKind.TryBlock: - case SyntaxKind.CatchBlock: case SyntaxKind.FinallyBlock: var openBrace = findChildOfKind(n, SyntaxKind.OpenBraceToken, sourceFile); var closeBrace = findChildOfKind(n, SyntaxKind.CloseBraceToken, sourceFile); diff --git a/src/services/services.ts b/src/services/services.ts index c12a1f53e02..96817e276e2 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -722,6 +722,9 @@ module ts { public filename: string; public text: string; + public statements: NodeArray; + public endOfFileToken: Node; + // These methods will have their implementation provided by the implementation the // compiler actually exports off of SourceFile. public getLineAndCharacterFromPosition: (position: number) => LineAndCharacter; @@ -732,15 +735,17 @@ module ts { public amdDependencies: string[]; public amdModuleName: string; public referencedFiles: FileReference[]; + + public referenceDiagnostics: Diagnostic[]; public parseDiagnostics: Diagnostic[]; public grammarDiagnostics: Diagnostic[]; public semanticDiagnostics: Diagnostic[]; + public hasNoDefaultLib: boolean; public externalModuleIndicator: Node; // The first node that causes this file to be an external module public nodeCount: number; public identifierCount: number; public symbolCount: number; - public statements: NodeArray; public version: string; public isOpen: boolean; public languageVersion: ScriptTarget; @@ -2576,7 +2581,7 @@ module ts { isFunction(containingNodeKind); case SyntaxKind.OpenParenToken: - return containingNodeKind === SyntaxKind.CatchBlock || + return containingNodeKind === SyntaxKind.CatchClause || isFunction(containingNodeKind); case SyntaxKind.OpenBraceToken: @@ -3567,8 +3572,8 @@ module ts { else if (node.kind === SyntaxKind.TryStatement) { var tryStatement = node; - if (tryStatement.catchBlock) { - aggregate(tryStatement.catchBlock); + if (tryStatement.catchClause) { + aggregate(tryStatement.catchClause); } else { // Exceptions thrown within a try block lacking a catch clause @@ -3607,7 +3612,7 @@ module ts { if (parent.kind === SyntaxKind.TryStatement) { var tryStatement = parent; - if (tryStatement.tryBlock === child && tryStatement.catchBlock) { + if (tryStatement.tryBlock === child && tryStatement.catchClause) { return child; } } @@ -3623,8 +3628,8 @@ module ts { pushKeywordIf(keywords, tryStatement.getFirstToken(), SyntaxKind.TryKeyword); - if (tryStatement.catchBlock) { - pushKeywordIf(keywords, tryStatement.catchBlock.getFirstToken(), SyntaxKind.CatchKeyword); + if (tryStatement.catchClause) { + pushKeywordIf(keywords, tryStatement.catchClause.getFirstToken(), SyntaxKind.CatchKeyword); } if (tryStatement.finallyBlock) { @@ -3839,8 +3844,8 @@ module ts { } forEach(nodes, node => { - if (node.flags & modifierFlag) { - forEach(node.getChildren(), child => pushKeywordIf(keywords, child, modifier)); + if (node.modifiers && node.flags & modifierFlag) { + forEach(node.modifiers, child => pushKeywordIf(keywords, child, modifier)); } }); @@ -4670,18 +4675,14 @@ module ts { function getEmitOutput(filename: string): EmitOutput { synchronizeHostData(); + filename = normalizeSlashes(filename); - var compilerOptions = program.getCompilerOptions(); - var targetSourceFile = program.getSourceFile(filename); // Current selected file to be output - // If --out flag is not specified, shouldEmitToOwnFile is true. Otherwise shouldEmitToOwnFile is false. - var shouldEmitToOwnFile = ts.shouldEmitToOwnFile(targetSourceFile, compilerOptions); - var emitOutput: EmitOutput = { - outputFiles: [], - emitOutputStatus: undefined, - }; + var sourceFile = getSourceFile(filename); + + var outputFiles: OutputFile[] = []; function getEmitOutputWriter(filename: string, data: string, writeByteOrderMark: boolean) { - emitOutput.outputFiles.push({ + outputFiles.push({ name: filename, writeByteOrderMark: writeByteOrderMark, text: data @@ -4691,41 +4692,15 @@ module ts { // Initialize writer for CompilerHost.writeFile writer = getEmitOutputWriter; - var containSyntacticErrors = false; - - if (shouldEmitToOwnFile) { - // Check only the file we want to emit - containSyntacticErrors = containErrors(program.getDiagnostics(targetSourceFile)); - } else { - // Check the syntactic of only sourceFiles that will get emitted into single output - // Terminate the process immediately if we encounter a syntax error from one of the sourceFiles - containSyntacticErrors = forEach(program.getSourceFiles(), sourceFile => { - if (!isExternalModuleOrDeclarationFile(sourceFile)) { - // If emit to a single file then we will check all files that do not have external module - return containErrors(program.getDiagnostics(sourceFile)); - } - return false; - }); - } - - if (containSyntacticErrors) { - // If there is a syntax error, terminate the process and report outputStatus - emitOutput.emitOutputStatus = EmitReturnStatus.AllOutputGenerationSkipped; - // Reset writer back to undefined to make sure that we produce an error message - // if CompilerHost.writeFile is called when we are not in getEmitOutput - writer = undefined; - return emitOutput; - } - - // Perform semantic and force a type check before emit to ensure that all symbols are updated - // EmitFiles will report if there is an error from TypeChecker and Emitter - // Depend whether we will have to emit into a single file or not either emit only selected file in the project, emit all files into a single file - var emitFilesResult = getFullTypeCheckChecker().emitFiles(targetSourceFile); - emitOutput.emitOutputStatus = emitFilesResult.emitResultStatus; + var emitOutput = getFullTypeCheckChecker().emitFiles(sourceFile); // Reset writer back to undefined to make sure that we produce an error message if CompilerHost.writeFile method is called when we are not in getEmitOutput writer = undefined; - return emitOutput; + + return { + outputFiles, + emitOutputStatus: emitOutput.emitResultStatus + }; } function getMeaningFromDeclaration(node: Node): SemanticMeaning { @@ -4743,7 +4718,7 @@ module ts { case SyntaxKind.FunctionDeclaration: case SyntaxKind.FunctionExpression: case SyntaxKind.ArrowFunction: - case SyntaxKind.CatchBlock: + case SyntaxKind.CatchClause: return SemanticMeaning.Value; case SyntaxKind.TypeParameter: diff --git a/src/services/shims.ts b/src/services/shims.ts index e1e95c1332c..5556743830f 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -912,6 +912,13 @@ module ts { throw new Error("Invalid operation"); } } + + // Here we expose the TypeScript services as an external module + // so that it may be consumed easily like a node module. + declare var module: any; + if (typeof module !== "undefined" && module.exports) { + module.exports = ts; + } } @@ -919,4 +926,3 @@ module ts { module TypeScript.Services { export var TypeScriptServicesFactory = ts.TypeScriptServicesFactory; } - diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index f3604b3dfdd..93363b4676b 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -524,7 +524,7 @@ module ts.SignatureHelp { var displayParts = mapToDisplayParts(writer => typeInfoResolver.getSymbolDisplayBuilder().buildParameterDisplay(parameter, writer, invocation)); - var isOptional = !!(parameter.valueDeclaration.flags & NodeFlags.QuestionMark); + var isOptional = hasQuestionToken(parameter.valueDeclaration); return { name: parameter.name, diff --git a/src/services/smartIndenter.ts b/src/services/smartIndenter.ts index 4e32522040e..82226449b96 100644 --- a/src/services/smartIndenter.ts +++ b/src/services/smartIndenter.ts @@ -328,7 +328,6 @@ module ts.formatting { case SyntaxKind.Block: case SyntaxKind.FunctionBlock: case SyntaxKind.TryBlock: - case SyntaxKind.CatchBlock: case SyntaxKind.FinallyBlock: case SyntaxKind.ModuleBlock: case SyntaxKind.ObjectLiteralExpression: @@ -404,12 +403,13 @@ module ts.formatting { case SyntaxKind.EnumDeclaration: case SyntaxKind.ObjectLiteralExpression: case SyntaxKind.Block: - case SyntaxKind.CatchBlock: case SyntaxKind.FinallyBlock: case SyntaxKind.FunctionBlock: case SyntaxKind.ModuleBlock: case SyntaxKind.SwitchStatement: return nodeEndsWith(n, SyntaxKind.CloseBraceToken, sourceFile); + case SyntaxKind.CatchClause: + return isCompletedNode((n).block, sourceFile); case SyntaxKind.ParenthesizedExpression: case SyntaxKind.CallSignature: case SyntaxKind.CallExpression: diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 4a3301312fb..9df0476c105 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -280,10 +280,6 @@ module ts { } function nodeHasTokens(n: Node): boolean { - if (n.kind === SyntaxKind.Unknown) { - return false; - } - // If we have a token or node that has a non-zero width, it must have tokens. // Note, that getWidth() does not take trivia into account. return n.getWidth() !== 0; diff --git a/tests/baselines/reference/accessorWithRestParam.errors.txt b/tests/baselines/reference/accessorWithRestParam.errors.txt index 6162d5a8238..c6f3ef70563 100644 --- a/tests/baselines/reference/accessorWithRestParam.errors.txt +++ b/tests/baselines/reference/accessorWithRestParam.errors.txt @@ -1,14 +1,14 @@ -tests/cases/compiler/accessorWithRestParam.ts(3,9): error TS1053: A 'set' accessor cannot have rest parameter. -tests/cases/compiler/accessorWithRestParam.ts(4,16): error TS1053: A 'set' accessor cannot have rest parameter. +tests/cases/compiler/accessorWithRestParam.ts(3,11): error TS1053: A 'set' accessor cannot have rest parameter. +tests/cases/compiler/accessorWithRestParam.ts(4,18): error TS1053: A 'set' accessor cannot have rest parameter. ==== tests/cases/compiler/accessorWithRestParam.ts (2 errors) ==== class C { set X(...v) { } - ~ + ~~~ !!! error TS1053: A 'set' accessor cannot have rest parameter. static set X(...v2) { } - ~ + ~~~ !!! error TS1053: A 'set' accessor cannot have rest parameter. } \ No newline at end of file diff --git a/tests/baselines/reference/anyAssignableToEveryType.js b/tests/baselines/reference/anyAssignableToEveryType.js index 6c117a5054d..75d847709a5 100644 --- a/tests/baselines/reference/anyAssignableToEveryType.js +++ b/tests/baselines/reference/anyAssignableToEveryType.js @@ -83,3 +83,8 @@ function foo(x, y, z) { y = a; z = a; } +//function foo(x: T, y: U, z: V) { +// x = a; +// y = a; +// z = a; +//} diff --git a/tests/baselines/reference/augmentedTypesClass3.js b/tests/baselines/reference/augmentedTypesClass3.js index dd0da2a1646..b42d9dda356 100644 --- a/tests/baselines/reference/augmentedTypesClass3.js +++ b/tests/baselines/reference/augmentedTypesClass3.js @@ -52,3 +52,4 @@ var c5c = (function () { }; return c5c; })(); +//import c5c = require(''); diff --git a/tests/baselines/reference/augmentedTypesEnum.js b/tests/baselines/reference/augmentedTypesEnum.js index f7a83018cfd..484b0addd58 100644 --- a/tests/baselines/reference/augmentedTypesEnum.js +++ b/tests/baselines/reference/augmentedTypesEnum.js @@ -105,3 +105,6 @@ var e6b; (function (e6b) { e6b.y = 2; })(e6b || (e6b = {})); // should be error +// enum then import, messes with error reporting +//enum e7 { One } +//import e7 = require(''); // should be error diff --git a/tests/baselines/reference/augmentedTypesEnum2.js b/tests/baselines/reference/augmentedTypesEnum2.js index 8ab98a7cb7b..434e508f14c 100644 --- a/tests/baselines/reference/augmentedTypesEnum2.js +++ b/tests/baselines/reference/augmentedTypesEnum2.js @@ -40,3 +40,5 @@ var e2 = (function () { }; return e2; })(); +//enum then enum - covered +//enum then import - covered diff --git a/tests/baselines/reference/augmentedTypesFunction.js b/tests/baselines/reference/augmentedTypesFunction.js index 078854e227c..34567c77e8c 100644 --- a/tests/baselines/reference/augmentedTypesFunction.js +++ b/tests/baselines/reference/augmentedTypesFunction.js @@ -93,3 +93,6 @@ var y5b; })(y5b || (y5b = {})); // should be an error function y5c() { } +// function then import, messes with other errors +//function y6() { } +//import y6 = require(''); diff --git a/tests/baselines/reference/augmentedTypesInterface.js b/tests/baselines/reference/augmentedTypesInterface.js index 709b16d615c..a5039f8b1d0 100644 --- a/tests/baselines/reference/augmentedTypesInterface.js +++ b/tests/baselines/reference/augmentedTypesInterface.js @@ -48,3 +48,4 @@ var i3; i3[i3["One"] = 0] = "One"; })(i3 || (i3 = {})); ; +//import i4 = require(''); // error diff --git a/tests/baselines/reference/augmentedTypesModules.js b/tests/baselines/reference/augmentedTypesModules.js index 0c7967b2227..a9bff3fa74b 100644 --- a/tests/baselines/reference/augmentedTypesModules.js +++ b/tests/baselines/reference/augmentedTypesModules.js @@ -268,3 +268,4 @@ var m6; (function (m6) { m6.y = 2; })(m6 || (m6 = {})); +//import m6 = require(''); diff --git a/tests/baselines/reference/augmentedTypesVar.js b/tests/baselines/reference/augmentedTypesVar.js index 4735d647056..f4404cecb3d 100644 --- a/tests/baselines/reference/augmentedTypesVar.js +++ b/tests/baselines/reference/augmentedTypesVar.js @@ -80,3 +80,6 @@ var x6b; (function (x6b) { x6b.y = 2; })(x6b || (x6b = {})); // error +// var then import, messes with other error reporting +//var x7 = 1; +//import x7 = require(''); diff --git a/tests/baselines/reference/baseIndexSignatureResolution.js b/tests/baselines/reference/baseIndexSignatureResolution.js index 0c1e6c610f3..4c2d63bf2c9 100644 --- a/tests/baselines/reference/baseIndexSignatureResolution.js +++ b/tests/baselines/reference/baseIndexSignatureResolution.js @@ -45,3 +45,37 @@ var Derived = (function (_super) { })(Base); var x = null; var y = x[0]; +/* +// Note - the equivalent for normal interface methods works fine: +interface A { + foo(): Base; +} +interface B extends A { + foo(): TBase; +} +var b: B = null; +var z: Derived = b.foo(); +class Base { private a: string; } +class Derived extends Base { private b: string; } + +// Note - commmenting "extends Foo" prevents the error +interface Foo { + [i: number]: Base; +} +interface FooOf extends Foo { + [i: number]: TBase; +} +var x: FooOf = null; +var y: Derived = x[0]; + +/* +// Note - the equivalent for normal interface methods works fine: +interface A { + foo(): Base; +} +interface B extends A { + foo(): TBase; +} +var b: B = null; +var z: Derived = b.foo(); + diff --git a/tests/baselines/reference/castingTuple.errors.txt b/tests/baselines/reference/castingTuple.errors.txt index f4efed6f1d1..98be259964d 100644 --- a/tests/baselines/reference/castingTuple.errors.txt +++ b/tests/baselines/reference/castingTuple.errors.txt @@ -2,19 +2,19 @@ tests/cases/conformance/types/tuple/castingTuple.ts(13,23): error TS2352: Neithe Property '2' is missing in type '[number, string]'. tests/cases/conformance/types/tuple/castingTuple.ts(16,21): error TS2352: Neither type '[C, D]' nor type '[C, D, A]' is assignable to the other. Property '2' is missing in type '[C, D]'. -tests/cases/conformance/types/tuple/castingTuple.ts(24,10): error TS2352: Neither type '[number, string]' nor type '[number, number]' is assignable to the other. +tests/cases/conformance/types/tuple/castingTuple.ts(28,10): error TS2352: Neither type '[number, string]' nor type '[number, number]' is assignable to the other. Types of property '1' are incompatible. Type 'string' is not assignable to type 'number'. -tests/cases/conformance/types/tuple/castingTuple.ts(25,10): error TS2352: Neither type '[C, D]' nor type '[A, I]' is assignable to the other. +tests/cases/conformance/types/tuple/castingTuple.ts(29,10): error TS2352: Neither type '[C, D]' nor type '[A, I]' is assignable to the other. Types of property '0' are incompatible. Type 'C' is not assignable to type 'A'. -tests/cases/conformance/types/tuple/castingTuple.ts(26,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'array1' must be of type '{}[]', but here has type 'number[]'. -tests/cases/conformance/types/tuple/castingTuple.ts(26,14): error TS2352: Neither type '[number, string]' nor type 'number[]' is assignable to the other. +tests/cases/conformance/types/tuple/castingTuple.ts(30,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'array1' must be of type '{}[]', but here has type 'number[]'. +tests/cases/conformance/types/tuple/castingTuple.ts(30,14): error TS2352: Neither type '[number, string]' nor type 'number[]' is assignable to the other. 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/types/tuple/castingTuple.ts(27,1): error TS2304: Cannot find name 't4'. +tests/cases/conformance/types/tuple/castingTuple.ts(31,1): error TS2304: Cannot find name 't4'. ==== tests/cases/conformance/types/tuple/castingTuple.ts (7 errors) ==== @@ -41,10 +41,14 @@ tests/cases/conformance/types/tuple/castingTuple.ts(27,1): error TS2304: Cannot !!! error TS2352: Neither type '[C, D]' nor type '[C, D, A]' is assignable to the other. !!! error TS2352: Property '2' is missing in type '[C, D]'. var eleFromCDA1 = classCDATuple[2]; // A - var eleFromCDA2 = classCDATuple[5]; // {} + var eleFromCDA2 = classCDATuple[5]; // C | D | A var t10: [E1, E2] = [E1.one, E2.one]; var t11 = <[number, number]>t10; var array1 = <{}[]>emptyObjTuple; + var unionTuple: [C, string | number] = [new C(), "foo"]; + var unionTuple2: [C, string | number, D] = [new C(), "foo", new D()]; + var unionTuple3: [number, string| number] = [10, "foo"]; + var unionTuple4 = <[number, number]>unionTuple3; // error var t3 = <[number, number]>numStrTuple; @@ -68,4 +72,5 @@ tests/cases/conformance/types/tuple/castingTuple.ts(27,1): error TS2304: Cannot !!! error TS2352: Type 'string' is not assignable to type 'number'. t4[2] = 10; ~~ -!!! error TS2304: Cannot find name 't4'. \ No newline at end of file +!!! error TS2304: Cannot find name 't4'. + \ No newline at end of file diff --git a/tests/baselines/reference/castingTuple.js b/tests/baselines/reference/castingTuple.js index 0671062bb4e..fffadcbc070 100644 --- a/tests/baselines/reference/castingTuple.js +++ b/tests/baselines/reference/castingTuple.js @@ -16,16 +16,21 @@ var classCDTuple: [C, D] = [new C(), new D()]; var interfaceIITuple = <[I, I]>classCDTuple; var classCDATuple = <[C, D, A]>classCDTuple; var eleFromCDA1 = classCDATuple[2]; // A -var eleFromCDA2 = classCDATuple[5]; // {} +var eleFromCDA2 = classCDATuple[5]; // C | D | A var t10: [E1, E2] = [E1.one, E2.one]; var t11 = <[number, number]>t10; var array1 = <{}[]>emptyObjTuple; +var unionTuple: [C, string | number] = [new C(), "foo"]; +var unionTuple2: [C, string | number, D] = [new C(), "foo", new D()]; +var unionTuple3: [number, string| number] = [10, "foo"]; +var unionTuple4 = <[number, number]>unionTuple3; // error var t3 = <[number, number]>numStrTuple; var t9 = <[A, I]>classCDTuple; var array1 = numStrTuple; -t4[2] = 10; +t4[2] = 10; + //// [castingTuple.js] var __extends = this.__extends || function (d, b) { @@ -84,10 +89,14 @@ var classCDTuple = [new C(), new D()]; var interfaceIITuple = classCDTuple; var classCDATuple = classCDTuple; var eleFromCDA1 = classCDATuple[2]; // A -var eleFromCDA2 = classCDATuple[5]; // {} +var eleFromCDA2 = classCDATuple[5]; // C | D | A var t10 = [0 /* one */, 0 /* one */]; var t11 = t10; var array1 = emptyObjTuple; +var unionTuple = [new C(), "foo"]; +var unionTuple2 = [new C(), "foo", new D()]; +var unionTuple3 = [10, "foo"]; +var unionTuple4 = unionTuple3; // error var t3 = numStrTuple; var t9 = classCDTuple; diff --git a/tests/baselines/reference/commentEmitAtEndOfFile1.js b/tests/baselines/reference/commentEmitAtEndOfFile1.js new file mode 100644 index 00000000000..1a1f7cb8900 --- /dev/null +++ b/tests/baselines/reference/commentEmitAtEndOfFile1.js @@ -0,0 +1,22 @@ +//// [commentEmitAtEndOfFile1.ts] +// test +var f = '' +// test #2 +module foo { + function bar() { } +} +// test #3 +module empty { +} +// test #4 + +//// [commentEmitAtEndOfFile1.js] +// test +var f = ''; +// test #2 +var foo; +(function (foo) { + function bar() { + } +})(foo || (foo = {})); +// test #4 diff --git a/tests/baselines/reference/commentEmitAtEndOfFile1.types b/tests/baselines/reference/commentEmitAtEndOfFile1.types new file mode 100644 index 00000000000..76b5c868cb6 --- /dev/null +++ b/tests/baselines/reference/commentEmitAtEndOfFile1.types @@ -0,0 +1,17 @@ +=== tests/cases/compiler/commentEmitAtEndOfFile1.ts === +// test +var f = '' +>f : string + +// test #2 +module foo { +>foo : typeof foo + + function bar() { } +>bar : () => void +} +// test #3 +module empty { +>empty : unknown +} +// test #4 diff --git a/tests/baselines/reference/commentsAtEndOfFile1.js b/tests/baselines/reference/commentsAtEndOfFile1.js index a0b0fe3731e..2d4dae39e6b 100644 --- a/tests/baselines/reference/commentsAtEndOfFile1.js +++ b/tests/baselines/reference/commentsAtEndOfFile1.js @@ -6,3 +6,4 @@ Input: //// [commentsAtEndOfFile1.js] Input: ; +//Testing two diff --git a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnCallSignature.js b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnCallSignature.js index 890add6bc8a..5a00fd85f3c 100644 --- a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnCallSignature.js +++ b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnCallSignature.js @@ -501,3 +501,4 @@ var r8b8 = b8 !== a8; var r8b9 = b9 !== a9; var r8b10 = b10 !== a10; var r8b11 = b11 !== a11; +//var r8b12 = b12 !== a12; diff --git a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnConstructorSignature.js b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnConstructorSignature.js index aefeb6d87ff..cba4f67933b 100644 --- a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnConstructorSignature.js +++ b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnConstructorSignature.js @@ -427,3 +427,4 @@ var r8b6 = b6 !== a6; var r8b7 = b7 !== a7; var r8b8 = b8 !== a8; var r8b9 = b9 !== a9; +//var r8b10 = b10 !== a10; diff --git a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedCallSignature.js b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedCallSignature.js index 1a83da3e663..1f2400f9bea 100644 --- a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedCallSignature.js +++ b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedCallSignature.js @@ -316,3 +316,4 @@ var r8b3 = b3 !== a3; var r8b4 = b4 !== a4; var r8b5 = b5 !== a5; var r8b6 = b6 !== a6; +//var r8b7 = b7 !== a7; diff --git a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedConstructorSignature.js b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedConstructorSignature.js index 393a2485c47..e80480e1a4e 100644 --- a/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedConstructorSignature.js +++ b/tests/baselines/reference/comparisonOperatorWithSubtypeObjectOnInstantiatedConstructorSignature.js @@ -316,3 +316,4 @@ var r8b3 = b3 !== a3; var r8b4 = b4 !== a4; var r8b5 = b5 !== a5; var r8b6 = b6 !== a6; +//var r8b7 = b7 !== a7; diff --git a/tests/baselines/reference/concatError.js b/tests/baselines/reference/concatError.js index e4ae4afdb65..04c0a16b836 100644 --- a/tests/baselines/reference/concatError.js +++ b/tests/baselines/reference/concatError.js @@ -43,3 +43,48 @@ interface Array { var fa; fa = fa.concat([0]); fa = fa.concat(0); +/* + + + + +declare class C { + public m(p1: C>): C; + //public p: T; +} + +var c: C; +var cc: C>; + +c = c.m(cc); +var n1: number[]; +/* +interface Array { + concat(...items: T[][]): T[]; // Note: This overload needs to be picked for arrays of arrays, even though both are applicable + concat(...items: T[]): T[]; +} +*/ +var fa: number[]; + +fa = fa.concat([0]); +fa = fa.concat(0); + + + + + +/* + + + + +declare class C { + public m(p1: C>): C; + //public p: T; +} + +var c: C; +var cc: C>; + +c = c.m(cc); + diff --git a/tests/baselines/reference/conditionalOperatorConditionIsBooleanType.js b/tests/baselines/reference/conditionalOperatorConditionIsBooleanType.js index ab9dca9023f..d9a8b2daa29 100644 --- a/tests/baselines/reference/conditionalOperatorConditionIsBooleanType.js +++ b/tests/baselines/reference/conditionalOperatorConditionIsBooleanType.js @@ -20,6 +20,7 @@ condBoolean ? exprBoolean1 : exprBoolean2; condBoolean ? exprNumber1 : exprNumber2; condBoolean ? exprString1 : exprString2; condBoolean ? exprIsObject1 : exprIsObject2; +condBoolean ? exprString1 : exprBoolean1; // union //Cond is a boolean type literal true ? exprAny1 : exprAny2; @@ -27,6 +28,7 @@ false ? exprBoolean1 : exprBoolean2; true ? exprNumber1 : exprNumber2; false ? exprString1 : exprString2; true ? exprIsObject1 : exprIsObject2; +true ? exprString1 : exprBoolean1; // union //Cond is a boolean type expression !true ? exprAny1 : exprAny2; @@ -34,6 +36,7 @@ typeof "123" == "string" ? exprBoolean1 : exprBoolean2; 2 > 1 ? exprNumber1 : exprNumber2; null === undefined ? exprString1 : exprString2; true || false ? exprIsObject1 : exprIsObject2; +null === undefined ? exprString1 : exprBoolean1; // union //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condBoolean ? exprAny1 : exprAny2; @@ -41,18 +44,22 @@ var resultIsBoolean1 = condBoolean ? exprBoolean1 : exprBoolean2; var resultIsNumber1 = condBoolean ? exprNumber1 : exprNumber2; var resultIsString1 = condBoolean ? exprString1 : exprString2; var resultIsObject1 = condBoolean ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean1 = condBoolean ? exprString1 : exprBoolean1; // union var resultIsAny2 = true ? exprAny1 : exprAny2; var resultIsBoolean2 = false ? exprBoolean1 : exprBoolean2; var resultIsNumber2 = true ? exprNumber1 : exprNumber2; var resultIsString2 = false ? exprString1 : exprString2; var resultIsObject2 = true ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean2 = true ? exprString1 : exprBoolean1; // union +var resultIsStringOrBoolean3 = false ? exprString1 : exprBoolean1; // union var resultIsAny3 = !true ? exprAny1 : exprAny2; var resultIsBoolean3 = typeof "123" == "string" ? exprBoolean1 : exprBoolean2; var resultIsNumber3 = 2 > 1 ? exprNumber1 : exprNumber2; var resultIsString3 = null === undefined ? exprString1 : exprString2; var resultIsObject3 = true || false ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean4 = typeof "123" === "string" ? exprString1 : exprBoolean1; // union //// [conditionalOperatorConditionIsBooleanType.js] @@ -74,31 +81,38 @@ condBoolean ? exprBoolean1 : exprBoolean2; condBoolean ? exprNumber1 : exprNumber2; condBoolean ? exprString1 : exprString2; condBoolean ? exprIsObject1 : exprIsObject2; +condBoolean ? exprString1 : exprBoolean1; // union //Cond is a boolean type literal true ? exprAny1 : exprAny2; false ? exprBoolean1 : exprBoolean2; true ? exprNumber1 : exprNumber2; false ? exprString1 : exprString2; true ? exprIsObject1 : exprIsObject2; +true ? exprString1 : exprBoolean1; // union //Cond is a boolean type expression !true ? exprAny1 : exprAny2; typeof "123" == "string" ? exprBoolean1 : exprBoolean2; 2 > 1 ? exprNumber1 : exprNumber2; null === undefined ? exprString1 : exprString2; true || false ? exprIsObject1 : exprIsObject2; +null === undefined ? exprString1 : exprBoolean1; // union //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condBoolean ? exprAny1 : exprAny2; var resultIsBoolean1 = condBoolean ? exprBoolean1 : exprBoolean2; var resultIsNumber1 = condBoolean ? exprNumber1 : exprNumber2; var resultIsString1 = condBoolean ? exprString1 : exprString2; var resultIsObject1 = condBoolean ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean1 = condBoolean ? exprString1 : exprBoolean1; // union var resultIsAny2 = true ? exprAny1 : exprAny2; var resultIsBoolean2 = false ? exprBoolean1 : exprBoolean2; var resultIsNumber2 = true ? exprNumber1 : exprNumber2; var resultIsString2 = false ? exprString1 : exprString2; var resultIsObject2 = true ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean2 = true ? exprString1 : exprBoolean1; // union +var resultIsStringOrBoolean3 = false ? exprString1 : exprBoolean1; // union var resultIsAny3 = !true ? exprAny1 : exprAny2; var resultIsBoolean3 = typeof "123" == "string" ? exprBoolean1 : exprBoolean2; var resultIsNumber3 = 2 > 1 ? exprNumber1 : exprNumber2; var resultIsString3 = null === undefined ? exprString1 : exprString2; var resultIsObject3 = true || false ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean4 = typeof "123" === "string" ? exprString1 : exprBoolean1; // union diff --git a/tests/baselines/reference/conditionalOperatorConditionIsBooleanType.types b/tests/baselines/reference/conditionalOperatorConditionIsBooleanType.types index b3ca65219cb..44fc9f5ed7b 100644 --- a/tests/baselines/reference/conditionalOperatorConditionIsBooleanType.types +++ b/tests/baselines/reference/conditionalOperatorConditionIsBooleanType.types @@ -66,6 +66,12 @@ condBoolean ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +condBoolean ? exprString1 : exprBoolean1; // union +>condBoolean ? exprString1 : exprBoolean1 : string | boolean +>condBoolean : boolean +>exprString1 : string +>exprBoolean1 : boolean + //Cond is a boolean type literal true ? exprAny1 : exprAny2; >true ? exprAny1 : exprAny2 : any @@ -92,6 +98,11 @@ true ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +true ? exprString1 : exprBoolean1; // union +>true ? exprString1 : exprBoolean1 : string | boolean +>exprString1 : string +>exprBoolean1 : boolean + //Cond is a boolean type expression !true ? exprAny1 : exprAny2; >!true ? exprAny1 : exprAny2 : any @@ -125,6 +136,13 @@ true || false ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +null === undefined ? exprString1 : exprBoolean1; // union +>null === undefined ? exprString1 : exprBoolean1 : string | boolean +>null === undefined : boolean +>undefined : undefined +>exprString1 : string +>exprBoolean1 : boolean + //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condBoolean ? exprAny1 : exprAny2; >resultIsAny1 : any @@ -161,6 +179,13 @@ var resultIsObject1 = condBoolean ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean1 = condBoolean ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean1 : string | boolean +>condBoolean ? exprString1 : exprBoolean1 : string | boolean +>condBoolean : boolean +>exprString1 : string +>exprBoolean1 : boolean + var resultIsAny2 = true ? exprAny1 : exprAny2; >resultIsAny2 : any >true ? exprAny1 : exprAny2 : any @@ -191,6 +216,18 @@ var resultIsObject2 = true ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean2 = true ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean2 : string | boolean +>true ? exprString1 : exprBoolean1 : string | boolean +>exprString1 : string +>exprBoolean1 : boolean + +var resultIsStringOrBoolean3 = false ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean3 : string | boolean +>false ? exprString1 : exprBoolean1 : string | boolean +>exprString1 : string +>exprBoolean1 : boolean + var resultIsAny3 = !true ? exprAny1 : exprAny2; >resultIsAny3 : any >!true ? exprAny1 : exprAny2 : any @@ -228,3 +265,11 @@ var resultIsObject3 = true || false ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean4 = typeof "123" === "string" ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean4 : string | boolean +>typeof "123" === "string" ? exprString1 : exprBoolean1 : string | boolean +>typeof "123" === "string" : boolean +>typeof "123" : string +>exprString1 : string +>exprBoolean1 : boolean + diff --git a/tests/baselines/reference/conditionalOperatorConditionIsNumberType.js b/tests/baselines/reference/conditionalOperatorConditionIsNumberType.js index 166841f0a89..46a04169e93 100644 --- a/tests/baselines/reference/conditionalOperatorConditionIsNumberType.js +++ b/tests/baselines/reference/conditionalOperatorConditionIsNumberType.js @@ -20,6 +20,7 @@ condNumber ? exprBoolean1 : exprBoolean2; condNumber ? exprNumber1 : exprNumber2; condNumber ? exprString1 : exprString2; condNumber ? exprIsObject1 : exprIsObject2; +condNumber ? exprString1 : exprBoolean1; // Union //Cond is a number type literal 1 ? exprAny1 : exprAny2; @@ -27,6 +28,7 @@ condNumber ? exprIsObject1 : exprIsObject2; 0.123456789 ? exprNumber1 : exprNumber2; - 10000000000000 ? exprString1 : exprString2; 1000000000000 ? exprIsObject1 : exprIsObject2; +10000 ? exprString1 : exprBoolean1; // Union //Cond is a number type expression function foo() { return 1 }; @@ -37,6 +39,7 @@ var array = [1, 2, 3]; "string".length ? exprNumber1 : exprNumber2; foo() ? exprString1 : exprString2; foo() / array[1] ? exprIsObject1 : exprIsObject2; +foo() ? exprString1 : exprBoolean1; // Union //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condNumber ? exprAny1 : exprAny2; @@ -44,19 +47,21 @@ var resultIsBoolean1 = condNumber ? exprBoolean1 : exprBoolean2; var resultIsNumber1 = condNumber ? exprNumber1 : exprNumber2; var resultIsString1 = condNumber ? exprString1 : exprString2; var resultIsObject1 = condNumber ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean1 = condNumber ? exprString1 : exprBoolean1; // Union var resultIsAny2 = 1 ? exprAny1 : exprAny2; var resultIsBoolean2 = 0 ? exprBoolean1 : exprBoolean2; var resultIsNumber2 = 0.123456789 ? exprNumber1 : exprNumber2; var resultIsString2 = - 10000000000000 ? exprString1 : exprString2; var resultIsObject2 = 1000000000000 ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean2 = 10000 ? exprString1 : exprBoolean1; // Union var resultIsAny3 = 1 * 0 ? exprAny1 : exprAny2; var resultIsBoolean3 = 1 + 1 ? exprBoolean1 : exprBoolean2; var resultIsNumber3 = "string".length ? exprNumber1 : exprNumber2; var resultIsString3 = foo() ? exprString1 : exprString2; var resultIsObject3 = foo() / array[1] ? exprIsObject1 : exprIsObject2; - +var resultIsStringOrBoolean3 = foo() / array[1] ? exprString1 : exprBoolean1; // Union //// [conditionalOperatorConditionIsNumberType.js] //Cond ? Expr1 : Expr2, Cond is of number type, Expr1 and Expr2 have the same type @@ -77,12 +82,14 @@ condNumber ? exprBoolean1 : exprBoolean2; condNumber ? exprNumber1 : exprNumber2; condNumber ? exprString1 : exprString2; condNumber ? exprIsObject1 : exprIsObject2; +condNumber ? exprString1 : exprBoolean1; // Union //Cond is a number type literal 1 ? exprAny1 : exprAny2; 0 ? exprBoolean1 : exprBoolean2; 0.123456789 ? exprNumber1 : exprNumber2; -10000000000000 ? exprString1 : exprString2; 1000000000000 ? exprIsObject1 : exprIsObject2; +10000 ? exprString1 : exprBoolean1; // Union //Cond is a number type expression function foo() { return 1; @@ -94,19 +101,23 @@ var array = [1, 2, 3]; "string".length ? exprNumber1 : exprNumber2; foo() ? exprString1 : exprString2; foo() / array[1] ? exprIsObject1 : exprIsObject2; +foo() ? exprString1 : exprBoolean1; // Union //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condNumber ? exprAny1 : exprAny2; var resultIsBoolean1 = condNumber ? exprBoolean1 : exprBoolean2; var resultIsNumber1 = condNumber ? exprNumber1 : exprNumber2; var resultIsString1 = condNumber ? exprString1 : exprString2; var resultIsObject1 = condNumber ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean1 = condNumber ? exprString1 : exprBoolean1; // Union var resultIsAny2 = 1 ? exprAny1 : exprAny2; var resultIsBoolean2 = 0 ? exprBoolean1 : exprBoolean2; var resultIsNumber2 = 0.123456789 ? exprNumber1 : exprNumber2; var resultIsString2 = -10000000000000 ? exprString1 : exprString2; var resultIsObject2 = 1000000000000 ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean2 = 10000 ? exprString1 : exprBoolean1; // Union var resultIsAny3 = 1 * 0 ? exprAny1 : exprAny2; var resultIsBoolean3 = 1 + 1 ? exprBoolean1 : exprBoolean2; var resultIsNumber3 = "string".length ? exprNumber1 : exprNumber2; var resultIsString3 = foo() ? exprString1 : exprString2; var resultIsObject3 = foo() / array[1] ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean3 = foo() / array[1] ? exprString1 : exprBoolean1; // Union diff --git a/tests/baselines/reference/conditionalOperatorConditionIsNumberType.types b/tests/baselines/reference/conditionalOperatorConditionIsNumberType.types index 3396885509a..99a81081d6b 100644 --- a/tests/baselines/reference/conditionalOperatorConditionIsNumberType.types +++ b/tests/baselines/reference/conditionalOperatorConditionIsNumberType.types @@ -66,6 +66,12 @@ condNumber ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +condNumber ? exprString1 : exprBoolean1; // Union +>condNumber ? exprString1 : exprBoolean1 : string | boolean +>condNumber : number +>exprString1 : string +>exprBoolean1 : boolean + //Cond is a number type literal 1 ? exprAny1 : exprAny2; >1 ? exprAny1 : exprAny2 : any @@ -93,6 +99,11 @@ condNumber ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +10000 ? exprString1 : exprBoolean1; // Union +>10000 ? exprString1 : exprBoolean1 : string | boolean +>exprString1 : string +>exprBoolean1 : boolean + //Cond is a number type expression function foo() { return 1 }; >foo : () => number @@ -137,6 +148,13 @@ foo() / array[1] ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +foo() ? exprString1 : exprBoolean1; // Union +>foo() ? exprString1 : exprBoolean1 : string | boolean +>foo() : number +>foo : () => number +>exprString1 : string +>exprBoolean1 : boolean + //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condNumber ? exprAny1 : exprAny2; >resultIsAny1 : any @@ -173,6 +191,13 @@ var resultIsObject1 = condNumber ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean1 = condNumber ? exprString1 : exprBoolean1; // Union +>resultIsStringOrBoolean1 : string | boolean +>condNumber ? exprString1 : exprBoolean1 : string | boolean +>condNumber : number +>exprString1 : string +>exprBoolean1 : boolean + var resultIsAny2 = 1 ? exprAny1 : exprAny2; >resultIsAny2 : any >1 ? exprAny1 : exprAny2 : any @@ -204,6 +229,12 @@ var resultIsObject2 = 1000000000000 ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean2 = 10000 ? exprString1 : exprBoolean1; // Union +>resultIsStringOrBoolean2 : string | boolean +>10000 ? exprString1 : exprBoolean1 : string | boolean +>exprString1 : string +>exprBoolean1 : boolean + var resultIsAny3 = 1 * 0 ? exprAny1 : exprAny2; >resultIsAny3 : any >1 * 0 ? exprAny1 : exprAny2 : any @@ -245,3 +276,14 @@ var resultIsObject3 = foo() / array[1] ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean3 = foo() / array[1] ? exprString1 : exprBoolean1; // Union +>resultIsStringOrBoolean3 : string | boolean +>foo() / array[1] ? exprString1 : exprBoolean1 : string | boolean +>foo() / array[1] : number +>foo() : number +>foo : () => number +>array[1] : number +>array : number[] +>exprString1 : string +>exprBoolean1 : boolean + diff --git a/tests/baselines/reference/conditionalOperatorConditionIsObjectType.js b/tests/baselines/reference/conditionalOperatorConditionIsObjectType.js index 3f98398d94d..b628c21bd14 100644 --- a/tests/baselines/reference/conditionalOperatorConditionIsObjectType.js +++ b/tests/baselines/reference/conditionalOperatorConditionIsObjectType.js @@ -23,6 +23,7 @@ condObject ? exprBoolean1 : exprBoolean2; condObject ? exprNumber1 : exprNumber2; condObject ? exprString1 : exprString2; condObject ? exprIsObject1 : exprIsObject2; +condObject ? exprString1 : exprBoolean1; // union //Cond is an object type literal ((a: string) => a.length) ? exprAny1 : exprAny2; @@ -30,6 +31,7 @@ condObject ? exprIsObject1 : exprIsObject2; ({}) ? exprNumber1 : exprNumber2; ({ a: 1, b: "s" }) ? exprString1 : exprString2; ({ a: 1, b: "s" }) ? exprIsObject1 : exprIsObject2; +({ a: 1, b: "s" }) ? exprString1: exprBoolean1; // union //Cond is an object type expression foo() ? exprAny1 : exprAny2; @@ -37,6 +39,7 @@ new Date() ? exprBoolean1 : exprBoolean2; new C() ? exprNumber1 : exprNumber2; C.doIt() ? exprString1 : exprString2; condObject.valueOf() ? exprIsObject1 : exprIsObject2; +new Date() ? exprString1 : exprBoolean1; // union //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condObject ? exprAny1 : exprAny2; @@ -44,18 +47,21 @@ var resultIsBoolean1 = condObject ? exprBoolean1 : exprBoolean2; var resultIsNumber1 = condObject ? exprNumber1 : exprNumber2; var resultIsString1 = condObject ? exprString1 : exprString2; var resultIsObject1 = condObject ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean1 = condObject ? exprString1 : exprBoolean1; // union var resultIsAny2 = ((a: string) => a.length) ? exprAny1 : exprAny2; var resultIsBoolean2 = ((a: string) => a.length) ? exprBoolean1 : exprBoolean2; var resultIsNumber2 = ({}) ? exprNumber1 : exprNumber2; var resultIsString2 = ({ a: 1, b: "s" }) ? exprString1 : exprString2; var resultIsObject2 = ({ a: 1, b: "s" }) ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean2 = ({ a: 1, b: "s" }) ? exprString1 : exprBoolean1; // union var resultIsAny3 = foo() ? exprAny1 : exprAny2; var resultIsBoolean3 = new Date() ? exprBoolean1 : exprBoolean2; var resultIsNumber3 = new C() ? exprNumber1 : exprNumber2; var resultIsString3 = C.doIt() ? exprString1 : exprString2; var resultIsObject3 = condObject.valueOf() ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean3 = C.doIt() ? exprString1 : exprBoolean1; // union //// [conditionalOperatorConditionIsObjectType.js] @@ -86,31 +92,37 @@ condObject ? exprBoolean1 : exprBoolean2; condObject ? exprNumber1 : exprNumber2; condObject ? exprString1 : exprString2; condObject ? exprIsObject1 : exprIsObject2; +condObject ? exprString1 : exprBoolean1; // union //Cond is an object type literal (function (a) { return a.length; }) ? exprAny1 : exprAny2; (function (a) { return a.length; }) ? exprBoolean1 : exprBoolean2; ({}) ? exprNumber1 : exprNumber2; ({ a: 1, b: "s" }) ? exprString1 : exprString2; ({ a: 1, b: "s" }) ? exprIsObject1 : exprIsObject2; +({ a: 1, b: "s" }) ? exprString1 : exprBoolean1; // union //Cond is an object type expression foo() ? exprAny1 : exprAny2; new Date() ? exprBoolean1 : exprBoolean2; new C() ? exprNumber1 : exprNumber2; C.doIt() ? exprString1 : exprString2; condObject.valueOf() ? exprIsObject1 : exprIsObject2; +new Date() ? exprString1 : exprBoolean1; // union //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condObject ? exprAny1 : exprAny2; var resultIsBoolean1 = condObject ? exprBoolean1 : exprBoolean2; var resultIsNumber1 = condObject ? exprNumber1 : exprNumber2; var resultIsString1 = condObject ? exprString1 : exprString2; var resultIsObject1 = condObject ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean1 = condObject ? exprString1 : exprBoolean1; // union var resultIsAny2 = (function (a) { return a.length; }) ? exprAny1 : exprAny2; var resultIsBoolean2 = (function (a) { return a.length; }) ? exprBoolean1 : exprBoolean2; var resultIsNumber2 = ({}) ? exprNumber1 : exprNumber2; var resultIsString2 = ({ a: 1, b: "s" }) ? exprString1 : exprString2; var resultIsObject2 = ({ a: 1, b: "s" }) ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean2 = ({ a: 1, b: "s" }) ? exprString1 : exprBoolean1; // union var resultIsAny3 = foo() ? exprAny1 : exprAny2; var resultIsBoolean3 = new Date() ? exprBoolean1 : exprBoolean2; var resultIsNumber3 = new C() ? exprNumber1 : exprNumber2; var resultIsString3 = C.doIt() ? exprString1 : exprString2; var resultIsObject3 = condObject.valueOf() ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean3 = C.doIt() ? exprString1 : exprBoolean1; // union diff --git a/tests/baselines/reference/conditionalOperatorConditionIsObjectType.types b/tests/baselines/reference/conditionalOperatorConditionIsObjectType.types index 199e93c6265..f99c591b593 100644 --- a/tests/baselines/reference/conditionalOperatorConditionIsObjectType.types +++ b/tests/baselines/reference/conditionalOperatorConditionIsObjectType.types @@ -74,6 +74,12 @@ condObject ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +condObject ? exprString1 : exprBoolean1; // union +>condObject ? exprString1 : exprBoolean1 : string | boolean +>condObject : Object +>exprString1 : string +>exprBoolean1 : boolean + //Cond is an object type literal ((a: string) => a.length) ? exprAny1 : exprAny2; >((a: string) => a.length) ? exprAny1 : exprAny2 : any @@ -122,6 +128,15 @@ condObject ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +({ a: 1, b: "s" }) ? exprString1: exprBoolean1; // union +>({ a: 1, b: "s" }) ? exprString1: exprBoolean1 : string | boolean +>({ a: 1, b: "s" }) : { a: number; b: string; } +>{ a: 1, b: "s" } : { a: number; b: string; } +>a : number +>b : string +>exprString1 : string +>exprBoolean1 : boolean + //Cond is an object type expression foo() ? exprAny1 : exprAny2; >foo() ? exprAny1 : exprAny2 : any @@ -162,6 +177,13 @@ condObject.valueOf() ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +new Date() ? exprString1 : exprBoolean1; // union +>new Date() ? exprString1 : exprBoolean1 : string | boolean +>new Date() : Date +>Date : DateConstructor +>exprString1 : string +>exprBoolean1 : boolean + //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condObject ? exprAny1 : exprAny2; >resultIsAny1 : any @@ -198,6 +220,13 @@ var resultIsObject1 = condObject ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean1 = condObject ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean1 : string | boolean +>condObject ? exprString1 : exprBoolean1 : string | boolean +>condObject : Object +>exprString1 : string +>exprBoolean1 : boolean + var resultIsAny2 = ((a: string) => a.length) ? exprAny1 : exprAny2; >resultIsAny2 : any >((a: string) => a.length) ? exprAny1 : exprAny2 : any @@ -250,6 +279,16 @@ var resultIsObject2 = ({ a: 1, b: "s" }) ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean2 = ({ a: 1, b: "s" }) ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean2 : string | boolean +>({ a: 1, b: "s" }) ? exprString1 : exprBoolean1 : string | boolean +>({ a: 1, b: "s" }) : { a: number; b: string; } +>{ a: 1, b: "s" } : { a: number; b: string; } +>a : number +>b : string +>exprString1 : string +>exprBoolean1 : boolean + var resultIsAny3 = foo() ? exprAny1 : exprAny2; >resultIsAny3 : any >foo() ? exprAny1 : exprAny2 : any @@ -294,3 +333,13 @@ var resultIsObject3 = condObject.valueOf() ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean3 = C.doIt() ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean3 : string | boolean +>C.doIt() ? exprString1 : exprBoolean1 : string | boolean +>C.doIt() : void +>C.doIt : () => void +>C : typeof C +>doIt : () => void +>exprString1 : string +>exprBoolean1 : boolean + diff --git a/tests/baselines/reference/conditionalOperatorConditoinIsAnyType.js b/tests/baselines/reference/conditionalOperatorConditoinIsAnyType.js index 5869023d17d..80cfaf97f26 100644 --- a/tests/baselines/reference/conditionalOperatorConditoinIsAnyType.js +++ b/tests/baselines/reference/conditionalOperatorConditoinIsAnyType.js @@ -21,6 +21,7 @@ condAny ? exprBoolean1 : exprBoolean2; condAny ? exprNumber1 : exprNumber2; condAny ? exprString1 : exprString2; condAny ? exprIsObject1 : exprIsObject2; +condAny ? exprString1 : exprBoolean1; // union //Cond is an any type literal null ? exprAny1 : exprAny2; @@ -28,6 +29,7 @@ null ? exprBoolean1 : exprBoolean2; undefined ? exprNumber1 : exprNumber2; [null, undefined] ? exprString1 : exprString2; [null, undefined] ? exprIsObject1 : exprIsObject2; +undefined ? exprString1 : exprBoolean1; // union //Cond is an any type expression x.doSomeThing() ? exprAny1 : exprAny2; @@ -35,6 +37,7 @@ x("x") ? exprBoolean1 : exprBoolean2; x(x) ? exprNumber1 : exprNumber2; x("x") ? exprString1 : exprString2; x.doSomeThing() ? exprIsObject1 : exprIsObject2; +x.doSomeThing() ? exprString1 : exprBoolean1; // union //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condAny ? exprAny1 : exprAny2; @@ -42,19 +45,23 @@ var resultIsBoolean1 = condAny ? exprBoolean1 : exprBoolean2; var resultIsNumber1 = condAny ? exprNumber1 : exprNumber2; var resultIsString1 = condAny ? exprString1 : exprString2; var resultIsObject1 = condAny ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean1 = condAny ? exprString1 : exprBoolean1; // union var resultIsAny2 = null ? exprAny1 : exprAny2; var resultIsBoolean2 = null ? exprBoolean1 : exprBoolean2; var resultIsNumber2 = undefined ? exprNumber1 : exprNumber2; var resultIsString2 = [null, undefined] ? exprString1 : exprString2; var resultIsObject2 = [null, undefined] ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean2 = null ? exprString1 : exprBoolean1; // union +var resultIsStringOrBoolean3 = undefined ? exprString1 : exprBoolean1; // union +var resultIsStringOrBoolean4 = [null, undefined] ? exprString1 : exprBoolean1; // union var resultIsAny3 = x.doSomeThing() ? exprAny1 : exprAny2; var resultIsBoolean3 = x("x") ? exprBoolean1 : exprBoolean2; var resultIsNumber3 = x(x) ? exprNumber1 : exprNumber2; var resultIsString3 = x("x") ? exprString1 : exprString2; var resultIsObject3 = x.doSomeThing() ? exprIsObject1 : exprIsObject2; - +var resultIsStringOrBoolean5 = x.doSomeThing() ? exprString1 : exprBoolean1; // union //// [conditionalOperatorConditoinIsAnyType.js] //Cond ? Expr1 : Expr2, Cond is of any type, Expr1 and Expr2 have the same type @@ -76,31 +83,39 @@ condAny ? exprBoolean1 : exprBoolean2; condAny ? exprNumber1 : exprNumber2; condAny ? exprString1 : exprString2; condAny ? exprIsObject1 : exprIsObject2; +condAny ? exprString1 : exprBoolean1; // union //Cond is an any type literal null ? exprAny1 : exprAny2; null ? exprBoolean1 : exprBoolean2; undefined ? exprNumber1 : exprNumber2; [null, undefined] ? exprString1 : exprString2; [null, undefined] ? exprIsObject1 : exprIsObject2; +undefined ? exprString1 : exprBoolean1; // union //Cond is an any type expression x.doSomeThing() ? exprAny1 : exprAny2; x("x") ? exprBoolean1 : exprBoolean2; x(x) ? exprNumber1 : exprNumber2; x("x") ? exprString1 : exprString2; x.doSomeThing() ? exprIsObject1 : exprIsObject2; +x.doSomeThing() ? exprString1 : exprBoolean1; // union //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condAny ? exprAny1 : exprAny2; var resultIsBoolean1 = condAny ? exprBoolean1 : exprBoolean2; var resultIsNumber1 = condAny ? exprNumber1 : exprNumber2; var resultIsString1 = condAny ? exprString1 : exprString2; var resultIsObject1 = condAny ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean1 = condAny ? exprString1 : exprBoolean1; // union var resultIsAny2 = null ? exprAny1 : exprAny2; var resultIsBoolean2 = null ? exprBoolean1 : exprBoolean2; var resultIsNumber2 = undefined ? exprNumber1 : exprNumber2; var resultIsString2 = [null, undefined] ? exprString1 : exprString2; var resultIsObject2 = [null, undefined] ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean2 = null ? exprString1 : exprBoolean1; // union +var resultIsStringOrBoolean3 = undefined ? exprString1 : exprBoolean1; // union +var resultIsStringOrBoolean4 = [null, undefined] ? exprString1 : exprBoolean1; // union var resultIsAny3 = x.doSomeThing() ? exprAny1 : exprAny2; var resultIsBoolean3 = x("x") ? exprBoolean1 : exprBoolean2; var resultIsNumber3 = x(x) ? exprNumber1 : exprNumber2; var resultIsString3 = x("x") ? exprString1 : exprString2; var resultIsObject3 = x.doSomeThing() ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean5 = x.doSomeThing() ? exprString1 : exprBoolean1; // union diff --git a/tests/baselines/reference/conditionalOperatorConditoinIsAnyType.types b/tests/baselines/reference/conditionalOperatorConditoinIsAnyType.types index 9f5fc9326bb..6542377795f 100644 --- a/tests/baselines/reference/conditionalOperatorConditoinIsAnyType.types +++ b/tests/baselines/reference/conditionalOperatorConditoinIsAnyType.types @@ -69,6 +69,12 @@ condAny ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +condAny ? exprString1 : exprBoolean1; // union +>condAny ? exprString1 : exprBoolean1 : string | boolean +>condAny : any +>exprString1 : string +>exprBoolean1 : boolean + //Cond is an any type literal null ? exprAny1 : exprAny2; >null ? exprAny1 : exprAny2 : any @@ -100,6 +106,12 @@ undefined ? exprNumber1 : exprNumber2; >exprIsObject1 : Object >exprIsObject2 : Object +undefined ? exprString1 : exprBoolean1; // union +>undefined ? exprString1 : exprBoolean1 : string | boolean +>undefined : undefined +>exprString1 : string +>exprBoolean1 : boolean + //Cond is an any type expression x.doSomeThing() ? exprAny1 : exprAny2; >x.doSomeThing() ? exprAny1 : exprAny2 : any @@ -141,6 +153,15 @@ x.doSomeThing() ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +x.doSomeThing() ? exprString1 : exprBoolean1; // union +>x.doSomeThing() ? exprString1 : exprBoolean1 : string | boolean +>x.doSomeThing() : any +>x.doSomeThing : any +>x : any +>doSomeThing : any +>exprString1 : string +>exprBoolean1 : boolean + //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condAny ? exprAny1 : exprAny2; >resultIsAny1 : any @@ -177,6 +198,13 @@ var resultIsObject1 = condAny ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean1 = condAny ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean1 : string | boolean +>condAny ? exprString1 : exprBoolean1 : string | boolean +>condAny : any +>exprString1 : string +>exprBoolean1 : boolean + var resultIsAny2 = null ? exprAny1 : exprAny2; >resultIsAny2 : any >null ? exprAny1 : exprAny2 : any @@ -212,6 +240,27 @@ var resultIsObject2 = [null, undefined] ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean2 = null ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean2 : string | boolean +>null ? exprString1 : exprBoolean1 : string | boolean +>exprString1 : string +>exprBoolean1 : boolean + +var resultIsStringOrBoolean3 = undefined ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean3 : string | boolean +>undefined ? exprString1 : exprBoolean1 : string | boolean +>undefined : undefined +>exprString1 : string +>exprBoolean1 : boolean + +var resultIsStringOrBoolean4 = [null, undefined] ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean4 : string | boolean +>[null, undefined] ? exprString1 : exprBoolean1 : string | boolean +>[null, undefined] : null[] +>undefined : undefined +>exprString1 : string +>exprBoolean1 : boolean + var resultIsAny3 = x.doSomeThing() ? exprAny1 : exprAny2; >resultIsAny3 : any >x.doSomeThing() ? exprAny1 : exprAny2 : any @@ -257,3 +306,13 @@ var resultIsObject3 = x.doSomeThing() ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean5 = x.doSomeThing() ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean5 : string | boolean +>x.doSomeThing() ? exprString1 : exprBoolean1 : string | boolean +>x.doSomeThing() : any +>x.doSomeThing : any +>x : any +>doSomeThing : any +>exprString1 : string +>exprBoolean1 : boolean + diff --git a/tests/baselines/reference/conditionalOperatorConditoinIsStringType.js b/tests/baselines/reference/conditionalOperatorConditoinIsStringType.js index 4bd67a40640..02c398e89e1 100644 --- a/tests/baselines/reference/conditionalOperatorConditoinIsStringType.js +++ b/tests/baselines/reference/conditionalOperatorConditoinIsStringType.js @@ -20,6 +20,7 @@ condString ? exprBoolean1 : exprBoolean2; condString ? exprNumber1 : exprNumber2; condString ? exprString1 : exprString2; condString ? exprIsObject1 : exprIsObject2; +condString ? exprString1 : exprBoolean1; // union //Cond is a string type literal "" ? exprAny1 : exprAny2; @@ -27,6 +28,7 @@ condString ? exprIsObject1 : exprIsObject2; 'c' ? exprNumber1 : exprNumber2; 'string' ? exprString1 : exprString2; " " ? exprIsObject1 : exprIsObject2; +"hello " ? exprString1 : exprBoolean1; // union //Cond is a string type expression function foo() { return "string" }; @@ -37,6 +39,7 @@ condString.toUpperCase ? exprBoolean1 : exprBoolean2; condString + "string" ? exprNumber1 : exprNumber2; foo() ? exprString1 : exprString2; array[1] ? exprIsObject1 : exprIsObject2; +foo() ? exprString1 : exprBoolean1; // union //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condString ? exprAny1 : exprAny2; @@ -44,19 +47,22 @@ var resultIsBoolean1 = condString ? exprBoolean1 : exprBoolean2; var resultIsNumber1 = condString ? exprNumber1 : exprNumber2; var resultIsString1 = condString ? exprString1 : exprString2; var resultIsObject1 = condString ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean1 = condString ? exprString1 : exprBoolean1; // union var resultIsAny2 = "" ? exprAny1 : exprAny2; var resultIsBoolean2 = "string" ? exprBoolean1 : exprBoolean2; var resultIsNumber2 = 'c' ? exprNumber1 : exprNumber2; var resultIsString2 = 'string' ? exprString1 : exprString2; var resultIsObject2 = " " ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean2 = "hello" ? exprString1 : exprBoolean1; // union var resultIsAny3 = typeof condString ? exprAny1 : exprAny2; var resultIsBoolean3 = condString.toUpperCase ? exprBoolean1 : exprBoolean2; var resultIsNumber3 = condString + "string" ? exprNumber1 : exprNumber2; var resultIsString3 = foo() ? exprString1 : exprString2; var resultIsObject3 = array[1] ? exprIsObject1 : exprIsObject2; - +var resultIsStringOrBoolean3 = typeof condString ? exprString1 : exprBoolean1; // union +var resultIsStringOrBoolean4 = condString.toUpperCase ? exprString1 : exprBoolean1; // union //// [conditionalOperatorConditoinIsStringType.js] //Cond ? Expr1 : Expr2, Cond is of string type, Expr1 and Expr2 have the same type @@ -77,12 +83,14 @@ condString ? exprBoolean1 : exprBoolean2; condString ? exprNumber1 : exprNumber2; condString ? exprString1 : exprString2; condString ? exprIsObject1 : exprIsObject2; +condString ? exprString1 : exprBoolean1; // union //Cond is a string type literal "" ? exprAny1 : exprAny2; "string" ? exprBoolean1 : exprBoolean2; 'c' ? exprNumber1 : exprNumber2; 'string' ? exprString1 : exprString2; " " ? exprIsObject1 : exprIsObject2; +"hello " ? exprString1 : exprBoolean1; // union //Cond is a string type expression function foo() { return "string"; @@ -94,19 +102,24 @@ condString.toUpperCase ? exprBoolean1 : exprBoolean2; condString + "string" ? exprNumber1 : exprNumber2; foo() ? exprString1 : exprString2; array[1] ? exprIsObject1 : exprIsObject2; +foo() ? exprString1 : exprBoolean1; // union //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condString ? exprAny1 : exprAny2; var resultIsBoolean1 = condString ? exprBoolean1 : exprBoolean2; var resultIsNumber1 = condString ? exprNumber1 : exprNumber2; var resultIsString1 = condString ? exprString1 : exprString2; var resultIsObject1 = condString ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean1 = condString ? exprString1 : exprBoolean1; // union var resultIsAny2 = "" ? exprAny1 : exprAny2; var resultIsBoolean2 = "string" ? exprBoolean1 : exprBoolean2; var resultIsNumber2 = 'c' ? exprNumber1 : exprNumber2; var resultIsString2 = 'string' ? exprString1 : exprString2; var resultIsObject2 = " " ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean2 = "hello" ? exprString1 : exprBoolean1; // union var resultIsAny3 = typeof condString ? exprAny1 : exprAny2; var resultIsBoolean3 = condString.toUpperCase ? exprBoolean1 : exprBoolean2; var resultIsNumber3 = condString + "string" ? exprNumber1 : exprNumber2; var resultIsString3 = foo() ? exprString1 : exprString2; var resultIsObject3 = array[1] ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean3 = typeof condString ? exprString1 : exprBoolean1; // union +var resultIsStringOrBoolean4 = condString.toUpperCase ? exprString1 : exprBoolean1; // union diff --git a/tests/baselines/reference/conditionalOperatorConditoinIsStringType.types b/tests/baselines/reference/conditionalOperatorConditoinIsStringType.types index 668e0fc437c..45a4db8d295 100644 --- a/tests/baselines/reference/conditionalOperatorConditoinIsStringType.types +++ b/tests/baselines/reference/conditionalOperatorConditoinIsStringType.types @@ -66,6 +66,12 @@ condString ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +condString ? exprString1 : exprBoolean1; // union +>condString ? exprString1 : exprBoolean1 : string | boolean +>condString : string +>exprString1 : string +>exprBoolean1 : boolean + //Cond is a string type literal "" ? exprAny1 : exprAny2; >"" ? exprAny1 : exprAny2 : any @@ -92,6 +98,11 @@ condString ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +"hello " ? exprString1 : exprBoolean1; // union +>"hello " ? exprString1 : exprBoolean1 : string | boolean +>exprString1 : string +>exprBoolean1 : boolean + //Cond is a string type expression function foo() { return "string" }; >foo : () => string @@ -136,6 +147,13 @@ array[1] ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +foo() ? exprString1 : exprBoolean1; // union +>foo() ? exprString1 : exprBoolean1 : string | boolean +>foo() : string +>foo : () => string +>exprString1 : string +>exprBoolean1 : boolean + //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condString ? exprAny1 : exprAny2; >resultIsAny1 : any @@ -172,6 +190,13 @@ var resultIsObject1 = condString ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean1 = condString ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean1 : string | boolean +>condString ? exprString1 : exprBoolean1 : string | boolean +>condString : string +>exprString1 : string +>exprBoolean1 : boolean + var resultIsAny2 = "" ? exprAny1 : exprAny2; >resultIsAny2 : any >"" ? exprAny1 : exprAny2 : any @@ -202,6 +227,12 @@ var resultIsObject2 = " " ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean2 = "hello" ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean2 : string | boolean +>"hello" ? exprString1 : exprBoolean1 : string | boolean +>exprString1 : string +>exprBoolean1 : boolean + var resultIsAny3 = typeof condString ? exprAny1 : exprAny2; >resultIsAny3 : any >typeof condString ? exprAny1 : exprAny2 : any @@ -243,3 +274,20 @@ var resultIsObject3 = array[1] ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean3 = typeof condString ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean3 : string | boolean +>typeof condString ? exprString1 : exprBoolean1 : string | boolean +>typeof condString : string +>condString : string +>exprString1 : string +>exprBoolean1 : boolean + +var resultIsStringOrBoolean4 = condString.toUpperCase ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean4 : string | boolean +>condString.toUpperCase ? exprString1 : exprBoolean1 : string | boolean +>condString.toUpperCase : () => string +>condString : string +>toUpperCase : () => string +>exprString1 : string +>exprBoolean1 : boolean + diff --git a/tests/baselines/reference/conditionalOperatorWithoutIdenticalBCT.errors.txt b/tests/baselines/reference/conditionalOperatorWithoutIdenticalBCT.errors.txt index 954e8af856f..2fa13333058 100644 --- a/tests/baselines/reference/conditionalOperatorWithoutIdenticalBCT.errors.txt +++ b/tests/baselines/reference/conditionalOperatorWithoutIdenticalBCT.errors.txt @@ -4,13 +4,13 @@ tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorWithou tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorWithoutIdenticalBCT.ts(16,5): error TS2322: Type 'A | B' is not assignable to type 'B'. Type 'A' is not assignable to type 'B'. Property 'propertyB' is missing in type 'A'. -tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorWithoutIdenticalBCT.ts(18,5): error TS2322: Type '((m: X) => number) | ((n: X) => string)' is not assignable to type '(t: X) => number'. +tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorWithoutIdenticalBCT.ts(19,5): error TS2322: Type '((m: X) => number) | ((n: X) => string)' is not assignable to type '(t: X) => number'. Type '(n: X) => string' is not assignable to type '(t: X) => number'. Type 'string' is not assignable to type 'number'. -tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorWithoutIdenticalBCT.ts(19,5): error TS2322: Type '((m: X) => number) | ((n: X) => string)' is not assignable to type '(t: X) => string'. +tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorWithoutIdenticalBCT.ts(20,5): error TS2322: Type '((m: X) => number) | ((n: X) => string)' is not assignable to type '(t: X) => string'. Type '(m: X) => number' is not assignable to type '(t: X) => string'. Type 'number' is not assignable to type 'string'. -tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorWithoutIdenticalBCT.ts(20,5): error TS2322: Type '((m: X) => number) | ((n: X) => string)' is not assignable to type '(t: X) => boolean'. +tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorWithoutIdenticalBCT.ts(21,5): error TS2322: Type '((m: X) => number) | ((n: X) => string)' is not assignable to type '(t: X) => boolean'. Type '(m: X) => number' is not assignable to type '(t: X) => boolean'. Type 'number' is not assignable to type 'boolean'. @@ -40,6 +40,7 @@ tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorWithou !!! error TS2322: Type 'A | B' is not assignable to type 'B'. !!! error TS2322: Type 'A' is not assignable to type 'B'. !!! error TS2322: Property 'propertyB' is missing in type 'A'. + var result31: A | B = true ? a : b; var result4: (t: X) => number = true ? (m) => m.propertyX1 : (n) => n.propertyX2; ~~~~~~~ @@ -55,4 +56,6 @@ tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorWithou ~~~~~~~ !!! error TS2322: Type '((m: X) => number) | ((n: X) => string)' is not assignable to type '(t: X) => boolean'. !!! error TS2322: Type '(m: X) => number' is not assignable to type '(t: X) => boolean'. -!!! error TS2322: Type 'number' is not assignable to type 'boolean'. \ No newline at end of file +!!! error TS2322: Type 'number' is not assignable to type 'boolean'. + var result61: (t: X) => number| string = true ? (m) => m.propertyX1 : (n) => n.propertyX2; + \ No newline at end of file diff --git a/tests/baselines/reference/conditionalOperatorWithoutIdenticalBCT.js b/tests/baselines/reference/conditionalOperatorWithoutIdenticalBCT.js index b6376dd781f..83262ed1301 100644 --- a/tests/baselines/reference/conditionalOperatorWithoutIdenticalBCT.js +++ b/tests/baselines/reference/conditionalOperatorWithoutIdenticalBCT.js @@ -15,10 +15,13 @@ var result1 = true ? a : b; //Be contextually typed and and bct is not identical, results in errors that union type is not assignable to target var result2: A = true ? a : b; var result3: B = true ? a : b; +var result31: A | B = true ? a : b; var result4: (t: X) => number = true ? (m) => m.propertyX1 : (n) => n.propertyX2; var result5: (t: X) => string = true ? (m) => m.propertyX1 : (n) => n.propertyX2; -var result6: (t: X) => boolean = true ? (m) => m.propertyX1 : (n) => n.propertyX2; +var result6: (t: X) => boolean = true ? (m) => m.propertyX1 : (n) => n.propertyX2; +var result61: (t: X) => number| string = true ? (m) => m.propertyX1 : (n) => n.propertyX2; + //// [conditionalOperatorWithoutIdenticalBCT.js] var __extends = this.__extends || function (d, b) { @@ -59,6 +62,8 @@ var result1 = true ? a : b; //Be contextually typed and and bct is not identical, results in errors that union type is not assignable to target var result2 = true ? a : b; var result3 = true ? a : b; +var result31 = true ? a : b; var result4 = true ? function (m) { return m.propertyX1; } : function (n) { return n.propertyX2; }; var result5 = true ? function (m) { return m.propertyX1; } : function (n) { return n.propertyX2; }; var result6 = true ? function (m) { return m.propertyX1; } : function (n) { return n.propertyX2; }; +var result61 = true ? function (m) { return m.propertyX1; } : function (n) { return n.propertyX2; }; diff --git a/tests/baselines/reference/conformanceFunctionOverloads.js b/tests/baselines/reference/conformanceFunctionOverloads.js index 15dec719e40..b245f6a2c91 100644 --- a/tests/baselines/reference/conformanceFunctionOverloads.js +++ b/tests/baselines/reference/conformanceFunctionOverloads.js @@ -25,3 +25,13 @@ //// [conformanceFunctionOverloads.js] // Function overloads do not emit code +// Function overload signature with optional parameter +// Function overload signature with optional parameter +// Function overloads with generic and non-generic overloads +// Function overloads whose only difference is returning different unconstrained generic parameters +// Function overloads whose only difference is returning different constrained generic parameters +// Function overloads that differ only by type parameter constraints +// Function overloads with matching accessibility +// Function overloads with matching export +// Function overloads with more params than implementation signature +// Function overloads where return types are same infinitely recursive type reference diff --git a/tests/baselines/reference/contextualTypeWithTuple.errors.txt b/tests/baselines/reference/contextualTypeWithTuple.errors.txt index 875d7b5e20a..ff9ace5a2c0 100644 --- a/tests/baselines/reference/contextualTypeWithTuple.errors.txt +++ b/tests/baselines/reference/contextualTypeWithTuple.errors.txt @@ -4,21 +4,27 @@ tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(3,5): error TS232 Type 'string | number | boolean' is not assignable to type 'string | number'. Type 'boolean' is not assignable to type 'string | number'. Type 'boolean' is not assignable to type 'number'. -tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(8,1): error TS2322: Type '[number, string, boolean]' is not assignable to type '[number, string]'. -tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(11,1): error TS2322: Type '[{}, number]' is not assignable to type '[{ a: string; }, number]'. +tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(15,1): error TS2322: Type '[number, string, boolean]' is not assignable to type '[number, string]'. +tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(18,1): error TS2322: Type '[{}, number]' is not assignable to type '[{ a: string; }, number]'. Types of property '0' are incompatible. Type '{}' is not assignable to type '{ a: string; }'. Property 'a' is missing in type '{}'. -tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(12,1): error TS2322: Type '[number, string]' is not assignable to type '[number, string, boolean]'. +tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(19,1): error TS2322: Type '[number, string]' is not assignable to type '[number, string, boolean]'. Property '2' is missing in type '[number, string]'. -tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(13,5): error TS2322: Type '[string, string, number]' is not assignable to type '[string, string]'. +tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(20,5): error TS2322: Type '[string, string, number]' is not assignable to type '[string, string]'. Types of property 'pop' are incompatible. Type '() => string | number' is not assignable to type '() => string'. Type 'string | number' is not assignable to type 'string'. Type 'number' is not assignable to type 'string'. +tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(24,1): error TS2322: Type '[C, string | number]' is not assignable to type '[C, string | number, D]'. + Property '2' is missing in type '[C, string | number]'. +tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(25,1): error TS2322: Type '[number, string | number]' is not assignable to type '[number, string]'. + Types of property '1' are incompatible. + Type 'string | number' is not assignable to type 'string'. + Type 'number' is not assignable to type 'string'. -==== tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts (5 errors) ==== +==== tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts (7 errors) ==== // no error var numStrTuple: [number, string] = [5, "hello"]; var numStrTuple2: [number, string] = [5, "foo", true]; @@ -32,6 +38,13 @@ tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(13,5): error TS23 var numStrBoolTuple: [number, string, boolean] = [5, "foo", true]; var objNumTuple: [{ a: string }, number] = [{ a: "world" }, 5]; var strTupleTuple: [string, [number, {}]] = ["bar", [5, { x: 1, y: 1 }]]; + class C { } + class D { } + var unionTuple: [C, string | number] = [new C(), "foo"]; + var unionTuple1: [C, string | number] = [new C(), "foo"]; + var unionTuple2: [C, string | number, D] = [new C(), "foo", new D()]; + var unionTuple3: [number, string| number] = [10, "foo"]; + numStrTuple = numStrTuple2; numStrTuple = numStrBoolTuple; ~~~~~~~~~~~ @@ -55,4 +68,16 @@ tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(13,5): error TS23 !!! error TS2322: Type '() => string | number' is not assignable to type '() => string'. !!! error TS2322: Type 'string | number' is not assignable to type 'string'. !!! error TS2322: Type 'number' is not assignable to type 'string'. - \ No newline at end of file + + unionTuple = unionTuple1; + unionTuple = unionTuple2; + unionTuple2 = unionTuple; + ~~~~~~~~~~~ +!!! error TS2322: Type '[C, string | number]' is not assignable to type '[C, string | number, D]'. +!!! error TS2322: Property '2' is missing in type '[C, string | number]'. + numStrTuple = unionTuple3; + ~~~~~~~~~~~ +!!! error TS2322: Type '[number, string | number]' is not assignable to type '[number, string]'. +!!! error TS2322: Types of property '1' are incompatible. +!!! error TS2322: Type 'string | number' is not assignable to type 'string'. +!!! error TS2322: Type 'number' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/contextualTypeWithTuple.js b/tests/baselines/reference/contextualTypeWithTuple.js index 61a2df5d8ce..cfcdd13f7d0 100644 --- a/tests/baselines/reference/contextualTypeWithTuple.js +++ b/tests/baselines/reference/contextualTypeWithTuple.js @@ -5,6 +5,13 @@ var numStrTuple2: [number, string] = [5, "foo", true]; var numStrBoolTuple: [number, string, boolean] = [5, "foo", true]; var objNumTuple: [{ a: string }, number] = [{ a: "world" }, 5]; var strTupleTuple: [string, [number, {}]] = ["bar", [5, { x: 1, y: 1 }]]; +class C { } +class D { } +var unionTuple: [C, string | number] = [new C(), "foo"]; +var unionTuple1: [C, string | number] = [new C(), "foo"]; +var unionTuple2: [C, string | number, D] = [new C(), "foo", new D()]; +var unionTuple3: [number, string| number] = [10, "foo"]; + numStrTuple = numStrTuple2; numStrTuple = numStrBoolTuple; @@ -12,7 +19,11 @@ numStrTuple = numStrBoolTuple; objNumTuple = [ {}, 5]; numStrBoolTuple = numStrTuple; var strStrTuple: [string, string] = ["foo", "bar", 5]; - + +unionTuple = unionTuple1; +unionTuple = unionTuple2; +unionTuple2 = unionTuple; +numStrTuple = unionTuple3; //// [contextualTypeWithTuple.js] // no error @@ -21,9 +32,27 @@ var numStrTuple2 = [5, "foo", true]; var numStrBoolTuple = [5, "foo", true]; var objNumTuple = [{ a: "world" }, 5]; var strTupleTuple = ["bar", [5, { x: 1, y: 1 }]]; +var C = (function () { + function C() { + } + return C; +})(); +var D = (function () { + function D() { + } + return D; +})(); +var unionTuple = [new C(), "foo"]; +var unionTuple1 = [new C(), "foo"]; +var unionTuple2 = [new C(), "foo", new D()]; +var unionTuple3 = [10, "foo"]; numStrTuple = numStrTuple2; numStrTuple = numStrBoolTuple; // error objNumTuple = [{}, 5]; numStrBoolTuple = numStrTuple; var strStrTuple = ["foo", "bar", 5]; +unionTuple = unionTuple1; +unionTuple = unionTuple2; +unionTuple2 = unionTuple; +numStrTuple = unionTuple3; diff --git a/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.js b/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.js index 2e21235ea0a..e29d4720cbc 100644 --- a/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.js +++ b/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.js @@ -45,42 +45,6 @@ var x = function (a) { return a.toString(); }; var x2 = function (a) { return a.toString(); }; // Like iWithCallSignatures var x2 = function (a) { return a; }; // Like iWithCallSignatures2 // With call signatures of mismatching parameter type -var x3 = function (a /*here a should be any*/) { return a.toString(); }; +var x3 = function (a) { return a.toString(); }; // With call signature count mismatch -var x4 = function (a //When used as a contextual type, a union type U has those members that are present in any of -// its constituent types, with types that are unions of the respective members in the constituent types. - -// Let S be the set of types in U that have call signatures. -// If S is not empty and the sets of call signatures of the types in S are identical ignoring return types, -// U has the same set of call signatures, but with return types that are unions of the return types of the respective call signatures from each type in S. - -interface IWithNoCallSignatures { - foo: string; -} -interface IWithCallSignatures { - (a: number): string; -} -interface IWithCallSignatures2 { - (a: number): number; -} -interface IWithCallSignatures3 { - (b: string): number; -} -interface IWithCallSignatures4 { - (a: number): string; - (a: string, b: number): number; -} - -// With no call signature | callSignatures -var x: IWithNoCallSignatures | IWithCallSignatures = a => a.toString(); - -// With call signatures with different return type -var x2: IWithCallSignatures | IWithCallSignatures2 = a => a.toString(); // Like iWithCallSignatures -var x2: IWithCallSignatures | IWithCallSignatures2 = a => a; // Like iWithCallSignatures2 - -// With call signatures of mismatching parameter type -var x3: IWithCallSignatures | IWithCallSignatures3 = a => /*here a should be any*/ a.toString(); - -// With call signature count mismatch -var x4: IWithCallSignatures | IWithCallSignatures4 = a => - ) { return a.toString(); }; +var x4 = function (a) { return a.toString(); }; diff --git a/tests/baselines/reference/emitCommentsOnlyFile.js b/tests/baselines/reference/emitCommentsOnlyFile.js index 263e9dd2588..d720dc3c191 100644 --- a/tests/baselines/reference/emitCommentsOnlyFile.js +++ b/tests/baselines/reference/emitCommentsOnlyFile.js @@ -29,3 +29,29 @@ //// [emitCommentsOnlyFile.js] +/** +* @name Foo +* @class +*/ +/**#@+ +* @memberOf Foo# +* @field +*/ +/** +* @name bar +* @type Object[] +*/ +/**#@-*/ +/** +* @name Foo2 +* @class +*/ +/**#@+ +* @memberOf Foo2# +* @field +*/ +/** +* @name bar +* @type Object[] +*/ +/**#@-*/ diff --git a/tests/baselines/reference/emitPostComments.js b/tests/baselines/reference/emitPostComments.js index 98d1d59457b..8a5736af00d 100644 --- a/tests/baselines/reference/emitPostComments.js +++ b/tests/baselines/reference/emitPostComments.js @@ -31,3 +31,29 @@ var y = 10; //// [emitPostComments.js] var y = 10; +/** +* @name Foo +* @class +*/ +/**#@+ +* @memberOf Foo# +* @field +*/ +/** +* @name bar +* @type Object[] +*/ +/**#@-*/ +/** +* @name Foo2 +* @class +*/ +/**#@+ +* @memberOf Foo2# +* @field +*/ +/** +* @name bar +* @type Object[] +*/ +/**#@-*/ diff --git a/tests/baselines/reference/emitPreComments.js b/tests/baselines/reference/emitPreComments.js index 5a79a430175..4ca3297fce7 100644 --- a/tests/baselines/reference/emitPreComments.js +++ b/tests/baselines/reference/emitPreComments.js @@ -33,3 +33,29 @@ var y = 10; //// [emitPreComments.js] // This is pre comment var y = 10; +/** +* @name Foo +* @class +*/ +/**#@+ +* @memberOf Foo# +* @field +*/ +/** +* @name bar +* @type Object[] +*/ +/**#@-*/ +/** +* @name Foo2 +* @class +*/ +/**#@+ +* @memberOf Foo2# +* @field +*/ +/** +* @name bar +* @type Object[] +*/ +/**#@-*/ diff --git a/tests/baselines/reference/errorSupression1.js b/tests/baselines/reference/errorSupression1.js index 92330a6c074..059530be452 100644 --- a/tests/baselines/reference/errorSupression1.js +++ b/tests/baselines/reference/errorSupression1.js @@ -20,3 +20,4 @@ var Foo = (function () { var baz = Foo.b; // Foo.b won't bind. baz.concat("y"); +// So we don't want an error on 'concat'. diff --git a/tests/baselines/reference/everyTypeAssignableToAny.js b/tests/baselines/reference/everyTypeAssignableToAny.js index 5ff22ce1962..8730167c3ff 100644 --- a/tests/baselines/reference/everyTypeAssignableToAny.js +++ b/tests/baselines/reference/everyTypeAssignableToAny.js @@ -113,3 +113,8 @@ function foo(x, y, z) { a = y; a = z; } +//function foo(x: T, y: U, z: V) { +// a = x; +// a = y; +// a = z; +//} diff --git a/tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.js b/tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.js new file mode 100644 index 00000000000..f6f9572ba6b --- /dev/null +++ b/tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.js @@ -0,0 +1,19 @@ +//// [externalModuleReferenceDoubleUnderscore1.ts] +declare module 'timezonecomplete' { + import basics = require("__timezonecomplete/basics"); + export import TimeUnit = basics.TimeUnit; +} + +declare module '__timezonecomplete/basics' { + export enum TimeUnit { + Second = 0, + Minute = 1, + Hour = 2, + Day = 3, + Week = 4, + Month = 5, + Year = 6, + } +} + +//// [externalModuleReferenceDoubleUnderscore1.js] diff --git a/tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.types b/tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.types new file mode 100644 index 00000000000..e255e64d467 --- /dev/null +++ b/tests/baselines/reference/externalModuleReferenceDoubleUnderscore1.types @@ -0,0 +1,37 @@ +=== tests/cases/compiler/externalModuleReferenceDoubleUnderscore1.ts === +declare module 'timezonecomplete' { + import basics = require("__timezonecomplete/basics"); +>basics : typeof basics + + export import TimeUnit = basics.TimeUnit; +>TimeUnit : typeof basics.TimeUnit +>basics : typeof basics +>TimeUnit : basics.TimeUnit +} + +declare module '__timezonecomplete/basics' { + export enum TimeUnit { +>TimeUnit : TimeUnit + + Second = 0, +>Second : TimeUnit + + Minute = 1, +>Minute : TimeUnit + + Hour = 2, +>Hour : TimeUnit + + Day = 3, +>Day : TimeUnit + + Week = 4, +>Week : TimeUnit + + Month = 5, +>Month : TimeUnit + + Year = 6, +>Year : TimeUnit + } +} diff --git a/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors1.errors.txt b/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors1.errors.txt index 309e731e54f..5934ab52ccf 100644 --- a/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors1.errors.txt +++ b/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors1.errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors1.ts(1,9): error TS1016: A required parameter cannot follow an optional parameter. -tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors1.ts(2,5): error TS1047: A rest parameter cannot be optional. +tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors1.ts(2,8): error TS1047: A rest parameter cannot be optional. tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors1.ts(4,5): error TS1048: A rest parameter cannot have an initializer. tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors1.ts(7,12): error TS1016: A required parameter cannot follow an optional parameter. @@ -9,7 +9,7 @@ tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors1.ts(7,12): error TS1016 ~~~~ !!! error TS1016: A required parameter cannot follow an optional parameter. (...arg?) => 102; - ~~~ + ~ !!! error TS1047: A rest parameter cannot be optional. (...arg) => 103; (...arg:number [] = []) => 104; diff --git a/tests/baselines/reference/functionConstraintSatisfaction.js b/tests/baselines/reference/functionConstraintSatisfaction.js index 452080917db..a16f4d1ed36 100644 --- a/tests/baselines/reference/functionConstraintSatisfaction.js +++ b/tests/baselines/reference/functionConstraintSatisfaction.js @@ -113,3 +113,7 @@ function foo2(x, y) { foo(x); foo(y); } +//function foo2(x: T, y: U) { +// foo(x); +// foo(y); +//} diff --git a/tests/baselines/reference/functionImplementationErrors.errors.txt b/tests/baselines/reference/functionImplementationErrors.errors.txt index fbae17a609d..8ebd5aa272d 100644 --- a/tests/baselines/reference/functionImplementationErrors.errors.txt +++ b/tests/baselines/reference/functionImplementationErrors.errors.txt @@ -6,9 +6,15 @@ tests/cases/conformance/functions/functionImplementationErrors.ts(25,16): error tests/cases/conformance/functions/functionImplementationErrors.ts(30,17): error TS2373: Initializer of parameter 'n' cannot reference identifier 'm' declared after it. tests/cases/conformance/functions/functionImplementationErrors.ts(35,17): error TS2373: Initializer of parameter 'n' cannot reference identifier 'm' declared after it. tests/cases/conformance/functions/functionImplementationErrors.ts(40,28): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. +tests/cases/conformance/functions/functionImplementationErrors.ts(49,1): error TS2354: No best common type exists among return expressions. +tests/cases/conformance/functions/functionImplementationErrors.ts(53,10): error TS2354: No best common type exists among return expressions. +tests/cases/conformance/functions/functionImplementationErrors.ts(57,11): error TS2354: No best common type exists among return expressions. +tests/cases/conformance/functions/functionImplementationErrors.ts(61,1): error TS2354: No best common type exists among return expressions. +tests/cases/conformance/functions/functionImplementationErrors.ts(65,11): error TS2354: No best common type exists among return expressions. +tests/cases/conformance/functions/functionImplementationErrors.ts(69,11): error TS2354: No best common type exists among return expressions. -==== tests/cases/conformance/functions/functionImplementationErrors.ts (8 errors) ==== +==== tests/cases/conformance/functions/functionImplementationErrors.ts (14 errors) ==== // FunctionExpression with no return type annotation with multiple return statements with unrelated types var f1 = function () { ~~~~~~~~~~~~~ @@ -83,4 +89,63 @@ tests/cases/conformance/functions/functionImplementationErrors.ts(40,28): error throw undefined; var x = 4; }; + + class Base { private x; } + class AnotherClass { private y; } + class Derived1 extends Base { private m; } + class Derived2 extends Base { private n; } + function f8() { + ~~~~~~~~~~~~~~~ + return new Derived1(); + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + return new Derived2(); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + } + ~ +!!! error TS2354: No best common type exists among return expressions. + var f9 = function () { + ~~~~~~~~~~~~~ + return new Derived1(); + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + return new Derived2(); + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + }; + ~ +!!! error TS2354: No best common type exists among return expressions. + var f10 = () => { + ~~~~~~~ + return new Derived1(); + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + return new Derived2(); + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + }; + ~ +!!! error TS2354: No best common type exists among return expressions. + function f11() { + ~~~~~~~~~~~~~~~~ + return new Base(); + ~~~~~~~~~~~~~~~~~~~~~~ + return new AnotherClass(); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + } + ~ +!!! error TS2354: No best common type exists among return expressions. + var f12 = function () { + ~~~~~~~~~~~~~ + return new Base(); + ~~~~~~~~~~~~~~~~~~~~~~ + return new AnotherClass(); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + }; + ~ +!!! error TS2354: No best common type exists among return expressions. + var f13 = () => { + ~~~~~~~ + return new Base(); + ~~~~~~~~~~~~~~~~~~~~~~ + return new AnotherClass(); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + }; + ~ +!!! error TS2354: No best common type exists among return expressions. \ No newline at end of file diff --git a/tests/baselines/reference/functionImplementationErrors.js b/tests/baselines/reference/functionImplementationErrors.js index 90e1997f396..5eaf9027335 100644 --- a/tests/baselines/reference/functionImplementationErrors.js +++ b/tests/baselines/reference/functionImplementationErrors.js @@ -42,9 +42,44 @@ undefined === function (): number { throw undefined; var x = 4; }; + +class Base { private x; } +class AnotherClass { private y; } +class Derived1 extends Base { private m; } +class Derived2 extends Base { private n; } +function f8() { + return new Derived1(); + return new Derived2(); +} +var f9 = function () { + return new Derived1(); + return new Derived2(); +}; +var f10 = () => { + return new Derived1(); + return new Derived2(); +}; +function f11() { + return new Base(); + return new AnotherClass(); +} +var f12 = function () { + return new Base(); + return new AnotherClass(); +}; +var f13 = () => { + return new Base(); + return new AnotherClass(); +}; //// [functionImplementationErrors.js] +var __extends = this.__extends || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + __.prototype = b.prototype; + d.prototype = new __(); +}; // FunctionExpression with no return type annotation with multiple return statements with unrelated types var f1 = function () { return ''; @@ -86,3 +121,51 @@ undefined === function () { throw undefined; var x = 4; }; +var Base = (function () { + function Base() { + } + return Base; +})(); +var AnotherClass = (function () { + function AnotherClass() { + } + return AnotherClass; +})(); +var Derived1 = (function (_super) { + __extends(Derived1, _super); + function Derived1() { + _super.apply(this, arguments); + } + return Derived1; +})(Base); +var Derived2 = (function (_super) { + __extends(Derived2, _super); + function Derived2() { + _super.apply(this, arguments); + } + return Derived2; +})(Base); +function f8() { + return new Derived1(); + return new Derived2(); +} +var f9 = function () { + return new Derived1(); + return new Derived2(); +}; +var f10 = function () { + return new Derived1(); + return new Derived2(); +}; +function f11() { + return new Base(); + return new AnotherClass(); +} +var f12 = function () { + return new Base(); + return new AnotherClass(); +}; +var f13 = function () { + return new Base(); + return new AnotherClass(); +}; diff --git a/tests/baselines/reference/functionImplementations.js b/tests/baselines/reference/functionImplementations.js index 365ee1d7c0d..7c7b753a880 100644 --- a/tests/baselines/reference/functionImplementations.js +++ b/tests/baselines/reference/functionImplementations.js @@ -70,6 +70,10 @@ var n = function () { return 5; }(); +// Otherwise, the inferred return type is the first of the types of the return statement expressions +// in the function body that is a supertype of each of the others, +// ignoring return statements with no expressions. +// A compile - time error occurs if no return statement expression has a type that is a supertype of each of the others. // FunctionExpression with no return type annotation with multiple return statements with subtype relation between returns class Base { private m; } class Derived extends Base { private q; } @@ -120,9 +124,37 @@ function f6(): number { return; } - - - +class Derived2 extends Base { private r: string; } +class AnotherClass { private x } +// if f is a contextually typed function expression, the inferred return type is the union type +// of the types of the return statement expressions in the function body, +// ignoring return statements with no expressions. +var f7: (x: number) => string | number = x => { // should be (x: number) => number | string + if (x < 0) { return x; } + return x.toString(); +} +var f8: (x: number) => any = x => { // should be (x: number) => Base + return new Base(); + return new Derived2(); +} +var f9: (x: number) => any = x => { // should be (x: number) => Base + return new Base(); + return new Derived(); + return new Derived2(); +} +var f10: (x: number) => any = x => { // should be (x: number) => Derived | Derived1 + return new Derived(); + return new Derived2(); +} +var f11: (x: number) => any = x => { // should be (x: number) => Base | AnotherClass + return new Base(); + return new AnotherClass(); +} +var f12: (x: number) => any = x => { // should be (x: number) => Base | AnotherClass + return new Base(); + return; // should be ignored + return new AnotherClass(); +} //// [functionImplementations.js] var __extends = this.__extends || function (d, b) { @@ -192,6 +224,10 @@ var n = function () { return 3; return 5; }(); +// Otherwise, the inferred return type is the first of the types of the return statement expressions +// in the function body that is a supertype of each of the others, +// ignoring return statements with no expressions. +// A compile - time error occurs if no return statement expression has a type that is a supertype of each of the others. // FunctionExpression with no return type annotation with multiple return statements with subtype relation between returns var Base = (function () { function Base() { @@ -249,3 +285,46 @@ function opt3(n, m) { function f6() { return; } +var Derived2 = (function (_super) { + __extends(Derived2, _super); + function Derived2() { + _super.apply(this, arguments); + } + return Derived2; +})(Base); +var AnotherClass = (function () { + function AnotherClass() { + } + return AnotherClass; +})(); +// if f is a contextually typed function expression, the inferred return type is the union type +// of the types of the return statement expressions in the function body, +// ignoring return statements with no expressions. +var f7 = function (x) { + if (x < 0) { + return x; + } + return x.toString(); +}; +var f8 = function (x) { + return new Base(); + return new Derived2(); +}; +var f9 = function (x) { + return new Base(); + return new Derived(); + return new Derived2(); +}; +var f10 = function (x) { + return new Derived(); + return new Derived2(); +}; +var f11 = function (x) { + return new Base(); + return new AnotherClass(); +}; +var f12 = function (x) { + return new Base(); + return; // should be ignored + return new AnotherClass(); +}; diff --git a/tests/baselines/reference/functionImplementations.types b/tests/baselines/reference/functionImplementations.types index 29fe7c0e39c..04144e3a65b 100644 --- a/tests/baselines/reference/functionImplementations.types +++ b/tests/baselines/reference/functionImplementations.types @@ -168,6 +168,10 @@ var n = function () { return 5; }(); +// Otherwise, the inferred return type is the first of the types of the return statement expressions +// in the function body that is a supertype of each of the others, +// ignoring return statements with no expressions. +// A compile - time error occurs if no return statement expression has a type that is a supertype of each of the others. // FunctionExpression with no return type annotation with multiple return statements with subtype relation between returns class Base { private m; } >Base : Base @@ -292,6 +296,107 @@ function f6(): number { return; } +class Derived2 extends Base { private r: string; } +>Derived2 : Derived2 +>Base : Base +>r : string +class AnotherClass { private x } +>AnotherClass : AnotherClass +>x : any +// if f is a contextually typed function expression, the inferred return type is the union type +// of the types of the return statement expressions in the function body, +// ignoring return statements with no expressions. +var f7: (x: number) => string | number = x => { // should be (x: number) => number | string +>f7 : (x: number) => string | number +>x : number +>x => { // should be (x: number) => number | string if (x < 0) { return x; } return x.toString();} : (x: number) => string | number +>x : number + if (x < 0) { return x; } +>x < 0 : boolean +>x : number +>x : number + + return x.toString(); +>x.toString() : string +>x.toString : (radix?: number) => string +>x : number +>toString : (radix?: number) => string +} +var f8: (x: number) => any = x => { // should be (x: number) => Base +>f8 : (x: number) => any +>x : number +>x => { // should be (x: number) => Base return new Base(); return new Derived2();} : (x: number) => Base +>x : number + + return new Base(); +>new Base() : Base +>Base : typeof Base + + return new Derived2(); +>new Derived2() : Derived2 +>Derived2 : typeof Derived2 +} +var f9: (x: number) => any = x => { // should be (x: number) => Base +>f9 : (x: number) => any +>x : number +>x => { // should be (x: number) => Base return new Base(); return new Derived(); return new Derived2();} : (x: number) => Base +>x : number + + return new Base(); +>new Base() : Base +>Base : typeof Base + + return new Derived(); +>new Derived() : Derived +>Derived : typeof Derived + + return new Derived2(); +>new Derived2() : Derived2 +>Derived2 : typeof Derived2 +} +var f10: (x: number) => any = x => { // should be (x: number) => Derived | Derived1 +>f10 : (x: number) => any +>x : number +>x => { // should be (x: number) => Derived | Derived1 return new Derived(); return new Derived2();} : (x: number) => Derived | Derived2 +>x : number + + return new Derived(); +>new Derived() : Derived +>Derived : typeof Derived + + return new Derived2(); +>new Derived2() : Derived2 +>Derived2 : typeof Derived2 +} +var f11: (x: number) => any = x => { // should be (x: number) => Base | AnotherClass +>f11 : (x: number) => any +>x : number +>x => { // should be (x: number) => Base | AnotherClass return new Base(); return new AnotherClass();} : (x: number) => Base | AnotherClass +>x : number + + return new Base(); +>new Base() : Base +>Base : typeof Base + + return new AnotherClass(); +>new AnotherClass() : AnotherClass +>AnotherClass : typeof AnotherClass +} +var f12: (x: number) => any = x => { // should be (x: number) => Base | AnotherClass +>f12 : (x: number) => any +>x : number +>x => { // should be (x: number) => Base | AnotherClass return new Base(); return; // should be ignored return new AnotherClass();} : (x: number) => Base | AnotherClass +>x : number + + return new Base(); +>new Base() : Base +>Base : typeof Base + + return; // should be ignored + return new AnotherClass(); +>new AnotherClass() : AnotherClass +>AnotherClass : typeof AnotherClass +} diff --git a/tests/baselines/reference/functionOverloadErrorsSyntax.errors.txt b/tests/baselines/reference/functionOverloadErrorsSyntax.errors.txt index 98e7f4cd714..7c83759d02d 100644 --- a/tests/baselines/reference/functionOverloadErrorsSyntax.errors.txt +++ b/tests/baselines/reference/functionOverloadErrorsSyntax.errors.txt @@ -1,6 +1,6 @@ tests/cases/conformance/functions/functionOverloadErrorsSyntax.ts(2,27): error TS1016: A required parameter cannot follow an optional parameter. tests/cases/conformance/functions/functionOverloadErrorsSyntax.ts(5,38): error TS1016: A required parameter cannot follow an optional parameter. -tests/cases/conformance/functions/functionOverloadErrorsSyntax.ts(9,28): error TS1014: A rest parameter must be last in a parameter list. +tests/cases/conformance/functions/functionOverloadErrorsSyntax.ts(9,25): error TS1014: A rest parameter must be last in a parameter list. ==== tests/cases/conformance/functions/functionOverloadErrorsSyntax.ts (3 errors) ==== @@ -17,7 +17,7 @@ tests/cases/conformance/functions/functionOverloadErrorsSyntax.ts(9,28): error T //Function overload signature with rest param followed by non-optional parameter function fn5(x: string, ...y: any[], z: string); - ~ + ~~~ !!! error TS1014: A rest parameter must be last in a parameter list. function fn5() { } \ No newline at end of file diff --git a/tests/baselines/reference/genericCallWithObjectTypeArgsAndNumericIndexer.js b/tests/baselines/reference/genericCallWithObjectTypeArgsAndNumericIndexer.js index aa2da602e25..f300e3a8093 100644 --- a/tests/baselines/reference/genericCallWithObjectTypeArgsAndNumericIndexer.js +++ b/tests/baselines/reference/genericCallWithObjectTypeArgsAndNumericIndexer.js @@ -57,3 +57,10 @@ function other3(arg) { // BUG 821629 //var u: U = r2[1]; // ok } +//function other3(arg: T) { +// var b: { [x: number]: T }; +// var r2 = foo(b); +// var d = r2[1]; +// // BUG 821629 +// //var u: U = r2[1]; // ok +//} diff --git a/tests/baselines/reference/genericCallWithObjectTypeArgsAndStringIndexer.js b/tests/baselines/reference/genericCallWithObjectTypeArgsAndStringIndexer.js index c810ce01fd4..eee87caf3de 100644 --- a/tests/baselines/reference/genericCallWithObjectTypeArgsAndStringIndexer.js +++ b/tests/baselines/reference/genericCallWithObjectTypeArgsAndStringIndexer.js @@ -58,3 +58,10 @@ function other3(arg) { // BUG 821629 //var u: U = r2['hm']; // ok } +//function other3(arg: T) { +// var b: { [x: string]: T }; +// var r2 = foo(b); +// var d: Date = r2['hm']; // ok +// // BUG 821629 +// //var u: U = r2['hm']; // ok +//} diff --git a/tests/baselines/reference/getEmitOutputWithEarlySyntacticErrors.baseline b/tests/baselines/reference/getEmitOutputWithEarlySyntacticErrors.baseline new file mode 100644 index 00000000000..a5d5d2eb9d7 --- /dev/null +++ b/tests/baselines/reference/getEmitOutputWithEarlySyntacticErrors.baseline @@ -0,0 +1,2 @@ +EmitOutputStatus : AllOutputGenerationSkipped + diff --git a/tests/baselines/reference/getEmitOutputWithSemanticErrorsForMultipleFiles.baseline b/tests/baselines/reference/getEmitOutputWithSemanticErrorsForMultipleFiles.baseline new file mode 100644 index 00000000000..c6396314824 --- /dev/null +++ b/tests/baselines/reference/getEmitOutputWithSemanticErrorsForMultipleFiles.baseline @@ -0,0 +1,8 @@ +EmitOutputStatus : Succeeded +Filename : tests/cases/fourslash/inputFile1.js +// File to emit, does not contain semantic errors +// expected to be emitted correctelly regardless of the semantic errors in the other file +var noErrors = true; +Filename : tests/cases/fourslash/inputFile1.d.ts +declare var noErrors: boolean; + diff --git a/tests/baselines/reference/getEmitOutputWithSemanticErrorsForMultipleFiles2.baseline b/tests/baselines/reference/getEmitOutputWithSemanticErrorsForMultipleFiles2.baseline new file mode 100644 index 00000000000..41b16b40e65 --- /dev/null +++ b/tests/baselines/reference/getEmitOutputWithSemanticErrorsForMultipleFiles2.baseline @@ -0,0 +1,8 @@ +EmitOutputStatus : DeclarationGenerationSkipped +Filename : out.js +// File to emit, does not contain semantic errors, but --out is passed +// expected to not generate declarations because of the semantic errors in the other file +var noErrors = true; +// File not emitted, and contains semantic errors +var semanticError = "string"; + diff --git a/tests/baselines/reference/getEmitOutputWithSyntacticErrorsForMultipleFiles.baseline b/tests/baselines/reference/getEmitOutputWithSyntacticErrorsForMultipleFiles.baseline new file mode 100644 index 00000000000..bf27703890b --- /dev/null +++ b/tests/baselines/reference/getEmitOutputWithSyntacticErrorsForMultipleFiles.baseline @@ -0,0 +1,6 @@ +EmitOutputStatus : Succeeded +Filename : tests/cases/fourslash/inputFile1.js +// File to emit, does not contain syntactic errors +// expected to be emitted correctelly regardless of the syntactic errors in the other file +var noErrors = true; + diff --git a/tests/baselines/reference/getEmitOutputWithSyntacticErrorsForMultipleFiles2.baseline b/tests/baselines/reference/getEmitOutputWithSyntacticErrorsForMultipleFiles2.baseline new file mode 100644 index 00000000000..a5d5d2eb9d7 --- /dev/null +++ b/tests/baselines/reference/getEmitOutputWithSyntacticErrorsForMultipleFiles2.baseline @@ -0,0 +1,2 @@ +EmitOutputStatus : AllOutputGenerationSkipped + diff --git a/tests/baselines/reference/heterogeneousArrayLiterals.js b/tests/baselines/reference/heterogeneousArrayLiterals.js index 8deb3b4b068..4ac929305c0 100644 --- a/tests/baselines/reference/heterogeneousArrayLiterals.js +++ b/tests/baselines/reference/heterogeneousArrayLiterals.js @@ -241,3 +241,28 @@ function foo4(t, u) { var j = [u, derived]; // Derived[] var k = [t, u]; } +//function foo3(t: T, u: U) { +// var a = [t, t]; // T[] +// var b = [t, null]; // T[] +// var c = [t, u]; // {}[] +// var d = [t, 1]; // {}[] +// var e = [() => t, () => u]; // {}[] +// var f = [() => t, () => u, () => null]; // { (): any }[] +// var g = [t, base]; // Base[] +// var h = [t, derived]; // Derived[] +// var i = [u, base]; // Base[] +// var j = [u, derived]; // Derived[] +//} +//function foo4(t: T, u: U) { +// var a = [t, t]; // T[] +// var b = [t, null]; // T[] +// var c = [t, u]; // BUG 821629 +// var d = [t, 1]; // {}[] +// var e = [() => t, () => u]; // {}[] +// var f = [() => t, () => u, () => null]; // { (): any }[] +// var g = [t, base]; // Base[] +// var h = [t, derived]; // Derived[] +// var i = [u, base]; // Base[] +// var j = [u, derived]; // Derived[] +// var k: Base[] = [t, u]; +//} diff --git a/tests/baselines/reference/indexSignatureTypeCheck.errors.txt b/tests/baselines/reference/indexSignatureTypeCheck.errors.txt index 1cc69f6294b..8a020fde5c6 100644 --- a/tests/baselines/reference/indexSignatureTypeCheck.errors.txt +++ b/tests/baselines/reference/indexSignatureTypeCheck.errors.txt @@ -1,5 +1,5 @@ -tests/cases/compiler/indexSignatureTypeCheck.ts(14,6): error TS1019: An index signature parameter cannot have a question mark. -tests/cases/compiler/indexSignatureTypeCheck.ts(15,9): error TS1017: An index signature cannot have a rest parameter. +tests/cases/compiler/indexSignatureTypeCheck.ts(14,8): error TS1019: An index signature parameter cannot have a question mark. +tests/cases/compiler/indexSignatureTypeCheck.ts(15,6): error TS1017: An index signature cannot have a rest parameter. tests/cases/compiler/indexSignatureTypeCheck.ts(16,6): error TS1096: An index signature must have exactly one parameter. tests/cases/compiler/indexSignatureTypeCheck.ts(17,6): error TS1096: An index signature must have exactly one parameter. @@ -19,10 +19,10 @@ tests/cases/compiler/indexSignatureTypeCheck.ts(17,6): error TS1096: An index si interface indexErrors { [p2?: string]; - ~~ + ~ !!! error TS1019: An index signature parameter cannot have a question mark. [...p3: any[]]; - ~~ + ~~~ !!! error TS1017: An index signature cannot have a rest parameter. [p4: string, p5?: string]; ~~ diff --git a/tests/baselines/reference/indexSignatureTypeCheck2.errors.txt b/tests/baselines/reference/indexSignatureTypeCheck2.errors.txt index 25e3ab94280..0fd594268c5 100644 --- a/tests/baselines/reference/indexSignatureTypeCheck2.errors.txt +++ b/tests/baselines/reference/indexSignatureTypeCheck2.errors.txt @@ -1,5 +1,5 @@ -tests/cases/compiler/indexSignatureTypeCheck2.ts(10,6): error TS1019: An index signature parameter cannot have a question mark. -tests/cases/compiler/indexSignatureTypeCheck2.ts(11,9): error TS1017: An index signature cannot have a rest parameter. +tests/cases/compiler/indexSignatureTypeCheck2.ts(10,8): error TS1019: An index signature parameter cannot have a question mark. +tests/cases/compiler/indexSignatureTypeCheck2.ts(11,6): error TS1017: An index signature cannot have a rest parameter. tests/cases/compiler/indexSignatureTypeCheck2.ts(12,6): error TS1096: An index signature must have exactly one parameter. tests/cases/compiler/indexSignatureTypeCheck2.ts(13,6): error TS1096: An index signature must have exactly one parameter. @@ -15,10 +15,10 @@ tests/cases/compiler/indexSignatureTypeCheck2.ts(13,6): error TS1096: An index s interface indexErrors { [p2?: string]; - ~~ + ~ !!! error TS1019: An index signature parameter cannot have a question mark. [...p3: any[]]; - ~~ + ~~~ !!! error TS1017: An index signature cannot have a rest parameter. [p4: string, p5?: string]; ~~ diff --git a/tests/baselines/reference/indexerAsOptional.errors.txt b/tests/baselines/reference/indexerAsOptional.errors.txt index 101c03acccd..cfd2d08cef9 100644 --- a/tests/baselines/reference/indexerAsOptional.errors.txt +++ b/tests/baselines/reference/indexerAsOptional.errors.txt @@ -1,18 +1,18 @@ -tests/cases/compiler/indexerAsOptional.ts(3,6): error TS1019: An index signature parameter cannot have a question mark. -tests/cases/compiler/indexerAsOptional.ts(8,6): error TS1019: An index signature parameter cannot have a question mark. +tests/cases/compiler/indexerAsOptional.ts(3,9): error TS1019: An index signature parameter cannot have a question mark. +tests/cases/compiler/indexerAsOptional.ts(8,9): error TS1019: An index signature parameter cannot have a question mark. ==== tests/cases/compiler/indexerAsOptional.ts (2 errors) ==== interface indexSig { //Index signatures can't be optional [idx?: number]: any; //err - ~~~ + ~ !!! error TS1019: An index signature parameter cannot have a question mark. } class indexSig2 { //Index signatures can't be optional [idx?: number]: any //err - ~~~ + ~ !!! error TS1019: An index signature parameter cannot have a question mark. } \ No newline at end of file diff --git a/tests/baselines/reference/indexerSignatureWithRestParam.errors.txt b/tests/baselines/reference/indexerSignatureWithRestParam.errors.txt index 4743ed8e91c..08c65816416 100644 --- a/tests/baselines/reference/indexerSignatureWithRestParam.errors.txt +++ b/tests/baselines/reference/indexerSignatureWithRestParam.errors.txt @@ -1,16 +1,16 @@ -tests/cases/compiler/indexerSignatureWithRestParam.ts(2,9): error TS1017: An index signature cannot have a rest parameter. -tests/cases/compiler/indexerSignatureWithRestParam.ts(6,9): error TS1017: An index signature cannot have a rest parameter. +tests/cases/compiler/indexerSignatureWithRestParam.ts(2,6): error TS1017: An index signature cannot have a rest parameter. +tests/cases/compiler/indexerSignatureWithRestParam.ts(6,6): error TS1017: An index signature cannot have a rest parameter. ==== tests/cases/compiler/indexerSignatureWithRestParam.ts (2 errors) ==== interface I { [...x]: string; - ~ + ~~~ !!! error TS1017: An index signature cannot have a rest parameter. } class C { [...x]: string - ~ + ~~~ !!! error TS1017: An index signature cannot have a rest parameter. } \ No newline at end of file diff --git a/tests/baselines/reference/indexerWithTuple.js b/tests/baselines/reference/indexerWithTuple.js index fc82716ba05..91d90792e6d 100644 --- a/tests/baselines/reference/indexerWithTuple.js +++ b/tests/baselines/reference/indexerWithTuple.js @@ -1,32 +1,65 @@ //// [indexerWithTuple.ts] var strNumTuple: [string, number] = ["foo", 10]; var numTupleTuple: [number, [string, number]] = [10, ["bar", 20]]; +var unionTuple1: [number, string| number] = [10, "foo"]; +var unionTuple2: [boolean, string| number] = [true, "foo"]; // no error var idx0 = 0; var idx1 = 1; var ele10 = strNumTuple[0]; // string var ele11 = strNumTuple[1]; // number -var ele12 = strNumTuple[2]; // {} -var ele13 = strNumTuple[idx0]; // {} -var ele14 = strNumTuple[idx1]; // {} +var ele12 = strNumTuple[2]; // string | number +var ele13 = strNumTuple[idx0]; // string | number +var ele14 = strNumTuple[idx1]; // string | number var ele15 = strNumTuple["0"]; // string var ele16 = strNumTuple["1"]; // number var strNumTuple1 = numTupleTuple[1]; //[string, number]; -var ele17 = numTupleTuple[2]; // {} +var ele17 = numTupleTuple[2]; // number | [string, number] +var eleUnion10 = unionTuple1[0]; // number +var eleUnion11 = unionTuple1[1]; // string | number +var eleUnion12 = unionTuple1[2]; // string | number +var eleUnion13 = unionTuple1[idx0]; // string | number +var eleUnion14 = unionTuple1[idx1]; // string | number +var eleUnion15 = unionTuple1["0"]; // number +var eleUnion16 = unionTuple1["1"]; // string | number + +var eleUnion20 = unionTuple2[0]; // boolean +var eleUnion21 = unionTuple2[1]; // string | number +var eleUnion22 = unionTuple2[2]; // string | number | boolean +var eleUnion23 = unionTuple2[idx0]; // string | number | boolean +var eleUnion24 = unionTuple2[idx1]; // string | number | boolean +var eleUnion25 = unionTuple2["0"]; // boolean +var eleUnion26 = unionTuple2["1"]; // string | number //// [indexerWithTuple.js] var strNumTuple = ["foo", 10]; var numTupleTuple = [10, ["bar", 20]]; +var unionTuple1 = [10, "foo"]; +var unionTuple2 = [true, "foo"]; // no error var idx0 = 0; var idx1 = 1; var ele10 = strNumTuple[0]; // string var ele11 = strNumTuple[1]; // number -var ele12 = strNumTuple[2]; // {} -var ele13 = strNumTuple[idx0]; // {} -var ele14 = strNumTuple[idx1]; // {} +var ele12 = strNumTuple[2]; // string | number +var ele13 = strNumTuple[idx0]; // string | number +var ele14 = strNumTuple[idx1]; // string | number var ele15 = strNumTuple["0"]; // string var ele16 = strNumTuple["1"]; // number var strNumTuple1 = numTupleTuple[1]; //[string, number]; -var ele17 = numTupleTuple[2]; // {} +var ele17 = numTupleTuple[2]; // number | [string, number] +var eleUnion10 = unionTuple1[0]; // number +var eleUnion11 = unionTuple1[1]; // string | number +var eleUnion12 = unionTuple1[2]; // string | number +var eleUnion13 = unionTuple1[idx0]; // string | number +var eleUnion14 = unionTuple1[idx1]; // string | number +var eleUnion15 = unionTuple1["0"]; // number +var eleUnion16 = unionTuple1["1"]; // string | number +var eleUnion20 = unionTuple2[0]; // boolean +var eleUnion21 = unionTuple2[1]; // string | number +var eleUnion22 = unionTuple2[2]; // string | number | boolean +var eleUnion23 = unionTuple2[idx0]; // string | number | boolean +var eleUnion24 = unionTuple2[idx1]; // string | number | boolean +var eleUnion25 = unionTuple2["0"]; // boolean +var eleUnion26 = unionTuple2["1"]; // string | number diff --git a/tests/baselines/reference/indexerWithTuple.types b/tests/baselines/reference/indexerWithTuple.types index 28053a33081..75b89ca6088 100644 --- a/tests/baselines/reference/indexerWithTuple.types +++ b/tests/baselines/reference/indexerWithTuple.types @@ -8,6 +8,14 @@ var numTupleTuple: [number, [string, number]] = [10, ["bar", 20]]; >[10, ["bar", 20]] : [number, [string, number]] >["bar", 20] : [string, number] +var unionTuple1: [number, string| number] = [10, "foo"]; +>unionTuple1 : [number, string | number] +>[10, "foo"] : [number, string] + +var unionTuple2: [boolean, string| number] = [true, "foo"]; +>unionTuple2 : [boolean, string | number] +>[true, "foo"] : [boolean, string] + // no error var idx0 = 0; >idx0 : number @@ -25,18 +33,18 @@ var ele11 = strNumTuple[1]; // number >strNumTuple[1] : number >strNumTuple : [string, number] -var ele12 = strNumTuple[2]; // {} +var ele12 = strNumTuple[2]; // string | number >ele12 : string | number >strNumTuple[2] : string | number >strNumTuple : [string, number] -var ele13 = strNumTuple[idx0]; // {} +var ele13 = strNumTuple[idx0]; // string | number >ele13 : string | number >strNumTuple[idx0] : string | number >strNumTuple : [string, number] >idx0 : number -var ele14 = strNumTuple[idx1]; // {} +var ele14 = strNumTuple[idx1]; // string | number >ele14 : string | number >strNumTuple[idx1] : string | number >strNumTuple : [string, number] @@ -57,8 +65,82 @@ var strNumTuple1 = numTupleTuple[1]; //[string, number]; >numTupleTuple[1] : [string, number] >numTupleTuple : [number, [string, number]] -var ele17 = numTupleTuple[2]; // {} +var ele17 = numTupleTuple[2]; // number | [string, number] >ele17 : number | [string, number] >numTupleTuple[2] : number | [string, number] >numTupleTuple : [number, [string, number]] +var eleUnion10 = unionTuple1[0]; // number +>eleUnion10 : number +>unionTuple1[0] : number +>unionTuple1 : [number, string | number] + +var eleUnion11 = unionTuple1[1]; // string | number +>eleUnion11 : string | number +>unionTuple1[1] : string | number +>unionTuple1 : [number, string | number] + +var eleUnion12 = unionTuple1[2]; // string | number +>eleUnion12 : string | number +>unionTuple1[2] : string | number +>unionTuple1 : [number, string | number] + +var eleUnion13 = unionTuple1[idx0]; // string | number +>eleUnion13 : string | number +>unionTuple1[idx0] : string | number +>unionTuple1 : [number, string | number] +>idx0 : number + +var eleUnion14 = unionTuple1[idx1]; // string | number +>eleUnion14 : string | number +>unionTuple1[idx1] : string | number +>unionTuple1 : [number, string | number] +>idx1 : number + +var eleUnion15 = unionTuple1["0"]; // number +>eleUnion15 : number +>unionTuple1["0"] : number +>unionTuple1 : [number, string | number] + +var eleUnion16 = unionTuple1["1"]; // string | number +>eleUnion16 : string | number +>unionTuple1["1"] : string | number +>unionTuple1 : [number, string | number] + +var eleUnion20 = unionTuple2[0]; // boolean +>eleUnion20 : boolean +>unionTuple2[0] : boolean +>unionTuple2 : [boolean, string | number] + +var eleUnion21 = unionTuple2[1]; // string | number +>eleUnion21 : string | number +>unionTuple2[1] : string | number +>unionTuple2 : [boolean, string | number] + +var eleUnion22 = unionTuple2[2]; // string | number | boolean +>eleUnion22 : string | number | boolean +>unionTuple2[2] : string | number | boolean +>unionTuple2 : [boolean, string | number] + +var eleUnion23 = unionTuple2[idx0]; // string | number | boolean +>eleUnion23 : string | number | boolean +>unionTuple2[idx0] : string | number | boolean +>unionTuple2 : [boolean, string | number] +>idx0 : number + +var eleUnion24 = unionTuple2[idx1]; // string | number | boolean +>eleUnion24 : string | number | boolean +>unionTuple2[idx1] : string | number | boolean +>unionTuple2 : [boolean, string | number] +>idx1 : number + +var eleUnion25 = unionTuple2["0"]; // boolean +>eleUnion25 : boolean +>unionTuple2["0"] : boolean +>unionTuple2 : [boolean, string | number] + +var eleUnion26 = unionTuple2["1"]; // string | number +>eleUnion26 : string | number +>unionTuple2["1"] : string | number +>unionTuple2 : [boolean, string | number] + diff --git a/tests/baselines/reference/innerTypeParameterShadowingOuterOne.js b/tests/baselines/reference/innerTypeParameterShadowingOuterOne.js index 81ed990532c..74354468e32 100644 --- a/tests/baselines/reference/innerTypeParameterShadowingOuterOne.js +++ b/tests/baselines/reference/innerTypeParameterShadowingOuterOne.js @@ -47,3 +47,11 @@ function f2() { var x; x.getDate(); } +//function f2() { +// function g() { +// var x: U; +// x.toFixed(); +// } +// var x: U; +// x.getDate(); +//} diff --git a/tests/baselines/reference/innerTypeParameterShadowingOuterOne2.js b/tests/baselines/reference/innerTypeParameterShadowingOuterOne2.js index 8a5a9448f18..36a250d365d 100644 --- a/tests/baselines/reference/innerTypeParameterShadowingOuterOne2.js +++ b/tests/baselines/reference/innerTypeParameterShadowingOuterOne2.js @@ -66,3 +66,13 @@ var C2 = (function () { }; return C2; })(); +//class C2 { +// g() { +// var x: U; +// x.toFixed(); +// } +// h() { +// var x: U; +// x.getDate(); +// } +//} diff --git a/tests/baselines/reference/logicalOrOperatorWithEveryType.js b/tests/baselines/reference/logicalOrOperatorWithEveryType.js index bf7a641882e..78601374c22 100644 --- a/tests/baselines/reference/logicalOrOperatorWithEveryType.js +++ b/tests/baselines/reference/logicalOrOperatorWithEveryType.js @@ -28,77 +28,77 @@ var ra10 = undefined || a1; // undefined || any is any var rb1 = a1 || a2; // any || boolean is any var rb2 = a2 || a2; // boolean || boolean is boolean -var rb3 = a3 || a2; // number || boolean is {} -var rb4 = a4 || a2; // string || boolean is {} -var rb5 = a5 || a2; // void || boolean is {} -var rb6 = a6 || a2; // enum || boolean is {} -var rb7 = a7 || a2; // object || boolean is {} -var rb8 = a8 || a2; // array || boolean is {} +var rb3 = a3 || a2; // number || boolean is number | boolean +var rb4 = a4 || a2; // string || boolean is string | boolean +var rb5 = a5 || a2; // void || boolean is void | boolean +var rb6 = a6 || a2; // enum || boolean is E | boolean +var rb7 = a7 || a2; // object || boolean is object | boolean +var rb8 = a8 || a2; // array || boolean is array | boolean var rb9 = null || a2; // null || boolean is boolean var rb10= undefined || a2; // undefined || boolean is boolean var rc1 = a1 || a3; // any || number is any -var rc2 = a2 || a3; // boolean || number is {} +var rc2 = a2 || a3; // boolean || number is boolean | number var rc3 = a3 || a3; // number || number is number -var rc4 = a4 || a3; // string || number is {} -var rc5 = a5 || a3; // void || number is {} +var rc4 = a4 || a3; // string || number is string | number +var rc5 = a5 || a3; // void || number is void | number var rc6 = a6 || a3; // enum || number is number -var rc7 = a7 || a3; // object || number is {} -var rc8 = a8 || a3; // array || number is {} +var rc7 = a7 || a3; // object || number is object | number +var rc8 = a8 || a3; // array || number is array | number var rc9 = null || a3; // null || number is number var rc10 = undefined || a3; // undefined || number is number var rd1 = a1 || a4; // any || string is any -var rd2 = a2 || a4; // boolean || string is {} -var rd3 = a3 || a4; // number || string is {} +var rd2 = a2 || a4; // boolean || string is boolean | string +var rd3 = a3 || a4; // number || string is number | string var rd4 = a4 || a4; // string || string is string -var rd5 = a5 || a4; // void || string is {} -var rd6 = a6 || a4; // enum || string is {} -var rd7 = a7 || a4; // object || string is {} -var rd8 = a8 || a4; // array || string is {} +var rd5 = a5 || a4; // void || string is void | string +var rd6 = a6 || a4; // enum || string is enum | string +var rd7 = a7 || a4; // object || string is object | string +var rd8 = a8 || a4; // array || string is array | string var rd9 = null || a4; // null || string is string var rd10 = undefined || a4; // undefined || string is string var re1 = a1 || a5; // any || void is any -var re2 = a2 || a5; // boolean || void is {} -var re3 = a3 || a5; // number || void is {} -var re4 = a4 || a5; // string || void is {} +var re2 = a2 || a5; // boolean || void is boolean | void +var re3 = a3 || a5; // number || void is number | void +var re4 = a4 || a5; // string || void is string | void var re5 = a5 || a5; // void || void is void -var re6 = a6 || a5; // enum || void is {} -var re7 = a7 || a5; // object || void is {} -var re8 = a8 || a5; // array || void is {} +var re6 = a6 || a5; // enum || void is enum | void +var re7 = a7 || a5; // object || void is object | void +var re8 = a8 || a5; // array || void is array | void var re9 = null || a5; // null || void is void var re10 = undefined || a5; // undefined || void is void var rg1 = a1 || a6; // any || enum is any -var rg2 = a2 || a6; // boolean || enum is {} +var rg2 = a2 || a6; // boolean || enum is boolean | enum var rg3 = a3 || a6; // number || enum is number -var rg4 = a4 || a6; // string || enum is {} -var rg5 = a5 || a6; // void || enum is {} +var rg4 = a4 || a6; // string || enum is string | enum +var rg5 = a5 || a6; // void || enum is void | enum var rg6 = a6 || a6; // enum || enum is E -var rg7 = a7 || a6; // object || enum is {} -var rg8 = a8 || a6; // array || enum is {} +var rg7 = a7 || a6; // object || enum is object | enum +var rg8 = a8 || a6; // array || enum is array | enum var rg9 = null || a6; // null || enum is E var rg10 = undefined || a6; // undefined || enum is E var rh1 = a1 || a7; // any || object is any -var rh2 = a2 || a7; // boolean || object is {} -var rh3 = a3 || a7; // number || object is {} -var rh4 = a4 || a7; // string || object is {} -var rh5 = a5 || a7; // void || object is {} -var rh6 = a6 || a7; // enum || object is {} +var rh2 = a2 || a7; // boolean || object is boolean | object +var rh3 = a3 || a7; // number || object is number | object +var rh4 = a4 || a7; // string || object is string | object +var rh5 = a5 || a7; // void || object is void | object +var rh6 = a6 || a7; // enum || object is enum | object var rh7 = a7 || a7; // object || object is object -var rh8 = a8 || a7; // array || object is {} +var rh8 = a8 || a7; // array || object is array | object var rh9 = null || a7; // null || object is object var rh10 = undefined || a7; // undefined || object is object var ri1 = a1 || a8; // any || array is any -var ri2 = a2 || a8; // boolean || array is {} -var ri3 = a3 || a8; // number || array is {} -var ri4 = a4 || a8; // string || array is {} -var ri5 = a5 || a8; // void || array is {} -var ri6 = a6 || a8; // enum || array is {} -var ri7 = a7 || a8; // object || array is {} +var ri2 = a2 || a8; // boolean || array is boolean | array +var ri3 = a3 || a8; // number || array is number | array +var ri4 = a4 || a8; // string || array is string | array +var ri5 = a5 || a8; // void || array is void | array +var ri6 = a6 || a8; // enum || array is enum | array +var ri7 = a7 || a8; // object || array is object | array var ri8 = a8 || a8; // array || array is array var ri9 = null || a8; // null || array is array var ri10 = undefined || a8; // undefined || array is array @@ -156,71 +156,71 @@ var ra9 = null || a1; // null || any is any var ra10 = undefined || a1; // undefined || any is any var rb1 = a1 || a2; // any || boolean is any var rb2 = a2 || a2; // boolean || boolean is boolean -var rb3 = a3 || a2; // number || boolean is {} -var rb4 = a4 || a2; // string || boolean is {} -var rb5 = a5 || a2; // void || boolean is {} -var rb6 = a6 || a2; // enum || boolean is {} -var rb7 = a7 || a2; // object || boolean is {} -var rb8 = a8 || a2; // array || boolean is {} +var rb3 = a3 || a2; // number || boolean is number | boolean +var rb4 = a4 || a2; // string || boolean is string | boolean +var rb5 = a5 || a2; // void || boolean is void | boolean +var rb6 = a6 || a2; // enum || boolean is E | boolean +var rb7 = a7 || a2; // object || boolean is object | boolean +var rb8 = a8 || a2; // array || boolean is array | boolean var rb9 = null || a2; // null || boolean is boolean var rb10 = undefined || a2; // undefined || boolean is boolean var rc1 = a1 || a3; // any || number is any -var rc2 = a2 || a3; // boolean || number is {} +var rc2 = a2 || a3; // boolean || number is boolean | number var rc3 = a3 || a3; // number || number is number -var rc4 = a4 || a3; // string || number is {} -var rc5 = a5 || a3; // void || number is {} +var rc4 = a4 || a3; // string || number is string | number +var rc5 = a5 || a3; // void || number is void | number var rc6 = a6 || a3; // enum || number is number -var rc7 = a7 || a3; // object || number is {} -var rc8 = a8 || a3; // array || number is {} +var rc7 = a7 || a3; // object || number is object | number +var rc8 = a8 || a3; // array || number is array | number var rc9 = null || a3; // null || number is number var rc10 = undefined || a3; // undefined || number is number var rd1 = a1 || a4; // any || string is any -var rd2 = a2 || a4; // boolean || string is {} -var rd3 = a3 || a4; // number || string is {} +var rd2 = a2 || a4; // boolean || string is boolean | string +var rd3 = a3 || a4; // number || string is number | string var rd4 = a4 || a4; // string || string is string -var rd5 = a5 || a4; // void || string is {} -var rd6 = a6 || a4; // enum || string is {} -var rd7 = a7 || a4; // object || string is {} -var rd8 = a8 || a4; // array || string is {} +var rd5 = a5 || a4; // void || string is void | string +var rd6 = a6 || a4; // enum || string is enum | string +var rd7 = a7 || a4; // object || string is object | string +var rd8 = a8 || a4; // array || string is array | string var rd9 = null || a4; // null || string is string var rd10 = undefined || a4; // undefined || string is string var re1 = a1 || a5; // any || void is any -var re2 = a2 || a5; // boolean || void is {} -var re3 = a3 || a5; // number || void is {} -var re4 = a4 || a5; // string || void is {} +var re2 = a2 || a5; // boolean || void is boolean | void +var re3 = a3 || a5; // number || void is number | void +var re4 = a4 || a5; // string || void is string | void var re5 = a5 || a5; // void || void is void -var re6 = a6 || a5; // enum || void is {} -var re7 = a7 || a5; // object || void is {} -var re8 = a8 || a5; // array || void is {} +var re6 = a6 || a5; // enum || void is enum | void +var re7 = a7 || a5; // object || void is object | void +var re8 = a8 || a5; // array || void is array | void var re9 = null || a5; // null || void is void var re10 = undefined || a5; // undefined || void is void var rg1 = a1 || a6; // any || enum is any -var rg2 = a2 || a6; // boolean || enum is {} +var rg2 = a2 || a6; // boolean || enum is boolean | enum var rg3 = a3 || a6; // number || enum is number -var rg4 = a4 || a6; // string || enum is {} -var rg5 = a5 || a6; // void || enum is {} +var rg4 = a4 || a6; // string || enum is string | enum +var rg5 = a5 || a6; // void || enum is void | enum var rg6 = a6 || a6; // enum || enum is E -var rg7 = a7 || a6; // object || enum is {} -var rg8 = a8 || a6; // array || enum is {} +var rg7 = a7 || a6; // object || enum is object | enum +var rg8 = a8 || a6; // array || enum is array | enum var rg9 = null || a6; // null || enum is E var rg10 = undefined || a6; // undefined || enum is E var rh1 = a1 || a7; // any || object is any -var rh2 = a2 || a7; // boolean || object is {} -var rh3 = a3 || a7; // number || object is {} -var rh4 = a4 || a7; // string || object is {} -var rh5 = a5 || a7; // void || object is {} -var rh6 = a6 || a7; // enum || object is {} +var rh2 = a2 || a7; // boolean || object is boolean | object +var rh3 = a3 || a7; // number || object is number | object +var rh4 = a4 || a7; // string || object is string | object +var rh5 = a5 || a7; // void || object is void | object +var rh6 = a6 || a7; // enum || object is enum | object var rh7 = a7 || a7; // object || object is object -var rh8 = a8 || a7; // array || object is {} +var rh8 = a8 || a7; // array || object is array | object var rh9 = null || a7; // null || object is object var rh10 = undefined || a7; // undefined || object is object var ri1 = a1 || a8; // any || array is any -var ri2 = a2 || a8; // boolean || array is {} -var ri3 = a3 || a8; // number || array is {} -var ri4 = a4 || a8; // string || array is {} -var ri5 = a5 || a8; // void || array is {} -var ri6 = a6 || a8; // enum || array is {} -var ri7 = a7 || a8; // object || array is {} +var ri2 = a2 || a8; // boolean || array is boolean | array +var ri3 = a3 || a8; // number || array is number | array +var ri4 = a4 || a8; // string || array is string | array +var ri5 = a5 || a8; // void || array is void | array +var ri6 = a6 || a8; // enum || array is enum | array +var ri7 = a7 || a8; // object || array is object | array var ri8 = a8 || a8; // array || array is array var ri9 = null || a8; // null || array is array var ri10 = undefined || a8; // undefined || array is array diff --git a/tests/baselines/reference/logicalOrOperatorWithEveryType.types b/tests/baselines/reference/logicalOrOperatorWithEveryType.types index 3e3b0dcf37f..ae8dab8c71c 100644 --- a/tests/baselines/reference/logicalOrOperatorWithEveryType.types +++ b/tests/baselines/reference/logicalOrOperatorWithEveryType.types @@ -107,37 +107,37 @@ var rb2 = a2 || a2; // boolean || boolean is boolean >a2 : boolean >a2 : boolean -var rb3 = a3 || a2; // number || boolean is {} +var rb3 = a3 || a2; // number || boolean is number | boolean >rb3 : number | boolean >a3 || a2 : number | boolean >a3 : number >a2 : boolean -var rb4 = a4 || a2; // string || boolean is {} +var rb4 = a4 || a2; // string || boolean is string | boolean >rb4 : string | boolean >a4 || a2 : string | boolean >a4 : string >a2 : boolean -var rb5 = a5 || a2; // void || boolean is {} +var rb5 = a5 || a2; // void || boolean is void | boolean >rb5 : boolean | void >a5 || a2 : boolean | void >a5 : void >a2 : boolean -var rb6 = a6 || a2; // enum || boolean is {} +var rb6 = a6 || a2; // enum || boolean is E | boolean >rb6 : boolean | E >a6 || a2 : boolean | E >a6 : E >a2 : boolean -var rb7 = a7 || a2; // object || boolean is {} +var rb7 = a7 || a2; // object || boolean is object | boolean >rb7 : boolean | { a: string; } >a7 || a2 : boolean | { a: string; } >a7 : { a: string; } >a2 : boolean -var rb8 = a8 || a2; // array || boolean is {} +var rb8 = a8 || a2; // array || boolean is array | boolean >rb8 : boolean | string[] >a8 || a2 : boolean | string[] >a8 : string[] @@ -160,7 +160,7 @@ var rc1 = a1 || a3; // any || number is any >a1 : any >a3 : number -var rc2 = a2 || a3; // boolean || number is {} +var rc2 = a2 || a3; // boolean || number is boolean | number >rc2 : number | boolean >a2 || a3 : number | boolean >a2 : boolean @@ -172,13 +172,13 @@ var rc3 = a3 || a3; // number || number is number >a3 : number >a3 : number -var rc4 = a4 || a3; // string || number is {} +var rc4 = a4 || a3; // string || number is string | number >rc4 : string | number >a4 || a3 : string | number >a4 : string >a3 : number -var rc5 = a5 || a3; // void || number is {} +var rc5 = a5 || a3; // void || number is void | number >rc5 : number | void >a5 || a3 : number | void >a5 : void @@ -190,13 +190,13 @@ var rc6 = a6 || a3; // enum || number is number >a6 : E >a3 : number -var rc7 = a7 || a3; // object || number is {} +var rc7 = a7 || a3; // object || number is object | number >rc7 : number | { a: string; } >a7 || a3 : number | { a: string; } >a7 : { a: string; } >a3 : number -var rc8 = a8 || a3; // array || number is {} +var rc8 = a8 || a3; // array || number is array | number >rc8 : number | string[] >a8 || a3 : number | string[] >a8 : string[] @@ -219,13 +219,13 @@ var rd1 = a1 || a4; // any || string is any >a1 : any >a4 : string -var rd2 = a2 || a4; // boolean || string is {} +var rd2 = a2 || a4; // boolean || string is boolean | string >rd2 : string | boolean >a2 || a4 : string | boolean >a2 : boolean >a4 : string -var rd3 = a3 || a4; // number || string is {} +var rd3 = a3 || a4; // number || string is number | string >rd3 : string | number >a3 || a4 : string | number >a3 : number @@ -237,25 +237,25 @@ var rd4 = a4 || a4; // string || string is string >a4 : string >a4 : string -var rd5 = a5 || a4; // void || string is {} +var rd5 = a5 || a4; // void || string is void | string >rd5 : string | void >a5 || a4 : string | void >a5 : void >a4 : string -var rd6 = a6 || a4; // enum || string is {} +var rd6 = a6 || a4; // enum || string is enum | string >rd6 : string | E >a6 || a4 : string | E >a6 : E >a4 : string -var rd7 = a7 || a4; // object || string is {} +var rd7 = a7 || a4; // object || string is object | string >rd7 : string | { a: string; } >a7 || a4 : string | { a: string; } >a7 : { a: string; } >a4 : string -var rd8 = a8 || a4; // array || string is {} +var rd8 = a8 || a4; // array || string is array | string >rd8 : string | string[] >a8 || a4 : string | string[] >a8 : string[] @@ -278,19 +278,19 @@ var re1 = a1 || a5; // any || void is any >a1 : any >a5 : void -var re2 = a2 || a5; // boolean || void is {} +var re2 = a2 || a5; // boolean || void is boolean | void >re2 : boolean | void >a2 || a5 : boolean | void >a2 : boolean >a5 : void -var re3 = a3 || a5; // number || void is {} +var re3 = a3 || a5; // number || void is number | void >re3 : number | void >a3 || a5 : number | void >a3 : number >a5 : void -var re4 = a4 || a5; // string || void is {} +var re4 = a4 || a5; // string || void is string | void >re4 : string | void >a4 || a5 : string | void >a4 : string @@ -302,19 +302,19 @@ var re5 = a5 || a5; // void || void is void >a5 : void >a5 : void -var re6 = a6 || a5; // enum || void is {} +var re6 = a6 || a5; // enum || void is enum | void >re6 : void | E >a6 || a5 : void | E >a6 : E >a5 : void -var re7 = a7 || a5; // object || void is {} +var re7 = a7 || a5; // object || void is object | void >re7 : void | { a: string; } >a7 || a5 : void | { a: string; } >a7 : { a: string; } >a5 : void -var re8 = a8 || a5; // array || void is {} +var re8 = a8 || a5; // array || void is array | void >re8 : void | string[] >a8 || a5 : void | string[] >a8 : string[] @@ -337,7 +337,7 @@ var rg1 = a1 || a6; // any || enum is any >a1 : any >a6 : E -var rg2 = a2 || a6; // boolean || enum is {} +var rg2 = a2 || a6; // boolean || enum is boolean | enum >rg2 : boolean | E >a2 || a6 : boolean | E >a2 : boolean @@ -349,13 +349,13 @@ var rg3 = a3 || a6; // number || enum is number >a3 : number >a6 : E -var rg4 = a4 || a6; // string || enum is {} +var rg4 = a4 || a6; // string || enum is string | enum >rg4 : string | E >a4 || a6 : string | E >a4 : string >a6 : E -var rg5 = a5 || a6; // void || enum is {} +var rg5 = a5 || a6; // void || enum is void | enum >rg5 : void | E >a5 || a6 : void | E >a5 : void @@ -367,13 +367,13 @@ var rg6 = a6 || a6; // enum || enum is E >a6 : E >a6 : E -var rg7 = a7 || a6; // object || enum is {} +var rg7 = a7 || a6; // object || enum is object | enum >rg7 : E | { a: string; } >a7 || a6 : E | { a: string; } >a7 : { a: string; } >a6 : E -var rg8 = a8 || a6; // array || enum is {} +var rg8 = a8 || a6; // array || enum is array | enum >rg8 : string[] | E >a8 || a6 : string[] | E >a8 : string[] @@ -396,31 +396,31 @@ var rh1 = a1 || a7; // any || object is any >a1 : any >a7 : { a: string; } -var rh2 = a2 || a7; // boolean || object is {} +var rh2 = a2 || a7; // boolean || object is boolean | object >rh2 : boolean | { a: string; } >a2 || a7 : boolean | { a: string; } >a2 : boolean >a7 : { a: string; } -var rh3 = a3 || a7; // number || object is {} +var rh3 = a3 || a7; // number || object is number | object >rh3 : number | { a: string; } >a3 || a7 : number | { a: string; } >a3 : number >a7 : { a: string; } -var rh4 = a4 || a7; // string || object is {} +var rh4 = a4 || a7; // string || object is string | object >rh4 : string | { a: string; } >a4 || a7 : string | { a: string; } >a4 : string >a7 : { a: string; } -var rh5 = a5 || a7; // void || object is {} +var rh5 = a5 || a7; // void || object is void | object >rh5 : void | { a: string; } >a5 || a7 : void | { a: string; } >a5 : void >a7 : { a: string; } -var rh6 = a6 || a7; // enum || object is {} +var rh6 = a6 || a7; // enum || object is enum | object >rh6 : E | { a: string; } >a6 || a7 : E | { a: string; } >a6 : E @@ -432,7 +432,7 @@ var rh7 = a7 || a7; // object || object is object >a7 : { a: string; } >a7 : { a: string; } -var rh8 = a8 || a7; // array || object is {} +var rh8 = a8 || a7; // array || object is array | object >rh8 : string[] | { a: string; } >a8 || a7 : string[] | { a: string; } >a8 : string[] @@ -455,37 +455,37 @@ var ri1 = a1 || a8; // any || array is any >a1 : any >a8 : string[] -var ri2 = a2 || a8; // boolean || array is {} +var ri2 = a2 || a8; // boolean || array is boolean | array >ri2 : boolean | string[] >a2 || a8 : boolean | string[] >a2 : boolean >a8 : string[] -var ri3 = a3 || a8; // number || array is {} +var ri3 = a3 || a8; // number || array is number | array >ri3 : number | string[] >a3 || a8 : number | string[] >a3 : number >a8 : string[] -var ri4 = a4 || a8; // string || array is {} +var ri4 = a4 || a8; // string || array is string | array >ri4 : string | string[] >a4 || a8 : string | string[] >a4 : string >a8 : string[] -var ri5 = a5 || a8; // void || array is {} +var ri5 = a5 || a8; // void || array is void | array >ri5 : void | string[] >a5 || a8 : void | string[] >a5 : void >a8 : string[] -var ri6 = a6 || a8; // enum || array is {} +var ri6 = a6 || a8; // enum || array is enum | array >ri6 : string[] | E >a6 || a8 : string[] | E >a6 : E >a8 : string[] -var ri7 = a7 || a8; // object || array is {} +var ri7 = a7 || a8; // object || array is object | array >ri7 : string[] | { a: string; } >a7 || a8 : string[] | { a: string; } >a7 : { a: string; } diff --git a/tests/baselines/reference/moduleIdentifiers.js b/tests/baselines/reference/moduleIdentifiers.js index e2050d98f5d..04d39019482 100644 --- a/tests/baselines/reference/moduleIdentifiers.js +++ b/tests/baselines/reference/moduleIdentifiers.js @@ -18,3 +18,5 @@ var M; //var p: M.P; //var m: M = M; var x1 = M.a; +//var x2 = m.a; +//var q: m.P; diff --git a/tests/baselines/reference/nullAssignableToEveryType.js b/tests/baselines/reference/nullAssignableToEveryType.js index 4901f4837bb..9917ebeac9e 100644 --- a/tests/baselines/reference/nullAssignableToEveryType.js +++ b/tests/baselines/reference/nullAssignableToEveryType.js @@ -80,3 +80,8 @@ function foo(x, y, z) { y = null; z = null; } +//function foo(x: T, y: U, z: V) { +// x = null; +// y = null; +// z = null; +//} diff --git a/tests/baselines/reference/parserIndexSignature1.errors.txt b/tests/baselines/reference/parserIndexSignature1.errors.txt index 74f5d0e0921..cde7259c7bd 100644 --- a/tests/baselines/reference/parserIndexSignature1.errors.txt +++ b/tests/baselines/reference/parserIndexSignature1.errors.txt @@ -1,9 +1,9 @@ -tests/cases/conformance/parser/ecmascript5/IndexSignatures/parserIndexSignature1.ts(2,7): error TS1017: An index signature cannot have a rest parameter. +tests/cases/conformance/parser/ecmascript5/IndexSignatures/parserIndexSignature1.ts(2,4): error TS1017: An index signature cannot have a rest parameter. ==== tests/cases/conformance/parser/ecmascript5/IndexSignatures/parserIndexSignature1.ts (1 errors) ==== interface I { [...a] - ~ + ~~~ !!! error TS1017: An index signature cannot have a rest parameter. } \ No newline at end of file diff --git a/tests/baselines/reference/parserIndexSignature3.errors.txt b/tests/baselines/reference/parserIndexSignature3.errors.txt index bc552fd6a1d..27310e4d0a4 100644 --- a/tests/baselines/reference/parserIndexSignature3.errors.txt +++ b/tests/baselines/reference/parserIndexSignature3.errors.txt @@ -1,9 +1,9 @@ -tests/cases/conformance/parser/ecmascript5/IndexSignatures/parserIndexSignature3.ts(2,4): error TS1019: An index signature parameter cannot have a question mark. +tests/cases/conformance/parser/ecmascript5/IndexSignatures/parserIndexSignature3.ts(2,5): error TS1019: An index signature parameter cannot have a question mark. ==== tests/cases/conformance/parser/ecmascript5/IndexSignatures/parserIndexSignature3.ts (1 errors) ==== interface I { [a?] - ~ + ~ !!! error TS1019: An index signature parameter cannot have a question mark. } \ No newline at end of file diff --git a/tests/baselines/reference/parserMemberAccessorDeclaration17.errors.txt b/tests/baselines/reference/parserMemberAccessorDeclaration17.errors.txt index 6edb9b98b7b..2d7f6e3be30 100644 --- a/tests/baselines/reference/parserMemberAccessorDeclaration17.errors.txt +++ b/tests/baselines/reference/parserMemberAccessorDeclaration17.errors.txt @@ -1,9 +1,9 @@ -tests/cases/conformance/parser/ecmascript5/MemberAccessorDeclarations/parserMemberAccessorDeclaration17.ts(2,8): error TS1051: A 'set' accessor cannot have an optional parameter. +tests/cases/conformance/parser/ecmascript5/MemberAccessorDeclarations/parserMemberAccessorDeclaration17.ts(2,13): error TS1051: A 'set' accessor cannot have an optional parameter. ==== tests/cases/conformance/parser/ecmascript5/MemberAccessorDeclarations/parserMemberAccessorDeclaration17.ts (1 errors) ==== class C { set Foo(a?: number) { } - ~~~ + ~ !!! error TS1051: A 'set' accessor cannot have an optional parameter. } \ No newline at end of file diff --git a/tests/baselines/reference/parserMemberAccessorDeclaration18.errors.txt b/tests/baselines/reference/parserMemberAccessorDeclaration18.errors.txt index 54d39a6d663..8296a087bab 100644 --- a/tests/baselines/reference/parserMemberAccessorDeclaration18.errors.txt +++ b/tests/baselines/reference/parserMemberAccessorDeclaration18.errors.txt @@ -1,9 +1,9 @@ -tests/cases/conformance/parser/ecmascript5/MemberAccessorDeclarations/parserMemberAccessorDeclaration18.ts(2,8): error TS1053: A 'set' accessor cannot have rest parameter. +tests/cases/conformance/parser/ecmascript5/MemberAccessorDeclarations/parserMemberAccessorDeclaration18.ts(2,12): error TS1053: A 'set' accessor cannot have rest parameter. ==== tests/cases/conformance/parser/ecmascript5/MemberAccessorDeclarations/parserMemberAccessorDeclaration18.ts (1 errors) ==== class C { set Foo(...a) { } - ~~~ + ~~~ !!! error TS1053: A 'set' accessor cannot have rest parameter. } \ No newline at end of file diff --git a/tests/baselines/reference/parserParameterList1.errors.txt b/tests/baselines/reference/parserParameterList1.errors.txt index 3b01ee02168..a7e9a533f63 100644 --- a/tests/baselines/reference/parserParameterList1.errors.txt +++ b/tests/baselines/reference/parserParameterList1.errors.txt @@ -1,9 +1,9 @@ -tests/cases/conformance/parser/ecmascript5/ParameterLists/parserParameterList1.ts(2,9): error TS1014: A rest parameter must be last in a parameter list. +tests/cases/conformance/parser/ecmascript5/ParameterLists/parserParameterList1.ts(2,6): error TS1014: A rest parameter must be last in a parameter list. ==== tests/cases/conformance/parser/ecmascript5/ParameterLists/parserParameterList1.ts (1 errors) ==== class C { F(...A, B) { } - ~ + ~~~ !!! error TS1014: A rest parameter must be last in a parameter list. } \ No newline at end of file diff --git a/tests/baselines/reference/parserParameterList11.errors.txt b/tests/baselines/reference/parserParameterList11.errors.txt index 1fcede6c398..2cb8def201d 100644 --- a/tests/baselines/reference/parserParameterList11.errors.txt +++ b/tests/baselines/reference/parserParameterList11.errors.txt @@ -1,7 +1,7 @@ -tests/cases/conformance/parser/ecmascript5/ParameterLists/parserParameterList11.ts(1,5): error TS1047: A rest parameter cannot be optional. +tests/cases/conformance/parser/ecmascript5/ParameterLists/parserParameterList11.ts(1,8): error TS1047: A rest parameter cannot be optional. ==== tests/cases/conformance/parser/ecmascript5/ParameterLists/parserParameterList11.ts (1 errors) ==== (...arg?) => 102; - ~~~ + ~ !!! error TS1047: A rest parameter cannot be optional. \ No newline at end of file diff --git a/tests/baselines/reference/parserParameterList9.errors.txt b/tests/baselines/reference/parserParameterList9.errors.txt index 2db96373cd0..5f670148faa 100644 --- a/tests/baselines/reference/parserParameterList9.errors.txt +++ b/tests/baselines/reference/parserParameterList9.errors.txt @@ -1,9 +1,9 @@ -tests/cases/conformance/parser/ecmascript5/ParameterLists/parserParameterList9.ts(2,11): error TS1047: A rest parameter cannot be optional. +tests/cases/conformance/parser/ecmascript5/ParameterLists/parserParameterList9.ts(2,14): error TS1047: A rest parameter cannot be optional. ==== tests/cases/conformance/parser/ecmascript5/ParameterLists/parserParameterList9.ts (1 errors) ==== class C { foo(...bar?) { } - ~~~ + ~ !!! error TS1047: A rest parameter cannot be optional. } \ No newline at end of file diff --git a/tests/baselines/reference/parserS7.6.1.1_A1.10.js b/tests/baselines/reference/parserS7.6.1.1_A1.10.js index 04e0076b16a..6465281d88d 100644 --- a/tests/baselines/reference/parserS7.6.1.1_A1.10.js +++ b/tests/baselines/reference/parserS7.6.1.1_A1.10.js @@ -17,3 +17,11 @@ //// [parserS7.6.1.1_A1.10.js] // Copyright 2009 the Sputnik authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. +/** + * The "for" token can not be used as identifier + * + * @path ch07/7.6/7.6.1/7.6.1.1/S7.6.1.1_A1.10.js + * @description Checking if execution of "for=1" fails + * @negative + */ +//for = 1; diff --git a/tests/baselines/reference/parserSyntaxWalker.generated.js b/tests/baselines/reference/parserSyntaxWalker.generated.js index 3b78baa0f74..392b5545830 100644 --- a/tests/baselines/reference/parserSyntaxWalker.generated.js +++ b/tests/baselines/reference/parserSyntaxWalker.generated.js @@ -289,3 +289,220 @@ // [index: number]: string; // } //} +//import fs = module("fs"); +//module TypeScriptAllInOne { +// export class Program { +// static Main(...args: string[]) { +// try { +// var bfs = new BasicFeatures(); +// var retValue: number = 0; +// retValue = bfs.VARIABLES(); +// if (retValue != 0) { +// return 1; +// } +// retValue = bfs.STATEMENTS(4); +// if (retValue != 0) { +// return 1; +// } +// retValue = bfs.TYPES(); +// if (retValue != 0) { +// return 1; +// } +// retValue = bfs.OPERATOR(); +// if (retValue != 0) { +// return 1; +// } +// } +// catch (e) { +// console.log(e); +// } +// finally { +// } +// console.log('Done'); +// return 0; +// } +// } +// class BasicFeatures { +// /// +// /// Test various of variables. Including nullable,key world as variable,special format +// /// +// /// +// public VARIABLES(): number { +// var local = Number.MAX_VALUE; +// var min = Number.MIN_VALUE; +// var inf = Number.NEGATIVE_INFINITY; +// var nan = Number.NaN; +// var undef = undefined; +// var п = local; +// var м = local; +// var local5 = null; +// var local6 = local5 instanceof fs.File; +// var hex = 0xBADC0DE, Hex = 0XDEADBEEF; +// var float = 6.02e23, float2 = 6.02E-23 +// var char = 'c', \u0066 = '\u0066', hexchar = '\x42'; +// var quoted = '"', quoted2 = "'"; +// var reg = /\w*/; +// var objLit = { "var": number = 42, equals: function (x) { return x["var"] === 42; }, toString: () => 'objLit{42}' }; +// var weekday = Weekdays.Monday; +// var con = char + f + hexchar + float.toString() + float2.toString() + reg.toString() + objLit + weekday; +// // +// var any = 0; +// var boolean = 0; +// var declare = 0; +// var constructor = 0; +// var get = 0; +// var implements = 0; +// var interface = 0; +// var let = 0; +// var module = 0; +// var number = 0; +// var package = 0; +// var private = 0; +// var protected = 0; +// var public = 0; +// var set = 0; +// var static = 0; +// var string = 0; +// var yield = 0; +// var sum3 = any + boolean + declare + constructor + get + implements + interface + let + module + number + package + private + protected + public + set + static + string + yield; +// return 0; +// } +// /// +// /// Test different statements. Including if-else,swith,foreach,(un)checked,lock,using,try-catch-finally +// /// +// /// +// /// +// STATEMENTS(i: number): number { +// var retVal = 0; +// if (i == 1) +// retVal = 1; +// else +// retVal = 0; +// switch (i) { +// case 2: +// retVal = 1; +// break; +// case 3: +// retVal = 1; +// break; +// default: +// break; +// } +// for (var x in { x: 0, y: 1 }) { +// } +// try { +// throw null; +// } +// catch (Exception) { +// } +// finally { +// try { } +// catch (Exception) { } +// } +// return retVal; +// } +// /// +// /// Test types in ts language. Including class,struct,interface,delegate,anonymous type +// /// +// /// +// public TYPES(): number { +// var retVal = 0; +// var c = new CLASS(); +// var xx: IF = c; +// retVal += c.Property; +// retVal += c.Member(); +// retVal += xx ^= Foo() ? 0 : 1; +// //anonymous type +// var anony = { a: new CLASS() }; +// retVal += anony.a.d(); +// return retVal; +// } +// ///// +// ///// Test different operators +// ///// +// ///// +// public OPERATOR(): number { +// var a: number[] = [1, 2, 3, 4, implements , ];/*[] bug*/ // YES [] +// var i = a[1];/*[]*/ +// i = i + i - i * i / i % i & i | i ^ i;/*+ - * / % & | ^*/ +// var b = true && false || true ^ false;/*& | ^*/ +// b = !b;/*!*/ +// i = ~i;/*~i*/ +// b = i < (i - continue ) && (i + 1) > i;/*< && >*/ +// var f = true ? 1 : 0;/*? :*/ // YES : +// i++;/*++*/ +// i--;/*--*/ +// b = true && false || true;/*&& ||*/ +// i = i << 5;/*<<*/ +// i = i >> 5;/*>>*/ +// var j = i; +// b = i == j && i != j && i <= j && i >= j;/*= == && != <= >=*/ +// i += 5.0;/*+=*/ +// i -= i;/*-=*/ +// i *= i;/**=*/ +// if (i == 0) +// i++; +// i /= i;/*/=*/ +// i %= i;/*%=*/ +// i &= i;/*&=*/ +// i |= i;/*|=*/ +// i ^= i;/*^=*/ +// i <<= i;/*<<=*/ +// i >>= i;/*>>=*/ +// if (i == 0 && !b && f == 1) +// return 0; +// else return 1; +// } +// } +// interface IF { +// Foo