diff --git a/Jakefile.js b/Jakefile.js index e5fc017e04a..f11d1bf423d 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -756,13 +756,14 @@ function runConsoleTests(defaultReporter, runInParallel) { colors = process.env.colors || process.env.color; colors = colors ? ' --no-colors ' : ' --colors '; reporter = process.env.reporter || process.env.r || defaultReporter; + var bail = (process.env.bail || process.env.b) ? "--bail" : ""; var lintFlag = process.env.lint !== 'false'; // timeout normally isn't necessary but Travis-CI has been timing out on compiler baselines occasionally // default timeout is 2sec which really should be enough, but maybe we just need a small amount longer if(!runInParallel) { tests = tests ? ' -g "' + tests + '"' : ''; - var cmd = "mocha" + (debug ? " --debug-brk" : "") + " -R " + reporter + tests + colors + ' -t ' + testTimeout + ' ' + run; + var cmd = "mocha" + (debug ? " --debug-brk" : "") + " -R " + reporter + tests + colors + bail + ' -t ' + testTimeout + ' ' + run; console.log(cmd); var savedNodeEnv = process.env.NODE_ENV; @@ -827,7 +828,7 @@ task("runtests-parallel", ["build-rules", "tests", builtLocalDirectory], functio runConsoleTests('min', /*runInParallel*/ true); }, {async: true}); -desc("Runs the tests using the built run.js file. Optional arguments are: t[ests]=regex r[eporter]=[list|spec|json|] d[ebug]=true color[s]=false lint=true."); +desc("Runs the tests using the built run.js file. Optional arguments are: t[ests]=regex r[eporter]=[list|spec|json|] d[ebug]=true color[s]=false lint=true bail=false."); task("runtests", ["build-rules", "tests", builtLocalDirectory], function() { runConsoleTests('mocha-fivemat-progress-reporter', /*runInParallel*/ false); }, {async: true}); diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index fafa67c5121..b45af24d4d1 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -578,12 +578,6 @@ namespace ts { } } - function isNarrowableReference(expr: Expression): boolean { - return expr.kind === SyntaxKind.Identifier || - expr.kind === SyntaxKind.ThisKeyword || - expr.kind === SyntaxKind.PropertyAccessExpression && isNarrowableReference((expr).expression); - } - function isNarrowingExpression(expr: Expression): boolean { switch (expr.kind) { case SyntaxKind.Identifier: @@ -591,7 +585,7 @@ namespace ts { case SyntaxKind.PropertyAccessExpression: return isNarrowableReference(expr); case SyntaxKind.CallExpression: - return true; + return hasNarrowableArgument(expr); case SyntaxKind.ParenthesizedExpression: return isNarrowingExpression((expr).expression); case SyntaxKind.BinaryExpression: @@ -602,6 +596,39 @@ namespace ts { return false; } + function isNarrowableReference(expr: Expression): boolean { + return expr.kind === SyntaxKind.Identifier || + expr.kind === SyntaxKind.ThisKeyword || + expr.kind === SyntaxKind.PropertyAccessExpression && isNarrowableReference((expr).expression); + } + + function hasNarrowableArgument(expr: CallExpression) { + if (expr.arguments) { + for (const argument of expr.arguments) { + if (isNarrowableReference(argument)) { + return true; + } + } + } + if (expr.expression.kind === SyntaxKind.PropertyAccessExpression && + isNarrowableReference((expr.expression).expression)) { + return true; + } + return false; + } + + function isNarrowingNullCheckOperands(expr1: Expression, expr2: Expression) { + return (expr1.kind === SyntaxKind.NullKeyword || expr1.kind === SyntaxKind.Identifier && (expr1).text === "undefined") && isNarrowableOperand(expr2); + } + + function isNarrowingTypeofOperands(expr1: Expression, expr2: Expression) { + return expr1.kind === SyntaxKind.TypeOfExpression && isNarrowableOperand((expr1).expression) && expr2.kind === SyntaxKind.StringLiteral; + } + + function isNarrowingDiscriminant(expr: Expression) { + return expr.kind === SyntaxKind.PropertyAccessExpression && isNarrowableReference((expr).expression); + } + function isNarrowingBinaryExpression(expr: BinaryExpression) { switch (expr.operatorToken.kind) { case SyntaxKind.EqualsToken: @@ -610,34 +637,35 @@ namespace ts { case SyntaxKind.ExclamationEqualsToken: case SyntaxKind.EqualsEqualsEqualsToken: case SyntaxKind.ExclamationEqualsEqualsToken: - if ((isNarrowingExpression(expr.left) && (expr.right.kind === SyntaxKind.NullKeyword || expr.right.kind === SyntaxKind.Identifier)) || - (isNarrowingExpression(expr.right) && (expr.left.kind === SyntaxKind.NullKeyword || expr.left.kind === SyntaxKind.Identifier))) { - return true; - } - if (isTypeOfNarrowingBinaryExpression(expr)) { - return true; - } - return false; + return isNarrowingNullCheckOperands(expr.right, expr.left) || isNarrowingNullCheckOperands(expr.left, expr.right) || + isNarrowingTypeofOperands(expr.right, expr.left) || isNarrowingTypeofOperands(expr.left, expr.right) || + isNarrowingDiscriminant(expr.left) || isNarrowingDiscriminant(expr.right); case SyntaxKind.InstanceOfKeyword: - return isNarrowingExpression(expr.left); + return isNarrowableOperand(expr.left); case SyntaxKind.CommaToken: return isNarrowingExpression(expr.right); } return false; } - function isTypeOfNarrowingBinaryExpression(expr: BinaryExpression) { - let typeOf: Expression; - if (expr.left.kind === SyntaxKind.StringLiteral) { - typeOf = expr.right; + function isNarrowableOperand(expr: Expression): boolean { + switch (expr.kind) { + case SyntaxKind.ParenthesizedExpression: + return isNarrowableOperand((expr).expression); + case SyntaxKind.BinaryExpression: + switch ((expr).operatorToken.kind) { + case SyntaxKind.EqualsToken: + return isNarrowableOperand((expr).left); + case SyntaxKind.CommaToken: + return isNarrowableOperand((expr).right); + } } - else if (expr.right.kind === SyntaxKind.StringLiteral) { - typeOf = expr.left; - } - else { - typeOf = undefined; - } - return typeOf && typeOf.kind === SyntaxKind.TypeOfExpression && isNarrowingExpression((typeOf).expression); + return isNarrowableReference(expr); + } + + function isNarrowingSwitchStatement(switchStatement: SwitchStatement) { + const expr = switchStatement.expression; + return expr.kind === SyntaxKind.PropertyAccessExpression && isNarrowableReference((expr).expression); } function createBranchLabel(): FlowLabel { @@ -683,8 +711,22 @@ namespace ts { setFlowNodeReferenced(antecedent); return { flags, - antecedent, expression, + antecedent + }; + } + + function createFlowSwitchClause(antecedent: FlowNode, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number): FlowNode { + if (!isNarrowingSwitchStatement(switchStatement)) { + return antecedent; + } + setFlowNodeReferenced(antecedent); + return { + flags: FlowFlags.SwitchClause, + switchStatement, + clauseStart, + clauseEnd, + antecedent }; } @@ -913,9 +955,12 @@ namespace ts { preSwitchCaseFlow = currentFlow; bind(node.caseBlock); addAntecedent(postSwitchLabel, currentFlow); - const hasNonEmptyDefault = forEach(node.caseBlock.clauses, c => c.kind === SyntaxKind.DefaultClause && c.statements.length); - if (!hasNonEmptyDefault) { - addAntecedent(postSwitchLabel, preSwitchCaseFlow); + const hasDefault = forEach(node.caseBlock.clauses, c => c.kind === SyntaxKind.DefaultClause); + // We mark a switch statement as possibly exhaustive if it has no default clause and if all + // case clauses have unreachable end points (e.g. they all return). + node.possiblyExhaustive = !hasDefault && !postSwitchLabel.antecedents; + if (!hasDefault) { + addAntecedent(postSwitchLabel, createFlowSwitchClause(preSwitchCaseFlow, node, 0, 0)); } currentBreakTarget = saveBreakTarget; preSwitchCaseFlow = savePreSwitchCaseFlow; @@ -924,25 +969,22 @@ namespace ts { function bindCaseBlock(node: CaseBlock): void { const clauses = node.clauses; + let fallthroughFlow = unreachableFlow; for (let i = 0; i < clauses.length; i++) { - const clause = clauses[i]; - if (clause.statements.length) { - if (currentFlow.flags & FlowFlags.Unreachable) { - currentFlow = preSwitchCaseFlow; - } - else { - const preCaseLabel = createBranchLabel(); - addAntecedent(preCaseLabel, preSwitchCaseFlow); - addAntecedent(preCaseLabel, currentFlow); - currentFlow = finishFlowLabel(preCaseLabel); - } - bind(clause); - if (!(currentFlow.flags & FlowFlags.Unreachable) && i !== clauses.length - 1 && options.noFallthroughCasesInSwitch) { - errorOnFirstToken(clause, Diagnostics.Fallthrough_case_in_switch); - } + const clauseStart = i; + while (!clauses[i].statements.length && i + 1 < clauses.length) { + bind(clauses[i]); + i++; } - else { - bind(clause); + const preCaseLabel = createBranchLabel(); + addAntecedent(preCaseLabel, createFlowSwitchClause(preSwitchCaseFlow, node.parent, clauseStart, i + 1)); + addAntecedent(preCaseLabel, fallthroughFlow); + currentFlow = finishFlowLabel(preCaseLabel); + const clause = clauses[i]; + bind(clause); + fallthroughFlow = currentFlow; + if (!(currentFlow.flags & FlowFlags.Unreachable) && i !== clauses.length - 1 && options.noFallthroughCasesInSwitch) { + errorOnFirstToken(clause, Diagnostics.Fallthrough_case_in_switch); } } } @@ -1961,7 +2003,7 @@ namespace ts { classPrototype.parent = leftSideOfAssignment; const funcSymbol = container.locals[constructorFunction.text]; - if (!funcSymbol || !(funcSymbol.flags & SymbolFlags.Function)) { + if (!funcSymbol || !(funcSymbol.flags & SymbolFlags.Function || isDeclarationOfFunctionExpression(funcSymbol))) { return; } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 47b0a53a8c3..ac8a47a9913 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -562,7 +562,8 @@ namespace ts { const declarationFile = getSourceFileOfNode(declaration); const useFile = getSourceFileOfNode(usage); if (declarationFile !== useFile) { - if (modulekind || (!compilerOptions.outFile && !compilerOptions.out)) { + if ((modulekind && (declarationFile.externalModuleIndicator || useFile.externalModuleIndicator)) || + (!compilerOptions.outFile && !compilerOptions.out)) { // nodes are in different files and order cannot be determines return true; } @@ -852,7 +853,8 @@ namespace ts { if (!result) { if (nameNotFoundMessage) { - if (!checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg)) { + if (!checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) && + !checkAndReportErrorForExtendingInterface(errorLocation)) { error(errorLocation, nameNotFoundMessage, typeof nameArg === "string" ? nameArg : declarationNameToString(nameArg)); } } @@ -936,6 +938,31 @@ namespace ts { return false; } + + function checkAndReportErrorForExtendingInterface(errorLocation: Node): boolean { + let parentClassExpression = errorLocation; + while (parentClassExpression) { + const kind = parentClassExpression.kind; + if (kind === SyntaxKind.Identifier || kind === SyntaxKind.PropertyAccessExpression) { + parentClassExpression = parentClassExpression.parent; + continue; + } + if (kind === SyntaxKind.ExpressionWithTypeArguments) { + break; + } + return false; + } + if (!parentClassExpression) { + return false; + } + const expression = (parentClassExpression).expression; + if (resolveEntityName(expression, SymbolFlags.Interface, /*ignoreErrors*/ true)) { + error(errorLocation, Diagnostics.Cannot_extend_an_interface_0_Did_you_mean_implements, getTextOfNode(expression)); + return true; + } + return false; + } + function checkResolvedBlockScopedVariable(result: Symbol, errorLocation: Node): void { Debug.assert((result.flags & SymbolFlags.BlockScopedVariable) !== 0); // Block-scoped variables cannot be used before their definition @@ -5185,7 +5212,6 @@ namespace ts { if (hasProperty(stringLiteralTypes, text)) { return stringLiteralTypes[text]; } - const type = stringLiteralTypes[text] = createType(TypeFlags.StringLiteral); type.text = text; return type; @@ -5650,6 +5676,10 @@ namespace ts { return checkTypeComparableTo(source, target, /*errorNode*/ undefined); } + function areTypesComparable(type1: Type, type2: Type): boolean { + return isTypeComparableTo(type1, type2) || isTypeComparableTo(type2, type1); + } + function checkTypeSubtypeOf(source: Type, target: Type, errorNode: Node, headMessage?: DiagnosticMessage, containingMessageChain?: DiagnosticMessageChain): boolean { return checkTypeRelatedTo(source, target, subtypeRelation, errorNode, headMessage, containingMessageChain); } @@ -6830,8 +6860,10 @@ namespace ts { return !!getPropertyOfType(type, "0"); } - function isStringLiteralType(type: Type) { - return type.flags & TypeFlags.StringLiteral; + function isStringLiteralUnionType(type: Type): boolean { + return type.flags & TypeFlags.StringLiteral ? true : + type.flags & TypeFlags.Union ? forEach((type).types, isStringLiteralUnionType) : + false; } /** @@ -7696,6 +7728,35 @@ namespace ts { return node; } + function getTypeOfSwitchClause(clause: CaseClause | DefaultClause) { + if (clause.kind === SyntaxKind.CaseClause) { + const expr = (clause).expression; + return expr.kind === SyntaxKind.StringLiteral ? getStringLiteralTypeForText((expr).text) : checkExpression(expr); + } + return undefined; + } + + function getSwitchClauseTypes(switchStatement: SwitchStatement): Type[] { + const links = getNodeLinks(switchStatement); + if (!links.switchTypes) { + // If all case clauses specify expressions that have unit types, we return an array + // of those unit types. Otherwise we return an empty array. + const types = map(switchStatement.caseBlock.clauses, getTypeOfSwitchClause); + links.switchTypes = forEach(types, t => !t || t.flags & TypeFlags.StringLiteral) ? types : emptyArray; + } + return links.switchTypes; + } + + function eachTypeContainedIn(source: Type, types: Type[]) { + return source.flags & TypeFlags.Union ? !forEach((source).types, t => !contains(types, t)) : contains(types, source); + } + + function filterType(type: Type, f: (t: Type) => boolean): Type { + return type.flags & TypeFlags.Union ? + getUnionType(filter((type).types, f)) : + f(type) ? type : neverType; + } + function getFlowTypeOfReference(reference: Node, declaredType: Type, assumeInitialized: boolean, includeOuterFunctions: boolean) { let key: string; if (!reference.flowNode || assumeInitialized && !(declaredType.flags & TypeFlags.Narrowable)) { @@ -7733,6 +7794,9 @@ namespace ts { else if (flow.flags & FlowFlags.Condition) { type = getTypeAtFlowCondition(flow); } + else if (flow.flags & FlowFlags.SwitchClause) { + type = getTypeAtSwitchClause(flow); + } else if (flow.flags & FlowFlags.Label) { if ((flow).antecedents.length === 1) { flow = (flow).antecedents[0]; @@ -7816,6 +7880,11 @@ namespace ts { return type; } + function getTypeAtSwitchClause(flow: FlowSwitchClause) { + const type = getTypeAtFlowNode(flow.antecedent); + return narrowTypeBySwitchOnDiscriminant(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd); + } + function getTypeAtFlowBranchLabel(flow: FlowLabel) { const antecedentTypes: Type[] = []; for (const antecedent of flow.antecedents) { @@ -7895,12 +7964,26 @@ namespace ts { case SyntaxKind.ExclamationEqualsToken: case SyntaxKind.EqualsEqualsEqualsToken: case SyntaxKind.ExclamationEqualsEqualsToken: - if (isNullOrUndefinedLiteral(expr.left) || isNullOrUndefinedLiteral(expr.right)) { - return narrowTypeByNullCheck(type, expr, assumeTrue); + const left = expr.left; + const operator = expr.operatorToken.kind; + const right = expr.right; + if (isNullOrUndefinedLiteral(right)) { + return narrowTypeByNullCheck(type, left, operator, right, assumeTrue); } - if (expr.left.kind === SyntaxKind.TypeOfExpression && expr.right.kind === SyntaxKind.StringLiteral || - expr.left.kind === SyntaxKind.StringLiteral && expr.right.kind === SyntaxKind.TypeOfExpression) { - return narrowTypeByTypeof(type, expr, assumeTrue); + if (isNullOrUndefinedLiteral(left)) { + return narrowTypeByNullCheck(type, right, operator, left, assumeTrue); + } + if (left.kind === SyntaxKind.TypeOfExpression && right.kind === SyntaxKind.StringLiteral) { + return narrowTypeByTypeof(type, left, operator, right, assumeTrue); + } + if (right.kind === SyntaxKind.TypeOfExpression && left.kind === SyntaxKind.StringLiteral) { + return narrowTypeByTypeof(type, right, operator, left, assumeTrue); + } + if (left.kind === SyntaxKind.PropertyAccessExpression) { + return narrowTypeByDiscriminant(type, left, operator, right, assumeTrue); + } + if (right.kind === SyntaxKind.PropertyAccessExpression) { + return narrowTypeByDiscriminant(type, right, operator, left, assumeTrue); } break; case SyntaxKind.InstanceOfKeyword: @@ -7911,41 +7994,35 @@ namespace ts { return type; } - function narrowTypeByNullCheck(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type { - // We have '==', '!=', '===', or '!==' operator with 'null' or 'undefined' on one side - const operator = expr.operatorToken.kind; - const nullLike = isNullOrUndefinedLiteral(expr.left) ? expr.left : expr.right; - const narrowed = isNullOrUndefinedLiteral(expr.left) ? expr.right : expr.left; + function narrowTypeByNullCheck(type: Type, target: Expression, operator: SyntaxKind, literal: Expression, assumeTrue: boolean): Type { + // We have '==', '!=', '===', or '!==' operator with 'null' or 'undefined' as value if (operator === SyntaxKind.ExclamationEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken) { assumeTrue = !assumeTrue; } - if (!strictNullChecks || !isMatchingReference(reference, getReferenceFromExpression(narrowed))) { + if (!strictNullChecks || !isMatchingReference(reference, getReferenceFromExpression(target))) { return type; } const doubleEquals = operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsToken; const facts = doubleEquals ? assumeTrue ? TypeFacts.EQUndefinedOrNull : TypeFacts.NEUndefinedOrNull : - nullLike.kind === SyntaxKind.NullKeyword ? + literal.kind === SyntaxKind.NullKeyword ? assumeTrue ? TypeFacts.EQNull : TypeFacts.NENull : assumeTrue ? TypeFacts.EQUndefined : TypeFacts.NEUndefined; return getTypeWithFacts(type, facts); } - function narrowTypeByTypeof(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type { - // We have '==', '!=', '====', or !==' operator with 'typeof xxx' on the left - // and string literal on the right - const narrowed = getReferenceFromExpression(((expr.left.kind === SyntaxKind.TypeOfExpression ? expr.left : expr.right)).expression); - const literal = (expr.right.kind === SyntaxKind.StringLiteral ? expr.right : expr.left); - if (!isMatchingReference(reference, narrowed)) { + function narrowTypeByTypeof(type: Type, typeOfExpr: TypeOfExpression, operator: SyntaxKind, literal: LiteralExpression, assumeTrue: boolean): Type { + // We have '==', '!=', '====', or !==' operator with 'typeof xxx' and string literal operands + const target = getReferenceFromExpression(typeOfExpr.expression); + if (!isMatchingReference(reference, target)) { // For a reference of the form 'x.y', a 'typeof x === ...' type guard resets the // narrowed type of 'y' to its declared type. - if (containsMatchingReference(reference, narrowed)) { + if (containsMatchingReference(reference, target)) { return declaredType; } return type; } - if (expr.operatorToken.kind === SyntaxKind.ExclamationEqualsToken || - expr.operatorToken.kind === SyntaxKind.ExclamationEqualsEqualsToken) { + if (operator === SyntaxKind.ExclamationEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken) { assumeTrue = !assumeTrue; } if (assumeTrue && !(type.flags & TypeFlags.Union)) { @@ -7963,6 +8040,58 @@ namespace ts { return getTypeWithFacts(type, facts); } + function narrowTypeByDiscriminant(type: Type, propAccess: PropertyAccessExpression, operator: SyntaxKind, value: Expression, assumeTrue: boolean): Type { + // We have '==', '!=', '===', or '!==' operator with property access as target + if (!isMatchingReference(reference, propAccess.expression)) { + return type; + } + const propName = propAccess.name.text; + const propType = getTypeOfPropertyOfType(type, propName); + if (!propType || !isStringLiteralUnionType(propType)) { + return type; + } + const discriminantType = value.kind === SyntaxKind.StringLiteral ? getStringLiteralTypeForText((value).text) : checkExpression(value); + if (!isStringLiteralUnionType(discriminantType)) { + return type; + } + if (operator === SyntaxKind.ExclamationEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken) { + assumeTrue = !assumeTrue; + } + if (assumeTrue) { + return filterType(type, t => areTypesComparable(getTypeOfPropertyOfType(t, propName), discriminantType)); + } + if (discriminantType.flags & TypeFlags.StringLiteral) { + return filterType(type, t => getTypeOfPropertyOfType(t, propName) !== discriminantType); + } + return type; + } + + function narrowTypeBySwitchOnDiscriminant(type: Type, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number) { + // We have switch statement with property access expression + if (!isMatchingReference(reference, (switchStatement.expression).expression)) { + return type; + } + const propName = (switchStatement.expression).name.text; + const propType = getTypeOfPropertyOfType(type, propName); + if (!propType || !isStringLiteralUnionType(propType)) { + return type; + } + const switchTypes = getSwitchClauseTypes(switchStatement); + if (!switchTypes.length) { + return type; + } + const clauseTypes = switchTypes.slice(clauseStart, clauseEnd); + const hasDefaultClause = clauseStart === clauseEnd || contains(clauseTypes, undefined); + const caseTypes = hasDefaultClause ? filter(clauseTypes, t => !!t) : clauseTypes; + const discriminantType = caseTypes.length ? getUnionType(caseTypes) : undefined; + const caseType = discriminantType && filterType(type, t => isTypeComparableTo(discriminantType, getTypeOfPropertyOfType(t, propName))); + if (!hasDefaultClause) { + return caseType; + } + const defaultType = filterType(type, t => !eachTypeContainedIn(getTypeOfPropertyOfType(t, propName), switchTypes)); + return caseType ? getUnionType([caseType, defaultType]) : defaultType; + } + function narrowTypeByInstanceof(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type { const left = getReferenceFromExpression(expr.left); if (!isMatchingReference(reference, left)) { @@ -8933,10 +9062,6 @@ namespace ts { return applyToContextualType(type, t => getIndexTypeOfStructuredType(t, kind)); } - function contextualTypeIsStringLiteralType(type: Type): boolean { - return !!(type.flags & TypeFlags.Union ? forEach((type).types, isStringLiteralType) : isStringLiteralType(type)); - } - // Return true if the given contextual type is a tuple-like type function contextualTypeIsTupleLikeType(type: Type): boolean { return !!(type.flags & TypeFlags.Union ? forEach((type).types, isTupleLikeType) : isTupleLikeType(type)); @@ -10038,7 +10163,7 @@ namespace ts { } const prop = getPropertyOfType(apparentType, right.text); if (!prop) { - if (right.text) { + if (right.text && !checkAndReportErrorForExtendingInterface(node)) { error(right, Diagnostics.Property_0_does_not_exist_on_type_1, declarationNameToString(right), typeToString(type.flags & TypeFlags.ThisType ? apparentType : type)); } return unknownType; @@ -11495,8 +11620,12 @@ namespace ts { // When resolved signature is a call signature (and not a construct signature) the result type is any, unless // the declaring function had members created through 'x.prototype.y = expr' or 'this.y = expr' psuedodeclarations // in a JS file - const funcSymbol = checkExpression(node.expression).symbol; - if (funcSymbol && funcSymbol.members && (funcSymbol.flags & SymbolFlags.Function)) { + // Note:JS inferred classes might come from a variable declaration instead of a function declaration. + // In this case, using getResolvedSymbol directly is required to avoid losing the members from the declaration. + const funcSymbol = node.expression.kind === SyntaxKind.Identifier ? + getResolvedSymbol(node.expression as Identifier) : + checkExpression(node.expression).symbol; + if (funcSymbol && funcSymbol.members && (funcSymbol.flags & SymbolFlags.Function || isDeclarationOfFunctionExpression(funcSymbol))) { return getInferredClassType(funcSymbol); } else if (compilerOptions.noImplicitAny) { @@ -11520,7 +11649,10 @@ namespace ts { function checkAssertion(node: AssertionExpression) { const exprType = getRegularTypeOfObjectLiteral(checkExpression(node.expression)); + + checkSourceElement(node.type); const targetType = getTypeFromTypeNode(node.type); + if (produceDiagnostics && targetType !== unknownType) { const widenedType = getWidenedType(exprType); if (!isTypeComparableTo(targetType, widenedType)) { @@ -11760,10 +11892,42 @@ namespace ts { return aggregatedTypes; } + function isExhaustiveSwitchStatement(node: SwitchStatement): boolean { + const expr = node.expression; + if (!node.possiblyExhaustive || expr.kind !== SyntaxKind.PropertyAccessExpression) { + return false; + } + const type = checkExpression((expr).expression); + if (!(type.flags & TypeFlags.Union)) { + return false; + } + const propName = (expr).name.text; + const propType = getTypeOfPropertyOfType(type, propName); + if (!propType || !isStringLiteralUnionType(propType)) { + return false; + } + const switchTypes = getSwitchClauseTypes(node); + if (!switchTypes.length) { + return false; + } + return eachTypeContainedIn(propType, switchTypes); + } + + function functionHasImplicitReturn(func: FunctionLikeDeclaration) { + if (!(func.flags & NodeFlags.HasImplicitReturn)) { + return false; + } + const lastStatement = lastOrUndefined((func.body).statements); + if (lastStatement && lastStatement.kind === SyntaxKind.SwitchStatement && isExhaustiveSwitchStatement(lastStatement)) { + return false; + } + return true; + } + function checkAndAggregateReturnExpressionTypes(func: FunctionLikeDeclaration, contextualMapper: TypeMapper): Type[] { const isAsync = isAsyncFunctionLike(func); const aggregatedTypes: Type[] = []; - let hasReturnWithNoExpression = !!(func.flags & NodeFlags.HasImplicitReturn); + let hasReturnWithNoExpression = functionHasImplicitReturn(func); let hasReturnOfTypeNever = false; forEachReturnStatement(func.body, returnStatement => { const expr = returnStatement.expression; @@ -11820,7 +11984,7 @@ namespace ts { // If all we have is a function signature, or an arrow function with an expression body, then there is nothing to check. // also if HasImplicitReturn flag is not set this means that all codepaths in function body end with return or throw - if (nodeIsMissing(func.body) || func.body.kind !== SyntaxKind.Block || !(func.flags & NodeFlags.HasImplicitReturn)) { + if (nodeIsMissing(func.body) || func.body.kind !== SyntaxKind.Block || !functionHasImplicitReturn(func)) { return; } @@ -12598,7 +12762,7 @@ namespace ts { function checkStringLiteralExpression(node: StringLiteral): Type { const contextualType = getContextualType(node); - if (contextualType && contextualTypeIsStringLiteralType(contextualType)) { + if (contextualType && isStringLiteralUnionType(contextualType)) { return getStringLiteralTypeForText(node.text); } @@ -13555,9 +13719,6 @@ namespace ts { } } - // when checking exported function declarations across modules check only duplicate implementations - // names and consistency of modifiers are verified when we check local symbol - const isExportSymbolInsideModule = symbol.parent && symbol.parent.flags & SymbolFlags.Module; let duplicateFunctionDeclaration = false; let multipleConstructorImplementation = false; for (const current of declarations) { @@ -13590,7 +13751,7 @@ namespace ts { duplicateFunctionDeclaration = true; } } - else if (!isExportSymbolInsideModule && previousDeclaration && previousDeclaration.parent === node.parent && previousDeclaration.end !== node.pos) { + else if (previousDeclaration && previousDeclaration.parent === node.parent && previousDeclaration.end !== node.pos) { reportImplementationExpectedError(previousDeclaration); } @@ -13624,7 +13785,7 @@ namespace ts { } // Abstract methods can't have an implementation -- in particular, they don't need one. - if (!isExportSymbolInsideModule && lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body && + if (lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body && !(lastSeenNonAmbientDeclaration.flags & NodeFlags.Abstract) && !lastSeenNonAmbientDeclaration.questionToken) { reportImplementationExpectedError(lastSeenNonAmbientDeclaration); } diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 9cca35977be..2e0bfa8290a 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -412,6 +412,10 @@ namespace ts { }, description: Diagnostics.Specify_library_files_to_be_included_in_the_compilation_Colon }, + { + name: "disableProjectSizeLimit", + type: "boolean" + }, { name: "strictNullChecks", type: "boolean", @@ -493,13 +497,20 @@ namespace ts { } /* @internal */ - export function parseListTypeOption(opt: CommandLineOptionOfListType, value: string, errors: Diagnostic[]): (string | number)[] { - const values = trimString((value || "")).split(","); + export function parseListTypeOption(opt: CommandLineOptionOfListType, value = "", errors: Diagnostic[]): (string | number)[] | undefined { + value = trimString(value); + if (startsWith(value, "-")) { + return undefined; + } + if (value === "") { + return []; + } + const values = value.split(","); switch (opt.element.type) { case "number": - return ts.map(values, parseInt); + return map(values, parseInt); case "string": - return ts.map(values, v => v || ""); + return map(values, v => v || ""); default: return filter(map(values, v => parseCustomTypeOption(opt.element, v, errors)), v => !!v); } @@ -560,8 +571,11 @@ namespace ts { i++; break; case "list": - options[opt.name] = parseListTypeOption(opt, args[i], errors); - i++; + const result = parseListTypeOption(opt, args[i], errors); + options[opt.name] = result || []; + if (result) { + i++; + } break; // If not a primitive, the possible types are specified in what is effectively a map of options. default: diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index ef1e8cd358c..d3ecb1715a9 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1935,6 +1935,10 @@ "category": "Error", "code": 2688 }, + "Cannot extend an interface '{0}'. Did you mean 'implements'?": { + "category": "Error", + "code": 2689 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", "code": 4000 @@ -2929,10 +2933,6 @@ "category": "Error", "code": 8012 }, - "'property declarations' can only be used in a .ts file.": { - "category": "Error", - "code": 8014 - }, "'enum declarations' can only be used in a .ts file.": { "category": "Error", "code": 8015 diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 46362bd7827..101778e7322 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2076,7 +2076,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge function createPropertyAccessExpression(expression: Expression, name: Identifier): PropertyAccessExpression { const result = createSynthesizedNode(SyntaxKind.PropertyAccessExpression); result.expression = parenthesizeForAccess(expression); - result.dotToken = createSynthesizedNode(SyntaxKind.DotToken); result.name = name; return result; } @@ -2150,9 +2149,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } // Return true if identifier resolves to an exported member of a namespace - function isNamespaceExportReference(node: Identifier) { + function isExportReference(node: Identifier) { const container = resolver.getReferencedExportContainer(node); - return container && container.kind !== SyntaxKind.SourceFile; + return !!container; } // Return true if identifier resolves to an imported identifier @@ -2185,10 +2184,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge // const foo_1 = require('./foo'); // exports.baz = { foo: foo_1.foo }; // - if (languageVersion < ScriptTarget.ES6 || (modulekind !== ModuleKind.ES6 && isImportedReference(node.name)) || isNamespaceExportReference(node.name) ) { + if (languageVersion < ScriptTarget.ES6 || (modulekind !== ModuleKind.ES6 && isImportedReference(node.name)) || isExportReference(node.name)) { // Emit identifier as an identifier write(": "); - emit(node.name); + emitExpressionIdentifier(node.name); } if (languageVersion >= ScriptTarget.ES6 && node.objectAssignmentInitializer) { @@ -2223,11 +2222,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge // Returns 'true' if the code was actually indented, false otherwise. // If the code is not indented, an optional valueToWriteWhenNotIndenting will be // emitted instead. - function indentIfOnDifferentLines(parent: Node, node1: Node, node2: Node, valueToWriteWhenNotIndenting?: string): boolean { + function indentIfOnDifferentLines(parent: Node, node1: TextRange, node2: TextRange, valueToWriteWhenNotIndenting?: string): boolean { const realNodesAreOnDifferentLines = !nodeIsSynthesized(parent) && !nodeEndIsOnSameLineAsNodeStart(node1, node2); // Always use a newline for synthesized code if the synthesizer desires it. - const synthesizedNodeIsOnDifferentLine = synthesizedNodeStartsOnNewLine(node2); + const synthesizedNodeIsOnDifferentLine = synthesizedNodeStartsOnNewLine(node2 as Node); if (realNodesAreOnDifferentLines || synthesizedNodeIsOnDifferentLine) { increaseIndent(); @@ -2257,7 +2256,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } emit(node.expression); - const indentedBeforeDot = indentIfOnDifferentLines(node, node.expression, node.dotToken); + const dotRangeStart = nodeIsSynthesized(node.expression) ? -1 : node.expression.end; + const dotRangeEnd = nodeIsSynthesized(node.expression) ? -1 : skipTrivia(currentText, node.expression.end) + 1; + const dotToken = { pos: dotRangeStart, end: dotRangeEnd }; + const indentedBeforeDot = indentIfOnDifferentLines(node, node.expression, dotToken); // 1 .toString is a valid property access, emit a space after the literal // Also emit a space if expression is a integer const enum value - it will appear in generated code as numeric literal @@ -2283,7 +2285,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge write("."); } - const indentedAfterDot = indentIfOnDifferentLines(node, node.dotToken, node.name); + const indentedAfterDot = indentIfOnDifferentLines(node, dotToken, node.name); emit(node.name); decreaseIndentIf(indentedBeforeDot, indentedAfterDot); } @@ -2780,7 +2782,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge const identifier = emitTempVariableAssignment(leftHandSideExpression.expression, /*canDefineTempVariablesInPlace*/ false, /*shouldEmitCommaBeforeAssignment*/ false); synthesizedLHS.expression = identifier; - (synthesizedLHS).dotToken = leftHandSideExpression.dotToken; (synthesizedLHS).name = leftHandSideExpression.name; write(", "); } @@ -3758,7 +3759,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge getLineOfLocalPositionFromLineMap(currentLineMap, node2.end); } - function nodeEndIsOnSameLineAsNodeStart(node1: Node, node2: Node) { + function nodeEndIsOnSameLineAsNodeStart(node1: TextRange, node2: TextRange) { return getLineOfLocalPositionFromLineMap(currentLineMap, node1.end) === getLineOfLocalPositionFromLineMap(currentLineMap, skipTrivia(currentText, node2.pos)); } @@ -6133,10 +6134,10 @@ const _super = (function (geti, seti) { if (parameters[i].dotDotDotToken) { let parameterType = parameters[i].type; - if (parameterType.kind === SyntaxKind.ArrayType) { + if (parameterType && parameterType.kind === SyntaxKind.ArrayType) { parameterType = (parameterType).elementType; } - else if (parameterType.kind === SyntaxKind.TypeReference && (parameterType).typeArguments && (parameterType).typeArguments.length === 1) { + else if (parameterType && parameterType.kind === SyntaxKind.TypeReference && (parameterType).typeArguments && (parameterType).typeArguments.length === 1) { parameterType = (parameterType).typeArguments[0]; } else { @@ -6156,9 +6157,15 @@ const _super = (function (geti, seti) { /** Serializes the return type of function. Used by the __metadata decorator for a method. */ function emitSerializedReturnTypeOfNode(node: Node) { - if (node && isFunctionLike(node) && (node).type) { - emitSerializedTypeNode((node).type); - return; + if (node && isFunctionLike(node)) { + if ((node).type) { + emitSerializedTypeNode((node).type); + return; + } + else if (isAsyncFunctionLike(node)) { + write("Promise"); + return; + } } write("void 0"); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index a31cf0cbe93..b2f3755ec46 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -137,7 +137,6 @@ namespace ts { return visitNodes(cbNodes, (node).properties); case SyntaxKind.PropertyAccessExpression: return visitNode(cbNode, (node).expression) || - visitNode(cbNode, (node).dotToken) || visitNode(cbNode, (node).name); case SyntaxKind.ElementAccessExpression: return visitNode(cbNode, (node).expression) || @@ -3571,7 +3570,7 @@ namespace ts { // If it wasn't then just try to parse out a '.' and report an error. const node = createNode(SyntaxKind.PropertyAccessExpression, expression.pos); node.expression = expression; - node.dotToken = parseExpectedToken(SyntaxKind.DotToken, /*reportAtCurrentPosition*/ false, Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access); + parseExpectedToken(SyntaxKind.DotToken, /*reportAtCurrentPosition*/ false, Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access); node.name = parseRightSideOfDot(/*allowIdentifierNames*/ true); return finishNode(node); } @@ -3807,7 +3806,6 @@ namespace ts { if (dotToken) { const propertyAccess = createNode(SyntaxKind.PropertyAccessExpression, expression.pos); propertyAccess.expression = expression; - propertyAccess.dotToken = dotToken; propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true); expression = finishNode(propertyAccess); continue; diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 15afbe18265..111343e08ff 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1601,8 +1601,19 @@ namespace ts { } break; case SyntaxKind.PropertyDeclaration: - diagnostics.push(createDiagnosticForNode(node, Diagnostics.property_declarations_can_only_be_used_in_a_ts_file)); - return true; + const propertyDeclaration = node; + if (propertyDeclaration.modifiers) { + for (const modifier of propertyDeclaration.modifiers) { + if (modifier.kind !== SyntaxKind.StaticKeyword) { + diagnostics.push(createDiagnosticForNode(modifier, Diagnostics._0_can_only_be_used_in_a_ts_file, tokenToString(modifier.kind))); + return true; + } + } + } + if (checkTypeAnnotation((node).type)) { + return true; + } + break; case SyntaxKind.EnumDeclaration: diagnostics.push(createDiagnosticForNode(node, Diagnostics.enum_declarations_can_only_be_used_in_a_ts_file)); return true; diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index 8b977c53111..338b6de1e63 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -15,6 +15,7 @@ namespace ts { useCaseSensitiveFileNames: boolean; write(s: string): void; readFile(path: string, encoding?: string): string; + getFileSize?(path: string): number; writeFile(path: string, data: string, writeByteOrderMark?: boolean): void; watchFile?(path: string, callback: FileWatcherCallback): FileWatcher; watchDirectory?(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher; @@ -79,7 +80,7 @@ namespace ts { realpath(path: string): string; }; - export var sys: System = (function () { + export var sys: System = (function() { function getWScriptSystem(): System { @@ -494,7 +495,7 @@ namespace ts { } ); }, - resolvePath: function (path: string): string { + resolvePath: function(path: string): string { return _path.resolve(path); }, fileExists, @@ -531,6 +532,16 @@ namespace ts { } return process.memoryUsage().heapUsed; }, + getFileSize(path) { + try { + const stat = _fs.statSync(path); + if (stat.isFile()) { + return stat.size; + } + } + catch (e) { } + return 0; + }, exit(exitCode?: number): void { process.exit(exitCode); }, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 97979364729..f3549aa3815 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -980,7 +980,6 @@ namespace ts { // @kind(SyntaxKind.PropertyAccessExpression) export interface PropertyAccessExpression extends MemberExpression, Declaration { expression: LeftHandSideExpression; - dotToken: Node; name: Identifier; } @@ -1188,6 +1187,7 @@ namespace ts { export interface SwitchStatement extends Statement { expression: Expression; caseBlock: CaseBlock; + possiblyExhaustive?: boolean; } // @kind(SyntaxKind.CaseBlock) @@ -1554,8 +1554,9 @@ namespace ts { Assignment = 1 << 4, // Assignment TrueCondition = 1 << 5, // Condition known to be true FalseCondition = 1 << 6, // Condition known to be false - Referenced = 1 << 7, // Referenced as antecedent once - Shared = 1 << 8, // Referenced as antecedent more than once + SwitchClause = 1 << 7, // Switch statement clause + Referenced = 1 << 8, // Referenced as antecedent once + Shared = 1 << 9, // Referenced as antecedent more than once Label = BranchLabel | LoopLabel, Condition = TrueCondition | FalseCondition } @@ -1591,6 +1592,13 @@ namespace ts { antecedent: FlowNode; } + export interface FlowSwitchClause extends FlowNode { + switchStatement: SwitchStatement; + clauseStart: number; // Start index of case/default clause range + clauseEnd: number; // End index of case/default clause range + antecedent: FlowNode; + } + export interface AmdDependency { path: string; name: string; @@ -2193,6 +2201,7 @@ namespace ts { resolvedJsxType?: Type; // resolved element attributes type of a JSX openinglike element hasSuperCall?: boolean; // recorded result when we try to find super-call. We only try to find one if this flag is undefined, indicating that we haven't made an attempt. superCall?: ExpressionStatement; // Cached first super-call found in the constructor. Used in checking whether super is called before this-accessing + switchTypes?: Type[]; // Cached array of switch case expression types } export const enum TypeFlags { @@ -2232,7 +2241,8 @@ namespace ts { /* @internal */ Nullable = Undefined | Null, - Falsy = String | Number | Boolean | Void | Undefined | Null, + /* @internal */ + Falsy = Void | Undefined | Null, // TODO: Add false, 0, and "" /* @internal */ Intrinsic = Any | String | Number | Boolean | ESSymbol | Void | Undefined | Null | Never, /* @internal */ @@ -2569,6 +2579,7 @@ namespace ts { /* @internal */ suppressOutputPathCheck?: boolean; target?: ScriptTarget; traceResolution?: boolean; + disableSizeLimit?: boolean; types?: string[]; /** Paths used to used to compute primary types search locations */ typeRoots?: string[]; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index b4f00917b1f..31b464b81ce 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1264,6 +1264,18 @@ namespace ts { return charCode === CharacterCodes.singleQuote || charCode === CharacterCodes.doubleQuote; } + /** + * Returns true if the node is a variable declaration whose initializer is a function expression. + * This function does not test if the node is in a JavaScript file or not. + */ + export function isDeclarationOfFunctionExpression(s: Symbol) { + if (s.valueDeclaration && s.valueDeclaration.kind === SyntaxKind.VariableDeclaration) { + const declaration = s.valueDeclaration as VariableDeclaration; + return declaration.initializer && declaration.initializer.kind === SyntaxKind.FunctionExpression; + } + return false; + } + /// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property /// assignments we treat as special in the binder export function getSpecialPropertyAssignmentKind(expression: Node): SpecialPropertyAssignmentKind { @@ -2702,6 +2714,10 @@ namespace ts { return forEach(supportedJavascriptExtensions, extension => fileExtensionIs(fileName, extension)); } + export function hasTypeScriptFileExtension(fileName: string) { + return forEach(supportedTypeScriptExtensions, extension => fileExtensionIs(fileName, extension)); + } + /** * Replace each instance of non-ascii characters by one, two, three, or four escape sequences * representing the UTF-8 encoding of the character, and return the expanded char code list. diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 8104f113392..695e19b4667 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -717,6 +717,8 @@ namespace FourSlash { public verifyCompletionEntryDetails(entryName: string, expectedText: string, expectedDocumentation?: string, kind?: string) { const details = this.getCompletionEntryDetails(entryName); + assert(details, "no completion entry available"); + assert.equal(ts.displayPartsToString(details.displayParts), expectedText, this.assertionMessageAtLastKnownMarker("completion entry details text")); if (expectedDocumentation !== undefined) { @@ -728,27 +730,6 @@ namespace FourSlash { } } - public verifyReferencesAtPositionListContains(fileName: string, start: number, end: number, isWriteAccess?: boolean) { - const references = this.getReferencesAtCaret(); - - if (!references || references.length === 0) { - this.raiseError("verifyReferencesAtPositionListContains failed - found 0 references, expected at least one."); - } - - for (let i = 0; i < references.length; i++) { - const reference = references[i]; - if (reference && reference.fileName === fileName && reference.textSpan.start === start && ts.textSpanEnd(reference.textSpan) === end) { - if (typeof isWriteAccess !== "undefined" && reference.isWriteAccess !== isWriteAccess) { - this.raiseError(`verifyReferencesAtPositionListContains failed - item isWriteAccess value does not match, actual: ${reference.isWriteAccess}, expected: ${isWriteAccess}.`); - } - return; - } - } - - const missingItem = { fileName: fileName, start: start, end: end, isWriteAccess: isWriteAccess }; - this.raiseError(`verifyReferencesAtPositionListContains failed - could not find the item: ${stringify(missingItem)} in the returned list: (${stringify(references)})`); - } - public verifyReferencesCountIs(count: number, localFilesOnly = true) { const references = this.getReferencesAtCaret(); let referencesCount = 0; @@ -772,6 +753,73 @@ namespace FourSlash { } } + public verifyReferencesAre(expectedReferences: Range[]) { + const actualReferences = this.getReferencesAtCaret() || []; + + if (actualReferences.length > expectedReferences.length) { + // Find the unaccounted-for reference. + for (const actual of actualReferences) { + if (!ts.forEach(expectedReferences, r => r.start === actual.textSpan.start)) { + this.raiseError(`A reference ${actual} is unaccounted for.`); + } + } + // Probably will never reach here. + this.raiseError(`There are ${actualReferences.length} references but only ${expectedReferences.length} were expected.`); + } + + for (const reference of expectedReferences) { + const {fileName, start, end} = reference; + if (reference.marker) { + const {isWriteAccess, isDefinition} = reference.marker.data; + this.verifyReferencesWorker(actualReferences, fileName, start, end, isWriteAccess, isDefinition); + } + else { + this.verifyReferencesWorker(actualReferences, fileName, start, end); + } + } + } + + public verifyReferencesOf({fileName, start}: Range, references: Range[]) { + this.openFile(fileName); + this.goToPosition(start); + this.verifyReferencesAre(references); + } + + public verifyRangesReferenceEachOther(ranges?: Range[]) { + ranges = ranges || this.getRanges(); + assert(ranges.length); + for (const range of ranges) { + this.verifyReferencesOf(range, ranges); + } + } + + public verifyReferencesAtPositionListContains(fileName: string, start: number, end: number, isWriteAccess?: boolean, isDefinition?: boolean) { + const references = this.getReferencesAtCaret(); + if (!references || references.length === 0) { + this.raiseError("verifyReferencesAtPositionListContains failed - found 0 references, expected at least one."); + } + this.verifyReferencesWorker(references, fileName, start, end, isWriteAccess, isDefinition); + } + + private verifyReferencesWorker(references: ts.ReferenceEntry[], fileName: string, start: number, end: number, isWriteAccess?: boolean, isDefinition?: boolean) { + for (let i = 0; i < references.length; i++) { + const reference = references[i]; + if (reference && reference.fileName === fileName && reference.textSpan.start === start && ts.textSpanEnd(reference.textSpan) === end) { + if (typeof isWriteAccess !== "undefined" && reference.isWriteAccess !== isWriteAccess) { + this.raiseError(`verifyReferencesAtPositionListContains failed - item isWriteAccess value does not match, actual: ${reference.isWriteAccess}, expected: ${isWriteAccess}.`); + } + if (typeof isDefinition !== "undefined" && reference.isDefinition !== isDefinition) { + this.raiseError(`verifyReferencesAtPositionListContains failed - item isDefinition value does not match, actual: ${reference.isDefinition}, expected: ${isDefinition}.`); + } + return; + } + } + + const missingItem = { fileName, start, end, isWriteAccess, isDefinition }; + this.raiseError(`verifyReferencesAtPositionListContains failed - could not find the item: ${stringify(missingItem)} in the returned list: (${stringify(references)})`); + + } + private getMemberListAtCaret() { return this.languageService.getCompletionsAtPosition(this.activeFile.fileName, this.currentCaretPosition); } @@ -2831,14 +2879,6 @@ namespace FourSlashInterface { this.state.verifyMemberListIsEmpty(this.negative); } - public referencesCountIs(count: number) { - this.state.verifyReferencesCountIs(count, /*localFilesOnly*/ false); - } - - public referencesAtPositionContains(range: FourSlash.Range, isWriteAccess?: boolean) { - this.state.verifyReferencesAtPositionListContains(range.fileName, range.start, range.end, isWriteAccess); - } - public signatureHelpPresent() { this.state.verifySignatureHelpPresent(!this.negative); } @@ -2930,6 +2970,22 @@ namespace FourSlashInterface { this.state.verifyGetEmitOutputContentsForCurrentFile(expected); } + public referencesCountIs(count: number) { + this.state.verifyReferencesCountIs(count, /*localFilesOnly*/ false); + } + + public referencesAre(ranges: FourSlash.Range[]) { + this.state.verifyReferencesAre(ranges); + } + + public referencesOf(start: FourSlash.Range, references: FourSlash.Range[]) { + this.state.verifyReferencesOf(start, references); + } + + public rangesReferenceEachOther(ranges?: FourSlash.Range[]) { + this.state.verifyRangesReferenceEachOther(ranges); + } + public currentParameterHelpArgumentNameIs(name: string) { this.state.verifyCurrentParameterHelpName(name); } diff --git a/src/lib/dom.generated.d.ts b/src/lib/dom.generated.d.ts index 5865e485754..40cd883af61 100644 --- a/src/lib/dom.generated.d.ts +++ b/src/lib/dom.generated.d.ts @@ -4,7 +4,7 @@ ///////////////////////////// interface Algorithm { - name?: string; + name: string; } interface AriaRequestEventInit extends EventInit { @@ -851,6 +851,7 @@ interface UIEventInit extends EventInit { } interface WebGLContextAttributes { + failIfMajorPerformanceCaveat?: boolean; alpha?: boolean; depth?: boolean; stencil?: boolean; @@ -919,7 +920,7 @@ interface ApplicationCache extends EventTarget { oncached: (ev: Event) => any; onchecking: (ev: Event) => any; ondownloading: (ev: Event) => any; - onerror: (ev: Event) => any; + onerror: (ev: ErrorEvent) => any; onnoupdate: (ev: Event) => any; onobsolete: (ev: Event) => any; onprogress: (ev: ProgressEvent) => any; @@ -2410,7 +2411,7 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven * Fires when the user aborts the download. * @param ev The event. */ - onabort: (ev: Event) => any; + onabort: (ev: UIEvent) => any; /** * Fires when the object is set as the active element. * @param ev The event. @@ -2512,7 +2513,7 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven * Fires when an error occurs during object loading. * @param ev The event. */ - onerror: (ev: Event) => any; + onerror: (ev: ErrorEvent) => any; /** * Fires when the object receives focus. * @param ev The event. @@ -2988,7 +2989,7 @@ interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEven * Returns a reference to the first object with the specified value of the ID or NAME attribute. * @param elementId String that specifies the ID value. Case-insensitive. */ - getElementById(elementId: string): HTMLElement; + getElementById(elementId: string): HTMLElement | null; getElementsByClassName(classNames: string): HTMLCollectionOf; /** * Gets a collection of objects based on the value of the NAME or ID attribute. @@ -3463,7 +3464,7 @@ interface Element extends Node, GlobalEventHandlers, ElementTraversal, NodeSelec readonly scrollWidth: number; readonly tagName: string; innerHTML: string; - getAttribute(name?: string): string | null; + getAttribute(name: string): string | null; getAttributeNS(namespaceURI: string, localName: string): string; getAttributeNode(name: string): Attr; getAttributeNodeNS(namespaceURI: string, localName: string): Attr; @@ -3673,6 +3674,7 @@ interface Element extends Node, GlobalEventHandlers, ElementTraversal, NodeSelec webkitRequestFullscreen(): void; getElementsByClassName(classNames: string): NodeListOf; matches(selector: string): boolean; + closest(selector: string): Element | null; addEventListener(type: "MSGestureChange", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void; addEventListener(type: "MSGestureDoubleTap", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void; addEventListener(type: "MSGestureEnd", listener: (ev: MSGestureEvent) => any, useCapture?: boolean): void; @@ -4203,7 +4205,7 @@ interface HTMLBodyElement extends HTMLElement { onbeforeprint: (ev: Event) => any; onbeforeunload: (ev: BeforeUnloadEvent) => any; onblur: (ev: FocusEvent) => any; - onerror: (ev: Event) => any; + onerror: (ev: ErrorEvent) => any; onfocus: (ev: FocusEvent) => any; onhashchange: (ev: HashChangeEvent) => any; onload: (ev: Event) => any; @@ -4432,9 +4434,9 @@ interface HTMLCanvasElement extends HTMLElement { * Returns an object that provides methods and properties for drawing and manipulating images and graphics on a canvas element in a document. A context object includes information about colors, line widths, fonts, and other graphic parameters that can be drawn on a canvas. * @param contextId The identifier (ID) of the type of canvas to create. Internet Explorer 9 and Internet Explorer 10 support only a 2-D context using canvas.getContext("2d"); IE11 Preview also supports 3-D or WebGL context using canvas.getContext("experimental-webgl"); */ - getContext(contextId: "2d"): CanvasRenderingContext2D; - getContext(contextId: "experimental-webgl"): WebGLRenderingContext; - getContext(contextId: string, ...args: any[]): CanvasRenderingContext2D | WebGLRenderingContext; + getContext(contextId: "2d", contextAttributes?: Canvas2DContextAttributes): CanvasRenderingContext2D | null; + getContext(contextId: "webgl" | "experimental-webgl", contextAttributes?: WebGLContextAttributes): WebGLRenderingContext | null; + getContext(contextId: string, contextAttributes?: {}): CanvasRenderingContext2D | WebGLRenderingContext | null; /** * Returns a blob object encoded as a Portable Network Graphics (PNG) format from a canvas image or drawing. */ @@ -4444,7 +4446,7 @@ interface HTMLCanvasElement extends HTMLElement { * @param type The standard MIME type for the image format to return. If you do not specify this parameter, the default value is a PNG format image. */ toDataURL(type?: string, ...args: any[]): string; - toBlob(): Blob; + toBlob(callback: (result: Blob | null) => void, ... arguments: any[]): void; } declare var HTMLCanvasElement: { @@ -4542,7 +4544,7 @@ interface HTMLElement extends Element { readonly offsetParent: Element; readonly offsetTop: number; readonly offsetWidth: number; - onabort: (ev: Event) => any; + onabort: (ev: UIEvent) => any; onactivate: (ev: UIEvent) => any; onbeforeactivate: (ev: UIEvent) => any; onbeforecopy: (ev: ClipboardEvent) => any; @@ -4570,7 +4572,7 @@ interface HTMLElement extends Element { ondurationchange: (ev: Event) => any; onemptied: (ev: Event) => any; onended: (ev: MediaStreamErrorEvent) => any; - onerror: (ev: Event) => any; + onerror: (ev: ErrorEvent) => any; onfocus: (ev: FocusEvent) => any; oninput: (ev: Event) => any; oninvalid: (ev: Event) => any; @@ -5120,7 +5122,7 @@ interface HTMLFrameSetElement extends HTMLElement { * Fires when the object loses the input focus. */ onblur: (ev: FocusEvent) => any; - onerror: (ev: Event) => any; + onerror: (ev: ErrorEvent) => any; /** * Fires when the object receives focus. */ @@ -5643,7 +5645,7 @@ interface HTMLInputElement extends HTMLElement { /** * Returns a FileList object on a file type input object. */ - readonly files: FileList; + readonly files: FileList | null; /** * Retrieves a reference to the form that the object is embedded in. */ @@ -6614,7 +6616,7 @@ declare var HTMLOptionElement: { create(): HTMLOptionElement; } -interface HTMLOptionsCollection extends HTMLCollection { +interface HTMLOptionsCollection extends HTMLCollectionOf { length: number; selectedIndex: number; add(element: HTMLOptionElement | HTMLOptGroupElement, before?: HTMLElement | number): void; @@ -6778,7 +6780,7 @@ interface HTMLSelectElement extends HTMLElement { * Sets or retrieves the name of the object. */ name: string; - options: HTMLCollectionOf; + readonly options: HTMLOptionsCollection; /** * When present, marks an element that can't be submitted without a value. */ @@ -7574,7 +7576,7 @@ interface IDBDatabase extends EventTarget { readonly name: string; readonly objectStoreNames: DOMStringList; onabort: (ev: Event) => any; - onerror: (ev: Event) => any; + onerror: (ev: ErrorEvent) => any; version: number; onversionchange: (ev: IDBVersionChangeEvent) => any; close(): void; @@ -7677,7 +7679,7 @@ declare var IDBOpenDBRequest: { interface IDBRequest extends EventTarget { readonly error: DOMError; - onerror: (ev: Event) => any; + onerror: (ev: ErrorEvent) => any; onsuccess: (ev: Event) => any; readonly readyState: string; readonly result: any; @@ -7699,7 +7701,7 @@ interface IDBTransaction extends EventTarget { readonly mode: string; onabort: (ev: Event) => any; oncomplete: (ev: Event) => any; - onerror: (ev: Event) => any; + onerror: (ev: ErrorEvent) => any; abort(): void; objectStore(name: string): IDBObjectStore; readonly READ_ONLY: string; @@ -7842,7 +7844,7 @@ declare var MSApp: MSApp; interface MSAppAsyncOperation extends EventTarget { readonly error: DOMError; oncomplete: (ev: Event) => any; - onerror: (ev: Event) => any; + onerror: (ev: ErrorEvent) => any; readonly readyState: number; readonly result: any; start(): void; @@ -8202,7 +8204,7 @@ declare var MSStreamReader: { interface MSWebViewAsyncOperation extends EventTarget { readonly error: DOMError; oncomplete: (ev: Event) => any; - onerror: (ev: Event) => any; + onerror: (ev: ErrorEvent) => any; readonly readyState: number; readonly result: any; readonly target: MSHTMLWebViewElement; @@ -8738,7 +8740,7 @@ interface Node extends EventTarget { contains(child: Node): boolean; hasAttributes(): boolean; hasChildNodes(): boolean; - insertBefore(newChild: Node, refChild: Node): Node; + insertBefore(newChild: Node, refChild: Node | null): Node; isDefaultNamespace(namespaceURI: string | null): boolean; isEqualNode(arg: Node): boolean; isSameNode(other: Node): boolean; @@ -8747,7 +8749,6 @@ interface Node extends EventTarget { normalize(): void; removeChild(oldChild: Node): Node; replaceChild(newChild: Node, oldChild: Node): Node; - contains(node: Node): boolean; readonly ATTRIBUTE_NODE: number; readonly CDATA_SECTION_NODE: number; readonly COMMENT_NODE: number; @@ -9283,7 +9284,7 @@ declare var RTCDTMFToneChangeEvent: { interface RTCDtlsTransport extends RTCStatsProvider { ondtlsstatechange: ((ev: RTCDtlsTransportStateChangedEvent) => any) | null; - onerror: ((ev: Event) => any) | null; + onerror: ((ev: ErrorEvent) => any) | null; readonly state: string; readonly transport: RTCIceTransport; getLocalParameters(): RTCDtlsParameters; @@ -9338,7 +9339,7 @@ declare var RTCIceCandidatePairChangedEvent: { interface RTCIceGatherer extends RTCStatsProvider { readonly component: string; - onerror: ((ev: Event) => any) | null; + onerror: ((ev: ErrorEvent) => any) | null; onlocalcandidate: ((ev: RTCIceGathererEvent) => any) | null; createAssociatedGatherer(): RTCIceGatherer; getLocalCandidates(): RTCIceCandidate[]; @@ -9397,7 +9398,7 @@ declare var RTCIceTransportStateChangedEvent: { } interface RTCRtpReceiver extends RTCStatsProvider { - onerror: ((ev: Event) => any) | null; + onerror: ((ev: ErrorEvent) => any) | null; readonly rtcpTransport: RTCDtlsTransport; readonly track: MediaStreamTrack | null; readonly transport: RTCDtlsTransport | RTCSrtpSdesTransport; @@ -9417,7 +9418,7 @@ declare var RTCRtpReceiver: { } interface RTCRtpSender extends RTCStatsProvider { - onerror: ((ev: Event) => any) | null; + onerror: ((ev: ErrorEvent) => any) | null; onssrcconflict: ((ev: RTCSsrcConflictEvent) => any) | null; readonly rtcpTransport: RTCDtlsTransport; readonly track: MediaStreamTrack; @@ -9438,7 +9439,7 @@ declare var RTCRtpSender: { } interface RTCSrtpSdesTransport extends EventTarget { - onerror: ((ev: Event) => any) | null; + onerror: ((ev: ErrorEvent) => any) | null; readonly transport: RTCIceTransport; addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; @@ -11478,18 +11479,24 @@ declare var StyleSheetPageList: { } interface SubtleCrypto { - decrypt(algorithm: string | Algorithm, key: CryptoKey, data: ArrayBufferView): PromiseLike; - deriveBits(algorithm: string | Algorithm, baseKey: CryptoKey, length: number): PromiseLike; - deriveKey(algorithm: string | Algorithm, baseKey: CryptoKey, derivedKeyType: string | Algorithm, extractable: boolean, keyUsages: string[]): PromiseLike; - digest(algorithm: string | Algorithm, data: ArrayBufferView): PromiseLike; - encrypt(algorithm: string | Algorithm, key: CryptoKey, data: ArrayBufferView): PromiseLike; - exportKey(format: string, key: CryptoKey): PromiseLike; - generateKey(algorithm: string | Algorithm, extractable: boolean, keyUsages: string[]): PromiseLike; - importKey(format: string, keyData: ArrayBufferView, algorithm: string | Algorithm | null, extractable: boolean, keyUsages: string[]): PromiseLike; - sign(algorithm: string | Algorithm, key: CryptoKey, data: ArrayBufferView): PromiseLike; - unwrapKey(format: string, wrappedKey: ArrayBufferView, unwrappingKey: CryptoKey, unwrapAlgorithm: string | Algorithm, unwrappedKeyAlgorithm: string | Algorithm | null, extractable: boolean, keyUsages: string[]): PromiseLike; - verify(algorithm: string | Algorithm, key: CryptoKey, signature: ArrayBufferView, data: ArrayBufferView): PromiseLike; - wrapKey(format: string, key: CryptoKey, wrappingKey: CryptoKey, wrapAlgorithm: string | Algorithm): PromiseLike; + decrypt(algorithm: string | RsaOaepParams | AesCtrParams | AesCbcParams | AesCmacParams | AesGcmParams | AesCfbParams, key: CryptoKey, data: BufferSource): PromiseLike; + deriveBits(algorithm: string | EcdhKeyDeriveParams | DhKeyDeriveParams | ConcatParams | HkdfCtrParams | Pbkdf2Params, baseKey: CryptoKey, length: number): PromiseLike; + deriveKey(algorithm: string | EcdhKeyDeriveParams | DhKeyDeriveParams | ConcatParams | HkdfCtrParams | Pbkdf2Params, baseKey: CryptoKey, derivedKeyType: string | AesDerivedKeyParams | HmacImportParams | ConcatParams | HkdfCtrParams | Pbkdf2Params, extractable: boolean, keyUsages: string[]): PromiseLike; + digest(algorithm: AlgorithmIdentifier, data: BufferSource): PromiseLike; + encrypt(algorithm: string | RsaOaepParams | AesCtrParams | AesCbcParams | AesCmacParams | AesGcmParams | AesCfbParams, key: CryptoKey, data: BufferSource): PromiseLike; + exportKey(format: "jwk", key: CryptoKey): PromiseLike; + exportKey(format: "raw" | "pkcs8" | "spki", key: CryptoKey): PromiseLike; + exportKey(format: string, key: CryptoKey): PromiseLike; + generateKey(algorithm: string, extractable: boolean, keyUsages: string[]): PromiseLike; + generateKey(algorithm: RsaHashedKeyGenParams | EcKeyGenParams | DhKeyGenParams, extractable: boolean, keyUsages: string[]): PromiseLike; + generateKey(algorithm: AesKeyGenParams | HmacKeyGenParams | Pbkdf2Params, extractable: boolean, keyUsages: string[]): PromiseLike; + importKey(format: "jwk", keyData: JsonWebKey, algorithm: string | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | DhImportKeyParams, extractable:boolean, keyUsages: string[]): PromiseLike; + importKey(format: "raw" | "pkcs8" | "spki", keyData: BufferSource, algorithm: string | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | DhImportKeyParams, extractable:boolean, keyUsages: string[]): PromiseLike; + importKey(format: string, keyData: JsonWebKey | BufferSource, algorithm: string | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | DhImportKeyParams, extractable:boolean, keyUsages: string[]): PromiseLike; + sign(algorithm: string | RsaPssParams | EcdsaParams | AesCmacParams, key: CryptoKey, data: BufferSource): PromiseLike; + unwrapKey(format: string, wrappedKey: BufferSource, unwrappingKey: CryptoKey, unwrapAlgorithm: AlgorithmIdentifier, unwrappedKeyAlgorithm: AlgorithmIdentifier, extractable: boolean, keyUsages: string[]): PromiseLike; + verify(algorithm: string | RsaPssParams | EcdsaParams | AesCmacParams, key: CryptoKey, signature: BufferSource, data: BufferSource): PromiseLike; + wrapKey(format: string, key: CryptoKey, wrappingKey: CryptoKey, wrapAlgorithm: AlgorithmIdentifier): PromiseLike; } declare var SubtleCrypto: { @@ -11557,7 +11564,7 @@ interface TextTrack extends EventTarget { readonly language: string; mode: any; oncuechange: (ev: Event) => any; - onerror: (ev: Event) => any; + onerror: (ev: ErrorEvent) => any; onload: (ev: Event) => any; readonly readyState: number; addCue(cue: TextTrackCue): void; @@ -12046,18 +12053,12 @@ interface WebGLRenderingContext { stencilMaskSeparate(face: number, mask: number): void; stencilOp(fail: number, zfail: number, zpass: number): void; stencilOpSeparate(face: number, fail: number, zfail: number, zpass: number): void; - texImage2D(target: number, level: number, internalformat: number, width: number, height: number, border: number, format: number, type: number, pixels: ArrayBufferView): void; - texImage2D(target: number, level: number, internalformat: number, format: number, type: number, image: HTMLImageElement): void; - texImage2D(target: number, level: number, internalformat: number, format: number, type: number, canvas: HTMLCanvasElement): void; - texImage2D(target: number, level: number, internalformat: number, format: number, type: number, video: HTMLVideoElement): void; - texImage2D(target: number, level: number, internalformat: number, format: number, type: number, pixels: ImageData): void; + texImage2D(target: number, level: number, internalformat: number, width: number, height: number, border: number, format: number, type: number, pixels?: ArrayBufferView): void; + texImage2D(target: number, level: number, internalformat: number, format: number, type: number, pixels?: ImageData | HTMLVideoElement | HTMLImageElement | HTMLCanvasElement): void; texParameterf(target: number, pname: number, param: number): void; texParameteri(target: number, pname: number, param: number): void; - texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, width: number, height: number, format: number, type: number, pixels: ArrayBufferView): void; - texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, image: HTMLImageElement): void; - texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, canvas: HTMLCanvasElement): void; - texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, video: HTMLVideoElement): void; - texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, pixels: ImageData): void; + texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, width: number, height: number, format: number, type: number, pixels?: ArrayBufferView): void; + texSubImage2D(target: number, level: number, xoffset: number, yoffset: number, format: number, type: number, pixels?: ImageData | HTMLVideoElement | HTMLImageElement | HTMLCanvasElement): void; uniform1f(location: WebGLUniformLocation | null, x: number): void; uniform1fv(location: WebGLUniformLocation, v: Float32Array | number[]): void; uniform1i(location: WebGLUniformLocation | null, x: number): void; @@ -12780,7 +12781,7 @@ interface WebSocket extends EventTarget { readonly bufferedAmount: number; readonly extensions: string; onclose: (ev: CloseEvent) => any; - onerror: (ev: Event) => any; + onerror: (ev: ErrorEvent) => any; onmessage: (ev: MessageEvent) => any; onopen: (ev: Event) => any; readonly protocol: string; @@ -12855,7 +12856,7 @@ interface Window extends EventTarget, WindowTimers, WindowSessionStorage, Window name: string; readonly navigator: Navigator; offscreenBuffering: string | boolean; - onabort: (ev: Event) => any; + onabort: (ev: UIEvent) => any; onafterprint: (ev: Event) => any; onbeforeprint: (ev: Event) => any; onbeforeunload: (ev: BeforeUnloadEvent) => any; @@ -12971,6 +12972,7 @@ interface Window extends EventTarget, WindowTimers, WindowSessionStorage, Window readonly top: Window; readonly window: Window; URL: typeof URL; + Blob: typeof Blob; alert(message?: any): void; blur(): void; cancelAnimationFrame(handle: number): void; @@ -13127,7 +13129,6 @@ declare var XMLDocument: { } interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget { - msCaching: string; onreadystatechange: (ev: ProgressEvent) => any; readonly readyState: number; readonly response: any; @@ -13139,6 +13140,7 @@ interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget { timeout: number; readonly upload: XMLHttpRequestUpload; withCredentials: boolean; + msCaching?: string; abort(): void; getAllResponseHeaders(): string; getResponseHeader(header: string): string | null; @@ -13277,7 +13279,7 @@ declare var XSLTProcessor: { } interface AbstractWorker { - onerror: (ev: Event) => any; + onerror: (ev: ErrorEvent) => any; addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } @@ -13436,7 +13438,7 @@ interface LinkStyle { interface MSBaseReader { onabort: (ev: Event) => any; - onerror: (ev: Event) => any; + onerror: (ev: ErrorEvent) => any; onload: (ev: Event) => any; onloadend: (ev: ProgressEvent) => any; onloadstart: (ev: Event) => any; @@ -13501,7 +13503,359 @@ interface NavigatorUserMedia { } interface NodeSelector { + querySelector(selectors: "a"): HTMLAnchorElement; + querySelector(selectors: "abbr"): HTMLElement; + querySelector(selectors: "acronym"): HTMLElement; + querySelector(selectors: "address"): HTMLElement; + querySelector(selectors: "applet"): HTMLAppletElement; + querySelector(selectors: "area"): HTMLAreaElement; + querySelector(selectors: "article"): HTMLElement; + querySelector(selectors: "aside"): HTMLElement; + querySelector(selectors: "audio"): HTMLAudioElement; + querySelector(selectors: "b"): HTMLElement; + querySelector(selectors: "base"): HTMLBaseElement; + querySelector(selectors: "basefont"): HTMLBaseFontElement; + querySelector(selectors: "bdo"): HTMLElement; + querySelector(selectors: "big"): HTMLElement; + querySelector(selectors: "blockquote"): HTMLQuoteElement; + querySelector(selectors: "body"): HTMLBodyElement; + querySelector(selectors: "br"): HTMLBRElement; + querySelector(selectors: "button"): HTMLButtonElement; + querySelector(selectors: "canvas"): HTMLCanvasElement; + querySelector(selectors: "caption"): HTMLTableCaptionElement; + querySelector(selectors: "center"): HTMLElement; + querySelector(selectors: "circle"): SVGCircleElement; + querySelector(selectors: "cite"): HTMLElement; + querySelector(selectors: "clippath"): SVGClipPathElement; + querySelector(selectors: "code"): HTMLElement; + querySelector(selectors: "col"): HTMLTableColElement; + querySelector(selectors: "colgroup"): HTMLTableColElement; + querySelector(selectors: "datalist"): HTMLDataListElement; + querySelector(selectors: "dd"): HTMLElement; + querySelector(selectors: "defs"): SVGDefsElement; + querySelector(selectors: "del"): HTMLModElement; + querySelector(selectors: "desc"): SVGDescElement; + querySelector(selectors: "dfn"): HTMLElement; + querySelector(selectors: "dir"): HTMLDirectoryElement; + querySelector(selectors: "div"): HTMLDivElement; + querySelector(selectors: "dl"): HTMLDListElement; + querySelector(selectors: "dt"): HTMLElement; + querySelector(selectors: "ellipse"): SVGEllipseElement; + querySelector(selectors: "em"): HTMLElement; + querySelector(selectors: "embed"): HTMLEmbedElement; + querySelector(selectors: "feblend"): SVGFEBlendElement; + querySelector(selectors: "fecolormatrix"): SVGFEColorMatrixElement; + querySelector(selectors: "fecomponenttransfer"): SVGFEComponentTransferElement; + querySelector(selectors: "fecomposite"): SVGFECompositeElement; + querySelector(selectors: "feconvolvematrix"): SVGFEConvolveMatrixElement; + querySelector(selectors: "fediffuselighting"): SVGFEDiffuseLightingElement; + querySelector(selectors: "fedisplacementmap"): SVGFEDisplacementMapElement; + querySelector(selectors: "fedistantlight"): SVGFEDistantLightElement; + querySelector(selectors: "feflood"): SVGFEFloodElement; + querySelector(selectors: "fefunca"): SVGFEFuncAElement; + querySelector(selectors: "fefuncb"): SVGFEFuncBElement; + querySelector(selectors: "fefuncg"): SVGFEFuncGElement; + querySelector(selectors: "fefuncr"): SVGFEFuncRElement; + querySelector(selectors: "fegaussianblur"): SVGFEGaussianBlurElement; + querySelector(selectors: "feimage"): SVGFEImageElement; + querySelector(selectors: "femerge"): SVGFEMergeElement; + querySelector(selectors: "femergenode"): SVGFEMergeNodeElement; + querySelector(selectors: "femorphology"): SVGFEMorphologyElement; + querySelector(selectors: "feoffset"): SVGFEOffsetElement; + querySelector(selectors: "fepointlight"): SVGFEPointLightElement; + querySelector(selectors: "fespecularlighting"): SVGFESpecularLightingElement; + querySelector(selectors: "fespotlight"): SVGFESpotLightElement; + querySelector(selectors: "fetile"): SVGFETileElement; + querySelector(selectors: "feturbulence"): SVGFETurbulenceElement; + querySelector(selectors: "fieldset"): HTMLFieldSetElement; + querySelector(selectors: "figcaption"): HTMLElement; + querySelector(selectors: "figure"): HTMLElement; + querySelector(selectors: "filter"): SVGFilterElement; + querySelector(selectors: "font"): HTMLFontElement; + querySelector(selectors: "footer"): HTMLElement; + querySelector(selectors: "foreignobject"): SVGForeignObjectElement; + querySelector(selectors: "form"): HTMLFormElement; + querySelector(selectors: "frame"): HTMLFrameElement; + querySelector(selectors: "frameset"): HTMLFrameSetElement; + querySelector(selectors: "g"): SVGGElement; + querySelector(selectors: "h1"): HTMLHeadingElement; + querySelector(selectors: "h2"): HTMLHeadingElement; + querySelector(selectors: "h3"): HTMLHeadingElement; + querySelector(selectors: "h4"): HTMLHeadingElement; + querySelector(selectors: "h5"): HTMLHeadingElement; + querySelector(selectors: "h6"): HTMLHeadingElement; + querySelector(selectors: "head"): HTMLHeadElement; + querySelector(selectors: "header"): HTMLElement; + querySelector(selectors: "hgroup"): HTMLElement; + querySelector(selectors: "hr"): HTMLHRElement; + querySelector(selectors: "html"): HTMLHtmlElement; + querySelector(selectors: "i"): HTMLElement; + querySelector(selectors: "iframe"): HTMLIFrameElement; + querySelector(selectors: "image"): SVGImageElement; + querySelector(selectors: "img"): HTMLImageElement; + querySelector(selectors: "input"): HTMLInputElement; + querySelector(selectors: "ins"): HTMLModElement; + querySelector(selectors: "isindex"): HTMLUnknownElement; + querySelector(selectors: "kbd"): HTMLElement; + querySelector(selectors: "keygen"): HTMLElement; + querySelector(selectors: "label"): HTMLLabelElement; + querySelector(selectors: "legend"): HTMLLegendElement; + querySelector(selectors: "li"): HTMLLIElement; + querySelector(selectors: "line"): SVGLineElement; + querySelector(selectors: "lineargradient"): SVGLinearGradientElement; + querySelector(selectors: "link"): HTMLLinkElement; + querySelector(selectors: "listing"): HTMLPreElement; + querySelector(selectors: "map"): HTMLMapElement; + querySelector(selectors: "mark"): HTMLElement; + querySelector(selectors: "marker"): SVGMarkerElement; + querySelector(selectors: "marquee"): HTMLMarqueeElement; + querySelector(selectors: "mask"): SVGMaskElement; + querySelector(selectors: "menu"): HTMLMenuElement; + querySelector(selectors: "meta"): HTMLMetaElement; + querySelector(selectors: "metadata"): SVGMetadataElement; + querySelector(selectors: "meter"): HTMLMeterElement; + querySelector(selectors: "nav"): HTMLElement; + querySelector(selectors: "nextid"): HTMLUnknownElement; + querySelector(selectors: "nobr"): HTMLElement; + querySelector(selectors: "noframes"): HTMLElement; + querySelector(selectors: "noscript"): HTMLElement; + querySelector(selectors: "object"): HTMLObjectElement; + querySelector(selectors: "ol"): HTMLOListElement; + querySelector(selectors: "optgroup"): HTMLOptGroupElement; + querySelector(selectors: "option"): HTMLOptionElement; + querySelector(selectors: "p"): HTMLParagraphElement; + querySelector(selectors: "param"): HTMLParamElement; + querySelector(selectors: "path"): SVGPathElement; + querySelector(selectors: "pattern"): SVGPatternElement; + querySelector(selectors: "picture"): HTMLPictureElement; + querySelector(selectors: "plaintext"): HTMLElement; + querySelector(selectors: "polygon"): SVGPolygonElement; + querySelector(selectors: "polyline"): SVGPolylineElement; + querySelector(selectors: "pre"): HTMLPreElement; + querySelector(selectors: "progress"): HTMLProgressElement; + querySelector(selectors: "q"): HTMLQuoteElement; + querySelector(selectors: "radialgradient"): SVGRadialGradientElement; + querySelector(selectors: "rect"): SVGRectElement; + querySelector(selectors: "rt"): HTMLElement; + querySelector(selectors: "ruby"): HTMLElement; + querySelector(selectors: "s"): HTMLElement; + querySelector(selectors: "samp"): HTMLElement; + querySelector(selectors: "script"): HTMLScriptElement; + querySelector(selectors: "section"): HTMLElement; + querySelector(selectors: "select"): HTMLSelectElement; + querySelector(selectors: "small"): HTMLElement; + querySelector(selectors: "source"): HTMLSourceElement; + querySelector(selectors: "span"): HTMLSpanElement; + querySelector(selectors: "stop"): SVGStopElement; + querySelector(selectors: "strike"): HTMLElement; + querySelector(selectors: "strong"): HTMLElement; + querySelector(selectors: "style"): HTMLStyleElement; + querySelector(selectors: "sub"): HTMLElement; + querySelector(selectors: "sup"): HTMLElement; + querySelector(selectors: "svg"): SVGSVGElement; + querySelector(selectors: "switch"): SVGSwitchElement; + querySelector(selectors: "symbol"): SVGSymbolElement; + querySelector(selectors: "table"): HTMLTableElement; + querySelector(selectors: "tbody"): HTMLTableSectionElement; + querySelector(selectors: "td"): HTMLTableDataCellElement; + querySelector(selectors: "template"): HTMLTemplateElement; + querySelector(selectors: "text"): SVGTextElement; + querySelector(selectors: "textpath"): SVGTextPathElement; + querySelector(selectors: "textarea"): HTMLTextAreaElement; + querySelector(selectors: "tfoot"): HTMLTableSectionElement; + querySelector(selectors: "th"): HTMLTableHeaderCellElement; + querySelector(selectors: "thead"): HTMLTableSectionElement; + querySelector(selectors: "title"): HTMLTitleElement; + querySelector(selectors: "tr"): HTMLTableRowElement; + querySelector(selectors: "track"): HTMLTrackElement; + querySelector(selectors: "tspan"): SVGTSpanElement; + querySelector(selectors: "tt"): HTMLElement; + querySelector(selectors: "u"): HTMLElement; + querySelector(selectors: "ul"): HTMLUListElement; + querySelector(selectors: "use"): SVGUseElement; + querySelector(selectors: "var"): HTMLElement; + querySelector(selectors: "video"): HTMLVideoElement; + querySelector(selectors: "view"): SVGViewElement; + querySelector(selectors: "wbr"): HTMLElement; + querySelector(selectors: "x-ms-webview"): MSHTMLWebViewElement; + querySelector(selectors: "xmp"): HTMLPreElement; querySelector(selectors: string): Element; + querySelectorAll(selectors: "a"): NodeListOf; + querySelectorAll(selectors: "abbr"): NodeListOf; + querySelectorAll(selectors: "acronym"): NodeListOf; + querySelectorAll(selectors: "address"): NodeListOf; + querySelectorAll(selectors: "applet"): NodeListOf; + querySelectorAll(selectors: "area"): NodeListOf; + querySelectorAll(selectors: "article"): NodeListOf; + querySelectorAll(selectors: "aside"): NodeListOf; + querySelectorAll(selectors: "audio"): NodeListOf; + querySelectorAll(selectors: "b"): NodeListOf; + querySelectorAll(selectors: "base"): NodeListOf; + querySelectorAll(selectors: "basefont"): NodeListOf; + querySelectorAll(selectors: "bdo"): NodeListOf; + querySelectorAll(selectors: "big"): NodeListOf; + querySelectorAll(selectors: "blockquote"): NodeListOf; + querySelectorAll(selectors: "body"): NodeListOf; + querySelectorAll(selectors: "br"): NodeListOf; + querySelectorAll(selectors: "button"): NodeListOf; + querySelectorAll(selectors: "canvas"): NodeListOf; + querySelectorAll(selectors: "caption"): NodeListOf; + querySelectorAll(selectors: "center"): NodeListOf; + querySelectorAll(selectors: "circle"): NodeListOf; + querySelectorAll(selectors: "cite"): NodeListOf; + querySelectorAll(selectors: "clippath"): NodeListOf; + querySelectorAll(selectors: "code"): NodeListOf; + querySelectorAll(selectors: "col"): NodeListOf; + querySelectorAll(selectors: "colgroup"): NodeListOf; + querySelectorAll(selectors: "datalist"): NodeListOf; + querySelectorAll(selectors: "dd"): NodeListOf; + querySelectorAll(selectors: "defs"): NodeListOf; + querySelectorAll(selectors: "del"): NodeListOf; + querySelectorAll(selectors: "desc"): NodeListOf; + querySelectorAll(selectors: "dfn"): NodeListOf; + querySelectorAll(selectors: "dir"): NodeListOf; + querySelectorAll(selectors: "div"): NodeListOf; + querySelectorAll(selectors: "dl"): NodeListOf; + querySelectorAll(selectors: "dt"): NodeListOf; + querySelectorAll(selectors: "ellipse"): NodeListOf; + querySelectorAll(selectors: "em"): NodeListOf; + querySelectorAll(selectors: "embed"): NodeListOf; + querySelectorAll(selectors: "feblend"): NodeListOf; + querySelectorAll(selectors: "fecolormatrix"): NodeListOf; + querySelectorAll(selectors: "fecomponenttransfer"): NodeListOf; + querySelectorAll(selectors: "fecomposite"): NodeListOf; + querySelectorAll(selectors: "feconvolvematrix"): NodeListOf; + querySelectorAll(selectors: "fediffuselighting"): NodeListOf; + querySelectorAll(selectors: "fedisplacementmap"): NodeListOf; + querySelectorAll(selectors: "fedistantlight"): NodeListOf; + querySelectorAll(selectors: "feflood"): NodeListOf; + querySelectorAll(selectors: "fefunca"): NodeListOf; + querySelectorAll(selectors: "fefuncb"): NodeListOf; + querySelectorAll(selectors: "fefuncg"): NodeListOf; + querySelectorAll(selectors: "fefuncr"): NodeListOf; + querySelectorAll(selectors: "fegaussianblur"): NodeListOf; + querySelectorAll(selectors: "feimage"): NodeListOf; + querySelectorAll(selectors: "femerge"): NodeListOf; + querySelectorAll(selectors: "femergenode"): NodeListOf; + querySelectorAll(selectors: "femorphology"): NodeListOf; + querySelectorAll(selectors: "feoffset"): NodeListOf; + querySelectorAll(selectors: "fepointlight"): NodeListOf; + querySelectorAll(selectors: "fespecularlighting"): NodeListOf; + querySelectorAll(selectors: "fespotlight"): NodeListOf; + querySelectorAll(selectors: "fetile"): NodeListOf; + querySelectorAll(selectors: "feturbulence"): NodeListOf; + querySelectorAll(selectors: "fieldset"): NodeListOf; + querySelectorAll(selectors: "figcaption"): NodeListOf; + querySelectorAll(selectors: "figure"): NodeListOf; + querySelectorAll(selectors: "filter"): NodeListOf; + querySelectorAll(selectors: "font"): NodeListOf; + querySelectorAll(selectors: "footer"): NodeListOf; + querySelectorAll(selectors: "foreignobject"): NodeListOf; + querySelectorAll(selectors: "form"): NodeListOf; + querySelectorAll(selectors: "frame"): NodeListOf; + querySelectorAll(selectors: "frameset"): NodeListOf; + querySelectorAll(selectors: "g"): NodeListOf; + querySelectorAll(selectors: "h1"): NodeListOf; + querySelectorAll(selectors: "h2"): NodeListOf; + querySelectorAll(selectors: "h3"): NodeListOf; + querySelectorAll(selectors: "h4"): NodeListOf; + querySelectorAll(selectors: "h5"): NodeListOf; + querySelectorAll(selectors: "h6"): NodeListOf; + querySelectorAll(selectors: "head"): NodeListOf; + querySelectorAll(selectors: "header"): NodeListOf; + querySelectorAll(selectors: "hgroup"): NodeListOf; + querySelectorAll(selectors: "hr"): NodeListOf; + querySelectorAll(selectors: "html"): NodeListOf; + querySelectorAll(selectors: "i"): NodeListOf; + querySelectorAll(selectors: "iframe"): NodeListOf; + querySelectorAll(selectors: "image"): NodeListOf; + querySelectorAll(selectors: "img"): NodeListOf; + querySelectorAll(selectors: "input"): NodeListOf; + querySelectorAll(selectors: "ins"): NodeListOf; + querySelectorAll(selectors: "isindex"): NodeListOf; + querySelectorAll(selectors: "kbd"): NodeListOf; + querySelectorAll(selectors: "keygen"): NodeListOf; + querySelectorAll(selectors: "label"): NodeListOf; + querySelectorAll(selectors: "legend"): NodeListOf; + querySelectorAll(selectors: "li"): NodeListOf; + querySelectorAll(selectors: "line"): NodeListOf; + querySelectorAll(selectors: "lineargradient"): NodeListOf; + querySelectorAll(selectors: "link"): NodeListOf; + querySelectorAll(selectors: "listing"): NodeListOf; + querySelectorAll(selectors: "map"): NodeListOf; + querySelectorAll(selectors: "mark"): NodeListOf; + querySelectorAll(selectors: "marker"): NodeListOf; + querySelectorAll(selectors: "marquee"): NodeListOf; + querySelectorAll(selectors: "mask"): NodeListOf; + querySelectorAll(selectors: "menu"): NodeListOf; + querySelectorAll(selectors: "meta"): NodeListOf; + querySelectorAll(selectors: "metadata"): NodeListOf; + querySelectorAll(selectors: "meter"): NodeListOf; + querySelectorAll(selectors: "nav"): NodeListOf; + querySelectorAll(selectors: "nextid"): NodeListOf; + querySelectorAll(selectors: "nobr"): NodeListOf; + querySelectorAll(selectors: "noframes"): NodeListOf; + querySelectorAll(selectors: "noscript"): NodeListOf; + querySelectorAll(selectors: "object"): NodeListOf; + querySelectorAll(selectors: "ol"): NodeListOf; + querySelectorAll(selectors: "optgroup"): NodeListOf; + querySelectorAll(selectors: "option"): NodeListOf; + querySelectorAll(selectors: "p"): NodeListOf; + querySelectorAll(selectors: "param"): NodeListOf; + querySelectorAll(selectors: "path"): NodeListOf; + querySelectorAll(selectors: "pattern"): NodeListOf; + querySelectorAll(selectors: "picture"): NodeListOf; + querySelectorAll(selectors: "plaintext"): NodeListOf; + querySelectorAll(selectors: "polygon"): NodeListOf; + querySelectorAll(selectors: "polyline"): NodeListOf; + querySelectorAll(selectors: "pre"): NodeListOf; + querySelectorAll(selectors: "progress"): NodeListOf; + querySelectorAll(selectors: "q"): NodeListOf; + querySelectorAll(selectors: "radialgradient"): NodeListOf; + querySelectorAll(selectors: "rect"): NodeListOf; + querySelectorAll(selectors: "rt"): NodeListOf; + querySelectorAll(selectors: "ruby"): NodeListOf; + querySelectorAll(selectors: "s"): NodeListOf; + querySelectorAll(selectors: "samp"): NodeListOf; + querySelectorAll(selectors: "script"): NodeListOf; + querySelectorAll(selectors: "section"): NodeListOf; + querySelectorAll(selectors: "select"): NodeListOf; + querySelectorAll(selectors: "small"): NodeListOf; + querySelectorAll(selectors: "source"): NodeListOf; + querySelectorAll(selectors: "span"): NodeListOf; + querySelectorAll(selectors: "stop"): NodeListOf; + querySelectorAll(selectors: "strike"): NodeListOf; + querySelectorAll(selectors: "strong"): NodeListOf; + querySelectorAll(selectors: "style"): NodeListOf; + querySelectorAll(selectors: "sub"): NodeListOf; + querySelectorAll(selectors: "sup"): NodeListOf; + querySelectorAll(selectors: "svg"): NodeListOf; + querySelectorAll(selectors: "switch"): NodeListOf; + querySelectorAll(selectors: "symbol"): NodeListOf; + querySelectorAll(selectors: "table"): NodeListOf; + querySelectorAll(selectors: "tbody"): NodeListOf; + querySelectorAll(selectors: "td"): NodeListOf; + querySelectorAll(selectors: "template"): NodeListOf; + querySelectorAll(selectors: "text"): NodeListOf; + querySelectorAll(selectors: "textpath"): NodeListOf; + querySelectorAll(selectors: "textarea"): NodeListOf; + querySelectorAll(selectors: "tfoot"): NodeListOf; + querySelectorAll(selectors: "th"): NodeListOf; + querySelectorAll(selectors: "thead"): NodeListOf; + querySelectorAll(selectors: "title"): NodeListOf; + querySelectorAll(selectors: "tr"): NodeListOf; + querySelectorAll(selectors: "track"): NodeListOf; + querySelectorAll(selectors: "tspan"): NodeListOf; + querySelectorAll(selectors: "tt"): NodeListOf; + querySelectorAll(selectors: "u"): NodeListOf; + querySelectorAll(selectors: "ul"): NodeListOf; + querySelectorAll(selectors: "use"): NodeListOf; + querySelectorAll(selectors: "var"): NodeListOf; + querySelectorAll(selectors: "video"): NodeListOf; + querySelectorAll(selectors: "view"): NodeListOf; + querySelectorAll(selectors: "wbr"): NodeListOf; + querySelectorAll(selectors: "x-ms-webview"): NodeListOf; + querySelectorAll(selectors: "xmp"): NodeListOf; querySelectorAll(selectors: string): NodeListOf; } @@ -13589,18 +13943,21 @@ interface WindowSessionStorage { interface WindowTimers extends Object, WindowTimersExtension { clearInterval(handle: number): void; clearTimeout(handle: number): void; + setInterval(handler: (...args: any[]) => void, timeout: number): number; setInterval(handler: any, timeout?: any, ...args: any[]): number; + setTimeout(handler: (...args: any[]) => void, timeout: number): number; setTimeout(handler: any, timeout?: any, ...args: any[]): number; } interface WindowTimersExtension { clearImmediate(handle: number): void; - setImmediate(expression: any, ...args: any[]): number; + setImmediate(handler: (...args: any[]) => void): number; + setImmediate(handler: any, ...args: any[]): number; } interface XMLHttpRequestEventTarget { onabort: (ev: Event) => any; - onerror: (ev: Event) => any; + onerror: (ev: ErrorEvent) => any; onload: (ev: Event) => any; onloadend: (ev: ProgressEvent) => any; onloadstart: (ev: Event) => any; @@ -13624,6 +13981,13 @@ interface StorageEventInit extends EventInit { storageArea?: Storage; } +interface Canvas2DContextAttributes { + alpha?: boolean; + willReadFrequently?: boolean; + storage?: boolean; + [attribute: string]: boolean | string; +} + interface NodeListOf extends NodeList { length: number; item(index: number): TNode; @@ -13673,6 +14037,177 @@ interface ClipboardEventInit extends EventInit { interface IDBArrayKey extends Array { } +interface RsaKeyGenParams extends Algorithm { + modulusLength: number; + publicExponent: Uint8Array; +} + +interface RsaHashedKeyGenParams extends RsaKeyGenParams { + hash: AlgorithmIdentifier; +} + +interface RsaKeyAlgorithm extends KeyAlgorithm { + modulusLength: number; + publicExponent: Uint8Array; +} + +interface RsaHashedKeyAlgorithm extends RsaKeyAlgorithm { + hash: AlgorithmIdentifier; +} + +interface RsaHashedImportParams { + hash: AlgorithmIdentifier; +} + +interface RsaPssParams { + saltLength: number; +} + +interface RsaOaepParams extends Algorithm { + label?: BufferSource; +} + +interface EcdsaParams extends Algorithm { + hash: AlgorithmIdentifier; +} + +interface EcKeyGenParams extends Algorithm { + typedCurve: string; +} + +interface EcKeyAlgorithm extends KeyAlgorithm { + typedCurve: string; +} + +interface EcKeyImportParams { + namedCurve: string; +} + +interface EcdhKeyDeriveParams extends Algorithm { + public: CryptoKey; +} + +interface AesCtrParams extends Algorithm { + counter: BufferSource; + length: number; +} + +interface AesKeyAlgorithm extends KeyAlgorithm { + length: number; +} + +interface AesKeyGenParams extends Algorithm { + length: number; +} + +interface AesDerivedKeyParams extends Algorithm { + length: number; +} + +interface AesCbcParams extends Algorithm { + iv: BufferSource; +} + +interface AesCmacParams extends Algorithm { + length: number; +} + +interface AesGcmParams extends Algorithm { + iv: BufferSource; + additionalData?: BufferSource; + tagLength?: number; +} + +interface AesCfbParams extends Algorithm { + iv: BufferSource; +} + +interface HmacImportParams extends Algorithm { + hash?: AlgorithmIdentifier; + length?: number; +} + +interface HmacKeyAlgorithm extends KeyAlgorithm { + hash: AlgorithmIdentifier; + length: number; +} + +interface HmacKeyGenParams extends Algorithm { + hash: AlgorithmIdentifier; + length?: number; +} + +interface DhKeyGenParams extends Algorithm { + prime: Uint8Array; + generator: Uint8Array; +} + +interface DhKeyAlgorithm extends KeyAlgorithm { + prime: Uint8Array; + generator: Uint8Array; +} + +interface DhKeyDeriveParams extends Algorithm { + public: CryptoKey; +} + +interface DhImportKeyParams extends Algorithm { + prime: Uint8Array; + generator: Uint8Array; +} + +interface ConcatParams extends Algorithm { + hash?: AlgorithmIdentifier; + algorithmId: Uint8Array; + partyUInfo: Uint8Array; + partyVInfo: Uint8Array; + publicInfo?: Uint8Array; + privateInfo?: Uint8Array; +} + +interface HkdfCtrParams extends Algorithm { + hash: AlgorithmIdentifier; + label: BufferSource; + context: BufferSource; +} + +interface Pbkdf2Params extends Algorithm { + salt: BufferSource; + iterations: number; + hash: AlgorithmIdentifier; +} + +interface RsaOtherPrimesInfo { + r: string; + d: string; + t: string; +} + +interface JsonWebKey { + kty: string; + use?: string; + key_ops?: string[]; + alg?: string; + kid?: string; + x5u?: string; + x5c?: string; + x5t?: string; + ext?: boolean; + crv?: string; + x?: string; + y?: string; + d?: string; + n?: string; + e?: string; + p?: string; + q?: string; + dp?: string; + dq?: string; + qi?: string; + oth?: RsaOtherPrimesInfo[]; + k?: string; +} + declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject; interface ErrorEventHandler { @@ -13746,7 +14281,7 @@ declare var msCredentials: MSCredentials; declare var name: string; declare var navigator: Navigator; declare var offscreenBuffering: string | boolean; -declare var onabort: (ev: Event) => any; +declare var onabort: (ev: UIEvent) => any; declare var onafterprint: (ev: Event) => any; declare var onbeforeprint: (ev: Event) => any; declare var onbeforeunload: (ev: BeforeUnloadEvent) => any; @@ -13896,10 +14431,13 @@ declare function dispatchEvent(evt: Event): boolean; declare function removeEventListener(type: string, listener?: EventListenerOrEventListenerObject, useCapture?: boolean): void; declare function clearInterval(handle: number): void; declare function clearTimeout(handle: number): void; +declare function setInterval(handler: (...args: any[]) => void, timeout: number): number; declare function setInterval(handler: any, timeout?: any, ...args: any[]): number; +declare function setTimeout(handler: (...args: any[]) => void, timeout: number): number; declare function setTimeout(handler: any, timeout?: any, ...args: any[]): number; declare function clearImmediate(handle: number): void; -declare function setImmediate(expression: any, ...args: any[]): number; +declare function setImmediate(handler: (...args: any[]) => void): number; +declare function setImmediate(handler: any, ...args: any[]): number; declare var sessionStorage: Storage; declare var localStorage: Storage; declare var console: Console; @@ -14042,4 +14580,6 @@ type MSOutboundPayload = MSVideoSendPayload | MSAudioSendPayload; type RTCIceGatherCandidate = RTCIceCandidate | RTCIceCandidateComplete; type RTCTransport = RTCDtlsTransport | RTCSrtpSdesTransport; type payloadtype = number; -type IDBValidKey = number | string | Date | IDBArrayKey; \ No newline at end of file +type IDBValidKey = number | string | Date | IDBArrayKey; +type BufferSource = ArrayBuffer | ArrayBufferView; +type MouseWheelEvent = WheelEvent; \ No newline at end of file diff --git a/src/lib/webworker.generated.d.ts b/src/lib/webworker.generated.d.ts index f5c77b8594d..6db86d71b2a 100644 --- a/src/lib/webworker.generated.d.ts +++ b/src/lib/webworker.generated.d.ts @@ -323,7 +323,7 @@ interface IDBDatabase extends EventTarget { readonly name: string; readonly objectStoreNames: DOMStringList; onabort: (ev: Event) => any; - onerror: (ev: Event) => any; + onerror: (ev: ErrorEvent) => any; version: number; onversionchange: (ev: IDBVersionChangeEvent) => any; close(): void; @@ -426,7 +426,7 @@ declare var IDBOpenDBRequest: { interface IDBRequest extends EventTarget { readonly error: DOMError; - onerror: (ev: Event) => any; + onerror: (ev: ErrorEvent) => any; onsuccess: (ev: Event) => any; readonly readyState: string; readonly result: any; @@ -448,7 +448,7 @@ interface IDBTransaction extends EventTarget { readonly mode: string; onabort: (ev: Event) => any; oncomplete: (ev: Event) => any; - onerror: (ev: Event) => any; + onerror: (ev: ErrorEvent) => any; abort(): void; objectStore(name: string): IDBObjectStore; readonly READ_ONLY: string; @@ -516,7 +516,7 @@ declare var MSApp: MSApp; interface MSAppAsyncOperation extends EventTarget { readonly error: DOMError; oncomplete: (ev: Event) => any; - onerror: (ev: Event) => any; + onerror: (ev: ErrorEvent) => any; readonly readyState: number; readonly result: any; start(): void; @@ -665,7 +665,7 @@ interface WebSocket extends EventTarget { readonly bufferedAmount: number; readonly extensions: string; onclose: (ev: CloseEvent) => any; - onerror: (ev: Event) => any; + onerror: (ev: ErrorEvent) => any; onmessage: (ev: MessageEvent) => any; onopen: (ev: Event) => any; readonly protocol: string; @@ -708,7 +708,6 @@ declare var Worker: { } interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget { - msCaching: string; onreadystatechange: (ev: ProgressEvent) => any; readonly readyState: number; readonly response: any; @@ -720,6 +719,7 @@ interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget { timeout: number; readonly upload: XMLHttpRequestUpload; withCredentials: boolean; + msCaching?: string; abort(): void; getAllResponseHeaders(): string; getResponseHeader(header: string): string | null; @@ -766,14 +766,14 @@ declare var XMLHttpRequestUpload: { } interface AbstractWorker { - onerror: (ev: Event) => any; + onerror: (ev: ErrorEvent) => any; addEventListener(type: "error", listener: (ev: ErrorEvent) => any, useCapture?: boolean): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; } interface MSBaseReader { onabort: (ev: Event) => any; - onerror: (ev: Event) => any; + onerror: (ev: ErrorEvent) => any; onload: (ev: Event) => any; onloadend: (ev: ProgressEvent) => any; onloadstart: (ev: Event) => any; @@ -819,7 +819,7 @@ interface WindowConsole { interface XMLHttpRequestEventTarget { onabort: (ev: Event) => any; - onerror: (ev: Event) => any; + onerror: (ev: ErrorEvent) => any; onload: (ev: Event) => any; onloadend: (ev: ProgressEvent) => any; onloadstart: (ev: Event) => any; @@ -849,7 +849,7 @@ declare var FileReaderSync: { interface WorkerGlobalScope extends EventTarget, WorkerUtils, DedicatedWorkerGlobalScope, WindowConsole { readonly location: WorkerLocation; - onerror: (ev: Event) => any; + onerror: (ev: ErrorEvent) => any; readonly self: WorkerGlobalScope; close(): void; msWriteProfilerMark(profilerMarkName: string): void; @@ -905,8 +905,11 @@ interface WorkerUtils extends Object, WindowBase64 { clearInterval(handle: number): void; clearTimeout(handle: number): void; importScripts(...urls: string[]): void; + setImmediate(handler: (...args: any[]) => void): number; setImmediate(handler: any, ...args: any[]): number; + setInterval(handler: (...args: any[]) => void, timeout: number): number; setInterval(handler: any, timeout?: any, ...args: any[]): number; + setTimeout(handler: (...args: any[]) => void, timeout: number): number; setTimeout(handler: any, timeout?: any, ...args: any[]): number; } @@ -942,6 +945,177 @@ interface ProgressEventInit extends EventInit { interface IDBArrayKey extends Array { } +interface RsaKeyGenParams extends Algorithm { + modulusLength: number; + publicExponent: Uint8Array; +} + +interface RsaHashedKeyGenParams extends RsaKeyGenParams { + hash: AlgorithmIdentifier; +} + +interface RsaKeyAlgorithm extends KeyAlgorithm { + modulusLength: number; + publicExponent: Uint8Array; +} + +interface RsaHashedKeyAlgorithm extends RsaKeyAlgorithm { + hash: AlgorithmIdentifier; +} + +interface RsaHashedImportParams { + hash: AlgorithmIdentifier; +} + +interface RsaPssParams { + saltLength: number; +} + +interface RsaOaepParams extends Algorithm { + label?: BufferSource; +} + +interface EcdsaParams extends Algorithm { + hash: AlgorithmIdentifier; +} + +interface EcKeyGenParams extends Algorithm { + typedCurve: string; +} + +interface EcKeyAlgorithm extends KeyAlgorithm { + typedCurve: string; +} + +interface EcKeyImportParams { + namedCurve: string; +} + +interface EcdhKeyDeriveParams extends Algorithm { + public: CryptoKey; +} + +interface AesCtrParams extends Algorithm { + counter: BufferSource; + length: number; +} + +interface AesKeyAlgorithm extends KeyAlgorithm { + length: number; +} + +interface AesKeyGenParams extends Algorithm { + length: number; +} + +interface AesDerivedKeyParams extends Algorithm { + length: number; +} + +interface AesCbcParams extends Algorithm { + iv: BufferSource; +} + +interface AesCmacParams extends Algorithm { + length: number; +} + +interface AesGcmParams extends Algorithm { + iv: BufferSource; + additionalData?: BufferSource; + tagLength?: number; +} + +interface AesCfbParams extends Algorithm { + iv: BufferSource; +} + +interface HmacImportParams extends Algorithm { + hash?: AlgorithmIdentifier; + length?: number; +} + +interface HmacKeyAlgorithm extends KeyAlgorithm { + hash: AlgorithmIdentifier; + length: number; +} + +interface HmacKeyGenParams extends Algorithm { + hash: AlgorithmIdentifier; + length?: number; +} + +interface DhKeyGenParams extends Algorithm { + prime: Uint8Array; + generator: Uint8Array; +} + +interface DhKeyAlgorithm extends KeyAlgorithm { + prime: Uint8Array; + generator: Uint8Array; +} + +interface DhKeyDeriveParams extends Algorithm { + public: CryptoKey; +} + +interface DhImportKeyParams extends Algorithm { + prime: Uint8Array; + generator: Uint8Array; +} + +interface ConcatParams extends Algorithm { + hash?: AlgorithmIdentifier; + algorithmId: Uint8Array; + partyUInfo: Uint8Array; + partyVInfo: Uint8Array; + publicInfo?: Uint8Array; + privateInfo?: Uint8Array; +} + +interface HkdfCtrParams extends Algorithm { + hash: AlgorithmIdentifier; + label: BufferSource; + context: BufferSource; +} + +interface Pbkdf2Params extends Algorithm { + salt: BufferSource; + iterations: number; + hash: AlgorithmIdentifier; +} + +interface RsaOtherPrimesInfo { + r: string; + d: string; + t: string; +} + +interface JsonWebKey { + kty: string; + use?: string; + key_ops?: string[]; + alg?: string; + kid?: string; + x5u?: string; + x5c?: string; + x5t?: string; + ext?: boolean; + crv?: string; + x?: string; + y?: string; + d?: string; + n?: string; + e?: string; + p?: string; + q?: string; + dp?: string; + dq?: string; + qi?: string; + oth?: RsaOtherPrimesInfo[]; + k?: string; +} + declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject; interface ErrorEventHandler { @@ -975,7 +1149,7 @@ interface FunctionStringCallback { (data: string): void; } declare var location: WorkerLocation; -declare var onerror: (ev: Event) => any; +declare var onerror: (ev: ErrorEvent) => any; declare var self: WorkerGlobalScope; declare function close(): void; declare function msWriteProfilerMark(profilerMarkName: string): void; @@ -990,8 +1164,11 @@ declare function clearImmediate(handle: number): void; declare function clearInterval(handle: number): void; declare function clearTimeout(handle: number): void; declare function importScripts(...urls: string[]): void; +declare function setImmediate(handler: (...args: any[]) => void): number; declare function setImmediate(handler: any, ...args: any[]): number; +declare function setInterval(handler: (...args: any[]) => void, timeout: number): number; declare function setInterval(handler: any, timeout?: any, ...args: any[]): number; +declare function setTimeout(handler: (...args: any[]) => void, timeout: number): number; declare function setTimeout(handler: any, timeout?: any, ...args: any[]): number; declare function atob(encodedString: string): string; declare function btoa(rawString: string): string; @@ -1002,4 +1179,6 @@ declare function addEventListener(type: "error", listener: (ev: ErrorEvent) => a declare function addEventListener(type: "message", listener: (ev: MessageEvent) => any, useCapture?: boolean): void; declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void; type IDBKeyPath = string; -type IDBValidKey = number | string | Date | IDBArrayKey; \ No newline at end of file +type IDBValidKey = number | string | Date | IDBArrayKey; +type BufferSource = ArrayBuffer | ArrayBufferView; +type MouseWheelEvent = WheelEvent; \ No newline at end of file diff --git a/src/server/client.ts b/src/server/client.ts index b0a1a8ec9e9..864dac9fdaa 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -376,6 +376,7 @@ namespace ts.server { fileName: fileName, textSpan: ts.createTextSpanFromBounds(start, end), isWriteAccess: entry.isWriteAccess, + isDefinition: entry.isDefinition, }; }); } @@ -536,6 +537,7 @@ namespace ts.server { fileName, textSpan: ts.createTextSpanFromBounds(start, end), isWriteAccess: entry.isWriteAccess, + isDefinition: false }; }); } diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 00793f8c3b2..458e28427d7 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -27,6 +27,8 @@ namespace ts.server { }); } + export const maxProgramSizeForNonTsFiles = 20 * 1024 * 1024; + export class ScriptInfo { svc: ScriptVersionCache; children: ScriptInfo[] = []; // files referenced by this file @@ -387,12 +389,29 @@ namespace ts.server { /** Used for configured projects which may have multiple open roots */ openRefCount = 0; - constructor(public projectService: ProjectService, public projectOptions?: ProjectOptions) { + constructor( + public projectService: ProjectService, + public projectOptions?: ProjectOptions, + public languageServiceDiabled = false) { if (projectOptions && projectOptions.files) { // If files are listed explicitly, allow all extensions projectOptions.compilerOptions.allowNonTsExtensions = true; } - this.compilerService = new CompilerService(this, projectOptions && projectOptions.compilerOptions); + if (!languageServiceDiabled) { + this.compilerService = new CompilerService(this, projectOptions && projectOptions.compilerOptions); + } + } + + enableLanguageService() { + // if the language service was disabled, we should re-initiate the compiler service + if (this.languageServiceDiabled) { + this.compilerService = new CompilerService(this, this.projectOptions && this.projectOptions.compilerOptions); + } + this.languageServiceDiabled = false; + } + + disableLanguageService() { + this.languageServiceDiabled = true; } addOpenRef() { @@ -409,19 +428,45 @@ namespace ts.server { } getRootFiles() { + if (this.languageServiceDiabled) { + // When the languageService was disabled, only return file list if it is a configured project + return this.projectOptions ? this.projectOptions.files : undefined; + } + return this.compilerService.host.roots.map(info => info.fileName); } getFileNames() { + if (this.languageServiceDiabled) { + if (!this.projectOptions) { + return undefined; + } + + const fileNames: string[] = []; + if (this.projectOptions && this.projectOptions.compilerOptions) { + fileNames.push(getDefaultLibFilePath(this.projectOptions.compilerOptions)); + } + ts.addRange(fileNames, this.projectOptions.files); + return fileNames; + } + const sourceFiles = this.program.getSourceFiles(); return sourceFiles.map(sourceFile => sourceFile.fileName); } getSourceFile(info: ScriptInfo) { + if (this.languageServiceDiabled) { + return undefined; + } + return this.filenameToSourceFile[info.fileName]; } getSourceFileFromName(filename: string, requireOpen?: boolean) { + if (this.languageServiceDiabled) { + return undefined; + } + const info = this.projectService.getScriptInfo(filename); if (info) { if ((!requireOpen) || info.isOpen) { @@ -431,15 +476,27 @@ namespace ts.server { } isRoot(info: ScriptInfo) { + if (this.languageServiceDiabled) { + return undefined; + } + return this.compilerService.host.roots.some(root => root === info); } removeReferencedFile(info: ScriptInfo) { + if (this.languageServiceDiabled) { + return; + } + this.compilerService.host.removeReferencedFile(info); this.updateGraph(); } updateFileMap() { + if (this.languageServiceDiabled) { + return; + } + this.filenameToSourceFile = {}; const sourceFiles = this.program.getSourceFiles(); for (let i = 0, len = sourceFiles.length; i < len; i++) { @@ -449,11 +506,19 @@ namespace ts.server { } finishGraph() { + if (this.languageServiceDiabled) { + return; + } + this.updateGraph(); this.compilerService.languageService.getNavigateToItems(".*"); } updateGraph() { + if (this.languageServiceDiabled) { + return; + } + this.program = this.compilerService.languageService.getProgram(); this.updateFileMap(); } @@ -464,15 +529,32 @@ namespace ts.server { // add a root file to project addRoot(info: ScriptInfo) { + if (this.languageServiceDiabled) { + return; + } + this.compilerService.host.addRoot(info); } // remove a root file from project removeRoot(info: ScriptInfo) { + if (this.languageServiceDiabled) { + return; + } + this.compilerService.host.removeRoot(info); } filesToString() { + if (this.languageServiceDiabled) { + if (this.projectOptions) { + let strBuilder = ""; + ts.forEach(this.projectOptions.files, + file => { strBuilder += file + "\n"; }); + return strBuilder; + } + } + let strBuilder = ""; ts.forEachValue(this.filenameToSourceFile, sourceFile => { strBuilder += sourceFile.fileName + "\n"; }); @@ -483,7 +565,9 @@ namespace ts.server { this.projectOptions = projectOptions; if (projectOptions.compilerOptions) { projectOptions.compilerOptions.allowNonTsExtensions = true; - this.compilerService.setCompilerOptions(projectOptions.compilerOptions); + if (!this.languageServiceDiabled) { + this.compilerService.setCompilerOptions(projectOptions.compilerOptions); + } } } } @@ -811,6 +895,7 @@ namespace ts.server { else { this.findReferencingProjects(info); if (info.defaultProject) { + info.defaultProject.addOpenRef(); this.openFilesReferenced.push(info); } else { @@ -1265,7 +1350,24 @@ namespace ts.server { return { succeeded: true, projectOptions }; } } + } + private exceedTotalNonTsFileSizeLimit(fileNames: string[]) { + let totalNonTsFileSize = 0; + if (!this.host.getFileSize) { + return false; + } + + for (const fileName of fileNames) { + if (hasTypeScriptFileExtension(fileName)) { + continue; + } + totalNonTsFileSize += this.host.getFileSize(fileName); + if (totalNonTsFileSize > maxProgramSizeForNonTsFiles) { + return true; + } + } + return false; } openConfigFile(configFilename: string, clientFileName?: string): { success: boolean, project?: Project, errors?: Diagnostic[] } { @@ -1274,6 +1376,19 @@ namespace ts.server { return { success: false, errors }; } else { + if (!projectOptions.compilerOptions.disableSizeLimit && projectOptions.compilerOptions.allowJs) { + if (this.exceedTotalNonTsFileSizeLimit(projectOptions.files)) { + const project = this.createProject(configFilename, projectOptions, /*languageServiceDisabled*/ true); + + // for configured projects with languageService disabled, we only watch its config file, + // do not care about the directory changes in the folder. + project.projectFileWatcher = this.host.watchFile( + toPath(configFilename, configFilename, createGetCanonicalFileName(sys.useCaseSensitiveFileNames)), + _ => this.watchedProjectConfigFileChanged(project)); + return { success: true, project }; + } + } + const project = this.createProject(configFilename, projectOptions); let errors: Diagnostic[]; for (const rootFilename of projectOptions.files) { @@ -1315,7 +1430,7 @@ namespace ts.server { } } - updateConfiguredProject(project: Project) { + updateConfiguredProject(project: Project): Diagnostic[] { if (!this.host.fileExists(project.projectFilename)) { this.log("Config file deleted"); this.removeProject(project); @@ -1326,7 +1441,43 @@ namespace ts.server { return errors; } else { - const oldFileNames = project.compilerService.host.roots.map(info => info.fileName); + if (projectOptions.compilerOptions && !projectOptions.compilerOptions.disableSizeLimit && this.exceedTotalNonTsFileSizeLimit(projectOptions.files)) { + project.setProjectOptions(projectOptions); + if (project.languageServiceDiabled) { + return; + } + + project.disableLanguageService(); + if (project.directoryWatcher) { + project.directoryWatcher.close(); + project.directoryWatcher = undefined; + } + return; + } + + if (project.languageServiceDiabled) { + project.setProjectOptions(projectOptions); + project.enableLanguageService(); + project.directoryWatcher = this.host.watchDirectory( + ts.getDirectoryPath(project.projectFilename), + path => this.directoryWatchedForSourceFilesChanged(project, path), + /*recursive*/ true + ); + + for (const rootFilename of projectOptions.files) { + if (this.host.fileExists(rootFilename)) { + const info = this.openFile(rootFilename, /*openedByClient*/ false); + project.addRoot(info); + } + } + project.finishGraph(); + return; + } + + // if the project is too large, the root files might not have been all loaded if the total + // program size reached the upper limit. In that case project.projectOptions.files should + // be more precise. However this would only happen for configured project. + const oldFileNames = project.projectOptions ? project.projectOptions.files : project.compilerService.host.roots.map(info => info.fileName); const newFileNames = ts.filter(projectOptions.files, f => this.host.fileExists(f)); const fileNamesToRemove = oldFileNames.filter(f => newFileNames.indexOf(f) < 0); const fileNamesToAdd = newFileNames.filter(f => oldFileNames.indexOf(f) < 0); @@ -1369,8 +1520,8 @@ namespace ts.server { } } - createProject(projectFilename: string, projectOptions?: ProjectOptions) { - const project = new Project(this, projectOptions); + createProject(projectFilename: string, projectOptions?: ProjectOptions, languageServiceDisabled?: boolean) { + const project = new Project(this, projectOptions, languageServiceDisabled); project.projectFilename = projectFilename; return project; } diff --git a/src/server/protocol.d.ts b/src/server/protocol.d.ts index d2c15b308ec..73ef396a7e4 100644 --- a/src/server/protocol.d.ts +++ b/src/server/protocol.d.ts @@ -123,6 +123,10 @@ declare namespace ts.server.protocol { * The list of normalized file name in the project, including 'lib.d.ts' */ fileNames?: string[]; + /** + * Indicates if the project has a active language service instance + */ + languageServiceDisabled?: boolean; } /** @@ -304,6 +308,11 @@ declare namespace ts.server.protocol { * True if reference is a write location, false otherwise. */ isWriteAccess: boolean; + + /** + * True if reference is a definition, false otherwise. + */ + isDefinition: boolean; } /** diff --git a/src/server/session.ts b/src/server/session.ts index 0ec3d87e58c..65540082f60 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -313,7 +313,7 @@ namespace ts.server { private getDefinition(line: number, offset: number, fileName: string): protocol.FileSpan[] { const file = ts.normalizePath(fileName); const project = this.projectService.getProjectForFile(file); - if (!project) { + if (!project || project.languageServiceDiabled) { throw Errors.NoProject; } @@ -335,7 +335,7 @@ namespace ts.server { private getTypeDefinition(line: number, offset: number, fileName: string): protocol.FileSpan[] { const file = ts.normalizePath(fileName); const project = this.projectService.getProjectForFile(file); - if (!project) { + if (!project || project.languageServiceDiabled) { throw Errors.NoProject; } @@ -358,7 +358,7 @@ namespace ts.server { fileName = ts.normalizePath(fileName); const project = this.projectService.getProjectForFile(fileName); - if (!project) { + if (!project || project.languageServiceDiabled) { throw Errors.NoProject; } @@ -379,7 +379,7 @@ namespace ts.server { start, end, file: fileName, - isWriteAccess + isWriteAccess, }; }); } @@ -388,7 +388,7 @@ namespace ts.server { fileName = ts.normalizePath(fileName); const project = this.projectService.getProjectForFile(fileName); - if (!project) { + if (!project || project.languageServiceDiabled) { throw Errors.NoProject; } @@ -423,15 +423,18 @@ namespace ts.server { private getProjectInfo(fileName: string, needFileNameList: boolean): protocol.ProjectInfo { fileName = ts.normalizePath(fileName); const project = this.projectService.getProjectForFile(fileName); + if (!project) { + throw Errors.NoProject; + } const projectInfo: protocol.ProjectInfo = { - configFileName: project.projectFilename + configFileName: project.projectFilename, + languageServiceDisabled: project.languageServiceDiabled }; if (needFileNameList) { projectInfo.fileNames = project.getFileNames(); } - return projectInfo; } @@ -439,11 +442,12 @@ namespace ts.server { const file = ts.normalizePath(fileName); const info = this.projectService.getScriptInfo(file); const projects = this.projectService.findReferencingProjects(info); - if (!projects.length) { + const projectsWithLanguageServiceEnabeld = ts.filter(projects, p => !p.languageServiceDiabled); + if (projectsWithLanguageServiceEnabeld.length === 0) { throw Errors.NoProject; } - const defaultProject = projects[0]; + const defaultProject = projectsWithLanguageServiceEnabeld[0]; // The rename info should be the same for every project const defaultProjectCompilerService = defaultProject.compilerService; const position = defaultProjectCompilerService.host.lineOffsetToPosition(file, line, offset); @@ -460,7 +464,7 @@ namespace ts.server { } const fileSpans = combineProjectOutput( - projects, + projectsWithLanguageServiceEnabeld, (project: Project) => { const compilerService = project.compilerService; const renameLocations = compilerService.languageService.findRenameLocations(file, position, findInStrings, findInComments); @@ -521,11 +525,12 @@ namespace ts.server { const file = ts.normalizePath(fileName); const info = this.projectService.getScriptInfo(file); const projects = this.projectService.findReferencingProjects(info); - if (!projects.length) { + const projectsWithLanguageServiceEnabeld = ts.filter(projects, p => !p.languageServiceDiabled); + if (projectsWithLanguageServiceEnabeld.length === 0) { throw Errors.NoProject; } - const defaultProject = projects[0]; + const defaultProject = projectsWithLanguageServiceEnabeld[0]; const position = defaultProject.compilerService.host.lineOffsetToPosition(file, line, offset); const nameInfo = defaultProject.compilerService.languageService.getQuickInfoAtPosition(file, position); if (!nameInfo) { @@ -537,7 +542,7 @@ namespace ts.server { const nameColStart = defaultProject.compilerService.host.positionToLineOffset(file, nameSpan.start).offset; const nameText = defaultProject.compilerService.host.getScriptSnapshot(file).getText(nameSpan.start, ts.textSpanEnd(nameSpan)); const refs = combineProjectOutput( - projects, + projectsWithLanguageServiceEnabeld, (project: Project) => { const compilerService = project.compilerService; const references = compilerService.languageService.getReferencesAtPosition(file, position); @@ -555,7 +560,8 @@ namespace ts.server { start: start, lineText: lineText, end: compilerService.host.positionToLineOffset(ref.fileName, ts.textSpanEnd(ref.textSpan)), - isWriteAccess: ref.isWriteAccess + isWriteAccess: ref.isWriteAccess, + isDefinition: ref.isDefinition }; }); }, @@ -595,7 +601,7 @@ namespace ts.server { private getQuickInfo(line: number, offset: number, fileName: string): protocol.QuickInfoResponseBody { const file = ts.normalizePath(fileName); const project = this.projectService.getProjectForFile(file); - if (!project) { + if (!project || project.languageServiceDiabled) { throw Errors.NoProject; } @@ -621,7 +627,7 @@ namespace ts.server { private getFormattingEditsForRange(line: number, offset: number, endLine: number, endOffset: number, fileName: string): protocol.CodeEdit[] { const file = ts.normalizePath(fileName); const project = this.projectService.getProjectForFile(file); - if (!project) { + if (!project || project.languageServiceDiabled) { throw Errors.NoProject; } @@ -649,7 +655,7 @@ namespace ts.server { const file = ts.normalizePath(fileName); const project = this.projectService.getProjectForFile(file); - if (!project) { + if (!project || project.languageServiceDiabled) { throw Errors.NoProject; } @@ -727,7 +733,7 @@ namespace ts.server { } const file = ts.normalizePath(fileName); const project = this.projectService.getProjectForFile(file); - if (!project) { + if (!project || project.languageServiceDiabled) { throw Errors.NoProject; } @@ -751,7 +757,7 @@ namespace ts.server { entryNames: string[], fileName: string): protocol.CompletionEntryDetails[] { const file = ts.normalizePath(fileName); const project = this.projectService.getProjectForFile(file); - if (!project) { + if (!project || project.languageServiceDiabled) { throw Errors.NoProject; } @@ -770,7 +776,7 @@ namespace ts.server { private getSignatureHelpItems(line: number, offset: number, fileName: string): protocol.SignatureHelpItems { const file = ts.normalizePath(fileName); const project = this.projectService.getProjectForFile(file); - if (!project) { + if (!project || project.languageServiceDiabled) { throw Errors.NoProject; } @@ -800,7 +806,7 @@ namespace ts.server { const checkList = fileNames.reduce((accum: PendingErrorCheck[], fileName: string) => { fileName = ts.normalizePath(fileName); const project = this.projectService.getProjectForFile(fileName); - if (project) { + if (project && !project.languageServiceDiabled) { accum.push({ fileName, project }); } return accum; @@ -814,7 +820,7 @@ namespace ts.server { private change(line: number, offset: number, endLine: number, endOffset: number, insertString: string, fileName: string) { const file = ts.normalizePath(fileName); const project = this.projectService.getProjectForFile(file); - if (project) { + if (project && !project.languageServiceDiabled) { const compilerService = project.compilerService; const start = compilerService.host.lineOffsetToPosition(file, line, offset); const end = compilerService.host.lineOffsetToPosition(file, endLine, endOffset); @@ -830,7 +836,7 @@ namespace ts.server { const file = ts.normalizePath(fileName); const tmpfile = ts.normalizePath(tempFileName); const project = this.projectService.getProjectForFile(file); - if (project) { + if (project && !project.languageServiceDiabled) { this.changeSeq++; // make sure no changes happen before this one is finished project.compilerService.host.reloadScript(file, tmpfile, () => { @@ -844,7 +850,7 @@ namespace ts.server { const tmpfile = ts.normalizePath(tempFileName); const project = this.projectService.getProjectForFile(file); - if (project) { + if (project && !project.languageServiceDiabled) { project.compilerService.host.saveTo(file, tmpfile); } } @@ -880,7 +886,7 @@ namespace ts.server { private getNavigationBarItems(fileName: string): protocol.NavigationBarItem[] { const file = ts.normalizePath(fileName); const project = this.projectService.getProjectForFile(file); - if (!project) { + if (!project || project.languageServiceDiabled) { throw Errors.NoProject; } @@ -897,13 +903,13 @@ namespace ts.server { const file = ts.normalizePath(fileName); const info = this.projectService.getScriptInfo(file); const projects = this.projectService.findReferencingProjects(info); - const defaultProject = projects[0]; - if (!defaultProject) { + const projectsWithLanguageServiceEnabeld = ts.filter(projects, p => !p.languageServiceDiabled); + if (projectsWithLanguageServiceEnabeld.length === 0) { throw Errors.NoProject; } const allNavToItems = combineProjectOutput( - projects, + projectsWithLanguageServiceEnabeld, (project: Project) => { const compilerService = project.compilerService; const navItems = compilerService.languageService.getNavigateToItems(searchValue, maxResultCount); @@ -955,7 +961,7 @@ namespace ts.server { const file = ts.normalizePath(fileName); const project = this.projectService.getProjectForFile(file); - if (!project) { + if (!project || project.languageServiceDiabled) { throw Errors.NoProject; } @@ -974,7 +980,11 @@ namespace ts.server { } getDiagnosticsForProject(delay: number, fileName: string) { - const { fileNames } = this.getProjectInfo(fileName, /*needFileNameList*/ true); + const { fileNames, languageServiceDisabled } = this.getProjectInfo(fileName, /*needFileNameList*/ true); + if (languageServiceDisabled) { + return; + } + // No need to analyze lib.d.ts let fileNamesInProject = fileNames.filter((value, index, array) => value.indexOf("lib.d.ts") < 0); diff --git a/src/services/services.ts b/src/services/services.ts index d051a4378e4..983ddfbf250 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1,4 +1,5 @@ /// +/// /// /// @@ -1209,6 +1210,7 @@ namespace ts { textSpan: TextSpan; fileName: string; isWriteAccess: boolean; + isDefinition: boolean; } export interface DocumentHighlights { @@ -2000,6 +2002,10 @@ namespace ts { // so pass --noLib to avoid reporting a file not found error. options.noLib = true; + // Clear out the lib and types option as well + options.lib = undefined; + options.types = undefined; + // We are not doing a full typecheck, we are not resolving the whole context, // so pass --noResolve to avoid reporting missing file errors. options.noResolve = true; @@ -2977,7 +2983,8 @@ namespace ts { oldSettings.moduleResolution !== newSettings.moduleResolution || oldSettings.noResolve !== newSettings.noResolve || oldSettings.jsx !== newSettings.jsx || - oldSettings.allowJs !== newSettings.allowJs); + oldSettings.allowJs !== newSettings.allowJs || + oldSettings.disableSizeLimit !== oldSettings.disableSizeLimit); // Now create a new compiler const compilerHost: CompilerHost = { @@ -4141,7 +4148,7 @@ namespace ts { if (!uniqueNames[name]) { uniqueNames[name] = name; - const displayName = getCompletionEntryDisplayName(name, target, /*performCharacterChecks*/ true); + const displayName = getCompletionEntryDisplayName(unescapeIdentifier(name), target, /*performCharacterChecks*/ true); if (displayName) { const entry = { name: displayName, @@ -5753,7 +5760,8 @@ namespace ts { result.push({ fileName: entry.fileName, textSpan: highlightSpan.textSpan, - isWriteAccess: highlightSpan.kind === HighlightSpanKind.writtenReference + isWriteAccess: highlightSpan.kind === HighlightSpanKind.writtenReference, + isDefinition: false }); } } @@ -6187,7 +6195,8 @@ namespace ts { references: [{ fileName: sourceFile.fileName, textSpan: createTextSpan(position, searchText.length), - isWriteAccess: false + isWriteAccess: false, + isDefinition: false }] }); } @@ -6741,7 +6750,8 @@ namespace ts { return { fileName: node.getSourceFile().fileName, textSpan: createTextSpanFromBounds(start, end), - isWriteAccess: isWriteAccess(node) + isWriteAccess: isWriteAccess(node), + isDefinition: isDeclarationName(node) || isLiteralComputedPropertyDeclarationName(node) }; } diff --git a/src/services/shims.ts b/src/services/shims.ts index 75448536bad..ac74ee09750 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -165,7 +165,7 @@ namespace ts { /** * Returns a JSON-encoded value of the type: - * { fileName: string; textSpan: { start: number; length: number}; isWriteAccess: boolean }[] + * { fileName: string; textSpan: { start: number; length: number}; isWriteAccess: boolean, isDefinition?: boolean }[] */ getReferencesAtPosition(fileName: string, position: number): string; @@ -1165,4 +1165,4 @@ namespace TypeScript.Services { /* @internal */ const toolsVersion = "1.9"; -/* tslint:enable:no-unused-variable */ \ No newline at end of file +/* tslint:enable:no-unused-variable */ diff --git a/tests/baselines/reference/classExtendingClassLikeType.errors.txt b/tests/baselines/reference/classExtendingClassLikeType.errors.txt index 6f9aef927ea..5edefd78ec5 100644 --- a/tests/baselines/reference/classExtendingClassLikeType.errors.txt +++ b/tests/baselines/reference/classExtendingClassLikeType.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/classes/classDeclarations/classExtendingClassLikeType.ts(7,18): error TS2304: Cannot find name 'Base'. +tests/cases/conformance/classes/classDeclarations/classExtendingClassLikeType.ts(7,18): error TS2689: Cannot extend an interface 'Base'. Did you mean 'implements'? tests/cases/conformance/classes/classDeclarations/classExtendingClassLikeType.ts(45,18): error TS2508: No base constructor has the specified number of type arguments. tests/cases/conformance/classes/classDeclarations/classExtendingClassLikeType.ts(56,18): error TS2510: Base constructors must all have the same return type. @@ -12,7 +12,7 @@ tests/cases/conformance/classes/classDeclarations/classExtendingClassLikeType.ts // Error, no Base constructor function class D0 extends Base { ~~~~ -!!! error TS2304: Cannot find name 'Base'. +!!! error TS2689: Cannot extend an interface 'Base'. Did you mean 'implements'? } interface BaseConstructor { diff --git a/tests/baselines/reference/classExtendsEveryObjectType.errors.txt b/tests/baselines/reference/classExtendsEveryObjectType.errors.txt index 0339dfad13a..e1c5137e3a9 100644 --- a/tests/baselines/reference/classExtendsEveryObjectType.errors.txt +++ b/tests/baselines/reference/classExtendsEveryObjectType.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsEveryObjectType.ts(4,17): error TS2304: Cannot find name 'I'. +tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsEveryObjectType.ts(4,17): error TS2689: Cannot extend an interface 'I'. Did you mean 'implements'? tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsEveryObjectType.ts(6,18): error TS2507: Type '{ foo: any; }' is not a constructor function type. tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsEveryObjectType.ts(6,25): error TS2304: Cannot find name 'string'. tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsEveryObjectType.ts(6,31): error TS1005: ',' expected. @@ -14,7 +14,7 @@ tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/cla } class C extends I { } // error ~ -!!! error TS2304: Cannot find name 'I'. +!!! error TS2689: Cannot extend an interface 'I'. Did you mean 'implements'? class C2 extends { foo: string; } { } // error ~~~~~~~~~~~~~~~~ diff --git a/tests/baselines/reference/classExtendsInterface.errors.txt b/tests/baselines/reference/classExtendsInterface.errors.txt index 2ecca6cf2cf..72b8466105c 100644 --- a/tests/baselines/reference/classExtendsInterface.errors.txt +++ b/tests/baselines/reference/classExtendsInterface.errors.txt @@ -1,17 +1,17 @@ -tests/cases/compiler/classExtendsInterface.ts(2,17): error TS2304: Cannot find name 'Comparable'. -tests/cases/compiler/classExtendsInterface.ts(6,21): error TS2304: Cannot find name 'Comparable2'. +tests/cases/compiler/classExtendsInterface.ts(2,17): error TS2689: Cannot extend an interface 'Comparable'. Did you mean 'implements'? +tests/cases/compiler/classExtendsInterface.ts(6,21): error TS2689: Cannot extend an interface 'Comparable2'. Did you mean 'implements'? ==== tests/cases/compiler/classExtendsInterface.ts (2 errors) ==== interface Comparable {} class A extends Comparable {} ~~~~~~~~~~ -!!! error TS2304: Cannot find name 'Comparable'. +!!! error TS2689: Cannot extend an interface 'Comparable'. Did you mean 'implements'? class B implements Comparable {} - + interface Comparable2 {} class A2 extends Comparable2 {} ~~~~~~~~~~~ -!!! error TS2304: Cannot find name 'Comparable2'. +!!! error TS2689: Cannot extend an interface 'Comparable2'. Did you mean 'implements'? class B2 implements Comparable2 {} \ No newline at end of file diff --git a/tests/baselines/reference/classExtendsInterface.js b/tests/baselines/reference/classExtendsInterface.js index c06c4e66d8b..b324f7382d8 100644 --- a/tests/baselines/reference/classExtendsInterface.js +++ b/tests/baselines/reference/classExtendsInterface.js @@ -2,7 +2,7 @@ interface Comparable {} class A extends Comparable {} class B implements Comparable {} - + interface Comparable2 {} class A2 extends Comparable2 {} class B2 implements Comparable2 {} diff --git a/tests/baselines/reference/classExtendsInterfaceInExpression.errors.txt b/tests/baselines/reference/classExtendsInterfaceInExpression.errors.txt new file mode 100644 index 00000000000..64b160ea766 --- /dev/null +++ b/tests/baselines/reference/classExtendsInterfaceInExpression.errors.txt @@ -0,0 +1,14 @@ +tests/cases/compiler/classExtendsInterfaceInExpression.ts(7,25): error TS2304: Cannot find name 'A'. + + +==== tests/cases/compiler/classExtendsInterfaceInExpression.ts (1 errors) ==== + interface A {} + + function factory(a: any): {new(): Object} { + return null; + } + + class C extends factory(A) {} + ~ +!!! error TS2304: Cannot find name 'A'. + \ No newline at end of file diff --git a/tests/baselines/reference/classExtendsInterfaceInExpression.js b/tests/baselines/reference/classExtendsInterfaceInExpression.js new file mode 100644 index 00000000000..69e63f92570 --- /dev/null +++ b/tests/baselines/reference/classExtendsInterfaceInExpression.js @@ -0,0 +1,26 @@ +//// [classExtendsInterfaceInExpression.ts] +interface A {} + +function factory(a: any): {new(): Object} { + return null; +} + +class C extends factory(A) {} + + +//// [classExtendsInterfaceInExpression.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +function factory(a) { + return null; +} +var C = (function (_super) { + __extends(C, _super); + function C() { + _super.apply(this, arguments); + } + return C; +}(factory(A))); diff --git a/tests/baselines/reference/classExtendsInterfaceInModule.errors.txt b/tests/baselines/reference/classExtendsInterfaceInModule.errors.txt new file mode 100644 index 00000000000..9a87ddf51b6 --- /dev/null +++ b/tests/baselines/reference/classExtendsInterfaceInModule.errors.txt @@ -0,0 +1,27 @@ +tests/cases/compiler/classExtendsInterfaceInModule.ts(5,18): error TS2689: Cannot extend an interface 'M.I1'. Did you mean 'implements'? +tests/cases/compiler/classExtendsInterfaceInModule.ts(6,21): error TS2689: Cannot extend an interface 'M.I2'. Did you mean 'implements'? +tests/cases/compiler/classExtendsInterfaceInModule.ts(14,17): error TS2689: Cannot extend an interface 'Mod.Nested.I'. Did you mean 'implements'? + + +==== tests/cases/compiler/classExtendsInterfaceInModule.ts (3 errors) ==== + module M { + export interface I1 {} + export interface I2 {} + } + class C1 extends M.I1 {} + ~ +!!! error TS2689: Cannot extend an interface 'M.I1'. Did you mean 'implements'? + class C2 extends M.I2 {} + ~ +!!! error TS2689: Cannot extend an interface 'M.I2'. Did you mean 'implements'? + + module Mod { + export namespace Nested { + export interface I {} + } + } + + class D extends Mod.Nested.I {} + ~~~ +!!! error TS2689: Cannot extend an interface 'Mod.Nested.I'. Did you mean 'implements'? + \ No newline at end of file diff --git a/tests/baselines/reference/classExtendsInterfaceInModule.js b/tests/baselines/reference/classExtendsInterfaceInModule.js new file mode 100644 index 00000000000..45415488700 --- /dev/null +++ b/tests/baselines/reference/classExtendsInterfaceInModule.js @@ -0,0 +1,44 @@ +//// [classExtendsInterfaceInModule.ts] +module M { + export interface I1 {} + export interface I2 {} +} +class C1 extends M.I1 {} +class C2 extends M.I2 {} + +module Mod { + export namespace Nested { + export interface I {} + } +} + +class D extends Mod.Nested.I {} + + +//// [classExtendsInterfaceInModule.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var C1 = (function (_super) { + __extends(C1, _super); + function C1() { + _super.apply(this, arguments); + } + return C1; +}(M.I1)); +var C2 = (function (_super) { + __extends(C2, _super); + function C2() { + _super.apply(this, arguments); + } + return C2; +}(M.I2)); +var D = (function (_super) { + __extends(D, _super); + function D() { + _super.apply(this, arguments); + } + return D; +}(Mod.Nested.I)); diff --git a/tests/baselines/reference/constDeclarations-useBeforeDefinition2.errors.txt b/tests/baselines/reference/constDeclarations-useBeforeDefinition2.errors.txt new file mode 100644 index 00000000000..a4d28f51878 --- /dev/null +++ b/tests/baselines/reference/constDeclarations-useBeforeDefinition2.errors.txt @@ -0,0 +1,11 @@ +tests/cases/compiler/file1.ts(2,1): error TS2448: Block-scoped variable 'c' used before its declaration. + + +==== tests/cases/compiler/file1.ts (1 errors) ==== + + c; + ~ +!!! error TS2448: Block-scoped variable 'c' used before its declaration. + +==== tests/cases/compiler/file2.ts (0 errors) ==== + const c = 0; \ No newline at end of file diff --git a/tests/baselines/reference/decoratorMetadataPromise.js b/tests/baselines/reference/decoratorMetadataPromise.js new file mode 100644 index 00000000000..3ed8942033d --- /dev/null +++ b/tests/baselines/reference/decoratorMetadataPromise.js @@ -0,0 +1,59 @@ +//// [decoratorMetadataPromise.ts] + +declare const decorator: MethodDecorator; + +class A { + @decorator + async foo() {} + @decorator + async bar(): Promise { return 0; } + @decorator + baz(n: Promise): Promise { return n; } +} + + +//// [decoratorMetadataPromise.js] +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments)).next()); + }); +}; +class A { + foo() { + return __awaiter(this, void 0, void 0, function* () { }); + } + bar() { + return __awaiter(this, void 0, void 0, function* () { return 0; }); + } + baz(n) { return n; } +} +__decorate([ + decorator, + __metadata('design:type', Function), + __metadata('design:paramtypes', []), + __metadata('design:returntype', Promise) +], A.prototype, "foo", null); +__decorate([ + decorator, + __metadata('design:type', Function), + __metadata('design:paramtypes', []), + __metadata('design:returntype', Promise) +], A.prototype, "bar", null); +__decorate([ + decorator, + __metadata('design:type', Function), + __metadata('design:paramtypes', [Promise]), + __metadata('design:returntype', Promise) +], A.prototype, "baz", null); diff --git a/tests/baselines/reference/decoratorMetadataPromise.symbols b/tests/baselines/reference/decoratorMetadataPromise.symbols new file mode 100644 index 00000000000..b0ebe05e8c1 --- /dev/null +++ b/tests/baselines/reference/decoratorMetadataPromise.symbols @@ -0,0 +1,33 @@ +=== tests/cases/compiler/decoratorMetadataPromise.ts === + +declare const decorator: MethodDecorator; +>decorator : Symbol(decorator, Decl(decoratorMetadataPromise.ts, 1, 13)) +>MethodDecorator : Symbol(MethodDecorator, Decl(lib.es5.d.ts, --, --)) + +class A { +>A : Symbol(A, Decl(decoratorMetadataPromise.ts, 1, 41)) + + @decorator +>decorator : Symbol(decorator, Decl(decoratorMetadataPromise.ts, 1, 13)) + + async foo() {} +>foo : Symbol(A.foo, Decl(decoratorMetadataPromise.ts, 3, 9)) + + @decorator +>decorator : Symbol(decorator, Decl(decoratorMetadataPromise.ts, 1, 13)) + + async bar(): Promise { return 0; } +>bar : Symbol(A.bar, Decl(decoratorMetadataPromise.ts, 5, 18)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + + @decorator +>decorator : Symbol(decorator, Decl(decoratorMetadataPromise.ts, 1, 13)) + + baz(n: Promise): Promise { return n; } +>baz : Symbol(A.baz, Decl(decoratorMetadataPromise.ts, 7, 46)) +>n : Symbol(n, Decl(decoratorMetadataPromise.ts, 9, 8)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>n : Symbol(n, Decl(decoratorMetadataPromise.ts, 9, 8)) +} + diff --git a/tests/baselines/reference/decoratorMetadataPromise.types b/tests/baselines/reference/decoratorMetadataPromise.types new file mode 100644 index 00000000000..900e751e841 --- /dev/null +++ b/tests/baselines/reference/decoratorMetadataPromise.types @@ -0,0 +1,34 @@ +=== tests/cases/compiler/decoratorMetadataPromise.ts === + +declare const decorator: MethodDecorator; +>decorator : (target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor | void +>MethodDecorator : (target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor | void + +class A { +>A : A + + @decorator +>decorator : (target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor | void + + async foo() {} +>foo : () => Promise + + @decorator +>decorator : (target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor | void + + async bar(): Promise { return 0; } +>bar : () => Promise +>Promise : Promise +>0 : number + + @decorator +>decorator : (target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor | void + + baz(n: Promise): Promise { return n; } +>baz : (n: Promise) => Promise +>n : Promise +>Promise : Promise +>Promise : Promise +>n : Promise +} + diff --git a/tests/baselines/reference/defaultValueInFunctionTypes.errors.txt b/tests/baselines/reference/defaultValueInFunctionTypes.errors.txt index 01a807b3e7d..5544b9caae0 100644 --- a/tests/baselines/reference/defaultValueInFunctionTypes.errors.txt +++ b/tests/baselines/reference/defaultValueInFunctionTypes.errors.txt @@ -1,8 +1,11 @@ tests/cases/compiler/defaultValueInFunctionTypes.ts(1,9): error TS2371: A parameter initializer is only allowed in a function or constructor implementation. +tests/cases/compiler/defaultValueInFunctionTypes.ts(2,11): error TS2371: A parameter initializer is only allowed in a function or constructor implementation. -==== tests/cases/compiler/defaultValueInFunctionTypes.ts (1 errors) ==== +==== tests/cases/compiler/defaultValueInFunctionTypes.ts (2 errors) ==== var x: (a: number = 1) => number; ~~~~~~~~~~~~~ !!! error TS2371: A parameter initializer is only allowed in a function or constructor implementation. - var y = <(a : string = "") => any>(undefined) \ No newline at end of file + var y = <(a : string = "") => any>(undefined) + ~~~~~~~~~~~~~~~ +!!! error TS2371: A parameter initializer is only allowed in a function or constructor implementation. \ No newline at end of file diff --git a/tests/baselines/reference/discriminatedUnionTypes1.js b/tests/baselines/reference/discriminatedUnionTypes1.js new file mode 100644 index 00000000000..8679689569a --- /dev/null +++ b/tests/baselines/reference/discriminatedUnionTypes1.js @@ -0,0 +1,252 @@ +//// [discriminatedUnionTypes1.ts] +interface Square { + kind: "square"; + size: number; +} + +interface Rectangle { + kind: "rectangle"; + width: number; + height: number; +} + +interface Circle { + kind: "circle"; + radius: number; +} + +type Shape = Square | Rectangle | Circle; + +function area1(s: Shape) { + if (s.kind === "square") { + return s.size * s.size; + } + else if (s.kind === "circle") { + return Math.PI * s.radius * s.radius; + } + else if (s.kind === "rectangle") { + return s.width * s.height; + } + else { + return 0; + } +} + +function area2(s: Shape) { + switch (s.kind) { + case "square": return s.size * s.size; + case "rectangle": return s.width * s.height; + case "circle": return Math.PI * s.radius * s.radius; + } +} + +function assertNever(x: never): never { + throw new Error("Unexpected object: " + x); +} + +function area3(s: Shape) { + switch (s.kind) { + case "square": return s.size * s.size; + case "rectangle": return s.width * s.height; + case "circle": return Math.PI * s.radius * s.radius; + default: return assertNever(s); + } +} + +function area4(s: Shape) { + switch (s.kind) { + case "square": return s.size * s.size; + case "rectangle": return s.width * s.height; + case "circle": return Math.PI * s.radius * s.radius; + } + return assertNever(s); +} + +type Message = + { kind: "A", x: string } | + { kind: "B" | "C", y: number } | + { kind: "D" }; + +function f1(m: Message) { + if (m.kind === "A") { + m; // { kind: "A", x: string } + } + else if (m.kind === "D") { + m; // { kind: "D" } + } + else { + m; // { kind: "B" | "C", y: number } + } +} + +function f2(m: Message) { + if (m.kind === "A") { + return; + } + m; // { kind: "B" | "C", y: number } | { kind: "D" } +} + +function f3(m: Message) { + if (m.kind === "X") { + m; // never + } +} + +function f4(m: Message, x: "A" | "D") { + if (m.kind == x) { + m; // { kind: "A", x: string } | { kind: "D" } + } +} + +function f5(m: Message) { + switch (m.kind) { + case "A": + m; // { kind: "A", x: string } + break; + case "D": + m; // { kind: "D" } + break; + default: + m; // { kind: "B" | "C", y: number } + } +} + +function f6(m: Message) { + switch (m.kind) { + case "A": + m; // { kind: "A", x: string } + case "D": + m; // { kind: "A", x: string } | { kind: "D" } + break; + default: + m; // { kind: "B" | "C", y: number } + } +} + +function f7(m: Message) { + switch (m.kind) { + case "A": + case "B": + return; + } + m; // { kind: "B" | "C", y: number } | { kind: "D" } +} + +function f8(m: Message) { + switch (m.kind) { + case "A": + return; + case "D": + throw new Error(); + } + m; // { kind: "B" | "C", y: number } +} + +//// [discriminatedUnionTypes1.js] +function area1(s) { + if (s.kind === "square") { + return s.size * s.size; + } + else if (s.kind === "circle") { + return Math.PI * s.radius * s.radius; + } + else if (s.kind === "rectangle") { + return s.width * s.height; + } + else { + return 0; + } +} +function area2(s) { + switch (s.kind) { + case "square": return s.size * s.size; + case "rectangle": return s.width * s.height; + case "circle": return Math.PI * s.radius * s.radius; + } +} +function assertNever(x) { + throw new Error("Unexpected object: " + x); +} +function area3(s) { + switch (s.kind) { + case "square": return s.size * s.size; + case "rectangle": return s.width * s.height; + case "circle": return Math.PI * s.radius * s.radius; + default: return assertNever(s); + } +} +function area4(s) { + switch (s.kind) { + case "square": return s.size * s.size; + case "rectangle": return s.width * s.height; + case "circle": return Math.PI * s.radius * s.radius; + } + return assertNever(s); +} +function f1(m) { + if (m.kind === "A") { + m; // { kind: "A", x: string } + } + else if (m.kind === "D") { + m; // { kind: "D" } + } + else { + m; // { kind: "B" | "C", y: number } + } +} +function f2(m) { + if (m.kind === "A") { + return; + } + m; // { kind: "B" | "C", y: number } | { kind: "D" } +} +function f3(m) { + if (m.kind === "X") { + m; // never + } +} +function f4(m, x) { + if (m.kind == x) { + m; // { kind: "A", x: string } | { kind: "D" } + } +} +function f5(m) { + switch (m.kind) { + case "A": + m; // { kind: "A", x: string } + break; + case "D": + m; // { kind: "D" } + break; + default: + m; // { kind: "B" | "C", y: number } + } +} +function f6(m) { + switch (m.kind) { + case "A": + m; // { kind: "A", x: string } + case "D": + m; // { kind: "A", x: string } | { kind: "D" } + break; + default: + m; // { kind: "B" | "C", y: number } + } +} +function f7(m) { + switch (m.kind) { + case "A": + case "B": + return; + } + m; // { kind: "B" | "C", y: number } | { kind: "D" } +} +function f8(m) { + switch (m.kind) { + case "A": + return; + case "D": + throw new Error(); + } + m; // { kind: "B" | "C", y: number } +} diff --git a/tests/baselines/reference/discriminatedUnionTypes1.symbols b/tests/baselines/reference/discriminatedUnionTypes1.symbols new file mode 100644 index 00000000000..38069447423 --- /dev/null +++ b/tests/baselines/reference/discriminatedUnionTypes1.symbols @@ -0,0 +1,402 @@ +=== tests/cases/conformance/types/union/discriminatedUnionTypes1.ts === +interface Square { +>Square : Symbol(Square, Decl(discriminatedUnionTypes1.ts, 0, 0)) + + kind: "square"; +>kind : Symbol(Square.kind, Decl(discriminatedUnionTypes1.ts, 0, 18)) + + size: number; +>size : Symbol(Square.size, Decl(discriminatedUnionTypes1.ts, 1, 19)) +} + +interface Rectangle { +>Rectangle : Symbol(Rectangle, Decl(discriminatedUnionTypes1.ts, 3, 1)) + + kind: "rectangle"; +>kind : Symbol(Rectangle.kind, Decl(discriminatedUnionTypes1.ts, 5, 21)) + + width: number; +>width : Symbol(Rectangle.width, Decl(discriminatedUnionTypes1.ts, 6, 22)) + + height: number; +>height : Symbol(Rectangle.height, Decl(discriminatedUnionTypes1.ts, 7, 18)) +} + +interface Circle { +>Circle : Symbol(Circle, Decl(discriminatedUnionTypes1.ts, 9, 1)) + + kind: "circle"; +>kind : Symbol(Circle.kind, Decl(discriminatedUnionTypes1.ts, 11, 18)) + + radius: number; +>radius : Symbol(Circle.radius, Decl(discriminatedUnionTypes1.ts, 12, 19)) +} + +type Shape = Square | Rectangle | Circle; +>Shape : Symbol(Shape, Decl(discriminatedUnionTypes1.ts, 14, 1)) +>Square : Symbol(Square, Decl(discriminatedUnionTypes1.ts, 0, 0)) +>Rectangle : Symbol(Rectangle, Decl(discriminatedUnionTypes1.ts, 3, 1)) +>Circle : Symbol(Circle, Decl(discriminatedUnionTypes1.ts, 9, 1)) + +function area1(s: Shape) { +>area1 : Symbol(area1, Decl(discriminatedUnionTypes1.ts, 16, 41)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 18, 15)) +>Shape : Symbol(Shape, Decl(discriminatedUnionTypes1.ts, 14, 1)) + + if (s.kind === "square") { +>s.kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 0, 18), Decl(discriminatedUnionTypes1.ts, 5, 21), Decl(discriminatedUnionTypes1.ts, 11, 18)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 18, 15)) +>kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 0, 18), Decl(discriminatedUnionTypes1.ts, 5, 21), Decl(discriminatedUnionTypes1.ts, 11, 18)) + + return s.size * s.size; +>s.size : Symbol(Square.size, Decl(discriminatedUnionTypes1.ts, 1, 19)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 18, 15)) +>size : Symbol(Square.size, Decl(discriminatedUnionTypes1.ts, 1, 19)) +>s.size : Symbol(Square.size, Decl(discriminatedUnionTypes1.ts, 1, 19)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 18, 15)) +>size : Symbol(Square.size, Decl(discriminatedUnionTypes1.ts, 1, 19)) + } + else if (s.kind === "circle") { +>s.kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 5, 21), Decl(discriminatedUnionTypes1.ts, 11, 18)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 18, 15)) +>kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 5, 21), Decl(discriminatedUnionTypes1.ts, 11, 18)) + + return Math.PI * s.radius * s.radius; +>Math.PI : Symbol(Math.PI, Decl(lib.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>PI : Symbol(Math.PI, Decl(lib.d.ts, --, --)) +>s.radius : Symbol(Circle.radius, Decl(discriminatedUnionTypes1.ts, 12, 19)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 18, 15)) +>radius : Symbol(Circle.radius, Decl(discriminatedUnionTypes1.ts, 12, 19)) +>s.radius : Symbol(Circle.radius, Decl(discriminatedUnionTypes1.ts, 12, 19)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 18, 15)) +>radius : Symbol(Circle.radius, Decl(discriminatedUnionTypes1.ts, 12, 19)) + } + else if (s.kind === "rectangle") { +>s.kind : Symbol(Rectangle.kind, Decl(discriminatedUnionTypes1.ts, 5, 21)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 18, 15)) +>kind : Symbol(Rectangle.kind, Decl(discriminatedUnionTypes1.ts, 5, 21)) + + return s.width * s.height; +>s.width : Symbol(Rectangle.width, Decl(discriminatedUnionTypes1.ts, 6, 22)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 18, 15)) +>width : Symbol(Rectangle.width, Decl(discriminatedUnionTypes1.ts, 6, 22)) +>s.height : Symbol(Rectangle.height, Decl(discriminatedUnionTypes1.ts, 7, 18)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 18, 15)) +>height : Symbol(Rectangle.height, Decl(discriminatedUnionTypes1.ts, 7, 18)) + } + else { + return 0; + } +} + +function area2(s: Shape) { +>area2 : Symbol(area2, Decl(discriminatedUnionTypes1.ts, 31, 1)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 33, 15)) +>Shape : Symbol(Shape, Decl(discriminatedUnionTypes1.ts, 14, 1)) + + switch (s.kind) { +>s.kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 0, 18), Decl(discriminatedUnionTypes1.ts, 5, 21), Decl(discriminatedUnionTypes1.ts, 11, 18)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 33, 15)) +>kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 0, 18), Decl(discriminatedUnionTypes1.ts, 5, 21), Decl(discriminatedUnionTypes1.ts, 11, 18)) + + case "square": return s.size * s.size; +>s.size : Symbol(Square.size, Decl(discriminatedUnionTypes1.ts, 1, 19)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 33, 15)) +>size : Symbol(Square.size, Decl(discriminatedUnionTypes1.ts, 1, 19)) +>s.size : Symbol(Square.size, Decl(discriminatedUnionTypes1.ts, 1, 19)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 33, 15)) +>size : Symbol(Square.size, Decl(discriminatedUnionTypes1.ts, 1, 19)) + + case "rectangle": return s.width * s.height; +>s.width : Symbol(Rectangle.width, Decl(discriminatedUnionTypes1.ts, 6, 22)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 33, 15)) +>width : Symbol(Rectangle.width, Decl(discriminatedUnionTypes1.ts, 6, 22)) +>s.height : Symbol(Rectangle.height, Decl(discriminatedUnionTypes1.ts, 7, 18)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 33, 15)) +>height : Symbol(Rectangle.height, Decl(discriminatedUnionTypes1.ts, 7, 18)) + + case "circle": return Math.PI * s.radius * s.radius; +>Math.PI : Symbol(Math.PI, Decl(lib.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>PI : Symbol(Math.PI, Decl(lib.d.ts, --, --)) +>s.radius : Symbol(Circle.radius, Decl(discriminatedUnionTypes1.ts, 12, 19)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 33, 15)) +>radius : Symbol(Circle.radius, Decl(discriminatedUnionTypes1.ts, 12, 19)) +>s.radius : Symbol(Circle.radius, Decl(discriminatedUnionTypes1.ts, 12, 19)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 33, 15)) +>radius : Symbol(Circle.radius, Decl(discriminatedUnionTypes1.ts, 12, 19)) + } +} + +function assertNever(x: never): never { +>assertNever : Symbol(assertNever, Decl(discriminatedUnionTypes1.ts, 39, 1)) +>x : Symbol(x, Decl(discriminatedUnionTypes1.ts, 41, 21)) + + throw new Error("Unexpected object: " + x); +>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(discriminatedUnionTypes1.ts, 41, 21)) +} + +function area3(s: Shape) { +>area3 : Symbol(area3, Decl(discriminatedUnionTypes1.ts, 43, 1)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 45, 15)) +>Shape : Symbol(Shape, Decl(discriminatedUnionTypes1.ts, 14, 1)) + + switch (s.kind) { +>s.kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 0, 18), Decl(discriminatedUnionTypes1.ts, 5, 21), Decl(discriminatedUnionTypes1.ts, 11, 18)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 45, 15)) +>kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 0, 18), Decl(discriminatedUnionTypes1.ts, 5, 21), Decl(discriminatedUnionTypes1.ts, 11, 18)) + + case "square": return s.size * s.size; +>s.size : Symbol(Square.size, Decl(discriminatedUnionTypes1.ts, 1, 19)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 45, 15)) +>size : Symbol(Square.size, Decl(discriminatedUnionTypes1.ts, 1, 19)) +>s.size : Symbol(Square.size, Decl(discriminatedUnionTypes1.ts, 1, 19)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 45, 15)) +>size : Symbol(Square.size, Decl(discriminatedUnionTypes1.ts, 1, 19)) + + case "rectangle": return s.width * s.height; +>s.width : Symbol(Rectangle.width, Decl(discriminatedUnionTypes1.ts, 6, 22)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 45, 15)) +>width : Symbol(Rectangle.width, Decl(discriminatedUnionTypes1.ts, 6, 22)) +>s.height : Symbol(Rectangle.height, Decl(discriminatedUnionTypes1.ts, 7, 18)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 45, 15)) +>height : Symbol(Rectangle.height, Decl(discriminatedUnionTypes1.ts, 7, 18)) + + case "circle": return Math.PI * s.radius * s.radius; +>Math.PI : Symbol(Math.PI, Decl(lib.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>PI : Symbol(Math.PI, Decl(lib.d.ts, --, --)) +>s.radius : Symbol(Circle.radius, Decl(discriminatedUnionTypes1.ts, 12, 19)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 45, 15)) +>radius : Symbol(Circle.radius, Decl(discriminatedUnionTypes1.ts, 12, 19)) +>s.radius : Symbol(Circle.radius, Decl(discriminatedUnionTypes1.ts, 12, 19)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 45, 15)) +>radius : Symbol(Circle.radius, Decl(discriminatedUnionTypes1.ts, 12, 19)) + + default: return assertNever(s); +>assertNever : Symbol(assertNever, Decl(discriminatedUnionTypes1.ts, 39, 1)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 45, 15)) + } +} + +function area4(s: Shape) { +>area4 : Symbol(area4, Decl(discriminatedUnionTypes1.ts, 52, 1)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 54, 15)) +>Shape : Symbol(Shape, Decl(discriminatedUnionTypes1.ts, 14, 1)) + + switch (s.kind) { +>s.kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 0, 18), Decl(discriminatedUnionTypes1.ts, 5, 21), Decl(discriminatedUnionTypes1.ts, 11, 18)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 54, 15)) +>kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 0, 18), Decl(discriminatedUnionTypes1.ts, 5, 21), Decl(discriminatedUnionTypes1.ts, 11, 18)) + + case "square": return s.size * s.size; +>s.size : Symbol(Square.size, Decl(discriminatedUnionTypes1.ts, 1, 19)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 54, 15)) +>size : Symbol(Square.size, Decl(discriminatedUnionTypes1.ts, 1, 19)) +>s.size : Symbol(Square.size, Decl(discriminatedUnionTypes1.ts, 1, 19)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 54, 15)) +>size : Symbol(Square.size, Decl(discriminatedUnionTypes1.ts, 1, 19)) + + case "rectangle": return s.width * s.height; +>s.width : Symbol(Rectangle.width, Decl(discriminatedUnionTypes1.ts, 6, 22)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 54, 15)) +>width : Symbol(Rectangle.width, Decl(discriminatedUnionTypes1.ts, 6, 22)) +>s.height : Symbol(Rectangle.height, Decl(discriminatedUnionTypes1.ts, 7, 18)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 54, 15)) +>height : Symbol(Rectangle.height, Decl(discriminatedUnionTypes1.ts, 7, 18)) + + case "circle": return Math.PI * s.radius * s.radius; +>Math.PI : Symbol(Math.PI, Decl(lib.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>PI : Symbol(Math.PI, Decl(lib.d.ts, --, --)) +>s.radius : Symbol(Circle.radius, Decl(discriminatedUnionTypes1.ts, 12, 19)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 54, 15)) +>radius : Symbol(Circle.radius, Decl(discriminatedUnionTypes1.ts, 12, 19)) +>s.radius : Symbol(Circle.radius, Decl(discriminatedUnionTypes1.ts, 12, 19)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 54, 15)) +>radius : Symbol(Circle.radius, Decl(discriminatedUnionTypes1.ts, 12, 19)) + } + return assertNever(s); +>assertNever : Symbol(assertNever, Decl(discriminatedUnionTypes1.ts, 39, 1)) +>s : Symbol(s, Decl(discriminatedUnionTypes1.ts, 54, 15)) +} + +type Message = +>Message : Symbol(Message, Decl(discriminatedUnionTypes1.ts, 61, 1)) + + { kind: "A", x: string } | +>kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 64, 5)) +>x : Symbol(x, Decl(discriminatedUnionTypes1.ts, 64, 16)) + + { kind: "B" | "C", y: number } | +>kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 65, 5)) +>y : Symbol(y, Decl(discriminatedUnionTypes1.ts, 65, 22)) + + { kind: "D" }; +>kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 66, 5)) + +function f1(m: Message) { +>f1 : Symbol(f1, Decl(discriminatedUnionTypes1.ts, 66, 18)) +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 68, 12)) +>Message : Symbol(Message, Decl(discriminatedUnionTypes1.ts, 61, 1)) + + if (m.kind === "A") { +>m.kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 64, 5), Decl(discriminatedUnionTypes1.ts, 65, 5), Decl(discriminatedUnionTypes1.ts, 66, 5)) +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 68, 12)) +>kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 64, 5), Decl(discriminatedUnionTypes1.ts, 65, 5), Decl(discriminatedUnionTypes1.ts, 66, 5)) + + m; // { kind: "A", x: string } +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 68, 12)) + } + else if (m.kind === "D") { +>m.kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 65, 5), Decl(discriminatedUnionTypes1.ts, 66, 5)) +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 68, 12)) +>kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 65, 5), Decl(discriminatedUnionTypes1.ts, 66, 5)) + + m; // { kind: "D" } +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 68, 12)) + } + else { + m; // { kind: "B" | "C", y: number } +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 68, 12)) + } +} + +function f2(m: Message) { +>f2 : Symbol(f2, Decl(discriminatedUnionTypes1.ts, 78, 1)) +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 80, 12)) +>Message : Symbol(Message, Decl(discriminatedUnionTypes1.ts, 61, 1)) + + if (m.kind === "A") { +>m.kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 64, 5), Decl(discriminatedUnionTypes1.ts, 65, 5), Decl(discriminatedUnionTypes1.ts, 66, 5)) +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 80, 12)) +>kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 64, 5), Decl(discriminatedUnionTypes1.ts, 65, 5), Decl(discriminatedUnionTypes1.ts, 66, 5)) + + return; + } + m; // { kind: "B" | "C", y: number } | { kind: "D" } +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 80, 12)) +} + +function f3(m: Message) { +>f3 : Symbol(f3, Decl(discriminatedUnionTypes1.ts, 85, 1)) +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 87, 12)) +>Message : Symbol(Message, Decl(discriminatedUnionTypes1.ts, 61, 1)) + + if (m.kind === "X") { +>m.kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 64, 5), Decl(discriminatedUnionTypes1.ts, 65, 5), Decl(discriminatedUnionTypes1.ts, 66, 5)) +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 87, 12)) +>kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 64, 5), Decl(discriminatedUnionTypes1.ts, 65, 5), Decl(discriminatedUnionTypes1.ts, 66, 5)) + + m; // never +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 87, 12)) + } +} + +function f4(m: Message, x: "A" | "D") { +>f4 : Symbol(f4, Decl(discriminatedUnionTypes1.ts, 91, 1)) +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 93, 12)) +>Message : Symbol(Message, Decl(discriminatedUnionTypes1.ts, 61, 1)) +>x : Symbol(x, Decl(discriminatedUnionTypes1.ts, 93, 23)) + + if (m.kind == x) { +>m.kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 64, 5), Decl(discriminatedUnionTypes1.ts, 65, 5), Decl(discriminatedUnionTypes1.ts, 66, 5)) +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 93, 12)) +>kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 64, 5), Decl(discriminatedUnionTypes1.ts, 65, 5), Decl(discriminatedUnionTypes1.ts, 66, 5)) +>x : Symbol(x, Decl(discriminatedUnionTypes1.ts, 93, 23)) + + m; // { kind: "A", x: string } | { kind: "D" } +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 93, 12)) + } +} + +function f5(m: Message) { +>f5 : Symbol(f5, Decl(discriminatedUnionTypes1.ts, 97, 1)) +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 99, 12)) +>Message : Symbol(Message, Decl(discriminatedUnionTypes1.ts, 61, 1)) + + switch (m.kind) { +>m.kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 64, 5), Decl(discriminatedUnionTypes1.ts, 65, 5), Decl(discriminatedUnionTypes1.ts, 66, 5)) +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 99, 12)) +>kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 64, 5), Decl(discriminatedUnionTypes1.ts, 65, 5), Decl(discriminatedUnionTypes1.ts, 66, 5)) + + case "A": + m; // { kind: "A", x: string } +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 99, 12)) + + break; + case "D": + m; // { kind: "D" } +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 99, 12)) + + break; + default: + m; // { kind: "B" | "C", y: number } +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 99, 12)) + } +} + +function f6(m: Message) { +>f6 : Symbol(f6, Decl(discriminatedUnionTypes1.ts, 110, 1)) +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 112, 12)) +>Message : Symbol(Message, Decl(discriminatedUnionTypes1.ts, 61, 1)) + + switch (m.kind) { +>m.kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 64, 5), Decl(discriminatedUnionTypes1.ts, 65, 5), Decl(discriminatedUnionTypes1.ts, 66, 5)) +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 112, 12)) +>kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 64, 5), Decl(discriminatedUnionTypes1.ts, 65, 5), Decl(discriminatedUnionTypes1.ts, 66, 5)) + + case "A": + m; // { kind: "A", x: string } +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 112, 12)) + + case "D": + m; // { kind: "A", x: string } | { kind: "D" } +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 112, 12)) + + break; + default: + m; // { kind: "B" | "C", y: number } +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 112, 12)) + } +} + +function f7(m: Message) { +>f7 : Symbol(f7, Decl(discriminatedUnionTypes1.ts, 122, 1)) +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 124, 12)) +>Message : Symbol(Message, Decl(discriminatedUnionTypes1.ts, 61, 1)) + + switch (m.kind) { +>m.kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 64, 5), Decl(discriminatedUnionTypes1.ts, 65, 5), Decl(discriminatedUnionTypes1.ts, 66, 5)) +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 124, 12)) +>kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 64, 5), Decl(discriminatedUnionTypes1.ts, 65, 5), Decl(discriminatedUnionTypes1.ts, 66, 5)) + + case "A": + case "B": + return; + } + m; // { kind: "B" | "C", y: number } | { kind: "D" } +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 124, 12)) +} + +function f8(m: Message) { +>f8 : Symbol(f8, Decl(discriminatedUnionTypes1.ts, 131, 1)) +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 133, 12)) +>Message : Symbol(Message, Decl(discriminatedUnionTypes1.ts, 61, 1)) + + switch (m.kind) { +>m.kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 64, 5), Decl(discriminatedUnionTypes1.ts, 65, 5), Decl(discriminatedUnionTypes1.ts, 66, 5)) +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 133, 12)) +>kind : Symbol(kind, Decl(discriminatedUnionTypes1.ts, 64, 5), Decl(discriminatedUnionTypes1.ts, 65, 5), Decl(discriminatedUnionTypes1.ts, 66, 5)) + + case "A": + return; + case "D": + throw new Error(); +>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + } + m; // { kind: "B" | "C", y: number } +>m : Symbol(m, Decl(discriminatedUnionTypes1.ts, 133, 12)) +} diff --git a/tests/baselines/reference/discriminatedUnionTypes1.types b/tests/baselines/reference/discriminatedUnionTypes1.types new file mode 100644 index 00000000000..234de28eaba --- /dev/null +++ b/tests/baselines/reference/discriminatedUnionTypes1.types @@ -0,0 +1,465 @@ +=== tests/cases/conformance/types/union/discriminatedUnionTypes1.ts === +interface Square { +>Square : Square + + kind: "square"; +>kind : "square" + + size: number; +>size : number +} + +interface Rectangle { +>Rectangle : Rectangle + + kind: "rectangle"; +>kind : "rectangle" + + width: number; +>width : number + + height: number; +>height : number +} + +interface Circle { +>Circle : Circle + + kind: "circle"; +>kind : "circle" + + radius: number; +>radius : number +} + +type Shape = Square | Rectangle | Circle; +>Shape : Square | Rectangle | Circle +>Square : Square +>Rectangle : Rectangle +>Circle : Circle + +function area1(s: Shape) { +>area1 : (s: Square | Rectangle | Circle) => number +>s : Square | Rectangle | Circle +>Shape : Square | Rectangle | Circle + + if (s.kind === "square") { +>s.kind === "square" : boolean +>s.kind : "square" | "rectangle" | "circle" +>s : Square | Rectangle | Circle +>kind : "square" | "rectangle" | "circle" +>"square" : string + + return s.size * s.size; +>s.size * s.size : number +>s.size : number +>s : Square +>size : number +>s.size : number +>s : Square +>size : number + } + else if (s.kind === "circle") { +>s.kind === "circle" : boolean +>s.kind : "rectangle" | "circle" +>s : Rectangle | Circle +>kind : "rectangle" | "circle" +>"circle" : string + + return Math.PI * s.radius * s.radius; +>Math.PI * s.radius * s.radius : number +>Math.PI * s.radius : number +>Math.PI : number +>Math : Math +>PI : number +>s.radius : number +>s : Circle +>radius : number +>s.radius : number +>s : Circle +>radius : number + } + else if (s.kind === "rectangle") { +>s.kind === "rectangle" : boolean +>s.kind : "rectangle" +>s : Rectangle +>kind : "rectangle" +>"rectangle" : string + + return s.width * s.height; +>s.width * s.height : number +>s.width : number +>s : Rectangle +>width : number +>s.height : number +>s : Rectangle +>height : number + } + else { + return 0; +>0 : number + } +} + +function area2(s: Shape) { +>area2 : (s: Square | Rectangle | Circle) => number +>s : Square | Rectangle | Circle +>Shape : Square | Rectangle | Circle + + switch (s.kind) { +>s.kind : "square" | "rectangle" | "circle" +>s : Square | Rectangle | Circle +>kind : "square" | "rectangle" | "circle" + + case "square": return s.size * s.size; +>"square" : string +>s.size * s.size : number +>s.size : number +>s : Square +>size : number +>s.size : number +>s : Square +>size : number + + case "rectangle": return s.width * s.height; +>"rectangle" : string +>s.width * s.height : number +>s.width : number +>s : Rectangle +>width : number +>s.height : number +>s : Rectangle +>height : number + + case "circle": return Math.PI * s.radius * s.radius; +>"circle" : string +>Math.PI * s.radius * s.radius : number +>Math.PI * s.radius : number +>Math.PI : number +>Math : Math +>PI : number +>s.radius : number +>s : Circle +>radius : number +>s.radius : number +>s : Circle +>radius : number + } +} + +function assertNever(x: never): never { +>assertNever : (x: never) => never +>x : never + + throw new Error("Unexpected object: " + x); +>new Error("Unexpected object: " + x) : Error +>Error : ErrorConstructor +>"Unexpected object: " + x : string +>"Unexpected object: " : string +>x : never +} + +function area3(s: Shape) { +>area3 : (s: Square | Rectangle | Circle) => number +>s : Square | Rectangle | Circle +>Shape : Square | Rectangle | Circle + + switch (s.kind) { +>s.kind : "square" | "rectangle" | "circle" +>s : Square | Rectangle | Circle +>kind : "square" | "rectangle" | "circle" + + case "square": return s.size * s.size; +>"square" : string +>s.size * s.size : number +>s.size : number +>s : Square +>size : number +>s.size : number +>s : Square +>size : number + + case "rectangle": return s.width * s.height; +>"rectangle" : string +>s.width * s.height : number +>s.width : number +>s : Rectangle +>width : number +>s.height : number +>s : Rectangle +>height : number + + case "circle": return Math.PI * s.radius * s.radius; +>"circle" : string +>Math.PI * s.radius * s.radius : number +>Math.PI * s.radius : number +>Math.PI : number +>Math : Math +>PI : number +>s.radius : number +>s : Circle +>radius : number +>s.radius : number +>s : Circle +>radius : number + + default: return assertNever(s); +>assertNever(s) : never +>assertNever : (x: never) => never +>s : never + } +} + +function area4(s: Shape) { +>area4 : (s: Square | Rectangle | Circle) => number +>s : Square | Rectangle | Circle +>Shape : Square | Rectangle | Circle + + switch (s.kind) { +>s.kind : "square" | "rectangle" | "circle" +>s : Square | Rectangle | Circle +>kind : "square" | "rectangle" | "circle" + + case "square": return s.size * s.size; +>"square" : string +>s.size * s.size : number +>s.size : number +>s : Square +>size : number +>s.size : number +>s : Square +>size : number + + case "rectangle": return s.width * s.height; +>"rectangle" : string +>s.width * s.height : number +>s.width : number +>s : Rectangle +>width : number +>s.height : number +>s : Rectangle +>height : number + + case "circle": return Math.PI * s.radius * s.radius; +>"circle" : string +>Math.PI * s.radius * s.radius : number +>Math.PI * s.radius : number +>Math.PI : number +>Math : Math +>PI : number +>s.radius : number +>s : Circle +>radius : number +>s.radius : number +>s : Circle +>radius : number + } + return assertNever(s); +>assertNever(s) : never +>assertNever : (x: never) => never +>s : never +} + +type Message = +>Message : { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; } + + { kind: "A", x: string } | +>kind : "A" +>x : string + + { kind: "B" | "C", y: number } | +>kind : "B" | "C" +>y : number + + { kind: "D" }; +>kind : "D" + +function f1(m: Message) { +>f1 : (m: { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; }) => void +>m : { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; } +>Message : { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; } + + if (m.kind === "A") { +>m.kind === "A" : boolean +>m.kind : "A" | "B" | "C" | "D" +>m : { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; } +>kind : "A" | "B" | "C" | "D" +>"A" : string + + m; // { kind: "A", x: string } +>m : { kind: "A"; x: string; } + } + else if (m.kind === "D") { +>m.kind === "D" : boolean +>m.kind : "B" | "C" | "D" +>m : { kind: "B" | "C"; y: number; } | { kind: "D"; } +>kind : "B" | "C" | "D" +>"D" : string + + m; // { kind: "D" } +>m : { kind: "D"; } + } + else { + m; // { kind: "B" | "C", y: number } +>m : { kind: "B" | "C"; y: number; } + } +} + +function f2(m: Message) { +>f2 : (m: { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; }) => void +>m : { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; } +>Message : { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; } + + if (m.kind === "A") { +>m.kind === "A" : boolean +>m.kind : "A" | "B" | "C" | "D" +>m : { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; } +>kind : "A" | "B" | "C" | "D" +>"A" : string + + return; + } + m; // { kind: "B" | "C", y: number } | { kind: "D" } +>m : { kind: "B" | "C"; y: number; } | { kind: "D"; } +} + +function f3(m: Message) { +>f3 : (m: { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; }) => void +>m : { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; } +>Message : { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; } + + if (m.kind === "X") { +>m.kind === "X" : boolean +>m.kind : "A" | "B" | "C" | "D" +>m : { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; } +>kind : "A" | "B" | "C" | "D" +>"X" : string + + m; // never +>m : never + } +} + +function f4(m: Message, x: "A" | "D") { +>f4 : (m: { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; }, x: "A" | "D") => void +>m : { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; } +>Message : { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; } +>x : "A" | "D" + + if (m.kind == x) { +>m.kind == x : boolean +>m.kind : "A" | "B" | "C" | "D" +>m : { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; } +>kind : "A" | "B" | "C" | "D" +>x : "A" | "D" + + m; // { kind: "A", x: string } | { kind: "D" } +>m : { kind: "A"; x: string; } | { kind: "D"; } + } +} + +function f5(m: Message) { +>f5 : (m: { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; }) => void +>m : { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; } +>Message : { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; } + + switch (m.kind) { +>m.kind : "A" | "B" | "C" | "D" +>m : { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; } +>kind : "A" | "B" | "C" | "D" + + case "A": +>"A" : string + + m; // { kind: "A", x: string } +>m : { kind: "A"; x: string; } + + break; + case "D": +>"D" : string + + m; // { kind: "D" } +>m : { kind: "D"; } + + break; + default: + m; // { kind: "B" | "C", y: number } +>m : { kind: "B" | "C"; y: number; } + } +} + +function f6(m: Message) { +>f6 : (m: { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; }) => void +>m : { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; } +>Message : { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; } + + switch (m.kind) { +>m.kind : "A" | "B" | "C" | "D" +>m : { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; } +>kind : "A" | "B" | "C" | "D" + + case "A": +>"A" : string + + m; // { kind: "A", x: string } +>m : { kind: "A"; x: string; } + + case "D": +>"D" : string + + m; // { kind: "A", x: string } | { kind: "D" } +>m : { kind: "D"; } | { kind: "A"; x: string; } + + break; + default: + m; // { kind: "B" | "C", y: number } +>m : { kind: "B" | "C"; y: number; } + } +} + +function f7(m: Message) { +>f7 : (m: { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; }) => void +>m : { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; } +>Message : { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; } + + switch (m.kind) { +>m.kind : "A" | "B" | "C" | "D" +>m : { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; } +>kind : "A" | "B" | "C" | "D" + + case "A": +>"A" : string + + case "B": +>"B" : string + + return; + } + m; // { kind: "B" | "C", y: number } | { kind: "D" } +>m : { kind: "B" | "C"; y: number; } | { kind: "D"; } +} + +function f8(m: Message) { +>f8 : (m: { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; }) => void +>m : { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; } +>Message : { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; } + + switch (m.kind) { +>m.kind : "A" | "B" | "C" | "D" +>m : { kind: "A"; x: string; } | { kind: "B" | "C"; y: number; } | { kind: "D"; } +>kind : "A" | "B" | "C" | "D" + + case "A": +>"A" : string + + return; + case "D": +>"D" : string + + throw new Error(); +>new Error() : Error +>Error : ErrorConstructor + } + m; // { kind: "B" | "C", y: number } +>m : { kind: "B" | "C"; y: number; } +} diff --git a/tests/baselines/reference/duplicatePropertiesInTypeAssertions01.errors.txt b/tests/baselines/reference/duplicatePropertiesInTypeAssertions01.errors.txt new file mode 100644 index 00000000000..80b108bbd66 --- /dev/null +++ b/tests/baselines/reference/duplicatePropertiesInTypeAssertions01.errors.txt @@ -0,0 +1,11 @@ +tests/cases/conformance/expressions/typeAssertions/duplicatePropertiesInTypeAssertions01.ts(2,11): error TS2300: Duplicate identifier 'a'. +tests/cases/conformance/expressions/typeAssertions/duplicatePropertiesInTypeAssertions01.ts(2,22): error TS2300: Duplicate identifier 'a'. + + +==== tests/cases/conformance/expressions/typeAssertions/duplicatePropertiesInTypeAssertions01.ts (2 errors) ==== + + let x = <{a: number; a: number}>{}; + ~ +!!! error TS2300: Duplicate identifier 'a'. + ~ +!!! error TS2300: Duplicate identifier 'a'. \ No newline at end of file diff --git a/tests/baselines/reference/duplicatePropertiesInTypeAssertions01.js b/tests/baselines/reference/duplicatePropertiesInTypeAssertions01.js new file mode 100644 index 00000000000..03f46ad110a --- /dev/null +++ b/tests/baselines/reference/duplicatePropertiesInTypeAssertions01.js @@ -0,0 +1,12 @@ +//// [duplicatePropertiesInTypeAssertions01.ts] + +let x = <{a: number; a: number}>{}; + +//// [duplicatePropertiesInTypeAssertions01.js] +var x = {}; + + +//// [duplicatePropertiesInTypeAssertions01.d.ts] +declare let x: { + a: number; +}; diff --git a/tests/baselines/reference/duplicatePropertiesInTypeAssertions02.errors.txt b/tests/baselines/reference/duplicatePropertiesInTypeAssertions02.errors.txt new file mode 100644 index 00000000000..eeb9ffa9302 --- /dev/null +++ b/tests/baselines/reference/duplicatePropertiesInTypeAssertions02.errors.txt @@ -0,0 +1,11 @@ +tests/cases/conformance/expressions/typeAssertions/duplicatePropertiesInTypeAssertions02.ts(2,16): error TS2300: Duplicate identifier 'a'. +tests/cases/conformance/expressions/typeAssertions/duplicatePropertiesInTypeAssertions02.ts(2,27): error TS2300: Duplicate identifier 'a'. + + +==== tests/cases/conformance/expressions/typeAssertions/duplicatePropertiesInTypeAssertions02.ts (2 errors) ==== + + let x = {} as {a: number; a: number}; + ~ +!!! error TS2300: Duplicate identifier 'a'. + ~ +!!! error TS2300: Duplicate identifier 'a'. \ No newline at end of file diff --git a/tests/baselines/reference/duplicatePropertiesInTypeAssertions02.js b/tests/baselines/reference/duplicatePropertiesInTypeAssertions02.js new file mode 100644 index 00000000000..8aa4449595a --- /dev/null +++ b/tests/baselines/reference/duplicatePropertiesInTypeAssertions02.js @@ -0,0 +1,12 @@ +//// [duplicatePropertiesInTypeAssertions02.ts] + +let x = {} as {a: number; a: number}; + +//// [duplicatePropertiesInTypeAssertions02.js] +var x = {}; + + +//// [duplicatePropertiesInTypeAssertions02.d.ts] +declare let x: { + a: number; +}; diff --git a/tests/baselines/reference/emitDecoratorMetadata_restArgs.js b/tests/baselines/reference/emitDecoratorMetadata_restArgs.js new file mode 100644 index 00000000000..35350c54e0a --- /dev/null +++ b/tests/baselines/reference/emitDecoratorMetadata_restArgs.js @@ -0,0 +1,80 @@ +//// [emitDecoratorMetadata_restArgs.ts] + +declare const MyClassDecorator: ClassDecorator; +declare const MyMethodDecorator: MethodDecorator; + +@MyClassDecorator +class A { + constructor(...args) {} + @MyMethodDecorator + method(...args) {} +} + +@MyClassDecorator +class B { + constructor(...args: number[]) {} + @MyMethodDecorator + method(...args: string[]) {} +} + + +//// [emitDecoratorMetadata_restArgs.js] +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var A = (function () { + function A() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i - 0] = arguments[_i]; + } + } + A.prototype.method = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i - 0] = arguments[_i]; + } + }; + __decorate([ + MyMethodDecorator, + __metadata('design:type', Function), + __metadata('design:paramtypes', [Object]), + __metadata('design:returntype', void 0) + ], A.prototype, "method", null); + A = __decorate([ + MyClassDecorator, + __metadata('design:paramtypes', [Object]) + ], A); + return A; +}()); +var B = (function () { + function B() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i - 0] = arguments[_i]; + } + } + B.prototype.method = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i - 0] = arguments[_i]; + } + }; + __decorate([ + MyMethodDecorator, + __metadata('design:type', Function), + __metadata('design:paramtypes', [String]), + __metadata('design:returntype', void 0) + ], B.prototype, "method", null); + B = __decorate([ + MyClassDecorator, + __metadata('design:paramtypes', [Number]) + ], B); + return B; +}()); diff --git a/tests/baselines/reference/emitDecoratorMetadata_restArgs.symbols b/tests/baselines/reference/emitDecoratorMetadata_restArgs.symbols new file mode 100644 index 00000000000..b665b778f86 --- /dev/null +++ b/tests/baselines/reference/emitDecoratorMetadata_restArgs.symbols @@ -0,0 +1,44 @@ +=== tests/cases/compiler/emitDecoratorMetadata_restArgs.ts === + +declare const MyClassDecorator: ClassDecorator; +>MyClassDecorator : Symbol(MyClassDecorator, Decl(emitDecoratorMetadata_restArgs.ts, 1, 13)) +>ClassDecorator : Symbol(ClassDecorator, Decl(lib.d.ts, --, --)) + +declare const MyMethodDecorator: MethodDecorator; +>MyMethodDecorator : Symbol(MyMethodDecorator, Decl(emitDecoratorMetadata_restArgs.ts, 2, 13)) +>MethodDecorator : Symbol(MethodDecorator, Decl(lib.d.ts, --, --)) + +@MyClassDecorator +>MyClassDecorator : Symbol(MyClassDecorator, Decl(emitDecoratorMetadata_restArgs.ts, 1, 13)) + +class A { +>A : Symbol(A, Decl(emitDecoratorMetadata_restArgs.ts, 2, 49)) + + constructor(...args) {} +>args : Symbol(args, Decl(emitDecoratorMetadata_restArgs.ts, 6, 16)) + + @MyMethodDecorator +>MyMethodDecorator : Symbol(MyMethodDecorator, Decl(emitDecoratorMetadata_restArgs.ts, 2, 13)) + + method(...args) {} +>method : Symbol(A.method, Decl(emitDecoratorMetadata_restArgs.ts, 6, 27)) +>args : Symbol(args, Decl(emitDecoratorMetadata_restArgs.ts, 8, 11)) +} + +@MyClassDecorator +>MyClassDecorator : Symbol(MyClassDecorator, Decl(emitDecoratorMetadata_restArgs.ts, 1, 13)) + +class B { +>B : Symbol(B, Decl(emitDecoratorMetadata_restArgs.ts, 9, 1)) + + constructor(...args: number[]) {} +>args : Symbol(args, Decl(emitDecoratorMetadata_restArgs.ts, 13, 16)) + + @MyMethodDecorator +>MyMethodDecorator : Symbol(MyMethodDecorator, Decl(emitDecoratorMetadata_restArgs.ts, 2, 13)) + + method(...args: string[]) {} +>method : Symbol(B.method, Decl(emitDecoratorMetadata_restArgs.ts, 13, 37)) +>args : Symbol(args, Decl(emitDecoratorMetadata_restArgs.ts, 15, 11)) +} + diff --git a/tests/baselines/reference/emitDecoratorMetadata_restArgs.types b/tests/baselines/reference/emitDecoratorMetadata_restArgs.types new file mode 100644 index 00000000000..4820d3a7d8d --- /dev/null +++ b/tests/baselines/reference/emitDecoratorMetadata_restArgs.types @@ -0,0 +1,44 @@ +=== tests/cases/compiler/emitDecoratorMetadata_restArgs.ts === + +declare const MyClassDecorator: ClassDecorator; +>MyClassDecorator : (target: TFunction) => TFunction | void +>ClassDecorator : (target: TFunction) => TFunction | void + +declare const MyMethodDecorator: MethodDecorator; +>MyMethodDecorator : (target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor | void +>MethodDecorator : (target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor | void + +@MyClassDecorator +>MyClassDecorator : (target: TFunction) => TFunction | void + +class A { +>A : A + + constructor(...args) {} +>args : any[] + + @MyMethodDecorator +>MyMethodDecorator : (target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor | void + + method(...args) {} +>method : (...args: any[]) => void +>args : any[] +} + +@MyClassDecorator +>MyClassDecorator : (target: TFunction) => TFunction | void + +class B { +>B : B + + constructor(...args: number[]) {} +>args : number[] + + @MyMethodDecorator +>MyMethodDecorator : (target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor | void + + method(...args: string[]) {} +>method : (...args: string[]) => void +>args : string[] +} + diff --git a/tests/baselines/reference/emptyTuplesTypeAssertion01.errors.txt b/tests/baselines/reference/emptyTuplesTypeAssertion01.errors.txt new file mode 100644 index 00000000000..4d70873bd74 --- /dev/null +++ b/tests/baselines/reference/emptyTuplesTypeAssertion01.errors.txt @@ -0,0 +1,9 @@ +tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion01.ts(2,10): error TS1122: A tuple type element list cannot be empty. + + +==== tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion01.ts (1 errors) ==== + + let x = <[]>[]; + ~~ +!!! error TS1122: A tuple type element list cannot be empty. + let y = x[0]; \ No newline at end of file diff --git a/tests/baselines/reference/emptyTuplesTypeAssertion01.js b/tests/baselines/reference/emptyTuplesTypeAssertion01.js new file mode 100644 index 00000000000..6ab1ec82bd5 --- /dev/null +++ b/tests/baselines/reference/emptyTuplesTypeAssertion01.js @@ -0,0 +1,13 @@ +//// [emptyTuplesTypeAssertion01.ts] + +let x = <[]>[]; +let y = x[0]; + +//// [emptyTuplesTypeAssertion01.js] +var x = []; +var y = x[0]; + + +//// [emptyTuplesTypeAssertion01.d.ts] +declare let x: []; +declare let y: never; diff --git a/tests/baselines/reference/emptyTuplesTypeAssertion02.errors.txt b/tests/baselines/reference/emptyTuplesTypeAssertion02.errors.txt new file mode 100644 index 00000000000..0cbc0d7371c --- /dev/null +++ b/tests/baselines/reference/emptyTuplesTypeAssertion02.errors.txt @@ -0,0 +1,9 @@ +tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion02.ts(2,15): error TS1122: A tuple type element list cannot be empty. + + +==== tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion02.ts (1 errors) ==== + + let x = [] as []; + ~~ +!!! error TS1122: A tuple type element list cannot be empty. + let y = x[0]; \ No newline at end of file diff --git a/tests/baselines/reference/emptyTuplesTypeAssertion02.js b/tests/baselines/reference/emptyTuplesTypeAssertion02.js new file mode 100644 index 00000000000..ad112732cd2 --- /dev/null +++ b/tests/baselines/reference/emptyTuplesTypeAssertion02.js @@ -0,0 +1,13 @@ +//// [emptyTuplesTypeAssertion02.ts] + +let x = [] as []; +let y = x[0]; + +//// [emptyTuplesTypeAssertion02.js] +var x = []; +var y = x[0]; + + +//// [emptyTuplesTypeAssertion02.d.ts] +declare let x: []; +declare let y: never; diff --git a/tests/baselines/reference/genericTypeReferenceWithoutTypeArgument2.errors.txt b/tests/baselines/reference/genericTypeReferenceWithoutTypeArgument2.errors.txt index e590ad42a7d..b6767a3b938 100644 --- a/tests/baselines/reference/genericTypeReferenceWithoutTypeArgument2.errors.txt +++ b/tests/baselines/reference/genericTypeReferenceWithoutTypeArgument2.errors.txt @@ -13,7 +13,7 @@ tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenc tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument2.ts(18,23): error TS2314: Generic type 'I' requires 1 type argument(s). tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument2.ts(18,27): error TS2314: Generic type 'I' requires 1 type argument(s). tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument2.ts(18,38): error TS2314: Generic type 'I' requires 1 type argument(s). -tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument2.ts(20,17): error TS2304: Cannot find name 'I'. +tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument2.ts(20,17): error TS2689: Cannot extend an interface 'I'. Did you mean 'implements'? tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument2.ts(23,21): error TS2314: Generic type 'I' requires 1 type argument(s). tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument2.ts(29,18): error TS2304: Cannot find name 'M'. tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument2.ts(30,24): error TS2314: Generic type 'E' requires 1 type argument(s). @@ -76,7 +76,7 @@ tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenc class D extends I { ~ -!!! error TS2304: Cannot find name 'I'. +!!! error TS2689: Cannot extend an interface 'I'. Did you mean 'implements'? } interface U extends I {} diff --git a/tests/baselines/reference/jsFileCompilationLetDeclarationOrder2.errors.txt b/tests/baselines/reference/jsFileCompilationLetDeclarationOrder2.errors.txt index 21390cc2955..b88c73e0439 100644 --- a/tests/baselines/reference/jsFileCompilationLetDeclarationOrder2.errors.txt +++ b/tests/baselines/reference/jsFileCompilationLetDeclarationOrder2.errors.txt @@ -1,10 +1,13 @@ error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. +tests/cases/compiler/a.ts(2,1): error TS2448: Block-scoped variable 'a' used before its declaration. !!! error TS5053: Option 'allowJs' cannot be specified with option 'declaration'. -==== tests/cases/compiler/a.ts (0 errors) ==== +==== tests/cases/compiler/a.ts (1 errors) ==== let b = 30; a = 10; + ~ +!!! error TS2448: Block-scoped variable 'a' used before its declaration. ==== tests/cases/compiler/b.js (0 errors) ==== let a = 10; b = 30; diff --git a/tests/baselines/reference/jsFileCompilationPropertySyntaxOfClass.errors.txt b/tests/baselines/reference/jsFileCompilationPropertySyntaxOfClass.errors.txt deleted file mode 100644 index fd5ea666459..00000000000 --- a/tests/baselines/reference/jsFileCompilationPropertySyntaxOfClass.errors.txt +++ /dev/null @@ -1,9 +0,0 @@ -error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file. -tests/cases/compiler/a.js(1,11): error TS8014: 'property declarations' can only be used in a .ts file. - - -!!! error TS5055: Cannot write file 'tests/cases/compiler/a.js' because it would overwrite input file. -==== tests/cases/compiler/a.js (1 errors) ==== - class C { v } - ~ -!!! error TS8014: 'property declarations' can only be used in a .ts file. \ No newline at end of file diff --git a/tests/baselines/reference/letDeclarations-useBeforeDefinition2.errors.txt b/tests/baselines/reference/letDeclarations-useBeforeDefinition2.errors.txt new file mode 100644 index 00000000000..5b8633312d9 --- /dev/null +++ b/tests/baselines/reference/letDeclarations-useBeforeDefinition2.errors.txt @@ -0,0 +1,11 @@ +tests/cases/compiler/file1.ts(2,1): error TS2448: Block-scoped variable 'l' used before its declaration. + + +==== tests/cases/compiler/file1.ts (1 errors) ==== + + l; + ~ +!!! error TS2448: Block-scoped variable 'l' used before its declaration. + +==== tests/cases/compiler/file2.ts (0 errors) ==== + const l = 0; \ No newline at end of file diff --git a/tests/baselines/reference/logicalAndOperatorStrictMode.types b/tests/baselines/reference/logicalAndOperatorStrictMode.types index ca225d4561a..a824af2f811 100644 --- a/tests/baselines/reference/logicalAndOperatorStrictMode.types +++ b/tests/baselines/reference/logicalAndOperatorStrictMode.types @@ -86,8 +86,8 @@ const a8 = a && z; >z : string | number | undefined const s1 = s && a; ->s1 : number[] | string ->s && a : number[] | string +>s1 : number[] +>s && a : number[] >s : string >a : number[] @@ -98,32 +98,32 @@ const s2 = s && s; >s : string const s3 = s && x; ->s3 : number | string ->s && x : number | string +>s3 : number +>s && x : number >s : string >x : number const s4 = s && b; ->s4 : boolean | string ->s && b : boolean | string +>s4 : boolean +>s && b : boolean >s : string >b : boolean const s5 = s && v; ->s5 : void | string ->s && v : void | string +>s5 : void +>s && v : void >s : string >v : void const s6 = s && u; ->s6 : string | undefined ->s && u : string | undefined +>s6 : undefined +>s && u : undefined >s : string >u : undefined const s7 = s && n; ->s7 : string | null ->s && n : string | null +>s7 : null +>s && n : null >s : string >n : null @@ -134,14 +134,14 @@ const s8 = s && z; >z : string | number | undefined const x1 = x && a; ->x1 : number[] | number ->x && a : number[] | number +>x1 : number[] +>x && a : number[] >x : number >a : number[] const x2 = x && s; ->x2 : string | number ->x && s : string | number +>x2 : string +>x && s : string >x : number >s : string @@ -152,26 +152,26 @@ const x3 = x && x; >x : number const x4 = x && b; ->x4 : boolean | number ->x && b : boolean | number +>x4 : boolean +>x && b : boolean >x : number >b : boolean const x5 = x && v; ->x5 : void | number ->x && v : void | number +>x5 : void +>x && v : void >x : number >v : void const x6 = x && u; ->x6 : number | undefined ->x && u : number | undefined +>x6 : undefined +>x && u : undefined >x : number >u : undefined const x7 = x && n; ->x7 : number | null ->x && n : number | null +>x7 : null +>x && n : null >x : number >n : null @@ -182,20 +182,20 @@ const x8 = x && z; >z : string | number | undefined const b1 = b && a; ->b1 : number[] | boolean ->b && a : number[] | boolean +>b1 : number[] +>b && a : number[] >b : boolean >a : number[] const b2 = b && s; ->b2 : string | boolean ->b && s : string | boolean +>b2 : string +>b && s : string >b : boolean >s : string const b3 = b && x; ->b3 : number | boolean ->b && x : number | boolean +>b3 : number +>b && x : number >b : boolean >x : number @@ -206,26 +206,26 @@ const b4 = b && b; >b : boolean const b5 = b && v; ->b5 : void | boolean ->b && v : void | boolean +>b5 : void +>b && v : void >b : boolean >v : void const b6 = b && u; ->b6 : boolean | undefined ->b && u : boolean | undefined +>b6 : undefined +>b && u : undefined >b : boolean >u : undefined const b7 = b && n; ->b7 : boolean | null ->b && n : boolean | null +>b7 : null +>b && n : null >b : boolean >n : null const b8 = b && z; ->b8 : string | number | boolean | undefined ->b && z : string | number | boolean | undefined +>b8 : string | number | undefined +>b && z : string | number | undefined >b : boolean >z : string | number | undefined @@ -374,44 +374,44 @@ const n8 = n && z; >z : string | number | undefined const z1 = z && a; ->z1 : number[] | string | number | undefined ->z && a : number[] | string | number | undefined +>z1 : number[] | undefined +>z && a : number[] | undefined >z : string | number | undefined >a : number[] const z2 = z && s; ->z2 : string | number | undefined ->z && s : string | number | undefined +>z2 : string | undefined +>z && s : string | undefined >z : string | number | undefined >s : string const z3 = z && x; ->z3 : number | string | undefined ->z && x : number | string | undefined +>z3 : number | undefined +>z && x : number | undefined >z : string | number | undefined >x : number const z4 = z && b; ->z4 : boolean | string | number | undefined ->z && b : boolean | string | number | undefined +>z4 : boolean | undefined +>z && b : boolean | undefined >z : string | number | undefined >b : boolean const z5 = z && v; ->z5 : void | string | number ->z && v : void | string | number +>z5 : void +>z && v : void >z : string | number | undefined >v : void const z6 = z && u; ->z6 : string | number | undefined ->z && u : string | number | undefined +>z6 : undefined +>z && u : undefined >z : string | number | undefined >u : undefined const z7 = z && n; ->z7 : string | number | null | undefined ->z && n : string | number | null | undefined +>z7 : null | undefined +>z && n : null | undefined >z : string | number | undefined >n : null diff --git a/tests/baselines/reference/missingFunctionImplementation.errors.txt b/tests/baselines/reference/missingFunctionImplementation.errors.txt new file mode 100644 index 00000000000..4cf58d97d49 --- /dev/null +++ b/tests/baselines/reference/missingFunctionImplementation.errors.txt @@ -0,0 +1,140 @@ +tests/cases/compiler/missingFunctionImplementation.ts(3,3): error TS2391: Function implementation is missing or not immediately following the declaration. +tests/cases/compiler/missingFunctionImplementation.ts(8,3): error TS2391: Function implementation is missing or not immediately following the declaration. +tests/cases/compiler/missingFunctionImplementation.ts(16,3): error TS2391: Function implementation is missing or not immediately following the declaration. +tests/cases/compiler/missingFunctionImplementation.ts(22,10): error TS2391: Function implementation is missing or not immediately following the declaration. +tests/cases/compiler/missingFunctionImplementation.ts(28,10): error TS2391: Function implementation is missing or not immediately following the declaration. +tests/cases/compiler/missingFunctionImplementation.ts(33,10): error TS2391: Function implementation is missing or not immediately following the declaration. +tests/cases/compiler/missingFunctionImplementation.ts(41,10): error TS2391: Function implementation is missing or not immediately following the declaration. +tests/cases/compiler/missingFunctionImplementation.ts(48,10): error TS2300: Duplicate identifier 'm'. +tests/cases/compiler/missingFunctionImplementation.ts(49,10): error TS2300: Duplicate identifier 'm'. +tests/cases/compiler/missingFunctionImplementation.ts(49,10): error TS2391: Function implementation is missing or not immediately following the declaration. +tests/cases/compiler/missingFunctionImplementation.ts(52,19): error TS2300: Duplicate identifier 'm'. +tests/cases/compiler/missingFunctionImplementation.ts(57,10): error TS2300: Duplicate identifier 'm'. +tests/cases/compiler/missingFunctionImplementation.ts(60,19): error TS2300: Duplicate identifier 'm'. +tests/cases/compiler/missingFunctionImplementation.ts(60,19): error TS2391: Function implementation is missing or not immediately following the declaration. +tests/cases/compiler/missingFunctionImplementation.ts(65,19): error TS2391: Function implementation is missing or not immediately following the declaration. +tests/cases/compiler/missingFunctionImplementation.ts(73,19): error TS2393: Duplicate function implementation. +tests/cases/compiler/missingFunctionImplementation.ts(74,19): error TS2393: Duplicate function implementation. +tests/cases/compiler/missingFunctionImplementation.ts(75,19): error TS2393: Duplicate function implementation. +tests/cases/compiler/missingFunctionImplementation.ts(78,19): error TS2393: Duplicate function implementation. + + +==== tests/cases/compiler/missingFunctionImplementation.ts (19 errors) ==== + + export class C1 { + m(): void; + ~ +!!! error TS2391: Function implementation is missing or not immediately following the declaration. + } + + // merged with a namespace + export class C2 { + m(): void; + ~ +!!! error TS2391: Function implementation is missing or not immediately following the declaration. + } + export namespace C2 { } + + + // merged with a namespace, multiple overloads + class C3 { + m(a, b); + m(a); + ~ +!!! error TS2391: Function implementation is missing or not immediately following the declaration. + } + namespace C3 { } + + // static methods, multiple overloads + class C4 { + static m(a): void; + ~ +!!! error TS2391: Function implementation is missing or not immediately following the declaration. + } + + // static methods, multiple overloads + class C5 { + static m(a): void; + static m(): void; + ~ +!!! error TS2391: Function implementation is missing or not immediately following the declaration. + } + + // merged with namespace, static methods + class C6 { + static m(): void; + ~ +!!! error TS2391: Function implementation is missing or not immediately following the declaration. + } + namespace C6 { + } + + // merged with namespace, static methods, multiple overloads + class C7 { + static m(a): void; + static m(): void; + ~ +!!! error TS2391: Function implementation is missing or not immediately following the declaration. + } + namespace C7 { + } + + // merged with namespace, static methods, duplicate declarations + class C8 { + static m(a): void; + ~ +!!! error TS2300: Duplicate identifier 'm'. + static m(a, b): void; + ~ +!!! error TS2300: Duplicate identifier 'm'. + ~ +!!! error TS2391: Function implementation is missing or not immediately following the declaration. + } + namespace C8 { + export function m(a?, b?): void { } + ~ +!!! error TS2300: Duplicate identifier 'm'. + } + + // merged with namespace, static methods, duplicate declarations + class C9 { + static m(a): void { } + ~ +!!! error TS2300: Duplicate identifier 'm'. + } + namespace C9 { + export function m(a): void; + ~ +!!! error TS2300: Duplicate identifier 'm'. + ~ +!!! error TS2391: Function implementation is missing or not immediately following the declaration. + } + + // merged namespaces + namespace N10 { + export function m(a): void; + ~ +!!! error TS2391: Function implementation is missing or not immediately following the declaration. + } + namespace N10 { + export function m(a): void { } + } + + // merged namespaces, duplicate defintions + namespace N12 { + export function m(a): void; + ~ +!!! error TS2393: Duplicate function implementation. + export function m(): void; + ~ +!!! error TS2393: Duplicate function implementation. + export function m(a?): void { } + ~ +!!! error TS2393: Duplicate function implementation. + } + namespace N12 { + export function m(a): void { } + ~ +!!! error TS2393: Duplicate function implementation. + } + \ No newline at end of file diff --git a/tests/baselines/reference/missingFunctionImplementation.js b/tests/baselines/reference/missingFunctionImplementation.js new file mode 100644 index 00000000000..a452c8080b7 --- /dev/null +++ b/tests/baselines/reference/missingFunctionImplementation.js @@ -0,0 +1,168 @@ +//// [missingFunctionImplementation.ts] + +export class C1 { + m(): void; +} + +// merged with a namespace +export class C2 { + m(): void; +} +export namespace C2 { } + + +// merged with a namespace, multiple overloads +class C3 { + m(a, b); + m(a); +} +namespace C3 { } + +// static methods, multiple overloads +class C4 { + static m(a): void; +} + +// static methods, multiple overloads +class C5 { + static m(a): void; + static m(): void; +} + +// merged with namespace, static methods +class C6 { + static m(): void; +} +namespace C6 { +} + +// merged with namespace, static methods, multiple overloads +class C7 { + static m(a): void; + static m(): void; +} +namespace C7 { +} + +// merged with namespace, static methods, duplicate declarations +class C8 { + static m(a): void; + static m(a, b): void; +} +namespace C8 { + export function m(a?, b?): void { } +} + +// merged with namespace, static methods, duplicate declarations +class C9 { + static m(a): void { } +} +namespace C9 { + export function m(a): void; +} + +// merged namespaces +namespace N10 { + export function m(a): void; +} +namespace N10 { + export function m(a): void { } +} + +// merged namespaces, duplicate defintions +namespace N12 { + export function m(a): void; + export function m(): void; + export function m(a?): void { } +} +namespace N12 { + export function m(a): void { } +} + + +//// [missingFunctionImplementation.js] +"use strict"; +var C1 = (function () { + function C1() { + } + return C1; +}()); +exports.C1 = C1; +// merged with a namespace +var C2 = (function () { + function C2() { + } + return C2; +}()); +exports.C2 = C2; +// merged with a namespace, multiple overloads +var C3 = (function () { + function C3() { + } + return C3; +}()); +// static methods, multiple overloads +var C4 = (function () { + function C4() { + } + return C4; +}()); +// static methods, multiple overloads +var C5 = (function () { + function C5() { + } + return C5; +}()); +// merged with namespace, static methods +var C6 = (function () { + function C6() { + } + return C6; +}()); +// merged with namespace, static methods, multiple overloads +var C7 = (function () { + function C7() { + } + return C7; +}()); +// merged with namespace, static methods, duplicate declarations +var C8 = (function () { + function C8() { + } + return C8; +}()); +var C8; +(function (C8) { + function m(a, b) { } + C8.m = m; +})(C8 || (C8 = {})); +// merged with namespace, static methods, duplicate declarations +var C9 = (function () { + function C9() { + } + C9.m = function (a) { }; + return C9; +}()); +var C9; +(function (C9) { +})(C9 || (C9 = {})); +// merged namespaces +var N10; +(function (N10) { +})(N10 || (N10 = {})); +var N10; +(function (N10) { + function m(a) { } + N10.m = m; +})(N10 || (N10 = {})); +// merged namespaces, duplicate defintions +var N12; +(function (N12) { + function m(a) { } + N12.m = m; +})(N12 || (N12 = {})); +var N12; +(function (N12) { + function m(a) { } + N12.m = m; +})(N12 || (N12 = {})); diff --git a/tests/baselines/reference/missingFunctionImplementation2.errors.txt b/tests/baselines/reference/missingFunctionImplementation2.errors.txt new file mode 100644 index 00000000000..a695482e1fb --- /dev/null +++ b/tests/baselines/reference/missingFunctionImplementation2.errors.txt @@ -0,0 +1,16 @@ +tests/cases/compiler/missingFunctionImplementation2_a.ts(3,19): error TS2384: Overload signatures must all be ambient or non-ambient. +tests/cases/compiler/missingFunctionImplementation2_b.ts(1,17): error TS2391: Function implementation is missing or not immediately following the declaration. + + +==== tests/cases/compiler/missingFunctionImplementation2_a.ts (1 errors) ==== + export {}; + declare module "./missingFunctionImplementation2_b.ts" { + export function f(a, b): void; + ~ +!!! error TS2384: Overload signatures must all be ambient or non-ambient. + } + +==== tests/cases/compiler/missingFunctionImplementation2_b.ts (1 errors) ==== + export function f(a?, b?); + ~ +!!! error TS2391: Function implementation is missing or not immediately following the declaration. \ No newline at end of file diff --git a/tests/baselines/reference/missingFunctionImplementation2.js b/tests/baselines/reference/missingFunctionImplementation2.js new file mode 100644 index 00000000000..104b6dd9443 --- /dev/null +++ b/tests/baselines/reference/missingFunctionImplementation2.js @@ -0,0 +1,15 @@ +//// [tests/cases/compiler/missingFunctionImplementation2.ts] //// + +//// [missingFunctionImplementation2_a.ts] +export {}; +declare module "./missingFunctionImplementation2_b.ts" { + export function f(a, b): void; +} + +//// [missingFunctionImplementation2_b.ts] +export function f(a?, b?); + +//// [missingFunctionImplementation2_a.js] +"use strict"; +//// [missingFunctionImplementation2_b.js] +"use strict"; diff --git a/tests/baselines/reference/shorthandOfExportedEntity01_targetES2015_CommonJS.js b/tests/baselines/reference/shorthandOfExportedEntity01_targetES2015_CommonJS.js new file mode 100644 index 00000000000..9e057951b3a --- /dev/null +++ b/tests/baselines/reference/shorthandOfExportedEntity01_targetES2015_CommonJS.js @@ -0,0 +1,21 @@ +//// [shorthandOfExportedEntity01_targetES2015_CommonJS.ts] + +export const test = "test"; + +export function foo () { + const x = { test }; +} + + +//// [shorthandOfExportedEntity01_targetES2015_CommonJS.js] +"use strict"; +exports.test = "test"; +function foo() { + const x = { test: exports.test }; +} +exports.foo = foo; + + +//// [shorthandOfExportedEntity01_targetES2015_CommonJS.d.ts] +export declare const test: string; +export declare function foo(): void; diff --git a/tests/baselines/reference/shorthandOfExportedEntity01_targetES2015_CommonJS.symbols b/tests/baselines/reference/shorthandOfExportedEntity01_targetES2015_CommonJS.symbols new file mode 100644 index 00000000000..341d40bc542 --- /dev/null +++ b/tests/baselines/reference/shorthandOfExportedEntity01_targetES2015_CommonJS.symbols @@ -0,0 +1,13 @@ +=== tests/cases/compiler/shorthandOfExportedEntity01_targetES2015_CommonJS.ts === + +export const test = "test"; +>test : Symbol(test, Decl(shorthandOfExportedEntity01_targetES2015_CommonJS.ts, 1, 12)) + +export function foo () { +>foo : Symbol(foo, Decl(shorthandOfExportedEntity01_targetES2015_CommonJS.ts, 1, 27)) + + const x = { test }; +>x : Symbol(x, Decl(shorthandOfExportedEntity01_targetES2015_CommonJS.ts, 4, 7)) +>test : Symbol(test, Decl(shorthandOfExportedEntity01_targetES2015_CommonJS.ts, 4, 13)) +} + diff --git a/tests/baselines/reference/shorthandOfExportedEntity01_targetES2015_CommonJS.types b/tests/baselines/reference/shorthandOfExportedEntity01_targetES2015_CommonJS.types new file mode 100644 index 00000000000..dcc04015993 --- /dev/null +++ b/tests/baselines/reference/shorthandOfExportedEntity01_targetES2015_CommonJS.types @@ -0,0 +1,15 @@ +=== tests/cases/compiler/shorthandOfExportedEntity01_targetES2015_CommonJS.ts === + +export const test = "test"; +>test : string +>"test" : string + +export function foo () { +>foo : () => void + + const x = { test }; +>x : { test: string; } +>{ test } : { test: string; } +>test : string +} + diff --git a/tests/baselines/reference/shorthandOfExportedEntity02_targetES5_CommonJS.js b/tests/baselines/reference/shorthandOfExportedEntity02_targetES5_CommonJS.js new file mode 100644 index 00000000000..764739705c4 --- /dev/null +++ b/tests/baselines/reference/shorthandOfExportedEntity02_targetES5_CommonJS.js @@ -0,0 +1,21 @@ +//// [shorthandOfExportedEntity02_targetES5_CommonJS.ts] + +export const test = "test"; + +export function foo () { + const x = { test }; +} + + +//// [shorthandOfExportedEntity02_targetES5_CommonJS.js] +"use strict"; +exports.test = "test"; +function foo() { + var x = { test: exports.test }; +} +exports.foo = foo; + + +//// [shorthandOfExportedEntity02_targetES5_CommonJS.d.ts] +export declare const test: string; +export declare function foo(): void; diff --git a/tests/baselines/reference/shorthandOfExportedEntity02_targetES5_CommonJS.symbols b/tests/baselines/reference/shorthandOfExportedEntity02_targetES5_CommonJS.symbols new file mode 100644 index 00000000000..3b0b40922c9 --- /dev/null +++ b/tests/baselines/reference/shorthandOfExportedEntity02_targetES5_CommonJS.symbols @@ -0,0 +1,13 @@ +=== tests/cases/compiler/shorthandOfExportedEntity02_targetES5_CommonJS.ts === + +export const test = "test"; +>test : Symbol(test, Decl(shorthandOfExportedEntity02_targetES5_CommonJS.ts, 1, 12)) + +export function foo () { +>foo : Symbol(foo, Decl(shorthandOfExportedEntity02_targetES5_CommonJS.ts, 1, 27)) + + const x = { test }; +>x : Symbol(x, Decl(shorthandOfExportedEntity02_targetES5_CommonJS.ts, 4, 7)) +>test : Symbol(test, Decl(shorthandOfExportedEntity02_targetES5_CommonJS.ts, 4, 13)) +} + diff --git a/tests/baselines/reference/shorthandOfExportedEntity02_targetES5_CommonJS.types b/tests/baselines/reference/shorthandOfExportedEntity02_targetES5_CommonJS.types new file mode 100644 index 00000000000..27d16e2166f --- /dev/null +++ b/tests/baselines/reference/shorthandOfExportedEntity02_targetES5_CommonJS.types @@ -0,0 +1,15 @@ +=== tests/cases/compiler/shorthandOfExportedEntity02_targetES5_CommonJS.ts === + +export const test = "test"; +>test : string +>"test" : string + +export function foo () { +>foo : () => void + + const x = { test }; +>x : { test: string; } +>{ test } : { test: string; } +>test : string +} + diff --git a/tests/baselines/reference/strictNullLogicalAndOr.js b/tests/baselines/reference/strictNullLogicalAndOr.js new file mode 100644 index 00000000000..f4dafe334b5 --- /dev/null +++ b/tests/baselines/reference/strictNullLogicalAndOr.js @@ -0,0 +1,26 @@ +//// [strictNullLogicalAndOr.ts] + +// Repro from #9113 + +let sinOrCos = Math.random() < .5; +let choice = sinOrCos && Math.sin || Math.cos; + +choice(Math.PI); + +function sq(n?: number): number { + const r = n !== undefined && n*n || 0; + return r; +} + +sq(3); + +//// [strictNullLogicalAndOr.js] +// Repro from #9113 +var sinOrCos = Math.random() < .5; +var choice = sinOrCos && Math.sin || Math.cos; +choice(Math.PI); +function sq(n) { + var r = n !== undefined && n * n || 0; + return r; +} +sq(3); diff --git a/tests/baselines/reference/strictNullLogicalAndOr.symbols b/tests/baselines/reference/strictNullLogicalAndOr.symbols new file mode 100644 index 00000000000..8bb0343b9c0 --- /dev/null +++ b/tests/baselines/reference/strictNullLogicalAndOr.symbols @@ -0,0 +1,44 @@ +=== tests/cases/compiler/strictNullLogicalAndOr.ts === + +// Repro from #9113 + +let sinOrCos = Math.random() < .5; +>sinOrCos : Symbol(sinOrCos, Decl(strictNullLogicalAndOr.ts, 3, 3)) +>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.d.ts, --, --)) + +let choice = sinOrCos && Math.sin || Math.cos; +>choice : Symbol(choice, Decl(strictNullLogicalAndOr.ts, 4, 3)) +>sinOrCos : Symbol(sinOrCos, Decl(strictNullLogicalAndOr.ts, 3, 3)) +>Math.sin : Symbol(Math.sin, Decl(lib.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>sin : Symbol(Math.sin, Decl(lib.d.ts, --, --)) +>Math.cos : Symbol(Math.cos, Decl(lib.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>cos : Symbol(Math.cos, Decl(lib.d.ts, --, --)) + +choice(Math.PI); +>choice : Symbol(choice, Decl(strictNullLogicalAndOr.ts, 4, 3)) +>Math.PI : Symbol(Math.PI, Decl(lib.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>PI : Symbol(Math.PI, Decl(lib.d.ts, --, --)) + +function sq(n?: number): number { +>sq : Symbol(sq, Decl(strictNullLogicalAndOr.ts, 6, 16)) +>n : Symbol(n, Decl(strictNullLogicalAndOr.ts, 8, 12)) + + const r = n !== undefined && n*n || 0; +>r : Symbol(r, Decl(strictNullLogicalAndOr.ts, 9, 7)) +>n : Symbol(n, Decl(strictNullLogicalAndOr.ts, 8, 12)) +>undefined : Symbol(undefined) +>n : Symbol(n, Decl(strictNullLogicalAndOr.ts, 8, 12)) +>n : Symbol(n, Decl(strictNullLogicalAndOr.ts, 8, 12)) + + return r; +>r : Symbol(r, Decl(strictNullLogicalAndOr.ts, 9, 7)) +} + +sq(3); +>sq : Symbol(sq, Decl(strictNullLogicalAndOr.ts, 6, 16)) + diff --git a/tests/baselines/reference/strictNullLogicalAndOr.types b/tests/baselines/reference/strictNullLogicalAndOr.types new file mode 100644 index 00000000000..a11a7033fb6 --- /dev/null +++ b/tests/baselines/reference/strictNullLogicalAndOr.types @@ -0,0 +1,57 @@ +=== tests/cases/compiler/strictNullLogicalAndOr.ts === + +// Repro from #9113 + +let sinOrCos = Math.random() < .5; +>sinOrCos : boolean +>Math.random() < .5 : boolean +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number +>.5 : number + +let choice = sinOrCos && Math.sin || Math.cos; +>choice : (x: number) => number +>sinOrCos && Math.sin || Math.cos : (x: number) => number +>sinOrCos && Math.sin : (x: number) => number +>sinOrCos : boolean +>Math.sin : (x: number) => number +>Math : Math +>sin : (x: number) => number +>Math.cos : (x: number) => number +>Math : Math +>cos : (x: number) => number + +choice(Math.PI); +>choice(Math.PI) : number +>choice : (x: number) => number +>Math.PI : number +>Math : Math +>PI : number + +function sq(n?: number): number { +>sq : (n?: number | undefined) => number +>n : number | undefined + + const r = n !== undefined && n*n || 0; +>r : number +>n !== undefined && n*n || 0 : number +>n !== undefined && n*n : number +>n !== undefined : boolean +>n : number | undefined +>undefined : undefined +>n*n : number +>n : number +>n : number +>0 : number + + return r; +>r : number +} + +sq(3); +>sq(3) : number +>sq : (n?: number | undefined) => number +>3 : number + diff --git a/tests/baselines/reference/transpile/Accepts string as enum values for compile-options.js b/tests/baselines/reference/transpile/Accepts string as enum values for compile-options.js new file mode 100644 index 00000000000..981e2e706cb --- /dev/null +++ b/tests/baselines/reference/transpile/Accepts string as enum values for compile-options.js @@ -0,0 +1,2 @@ +export const x = 0; +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Does not generate semantic diagnostics.js b/tests/baselines/reference/transpile/Does not generate semantic diagnostics.js new file mode 100644 index 00000000000..61a703e13bb --- /dev/null +++ b/tests/baselines/reference/transpile/Does not generate semantic diagnostics.js @@ -0,0 +1,3 @@ +"use strict"; +var x = 0; +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Generates expected syntactic diagnostics.errors.txt b/tests/baselines/reference/transpile/Generates expected syntactic diagnostics.errors.txt new file mode 100644 index 00000000000..6fbdba6f2c6 --- /dev/null +++ b/tests/baselines/reference/transpile/Generates expected syntactic diagnostics.errors.txt @@ -0,0 +1,7 @@ +file.ts(1,3): error TS1005: ';' expected. + + +==== file.ts (1 errors) ==== + a b + ~ +!!! error TS1005: ';' expected. \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Generates expected syntactic diagnostics.js b/tests/baselines/reference/transpile/Generates expected syntactic diagnostics.js new file mode 100644 index 00000000000..9d108d63313 --- /dev/null +++ b/tests/baselines/reference/transpile/Generates expected syntactic diagnostics.js @@ -0,0 +1,4 @@ +"use strict"; +a; +b; +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Generates module output.js b/tests/baselines/reference/transpile/Generates module output.js new file mode 100644 index 00000000000..9eadd1f2717 --- /dev/null +++ b/tests/baselines/reference/transpile/Generates module output.js @@ -0,0 +1,5 @@ +define(["require", "exports"], function (require, exports) { + "use strict"; + var x = 0; +}); +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Generates no diagnostics for missing file references.js b/tests/baselines/reference/transpile/Generates no diagnostics for missing file references.js new file mode 100644 index 00000000000..88d98628eee --- /dev/null +++ b/tests/baselines/reference/transpile/Generates no diagnostics for missing file references.js @@ -0,0 +1,4 @@ +"use strict"; +/// +var x = 0; +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Generates no diagnostics for missing module imports.js b/tests/baselines/reference/transpile/Generates no diagnostics for missing module imports.js new file mode 100644 index 00000000000..1ceb1bcd146 --- /dev/null +++ b/tests/baselines/reference/transpile/Generates no diagnostics for missing module imports.js @@ -0,0 +1,2 @@ +"use strict"; +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Generates no diagnostics with valid inputs.js b/tests/baselines/reference/transpile/Generates no diagnostics with valid inputs.js new file mode 100644 index 00000000000..61a703e13bb --- /dev/null +++ b/tests/baselines/reference/transpile/Generates no diagnostics with valid inputs.js @@ -0,0 +1,3 @@ +"use strict"; +var x = 0; +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/No extra errors for file without extension.js b/tests/baselines/reference/transpile/No extra errors for file without extension.js new file mode 100644 index 00000000000..61a703e13bb --- /dev/null +++ b/tests/baselines/reference/transpile/No extra errors for file without extension.js @@ -0,0 +1,3 @@ +"use strict"; +var x = 0; +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Rename dependencies - AMD.js b/tests/baselines/reference/transpile/Rename dependencies - AMD.js new file mode 100644 index 00000000000..a0dd948c9fc --- /dev/null +++ b/tests/baselines/reference/transpile/Rename dependencies - AMD.js @@ -0,0 +1,5 @@ +define(["require", "exports", "SomeOtherName"], function (require, exports, SomeName_1) { + "use strict"; + use(SomeName_1.foo); +}); +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Rename dependencies - System.js b/tests/baselines/reference/transpile/Rename dependencies - System.js new file mode 100644 index 00000000000..8f3fcaa8559 --- /dev/null +++ b/tests/baselines/reference/transpile/Rename dependencies - System.js @@ -0,0 +1,15 @@ +System.register(["SomeOtherName"], function(exports_1, context_1) { + "use strict"; + var __moduleName = context_1 && context_1.id; + var SomeName_1; + return { + setters:[ + function (SomeName_1_1) { + SomeName_1 = SomeName_1_1; + }], + execute: function() { + use(SomeName_1.foo); + } + } +}); +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Rename dependencies - UMD.js b/tests/baselines/reference/transpile/Rename dependencies - UMD.js new file mode 100644 index 00000000000..94a7249678f --- /dev/null +++ b/tests/baselines/reference/transpile/Rename dependencies - UMD.js @@ -0,0 +1,13 @@ +(function (factory) { + if (typeof module === 'object' && typeof module.exports === 'object') { + var v = factory(require, exports); if (v !== undefined) module.exports = v; + } + else if (typeof define === 'function' && define.amd) { + define(["require", "exports", "SomeOtherName"], factory); + } +})(function (require, exports) { + "use strict"; + var SomeName_1 = require("SomeOtherName"); + use(SomeName_1.foo); +}); +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Report an error when compiler-options input is empty object.errors.txt b/tests/baselines/reference/transpile/Report an error when compiler-options input is empty object.errors.txt new file mode 100644 index 00000000000..d7d6eb69300 --- /dev/null +++ b/tests/baselines/reference/transpile/Report an error when compiler-options input is empty object.errors.txt @@ -0,0 +1,6 @@ +error TS6046: Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015' + + +!!! error TS6046: Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015' +==== file.ts (0 errors) ==== + \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Report an error when compiler-options input is empty object.js b/tests/baselines/reference/transpile/Report an error when compiler-options input is empty object.js new file mode 100644 index 00000000000..1ceb1bcd146 --- /dev/null +++ b/tests/baselines/reference/transpile/Report an error when compiler-options input is empty object.js @@ -0,0 +1,2 @@ +"use strict"; +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Report an error when compiler-options input is empty string.errors.txt b/tests/baselines/reference/transpile/Report an error when compiler-options input is empty string.errors.txt new file mode 100644 index 00000000000..d7d6eb69300 --- /dev/null +++ b/tests/baselines/reference/transpile/Report an error when compiler-options input is empty string.errors.txt @@ -0,0 +1,6 @@ +error TS6046: Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015' + + +!!! error TS6046: Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015' +==== file.ts (0 errors) ==== + \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Report an error when compiler-options input is empty string.js b/tests/baselines/reference/transpile/Report an error when compiler-options input is empty string.js new file mode 100644 index 00000000000..1ceb1bcd146 --- /dev/null +++ b/tests/baselines/reference/transpile/Report an error when compiler-options input is empty string.js @@ -0,0 +1,2 @@ +"use strict"; +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Report an error when compiler-options module-kind is out-of-range.errors.txt b/tests/baselines/reference/transpile/Report an error when compiler-options module-kind is out-of-range.errors.txt new file mode 100644 index 00000000000..d7d6eb69300 --- /dev/null +++ b/tests/baselines/reference/transpile/Report an error when compiler-options module-kind is out-of-range.errors.txt @@ -0,0 +1,6 @@ +error TS6046: Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015' + + +!!! error TS6046: Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015' +==== file.ts (0 errors) ==== + \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Report an error when compiler-options module-kind is out-of-range.js b/tests/baselines/reference/transpile/Report an error when compiler-options module-kind is out-of-range.js new file mode 100644 index 00000000000..1ceb1bcd146 --- /dev/null +++ b/tests/baselines/reference/transpile/Report an error when compiler-options module-kind is out-of-range.js @@ -0,0 +1,2 @@ +"use strict"; +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Report an error when compiler-options target-script is out-of-range.errors.txt b/tests/baselines/reference/transpile/Report an error when compiler-options target-script is out-of-range.errors.txt new file mode 100644 index 00000000000..d7d6eb69300 --- /dev/null +++ b/tests/baselines/reference/transpile/Report an error when compiler-options target-script is out-of-range.errors.txt @@ -0,0 +1,6 @@ +error TS6046: Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015' + + +!!! error TS6046: Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015' +==== file.ts (0 errors) ==== + \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Report an error when compiler-options target-script is out-of-range.js b/tests/baselines/reference/transpile/Report an error when compiler-options target-script is out-of-range.js new file mode 100644 index 00000000000..1ceb1bcd146 --- /dev/null +++ b/tests/baselines/reference/transpile/Report an error when compiler-options target-script is out-of-range.js @@ -0,0 +1,2 @@ +"use strict"; +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Sets module name.js b/tests/baselines/reference/transpile/Sets module name.js new file mode 100644 index 00000000000..683266f8383 --- /dev/null +++ b/tests/baselines/reference/transpile/Sets module name.js @@ -0,0 +1,12 @@ +System.register("NamedModule", [], function(exports_1, context_1) { + "use strict"; + var __moduleName = context_1 && context_1.id; + var x; + return { + setters:[], + execute: function() { + var x = 1; + } + } +}); +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Support options with lib values.js b/tests/baselines/reference/transpile/Support options with lib values.js new file mode 100644 index 00000000000..36c68f08b9f --- /dev/null +++ b/tests/baselines/reference/transpile/Support options with lib values.js @@ -0,0 +1,3 @@ +"use strict"; +var a = 10; +//# sourceMappingURL=input.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Support options with types values.js b/tests/baselines/reference/transpile/Support options with types values.js new file mode 100644 index 00000000000..36c68f08b9f --- /dev/null +++ b/tests/baselines/reference/transpile/Support options with types values.js @@ -0,0 +1,3 @@ +"use strict"; +var a = 10; +//# sourceMappingURL=input.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Supports backslashes in file name.js b/tests/baselines/reference/transpile/Supports backslashes in file name.js new file mode 100644 index 00000000000..942449753b0 --- /dev/null +++ b/tests/baselines/reference/transpile/Supports backslashes in file name.js @@ -0,0 +1,3 @@ +"use strict"; +var x; +//# sourceMappingURL=b.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Supports urls in file name.js b/tests/baselines/reference/transpile/Supports urls in file name.js new file mode 100644 index 00000000000..3923d3c9a41 --- /dev/null +++ b/tests/baselines/reference/transpile/Supports urls in file name.js @@ -0,0 +1,3 @@ +"use strict"; +var x; +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Transpile with emit decorators and emit metadata.js b/tests/baselines/reference/transpile/Transpile with emit decorators and emit metadata.js new file mode 100644 index 00000000000..407ee216d58 --- /dev/null +++ b/tests/baselines/reference/transpile/Transpile with emit decorators and emit metadata.js @@ -0,0 +1,19 @@ +"use strict"; +var db_1 = require('./db'); +function someDecorator(target) { + return target; +} +var MyClass = (function () { + function MyClass(db) { + this.db = db; + this.db.doSomething(); + } + MyClass = __decorate([ + someDecorator, + __metadata('design:paramtypes', [(typeof (_a = typeof db_1.db !== 'undefined' && db_1.db) === 'function' && _a) || Object]) + ], MyClass); + return MyClass; + var _a; +}()); +exports.MyClass = MyClass; +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Uses correct newLine character.js b/tests/baselines/reference/transpile/Uses correct newLine character.js new file mode 100644 index 00000000000..bab9c3c4443 --- /dev/null +++ b/tests/baselines/reference/transpile/Uses correct newLine character.js @@ -0,0 +1,3 @@ +"use strict"; +var x = 0; +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/transpile .js files.js b/tests/baselines/reference/transpile/transpile .js files.js new file mode 100644 index 00000000000..c17099d84ba --- /dev/null +++ b/tests/baselines/reference/transpile/transpile .js files.js @@ -0,0 +1,3 @@ +"use strict"; +var a = 10; +//# sourceMappingURL=input.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/transpile file as tsx if jsx is specified.js b/tests/baselines/reference/transpile/transpile file as tsx if jsx is specified.js new file mode 100644 index 00000000000..baa27ee64ce --- /dev/null +++ b/tests/baselines/reference/transpile/transpile file as tsx if jsx is specified.js @@ -0,0 +1,3 @@ +"use strict"; +var x = React.createElement("div", null); +//# sourceMappingURL=file.js.map \ No newline at end of file diff --git a/tests/cases/compiler/classExtendsInterface.ts b/tests/cases/compiler/classExtendsInterface.ts index 36f42167d1a..eaab1d60fc4 100644 --- a/tests/cases/compiler/classExtendsInterface.ts +++ b/tests/cases/compiler/classExtendsInterface.ts @@ -1,7 +1,7 @@ interface Comparable {} class A extends Comparable {} class B implements Comparable {} - + interface Comparable2 {} class A2 extends Comparable2 {} class B2 implements Comparable2 {} diff --git a/tests/cases/compiler/classExtendsInterfaceInExpression.ts b/tests/cases/compiler/classExtendsInterfaceInExpression.ts new file mode 100644 index 00000000000..002631afedf --- /dev/null +++ b/tests/cases/compiler/classExtendsInterfaceInExpression.ts @@ -0,0 +1,7 @@ +interface A {} + +function factory(a: any): {new(): Object} { + return null; +} + +class C extends factory(A) {} diff --git a/tests/cases/compiler/classExtendsInterfaceInModule.ts b/tests/cases/compiler/classExtendsInterfaceInModule.ts new file mode 100644 index 00000000000..4ea24e5dd7d --- /dev/null +++ b/tests/cases/compiler/classExtendsInterfaceInModule.ts @@ -0,0 +1,14 @@ +module M { + export interface I1 {} + export interface I2 {} +} +class C1 extends M.I1 {} +class C2 extends M.I2 {} + +module Mod { + export namespace Nested { + export interface I {} + } +} + +class D extends Mod.Nested.I {} diff --git a/tests/cases/compiler/decoratorMetadataPromise.ts b/tests/cases/compiler/decoratorMetadataPromise.ts new file mode 100644 index 00000000000..ef55e1946de --- /dev/null +++ b/tests/cases/compiler/decoratorMetadataPromise.ts @@ -0,0 +1,14 @@ +// @experimentaldecorators: true +// @emitdecoratormetadata: true +// @target: es6 + +declare const decorator: MethodDecorator; + +class A { + @decorator + async foo() {} + @decorator + async bar(): Promise { return 0; } + @decorator + baz(n: Promise): Promise { return n; } +} diff --git a/tests/cases/compiler/emitDecoratorMetadata_restArgs.ts b/tests/cases/compiler/emitDecoratorMetadata_restArgs.ts new file mode 100644 index 00000000000..6b0741e2205 --- /dev/null +++ b/tests/cases/compiler/emitDecoratorMetadata_restArgs.ts @@ -0,0 +1,20 @@ +// @experimentaldecorators: true +// @emitdecoratormetadata: true +// @target: ES5 + +declare const MyClassDecorator: ClassDecorator; +declare const MyMethodDecorator: MethodDecorator; + +@MyClassDecorator +class A { + constructor(...args) {} + @MyMethodDecorator + method(...args) {} +} + +@MyClassDecorator +class B { + constructor(...args: number[]) {} + @MyMethodDecorator + method(...args: string[]) {} +} diff --git a/tests/cases/compiler/jsFileCompilationPropertySyntaxOfClass.ts b/tests/cases/compiler/jsFileCompilationPropertySyntaxOfClass.ts deleted file mode 100644 index 62a0058bcef..00000000000 --- a/tests/cases/compiler/jsFileCompilationPropertySyntaxOfClass.ts +++ /dev/null @@ -1,3 +0,0 @@ -// @allowJs: true -// @filename: a.js -class C { v } \ No newline at end of file diff --git a/tests/cases/compiler/missingFunctionImplementation.ts b/tests/cases/compiler/missingFunctionImplementation.ts new file mode 100644 index 00000000000..e261db3a667 --- /dev/null +++ b/tests/cases/compiler/missingFunctionImplementation.ts @@ -0,0 +1,79 @@ + +export class C1 { + m(): void; +} + +// merged with a namespace +export class C2 { + m(): void; +} +export namespace C2 { } + + +// merged with a namespace, multiple overloads +class C3 { + m(a, b); + m(a); +} +namespace C3 { } + +// static methods, multiple overloads +class C4 { + static m(a): void; +} + +// static methods, multiple overloads +class C5 { + static m(a): void; + static m(): void; +} + +// merged with namespace, static methods +class C6 { + static m(): void; +} +namespace C6 { +} + +// merged with namespace, static methods, multiple overloads +class C7 { + static m(a): void; + static m(): void; +} +namespace C7 { +} + +// merged with namespace, static methods, duplicate declarations +class C8 { + static m(a): void; + static m(a, b): void; +} +namespace C8 { + export function m(a?, b?): void { } +} + +// merged with namespace, static methods, duplicate declarations +class C9 { + static m(a): void { } +} +namespace C9 { + export function m(a): void; +} + +// merged namespaces +namespace N10 { + export function m(a): void; +} +namespace N10 { + export function m(a): void { } +} + +// merged namespaces, duplicate defintions +namespace N12 { + export function m(a): void; + export function m(): void; + export function m(a?): void { } +} +namespace N12 { + export function m(a): void { } +} diff --git a/tests/cases/compiler/missingFunctionImplementation2.ts b/tests/cases/compiler/missingFunctionImplementation2.ts new file mode 100644 index 00000000000..25909b6add4 --- /dev/null +++ b/tests/cases/compiler/missingFunctionImplementation2.ts @@ -0,0 +1,8 @@ +// @Filename: missingFunctionImplementation2_a.ts +export {}; +declare module "./missingFunctionImplementation2_b.ts" { + export function f(a, b): void; +} + +// @Filename: missingFunctionImplementation2_b.ts +export function f(a?, b?); \ No newline at end of file diff --git a/tests/cases/compiler/shorthandOfExportedEntity01_targetES2015_CommonJS.ts b/tests/cases/compiler/shorthandOfExportedEntity01_targetES2015_CommonJS.ts new file mode 100644 index 00000000000..25328afd6ce --- /dev/null +++ b/tests/cases/compiler/shorthandOfExportedEntity01_targetES2015_CommonJS.ts @@ -0,0 +1,9 @@ +// @target: ES2015 +// @module: commonjs +// @declaration: true + +export const test = "test"; + +export function foo () { + const x = { test }; +} diff --git a/tests/cases/compiler/shorthandOfExportedEntity02_targetES5_CommonJS.ts b/tests/cases/compiler/shorthandOfExportedEntity02_targetES5_CommonJS.ts new file mode 100644 index 00000000000..c7b3a2b37ec --- /dev/null +++ b/tests/cases/compiler/shorthandOfExportedEntity02_targetES5_CommonJS.ts @@ -0,0 +1,9 @@ +// @target: ES5 +// @module: commonjs +// @declaration: true + +export const test = "test"; + +export function foo () { + const x = { test }; +} diff --git a/tests/cases/compiler/strictNullLogicalAndOr.ts b/tests/cases/compiler/strictNullLogicalAndOr.ts new file mode 100644 index 00000000000..68055f8b20b --- /dev/null +++ b/tests/cases/compiler/strictNullLogicalAndOr.ts @@ -0,0 +1,15 @@ +// @strictNullChecks: true + +// Repro from #9113 + +let sinOrCos = Math.random() < .5; +let choice = sinOrCos && Math.sin || Math.cos; + +choice(Math.PI); + +function sq(n?: number): number { + const r = n !== undefined && n*n || 0; + return r; +} + +sq(3); \ No newline at end of file diff --git a/tests/cases/conformance/expressions/typeAssertions/duplicatePropertiesInTypeAssertions01.ts b/tests/cases/conformance/expressions/typeAssertions/duplicatePropertiesInTypeAssertions01.ts new file mode 100644 index 00000000000..2f3da304c99 --- /dev/null +++ b/tests/cases/conformance/expressions/typeAssertions/duplicatePropertiesInTypeAssertions01.ts @@ -0,0 +1,3 @@ +// @declaration: true + +let x = <{a: number; a: number}>{}; \ No newline at end of file diff --git a/tests/cases/conformance/expressions/typeAssertions/duplicatePropertiesInTypeAssertions02.ts b/tests/cases/conformance/expressions/typeAssertions/duplicatePropertiesInTypeAssertions02.ts new file mode 100644 index 00000000000..265fdbe5321 --- /dev/null +++ b/tests/cases/conformance/expressions/typeAssertions/duplicatePropertiesInTypeAssertions02.ts @@ -0,0 +1,3 @@ +// @declaration: true + +let x = {} as {a: number; a: number}; \ No newline at end of file diff --git a/tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion01.ts b/tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion01.ts new file mode 100644 index 00000000000..2e1e2d42499 --- /dev/null +++ b/tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion01.ts @@ -0,0 +1,4 @@ +// @declaration: true + +let x = <[]>[]; +let y = x[0]; \ No newline at end of file diff --git a/tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion02.ts b/tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion02.ts new file mode 100644 index 00000000000..43f63e9ce77 --- /dev/null +++ b/tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion02.ts @@ -0,0 +1,4 @@ +// @declaration: true + +let x = [] as []; +let y = x[0]; \ No newline at end of file diff --git a/tests/cases/conformance/types/union/discriminatedUnionTypes1.ts b/tests/cases/conformance/types/union/discriminatedUnionTypes1.ts new file mode 100644 index 00000000000..404162308b9 --- /dev/null +++ b/tests/cases/conformance/types/union/discriminatedUnionTypes1.ts @@ -0,0 +1,142 @@ +interface Square { + kind: "square"; + size: number; +} + +interface Rectangle { + kind: "rectangle"; + width: number; + height: number; +} + +interface Circle { + kind: "circle"; + radius: number; +} + +type Shape = Square | Rectangle | Circle; + +function area1(s: Shape) { + if (s.kind === "square") { + return s.size * s.size; + } + else if (s.kind === "circle") { + return Math.PI * s.radius * s.radius; + } + else if (s.kind === "rectangle") { + return s.width * s.height; + } + else { + return 0; + } +} + +function area2(s: Shape) { + switch (s.kind) { + case "square": return s.size * s.size; + case "rectangle": return s.width * s.height; + case "circle": return Math.PI * s.radius * s.radius; + } +} + +function assertNever(x: never): never { + throw new Error("Unexpected object: " + x); +} + +function area3(s: Shape) { + switch (s.kind) { + case "square": return s.size * s.size; + case "rectangle": return s.width * s.height; + case "circle": return Math.PI * s.radius * s.radius; + default: return assertNever(s); + } +} + +function area4(s: Shape) { + switch (s.kind) { + case "square": return s.size * s.size; + case "rectangle": return s.width * s.height; + case "circle": return Math.PI * s.radius * s.radius; + } + return assertNever(s); +} + +type Message = + { kind: "A", x: string } | + { kind: "B" | "C", y: number } | + { kind: "D" }; + +function f1(m: Message) { + if (m.kind === "A") { + m; // { kind: "A", x: string } + } + else if (m.kind === "D") { + m; // { kind: "D" } + } + else { + m; // { kind: "B" | "C", y: number } + } +} + +function f2(m: Message) { + if (m.kind === "A") { + return; + } + m; // { kind: "B" | "C", y: number } | { kind: "D" } +} + +function f3(m: Message) { + if (m.kind === "X") { + m; // never + } +} + +function f4(m: Message, x: "A" | "D") { + if (m.kind == x) { + m; // { kind: "A", x: string } | { kind: "D" } + } +} + +function f5(m: Message) { + switch (m.kind) { + case "A": + m; // { kind: "A", x: string } + break; + case "D": + m; // { kind: "D" } + break; + default: + m; // { kind: "B" | "C", y: number } + } +} + +function f6(m: Message) { + switch (m.kind) { + case "A": + m; // { kind: "A", x: string } + case "D": + m; // { kind: "A", x: string } | { kind: "D" } + break; + default: + m; // { kind: "B" | "C", y: number } + } +} + +function f7(m: Message) { + switch (m.kind) { + case "A": + case "B": + return; + } + m; // { kind: "B" | "C", y: number } | { kind: "D" } +} + +function f8(m: Message) { + switch (m.kind) { + case "A": + return; + case "D": + throw new Error(); + } + m; // { kind: "B" | "C", y: number } +} \ No newline at end of file diff --git a/tests/cases/fourslash/ambientShorthandFindAllRefs.ts b/tests/cases/fourslash/ambientShorthandFindAllRefs.ts index 16fddd1869d..2f0dbf914e7 100644 --- a/tests/cases/fourslash/ambientShorthandFindAllRefs.ts +++ b/tests/cases/fourslash/ambientShorthandFindAllRefs.ts @@ -9,13 +9,4 @@ // @Filename: user2.ts ////import {[|x|]} from "jquery"; -let ranges = test.ranges(); -for (let range of ranges) { - goTo.file(range.fileName); - goTo.position(range.start); - - verify.referencesCountIs(ranges.length); - for (let expectedRange of ranges) { - verify.referencesAtPositionContains(expectedRange); - } -} +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/codeCompletionEscaping.ts b/tests/cases/fourslash/codeCompletionEscaping.ts new file mode 100644 index 00000000000..5061a87e5b6 --- /dev/null +++ b/tests/cases/fourslash/codeCompletionEscaping.ts @@ -0,0 +1,9 @@ +/// + +// @Filename: a.js +// @allowJs: true +////___foo; __foo;/**/ + +goTo.marker(); +verify.completionListContains("__foo", undefined, undefined, "warning"); +verify.completionListContains("___foo", undefined, undefined, "warning"); diff --git a/tests/cases/fourslash/findAllRefsForComputedProperties.ts b/tests/cases/fourslash/findAllRefsForComputedProperties.ts index 3ea226b3ce4..065d34c6fc5 100644 --- a/tests/cases/fourslash/findAllRefsForComputedProperties.ts +++ b/tests/cases/fourslash/findAllRefsForComputedProperties.ts @@ -13,12 +13,4 @@ //// ["[|prop1|]"]: function () { }, ////} -let ranges = test.ranges(); -for (let range of ranges) { - goTo.position(range.start); - - verify.referencesCountIs(ranges.length); - for (let expectedReference of ranges) { - verify.referencesAtPositionContains(expectedReference); - } -} \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsForComputedProperties2.ts b/tests/cases/fourslash/findAllRefsForComputedProperties2.ts index b9f6e9538eb..37a9bd8470e 100644 --- a/tests/cases/fourslash/findAllRefsForComputedProperties2.ts +++ b/tests/cases/fourslash/findAllRefsForComputedProperties2.ts @@ -12,12 +12,4 @@ //// ["[|42|]"]: function () { } ////} -let ranges = test.ranges(); -for (let range of ranges) { - goTo.position(range.start); - - verify.referencesCountIs(ranges.length); - for (let expectedReference of ranges) { - verify.referencesAtPositionContains(expectedReference); - } -} \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsForDefaultExport01.ts b/tests/cases/fourslash/findAllRefsForDefaultExport01.ts index 2f40af93c02..39079294a3b 100644 --- a/tests/cases/fourslash/findAllRefsForDefaultExport01.ts +++ b/tests/cases/fourslash/findAllRefsForDefaultExport01.ts @@ -7,12 +7,4 @@ //// ////var y = new [|DefaultExportedClass|]; -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - - verify.referencesCountIs(ranges.length); - for (let expectedReference of ranges) { - verify.referencesAtPositionContains(expectedReference); - } -} \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsForDefaultExport02.ts b/tests/cases/fourslash/findAllRefsForDefaultExport02.ts index db773c74e3c..19f31ece9b0 100644 --- a/tests/cases/fourslash/findAllRefsForDefaultExport02.ts +++ b/tests/cases/fourslash/findAllRefsForDefaultExport02.ts @@ -8,12 +8,4 @@ //// ////var y = [|DefaultExportedFunction|](); -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - - verify.referencesCountIs(ranges.length); - for (let expectedReference of ranges) { - verify.referencesAtPositionContains(expectedReference); - } -} \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsForDefaultExport03.ts b/tests/cases/fourslash/findAllRefsForDefaultExport03.ts index f753d17de49..b9bbfa14a64 100644 --- a/tests/cases/fourslash/findAllRefsForDefaultExport03.ts +++ b/tests/cases/fourslash/findAllRefsForDefaultExport03.ts @@ -14,12 +14,4 @@ //// var local = 100; ////} -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - - verify.referencesCountIs(ranges.length); - for (let expectedReference of ranges) { - verify.referencesAtPositionContains(expectedReference); - } -} \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsForDefaultExport04.ts b/tests/cases/fourslash/findAllRefsForDefaultExport04.ts index 45b008b55fe..44b7ee0a06f 100644 --- a/tests/cases/fourslash/findAllRefsForDefaultExport04.ts +++ b/tests/cases/fourslash/findAllRefsForDefaultExport04.ts @@ -20,9 +20,4 @@ // site is included in the references to the namespace. goTo.marker(); -let ranges = test.ranges(); -verify.referencesCountIs(ranges.length); - -for (let expectedReference of ranges) { - verify.referencesAtPositionContains(expectedReference); -} +verify.referencesAre(test.ranges()); diff --git a/tests/cases/fourslash/findAllRefsForDefaultExport05.ts b/tests/cases/fourslash/findAllRefsForDefaultExport05.ts index 6655138da3b..0f06792458d 100644 --- a/tests/cases/fourslash/findAllRefsForDefaultExport05.ts +++ b/tests/cases/fourslash/findAllRefsForDefaultExport05.ts @@ -20,9 +20,4 @@ // and all value-uses of 'f' are included in the references to the function. goTo.marker(); -let ranges = test.ranges(); -verify.referencesCountIs(ranges.length); - -for (let expectedReference of ranges) { - verify.referencesAtPositionContains(expectedReference); -} +verify.referencesAre(test.ranges()); diff --git a/tests/cases/fourslash/findAllRefsForDefaultExport06.ts b/tests/cases/fourslash/findAllRefsForDefaultExport06.ts index 12c187b4b0c..cdd9b4f980c 100644 --- a/tests/cases/fourslash/findAllRefsForDefaultExport06.ts +++ b/tests/cases/fourslash/findAllRefsForDefaultExport06.ts @@ -20,9 +20,4 @@ // and all value-uses of 'f' are included in the references to the function. goTo.marker(); -let ranges = test.ranges(); -verify.referencesCountIs(ranges.length); - -for (let expectedReference of ranges) { - verify.referencesAtPositionContains(expectedReference); -} +verify.referencesAre(test.ranges()); diff --git a/tests/cases/fourslash/findAllRefsForFunctionExpression01.ts b/tests/cases/fourslash/findAllRefsForFunctionExpression01.ts index a312a277ebb..35d5c45e3d9 100644 --- a/tests/cases/fourslash/findAllRefsForFunctionExpression01.ts +++ b/tests/cases/fourslash/findAllRefsForFunctionExpression01.ts @@ -9,13 +9,4 @@ /////// ////foo(); - -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - - verify.referencesCountIs(ranges.length); - for (let expectedReference of ranges) { - verify.referencesAtPositionContains(expectedReference); - } -} \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsForObjectLiteralProperties.ts b/tests/cases/fourslash/findAllRefsForObjectLiteralProperties.ts index cb5e702dc90..cea4db81ea1 100644 --- a/tests/cases/fourslash/findAllRefsForObjectLiteralProperties.ts +++ b/tests/cases/fourslash/findAllRefsForObjectLiteralProperties.ts @@ -8,13 +8,4 @@ //// ////let {[|property|]: pVar} = x; - -let ranges = test.ranges(); -for (let range of ranges) { - goTo.position(range.start); - - verify.referencesCountIs(ranges.length); - for (let expectedReference of ranges) { - verify.referencesAtPositionContains(expectedReference); - } -} \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsForStringLiteralTypes.ts b/tests/cases/fourslash/findAllRefsForStringLiteralTypes.ts index dcf7240312c..45e981d8a84 100644 --- a/tests/cases/fourslash/findAllRefsForStringLiteralTypes.ts +++ b/tests/cases/fourslash/findAllRefsForStringLiteralTypes.ts @@ -3,12 +3,4 @@ ////type Options = "[|option 1|]" | "option 2"; ////let myOption: Options = "[|option 1|]"; -let ranges = test.ranges(); -for (let range of ranges) { - goTo.position(range.start); - - verify.referencesCountIs(ranges.length); - for (let expectedReference of ranges) { - verify.referencesAtPositionContains(expectedReference); - } -} \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsForVariableInExtendsClause01.ts b/tests/cases/fourslash/findAllRefsForVariableInExtendsClause01.ts index 1ec144d7e82..dd8fb1026c4 100644 --- a/tests/cases/fourslash/findAllRefsForVariableInExtendsClause01.ts +++ b/tests/cases/fourslash/findAllRefsForVariableInExtendsClause01.ts @@ -1,15 +1,6 @@ /// - ////var [|Base|] = class { }; ////class C extends [|Base|] { } -let ranges = test.ranges(); -for (let range of ranges) { - goTo.position(range.start); - - verify.referencesCountIs(ranges.length); - for (let expectedReference of ranges) { - verify.referencesAtPositionContains(expectedReference); - } -} \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsForVariableInExtendsClause02.ts b/tests/cases/fourslash/findAllRefsForVariableInExtendsClause02.ts index 0f06a3c4202..3fc41358dfd 100644 --- a/tests/cases/fourslash/findAllRefsForVariableInExtendsClause02.ts +++ b/tests/cases/fourslash/findAllRefsForVariableInExtendsClause02.ts @@ -6,12 +6,4 @@ //// interface I extends [|Base|] { } ////} -let ranges = test.ranges(); -for (let range of ranges) { - goTo.position(range.start); - - verify.referencesCountIs(ranges.length); - for (let expectedReference of ranges) { - verify.referencesAtPositionContains(expectedReference); - } -} \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsInClassExpression.ts b/tests/cases/fourslash/findAllRefsInClassExpression.ts index 951acdd336c..f874bcbcb5c 100644 --- a/tests/cases/fourslash/findAllRefsInClassExpression.ts +++ b/tests/cases/fourslash/findAllRefsInClassExpression.ts @@ -5,12 +5,4 @@ //// [|boom|](){} ////} -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - - verify.referencesCountIs(ranges.length); - for (let expectedReference of ranges) { - verify.referencesAtPositionContains(expectedReference); - } -} \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsInheritedProperties1.ts b/tests/cases/fourslash/findAllRefsInheritedProperties1.ts index b2755923d37..358ba3f249d 100644 --- a/tests/cases/fourslash/findAllRefsInheritedProperties1.ts +++ b/tests/cases/fourslash/findAllRefsInheritedProperties1.ts @@ -9,17 +9,8 @@ //// v.[|doStuff|](); //// v.[|propName|]; -function verifyReferences(query: FourSlashInterface.Range, references: FourSlashInterface.Range[]) { - goTo.position(query.start); - for (const ref of references) { - verify.referencesAtPositionContains(ref); - } -} - -const ranges = test.ranges(); -verify.assertHasRanges(ranges); -const [r0, r1, r2, r3] = ranges; -verifyReferences(r0, [r0, r2]); -verifyReferences(r1, [r1, r3]); -verifyReferences(r2, [r0, r2]); -verifyReferences(r3, [r1, r3]); \ No newline at end of file +const [r0, r1, r2, r3] = test.ranges(); +verify.referencesOf(r0, [r0, r2]); +verify.referencesOf(r1, [r1, r3]); +verify.referencesOf(r2, [r0, r2]); +verify.referencesOf(r3, [r1, r3]); diff --git a/tests/cases/fourslash/findAllRefsInheritedProperties2.ts b/tests/cases/fourslash/findAllRefsInheritedProperties2.ts index 1ab92c251da..9fe36fbb48e 100644 --- a/tests/cases/fourslash/findAllRefsInheritedProperties2.ts +++ b/tests/cases/fourslash/findAllRefsInheritedProperties2.ts @@ -9,17 +9,8 @@ //// v.[|doStuff|](); // r2 //// v.[|propName|]; // r3 -function verifyReferences(query: FourSlashInterface.Range, references: FourSlashInterface.Range[]) { - goTo.position(query.start); - for (const ref of references) { - verify.referencesAtPositionContains(ref); - } -} - -const ranges = test.ranges(); -verify.assertHasRanges(ranges); -const [r0, r1, r2, r3] = ranges; -verifyReferences(r0, [r0, r2]); -verifyReferences(r1, [r1, r3]); -verifyReferences(r2, [r0, r2]); -verifyReferences(r3, [r1, r3]); \ No newline at end of file +const [r0, r1, r2, r3] = test.ranges(); +verify.referencesOf(r0, [r0, r2]); +verify.referencesOf(r1, [r1, r3]); +verify.referencesOf(r2, [r0, r2]); +verify.referencesOf(r3, [r1, r3]); diff --git a/tests/cases/fourslash/findAllRefsInheritedProperties3.ts b/tests/cases/fourslash/findAllRefsInheritedProperties3.ts index 9a46b08f357..772fb78a2e8 100644 --- a/tests/cases/fourslash/findAllRefsInheritedProperties3.ts +++ b/tests/cases/fourslash/findAllRefsInheritedProperties3.ts @@ -17,21 +17,12 @@ //// v.[|propName|]; // r6 //// v.[|doStuff|](); // r7 -function verifyReferences(query: FourSlashInterface.Range, references: FourSlashInterface.Range[]) { - goTo.position(query.start); - for (const ref of references) { - verify.referencesAtPositionContains(ref); - } -} - -const ranges = test.ranges(); -verify.assertHasRanges(ranges); -const [r0, r1, r2, r3, r4, r5, r6, r7] = ranges; -verifyReferences(r0, [r0]); -verifyReferences(r1, [r1, r5, r6]); -verifyReferences(r2, [r2, r4, r7]); -verifyReferences(r3, [r3, r5, r6]); -verifyReferences(r4, [r2, r4, r7]); -verifyReferences(r5, [r1, r3, r5, r6]); -verifyReferences(r6, [r1, r3, r5, r6]); -verifyReferences(r7, [r2, r4, r7]); \ No newline at end of file +const [r0, r1, r2, r3, r4, r5, r6, r7] = test.ranges(); +verify.referencesOf(r0, [r0, r4, r7]); +verify.referencesOf(r1, [r1, r5, r6]); +verify.referencesOf(r2, [r2, r4, r7]); +verify.referencesOf(r3, [r3, r5, r6]); +verify.referencesOf(r4, [r0, r2, r4, r7]); +verify.referencesOf(r5, [r1, r3, r5, r6]); +verify.referencesOf(r6, [r1, r3, r5, r6]); +verify.referencesOf(r7, [r0, r2, r4, r7]); diff --git a/tests/cases/fourslash/findAllRefsInheritedProperties4.ts b/tests/cases/fourslash/findAllRefsInheritedProperties4.ts index bcd41331f73..1ecb85bfae1 100644 --- a/tests/cases/fourslash/findAllRefsInheritedProperties4.ts +++ b/tests/cases/fourslash/findAllRefsInheritedProperties4.ts @@ -13,18 +13,9 @@ //// d.[|prop0|]; // r3 //// d.[|prop1|]; // r4 -function verifyReferences(query: FourSlashInterface.Range, references: FourSlashInterface.Range[]) { - goTo.position(query.start); - for (const ref of references) { - verify.referencesAtPositionContains(ref); - } -} - -const ranges = test.ranges(); -verify.assertHasRanges(ranges); -const [r0, r1, r2, r3, r4] = ranges; -verifyReferences(r0, [r0, r2, r3]); -verifyReferences(r1, [r1]); -verifyReferences(r2, [r0, r2, r3]); -verifyReferences(r3, [r0, r2, r3]); -verifyReferences(r4, []); \ No newline at end of file +const [r0, r1, r2, r3, r4] = test.ranges(); +verify.referencesOf(r0, [r0, r2, r3]); +verify.referencesOf(r1, [r1]); +verify.referencesOf(r2, [r0, r2, r3]); +verify.referencesOf(r3, [r0, r2, r3]); +verify.referencesOf(r4, []); diff --git a/tests/cases/fourslash/findAllRefsInheritedProperties5.ts b/tests/cases/fourslash/findAllRefsInheritedProperties5.ts index d4e02a36b09..6d6dbb392bf 100644 --- a/tests/cases/fourslash/findAllRefsInheritedProperties5.ts +++ b/tests/cases/fourslash/findAllRefsInheritedProperties5.ts @@ -13,18 +13,9 @@ //// d.[|prop0|]; // r3 //// d.[|prop1|]; // r4 -function verifyReferences(query: FourSlashInterface.Range, references: FourSlashInterface.Range[]) { - goTo.position(query.start); - for (const ref of references) { - verify.referencesAtPositionContains(ref); - } -} - -const ranges = test.ranges(); -verify.assertHasRanges(ranges); -const [r0, r1, r2, r3, r4] = ranges; -verifyReferences(r0, [r0]); -verifyReferences(r1, [r1]); -verifyReferences(r2, [r2, r3]); -verifyReferences(r3, [r2, r3]); -verifyReferences(r4, []); +const [r0, r1, r2, r3, r4] = test.ranges(); +verify.referencesOf(r0, [r0]); +verify.referencesOf(r1, [r1]); +verify.referencesOf(r2, [r2, r3]); +verify.referencesOf(r3, [r2, r3]); +verify.referencesOf(r4, []); diff --git a/tests/cases/fourslash/findAllRefsInsideTemplates1.ts b/tests/cases/fourslash/findAllRefsInsideTemplates1.ts index dd4461751de..9ab4c624230 100644 --- a/tests/cases/fourslash/findAllRefsInsideTemplates1.ts +++ b/tests/cases/fourslash/findAllRefsInsideTemplates1.ts @@ -3,10 +3,4 @@ ////var [|x|] = 10; ////var y = `${ [|x|] } ${ [|x|] }` -test.ranges().forEach(targetRange => { - goTo.position(targetRange.start); - - test.ranges().forEach(range => { - verify.referencesAtPositionContains(range); - }); -}); \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsInsideTemplates2.ts b/tests/cases/fourslash/findAllRefsInsideTemplates2.ts index 7f585234082..63265eb944b 100644 --- a/tests/cases/fourslash/findAllRefsInsideTemplates2.ts +++ b/tests/cases/fourslash/findAllRefsInsideTemplates2.ts @@ -3,10 +3,4 @@ ////function [|f|](...rest: any[]) { } ////[|f|] `${ [|f|] } ${ [|f|] }` -test.ranges().forEach(targetRange => { - goTo.position(targetRange.start); - - test.ranges().forEach(range => { - verify.referencesAtPositionContains(range); - }); -}); \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName01.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName01.ts index 0d03561515d..895b2168b23 100644 --- a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName01.ts +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName01.ts @@ -8,12 +8,4 @@ ////var foo: I; ////var { [|property1|]: prop1 } = foo; -let ranges = test.ranges(); -for (let range of ranges) { - goTo.position(range.start); - - verify.referencesCountIs(ranges.length); - for (let expectedRange of ranges) { - verify.referencesAtPositionContains(expectedRange); - } -} \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName02.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName02.ts index 86514051557..67a31f33d1e 100644 --- a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName02.ts +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName02.ts @@ -8,12 +8,4 @@ ////var foo: I; ////var { [|property1|]: {} } = foo; -let ranges = test.ranges(); -for (let range of ranges) { - goTo.position(range.start); - - verify.referencesCountIs(ranges.length); - for (let expectedRange of ranges) { - verify.referencesAtPositionContains(expectedRange); - } -} \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName03.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName03.ts index 8dc2b1e7bb8..40ecf0139a7 100644 --- a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName03.ts +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName03.ts @@ -8,12 +8,4 @@ ////var foo: I; ////var [{ [|property1|]: prop1 }, { [|property1|], property2 } ] = [foo, foo]; -let ranges = test.ranges(); -for (let range of ranges) { - goTo.position(range.start); - - verify.referencesCountIs(ranges.length); - for (let expectedRange of ranges) { - verify.referencesAtPositionContains(expectedRange); - } -} \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName04.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName04.ts index dfa0997774e..5696d242fed 100644 --- a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName04.ts +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName04.ts @@ -5,17 +5,11 @@ //// property2: string; ////} //// -////function f({ /**/[|property1|]: p1 }: I, +////function f({ [|property1|]: p1 }: I, //// { [|property1|] }: I, //// { property1: p2 }) { //// //// return [|property1|] + 1; ////} -goTo.marker(); - -let ranges = test.ranges(); -verify.referencesCountIs(ranges.length); -for (let expectedRange of ranges) { - verify.referencesAtPositionContains(expectedRange); -} \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName06.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName06.ts index 379d1d4d5f5..8be45ac87e6 100644 --- a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName06.ts +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName06.ts @@ -19,12 +19,4 @@ // Note: if this test ever changes, consider updating // 'quickInfoForObjectBindingElementPropertyName05.ts' -let ranges = test.ranges(); -for (let range of ranges) { - goTo.position(range.start); - - verify.referencesCountIs(ranges.length); - for (let expectedRange of ranges) { - verify.referencesAtPositionContains(expectedRange); - } -} \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName07.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName07.ts index 6448d2396b3..96f414dc060 100644 --- a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName07.ts +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName07.ts @@ -4,12 +4,4 @@ //// ////p, [{ [|a|]: p, b }] = [{ [|a|]: 10, b: true }]; -let ranges = test.ranges(); -for (let range of ranges) { - goTo.position(range.start); - - verify.referencesCountIs(ranges.length); - for (let expectedRange of ranges) { - verify.referencesAtPositionContains(expectedRange); - } -} \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName09.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName09.ts index 0b82c73e31d..5696d242fed 100644 --- a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName09.ts +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName09.ts @@ -6,16 +6,10 @@ ////} //// ////function f({ [|property1|]: p1 }: I, -//// { /**/[|property1|] }: I, +//// { [|property1|] }: I, //// { property1: p2 }) { //// //// return [|property1|] + 1; ////} -goTo.marker(); - -let ranges = test.ranges(); -verify.referencesCountIs(ranges.length); -for (let expectedRange of ranges) { - verify.referencesAtPositionContains(expectedRange); -} \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName10.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName10.ts index 7b8be1aa91c..6ffa4b03b68 100644 --- a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName10.ts +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName10.ts @@ -8,12 +8,4 @@ ////function f ({ [|next|]: { [|next|]: x} }: Recursive) { ////} -let ranges = test.ranges(); -for (let range of ranges) { - goTo.position(range.start); - - verify.referencesCountIs(ranges.length); - for (let expectedRange of ranges) { - verify.referencesAtPositionContains(expectedRange); - } -} \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsOnPrivateParameterProperty1.ts b/tests/cases/fourslash/findAllRefsOnPrivateParameterProperty1.ts index 6686a771b34..3b8b5084a6b 100644 --- a/tests/cases/fourslash/findAllRefsOnPrivateParameterProperty1.ts +++ b/tests/cases/fourslash/findAllRefsOnPrivateParameterProperty1.ts @@ -9,10 +9,4 @@ //// } ////} -test.ranges().forEach(r => { - goTo.position(r.start); - - test.ranges().forEach(range => { - verify.referencesAtPositionContains(range); - }); -}); +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration1.ts b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration1.ts index 4018698f4ef..8f30e3cc853 100644 --- a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration1.ts +++ b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration1.ts @@ -7,15 +7,4 @@ //// } //// } -const ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (const range of ranges) { - goTo.position(range.start); - - if (ranges.length) { - verify.referencesCountIs(ranges.length); - for (const expectedRange of ranges) { - verify.referencesAtPositionContains(expectedRange); - } - } -} \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration2.ts b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration2.ts index a450a77e2dc..d9656e8b5cf 100644 --- a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration2.ts +++ b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration2.ts @@ -7,13 +7,4 @@ //// } //// } -let ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (let range of ranges) { - goTo.position(range.start); - - verify.referencesCountIs(ranges.length); - for (let expectedRange of ranges) { - verify.referencesAtPositionContains(expectedRange); - } -} \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration3.ts b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration3.ts index 82fd67dfc9b..dc48ffedb21 100644 --- a/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration3.ts +++ b/tests/cases/fourslash/findAllRefsParameterPropertyDeclaration3.ts @@ -7,13 +7,4 @@ //// } //// } -const ranges = test.ranges(); -verify.assertHasRanges(ranges); -for (const range of ranges) { - goTo.position(range.start); - - verify.referencesCountIs(ranges.length); - for (const expectedRange of ranges) { - verify.referencesAtPositionContains(expectedRange); - } -} \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsPropertyContextuallyTypedByTypeParam01.ts b/tests/cases/fourslash/findAllRefsPropertyContextuallyTypedByTypeParam01.ts index 357b355971d..f5b0143ac4b 100644 --- a/tests/cases/fourslash/findAllRefsPropertyContextuallyTypedByTypeParam01.ts +++ b/tests/cases/fourslash/findAllRefsPropertyContextuallyTypedByTypeParam01.ts @@ -17,12 +17,4 @@ //// [|a|]: "ss" ////}; -let ranges = test.ranges() -for (let range of ranges) { - goTo.position(range.start); - - verify.referencesCountIs(ranges.length); - for (let expectedReference of ranges) { - verify.referencesAtPositionContains(expectedReference); - } -} \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames1.ts b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames1.ts index 369258832a9..7cc47ee34ea 100644 --- a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames1.ts +++ b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames1.ts @@ -7,12 +7,4 @@ ////var x: Foo; ////x.[|_bar|]; - -test.ranges().forEach(r1 => { - goTo.position(r1.start); - verify.referencesCountIs(2); - - test.ranges().forEach(r2 => { - verify.referencesAtPositionContains(r2); - }); -}); \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames2.ts b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames2.ts index 53adb8236a4..d1449016b59 100644 --- a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames2.ts +++ b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames2.ts @@ -7,12 +7,4 @@ ////var x: Foo; ////x.[|__bar|]; - -test.ranges().forEach(r1 => { - goTo.position(r1.start); - verify.referencesCountIs(2); - - test.ranges().forEach(r2 => { - verify.referencesAtPositionContains(r2); - }); -}); \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames3.ts b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames3.ts index 1793ec6ddc4..e0d6f7f3456 100644 --- a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames3.ts +++ b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames3.ts @@ -7,12 +7,4 @@ ////var x: Foo; ////x.[|___bar|]; - -test.ranges().forEach(r1 => { - goTo.position(r1.start); - verify.referencesCountIs(2); - - test.ranges().forEach(r2 => { - verify.referencesAtPositionContains(r2); - }); -}); \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames4.ts b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames4.ts index 694ecdc79ab..5a8de54db4d 100644 --- a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames4.ts +++ b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames4.ts @@ -7,12 +7,4 @@ ////var x: Foo; ////x.[|____bar|]; - -test.ranges().forEach(r1 => { - goTo.position(r1.start); - verify.referencesCountIs(2); - - test.ranges().forEach(r2 => { - verify.referencesAtPositionContains(r2); - }); -}); \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames5.ts b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames5.ts index a110597f4b7..4ab28f164fe 100644 --- a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames5.ts +++ b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames5.ts @@ -13,12 +13,4 @@ ////x.[|___bar|]; ////x.____bar; - -test.ranges().forEach(r1 => { - goTo.position(r1.start); - verify.referencesCountIs(2); - - test.ranges().forEach(r2 => { - verify.referencesAtPositionContains(r2); - }); -}); \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames6.ts b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames6.ts index 97ed29eb178..191b0bdbc14 100644 --- a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames6.ts +++ b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames6.ts @@ -13,12 +13,4 @@ ////x.___bar; ////x.____bar; - -test.ranges().forEach(r1 => { - goTo.position(r1.start); - verify.referencesCountIs(2); - - test.ranges().forEach(r2 => { - verify.referencesAtPositionContains(r2); - }); -}); \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames7.ts b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames7.ts index afcaf625ede..f3578193096 100644 --- a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames7.ts +++ b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames7.ts @@ -4,11 +4,4 @@ //// [|__foo|](); ////} -test.ranges().forEach(r => { - goTo.position(r.start); - verify.referencesCountIs(2); - - test.ranges().forEach(range => { - verify.referencesAtPositionContains(range); - }); -}); \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames8.ts b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames8.ts index 08ed3414366..15c66f4e7c6 100644 --- a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames8.ts +++ b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames8.ts @@ -4,11 +4,4 @@ //// [|__foo|](); ////}) -test.ranges().forEach(r => { - goTo.position(r.start); - verify.referencesCountIs(2); - - test.ranges().forEach(range => { - verify.referencesAtPositionContains(range); - }); -}); \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames9.ts b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames9.ts index a3923783c46..cc33b618c41 100644 --- a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames9.ts +++ b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames9.ts @@ -4,11 +4,4 @@ //// [|___foo|](); ////}) -test.ranges().forEach(r => { - goTo.position(r.start); - verify.referencesCountIs(2); - - test.ranges().forEach(range => { - verify.referencesAtPositionContains(range); - }); -}); \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 540a6503138..dd8a61ac458 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -124,8 +124,6 @@ declare namespace FourSlashInterface { completionListIsEmpty(): void; completionListAllowsNewIdentifier(): void; memberListIsEmpty(): void; - referencesCountIs(count: number): void; - referencesAtPositionContains(range: Range, isWriteAccess?: boolean): void; signatureHelpPresent(): void; errorExistsBetweenMarkers(startMarker: string, endMarker: string): void; errorExistsAfterMarker(markerName?: string): void; @@ -154,6 +152,24 @@ declare namespace FourSlashInterface { currentFileContentIs(text: string): void; verifyGetEmitOutputForCurrentFile(expected: string): void; verifyGetEmitOutputContentsForCurrentFile(expected: ts.OutputFile[]): void; + referencesCountIs(count: number): void; + /** + * Asserts that the given ranges are the references from the current position. + * If ranges have markers, those markers may have "isDefinition" and "isWriteAccess" data + * (otherwise these properties pf the reference are not tested). + * Order of ranges does not matter. + */ + referencesAre(ranges: Range[]): void; + /** + * Like `referencesAre`, but goes to `start` first. + * `start` should be included in `references`. + */ + referencesOf(start: Range, references: Range[]): void; + /** + * Performs `referencesOf` for every range on the whole set. + * If `ranges` is omitted, this is `test.ranges()`. + */ + rangesReferenceEachOther(ranges?: Range[]): void; currentParameterHelpArgumentNameIs(name: string): void; currentParameterSpanIs(parameter: string): void; currentParameterHelpArgumentDocCommentIs(docComment: string): void; diff --git a/tests/cases/fourslash/getJavaScriptSemanticDiagnostics18.ts b/tests/cases/fourslash/getJavaScriptSemanticDiagnostics18.ts index fdaafa9aa51..707d1537fc5 100644 --- a/tests/cases/fourslash/getJavaScriptSemanticDiagnostics18.ts +++ b/tests/cases/fourslash/getJavaScriptSemanticDiagnostics18.ts @@ -2,14 +2,35 @@ // @allowJs: true // @Filename: a.js -//// class C { v } +////class C { +//// x; // Regular property declaration allowed +//// static y; // static allowed +//// public z; // public not allowed +////} +goTo.file("a.js"); verify.getSemanticDiagnostics(`[ { - "message": "'property declarations' can only be used in a .ts file.", - "start": 10, - "length": 1, + "message": "\'public\' can only be used in a .ts file.", + "start": 93, + "length": 6, "category": "error", - "code": 8014 + "code": 8009 } -]`); \ No newline at end of file +]`); + +// @Filename: b.js +////class C { +//// x: number; // Types not allowed +////} + +goTo.file("b.js"); +verify.getSemanticDiagnostics(`[ + { + "message": "'types' can only be used in a .ts file.", + "start": 17, + "length": 6, + "category": "error", + "code": 8010 + } +]`); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfArrowFunction.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfArrowFunction.ts new file mode 100644 index 00000000000..57b4c14ffba --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfArrowFunction.ts @@ -0,0 +1,5 @@ +/// +////var [|{| "isDefinition": true |}f|] = x => x + 1; +////[|{| "isDefinition": false |}f|](12); + +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfBindingPattern.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfBindingPattern.ts new file mode 100644 index 00000000000..e60921ec3b8 --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfBindingPattern.ts @@ -0,0 +1,5 @@ +/// +////const { [|{| "isDefinition": true |}x|], y } = { x: 1, y: 2 }; +////const z = [|{| "isDefinition": false |}x|]; + +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfClass.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfClass.ts new file mode 100644 index 00000000000..0a3c2e4231c --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfClass.ts @@ -0,0 +1,10 @@ +/// +////class [|{| "isDefinition": true |}C|] { +//// n: number; +//// constructor() { +//// this.n = 12; +//// } +////} +////let c = new [|{| "isDefinition": false |}C|](); + +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfComputedProperty.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfComputedProperty.ts new file mode 100644 index 00000000000..81df97eff2d --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfComputedProperty.ts @@ -0,0 +1,7 @@ +/// +////let o = { ["/**/[|{| "isDefinition": true |}foo|]"]: 12 }; +////let y = o.[|{| "isDefinition": false |}foo|]; +////let z = o['[|{| "isDefinition": false |}foo|]']; + +goTo.marker(); +verify.referencesAre(test.ranges()); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfEnum.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfEnum.ts new file mode 100644 index 00000000000..5b77bf6158a --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfEnum.ts @@ -0,0 +1,8 @@ +/// +////enum [|{| "isDefinition": true |}E|] { +//// First, +//// Second +////} +////let first = [|{| "isDefinition": false |}E|].First; + +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfExport.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfExport.ts new file mode 100644 index 00000000000..759df4fa383 --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfExport.ts @@ -0,0 +1,8 @@ +/// +// @Filename: m.ts +////export var [|{| "isDefinition": true |}x|] = 12; +// @Filename: main.ts +////import { [|{| "isDefinition": true |}x|] } from "./m"; +////const y = [|{| "isDefinition": false |}x|]; + +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfFunction.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfFunction.ts new file mode 100644 index 00000000000..357ef088d61 --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfFunction.ts @@ -0,0 +1,6 @@ +/// +////function [|{| "isDefinition": true |}func|](x: number) { +////} +////[|{| "isDefinition": false |}func|](x) + +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfInterface.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfInterface.ts new file mode 100644 index 00000000000..b7117995d84 --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfInterface.ts @@ -0,0 +1,7 @@ +/// +////interface [|{| "isDefinition": true |}I|] { +//// p: number; +////} +////let i: [|{| "isDefinition": false |}I|] = { p: 12 }; + +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfInterfaceClassMerge.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfInterfaceClassMerge.ts new file mode 100644 index 00000000000..b0506490c70 --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfInterfaceClassMerge.ts @@ -0,0 +1,16 @@ +/// +////interface [|{| "isDefinition": true |}Numbers|] { +//// p: number; +////} +////interface [|{| "isDefinition": true |}Numbers|] { +//// m: number; +////} +////class [|{| "isDefinition": true |}Numbers|] { +//// f(n: number) { +//// return this.p + this.m + n; +//// } +////} +////let i: [|{| "isDefinition": false |}Numbers|] = new [|{| "isDefinition": false |}Numbers|](); +////let x = i.f(i.p + i.m); + +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfNamespace.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfNamespace.ts new file mode 100644 index 00000000000..ff1cf00fa9b --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfNamespace.ts @@ -0,0 +1,7 @@ +/// +////namespace [|{| "isDefinition": true |}Numbers|] { +//// export var n = 12; +////} +////let x = [|{| "isDefinition": false |}Numbers|].n + 1; + +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfNumberNamedProperty.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfNumberNamedProperty.ts new file mode 100644 index 00000000000..a041dab435a --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfNumberNamedProperty.ts @@ -0,0 +1,5 @@ +/// +////let o = { [|{| "isDefinition": true |}1|]: 12 }; +////let y = o[[|{| "isDefinition": false |}1|]]; + +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfParameter.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfParameter.ts new file mode 100644 index 00000000000..cdcc47014fd --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfParameter.ts @@ -0,0 +1,6 @@ +/// +////function f([|{| "isDefinition": true |}x|]: number) { +//// return [|{| "isDefinition": false |}x|] + 1 +////} + +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfStringNamedProperty.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfStringNamedProperty.ts new file mode 100644 index 00000000000..383cf49a2e3 --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfStringNamedProperty.ts @@ -0,0 +1,5 @@ +/// +////let o = { "[|{| "isDefinition": true |}x|]": 12 }; +////let y = o.[|{| "isDefinition": false |}x|]; + +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfTypeAlias.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfTypeAlias.ts new file mode 100644 index 00000000000..2bd66830c69 --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfTypeAlias.ts @@ -0,0 +1,5 @@ +/// +////type [|{| "isDefinition": true |}Alias|]= number; +////let n: [|{| "isDefinition": false |}Alias|] = 12; + +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfVariable.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfVariable.ts new file mode 100644 index 00000000000..78529186ad3 --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfVariable.ts @@ -0,0 +1,20 @@ +/// +////var [|{| "isDefinition": true |}x|] = 0; +////var assignmentRightHandSide = [|{| "isDefinition": false |}x|]; +////var assignmentRightHandSide2 = 1 + [|{| "isDefinition": false |}x|]; +//// +////[|{| "isDefinition": false |}x|] = 1; +////[|{| "isDefinition": false |}x|] = [|{| "isDefinition": false |}x|] + [|{| "isDefinition": false |}x|]; +//// +////[|{| "isDefinition": false |}x|] == 1; +////[|{| "isDefinition": false |}x|] <= 1; +//// +////var preIncrement = ++[|{| "isDefinition": false |}x|]; +////var postIncrement = [|{| "isDefinition": false |}x|]++; +////var preDecrement = --[|{| "isDefinition": false |}x|]; +////var postDecrement = [|{| "isDefinition": false |}x|]--; +//// +////[|{| "isDefinition": false |}x|] += 1; +////[|{| "isDefinition": false |}x|] <<= 1; + +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/navigationBarJsDoc.ts b/tests/cases/fourslash/navigationBarJsDoc.ts new file mode 100644 index 00000000000..20a235bce95 --- /dev/null +++ b/tests/cases/fourslash/navigationBarJsDoc.ts @@ -0,0 +1,21 @@ +/// + +// @Filename: foo.js +/////** @typedef {(number|string)} NumberLike */ +/////** @typedef {(string|number)} */ +////const x = 0; + +verify.navigationBar([ + { + "text": "NumberLike", + "kind": "type" + }, + { + "text": "x", + "kind": "type" + }, + { + "text": "x", + "kind": "var" + } +]); diff --git a/tests/cases/fourslash/referenceToClass.ts b/tests/cases/fourslash/referenceToClass.ts index 2907a468577..3e523487bd1 100644 --- a/tests/cases/fourslash/referenceToClass.ts +++ b/tests/cases/fourslash/referenceToClass.ts @@ -3,34 +3,21 @@ // Class references should work across file and not find local variables. // @Filename: referenceToClass_1.ts -////class /*1*/foo { -//// public n: /*2*/foo; +////class [|foo|] { +//// public n: [|foo|]; //// public foo: number; ////} //// ////class bar { -//// public n: fo/*3*/o; -//// public k = new foo(); +//// public n: [|foo|]; +//// public k = new [|foo|](); ////} //// ////module mod { -//// var k: foo = null; +//// var k: [|foo|] = null; ////} // @Filename: referenceToClass_2.ts -////var k: /*4*/foo; +////var k: [|foo|]; -goTo.marker("1"); -verify.referencesCountIs(6); - -goTo.marker("2"); - -verify.referencesCountIs(6); - -goTo.marker("3"); - -verify.referencesCountIs(6); - -goTo.marker("4"); - -verify.referencesCountIs(6); \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/referencesForStaticsAndMembersWithSameNames.ts b/tests/cases/fourslash/referencesForStaticsAndMembersWithSameNames.ts index fe83f47757b..cada3e0fcf4 100644 --- a/tests/cases/fourslash/referencesForStaticsAndMembersWithSameNames.ts +++ b/tests/cases/fourslash/referencesForStaticsAndMembersWithSameNames.ts @@ -3,12 +3,12 @@ ////module FindRef4 { //// module MixedStaticsClassTest { //// export class Foo { -//// b/*3*/ar: Foo; -//// static b/*4*/ar: Foo; +//// [|bar|]: Foo; +//// static [|bar|]: Foo; //// -//// public f/*1*/oo(): void { +//// public [|foo|](): void { //// } -//// public static f/*2*/oo(): void { +//// public static [|foo|](): void { //// } //// } //// } @@ -16,34 +16,25 @@ //// function test() { //// // instance function //// var x = new MixedStaticsClassTest.Foo(); -//// x.foo(); -//// x.bar; -//// -//// var y = new MixedStaticsClassTest.Foo(); -//// y.foo(); -//// y.bar; +//// x.[|foo|](); +//// x.[|bar|]; //// //// // static function -//// MixedStaticsClassTest.Foo.foo(); -//// MixedStaticsClassTest.Foo.bar; +//// MixedStaticsClassTest.Foo.[|foo|](); +//// MixedStaticsClassTest.Foo.[|bar|]; //// } ////} -// this line triggers a semantic/syntactic error check, remove line when 788570 is fixed -edit.insert(''); +const [fooBar, fooStaticBar, fooFoo, fooStaticFoo, xFoo, xBar, staticFoo, staticBar] = test.ranges(); // References to a member method with the same name as a static. -goTo.marker("1"); -verify.referencesCountIs(3); +verify.referencesOf(fooFoo, [fooFoo, xFoo]); // References to a static method with the same name as a member. -goTo.marker("2"); -verify.referencesCountIs(2); +verify.referencesOf(fooStaticFoo, [fooStaticFoo, staticFoo]); // References to a member property with the same name as a static. -goTo.marker("3"); -verify.referencesCountIs(3); +verify.referencesOf(fooBar, [fooBar, xBar]); // References to a static property with the same name as a member. -goTo.marker("4"); -verify.referencesCountIs(2); +verify.referencesOf(fooStaticBar, [fooStaticBar, staticBar]); diff --git a/tests/cases/fourslash/referencesForStringLiteralPropertyNames.ts b/tests/cases/fourslash/referencesForStringLiteralPropertyNames.ts index e2f61d9cab3..2db0325d324 100644 --- a/tests/cases/fourslash/referencesForStringLiteralPropertyNames.ts +++ b/tests/cases/fourslash/referencesForStringLiteralPropertyNames.ts @@ -1,16 +1,13 @@ /// ////class Foo { -//// public /*1*/"ss": any; +//// public "[|ss|]": any; ////} //// ////var x: Foo; -////x.ss; -////x[/*2*/"ss"]; -////x = { "ss": 0 }; -////x = { /*3*/ss: 0 }; +////x.[|ss|]; +////x["[|ss|]"]; +////x = { "[|ss|]": 0 }; +////x = { [|ss|]: 0 }; -test.markers().forEach((m) => { - goTo.position(m.position, m.fileName); - verify.referencesCountIs(5); -}); +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/referencesForStringLiteralPropertyNames2.ts b/tests/cases/fourslash/referencesForStringLiteralPropertyNames2.ts index 67b956dcd02..275a2b2756c 100644 --- a/tests/cases/fourslash/referencesForStringLiteralPropertyNames2.ts +++ b/tests/cases/fourslash/referencesForStringLiteralPropertyNames2.ts @@ -1,15 +1,10 @@ /// ////class Foo { -//// /*1*/"blah"() { return 0; } +//// "[|blah|]"() { return 0; } ////} //// ////var x: Foo; -////x./*2*/blah; +////x.[|blah|]; - -goTo.marker("1"); -verify.referencesCountIs(2); - -goTo.marker("2"); -verify.referencesCountIs(2); +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/referencesForStringLiteralPropertyNames3.ts b/tests/cases/fourslash/referencesForStringLiteralPropertyNames3.ts index 3288aec9b92..55a067ae8c3 100644 --- a/tests/cases/fourslash/referencesForStringLiteralPropertyNames3.ts +++ b/tests/cases/fourslash/referencesForStringLiteralPropertyNames3.ts @@ -1,15 +1,11 @@ /// ////class Foo2 { -//// get /*1*/"42"() { return 0; } -//// set /*2*/42(n) { } +//// get "[|42|]"() { return 0; } +//// set [|42|](n) { } ////} //// ////var y: Foo2; -////y[42]; +////y[[|42|]]; -goTo.marker("1"); -verify.referencesCountIs(3); - -goTo.marker("2"); -verify.referencesCountIs(3); \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/referencesForStringLiteralPropertyNames4.ts b/tests/cases/fourslash/referencesForStringLiteralPropertyNames4.ts index 08d04188ee9..34cad8f11e8 100644 --- a/tests/cases/fourslash/referencesForStringLiteralPropertyNames4.ts +++ b/tests/cases/fourslash/referencesForStringLiteralPropertyNames4.ts @@ -4,5 +4,4 @@ ////x["[|someProperty|]"] = 3; ////x./*1*/[|someProperty|] = 5; -goTo.marker("1"); -test.ranges().forEach(r => verify.referencesAtPositionContains(r)); \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/referencesForUnionProperties.ts b/tests/cases/fourslash/referencesForUnionProperties.ts index d5f0a2fd516..07eebeb5f74 100644 --- a/tests/cases/fourslash/referencesForUnionProperties.ts +++ b/tests/cases/fourslash/referencesForUnionProperties.ts @@ -1,16 +1,16 @@ /// ////interface One { -//// common: { /*1*/a: number; }; +//// common: { [|a|]: number; }; ////} //// ////interface Base { -//// /*2*/a: string; +//// [|a|]: string; //// b: string; ////} //// ////interface HasAOrB extends Base { -//// /*3*/a: string; +//// [|a|]: string; //// b: string; ////} //// @@ -20,16 +20,10 @@ //// ////var x : One | Two; //// -////x.common./*4*/a; +////x.common.[|a|]; -goTo.marker("1"); -verify.referencesCountIs(2); // One.common.a, x.common.a - -goTo.marker("2"); -verify.referencesCountIs(3); // Base.a, HasAOrB.a, x.common.a - -goTo.marker("3"); -verify.referencesCountIs(3); // Base.a, HasAOrB.a, x.common.a - -goTo.marker("4"); -verify.referencesCountIs(4); // One.common.a, Base.a, HasAOrB.a, x.common.a \ No newline at end of file +const [one, base, hasAOrB, x] = test.ranges(); +verify.referencesOf(one, [one, x]); +verify.referencesOf(base, [base, hasAOrB, x]); +verify.referencesOf(hasAOrB, [base, hasAOrB, x]); +verify.referencesOf(x, [one, base, hasAOrB, x]); diff --git a/tests/cases/fourslash/referencesInComment.ts b/tests/cases/fourslash/referencesInComment.ts index 7ae9fdec9d2..00f7ba26860 100644 --- a/tests/cases/fourslash/referencesInComment.ts +++ b/tests/cases/fourslash/referencesInComment.ts @@ -5,14 +5,6 @@ ////class foo { } ////var bar = 0; -goTo.marker("1"); -verify.referencesCountIs(0); - -goTo.marker("2"); -verify.referencesCountIs(0); - -goTo.marker("3"); -verify.referencesCountIs(0); - -goTo.marker("4"); -verify.referencesCountIs(0); \ No newline at end of file +for (const marker of test.markers()) { + verify.referencesCountIs(0); +} diff --git a/tests/cases/fourslash/renameImportAndExportInDiffFiles.ts b/tests/cases/fourslash/renameImportAndExportInDiffFiles.ts index 7b098721196..e982d6a4c7b 100644 --- a/tests/cases/fourslash/renameImportAndExportInDiffFiles.ts +++ b/tests/cases/fourslash/renameImportAndExportInDiffFiles.ts @@ -1,18 +1,10 @@ /// // @Filename: a.ts -////export var /*1*/a; +////export var [|a|]; // @Filename: b.ts -////import { /*2*/a } from './a'; -////export { /*3*/a }; +////import { [|a|] } from './a'; +////export { [|a|] }; -goTo.file("a.ts"); -goTo.marker("1"); - -goTo.file("b.ts"); -goTo.marker("2"); -verify.referencesCountIs(3); - -goTo.marker("3"); -verify.referencesCountIs(3); \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/salsaMethodsOnAssignedFunctionExpressions.ts b/tests/cases/fourslash/salsaMethodsOnAssignedFunctionExpressions.ts new file mode 100644 index 00000000000..a73207c01d2 --- /dev/null +++ b/tests/cases/fourslash/salsaMethodsOnAssignedFunctionExpressions.ts @@ -0,0 +1,17 @@ +/// +// @allowJs: true +// @Filename: something.js +////var C = function () { } +/////** +//// * The prototype method. +//// * @param {string} a Parameter definition. +//// */ +////function f(a) {} +////C.prototype.m = f; +//// +////var x = new C(); +////x/*1*/./*2*/m(); +goTo.marker('1'); +verify.quickInfoIs('var x: {\n m: (a: string) => void;\n}'); +goTo.marker('2'); +verify.completionListContains('m', '(property) C.m: (a: string) => void', 'The prototype method.'); diff --git a/tests/cases/fourslash/server/references01.ts b/tests/cases/fourslash/server/references01.ts index 0ecbeb43de3..528f79de5b4 100644 --- a/tests/cases/fourslash/server/references01.ts +++ b/tests/cases/fourslash/server/references01.ts @@ -3,16 +3,13 @@ // Global class reference. // @Filename: referencesForGlobals_1.ts -////class /*2*/globalClass { +////class [|globalClass|] { //// public f() { } ////} // @Filename: referencesForGlobals_2.ts /////// -////var c = /*1*/globalClass(); +////var c = [|globalClass|](); -goTo.marker("1"); -verify.referencesCountIs(2); - -goTo.marker("2"); -verify.referencesCountIs(2); \ No newline at end of file +// Must reverse ranges so that referencesForGlobals_2 goes first -- otherwise referencesForGlobals_1 won't pick it up. +verify.rangesReferenceEachOther(test.ranges().reverse()); diff --git a/tests/cases/fourslash/server/referencesInConfiguredProject.ts b/tests/cases/fourslash/server/referencesInConfiguredProject.ts index 9a0d7095a93..109b5e36e4d 100644 --- a/tests/cases/fourslash/server/referencesInConfiguredProject.ts +++ b/tests/cases/fourslash/server/referencesInConfiguredProject.ts @@ -3,18 +3,14 @@ // Global class reference. // @Filename: referencesForGlobals_1.ts -////class /*2*/globalClass { +////class [|globalClass|] { //// public f() { } ////} // @Filename: referencesForGlobals_2.ts -////var c = /*1*/globalClass(); +////var c = [|globalClass|](); // @Filename: tsconfig.json ////{ "files": ["referencesForGlobals_1.ts", "referencesForGlobals_2.ts"] } -goTo.marker("1"); -verify.referencesCountIs(2); - -goTo.marker("2"); -verify.referencesCountIs(2); \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/shims-pp/getReferencesAtPosition.ts b/tests/cases/fourslash/shims-pp/getReferencesAtPosition.ts index a25a6e1285f..cb829807602 100644 --- a/tests/cases/fourslash/shims-pp/getReferencesAtPosition.ts +++ b/tests/cases/fourslash/shims-pp/getReferencesAtPosition.ts @@ -7,7 +7,7 @@ //// //// } //// -//// public /*1*/start(){ +//// public [|start|](){ //// return this; //// } //// @@ -20,10 +20,7 @@ ////import Second = require("./findAllRefsOnDefinition-import"); //// ////var second = new Second.Test() -////second.start(); +////second.[|start|](); ////second.stop(); -goTo.file("findAllRefsOnDefinition-import.ts"); -goTo.marker("1"); - -verify.referencesCountIs(2); \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/fourslash/shims/getReferencesAtPosition.ts b/tests/cases/fourslash/shims/getReferencesAtPosition.ts index a25a6e1285f..cb829807602 100644 --- a/tests/cases/fourslash/shims/getReferencesAtPosition.ts +++ b/tests/cases/fourslash/shims/getReferencesAtPosition.ts @@ -7,7 +7,7 @@ //// //// } //// -//// public /*1*/start(){ +//// public [|start|](){ //// return this; //// } //// @@ -20,10 +20,7 @@ ////import Second = require("./findAllRefsOnDefinition-import"); //// ////var second = new Second.Test() -////second.start(); +////second.[|start|](); ////second.stop(); -goTo.file("findAllRefsOnDefinition-import.ts"); -goTo.marker("1"); - -verify.referencesCountIs(2); \ No newline at end of file +verify.rangesReferenceEachOther(); diff --git a/tests/cases/unittests/commandLineParsing.ts b/tests/cases/unittests/commandLineParsing.ts index 8212ff03da4..095f912ac1c 100644 --- a/tests/cases/unittests/commandLineParsing.ts +++ b/tests/cases/unittests/commandLineParsing.ts @@ -216,10 +216,23 @@ namespace ts { file: undefined, start: undefined, length: undefined, - }, { - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'", - category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category, - code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code, + }], + fileNames: ["0.ts"], + options: { + lib: [] + } + }); + }); + + it("Parse empty string of --lib ", () => { + // 0.ts --lib + // This test is an error because the empty string is falsey + assertParseResult(["0.ts", "--lib", ""], + { + errors: [{ + messageText: "Compiler option 'lib' expects an argument.", + category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category, + code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code, file: undefined, start: undefined, @@ -232,6 +245,19 @@ namespace ts { }); }); + it("Parse immediately following command line argument of --lib ", () => { + // 0.ts --lib + assertParseResult(["0.ts", "--lib", "--sourcemap"], + { + errors: [], + fileNames: ["0.ts"], + options: { + lib: [], + sourceMap: true + } + }); + }); + it("Parse --lib option with extra comma ", () => { // --lib es5, es7 0.ts assertParseResult(["--lib", "es5,", "es7", "0.ts"], diff --git a/tests/cases/unittests/incrementalParser.ts b/tests/cases/unittests/incrementalParser.ts index 0988d51e11b..741c9e54cad 100644 --- a/tests/cases/unittests/incrementalParser.ts +++ b/tests/cases/unittests/incrementalParser.ts @@ -647,7 +647,7 @@ module m3 { }\ const oldText = ScriptSnapshot.fromString(source); const newTextAndChange = withInsert(oldText, 0, ""); - compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 8); + compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 7); }); it("Class to interface", () => { diff --git a/tests/cases/unittests/transpile.ts b/tests/cases/unittests/transpile.ts index a4b1416ed29..3f29002e6a2 100644 --- a/tests/cases/unittests/transpile.ts +++ b/tests/cases/unittests/transpile.ts @@ -5,328 +5,243 @@ namespace ts { interface TranspileTestSettings { options?: TranspileOptions; - expectedOutput?: string; - expectedDiagnosticCodes?: number[]; - expectedDiagnosticTexts?: string[]; } - function checkDiagnostics(diagnostics: Diagnostic[], expectedDiagnosticCodes: number[] = [], expectedDiagnosticTexts?: string[]) { - const n = expectedDiagnosticCodes.length; - if (expectedDiagnosticTexts) { - assert.equal(n, expectedDiagnosticTexts.length); - } - for (let i = 0; i < n; i++) { - assert.equal(expectedDiagnosticCodes[i], diagnostics[i] && diagnostics[i].code, `Could not find expected diagnostic.`); - if (expectedDiagnosticTexts) { - assert.equal(expectedDiagnosticTexts[i], diagnostics[i] && diagnostics[i].messageText); - } - }; - assert.equal(diagnostics.length, n, "Resuting diagnostics count does not match expected"); - } + function transpilesCorrectly(name: string, input: string, testSettings: TranspileTestSettings) { + describe(name, () => { + let justName: string; + let transpileOptions: TranspileOptions; + let canUseOldTranspile: boolean; + let toBeCompiled: Harness.Compiler.TestFile[]; + let transpileResult: TranspileOutput; + let oldTranspileResult: string; + let oldTranspileDiagnostics: Diagnostic[]; - function test(input: string, testSettings: TranspileTestSettings): void { + before(() => { + transpileOptions = testSettings.options || {}; + if (!transpileOptions.compilerOptions) { + transpileOptions.compilerOptions = {}; + } - const transpileOptions: TranspileOptions = testSettings.options || {}; - if (!transpileOptions.compilerOptions) { - transpileOptions.compilerOptions = {}; - } - if (transpileOptions.compilerOptions.newLine === undefined) { - // use \r\n as default new line - transpileOptions.compilerOptions.newLine = ts.NewLineKind.CarriageReturnLineFeed; - } + if (transpileOptions.compilerOptions.newLine === undefined) { + // use \r\n as default new line + transpileOptions.compilerOptions.newLine = ts.NewLineKind.CarriageReturnLineFeed; + } - const canUseOldTranspile = !transpileOptions.renamedDependencies; + transpileOptions.compilerOptions.sourceMap = true; - transpileOptions.reportDiagnostics = true; - const transpileModuleResult = transpileModule(input, transpileOptions); + if (!transpileOptions.fileName) { + transpileOptions.fileName = transpileOptions.compilerOptions.jsx ? "file.tsx" : "file.ts"; + } - checkDiagnostics(transpileModuleResult.diagnostics, testSettings.expectedDiagnosticCodes, testSettings.expectedDiagnosticTexts); + transpileOptions.reportDiagnostics = true; - if (testSettings.expectedOutput !== undefined) { - assert.equal(transpileModuleResult.outputText, testSettings.expectedOutput); - } + justName = "transpile/" + name.replace(/[^a-z0-9\-. ]/ig, "") + (transpileOptions.compilerOptions.jsx ? ".tsx" : ".ts"); + toBeCompiled = [{ + unitName: transpileOptions.fileName, + content: input + }]; - if (canUseOldTranspile) { - const diagnostics: Diagnostic[] = []; - const transpileResult = transpile(input, transpileOptions.compilerOptions, transpileOptions.fileName, diagnostics, transpileOptions.moduleName); - checkDiagnostics(diagnostics, testSettings.expectedDiagnosticCodes, testSettings.expectedDiagnosticTexts); - if (testSettings.expectedOutput) { - assert.equal(transpileResult, testSettings.expectedOutput); - } - } + canUseOldTranspile = !transpileOptions.renamedDependencies; + transpileResult = transpileModule(input, transpileOptions); - // check source maps - if (!transpileOptions.compilerOptions) { - transpileOptions.compilerOptions = {}; - } - - if (!transpileOptions.fileName) { - transpileOptions.fileName = transpileOptions.compilerOptions.jsx ? "file.tsx" : "file.ts"; - } - - transpileOptions.compilerOptions.sourceMap = true; - const transpileModuleResultWithSourceMap = transpileModule(input, transpileOptions); - assert.isTrue(transpileModuleResultWithSourceMap.sourceMapText !== undefined); - - const expectedSourceMapFileName = removeFileExtension(getBaseFileName(normalizeSlashes(transpileOptions.fileName))) + ".js.map"; - const expectedSourceMappingUrlLine = `//# sourceMappingURL=${expectedSourceMapFileName}`; - - if (testSettings.expectedOutput !== undefined) { - assert.equal(transpileModuleResultWithSourceMap.outputText, testSettings.expectedOutput + expectedSourceMappingUrlLine); - } - else { - // expected output is not set, just verify that output text has sourceMappingURL as a last line - const output = transpileModuleResultWithSourceMap.outputText; - assert.isTrue(output.length >= expectedSourceMappingUrlLine.length); - if (output.length === expectedSourceMappingUrlLine.length) { - assert.equal(output, expectedSourceMappingUrlLine); - } - else { - const suffix = getNewLineCharacter(transpileOptions.compilerOptions) + expectedSourceMappingUrlLine; - assert.isTrue(output.indexOf(suffix, output.length - suffix.length) !== -1); - } - } - - } - - it("Generates no diagnostics with valid inputs", () => { - // No errors - test(`var x = 0;`, { options: { compilerOptions: { module: ModuleKind.CommonJS } } }); - }); - - it("Generates no diagnostics for missing file references", () => { - test(`/// -var x = 0;`, - { options: { compilerOptions: { module: ModuleKind.CommonJS } } }); - }); - - it("Generates no diagnostics for missing module imports", () => { - test(`import {a} from "module2";`, - { options: { compilerOptions: { module: ModuleKind.CommonJS } } }); - }); - - it("Generates expected syntactic diagnostics", () => { - test(`a b`, - { options: { compilerOptions: { module: ModuleKind.CommonJS } }, expectedDiagnosticCodes: [1005] }); /// 1005: ';' Expected - }); - - it("Does not generate semantic diagnostics", () => { - test(`var x: string = 0;`, - { options: { compilerOptions: { module: ModuleKind.CommonJS } } }); - }); - - it("Generates module output", () => { - test(`var x = 0;`, - { - options: { compilerOptions: { module: ModuleKind.AMD } }, - expectedOutput: `define(["require", "exports"], function (require, exports) {\r\n "use strict";\r\n var x = 0;\r\n});\r\n` + if (canUseOldTranspile) { + oldTranspileDiagnostics = []; + oldTranspileResult = transpile(input, transpileOptions.compilerOptions, transpileOptions.fileName, oldTranspileDiagnostics, transpileOptions.moduleName); + } }); - }); - it("Uses correct newLine character", () => { - test(`var x = 0;`, - { - options: { compilerOptions: { module: ModuleKind.CommonJS, newLine: NewLineKind.LineFeed } }, - expectedOutput: `"use strict";\nvar x = 0;\n` + after(() => { + justName = undefined; + transpileOptions = undefined; + canUseOldTranspile = undefined; + toBeCompiled = undefined; + transpileResult = undefined; + oldTranspileResult = undefined; + oldTranspileDiagnostics = undefined; }); - }); - it("Sets module name", () => { - const output = - `System.register("NamedModule", [], function(exports_1, context_1) {\n` + - ` "use strict";\n` + - ` var __moduleName = context_1 && context_1.id;\n` + - ` var x;\n` + - ` return {\n` + - ` setters:[],\n` + - ` execute: function() {\n` + - ` var x = 1;\n` + - ` }\n` + - ` }\n` + - `});\n`; - test("var x = 1;", - { - options: { compilerOptions: { module: ModuleKind.System, newLine: NewLineKind.LineFeed }, moduleName: "NamedModule" }, - expectedOutput: output - }); - }); - - it("No extra errors for file without extension", () => { - test(`"use strict";\r\nvar x = 0;`, { options: { compilerOptions: { module: ModuleKind.CommonJS }, fileName: "file" } }); - }); - - it("Rename dependencies - System", () => { - const input = - `import {foo} from "SomeName";\n` + - `declare function use(a: any);\n` + - `use(foo);`; - const output = - `System.register(["SomeOtherName"], function(exports_1, context_1) {\n` + - ` "use strict";\n` + - ` var __moduleName = context_1 && context_1.id;\n` + - ` var SomeName_1;\n` + - ` return {\n` + - ` setters:[\n` + - ` function (SomeName_1_1) {\n` + - ` SomeName_1 = SomeName_1_1;\n` + - ` }],\n` + - ` execute: function() {\n` + - ` use(SomeName_1.foo);\n` + - ` }\n` + - ` }\n` + - `});\n`; - - test(input, - { - options: { compilerOptions: { module: ModuleKind.System, newLine: NewLineKind.LineFeed }, renamedDependencies: { "SomeName": "SomeOtherName" } }, - expectedOutput: output - }); - }); - - it("Rename dependencies - AMD", () => { - const input = - `import {foo} from "SomeName";\n` + - `declare function use(a: any);\n` + - `use(foo);`; - const output = - `define(["require", "exports", "SomeOtherName"], function (require, exports, SomeName_1) {\n` + - ` "use strict";\n` + - ` use(SomeName_1.foo);\n` + - `});\n`; - - test(input, - { - options: { compilerOptions: { module: ModuleKind.AMD, newLine: NewLineKind.LineFeed }, renamedDependencies: { "SomeName": "SomeOtherName" } }, - expectedOutput: output - }); - }); - - it("Rename dependencies - UMD", () => { - const input = - `import {foo} from "SomeName";\n` + - `declare function use(a: any);\n` + - `use(foo);`; - const output = - `(function (factory) {\n` + - ` if (typeof module === 'object' && typeof module.exports === 'object') {\n` + - ` var v = factory(require, exports); if (v !== undefined) module.exports = v;\n` + - ` }\n` + - ` else if (typeof define === 'function' && define.amd) {\n` + - ` define(["require", "exports", "SomeOtherName"], factory);\n` + - ` }\n` + - `})(function (require, exports) {\n` + - ` "use strict";\n` + - ` var SomeName_1 = require("SomeOtherName");\n` + - ` use(SomeName_1.foo);\n` + - `});\n`; - - test(input, - { - options: { compilerOptions: { module: ModuleKind.UMD, newLine: NewLineKind.LineFeed }, renamedDependencies: { "SomeName": "SomeOtherName" } }, - expectedOutput: output - }); - }); - - it("Transpile with emit decorators and emit metadata", () => { - const input = - `import {db} from './db';\n` + - `function someDecorator(target) {\n` + - ` return target;\n` + - `} \n` + - `@someDecorator\n` + - `class MyClass {\n` + - ` db: db;\n` + - ` constructor(db: db) {\n` + - ` this.db = db;\n` + - ` this.db.doSomething(); \n` + - ` }\n` + - `}\n` + - `export {MyClass}; \n`; - const output = - `"use strict";\n` + - `var db_1 = require(\'./db\');\n` + - `function someDecorator(target) {\n` + - ` return target;\n` + - `}\n` + - `var MyClass = (function () {\n` + - ` function MyClass(db) {\n` + - ` this.db = db;\n` + - ` this.db.doSomething();\n` + - ` }\n` + - ` MyClass = __decorate([\n` + - ` someDecorator, \n` + - ` __metadata(\'design:paramtypes\', [(typeof (_a = typeof db_1.db !== \'undefined\' && db_1.db) === \'function\' && _a) || Object])\n` + - ` ], MyClass);\n` + - ` return MyClass;\n` + - ` var _a;\n` + - `}());\n` + - `exports.MyClass = MyClass;\n`; - - test(input, - { - options: { - compilerOptions: { - module: ModuleKind.CommonJS, - newLine: NewLineKind.LineFeed, - noEmitHelpers: true, - emitDecoratorMetadata: true, - experimentalDecorators: true, - target: ScriptTarget.ES5, + it("Correct errors for " + justName, () => { + Harness.Baseline.runBaseline("Correct errors", justName.replace(/\.tsx?$/, ".errors.txt"), () => { + if (transpileResult.diagnostics.length === 0) { + /* tslint:disable:no-null-keyword */ + return null; + /* tslint:enable:no-null-keyword */ } - }, - expectedOutput: output + + return Harness.Compiler.getErrorBaseline(toBeCompiled, transpileResult.diagnostics); + }); }); - }); - it("Supports backslashes in file name", () => { - test("var x", { expectedOutput: `"use strict";\r\nvar x;\r\n`, options: { fileName: "a\\b.ts" }}); - }); + if (canUseOldTranspile) { + it("Correct errors (old transpile) for " + justName, () => { + Harness.Baseline.runBaseline("Correct errors", justName.replace(/\.tsx?$/, ".oldTranspile.errors.txt"), () => { + if (oldTranspileDiagnostics.length === 0) { + /* tslint:disable:no-null-keyword */ + return null; + /* tslint:enable:no-null-keyword */ + } - it("transpile file as 'tsx' if 'jsx' is specified", () => { - const input = `var x =
`; - const output = `"use strict";\nvar x = React.createElement("div", null);\n`; - test(input, { - expectedOutput: output, - options: { compilerOptions: { jsx: JsxEmit.React, newLine: NewLineKind.LineFeed } } - }); - }); + return Harness.Compiler.getErrorBaseline(toBeCompiled, oldTranspileDiagnostics); + }); + }); + } - it("transpile .js files", () => { - const input = "const a = 10;"; - const output = `"use strict";\nvar a = 10;\n`; - test(input, { - expectedOutput: output, - options: { compilerOptions: { newLine: NewLineKind.LineFeed, module: ModuleKind.CommonJS }, fileName: "input.js", reportDiagnostics: true } - }); - }); - - it("Supports urls in file name", () => { - test("var x", { expectedOutput: `"use strict";\r\nvar x;\r\n`, options: { fileName: "http://somewhere/directory//directory2/file.ts" } }); - }); - - describe("String values for enums", () => { - it("Accepts strings instead of enum values", () => { - test(`export const x = 0`, { - options: { - compilerOptions: { - module: "es6", - // Capitalization and spaces ignored - target: " Es6 " + it("Correct output for " + justName, () => { + Harness.Baseline.runBaseline("Correct output", justName.replace(/\.tsx?$/, ".js"), () => { + if (transpileResult.outputText) { + return transpileResult.outputText; } - }, - expectedOutput: "export const x = 0;\r\n" + else { + // This can happen if compiler recieve invalid compiler-options + /* tslint:disable:no-null-keyword */ + return null; + /* tslint:enable:no-null-keyword */ + } + }); }); - }); - it("Fails on bad value", () => { - for (const value in [123, {}, ""]) { - test(``, { - options: { compilerOptions: { module: value } }, - expectedDiagnosticCodes: [6046], - expectedDiagnosticTexts: ["Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'"] + + if (canUseOldTranspile) { + it("Correct output (old transpile) for " + justName, () => { + Harness.Baseline.runBaseline("Correct output", justName.replace(/\.tsx?$/, ".oldTranspile.js"), () => { + return oldTranspileResult; + }); }); } }); + } + + transpilesCorrectly("Generates no diagnostics with valid inputs", `var x = 0;`, { + options: { compilerOptions: { module: ModuleKind.CommonJS } } + }); + + transpilesCorrectly("Generates no diagnostics for missing file references", `/// +var x = 0;`, { + options: { compilerOptions: { module: ModuleKind.CommonJS } } + }); + + transpilesCorrectly("Generates no diagnostics for missing module imports", `import {a} from "module2";`, { + options: { compilerOptions: { module: ModuleKind.CommonJS } } + }); + + transpilesCorrectly("Generates expected syntactic diagnostics", `a b`, { + options: { compilerOptions: { module: ModuleKind.CommonJS } } + }); + + transpilesCorrectly("Does not generate semantic diagnostics", `var x: string = 0;`, { + options: { compilerOptions: { module: ModuleKind.CommonJS } } + }); + + transpilesCorrectly("Generates module output", `var x = 0;`, { + options: { compilerOptions: { module: ModuleKind.AMD } } + }); + + transpilesCorrectly("Uses correct newLine character", `var x = 0;`, { + options: { compilerOptions: { module: ModuleKind.CommonJS, newLine: NewLineKind.LineFeed } } + }); + + transpilesCorrectly("Sets module name", "var x = 1;", { + options: { compilerOptions: { module: ModuleKind.System, newLine: NewLineKind.LineFeed }, moduleName: "NamedModule" } + }); + + transpilesCorrectly("No extra errors for file without extension", `"use strict";\r\nvar x = 0;`, { + options: { compilerOptions: { module: ModuleKind.CommonJS }, fileName: "file" } + }); + + transpilesCorrectly("Rename dependencies - System", + `import {foo} from "SomeName";\n` + + `declare function use(a: any);\n` + + `use(foo);`, { + options: { compilerOptions: { module: ModuleKind.System, newLine: NewLineKind.LineFeed }, renamedDependencies: { "SomeName": "SomeOtherName" } } + }); + + transpilesCorrectly("Rename dependencies - AMD", + `import {foo} from "SomeName";\n` + + `declare function use(a: any);\n` + + `use(foo);`, { + options: { compilerOptions: { module: ModuleKind.AMD, newLine: NewLineKind.LineFeed }, renamedDependencies: { "SomeName": "SomeOtherName" } } + }); + + transpilesCorrectly("Rename dependencies - UMD", + `import {foo} from "SomeName";\n` + + `declare function use(a: any);\n` + + `use(foo);`, { + options: { compilerOptions: { module: ModuleKind.UMD, newLine: NewLineKind.LineFeed }, renamedDependencies: { "SomeName": "SomeOtherName" } } + }); + + transpilesCorrectly("Transpile with emit decorators and emit metadata", + `import {db} from './db';\n` + + `function someDecorator(target) {\n` + + ` return target;\n` + + `} \n` + + `@someDecorator\n` + + `class MyClass {\n` + + ` db: db;\n` + + ` constructor(db: db) {\n` + + ` this.db = db;\n` + + ` this.db.doSomething(); \n` + + ` }\n` + + `}\n` + + `export {MyClass}; \n`, { + options: { + compilerOptions: { + module: ModuleKind.CommonJS, + newLine: NewLineKind.LineFeed, + noEmitHelpers: true, + emitDecoratorMetadata: true, + experimentalDecorators: true, + target: ScriptTarget.ES5, + } + } + }); + + transpilesCorrectly("Supports backslashes in file name", "var x", { + options: { fileName: "a\\b.ts" } + }); + + transpilesCorrectly("transpile file as 'tsx' if 'jsx' is specified", `var x =
`, { + options: { compilerOptions: { jsx: JsxEmit.React, newLine: NewLineKind.LineFeed } } + }); + + transpilesCorrectly("transpile .js files", "const a = 10;", { + options: { compilerOptions: { newLine: NewLineKind.LineFeed, module: ModuleKind.CommonJS }, fileName: "input.js", reportDiagnostics: true } + }); + + transpilesCorrectly("Supports urls in file name", "var x", { + options: { fileName: "http://somewhere/directory//directory2/file.ts" } + }); + + transpilesCorrectly("Accepts string as enum values for compile-options", "export const x = 0", { + options: { compilerOptions: { + module: "es6", + // Capitalization and spaces ignored + target: " Es6 " + }} + }); + + transpilesCorrectly("Report an error when compiler-options module-kind is out-of-range", "", { + options: { compilerOptions: { module: 123 }} + }); + + transpilesCorrectly("Report an error when compiler-options target-script is out-of-range", "", { + options: { compilerOptions: { module: 123 }} + }); + + transpilesCorrectly("Report an error when compiler-options input is empty object", "", { + options: { compilerOptions: { module: {} }} + }); + + transpilesCorrectly("Report an error when compiler-options input is empty string", "", { + options: { compilerOptions: { module: "" }} + }); + + transpilesCorrectly("Support options with lib values", "const a = 10;", { + options: { compilerOptions: { lib: ["es6", "dom"], module: ModuleKind.CommonJS }, fileName: "input.js", reportDiagnostics: true } + }); + + transpilesCorrectly("Support options with types values", "const a = 10;", { + options: { compilerOptions: { types: ["jquery", "typescript"], module: ModuleKind.CommonJS }, fileName: "input.js", reportDiagnostics: true } }); }); } diff --git a/tests/cases/unittests/tsserverProjectSystem.ts b/tests/cases/unittests/tsserverProjectSystem.ts index dcefd491fff..308aa82f85f 100644 --- a/tests/cases/unittests/tsserverProjectSystem.ts +++ b/tests/cases/unittests/tsserverProjectSystem.ts @@ -25,6 +25,7 @@ namespace ts { interface FileOrFolder { path: string; content?: string; + fileSize?: number; } interface FSEntry { @@ -34,6 +35,7 @@ namespace ts { interface File extends FSEntry { content: string; + fileSize?: number; } interface Folder extends FSEntry { @@ -140,7 +142,7 @@ namespace ts { const path = this.toPath(fileOrFolder.path); const fullPath = getNormalizedAbsolutePath(fileOrFolder.path, this.currentDirectory); if (typeof fileOrFolder.content === "string") { - const entry = { path, content: fileOrFolder.content, fullPath }; + const entry = { path, content: fileOrFolder.content, fullPath, fileSize: fileOrFolder.fileSize }; this.fs.set(path, entry); addFolder(getDirectoryPath(fullPath), this.toPath, this.fs).entries.push(entry); } @@ -155,6 +157,17 @@ namespace ts { return this.fs.contains(path) && isFile(this.fs.get(path)); }; + getFileSize(s: string) { + const path = this.toPath(s); + if (this.fs.contains(path)) { + const entry = this.fs.get(path); + if (isFile(entry)) { + return entry.fileSize ? entry.fileSize : entry.content.length; + } + } + return undefined; + } + directoryExists(s: string) { const path = this.toPath(s); return this.fs.contains(path) && isFolder(this.fs.get(path)); @@ -566,5 +579,59 @@ namespace ts { checkConfiguredProjectActualFiles(project, [file1.path, classicModuleFile.path]); checkNumberOfInferredProjects(projectService, 1); }); + + it("should keep the configured project when the opened file is referenced by the project but not its root", () => { + const file1: FileOrFolder = { + path: "/a/b/main.ts", + content: "import { objA } from './obj-a';" + }; + const file2: FileOrFolder = { + path: "/a/b/obj-a.ts", + content: `export const objA = Object.assign({foo: "bar"}, {bar: "baz"});` + }; + const configFile: FileOrFolder = { + path: "/a/b/tsconfig.json", + content: `{ + "compilerOptions": { + "target": "es6" + }, + "files": [ "main.ts" ] + }` + }; + const host = new TestServerHost(/*useCaseSensitiveFileNames*/ false, getExecutingFilePathFromLibFile(libFile), "/", [file1, file2, configFile]); + const projectService = new server.ProjectService(host, nullLogger); + projectService.openClientFile(file1.path); + projectService.closeClientFile(file1.path); + projectService.openClientFile(file2.path); + checkNumberOfConfiguredProjects(projectService, 1); + checkNumberOfInferredProjects(projectService, 0); + }); + + it("should keep the configured project when the opened file is referenced by the project but not its root", () => { + const file1: FileOrFolder = { + path: "/a/b/main.ts", + content: "import { objA } from './obj-a';" + }; + const file2: FileOrFolder = { + path: "/a/b/obj-a.ts", + content: `export const objA = Object.assign({foo: "bar"}, {bar: "baz"});` + }; + const configFile: FileOrFolder = { + path: "/a/b/tsconfig.json", + content: `{ + "compilerOptions": { + "target": "es6" + }, + "files": [ "main.ts" ] + }` + }; + const host = new TestServerHost(/*useCaseSensitiveFileNames*/ false, getExecutingFilePathFromLibFile(libFile), "/", [file1, file2, configFile]); + const projectService = new server.ProjectService(host, nullLogger); + projectService.openClientFile(file1.path); + projectService.closeClientFile(file1.path); + projectService.openClientFile(file2.path); + checkNumberOfConfiguredProjects(projectService, 1); + checkNumberOfInferredProjects(projectService, 0); + }); }); } \ No newline at end of file