Merge remote-tracking branch 'upstream/master' into fix8275

This commit is contained in:
Ryan Cavanaugh
2016-05-18 12:07:11 -07:00
100 changed files with 2093 additions and 367 deletions
+1
View File
@@ -962,6 +962,7 @@ function lintFileAsync(options, path, cb) {
var servicesLintTargets = [
"navigateTo.ts",
"navigationBar.ts",
"outliningElementsCollector.ts",
"patternMatcher.ts",
"services.ts",
+81 -67
View File
@@ -79,6 +79,7 @@ namespace ts {
getIndexTypeOfType,
getBaseTypes,
getReturnTypeOfSignature,
getNonNullableType,
getSymbolsInScope,
getSymbolAtLocation,
getShorthandAssignmentValueSymbol,
@@ -120,9 +121,9 @@ namespace ts {
const nullType = createIntrinsicType(TypeFlags.Null | nullableWideningFlags, "null");
const emptyArrayElementType = createIntrinsicType(TypeFlags.Undefined | TypeFlags.ContainsUndefinedOrNull, "undefined");
const unknownType = createIntrinsicType(TypeFlags.Any, "unknown");
const neverType = createIntrinsicType(TypeFlags.Never, "never");
const emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
const nothingType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
const emptyGenericType = <GenericType><ObjectType>createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
emptyGenericType.instantiations = {};
@@ -2029,12 +2030,7 @@ namespace ts {
writeUnionOrIntersectionType(<UnionOrIntersectionType>type, flags);
}
else if (type.flags & TypeFlags.Anonymous) {
if (type === nothingType) {
writer.writeKeyword("nothing");
}
else {
writeAnonymousType(<ObjectType>type, flags);
}
writeAnonymousType(<ObjectType>type, flags);
}
else if (type.flags & TypeFlags.StringLiteral) {
writer.writeStringLiteral(`"${escapeString((<StringLiteralType>type).text)}"`);
@@ -2884,6 +2880,10 @@ namespace ts {
return undefined;
}
function addOptionality(type: Type, optional: boolean): Type {
return strictNullChecks && optional ? addNullableKind(type, TypeFlags.Undefined) : type;
}
// Return the inferred type for a variable, parameter, or property declaration
function getTypeForVariableLikeDeclaration(declaration: VariableLikeDeclaration): Type {
if (declaration.flags & NodeFlags.JavaScriptFile) {
@@ -2915,8 +2915,7 @@ namespace ts {
// Use type from type annotation if one is present
if (declaration.type) {
const type = getTypeFromTypeNode(declaration.type);
return strictNullChecks && declaration.questionToken ? addNullableKind(type, TypeFlags.Undefined) : type;
return addOptionality(getTypeFromTypeNode(declaration.type), /*optional*/ !!declaration.questionToken);
}
if (declaration.kind === SyntaxKind.Parameter) {
@@ -2938,13 +2937,13 @@ namespace ts {
? getContextuallyTypedThisType(func)
: getContextuallyTypedParameterType(<ParameterDeclaration>declaration);
if (type) {
return strictNullChecks && declaration.questionToken ? addNullableKind(type, TypeFlags.Undefined) : type;
return addOptionality(type, /*optional*/ !!declaration.questionToken);
}
}
// Use the type of the initializer expression if one is present
if (declaration.initializer) {
return checkExpressionCached(declaration.initializer);
return addOptionality(checkExpressionCached(declaration.initializer), /*optional*/ !!declaration.questionToken);
}
// If it is a short-hand property assignment, use the type of the identifier
@@ -3215,7 +3214,9 @@ namespace ts {
function getTypeOfFuncClassEnumModule(symbol: Symbol): Type {
const links = getSymbolLinks(symbol);
if (!links.type) {
links.type = createObjectType(TypeFlags.Anonymous, symbol);
const type = createObjectType(TypeFlags.Anonymous, symbol);
links.type = strictNullChecks && symbol.flags & SymbolFlags.Optional ?
addNullableKind(type, TypeFlags.Undefined) : type;
}
return links.type;
}
@@ -3670,6 +3671,7 @@ namespace ts {
case SyntaxKind.VoidKeyword:
case SyntaxKind.UndefinedKeyword:
case SyntaxKind.NullKeyword:
case SyntaxKind.NeverKeyword:
case SyntaxKind.StringLiteralType:
return true;
case SyntaxKind.ArrayType:
@@ -5005,7 +5007,7 @@ namespace ts {
if (type.flags & TypeFlags.Undefined) typeSet.containsUndefined = true;
if (type.flags & TypeFlags.Null) typeSet.containsNull = true;
}
else if (type !== nothingType && !contains(typeSet, type)) {
else if (type !== neverType && !contains(typeSet, type)) {
typeSet.push(type);
}
}
@@ -5046,7 +5048,7 @@ namespace ts {
// a named type that circularly references itself.
function getUnionType(types: Type[], noSubtypeReduction?: boolean): Type {
if (types.length === 0) {
return nothingType;
return neverType;
}
if (types.length === 1) {
return types[0];
@@ -5066,7 +5068,7 @@ namespace ts {
if (typeSet.length === 0) {
return typeSet.containsNull ? nullType :
typeSet.containsUndefined ? undefinedType :
nothingType;
neverType;
}
else if (typeSet.length === 1) {
return typeSet[0];
@@ -5150,7 +5152,7 @@ namespace ts {
function getTypeFromStringLiteralTypeNode(node: StringLiteralTypeNode): Type {
const links = getNodeLinks(node);
if (!links.resolvedType) {
links.resolvedType = getStringLiteralTypeForText(node.text);
links.resolvedType = getStringLiteralTypeForText(unescapeIdentifier(node.text));
}
return links.resolvedType;
}
@@ -5214,6 +5216,8 @@ namespace ts {
return undefinedType;
case SyntaxKind.NullKeyword:
return nullType;
case SyntaxKind.NeverKeyword:
return neverType;
case SyntaxKind.ThisType:
case SyntaxKind.ThisKeyword:
return getTypeFromThisTypeNode(node);
@@ -5859,28 +5863,28 @@ namespace ts {
return isIdenticalTo(source, target);
}
if (target.flags & TypeFlags.Any) return Ternary.True;
if (source.flags & TypeFlags.Undefined) {
if (!strictNullChecks || target.flags & (TypeFlags.Undefined | TypeFlags.Void) || source === emptyArrayElementType) return Ternary.True;
}
if (source.flags & TypeFlags.Null) {
if (!strictNullChecks || target.flags & TypeFlags.Null) return Ternary.True;
}
if (source.flags & TypeFlags.Enum && target === numberType) return Ternary.True;
if (source.flags & TypeFlags.Enum && target.flags & TypeFlags.Enum) {
if (result = enumRelatedTo(source, target, reportErrors)) {
return result;
if (!(target.flags & TypeFlags.Never)) {
if (target.flags & TypeFlags.Any) return Ternary.True;
if (source.flags & TypeFlags.Undefined) {
if (!strictNullChecks || target.flags & (TypeFlags.Undefined | TypeFlags.Void) || source === emptyArrayElementType) return Ternary.True;
}
if (source.flags & TypeFlags.Null) {
if (!strictNullChecks || target.flags & TypeFlags.Null) return Ternary.True;
}
if (source.flags & TypeFlags.Enum && target === numberType) return Ternary.True;
if (source.flags & TypeFlags.Enum && target.flags & TypeFlags.Enum) {
if (result = enumRelatedTo(source, target, reportErrors)) {
return result;
}
}
if (source.flags & TypeFlags.StringLiteral && target === stringType) return Ternary.True;
if (relation === assignableRelation || relation === comparableRelation) {
if (source.flags & (TypeFlags.Any | TypeFlags.Never)) return Ternary.True;
if (source === numberType && target.flags & TypeFlags.Enum) return Ternary.True;
}
if (source.flags & TypeFlags.Boolean && target.flags & TypeFlags.Boolean) {
return Ternary.True;
}
}
if (source.flags & TypeFlags.StringLiteral && target === stringType) return Ternary.True;
if (relation === assignableRelation || relation === comparableRelation) {
if (isTypeAny(source)) return Ternary.True;
if (source === numberType && target.flags & TypeFlags.Enum) return Ternary.True;
}
if (source.flags & TypeFlags.Boolean && target.flags & TypeFlags.Boolean) {
return Ternary.True;
}
if (source.flags & TypeFlags.FreshObjectLiteral) {
@@ -7485,7 +7489,7 @@ namespace ts {
function getTypeWithFacts(type: Type, include: TypeFacts) {
if (!(type.flags & TypeFlags.Union)) {
return getTypeFacts(type) & include ? type : nothingType;
return getTypeFacts(type) & include ? type : neverType;
}
let firstType: Type;
let types: Type[];
@@ -7502,7 +7506,7 @@ namespace ts {
}
}
}
return firstType ? types ? getUnionType(types, /*noSubtypeReduction*/ true) : firstType : nothingType;
return firstType ? types ? getUnionType(types, /*noSubtypeReduction*/ true) : firstType : neverType;
}
function getTypeWithDefault(type: Type, defaultExpression: Expression) {
@@ -7614,15 +7618,16 @@ namespace ts {
getInitialTypeOfBindingElement(<BindingElement>node);
}
function getFlowTypeOfReference(reference: Node, declaredType: Type, initialType: Type) {
function getFlowTypeOfReference(reference: Node, declaredType: Type, assumeInitialized: boolean) {
let key: string;
if (!reference.flowNode || declaredType === initialType && !(declaredType.flags & TypeFlags.Narrowable)) {
if (!reference.flowNode || assumeInitialized && !(declaredType.flags & TypeFlags.Narrowable)) {
return declaredType;
}
const initialType = assumeInitialized ? declaredType : addNullableKind(declaredType, TypeFlags.Undefined);
const visitedFlowStart = visitedFlowCount;
const result = getTypeAtFlowNode(reference.flowNode);
visitedFlowCount = visitedFlowStart;
if (reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(result, TypeFacts.NEUndefinedOrNull) === nothingType) {
if (reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(result, TypeFacts.NEUndefinedOrNull) === neverType) {
return declaredType;
}
return result;
@@ -7710,7 +7715,7 @@ namespace ts {
function getTypeAtFlowCondition(flow: FlowCondition) {
let type = getTypeAtFlowNode(flow.antecedent);
if (type !== nothingType) {
if (type !== neverType) {
// If we have an antecedent type (meaning we're reachable in some way), we first
// attempt to narrow the antecedent type. If that produces the nothing type, then
// we take the type guard as an indication that control could reach here in a
@@ -7720,7 +7725,7 @@ namespace ts {
// narrow that.
const assumeTrue = (flow.flags & FlowFlags.TrueCondition) !== 0;
type = narrowType(type, flow.expression, assumeTrue);
if (type === nothingType) {
if (type === neverType) {
type = narrowType(declaredType, flow.expression, assumeTrue);
}
}
@@ -7942,7 +7947,7 @@ namespace ts {
const targetType = type.flags & TypeFlags.TypeParameter ? getApparentType(type) : type;
return isTypeAssignableTo(candidate, targetType) ? candidate :
isTypeAssignableTo(type, candidate) ? type :
nothingType;
neverType;
}
function narrowTypeByTypePredicate(type: Type, callExpression: CallExpression, assumeTrue: boolean): Type {
@@ -8092,11 +8097,11 @@ namespace ts {
return type;
}
const declaration = localOrExportSymbol.valueDeclaration;
const defaultsToDeclaredType = !strictNullChecks || type.flags & TypeFlags.Any || !declaration ||
const assumeInitialized = !strictNullChecks || (type.flags & TypeFlags.Any) !== 0 || !declaration ||
getRootDeclaration(declaration).kind === SyntaxKind.Parameter || isInAmbientContext(declaration) ||
getContainingFunctionOrModule(declaration) !== getContainingFunctionOrModule(node);
const flowType = getFlowTypeOfReference(node, type, defaultsToDeclaredType ? type : addNullableKind(type, TypeFlags.Undefined));
if (strictNullChecks && !(type.flags & TypeFlags.Any) && !(getNullableKind(type) & TypeFlags.Undefined) && getNullableKind(flowType) & TypeFlags.Undefined) {
const flowType = getFlowTypeOfReference(node, type, assumeInitialized);
if (!assumeInitialized && !(getNullableKind(type) & TypeFlags.Undefined) && getNullableKind(flowType) & TypeFlags.Undefined) {
error(node, Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol));
// Return the declared type to reduce follow-on errors
return type;
@@ -8344,7 +8349,7 @@ namespace ts {
if (isClassLike(container.parent)) {
const symbol = getSymbolOfNode(container.parent);
const type = container.flags & NodeFlags.Static ? getTypeOfSymbol(symbol) : (<InterfaceType>getDeclaredTypeOfSymbol(symbol)).thisType;
return getFlowTypeOfReference(node, type, type);
return getFlowTypeOfReference(node, type, /*assumeInitialized*/ true);
}
if (isInJavaScriptFile(node)) {
@@ -9919,7 +9924,8 @@ namespace ts {
}
const propType = getTypeOfSymbol(prop);
if (node.kind !== SyntaxKind.PropertyAccessExpression || !(prop.flags & (SymbolFlags.Variable | SymbolFlags.Property | SymbolFlags.Accessor)) || isAssignmentTarget(node)) {
if (node.kind !== SyntaxKind.PropertyAccessExpression || isAssignmentTarget(node) ||
!(propType.flags & TypeFlags.Union) && !(prop.flags & (SymbolFlags.Variable | SymbolFlags.Property | SymbolFlags.Accessor))) {
return propType;
}
const leftmostNode = getLeftmostIdentifierOrThis(node);
@@ -9936,7 +9942,7 @@ namespace ts {
return propType;
}
}
return getFlowTypeOfReference(node, propType, propType);
return getFlowTypeOfReference(node, propType, /*assumeInitialized*/ true);
}
function isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName, propertyName: string): boolean {
@@ -11455,6 +11461,12 @@ namespace ts {
const links = getSymbolLinks(parameter);
if (!links.type) {
links.type = instantiateType(contextualType, mapper);
// if inference didn't come up with anything but {}, fall back to the binding pattern if present.
if (links.type === emptyObjectType &&
(parameter.valueDeclaration.name.kind === SyntaxKind.ObjectBindingPattern ||
parameter.valueDeclaration.name.kind === SyntaxKind.ArrayBindingPattern)) {
links.type = getTypeFromBindingPattern(<BindingPattern>parameter.valueDeclaration.name);
}
assignBindingElementTypes(<ParameterDeclaration>parameter.valueDeclaration);
}
else if (isInferentialContext(mapper)) {
@@ -11547,6 +11559,9 @@ namespace ts {
else {
const hasImplicitReturn = !!(func.flags & NodeFlags.HasImplicitReturn);
types = checkAndAggregateReturnExpressionTypes(<Block>func.body, contextualMapper, isAsync, hasImplicitReturn);
if (!types) {
return neverType;
}
if (types.length === 0) {
if (isAsync) {
// For an async function, the return type will not be void, but rather a Promise for void.
@@ -11555,12 +11570,9 @@ namespace ts {
error(func, Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type);
return unknownType;
}
return promiseType;
}
else {
return voidType;
}
return voidType;
}
}
// When yield/return statements are contextually typed we allow the return type to be a union type.
@@ -11640,7 +11652,7 @@ namespace ts {
// the native Promise<T> type by the caller.
type = checkAwaitedType(type, body.parent, Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member);
}
if (!contains(aggregatedTypes, type)) {
if (type !== neverType && !contains(aggregatedTypes, type)) {
aggregatedTypes.push(type);
}
}
@@ -11648,6 +11660,9 @@ namespace ts {
hasOmittedExpressions = true;
}
});
if (aggregatedTypes.length === 0 && !hasOmittedExpressions && !hasImplicitReturn) {
return undefined;
}
if (strictNullChecks && aggregatedTypes.length && (hasOmittedExpressions || hasImplicitReturn)) {
if (!contains(aggregatedTypes, undefinedType)) {
aggregatedTypes.push(undefinedType);
@@ -11683,7 +11698,10 @@ namespace ts {
const hasExplicitReturn = func.flags & NodeFlags.HasExplicitReturn;
if (returnType && !hasExplicitReturn) {
if (returnType === neverType) {
error(func.type, Diagnostics.A_function_returning_never_cannot_have_a_reachable_end_point);
}
else if (returnType && !hasExplicitReturn) {
// minimal check: function has syntactic return type annotation and no explicit return statements in the body
// this function does not conform to the specification.
// NOTE: having returnType !== undefined is a precondition for entering this branch so func.type will always be present
@@ -13394,7 +13412,7 @@ namespace ts {
// Abstract methods can't have an implementation -- in particular, they don't need one.
if (!isExportSymbolInsideModule && lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body &&
!(lastSeenNonAmbientDeclaration.flags & NodeFlags.Abstract)) {
!(lastSeenNonAmbientDeclaration.flags & NodeFlags.Abstract) && !lastSeenNonAmbientDeclaration.questionToken) {
reportImplementationExpectedError(lastSeenNonAmbientDeclaration);
}
@@ -14747,7 +14765,7 @@ namespace ts {
arrayType = getUnionType(filter((arrayOrStringType as UnionType).types, t => !(t.flags & TypeFlags.StringLike)));
}
else if (arrayOrStringType.flags & TypeFlags.StringLike) {
arrayType = nothingType;
arrayType = neverType;
}
const hasStringConstituent = arrayOrStringType !== arrayType;
let reportedError = false;
@@ -14759,7 +14777,7 @@ namespace ts {
// Now that we've removed all the StringLike types, if no constituents remain, then the entire
// arrayOrStringType was a string.
if (arrayType === nothingType) {
if (arrayType === neverType) {
return stringType;
}
}
@@ -14820,7 +14838,7 @@ namespace ts {
if (func) {
const signature = getSignatureFromDeclaration(func);
const returnType = getReturnTypeOfSignature(signature);
if (strictNullChecks || node.expression) {
if (strictNullChecks || node.expression || returnType === neverType) {
const exprType = node.expression ? checkExpressionCached(node.expression) : undefinedType;
if (func.asteriskToken) {
@@ -18284,7 +18302,7 @@ namespace ts {
}
if (node.parent.kind === SyntaxKind.ObjectLiteralExpression) {
if (checkGrammarForInvalidQuestionMark(node, node.questionToken, Diagnostics.A_class_member_cannot_be_declared_optional)) {
if (checkGrammarForInvalidQuestionMark(node, node.questionToken, Diagnostics.An_object_member_cannot_be_declared_optional)) {
return true;
}
else if (node.body === undefined) {
@@ -18293,9 +18311,6 @@ namespace ts {
}
if (isClassLike(node.parent)) {
if (checkGrammarForInvalidQuestionMark(node, node.questionToken, Diagnostics.A_class_member_cannot_be_declared_optional)) {
return true;
}
// Technically, computed properties in ambient contexts is disallowed
// for property declarations and accessors too, not just methods.
// However, property declarations disallow computed names in general,
@@ -18517,8 +18532,7 @@ namespace ts {
function checkGrammarProperty(node: PropertyDeclaration) {
if (isClassLike(node.parent)) {
if (checkGrammarForInvalidQuestionMark(node, node.questionToken, Diagnostics.A_class_member_cannot_be_declared_optional) ||
checkGrammarForNonSymbolComputedProperty(node.name, Diagnostics.A_computed_property_name_in_a_class_property_declaration_must_directly_refer_to_a_built_in_symbol)) {
if (checkGrammarForNonSymbolComputedProperty(node.name, Diagnostics.A_computed_property_name_in_a_class_property_declaration_must_directly_refer_to_a_built_in_symbol)) {
return true;
}
}
+2 -1
View File
@@ -395,6 +395,7 @@ namespace ts {
case SyntaxKind.VoidKeyword:
case SyntaxKind.UndefinedKeyword:
case SyntaxKind.NullKeyword:
case SyntaxKind.NeverKeyword:
case SyntaxKind.ThisType:
case SyntaxKind.StringLiteralType:
return writeTextOfNode(currentText, type);
@@ -1129,7 +1130,7 @@ namespace ts {
// what we want, namely the name expression enclosed in brackets.
writeTextOfNode(currentText, node.name);
// If optional property emit ?
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) && hasQuestionToken(node)) {
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature || node.kind === SyntaxKind.Parameter) && hasQuestionToken(node)) {
write("?");
}
if ((node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) && node.parent.kind === SyntaxKind.TypeLiteral) {
+4 -4
View File
@@ -315,10 +315,6 @@
"category": "Error",
"code": 1110
},
"A class member cannot be declared optional.": {
"category": "Error",
"code": 1112
},
"A 'default' clause cannot appear more than once in a 'switch' statement.": {
"category": "Error",
"code": 1113
@@ -1751,6 +1747,10 @@
"category": "Error",
"code": 2533
},
"A function returning 'never' cannot have a reachable end point.": {
"category": "Error",
"code": 2534
},
"JSX element attributes type '{0}' may not be a union type.": {
"category": "Error",
"code": 2600
+2
View File
@@ -2368,6 +2368,7 @@ namespace ts {
case SyntaxKind.BooleanKeyword:
case SyntaxKind.SymbolKeyword:
case SyntaxKind.UndefinedKeyword:
case SyntaxKind.NeverKeyword:
// If these are followed by a dot, then parse these out as a dotted type reference instead.
const node = tryParse(parseKeywordAndNoDot);
return node || parseTypeReference();
@@ -2410,6 +2411,7 @@ namespace ts {
case SyntaxKind.NullKeyword:
case SyntaxKind.ThisKeyword:
case SyntaxKind.TypeOfKeyword:
case SyntaxKind.NeverKeyword:
case SyntaxKind.OpenBraceToken:
case SyntaxKind.OpenBracketToken:
case SyntaxKind.LessThanToken:
+1
View File
@@ -91,6 +91,7 @@ namespace ts {
"let": SyntaxKind.LetKeyword,
"module": SyntaxKind.ModuleKeyword,
"namespace": SyntaxKind.NamespaceKeyword,
"never": SyntaxKind.NeverKeyword,
"new": SyntaxKind.NewKeyword,
"null": SyntaxKind.NullKeyword,
"number": SyntaxKind.NumberKeyword,
+4 -1
View File
@@ -164,6 +164,7 @@ namespace ts {
IsKeyword,
ModuleKeyword,
NamespaceKeyword,
NeverKeyword,
ReadonlyKeyword,
RequireKeyword,
NumberKeyword,
@@ -1772,6 +1773,7 @@ namespace ts {
getIndexTypeOfType(type: Type, kind: IndexKind): Type;
getBaseTypes(type: InterfaceType): ObjectType[];
getReturnTypeOfSignature(signature: Signature): Type;
getNonNullableType(type: Type): Type;
getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[];
getSymbolAtLocation(node: Node): Symbol;
@@ -2170,11 +2172,12 @@ namespace ts {
ESSymbol = 0x01000000, // Type of symbol primitive introduced in ES6
ThisType = 0x02000000, // This type
ObjectLiteralPatternWithComputedProperties = 0x04000000, // Object literal type implied by binding pattern has computed properties
Never = 0x08000000, // Never type
/* @internal */
Nullable = Undefined | Null,
/* @internal */
Intrinsic = Any | String | Number | Boolean | ESSymbol | Void | Undefined | Null,
Intrinsic = Any | String | Number | Boolean | ESSymbol | Void | Undefined | Null | Never,
/* @internal */
Primitive = String | Number | Boolean | ESSymbol | Void | Undefined | Null | StringLiteral | Enum,
StringLike = String | StringLiteral,
+1
View File
@@ -613,6 +613,7 @@ namespace ts {
case SyntaxKind.BooleanKeyword:
case SyntaxKind.SymbolKeyword:
case SyntaxKind.UndefinedKeyword:
case SyntaxKind.NeverKeyword:
return true;
case SyntaxKind.VoidKeyword:
return node.parent.kind !== SyntaxKind.VoidExpression;
+32 -14
View File
@@ -1968,12 +1968,12 @@ namespace FourSlash {
}
}
public verifyGetScriptLexicalStructureListCount(expected: number) {
public verifyNavigationBarCount(expected: number) {
const items = this.languageService.getNavigationBarItems(this.activeFile.fileName);
const actual = this.getNavigationBarItemsCount(items);
if (expected !== actual) {
this.raiseError(`verifyGetScriptLexicalStructureListCount failed - found: ${actual} navigation items, expected: ${expected}.`);
this.raiseError(`verifyNavigationBarCount failed - found: ${actual} navigation items, expected: ${expected}.`);
}
}
@@ -1989,19 +1989,19 @@ namespace FourSlash {
return result;
}
public verifyGetScriptLexicalStructureListContains(name: string, kind: string) {
public verifyNavigationBarContains(name: string, kind: string) {
const items = this.languageService.getNavigationBarItems(this.activeFile.fileName);
if (!items || items.length === 0) {
this.raiseError("verifyGetScriptLexicalStructureListContains failed - found 0 navigation items, expected at least one.");
this.raiseError("verifyNavigationBarContains failed - found 0 navigation items, expected at least one.");
}
if (this.navigationBarItemsContains(items, name, kind)) {
return;
}
const missingItem = { name: name, kind: kind };
this.raiseError(`verifyGetScriptLexicalStructureListContains failed - could not find the item: ${JSON.stringify(missingItem, undefined, 2)} in the returned list: (${JSON.stringify(items, undefined, 2)})`);
const missingItem = { name, kind };
this.raiseError(`verifyNavigationBarContains failed - could not find the item: ${JSON.stringify(missingItem, undefined, 2)} in the returned list: (${JSON.stringify(items, undefined, 2)})`);
}
private navigationBarItemsContains(items: ts.NavigationBarItem[], name: string, kind: string) {
@@ -2021,6 +2021,20 @@ namespace FourSlash {
return false;
}
public verifyNavigationBarChildItem(parent: string, name: string, kind: string) {
const items = this.languageService.getNavigationBarItems(this.activeFile.fileName);
for (let i = 0; i < items.length; i++) {
const item = items[i];
if (item.text === parent) {
if (this.navigationBarItemsContains(item.childItems, name, kind))
return;
const missingItem = { name, kind };
this.raiseError(`verifyNavigationBarChildItem failed - could not find the item: ${JSON.stringify(missingItem)} in the children list: (${JSON.stringify(item.childItems, undefined, 2)})`);
}
}
}
public printNavigationItems(searchValue: string) {
const items = this.languageService.getNavigateToItems(searchValue);
const length = items && items.length;
@@ -2033,11 +2047,11 @@ namespace FourSlash {
}
}
public printScriptLexicalStructureItems() {
public printNavigationBar() {
const items = this.languageService.getNavigationBarItems(this.activeFile.fileName);
const length = items && items.length;
Harness.IO.log(`NavigationItems list (${length} items)`);
Harness.IO.log(`Navigation bar (${length} items)`);
for (let i = 0; i < length; i++) {
const item = items[i];
@@ -3029,19 +3043,23 @@ namespace FourSlashInterface {
this.DocCommentTemplate(/*expectedText*/ undefined, /*expectedOffset*/ undefined, /*empty*/ true);
}
public getScriptLexicalStructureListCount(count: number) {
this.state.verifyGetScriptLexicalStructureListCount(count);
public navigationBarCount(count: number) {
this.state.verifyNavigationBarCount(count);
}
// TODO: figure out what to do with the unused arguments.
public getScriptLexicalStructureListContains(
public navigationBarContains(
name: string,
kind: string,
fileName?: string,
parentName?: string,
isAdditionalSpan?: boolean,
markerPosition?: number) {
this.state.verifyGetScriptLexicalStructureListContains(name, kind);
this.state.verifyNavigationBarContains(name, kind);
}
public navigationBarChildItem(parent: string, name: string, kind: string) {
this.state.verifyNavigationBarChildItem(parent, name, kind);
}
public navigationItemsListCount(count: number, searchValue: string, matchKind?: string) {
@@ -3234,8 +3252,8 @@ namespace FourSlashInterface {
this.state.printNavigationItems(searchValue);
}
public printScriptLexicalStructureItems() {
this.state.printScriptLexicalStructureItems();
public printNavigationBar() {
this.state.printNavigationBar();
}
public printReferences() {
+11 -11
View File
@@ -24,7 +24,7 @@ namespace ts.BreakpointResolver {
// token on same line if trailing trivia (comments or white spaces on same line) part of the last token on that line
tokenAtLocation = findPrecedingToken(tokenAtLocation.pos, sourceFile);
// Its a blank line
// It's a blank line
if (!tokenAtLocation || sourceFile.getLineAndCharacterOfPosition(tokenAtLocation.getEnd()).line !== lineOfPosition) {
return undefined;
}
@@ -312,7 +312,7 @@ namespace ts.BreakpointResolver {
case SyntaxKind.BinaryExpression:
if ((<BinaryExpression>node.parent).operatorToken.kind === SyntaxKind.CommaToken) {
// if this is comma expression, the breakpoint is possible in this expression
// If this is a comma expression, the breakpoint is possible in this expression
return textSpan(node);
}
break;
@@ -387,7 +387,7 @@ namespace ts.BreakpointResolver {
return spanInNode(variableDeclaration.parent.parent);
}
// If this is a destructuring pattern set breakpoint in binding pattern
// If this is a destructuring pattern, set breakpoint in binding pattern
if (isBindingPattern(variableDeclaration.name)) {
return spanInBindingPattern(<BindingPattern>variableDeclaration.name);
}
@@ -402,9 +402,9 @@ namespace ts.BreakpointResolver {
let declarations = variableDeclaration.parent.declarations;
if (declarations && declarations[0] !== variableDeclaration) {
// If we cant set breakpoint on this declaration, set it on previous one
// If we cannot set breakpoint on this declaration, set it on previous one
// Because the variable declaration may be binding pattern and
// we would like to set breakpoint in last binding element if thats the case,
// we would like to set breakpoint in last binding element if that's the case,
// use preceding token instead
return spanInNode(findPrecedingToken(variableDeclaration.pos, sourceFile, variableDeclaration.parent));
}
@@ -418,7 +418,7 @@ namespace ts.BreakpointResolver {
function spanInParameterDeclaration(parameter: ParameterDeclaration): TextSpan {
if (isBindingPattern(parameter.name)) {
// set breakpoint in binding pattern
// Set breakpoint in binding pattern
return spanInBindingPattern(<BindingPattern>parameter.name);
}
else if (canHaveSpanInParameterDeclaration(parameter)) {
@@ -492,7 +492,7 @@ namespace ts.BreakpointResolver {
function spanInInitializerOfForLike(forLikeStatement: ForStatement | ForOfStatement | ForInStatement): TextSpan {
if (forLikeStatement.initializer.kind === SyntaxKind.VariableDeclarationList) {
// declaration list, set breakpoint in first declaration
// Declaration list - set breakpoint in first declaration
let variableDeclarationList = <VariableDeclarationList>forLikeStatement.initializer;
if (variableDeclarationList.declarations.length > 0) {
return spanInNode(variableDeclarationList.declarations[0]);
@@ -578,7 +578,7 @@ namespace ts.BreakpointResolver {
function spanInCloseBraceToken(node: Node): TextSpan {
switch (node.parent.kind) {
case SyntaxKind.ModuleBlock:
// If this is not instantiated module block no bp span
// If this is not an instantiated module block, no bp span
if (getModuleInstanceState(node.parent.parent) !== ModuleInstanceState.Instantiated) {
return undefined;
}
@@ -593,7 +593,7 @@ namespace ts.BreakpointResolver {
// Span on close brace token
return textSpan(node);
}
// fall through.
// fall through
case SyntaxKind.CatchClause:
return spanInNode(lastOrUndefined((<Block>node.parent).statements));
@@ -714,7 +714,7 @@ namespace ts.BreakpointResolver {
function spanInOfKeyword(node: Node): TextSpan {
if (node.parent.kind === SyntaxKind.ForOfStatement) {
// set using next token
// Set using next token
return spanInNextNode(node);
}
@@ -723,4 +723,4 @@ namespace ts.BreakpointResolver {
}
}
}
}
}
+36 -30
View File
@@ -20,13 +20,13 @@ namespace ts.formatting {
Unknown = -1
}
/*
/*
* Indentation for the scope that can be dynamically recomputed.
* i.e
* i.e
* while(true)
* { let x;
* }
* Normally indentation is applied only to the first token in line so at glance 'var' should not be touched.
* Normally indentation is applied only to the first token in line so at glance 'var' should not be touched.
* However if some format rule adds new line between '}' and 'var' 'var' will become
* the first token in line so it should be indented
*/
@@ -48,15 +48,15 @@ namespace ts.formatting {
* foo(bar({
* $
* }))
* Both 'foo', 'bar' introduce new indentation with delta = 4, but total indentation in $ is not 8.
* Both 'foo', 'bar' introduce new indentation with delta = 4, but total indentation in $ is not 8.
* foo: { indentation: 0, delta: 4 }
* bar: { indentation: foo.indentation + foo.delta = 4, delta: 4} however 'foo' and 'bar' are on the same line
* so bar inherits indentation from foo and bar.delta will be 4
*
*
*/
getDelta(child: TextRangeWithKind): number;
/**
* Formatter calls this function when rule adds or deletes new lines from the text
* Formatter calls this function when rule adds or deletes new lines from the text
* so indentation scope can adjust values of indentation and delta.
*/
recomputeIndentation(lineAddedByFormatting: boolean): void;
@@ -130,9 +130,9 @@ namespace ts.formatting {
function findOutermostParent(position: number, expectedTokenKind: SyntaxKind, sourceFile: SourceFile): Node {
let precedingToken = findPrecedingToken(position, sourceFile);
// when it is claimed that trigger character was typed at given position
// when it is claimed that trigger character was typed at given position
// we verify that there is a token with a matching kind whose end is equal to position (because the character was just typed).
// If this condition is not hold - then trigger character was typed in some other context,
// If this condition is not hold - then trigger character was typed in some other context,
// i.e.in comment and thus should not trigger autoformatting
if (!precedingToken ||
precedingToken.kind !== expectedTokenKind ||
@@ -142,12 +142,12 @@ namespace ts.formatting {
// walk up and search for the parent node that ends at the same position with precedingToken.
// for cases like this
//
//
// let x = 1;
// while (true) {
// }
// }
// after typing close curly in while statement we want to reformat just the while statement.
// However if we just walk upwards searching for the parent that has the same end value -
// However if we just walk upwards searching for the parent that has the same end value -
// we'll end up with the whole source file. isListElement allows to stop on the list element level
let current = precedingToken;
while (current &&
@@ -223,7 +223,7 @@ namespace ts.formatting {
// 'index' tracks the index of the most recent error that was checked.
while (true) {
if (index >= sorted.length) {
// all errors in the range were already checked -> no error in specified range
// all errors in the range were already checked -> no error in specified range
return false;
}
@@ -249,7 +249,7 @@ namespace ts.formatting {
/**
* Start of the original range might fall inside the comment - scanner will not yield appropriate results
* This function will look for token that is located before the start of target range
* This function will look for token that is located before the start of target range
* and return its end as start position for the scanner.
*/
function getScanStartPosition(enclosingNode: Node, originalRange: TextRange, sourceFile: SourceFile): number {
@@ -274,7 +274,7 @@ namespace ts.formatting {
}
/*
* For cases like
* For cases like
* if (a ||
* b ||$
* c) {...}
@@ -284,8 +284,8 @@ namespace ts.formatting {
* Initial indentation for this node will be 0.
* Binary expressions don't introduce new indentation scopes, however it is possible
* that some parent node on the same line does - like if statement in this case.
* Note that we are considering parents only from the same line with initial node -
* if parent is on the different line - its delta was already contributed
* Note that we are considering parents only from the same line with initial node -
* if parent is on the different line - its delta was already contributed
* to the initial indentation.
*/
function getOwnOrInheritedDelta(n: Node, options: FormatCodeOptions, sourceFile: SourceFile): number {
@@ -364,10 +364,10 @@ namespace ts.formatting {
// local functions
/** Tries to compute the indentation for a list element.
* If list element is not in range then
* function will pick its actual indentation
* If list element is not in range then
* function will pick its actual indentation
* so it can be pushed downstream as inherited indentation.
* If list element is in the range - its indentation will be equal
* If list element is in the range - its indentation will be equal
* to inherited indentation from its predecessors.
*/
function tryComputeIndentationForListItem(startPos: number,
@@ -378,7 +378,7 @@ namespace ts.formatting {
if (rangeOverlapsWithStartEnd(range, startPos, endPos) ||
rangeContainsStartEnd(range, startPos, endPos) /* Not to miss zero-range nodes e.g. JsxText */) {
if (inheritedIndentation !== Constants.Unknown) {
return inheritedIndentation;
}
@@ -529,12 +529,12 @@ namespace ts.formatting {
// a useful observations when tracking context node
// /
// [a]
// / | \
// / | \
// [b] [c] [d]
// node 'a' is a context node for nodes 'b', 'c', 'd'
// node 'a' is a context node for nodes 'b', 'c', 'd'
// except for the leftmost leaf token in [b] - in this case context node ('e') is located somewhere above 'a'
// this rule can be applied recursively to child nodes of 'a'.
//
//
// context node is set to parent node value after processing every child node
// context node is set to parent of the token after processing every token
@@ -567,7 +567,8 @@ namespace ts.formatting {
parentDynamicIndentation: DynamicIndentation,
parentStartLine: number,
undecoratedParentStartLine: number,
isListItem: boolean): number {
isListItem: boolean,
isFirstListItem?: boolean): number {
let childStartPos = child.getStart(sourceFile);
@@ -626,6 +627,10 @@ namespace ts.formatting {
childContextNode = node;
if (isFirstListItem && parent.kind === SyntaxKind.ArrayLiteralExpression && inheritedIndentation === Constants.Unknown) {
inheritedIndentation = childIndentation.indentation;
}
return inheritedIndentation;
}
@@ -665,8 +670,9 @@ namespace ts.formatting {
}
let inheritedIndentation = Constants.Unknown;
for (let child of nodes) {
inheritedIndentation = processChildNode(child, inheritedIndentation, node, listDynamicIndentation, startLine, startLine, /*isListElement*/ true)
for (let i = 0; i < nodes.length; i++) {
const child = nodes[i];
inheritedIndentation = processChildNode(child, inheritedIndentation, node, listDynamicIndentation, startLine, startLine, /*isListElement*/ true, /*isFirstListItem*/ i === 0);
}
if (listEndToken !== SyntaxKind.Unknown) {
@@ -674,7 +680,7 @@ namespace ts.formatting {
let tokenInfo = formattingScanner.readTokenInfo(parent);
// consume the list end token only if it is still belong to the parent
// there might be the case when current token matches end token but does not considered as one
// function (x: function) <--
// function (x: function) <--
// without this check close paren will be interpreted as list end token for function expression which is wrong
if (tokenInfo.token.kind === listEndToken && rangeContainsRange(parent, tokenInfo.token)) {
// consume list end token
@@ -733,7 +739,7 @@ namespace ts.formatting {
let commentIndentation = dynamicIndentation.getIndentationForComment(currentTokenInfo.token.kind, tokenIndentation, container);
for (let triviaItem of currentTokenInfo.leadingTrivia) {
const triviaInRange = rangeContainsRange(originalRange, triviaItem);
const triviaInRange = rangeContainsRange(originalRange, triviaItem);
switch (triviaItem.kind) {
case SyntaxKind.MultiLineCommentTrivia:
if (triviaInRange) {
@@ -826,7 +832,7 @@ namespace ts.formatting {
if (rule.Operation.Action & (RuleAction.Space | RuleAction.Delete) && currentStartLine !== previousStartLine) {
lineAdded = false;
// Handle the case where the next line is moved to be the end of this line.
// Handle the case where the next line is moved to be the end of this line.
// In this case we don't indent the next line in the next pass.
if (currentParent.getStart(sourceFile) === currentItem.pos) {
dynamicIndentation.recomputeIndentation(/*lineAdded*/ false);
@@ -834,7 +840,7 @@ namespace ts.formatting {
}
else if (rule.Operation.Action & RuleAction.NewLine && currentStartLine === previousStartLine) {
lineAdded = true;
// Handle the case where token2 is moved to the new line.
// Handle the case where token2 is moved to the new line.
// In this case we indent token2 in the next pass but we set
// sameLineIndent flag to notify the indenter that the indentation is within the line.
if (currentParent.getStart(sourceFile) === currentItem.pos) {
+49 -36
View File
@@ -46,7 +46,7 @@ namespace ts.NavigationBar {
}
function getChildNodes(nodes: Node[]): Node[] {
let childNodes: Node[] = [];
const childNodes: Node[] = [];
function visit(node: Node) {
switch (node.kind) {
@@ -109,7 +109,7 @@ namespace ts.NavigationBar {
}
}
//for (let i = 0, n = nodes.length; i < n; i++) {
// for (let i = 0, n = nodes.length; i < n; i++) {
// let node = nodes[i];
// if (node.kind === SyntaxKind.ClassDeclaration ||
@@ -123,13 +123,13 @@ namespace ts.NavigationBar {
// else if (node.kind === SyntaxKind.VariableStatement) {
// childNodes.push.apply(childNodes, (<VariableStatement>node).declarations);
// }
//}
// }
forEach(nodes, visit);
return sortNodes(childNodes);
}
function getTopLevelNodes(node: SourceFile): Node[] {
let topLevelNodes: Node[] = [];
const topLevelNodes: Node[] = [];
topLevelNodes.push(node);
addTopLevelNodes(node.statements, topLevelNodes);
@@ -157,7 +157,7 @@ namespace ts.NavigationBar {
function addTopLevelNodes(nodes: Node[], topLevelNodes: Node[]): void {
nodes = sortNodes(nodes);
for (let node of nodes) {
for (const node of nodes) {
switch (node.kind) {
case SyntaxKind.ClassDeclaration:
topLevelNodes.push(node);
@@ -176,6 +176,7 @@ namespace ts.NavigationBar {
break;
case SyntaxKind.EnumDeclaration:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.TypeAliasDeclaration:
topLevelNodes.push(node);
break;
@@ -197,7 +198,7 @@ namespace ts.NavigationBar {
}
function hasNamedFunctionDeclarations(nodes: NodeArray<Statement>): boolean {
for (let s of nodes) {
for (const s of nodes) {
if (s.kind === SyntaxKind.FunctionDeclaration && !isEmpty((<FunctionDeclaration>s).name.text)) {
return true;
}
@@ -237,17 +238,17 @@ namespace ts.NavigationBar {
}
function getItemsWorker(nodes: Node[], createItem: (n: Node) => ts.NavigationBarItem): ts.NavigationBarItem[] {
let items: ts.NavigationBarItem[] = [];
const items: ts.NavigationBarItem[] = [];
let keyToItem: Map<NavigationBarItem> = {};
const keyToItem: Map<NavigationBarItem> = {};
for (let child of nodes) {
let item = createItem(child);
for (const child of nodes) {
const item = createItem(child);
if (item !== undefined) {
if (item.text.length > 0) {
let key = item.text + "-" + item.kind + "-" + item.indent;
const key = item.text + "-" + item.kind + "-" + item.indent;
let itemWithSameName = keyToItem[key];
const itemWithSameName = keyToItem[key];
if (itemWithSameName) {
// We had an item with the same name. Merge these items together.
merge(itemWithSameName, item);
@@ -274,8 +275,8 @@ namespace ts.NavigationBar {
// Next, recursively merge or add any children in the source as appropriate.
outer:
for (let sourceChild of source.childItems) {
for (let targetChild of target.childItems) {
for (const sourceChild of source.childItems) {
for (const targetChild of target.childItems) {
if (targetChild.text === sourceChild.text && targetChild.kind === sourceChild.kind) {
// Found a match. merge them.
merge(targetChild, sourceChild);
@@ -382,7 +383,7 @@ namespace ts.NavigationBar {
return !text || text.trim() === "";
}
function getNavigationBarItem(text: string, kind: string, kindModifiers: string, spans: TextSpan[], childItems: NavigationBarItem[] = [], indent: number = 0): NavigationBarItem {
function getNavigationBarItem(text: string, kind: string, kindModifiers: string, spans: TextSpan[], childItems: NavigationBarItem[] = [], indent = 0): NavigationBarItem {
if (isEmpty(text)) {
return undefined;
}
@@ -422,6 +423,9 @@ namespace ts.NavigationBar {
case SyntaxKind.FunctionDeclaration:
return createFunctionItem(<FunctionDeclaration>node);
case SyntaxKind.TypeAliasDeclaration:
return createTypeAliasItem(<TypeAliasDeclaration>node);
}
return undefined;
@@ -433,7 +437,7 @@ namespace ts.NavigationBar {
}
// Otherwise, we need to aggregate each identifier to build up the qualified name.
let result: string[] = [];
const result: string[] = [];
result.push(moduleDeclaration.name.text);
@@ -447,9 +451,9 @@ namespace ts.NavigationBar {
}
function createModuleItem(node: ModuleDeclaration): NavigationBarItem {
let moduleName = getModuleName(node);
const moduleName = getModuleName(node);
let childItems = getItemsWorker(getChildNodes((<Block>getInnermostModule(node).body).statements), createChildItem);
const childItems = getItemsWorker(getChildNodes((<Block>getInnermostModule(node).body).statements), createChildItem);
return getNavigationBarItem(moduleName,
ts.ScriptElementKind.moduleElement,
@@ -461,9 +465,9 @@ namespace ts.NavigationBar {
function createFunctionItem(node: FunctionDeclaration): ts.NavigationBarItem {
if (node.body && node.body.kind === SyntaxKind.Block) {
let childItems = getItemsWorker(sortNodes((<Block>node.body).statements), createChildItem);
const childItems = getItemsWorker(sortNodes((<Block>node.body).statements), createChildItem);
return getNavigationBarItem(!node.name ? "default": node.name.text,
return getNavigationBarItem(!node.name ? "default" : node.name.text,
ts.ScriptElementKind.functionElement,
getNodeModifiers(node),
[getNodeSpan(node)],
@@ -474,9 +478,18 @@ namespace ts.NavigationBar {
return undefined;
}
function createTypeAliasItem(node: TypeAliasDeclaration): ts.NavigationBarItem {
return getNavigationBarItem(node.name.text,
ts.ScriptElementKind.typeElement,
getNodeModifiers(node),
[getNodeSpan(node)],
[],
getIndent(node));
}
function createMemberFunctionLikeItem(node: MethodDeclaration | ConstructorDeclaration): ts.NavigationBarItem {
if (node.body && node.body.kind === SyntaxKind.Block) {
let childItems = getItemsWorker(sortNodes((<Block>node.body).statements), createChildItem);
const childItems = getItemsWorker(sortNodes((<Block>node.body).statements), createChildItem);
let scriptElementKind: string;
let memberFunctionName: string;
if (node.kind === SyntaxKind.MethodDeclaration) {
@@ -500,16 +513,16 @@ namespace ts.NavigationBar {
}
function createSourceFileItem(node: SourceFile): ts.NavigationBarItem {
let childItems = getItemsWorker(getChildNodes(node.statements), createChildItem);
const childItems = getItemsWorker(getChildNodes(node.statements), createChildItem);
if (childItems === undefined || childItems.length === 0) {
return undefined;
}
hasGlobalNode = true;
let rootName = isExternalModule(node)
const rootName = isExternalModule(node)
? "\"" + escapeString(getBaseFileName(removeFileExtension(normalizePath(node.fileName)))) + "\""
: "<global>"
: "<global>";
return getNavigationBarItem(rootName,
ts.ScriptElementKind.moduleElement,
@@ -522,14 +535,14 @@ namespace ts.NavigationBar {
let childItems: NavigationBarItem[];
if (node.members) {
let constructor = <ConstructorDeclaration>forEach(node.members, member => {
const constructor = <ConstructorDeclaration>forEach(node.members, member => {
return member.kind === SyntaxKind.Constructor && member;
});
// Add the constructor parameters in as children of the class (for property parameters).
// Note that *all non-binding pattern named* parameters will be added to the nodes array, but parameters that
// are not properties will be filtered out later by createChildItem.
let nodes: Node[] = removeDynamicallyNamedProperties(node);
const nodes: Node[] = removeDynamicallyNamedProperties(node);
if (constructor) {
addRange(nodes, filter(constructor.parameters, p => !isBindingPattern(p.name)));
}
@@ -537,7 +550,7 @@ namespace ts.NavigationBar {
childItems = getItemsWorker(sortNodes(nodes), createChildItem);
}
var nodeName = !node.name ? "default" : node.name.text;
const nodeName = !node.name ? "default" : node.name.text;
return getNavigationBarItem(
nodeName,
@@ -549,7 +562,7 @@ namespace ts.NavigationBar {
}
function createEnumItem(node: EnumDeclaration): ts.NavigationBarItem {
let childItems = getItemsWorker(sortNodes(removeComputedProperties(node)), createChildItem);
const childItems = getItemsWorker(sortNodes(removeComputedProperties(node)), createChildItem);
return getNavigationBarItem(
node.name.text,
ts.ScriptElementKind.enumElement,
@@ -560,7 +573,7 @@ namespace ts.NavigationBar {
}
function createInterfaceItem(node: InterfaceDeclaration): ts.NavigationBarItem {
let childItems = getItemsWorker(sortNodes(removeDynamicallyNamedProperties(node)), createChildItem);
const childItems = getItemsWorker(sortNodes(removeDynamicallyNamedProperties(node)), createChildItem);
return getNavigationBarItem(
node.name.text,
ts.ScriptElementKind.interfaceElement,
@@ -578,7 +591,7 @@ namespace ts.NavigationBar {
/**
* Like removeComputedProperties, but retains the properties with well known symbol names
*/
function removeDynamicallyNamedProperties(node: ClassDeclaration | InterfaceDeclaration): Declaration[]{
function removeDynamicallyNamedProperties(node: ClassDeclaration | InterfaceDeclaration): Declaration[] {
return filter<Declaration>(node.members, member => !hasDynamicName(member));
}
@@ -606,11 +619,11 @@ namespace ts.NavigationBar {
const anonClassText = "<class>";
let indent = 0;
let rootName = isExternalModule(sourceFile) ?
const rootName = isExternalModule(sourceFile) ?
"\"" + escapeString(getBaseFileName(removeFileExtension(normalizePath(sourceFile.fileName)))) + "\""
: "<global>";
let sourceFileItem = getNavBarItem(rootName, ScriptElementKind.moduleElement, [getNodeSpan(sourceFile)]);
const sourceFileItem = getNavBarItem(rootName, ScriptElementKind.moduleElement, [getNodeSpan(sourceFile)]);
let topItem = sourceFileItem;
// Walk the whole file, because we want to also find function expressions - which may be in variable initializer,
@@ -643,12 +656,12 @@ namespace ts.NavigationBar {
}
}
function createNavBarItem(node: Node) : NavigationBarItem {
function createNavBarItem(node: Node): NavigationBarItem {
switch (node.kind) {
case SyntaxKind.VariableDeclaration:
// Only add to the navbar if at the top-level of the file
// Note: "const" and "let" are also SyntaxKind.VariableDeclarations
if(node.parent/*VariableDeclarationList*/.parent/*VariableStatement*/
if (node.parent/*VariableDeclarationList*/.parent/*VariableStatement*/
.parent/*SourceFile*/.kind !== SyntaxKind.SourceFile) {
return undefined;
}
@@ -711,7 +724,7 @@ namespace ts.NavigationBar {
function getNavBarItem(text: string, kind: string, spans: TextSpan[], kindModifiers = ScriptElementKindModifier.none): NavigationBarItem {
return {
text, kind, kindModifiers, spans, childItems: [], indent, bolded: false, grayed: false
}
};
}
function getDefineModuleItem(node: Node): NavigationBarItem {
@@ -724,7 +737,7 @@ namespace ts.NavigationBar {
return undefined;
}
const callExpr = node.parent as CallExpression;
if (callExpr.expression.kind !== SyntaxKind.Identifier || callExpr.expression.getText() !== 'define') {
if (callExpr.expression.kind !== SyntaxKind.Identifier || callExpr.expression.getText() !== "define") {
return undefined;
}
+41 -36
View File
@@ -50,6 +50,7 @@ namespace ts {
getStringIndexType(): Type;
getNumberIndexType(): Type;
getBaseTypes(): ObjectType[];
getNonNullableType(): Type;
}
export interface Signature {
@@ -735,6 +736,9 @@ namespace ts {
? this.checker.getBaseTypes(<InterfaceType><Type>this)
: undefined;
}
getNonNullableType(): Type {
return this.checker.getNonNullableType(this);
}
}
class SignatureObject implements Signature {
@@ -904,6 +908,7 @@ namespace ts {
function visit(node: Node): void {
switch (node.kind) {
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.FunctionExpression:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
const functionDeclaration = <FunctionLikeDeclaration>node;
@@ -930,6 +935,7 @@ namespace ts {
break;
case SyntaxKind.ClassDeclaration:
case SyntaxKind.ClassExpression:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.TypeAliasDeclaration:
case SyntaxKind.EnumDeclaration:
@@ -944,22 +950,9 @@ namespace ts {
case SyntaxKind.SetAccessor:
case SyntaxKind.TypeLiteral:
addDeclaration(<Declaration>node);
// fall through
case SyntaxKind.Constructor:
case SyntaxKind.VariableStatement:
case SyntaxKind.VariableDeclarationList:
case SyntaxKind.ObjectBindingPattern:
case SyntaxKind.ArrayBindingPattern:
case SyntaxKind.ModuleBlock:
forEachChild(node, visit);
break;
case SyntaxKind.Block:
if (isFunctionBlock(node)) {
forEachChild(node, visit);
}
break;
case SyntaxKind.Parameter:
// Only consider parameter properties
if (!(node.flags & NodeFlags.ParameterPropertyModifier)) {
@@ -967,11 +960,15 @@ namespace ts {
}
// fall through
case SyntaxKind.VariableDeclaration:
case SyntaxKind.BindingElement:
if (isBindingPattern((<VariableDeclaration>node).name)) {
forEachChild((<VariableDeclaration>node).name, visit);
case SyntaxKind.BindingElement: {
const decl = <VariableDeclaration> node;
if (isBindingPattern(decl.name)) {
forEachChild(decl.name, visit);
break;
}
if (decl.initializer)
visit(decl.initializer);
}
case SyntaxKind.EnumMember:
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
@@ -1008,6 +1005,9 @@ namespace ts {
}
}
break;
default:
forEachChild(node, visit);
}
}
}
@@ -2770,7 +2770,9 @@ namespace ts {
/* @internal */ export function getNodeKind(node: Node): string {
switch (node.kind) {
case SyntaxKind.ModuleDeclaration: return ScriptElementKind.moduleElement;
case SyntaxKind.ClassDeclaration: return ScriptElementKind.classElement;
case SyntaxKind.ClassDeclaration:
case SyntaxKind.ClassExpression:
return ScriptElementKind.classElement;
case SyntaxKind.InterfaceDeclaration: return ScriptElementKind.interfaceElement;
case SyntaxKind.TypeAliasDeclaration: return ScriptElementKind.typeElement;
case SyntaxKind.EnumDeclaration: return ScriptElementKind.enumElement;
@@ -2780,7 +2782,9 @@ namespace ts {
: isLet(node)
? ScriptElementKind.letElement
: ScriptElementKind.variableElement;
case SyntaxKind.FunctionDeclaration: return ScriptElementKind.functionElement;
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.FunctionExpression:
return ScriptElementKind.functionElement;
case SyntaxKind.GetAccessor: return ScriptElementKind.memberGetAccessorElement;
case SyntaxKind.SetAccessor: return ScriptElementKind.memberSetAccessorElement;
case SyntaxKind.MethodDeclaration:
@@ -4366,7 +4370,7 @@ namespace ts {
(location.kind === SyntaxKind.ConstructorKeyword && location.parent.kind === SyntaxKind.Constructor)) { // At constructor keyword of constructor declaration
// get the signature from the declaration and write it
const functionDeclaration = <FunctionLikeDeclaration>location.parent;
const allSignatures = functionDeclaration.kind === SyntaxKind.Constructor ? type.getConstructSignatures() : type.getCallSignatures();
const allSignatures = functionDeclaration.kind === SyntaxKind.Constructor ? type.getNonNullableType().getConstructSignatures() : type.getNonNullableType().getCallSignatures();
if (!typeChecker.isImplementationOfOverload(functionDeclaration)) {
signature = typeChecker.getSignatureFromDeclaration(functionDeclaration);
}
@@ -4564,7 +4568,7 @@ namespace ts {
symbolFlags & SymbolFlags.Signature ||
symbolFlags & SymbolFlags.Accessor ||
symbolKind === ScriptElementKind.memberFunctionElement) {
const allSignatures = type.getCallSignatures();
const allSignatures = type.getNonNullableType().getCallSignatures();
addSignatureDisplayParts(allSignatures[0], allSignatures);
}
}
@@ -4645,7 +4649,7 @@ namespace ts {
const sourceFile = getValidSourceFile(fileName);
const node = getTouchingPropertyName(sourceFile, position);
if (!node) {
if (node === sourceFile) {
return undefined;
}
@@ -4802,18 +4806,6 @@ namespace ts {
const sourceFile = getValidSourceFile(fileName);
const node = getTouchingPropertyName(sourceFile, position);
if (!node) {
return undefined;
}
// Labels
if (isJumpStatementTarget(node)) {
const labelName = (<Identifier>node).text;
const label = getTargetLabel((<BreakOrContinueStatement>node.parent), (<Identifier>node).text);
return label ? [createDefinitionInfo(label, ScriptElementKind.label, labelName, /*containerName*/ undefined)] : undefined;
}
/// Triple slash reference comments
const comment = findReferenceInPosition(sourceFile.referencedFiles, position);
if (comment) {
@@ -4823,6 +4815,7 @@ namespace ts {
}
return undefined;
}
// Type reference directives
const typeReferenceDirective = findReferenceInPosition(sourceFile.typeReferenceDirectives, position);
if (typeReferenceDirective) {
@@ -4833,6 +4826,18 @@ namespace ts {
return undefined;
}
const node = getTouchingPropertyName(sourceFile, position);
if (node === sourceFile) {
return undefined;
}
// Labels
if (isJumpStatementTarget(node)) {
const labelName = (<Identifier>node).text;
const label = getTargetLabel((<BreakOrContinueStatement>node.parent), (<Identifier>node).text);
return label ? [createDefinitionInfo(label, ScriptElementKind.label, labelName, /*containerName*/ undefined)] : undefined;
}
const typeChecker = program.getTypeChecker();
let symbol = typeChecker.getSymbolAtLocation(node);
@@ -4891,7 +4896,7 @@ namespace ts {
const sourceFile = getValidSourceFile(fileName);
const node = getTouchingPropertyName(sourceFile, position);
if (!node) {
if (node === sourceFile) {
return undefined;
}
@@ -5628,7 +5633,7 @@ namespace ts {
const sourceFile = getValidSourceFile(fileName);
const node = getTouchingPropertyName(sourceFile, position);
if (!node) {
if (node === sourceFile) {
return undefined;
}
@@ -6795,7 +6800,7 @@ namespace ts {
// Get node at the location
const node = getTouchingPropertyName(sourceFile, startPos);
if (!node) {
if (node === sourceFile) {
return;
}
@@ -1,26 +0,0 @@
tests/cases/conformance/types/namedTypes/classWithOptionalParameter.ts(4,6): error TS1112: A class member cannot be declared optional.
tests/cases/conformance/types/namedTypes/classWithOptionalParameter.ts(5,6): error TS1112: A class member cannot be declared optional.
tests/cases/conformance/types/namedTypes/classWithOptionalParameter.ts(9,6): error TS1112: A class member cannot be declared optional.
tests/cases/conformance/types/namedTypes/classWithOptionalParameter.ts(10,6): error TS1112: A class member cannot be declared optional.
==== tests/cases/conformance/types/namedTypes/classWithOptionalParameter.ts (4 errors) ====
// classes do not permit optional parameters, these are errors
class C {
x?: string;
~
!!! error TS1112: A class member cannot be declared optional.
f?() {}
~
!!! error TS1112: A class member cannot be declared optional.
}
class C2<T> {
x?: T;
~
!!! error TS1112: A class member cannot be declared optional.
f?(x: T) {}
~
!!! error TS1112: A class member cannot be declared optional.
}
@@ -0,0 +1,26 @@
=== tests/cases/conformance/types/namedTypes/classWithOptionalParameter.ts ===
// classes do not permit optional parameters, these are errors
class C {
>C : Symbol(C, Decl(classWithOptionalParameter.ts, 0, 0))
x?: string;
>x : Symbol(C.x, Decl(classWithOptionalParameter.ts, 2, 9))
f?() {}
>f : Symbol(C.f, Decl(classWithOptionalParameter.ts, 3, 15))
}
class C2<T> {
>C2 : Symbol(C2, Decl(classWithOptionalParameter.ts, 5, 1))
>T : Symbol(T, Decl(classWithOptionalParameter.ts, 7, 9))
x?: T;
>x : Symbol(C2.x, Decl(classWithOptionalParameter.ts, 7, 13))
>T : Symbol(T, Decl(classWithOptionalParameter.ts, 7, 9))
f?(x: T) {}
>f : Symbol(C2.f, Decl(classWithOptionalParameter.ts, 8, 10))
>x : Symbol(x, Decl(classWithOptionalParameter.ts, 9, 7))
>T : Symbol(T, Decl(classWithOptionalParameter.ts, 7, 9))
}
@@ -0,0 +1,26 @@
=== tests/cases/conformance/types/namedTypes/classWithOptionalParameter.ts ===
// classes do not permit optional parameters, these are errors
class C {
>C : C
x?: string;
>x : string
f?() {}
>f : () => void
}
class C2<T> {
>C2 : C2<T>
>T : T
x?: T;
>x : T
>T : T
f?(x: T) {}
>f : (x: T) => void
>x : T
>T : T
}
@@ -4,7 +4,7 @@ let cond: boolean;
>cond : boolean
function ff() {
>ff : () => void
>ff : () => never
let x: string | undefined;
>x : string | undefined
@@ -247,7 +247,7 @@ export declare class ConstructorWithPrivateParameterProperty {
constructor(x: string);
}
export declare class ConstructorWithOptionalParameterProperty {
x: string;
x?: string;
constructor(x?: string);
}
export declare class ConstructorWithParameterInitializer {
@@ -281,7 +281,7 @@ declare class GlobalConstructorWithPrivateParameterProperty {
constructor(x: string);
}
declare class GlobalConstructorWithOptionalParameterProperty {
x: string;
x?: string;
constructor(x?: string);
}
declare class GlobalConstructorWithParameterInitializer {
@@ -0,0 +1,11 @@
tests/cases/compiler/doubleUnderStringLiteralAssignability.ts(2,5): error TS2322: Type '"no_dunder"' is not assignable to type '"__dunder"'.
==== tests/cases/compiler/doubleUnderStringLiteralAssignability.ts (1 errors) ====
var shouldBeOk: '__dunder' = '__dunder';
var bad: '__dunder' = 'no_dunder';
~~~
!!! error TS2322: Type '"no_dunder"' is not assignable to type '"__dunder"'.
var okok: '___thunder' = '___thunder';
var alsoOk: '_sunder' = '_sunder';
@@ -0,0 +1,12 @@
//// [doubleUnderStringLiteralAssignability.ts]
var shouldBeOk: '__dunder' = '__dunder';
var bad: '__dunder' = 'no_dunder';
var okok: '___thunder' = '___thunder';
var alsoOk: '_sunder' = '_sunder';
//// [doubleUnderStringLiteralAssignability.js]
var shouldBeOk = '__dunder';
var bad = 'no_dunder';
var okok = '___thunder';
var alsoOk = '_sunder';
@@ -7,7 +7,7 @@ while (true) {
>true : boolean
function f() {
>f : () => void
>f : () => never
target:
>target : any
@@ -0,0 +1,30 @@
//// [fallbackToBindingPatternForTypeInference.ts]
declare function trans<T>(f: (x: T) => string): number;
trans(({a}) => a);
trans(([b,c]) => 'foo');
trans(({d: [e,f]}) => 'foo');
trans(([{g},{h}]) => 'foo');
trans(({a, b = 10}) => a);
//// [fallbackToBindingPatternForTypeInference.js]
trans(function (_a) {
var a = _a.a;
return a;
});
trans(function (_a) {
var b = _a[0], c = _a[1];
return 'foo';
});
trans(function (_a) {
var _b = _a.d, e = _b[0], f = _b[1];
return 'foo';
});
trans(function (_a) {
var g = _a[0].g, h = _a[1].h;
return 'foo';
});
trans(function (_a) {
var a = _a.a, _b = _a.b, b = _b === void 0 ? 10 : _b;
return a;
});
@@ -0,0 +1,34 @@
=== tests/cases/compiler/fallbackToBindingPatternForTypeInference.ts ===
declare function trans<T>(f: (x: T) => string): number;
>trans : Symbol(trans, Decl(fallbackToBindingPatternForTypeInference.ts, 0, 0))
>T : Symbol(T, Decl(fallbackToBindingPatternForTypeInference.ts, 0, 23))
>f : Symbol(f, Decl(fallbackToBindingPatternForTypeInference.ts, 0, 26))
>x : Symbol(x, Decl(fallbackToBindingPatternForTypeInference.ts, 0, 30))
>T : Symbol(T, Decl(fallbackToBindingPatternForTypeInference.ts, 0, 23))
trans(({a}) => a);
>trans : Symbol(trans, Decl(fallbackToBindingPatternForTypeInference.ts, 0, 0))
>a : Symbol(a, Decl(fallbackToBindingPatternForTypeInference.ts, 1, 8))
>a : Symbol(a, Decl(fallbackToBindingPatternForTypeInference.ts, 1, 8))
trans(([b,c]) => 'foo');
>trans : Symbol(trans, Decl(fallbackToBindingPatternForTypeInference.ts, 0, 0))
>b : Symbol(b, Decl(fallbackToBindingPatternForTypeInference.ts, 2, 8))
>c : Symbol(c, Decl(fallbackToBindingPatternForTypeInference.ts, 2, 10))
trans(({d: [e,f]}) => 'foo');
>trans : Symbol(trans, Decl(fallbackToBindingPatternForTypeInference.ts, 0, 0))
>e : Symbol(e, Decl(fallbackToBindingPatternForTypeInference.ts, 3, 12))
>f : Symbol(f, Decl(fallbackToBindingPatternForTypeInference.ts, 3, 14))
trans(([{g},{h}]) => 'foo');
>trans : Symbol(trans, Decl(fallbackToBindingPatternForTypeInference.ts, 0, 0))
>g : Symbol(g, Decl(fallbackToBindingPatternForTypeInference.ts, 4, 9))
>h : Symbol(h, Decl(fallbackToBindingPatternForTypeInference.ts, 4, 13))
trans(({a, b = 10}) => a);
>trans : Symbol(trans, Decl(fallbackToBindingPatternForTypeInference.ts, 0, 0))
>a : Symbol(a, Decl(fallbackToBindingPatternForTypeInference.ts, 5, 8))
>b : Symbol(b, Decl(fallbackToBindingPatternForTypeInference.ts, 5, 10))
>a : Symbol(a, Decl(fallbackToBindingPatternForTypeInference.ts, 5, 8))
@@ -0,0 +1,49 @@
=== tests/cases/compiler/fallbackToBindingPatternForTypeInference.ts ===
declare function trans<T>(f: (x: T) => string): number;
>trans : <T>(f: (x: T) => string) => number
>T : T
>f : (x: T) => string
>x : T
>T : T
trans(({a}) => a);
>trans(({a}) => a) : number
>trans : <T>(f: (x: T) => string) => number
>({a}) => a : ({a}: { a: any; }) => any
>a : any
>a : any
trans(([b,c]) => 'foo');
>trans(([b,c]) => 'foo') : number
>trans : <T>(f: (x: T) => string) => number
>([b,c]) => 'foo' : ([b, c]: [any, any]) => string
>b : any
>c : any
>'foo' : string
trans(({d: [e,f]}) => 'foo');
>trans(({d: [e,f]}) => 'foo') : number
>trans : <T>(f: (x: T) => string) => number
>({d: [e,f]}) => 'foo' : ({d: [e, f]}: { d: [any, any]; }) => string
>d : any
>e : any
>f : any
>'foo' : string
trans(([{g},{h}]) => 'foo');
>trans(([{g},{h}]) => 'foo') : number
>trans : <T>(f: (x: T) => string) => number
>([{g},{h}]) => 'foo' : ([{g}, {h}]: [{ g: any; }, { h: any; }]) => string
>g : any
>h : any
>'foo' : string
trans(({a, b = 10}) => a);
>trans(({a, b = 10}) => a) : number
>trans : <T>(f: (x: T) => string) => number
>({a, b = 10}) => a : ({a, b}: { a: any; b?: number; }) => any
>a : any
>b : number
>10 : number
>a : any
@@ -16,7 +16,7 @@ for (var x = <number>undefined; ;) { }
// new declaration space, making redeclaring x as a string valid
function declSpace() {
>declSpace : () => void
>declSpace : () => never
for (var x = 'this is a string'; ;) { }
>x : string
@@ -133,8 +133,8 @@ function fn5(x: Derived1) {
// 1.5: y: Derived1
// Want: ???
let y = x;
>y : nothing
>x : nothing
>y : never
>x : never
}
}
@@ -42,7 +42,7 @@ function isB(x: any): x is B {
}
function f1(x: A | B) {
>f1 : (x: A | B) => void
>f1 : (x: A | B) => never
>x : A | B
>A : A
>B : B
@@ -78,7 +78,7 @@ function f1(x: A | B) {
}
function f2(x: A | B) {
>f2 : (x: A | B) => void
>f2 : (x: A | B) => never
>x : A | B
>A : A
>B : B
@@ -1,6 +1,6 @@
=== tests/cases/compiler/nestedBlockScopedBindings3.ts ===
function a0() {
>a0 : () => void
>a0 : () => never
{
for (let x = 0; x < 1; ) {
>x : number
@@ -26,7 +26,7 @@ function a0() {
}
function a1() {
>a1 : () => void
>a1 : () => never
for (let x; x < 1;) {
>x : any
@@ -48,7 +48,7 @@ function a1() {
}
function a2() {
>a2 : () => void
>a2 : () => never
for (let x; x < 1;) {
>x : any
@@ -1,6 +1,6 @@
=== tests/cases/compiler/nestedBlockScopedBindings4.ts ===
function a0() {
>a0 : () => void
>a0 : () => never
for (let x; x < 1;) {
>x : any
@@ -28,7 +28,7 @@ function a0() {
}
function a1() {
>a1 : () => void
>a1 : () => never
for (let x; x < 1;) {
>x : any
@@ -60,7 +60,7 @@ function a1() {
}
function a2() {
>a2 : () => void
>a2 : () => never
for (let x; x < 1;) {
>x : any
@@ -93,7 +93,7 @@ function a2() {
function a3() {
>a3 : () => void
>a3 : () => never
for (let x; x < 1;) {
>x : any
@@ -1,6 +1,6 @@
=== tests/cases/compiler/nestedBlockScopedBindings6.ts ===
function a0() {
>a0 : () => void
>a0 : () => never
for (let x of [1]) {
>x : number
@@ -27,7 +27,7 @@ function a0() {
}
function a1() {
>a1 : () => void
>a1 : () => never
for (let x of [1]) {
>x : number
@@ -58,7 +58,7 @@ function a1() {
}
function a2() {
>a2 : () => void
>a2 : () => never
for (let x of [1]) {
>x : number
@@ -89,7 +89,7 @@ function a2() {
}
function a3() {
>a3 : () => void
>a3 : () => never
for (let x of [1]) {
>x : number
+138
View File
@@ -0,0 +1,138 @@
//// [neverType.ts]
function error(message: string) {
throw new Error(message);
}
function fail() {
return error("Something failed");
}
function infiniteLoop() {
while (true) {
}
}
function move1(direction: "up" | "down") {
switch (direction) {
case "up":
return 1;
case "down":
return -1;
}
return error("Should never get here");
}
function move2(direction: "up" | "down") {
return direction === "up" ? 1 :
direction === "down" ? -1 :
error("Should never get here");
}
function check<T>(x: T | undefined) {
return x || error("Undefined value");
}
function f1(x: string | number) {
if (typeof x === "boolean") {
x; // never
}
}
function f2(x: string | number) {
while (true) {
if (typeof x === "boolean") {
return x; // never
}
}
}
function failOrThrow(shouldFail: boolean) {
if (shouldFail) {
return fail();
}
throw new Error();
}
function test(cb: () => string) {
let s = cb();
return s;
}
let errorCallback = () => error("Error callback");
test(() => "hello");
test(() => fail());
test(() => { throw new Error(); })
test(errorCallback);
//// [neverType.js]
function error(message) {
throw new Error(message);
}
function fail() {
return error("Something failed");
}
function infiniteLoop() {
while (true) {
}
}
function move1(direction) {
switch (direction) {
case "up":
return 1;
case "down":
return -1;
}
return error("Should never get here");
}
function move2(direction) {
return direction === "up" ? 1 :
direction === "down" ? -1 :
error("Should never get here");
}
function check(x) {
return x || error("Undefined value");
}
function f1(x) {
if (typeof x === "boolean") {
x; // never
}
}
function f2(x) {
while (true) {
if (typeof x === "boolean") {
return x; // never
}
}
}
function failOrThrow(shouldFail) {
if (shouldFail) {
return fail();
}
throw new Error();
}
function test(cb) {
var s = cb();
return s;
}
var errorCallback = function () { return error("Error callback"); };
test(function () { return "hello"; });
test(function () { return fail(); });
test(function () { throw new Error(); });
test(errorCallback);
//// [neverType.d.ts]
declare function error(message: string): never;
declare function fail(): never;
declare function infiniteLoop(): never;
declare function move1(direction: "up" | "down"): number;
declare function move2(direction: "up" | "down"): number;
declare function check<T>(x: T | undefined): T;
declare function f1(x: string | number): void;
declare function f2(x: string | number): never;
declare function failOrThrow(shouldFail: boolean): never;
declare function test(cb: () => string): string;
declare let errorCallback: () => never;
+137
View File
@@ -0,0 +1,137 @@
=== tests/cases/conformance/types/never/neverType.ts ===
function error(message: string) {
>error : Symbol(error, Decl(neverType.ts, 0, 0))
>message : Symbol(message, Decl(neverType.ts, 1, 15))
throw new Error(message);
>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>message : Symbol(message, Decl(neverType.ts, 1, 15))
}
function fail() {
>fail : Symbol(fail, Decl(neverType.ts, 3, 1))
return error("Something failed");
>error : Symbol(error, Decl(neverType.ts, 0, 0))
}
function infiniteLoop() {
>infiniteLoop : Symbol(infiniteLoop, Decl(neverType.ts, 7, 1))
while (true) {
}
}
function move1(direction: "up" | "down") {
>move1 : Symbol(move1, Decl(neverType.ts, 12, 1))
>direction : Symbol(direction, Decl(neverType.ts, 14, 15))
switch (direction) {
>direction : Symbol(direction, Decl(neverType.ts, 14, 15))
case "up":
return 1;
case "down":
return -1;
}
return error("Should never get here");
>error : Symbol(error, Decl(neverType.ts, 0, 0))
}
function move2(direction: "up" | "down") {
>move2 : Symbol(move2, Decl(neverType.ts, 22, 1))
>direction : Symbol(direction, Decl(neverType.ts, 24, 15))
return direction === "up" ? 1 :
>direction : Symbol(direction, Decl(neverType.ts, 24, 15))
direction === "down" ? -1 :
>direction : Symbol(direction, Decl(neverType.ts, 24, 15))
error("Should never get here");
>error : Symbol(error, Decl(neverType.ts, 0, 0))
}
function check<T>(x: T | undefined) {
>check : Symbol(check, Decl(neverType.ts, 28, 1))
>T : Symbol(T, Decl(neverType.ts, 30, 15))
>x : Symbol(x, Decl(neverType.ts, 30, 18))
>T : Symbol(T, Decl(neverType.ts, 30, 15))
return x || error("Undefined value");
>x : Symbol(x, Decl(neverType.ts, 30, 18))
>error : Symbol(error, Decl(neverType.ts, 0, 0))
}
function f1(x: string | number) {
>f1 : Symbol(f1, Decl(neverType.ts, 32, 1))
>x : Symbol(x, Decl(neverType.ts, 34, 12))
if (typeof x === "boolean") {
>x : Symbol(x, Decl(neverType.ts, 34, 12))
x; // never
>x : Symbol(x, Decl(neverType.ts, 34, 12))
}
}
function f2(x: string | number) {
>f2 : Symbol(f2, Decl(neverType.ts, 38, 1))
>x : Symbol(x, Decl(neverType.ts, 40, 12))
while (true) {
if (typeof x === "boolean") {
>x : Symbol(x, Decl(neverType.ts, 40, 12))
return x; // never
>x : Symbol(x, Decl(neverType.ts, 40, 12))
}
}
}
function failOrThrow(shouldFail: boolean) {
>failOrThrow : Symbol(failOrThrow, Decl(neverType.ts, 46, 1))
>shouldFail : Symbol(shouldFail, Decl(neverType.ts, 48, 21))
if (shouldFail) {
>shouldFail : Symbol(shouldFail, Decl(neverType.ts, 48, 21))
return fail();
>fail : Symbol(fail, Decl(neverType.ts, 3, 1))
}
throw new Error();
>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
}
function test(cb: () => string) {
>test : Symbol(test, Decl(neverType.ts, 53, 1))
>cb : Symbol(cb, Decl(neverType.ts, 55, 14))
let s = cb();
>s : Symbol(s, Decl(neverType.ts, 56, 7))
>cb : Symbol(cb, Decl(neverType.ts, 55, 14))
return s;
>s : Symbol(s, Decl(neverType.ts, 56, 7))
}
let errorCallback = () => error("Error callback");
>errorCallback : Symbol(errorCallback, Decl(neverType.ts, 60, 3))
>error : Symbol(error, Decl(neverType.ts, 0, 0))
test(() => "hello");
>test : Symbol(test, Decl(neverType.ts, 53, 1))
test(() => fail());
>test : Symbol(test, Decl(neverType.ts, 53, 1))
>fail : Symbol(fail, Decl(neverType.ts, 3, 1))
test(() => { throw new Error(); })
>test : Symbol(test, Decl(neverType.ts, 53, 1))
>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
test(errorCallback);
>test : Symbol(test, Decl(neverType.ts, 53, 1))
>errorCallback : Symbol(errorCallback, Decl(neverType.ts, 60, 3))
+189
View File
@@ -0,0 +1,189 @@
=== tests/cases/conformance/types/never/neverType.ts ===
function error(message: string) {
>error : (message: string) => never
>message : string
throw new Error(message);
>new Error(message) : Error
>Error : ErrorConstructor
>message : string
}
function fail() {
>fail : () => never
return error("Something failed");
>error("Something failed") : never
>error : (message: string) => never
>"Something failed" : string
}
function infiniteLoop() {
>infiniteLoop : () => never
while (true) {
>true : boolean
}
}
function move1(direction: "up" | "down") {
>move1 : (direction: "up" | "down") => number
>direction : "up" | "down"
switch (direction) {
>direction : "up" | "down"
case "up":
>"up" : string
return 1;
>1 : number
case "down":
>"down" : string
return -1;
>-1 : number
>1 : number
}
return error("Should never get here");
>error("Should never get here") : never
>error : (message: string) => never
>"Should never get here" : string
}
function move2(direction: "up" | "down") {
>move2 : (direction: "up" | "down") => number
>direction : "up" | "down"
return direction === "up" ? 1 :
>direction === "up" ? 1 : direction === "down" ? -1 : error("Should never get here") : number
>direction === "up" : boolean
>direction : "up" | "down"
>"up" : string
>1 : number
direction === "down" ? -1 :
>direction === "down" ? -1 : error("Should never get here") : number
>direction === "down" : boolean
>direction : "up" | "down"
>"down" : string
>-1 : number
>1 : number
error("Should never get here");
>error("Should never get here") : never
>error : (message: string) => never
>"Should never get here" : string
}
function check<T>(x: T | undefined) {
>check : <T>(x: T | undefined) => T
>T : T
>x : T | undefined
>T : T
return x || error("Undefined value");
>x || error("Undefined value") : T
>x : T | undefined
>error("Undefined value") : never
>error : (message: string) => never
>"Undefined value" : string
}
function f1(x: string | number) {
>f1 : (x: string | number) => void
>x : string | number
if (typeof x === "boolean") {
>typeof x === "boolean" : boolean
>typeof x : string
>x : string | number
>"boolean" : string
x; // never
>x : never
}
}
function f2(x: string | number) {
>f2 : (x: string | number) => never
>x : string | number
while (true) {
>true : boolean
if (typeof x === "boolean") {
>typeof x === "boolean" : boolean
>typeof x : string
>x : string | number
>"boolean" : string
return x; // never
>x : never
}
}
}
function failOrThrow(shouldFail: boolean) {
>failOrThrow : (shouldFail: boolean) => never
>shouldFail : boolean
if (shouldFail) {
>shouldFail : boolean
return fail();
>fail() : never
>fail : () => never
}
throw new Error();
>new Error() : Error
>Error : ErrorConstructor
}
function test(cb: () => string) {
>test : (cb: () => string) => string
>cb : () => string
let s = cb();
>s : string
>cb() : string
>cb : () => string
return s;
>s : string
}
let errorCallback = () => error("Error callback");
>errorCallback : () => never
>() => error("Error callback") : () => never
>error("Error callback") : never
>error : (message: string) => never
>"Error callback" : string
test(() => "hello");
>test(() => "hello") : string
>test : (cb: () => string) => string
>() => "hello" : () => string
>"hello" : string
test(() => fail());
>test(() => fail()) : string
>test : (cb: () => string) => string
>() => fail() : () => never
>fail() : never
>fail : () => never
test(() => { throw new Error(); })
>test(() => { throw new Error(); }) : string
>test : (cb: () => string) => string
>() => { throw new Error(); } : () => never
>new Error() : Error
>Error : ErrorConstructor
test(errorCallback);
>test(errorCallback) : string
>test : (cb: () => string) => string
>errorCallback : () => never
@@ -0,0 +1,50 @@
tests/cases/conformance/types/never/neverTypeErrors1.ts(3,5): error TS2322: Type 'number' is not assignable to type 'never'.
tests/cases/conformance/types/never/neverTypeErrors1.ts(4,5): error TS2322: Type 'string' is not assignable to type 'never'.
tests/cases/conformance/types/never/neverTypeErrors1.ts(5,5): error TS2322: Type 'boolean' is not assignable to type 'never'.
tests/cases/conformance/types/never/neverTypeErrors1.ts(6,5): error TS2322: Type 'undefined' is not assignable to type 'never'.
tests/cases/conformance/types/never/neverTypeErrors1.ts(7,5): error TS2322: Type 'null' is not assignable to type 'never'.
tests/cases/conformance/types/never/neverTypeErrors1.ts(8,5): error TS2322: Type '{}' is not assignable to type 'never'.
tests/cases/conformance/types/never/neverTypeErrors1.ts(12,5): error TS2322: Type 'undefined' is not assignable to type 'never'.
tests/cases/conformance/types/never/neverTypeErrors1.ts(16,12): error TS2322: Type 'number' is not assignable to type 'never'.
tests/cases/conformance/types/never/neverTypeErrors1.ts(19,16): error TS2534: A function returning 'never' cannot have a reachable end point.
==== tests/cases/conformance/types/never/neverTypeErrors1.ts (9 errors) ====
function f1() {
let x: never;
x = 1;
~
!!! error TS2322: Type 'number' is not assignable to type 'never'.
x = "abc";
~
!!! error TS2322: Type 'string' is not assignable to type 'never'.
x = false;
~
!!! error TS2322: Type 'boolean' is not assignable to type 'never'.
x = undefined;
~
!!! error TS2322: Type 'undefined' is not assignable to type 'never'.
x = null;
~
!!! error TS2322: Type 'null' is not assignable to type 'never'.
x = {};
~
!!! error TS2322: Type '{}' is not assignable to type 'never'.
}
function f2(): never {
return;
~~~~~~~
!!! error TS2322: Type 'undefined' is not assignable to type 'never'.
}
function f3(): never {
return 1;
~
!!! error TS2322: Type 'number' is not assignable to type 'never'.
}
function f4(): never {
~~~~~
!!! error TS2534: A function returning 'never' cannot have a reachable end point.
}
@@ -0,0 +1,40 @@
//// [neverTypeErrors1.ts]
function f1() {
let x: never;
x = 1;
x = "abc";
x = false;
x = undefined;
x = null;
x = {};
}
function f2(): never {
return;
}
function f3(): never {
return 1;
}
function f4(): never {
}
//// [neverTypeErrors1.js]
function f1() {
var x;
x = 1;
x = "abc";
x = false;
x = undefined;
x = null;
x = {};
}
function f2() {
return;
}
function f3() {
return 1;
}
function f4() {
}
@@ -0,0 +1,51 @@
tests/cases/conformance/types/never/neverTypeErrors2.ts(4,5): error TS2322: Type 'number' is not assignable to type 'never'.
tests/cases/conformance/types/never/neverTypeErrors2.ts(5,5): error TS2322: Type 'string' is not assignable to type 'never'.
tests/cases/conformance/types/never/neverTypeErrors2.ts(6,5): error TS2322: Type 'boolean' is not assignable to type 'never'.
tests/cases/conformance/types/never/neverTypeErrors2.ts(7,5): error TS2322: Type 'undefined' is not assignable to type 'never'.
tests/cases/conformance/types/never/neverTypeErrors2.ts(8,5): error TS2322: Type 'null' is not assignable to type 'never'.
tests/cases/conformance/types/never/neverTypeErrors2.ts(9,5): error TS2322: Type '{}' is not assignable to type 'never'.
tests/cases/conformance/types/never/neverTypeErrors2.ts(13,5): error TS2322: Type 'undefined' is not assignable to type 'never'.
tests/cases/conformance/types/never/neverTypeErrors2.ts(17,12): error TS2322: Type 'number' is not assignable to type 'never'.
tests/cases/conformance/types/never/neverTypeErrors2.ts(20,16): error TS2534: A function returning 'never' cannot have a reachable end point.
==== tests/cases/conformance/types/never/neverTypeErrors2.ts (9 errors) ====
function f1() {
let x: never;
x = 1;
~
!!! error TS2322: Type 'number' is not assignable to type 'never'.
x = "abc";
~
!!! error TS2322: Type 'string' is not assignable to type 'never'.
x = false;
~
!!! error TS2322: Type 'boolean' is not assignable to type 'never'.
x = undefined;
~
!!! error TS2322: Type 'undefined' is not assignable to type 'never'.
x = null;
~
!!! error TS2322: Type 'null' is not assignable to type 'never'.
x = {};
~
!!! error TS2322: Type '{}' is not assignable to type 'never'.
}
function f2(): never {
return;
~~~~~~~
!!! error TS2322: Type 'undefined' is not assignable to type 'never'.
}
function f3(): never {
return 1;
~
!!! error TS2322: Type 'number' is not assignable to type 'never'.
}
function f4(): never {
~~~~~
!!! error TS2534: A function returning 'never' cannot have a reachable end point.
}
@@ -0,0 +1,41 @@
//// [neverTypeErrors2.ts]
function f1() {
let x: never;
x = 1;
x = "abc";
x = false;
x = undefined;
x = null;
x = {};
}
function f2(): never {
return;
}
function f3(): never {
return 1;
}
function f4(): never {
}
//// [neverTypeErrors2.js]
function f1() {
var x;
x = 1;
x = "abc";
x = false;
x = undefined;
x = null;
x = {};
}
function f2() {
return;
}
function f3() {
return 1;
}
function f4() {
}
@@ -1,7 +1,7 @@
tests/cases/compiler/objectLiteralMemberWithQuestionMark1.ts(1,14): error TS1112: A class member cannot be declared optional.
tests/cases/compiler/objectLiteralMemberWithQuestionMark1.ts(1,14): error TS1162: An object member cannot be declared optional.
==== tests/cases/compiler/objectLiteralMemberWithQuestionMark1.ts (1 errors) ====
var v = { foo?() { } }
~
!!! error TS1112: A class member cannot be declared optional.
!!! error TS1162: An object member cannot be declared optional.
@@ -1,9 +1,7 @@
tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties.ts(12,6): error TS1112: A class member cannot be declared optional.
tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties.ts(20,6): error TS1112: A class member cannot be declared optional.
tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties.ts(24,6): error TS1162: An object member cannot be declared optional.
==== tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties.ts (3 errors) ====
==== tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWithOptionalProperties.ts (1 errors) ====
// Basic uses of optional properties
var a: {
@@ -15,9 +13,7 @@ tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWith
}
class C {
x?: number; // error
~
!!! error TS1112: A class member cannot be declared optional.
x?: number; // ok
}
interface I2<T> {
@@ -25,9 +21,7 @@ tests/cases/conformance/types/objectTypeLiteral/methodSignatures/objectTypesWith
}
class C2<T> {
x?: T; // error
~
!!! error TS1112: A class member cannot be declared optional.
x?: T; // ok
}
var b = {
@@ -10,7 +10,7 @@ interface I {
}
class C {
x?: number; // error
x?: number; // ok
}
interface I2<T> {
@@ -18,7 +18,7 @@ interface I2<T> {
}
class C2<T> {
x?: T; // error
x?: T; // ok
}
var b = {
@@ -0,0 +1,147 @@
//// [optionalMethods.ts]
interface Foo {
a: number;
b?: number;
f(): number;
g?(): number;
}
function test1(x: Foo) {
x.a;
x.b;
x.f;
x.g;
let f1 = x.f();
let g1 = x.g && x.g();
let g2 = x.g ? x.g() : 0;
}
class Bar {
a: number;
b?: number;
c? = 2;
constructor(public d?: number, public e = 10) {}
f() {
return 1;
}
g?(): number; // Body of optional method can be omitted
h?() {
return 2;
}
}
function test2(x: Bar) {
x.a;
x.b;
x.c;
x.d;
x.e;
x.f;
x.g;
let f1 = x.f();
let g1 = x.g && x.g();
let g2 = x.g ? x.g() : 0;
let h1 = x.h && x.h();
let h2 = x.h ? x.h() : 0;
}
class Base {
a?: number;
f?(): number;
}
class Derived extends Base {
a = 1;
f(): number { return 1; }
}
//// [optionalMethods.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 test1(x) {
x.a;
x.b;
x.f;
x.g;
var f1 = x.f();
var g1 = x.g && x.g();
var g2 = x.g ? x.g() : 0;
}
var Bar = (function () {
function Bar(d, e) {
if (e === void 0) { e = 10; }
this.d = d;
this.e = e;
this.c = 2;
}
Bar.prototype.f = function () {
return 1;
};
Bar.prototype.h = function () {
return 2;
};
return Bar;
}());
function test2(x) {
x.a;
x.b;
x.c;
x.d;
x.e;
x.f;
x.g;
var f1 = x.f();
var g1 = x.g && x.g();
var g2 = x.g ? x.g() : 0;
var h1 = x.h && x.h();
var h2 = x.h ? x.h() : 0;
}
var Base = (function () {
function Base() {
}
return Base;
}());
var Derived = (function (_super) {
__extends(Derived, _super);
function Derived() {
_super.apply(this, arguments);
this.a = 1;
}
Derived.prototype.f = function () { return 1; };
return Derived;
}(Base));
//// [optionalMethods.d.ts]
interface Foo {
a: number;
b?: number;
f(): number;
g?(): number;
}
declare function test1(x: Foo): void;
declare class Bar {
d?: number;
e: number;
a: number;
b?: number;
c?: number | undefined;
constructor(d?: number, e?: number);
f(): number;
g?(): number;
h?(): number;
}
declare function test2(x: Bar): void;
declare class Base {
a?: number;
f?(): number;
}
declare class Derived extends Base {
a: number;
f(): number;
}
@@ -0,0 +1,203 @@
=== tests/cases/conformance/types/namedTypes/optionalMethods.ts ===
interface Foo {
>Foo : Symbol(Foo, Decl(optionalMethods.ts, 0, 0))
a: number;
>a : Symbol(Foo.a, Decl(optionalMethods.ts, 1, 15))
b?: number;
>b : Symbol(Foo.b, Decl(optionalMethods.ts, 2, 14))
f(): number;
>f : Symbol(Foo.f, Decl(optionalMethods.ts, 3, 15))
g?(): number;
>g : Symbol(Foo.g, Decl(optionalMethods.ts, 4, 16))
}
function test1(x: Foo) {
>test1 : Symbol(test1, Decl(optionalMethods.ts, 6, 1))
>x : Symbol(x, Decl(optionalMethods.ts, 8, 15))
>Foo : Symbol(Foo, Decl(optionalMethods.ts, 0, 0))
x.a;
>x.a : Symbol(Foo.a, Decl(optionalMethods.ts, 1, 15))
>x : Symbol(x, Decl(optionalMethods.ts, 8, 15))
>a : Symbol(Foo.a, Decl(optionalMethods.ts, 1, 15))
x.b;
>x.b : Symbol(Foo.b, Decl(optionalMethods.ts, 2, 14))
>x : Symbol(x, Decl(optionalMethods.ts, 8, 15))
>b : Symbol(Foo.b, Decl(optionalMethods.ts, 2, 14))
x.f;
>x.f : Symbol(Foo.f, Decl(optionalMethods.ts, 3, 15))
>x : Symbol(x, Decl(optionalMethods.ts, 8, 15))
>f : Symbol(Foo.f, Decl(optionalMethods.ts, 3, 15))
x.g;
>x.g : Symbol(Foo.g, Decl(optionalMethods.ts, 4, 16))
>x : Symbol(x, Decl(optionalMethods.ts, 8, 15))
>g : Symbol(Foo.g, Decl(optionalMethods.ts, 4, 16))
let f1 = x.f();
>f1 : Symbol(f1, Decl(optionalMethods.ts, 13, 7))
>x.f : Symbol(Foo.f, Decl(optionalMethods.ts, 3, 15))
>x : Symbol(x, Decl(optionalMethods.ts, 8, 15))
>f : Symbol(Foo.f, Decl(optionalMethods.ts, 3, 15))
let g1 = x.g && x.g();
>g1 : Symbol(g1, Decl(optionalMethods.ts, 14, 7))
>x.g : Symbol(Foo.g, Decl(optionalMethods.ts, 4, 16))
>x : Symbol(x, Decl(optionalMethods.ts, 8, 15))
>g : Symbol(Foo.g, Decl(optionalMethods.ts, 4, 16))
>x.g : Symbol(Foo.g, Decl(optionalMethods.ts, 4, 16))
>x : Symbol(x, Decl(optionalMethods.ts, 8, 15))
>g : Symbol(Foo.g, Decl(optionalMethods.ts, 4, 16))
let g2 = x.g ? x.g() : 0;
>g2 : Symbol(g2, Decl(optionalMethods.ts, 15, 7))
>x.g : Symbol(Foo.g, Decl(optionalMethods.ts, 4, 16))
>x : Symbol(x, Decl(optionalMethods.ts, 8, 15))
>g : Symbol(Foo.g, Decl(optionalMethods.ts, 4, 16))
>x.g : Symbol(Foo.g, Decl(optionalMethods.ts, 4, 16))
>x : Symbol(x, Decl(optionalMethods.ts, 8, 15))
>g : Symbol(Foo.g, Decl(optionalMethods.ts, 4, 16))
}
class Bar {
>Bar : Symbol(Bar, Decl(optionalMethods.ts, 16, 1))
a: number;
>a : Symbol(Bar.a, Decl(optionalMethods.ts, 18, 11))
b?: number;
>b : Symbol(Bar.b, Decl(optionalMethods.ts, 19, 14))
c? = 2;
>c : Symbol(Bar.c, Decl(optionalMethods.ts, 20, 15))
constructor(public d?: number, public e = 10) {}
>d : Symbol(Bar.d, Decl(optionalMethods.ts, 22, 16))
>e : Symbol(Bar.e, Decl(optionalMethods.ts, 22, 34))
f() {
>f : Symbol(Bar.f, Decl(optionalMethods.ts, 22, 52))
return 1;
}
g?(): number; // Body of optional method can be omitted
>g : Symbol(Bar.g, Decl(optionalMethods.ts, 25, 5))
h?() {
>h : Symbol(Bar.h, Decl(optionalMethods.ts, 26, 17))
return 2;
}
}
function test2(x: Bar) {
>test2 : Symbol(test2, Decl(optionalMethods.ts, 30, 1))
>x : Symbol(x, Decl(optionalMethods.ts, 32, 15))
>Bar : Symbol(Bar, Decl(optionalMethods.ts, 16, 1))
x.a;
>x.a : Symbol(Bar.a, Decl(optionalMethods.ts, 18, 11))
>x : Symbol(x, Decl(optionalMethods.ts, 32, 15))
>a : Symbol(Bar.a, Decl(optionalMethods.ts, 18, 11))
x.b;
>x.b : Symbol(Bar.b, Decl(optionalMethods.ts, 19, 14))
>x : Symbol(x, Decl(optionalMethods.ts, 32, 15))
>b : Symbol(Bar.b, Decl(optionalMethods.ts, 19, 14))
x.c;
>x.c : Symbol(Bar.c, Decl(optionalMethods.ts, 20, 15))
>x : Symbol(x, Decl(optionalMethods.ts, 32, 15))
>c : Symbol(Bar.c, Decl(optionalMethods.ts, 20, 15))
x.d;
>x.d : Symbol(Bar.d, Decl(optionalMethods.ts, 22, 16))
>x : Symbol(x, Decl(optionalMethods.ts, 32, 15))
>d : Symbol(Bar.d, Decl(optionalMethods.ts, 22, 16))
x.e;
>x.e : Symbol(Bar.e, Decl(optionalMethods.ts, 22, 34))
>x : Symbol(x, Decl(optionalMethods.ts, 32, 15))
>e : Symbol(Bar.e, Decl(optionalMethods.ts, 22, 34))
x.f;
>x.f : Symbol(Bar.f, Decl(optionalMethods.ts, 22, 52))
>x : Symbol(x, Decl(optionalMethods.ts, 32, 15))
>f : Symbol(Bar.f, Decl(optionalMethods.ts, 22, 52))
x.g;
>x.g : Symbol(Bar.g, Decl(optionalMethods.ts, 25, 5))
>x : Symbol(x, Decl(optionalMethods.ts, 32, 15))
>g : Symbol(Bar.g, Decl(optionalMethods.ts, 25, 5))
let f1 = x.f();
>f1 : Symbol(f1, Decl(optionalMethods.ts, 40, 7))
>x.f : Symbol(Bar.f, Decl(optionalMethods.ts, 22, 52))
>x : Symbol(x, Decl(optionalMethods.ts, 32, 15))
>f : Symbol(Bar.f, Decl(optionalMethods.ts, 22, 52))
let g1 = x.g && x.g();
>g1 : Symbol(g1, Decl(optionalMethods.ts, 41, 7))
>x.g : Symbol(Bar.g, Decl(optionalMethods.ts, 25, 5))
>x : Symbol(x, Decl(optionalMethods.ts, 32, 15))
>g : Symbol(Bar.g, Decl(optionalMethods.ts, 25, 5))
>x.g : Symbol(Bar.g, Decl(optionalMethods.ts, 25, 5))
>x : Symbol(x, Decl(optionalMethods.ts, 32, 15))
>g : Symbol(Bar.g, Decl(optionalMethods.ts, 25, 5))
let g2 = x.g ? x.g() : 0;
>g2 : Symbol(g2, Decl(optionalMethods.ts, 42, 7))
>x.g : Symbol(Bar.g, Decl(optionalMethods.ts, 25, 5))
>x : Symbol(x, Decl(optionalMethods.ts, 32, 15))
>g : Symbol(Bar.g, Decl(optionalMethods.ts, 25, 5))
>x.g : Symbol(Bar.g, Decl(optionalMethods.ts, 25, 5))
>x : Symbol(x, Decl(optionalMethods.ts, 32, 15))
>g : Symbol(Bar.g, Decl(optionalMethods.ts, 25, 5))
let h1 = x.h && x.h();
>h1 : Symbol(h1, Decl(optionalMethods.ts, 43, 7))
>x.h : Symbol(Bar.h, Decl(optionalMethods.ts, 26, 17))
>x : Symbol(x, Decl(optionalMethods.ts, 32, 15))
>h : Symbol(Bar.h, Decl(optionalMethods.ts, 26, 17))
>x.h : Symbol(Bar.h, Decl(optionalMethods.ts, 26, 17))
>x : Symbol(x, Decl(optionalMethods.ts, 32, 15))
>h : Symbol(Bar.h, Decl(optionalMethods.ts, 26, 17))
let h2 = x.h ? x.h() : 0;
>h2 : Symbol(h2, Decl(optionalMethods.ts, 44, 7))
>x.h : Symbol(Bar.h, Decl(optionalMethods.ts, 26, 17))
>x : Symbol(x, Decl(optionalMethods.ts, 32, 15))
>h : Symbol(Bar.h, Decl(optionalMethods.ts, 26, 17))
>x.h : Symbol(Bar.h, Decl(optionalMethods.ts, 26, 17))
>x : Symbol(x, Decl(optionalMethods.ts, 32, 15))
>h : Symbol(Bar.h, Decl(optionalMethods.ts, 26, 17))
}
class Base {
>Base : Symbol(Base, Decl(optionalMethods.ts, 45, 1))
a?: number;
>a : Symbol(Base.a, Decl(optionalMethods.ts, 47, 12))
f?(): number;
>f : Symbol(Base.f, Decl(optionalMethods.ts, 48, 15))
}
class Derived extends Base {
>Derived : Symbol(Derived, Decl(optionalMethods.ts, 50, 1))
>Base : Symbol(Base, Decl(optionalMethods.ts, 45, 1))
a = 1;
>a : Symbol(Derived.a, Decl(optionalMethods.ts, 52, 28))
f(): number { return 1; }
>f : Symbol(Derived.f, Decl(optionalMethods.ts, 53, 10))
}
@@ -0,0 +1,226 @@
=== tests/cases/conformance/types/namedTypes/optionalMethods.ts ===
interface Foo {
>Foo : Foo
a: number;
>a : number
b?: number;
>b : number | undefined
f(): number;
>f : () => number
g?(): number;
>g : (() => number) | undefined
}
function test1(x: Foo) {
>test1 : (x: Foo) => void
>x : Foo
>Foo : Foo
x.a;
>x.a : number
>x : Foo
>a : number
x.b;
>x.b : number | undefined
>x : Foo
>b : number | undefined
x.f;
>x.f : () => number
>x : Foo
>f : () => number
x.g;
>x.g : (() => number) | undefined
>x : Foo
>g : (() => number) | undefined
let f1 = x.f();
>f1 : number
>x.f() : number
>x.f : () => number
>x : Foo
>f : () => number
let g1 = x.g && x.g();
>g1 : number | undefined
>x.g && x.g() : number | undefined
>x.g : (() => number) | undefined
>x : Foo
>g : (() => number) | undefined
>x.g() : number
>x.g : () => number
>x : Foo
>g : () => number
let g2 = x.g ? x.g() : 0;
>g2 : number
>x.g ? x.g() : 0 : number
>x.g : (() => number) | undefined
>x : Foo
>g : (() => number) | undefined
>x.g() : number
>x.g : () => number
>x : Foo
>g : () => number
>0 : number
}
class Bar {
>Bar : Bar
a: number;
>a : number
b?: number;
>b : number | undefined
c? = 2;
>c : number | undefined
>2 : number
constructor(public d?: number, public e = 10) {}
>d : number | undefined
>e : number
>10 : number
f() {
>f : () => number
return 1;
>1 : number
}
g?(): number; // Body of optional method can be omitted
>g : (() => number) | undefined
h?() {
>h : (() => number) | undefined
return 2;
>2 : number
}
}
function test2(x: Bar) {
>test2 : (x: Bar) => void
>x : Bar
>Bar : Bar
x.a;
>x.a : number
>x : Bar
>a : number
x.b;
>x.b : number | undefined
>x : Bar
>b : number | undefined
x.c;
>x.c : number | undefined
>x : Bar
>c : number | undefined
x.d;
>x.d : number | undefined
>x : Bar
>d : number | undefined
x.e;
>x.e : number
>x : Bar
>e : number
x.f;
>x.f : () => number
>x : Bar
>f : () => number
x.g;
>x.g : (() => number) | undefined
>x : Bar
>g : (() => number) | undefined
let f1 = x.f();
>f1 : number
>x.f() : number
>x.f : () => number
>x : Bar
>f : () => number
let g1 = x.g && x.g();
>g1 : number | undefined
>x.g && x.g() : number | undefined
>x.g : (() => number) | undefined
>x : Bar
>g : (() => number) | undefined
>x.g() : number
>x.g : () => number
>x : Bar
>g : () => number
let g2 = x.g ? x.g() : 0;
>g2 : number
>x.g ? x.g() : 0 : number
>x.g : (() => number) | undefined
>x : Bar
>g : (() => number) | undefined
>x.g() : number
>x.g : () => number
>x : Bar
>g : () => number
>0 : number
let h1 = x.h && x.h();
>h1 : number | undefined
>x.h && x.h() : number | undefined
>x.h : (() => number) | undefined
>x : Bar
>h : (() => number) | undefined
>x.h() : number
>x.h : () => number
>x : Bar
>h : () => number
let h2 = x.h ? x.h() : 0;
>h2 : number
>x.h ? x.h() : 0 : number
>x.h : (() => number) | undefined
>x : Bar
>h : (() => number) | undefined
>x.h() : number
>x.h : () => number
>x : Bar
>h : () => number
>0 : number
}
class Base {
>Base : Base
a?: number;
>a : number | undefined
f?(): number;
>f : (() => number) | undefined
}
class Derived extends Base {
>Derived : Derived
>Base : Base
a = 1;
>a : number
>1 : number
f(): number { return 1; }
>f : () => number
>1 : number
}
@@ -7,7 +7,7 @@ while (true) {
>true : boolean
function f() {
>f : () => void
>f : () => never
target:
>target : any
@@ -63,7 +63,7 @@ var x3 = f1()
.then(f2, (e: Error) => {
>then : { <TResult>(onfulfilled?: (value: T1) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => TResult | PromiseLike<TResult>): Promise<TResult>; <TResult>(onfulfilled?: (value: T1) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => void): Promise<TResult>; }
>f2 : (x: T1) => T2
>(e: Error) => { throw e;} : (e: Error) => void
>(e: Error) => { throw e;} : (e: Error) => never
>e : Error
>Error : Error
@@ -116,6 +116,6 @@ if (!hasKind(x, "B")) {
}
else {
let d = x;
>d : nothing
>x : nothing
>d : never
>x : never
}
@@ -110,6 +110,6 @@ if (!hasKind(x, "B")) {
}
else {
let d = x;
>d : nothing
>x : nothing
>d : never
>x : never
}
@@ -113,6 +113,6 @@ if (!hasKind(x, "B")) {
}
else {
let d = x;
>d : nothing
>x : nothing
>d : never
>x : never
}
@@ -1,7 +1,7 @@
=== tests/cases/conformance/statements/throwStatements/throwInEnclosingStatements.ts ===
function fn(x) {
>fn : (x: any) => void
>fn : (x: any) => never
>x : any
throw x;
@@ -9,7 +9,7 @@ function fn(x) {
}
<T>(x: T) => { throw x; }
><T>(x: T) => { throw x; } : <T>(x: T) => void
><T>(x: T) => { throw x; } : <T>(x: T) => never
>T : T
>x : T
>T : T
@@ -78,7 +78,7 @@ class C<T> {
>T : T
biz() {
>biz : () => void
>biz : () => never
throw this.value;
>this.value : T
@@ -93,15 +93,15 @@ class C<T> {
}
var aa = {
>aa : { id: number; biz(): void; }
>{ id:12, biz() { throw this; }} : { id: number; biz(): void; }
>aa : { id: number; biz(): never; }
>{ id:12, biz() { throw this; }} : { id: number; biz(): never; }
id:12,
>id : number
>12 : number
biz() {
>biz : () => void
>biz : () => never
throw this;
>this : any
@@ -121,7 +121,7 @@ if (typeof strOrNum === "boolean") {
let z1: {} = strOrNum; // {}
>z1 : {}
>strOrNum : nothing
>strOrNum : never
}
else {
let z2: string | number = strOrNum; // string | number
@@ -215,6 +215,6 @@ if (typeof strOrNum !== "boolean") {
else {
let z2: {} = strOrNum; // {}
>z2 : {}
>strOrNum : nothing
>strOrNum : never
}
@@ -120,7 +120,7 @@ if (typeof strOrBool === "number") {
let y1: {} = strOrBool; // {}
>y1 : {}
>strOrBool : nothing
>strOrBool : never
}
else {
let y2: string | boolean = strOrBool; // string | boolean
@@ -212,6 +212,6 @@ if (typeof strOrBool !== "number") {
else {
let y2: {} = strOrBool; // {}
>y2 : {}
>strOrBool : nothing
>strOrBool : never
}
@@ -105,7 +105,7 @@ if (typeof strOrNumOrBool === "Object") {
let q1: {} = strOrNumOrBool; // {}
>q1 : {}
>strOrNumOrBool : nothing
>strOrNumOrBool : never
}
else {
let q2: string | number | boolean = strOrNumOrBool; // string | number | boolean
@@ -178,6 +178,6 @@ if (typeof strOrNumOrBool !== "Object") {
else {
let q2: {} = strOrNumOrBool; // {}
>q2 : {}
>strOrNumOrBool : nothing
>strOrNumOrBool : never
}
@@ -121,7 +121,7 @@ if (typeof numOrBool === "string") {
let x1: {} = numOrBool; // {}
>x1 : {}
>numOrBool : nothing
>numOrBool : never
}
else {
let x2: number | boolean = numOrBool; // number | boolean
@@ -214,6 +214,6 @@ if (typeof numOrBool !== "string") {
else {
let x2: {} = numOrBool; // {}
>x2 : {}
>numOrBool : nothing
>numOrBool : never
}
@@ -259,7 +259,7 @@ function f4() {
>"boolean" : string
x; // nothing (boolean not in declared type)
>x : nothing
>x : never
}
x; // undefined
>x : undefined
@@ -1,4 +1,4 @@
tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOf.ts(7,20): error TS2339: Property 'global' does not exist on type 'nothing'.
tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOf.ts(7,20): error TS2339: Property 'global' does not exist on type 'never'.
==== tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOf.ts (1 errors) ====
@@ -10,5 +10,5 @@ tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOf.ts(7,20)
result = result2;
} else if (!result.global) {
~~~~~~
!!! error TS2339: Property 'global' does not exist on type 'nothing'.
!!! error TS2339: Property 'global' does not exist on type 'never'.
}
@@ -0,0 +1,4 @@
var shouldBeOk: '__dunder' = '__dunder';
var bad: '__dunder' = 'no_dunder';
var okok: '___thunder' = '___thunder';
var alsoOk: '_sunder' = '_sunder';
@@ -0,0 +1,6 @@
declare function trans<T>(f: (x: T) => string): number;
trans(({a}) => a);
trans(([b,c]) => 'foo');
trans(({d: [e,f]}) => 'foo');
trans(([{g},{h}]) => 'foo');
trans(({a, b = 10}) => a);
@@ -0,0 +1,58 @@
// @strictNullChecks: true
// @declaration: true
interface Foo {
a: number;
b?: number;
f(): number;
g?(): number;
}
function test1(x: Foo) {
x.a;
x.b;
x.f;
x.g;
let f1 = x.f();
let g1 = x.g && x.g();
let g2 = x.g ? x.g() : 0;
}
class Bar {
a: number;
b?: number;
c? = 2;
constructor(public d?: number, public e = 10) {}
f() {
return 1;
}
g?(): number; // Body of optional method can be omitted
h?() {
return 2;
}
}
function test2(x: Bar) {
x.a;
x.b;
x.c;
x.d;
x.e;
x.f;
x.g;
let f1 = x.f();
let g1 = x.g && x.g();
let g2 = x.g ? x.g() : 0;
let h1 = x.h && x.h();
let h2 = x.h ? x.h() : 0;
}
class Base {
a?: number;
f?(): number;
}
class Derived extends Base {
a = 1;
f(): number { return 1; }
}
@@ -0,0 +1,68 @@
// @strictNullChecks: true
// @declaration: true
function error(message: string) {
throw new Error(message);
}
function fail() {
return error("Something failed");
}
function infiniteLoop() {
while (true) {
}
}
function move1(direction: "up" | "down") {
switch (direction) {
case "up":
return 1;
case "down":
return -1;
}
return error("Should never get here");
}
function move2(direction: "up" | "down") {
return direction === "up" ? 1 :
direction === "down" ? -1 :
error("Should never get here");
}
function check<T>(x: T | undefined) {
return x || error("Undefined value");
}
function f1(x: string | number) {
if (typeof x === "boolean") {
x; // never
}
}
function f2(x: string | number) {
while (true) {
if (typeof x === "boolean") {
return x; // never
}
}
}
function failOrThrow(shouldFail: boolean) {
if (shouldFail) {
return fail();
}
throw new Error();
}
function test(cb: () => string) {
let s = cb();
return s;
}
let errorCallback = () => error("Error callback");
test(() => "hello");
test(() => fail());
test(() => { throw new Error(); })
test(errorCallback);
@@ -0,0 +1,20 @@
function f1() {
let x: never;
x = 1;
x = "abc";
x = false;
x = undefined;
x = null;
x = {};
}
function f2(): never {
return;
}
function f3(): never {
return 1;
}
function f4(): never {
}
@@ -0,0 +1,22 @@
// @strictNullChecks: true
function f1() {
let x: never;
x = 1;
x = "abc";
x = false;
x = undefined;
x = null;
x = {};
}
function f2(): never {
return;
}
function f3(): never {
return 1;
}
function f4(): never {
}
@@ -9,7 +9,7 @@ interface I {
}
class C {
x?: number; // error
x?: number; // ok
}
interface I2<T> {
@@ -17,7 +17,7 @@ interface I2<T> {
}
class C2<T> {
x?: T; // error
x?: T; // ok
}
var b = {
@@ -0,0 +1,30 @@
/// <reference path="fourslash.ts"/>
////class A {}
////const B = class C {
//// public x;
////};
////function D() {}
////const E = function F() {}
////console.log(function() {}, class {}); // Expression with no name should have no effect.
////console.log(function inner() {});
////String(function fun() { class cls { public prop; } }));
function navExact(name: string, kind: string) {
verify.navigationItemsListContains(name, kind, name, "exact");
}
navExact("A", "class");
navExact("B", "const");
navExact("C", "class");
navExact("x", "property");
navExact("D", "function");
navExact("E", "const");
navExact("F", "function")
navExact("inner", "function");
navExact("fun", "function");
navExact("cls", "class");
navExact("prop", "property");
@@ -5,4 +5,4 @@
goTo.marker();
edit.deleteAtCaret('class Bar { }'.length);
verify.getScriptLexicalStructureListContains('Foo', 'enum', 'tests/cases/fourslash/deleteClassWithEnumPresent.ts', '');
verify.navigationBarContains('Foo', 'enum', 'tests/cases/fourslash/deleteClassWithEnumPresent.ts', '');
@@ -0,0 +1,45 @@
///<reference path='fourslash.ts' />
////export let Things = [{
//// Hat: 'hat', /*1*/
//// Glove: 'glove',
//// Umbrella: 'umbrella'
////},{/*2*/
//// Salad: 'salad', /*3*/
//// Burrito: 'burrito',
//// Pie: 'pie'
//// }];/*4*/
////
////export let Things2 = [
////{
//// Hat: 'hat', /*5*/
//// Glove: 'glove',
//// Umbrella: 'umbrella'
////}/*6*/,
//// {
//// Salad: 'salad', /*7*/
//// Burrito: ['burrito', 'carne asada', 'tinga de res', 'tinga de pollo'], /*8*/
//// Pie: 'pie'
//// }];/*9*/
format.document();
goTo.marker("1");
verify.currentLineContentIs(" Hat: 'hat',");
goTo.marker("2");
verify.currentLineContentIs("}, {");
goTo.marker("3");
verify.currentLineContentIs(" Salad: 'salad',");
goTo.marker("4");
verify.currentLineContentIs("}];");
goTo.marker("5");
verify.currentLineContentIs(" Hat: 'hat',");
goTo.marker("6");
verify.currentLineContentIs(" },");
goTo.marker("7");
verify.currentLineContentIs(" Salad: 'salad',");
goTo.marker("8");
verify.currentLineContentIs(" Burrito: ['burrito', 'carne asada', 'tinga de res', 'tinga de pollo'],");
goTo.marker("9");
verify.currentLineContentIs(" }];");
+4 -2
View File
@@ -175,8 +175,9 @@ declare namespace FourSlashInterface {
DocCommentTemplate(expectedText: string, expectedOffset: number, empty?: boolean): void;
noDocCommentTemplate(): void;
getScriptLexicalStructureListCount(count: number): void;
getScriptLexicalStructureListContains(name: string, kind: string, fileName?: string, parentName?: string, isAdditionalSpan?: boolean, markerPosition?: number): void;
navigationBarCount(count: number): void;
navigationBarContains(name: string, kind: string, fileName?: string, parentName?: string, isAdditionalSpan?: boolean, markerPosition?: number): void;
navigationBarChildItem(parent: string, text: string, kind: string): void;
navigationItemsListCount(count: number, searchValue: string, matchKind?: string): void;
navigationItemsListContains(name: string, kind: string, searchValue: string, matchKind: string, fileName?: string, parentName?: string): void;
occurrencesAtPositionContains(range: Range, isWriteAccess?: boolean): void;
@@ -236,6 +237,7 @@ declare namespace FourSlashInterface {
printBreakpointAtCurrentLocation(): void;
printNameOrDottedNameSpans(pos: number): void;
printErrorList(): void;
printNavigationBar(): void;
printNavigationItems(searchValue?: string): void;
printScriptLexicalStructureItems(): void;
printReferences(): void;
@@ -0,0 +1,11 @@
/// <reference path="fourslash.ts" />
////class C {
//// foo;
//// ["bar"]: string;
////}
verify.navigationBarCount(3);
verify.navigationBarContains("C", "class");
verify.navigationBarChildItem("C", "[\"bar\"]", "property");
verify.navigationBarChildItem("C", "foo", "property");
+11
View File
@@ -0,0 +1,11 @@
/// <reference path="fourslash.ts" />
////export function f() {}
//////foo
/////**///moo
goTo.marker();
verify.quickInfoIs("");
verify.verifyDefinitionsName("", "");
verify.typeDefinitionCountIs(0);
verify.referencesCountIs(0);
+1 -1
View File
@@ -3,7 +3,7 @@
//// {| "itemName": "c", "kind": "const", "parentName": "" |}const c = 0;
test.markers().forEach(marker => {
verify.getScriptLexicalStructureListContains(
verify.navigationBarContains(
marker.data.itemName,
marker.data.kind,
marker.fileName,
@@ -29,7 +29,7 @@
test.markers().forEach(marker => {
if (marker.data) {
verify.getScriptLexicalStructureListContains(
verify.navigationBarContains(
marker.data.itemName,
marker.data.kind,
marker.fileName,
@@ -38,4 +38,4 @@ test.markers().forEach(marker => {
marker.position);
}
});
verify.getScriptLexicalStructureListCount(12);
verify.navigationBarCount(12);
@@ -14,7 +14,7 @@
test.markers().forEach(marker => {
goTo.file(marker.fileName);
verify.getScriptLexicalStructureListContains(
verify.navigationBarContains(
marker.data.itemName,
marker.data.kind,
marker.fileName,
+1 -1
View File
@@ -3,7 +3,7 @@
//// {| "itemName": "c", "kind": "let", "parentName": "" |}let c = 0;
test.markers().forEach(marker => {
verify.getScriptLexicalStructureListContains(
verify.navigationBarContains(
marker.data.itemName,
marker.data.kind,
marker.fileName,
@@ -6,16 +6,16 @@
////const bar1, [c, d]
////var {e, x: [f, g]} = {a:1, x:[]};
verify.getScriptLexicalStructureListCount(12); // global (1) + variable declarations (4) + binding patterns (7)
verify.getScriptLexicalStructureListContains("foo", "var");
verify.getScriptLexicalStructureListContains("bar", "var");
verify.getScriptLexicalStructureListContains("foo1", "let")
verify.getScriptLexicalStructureListContains("a", "let");
verify.getScriptLexicalStructureListContains("b", "let");
verify.getScriptLexicalStructureListContains("bar1", "const");
verify.getScriptLexicalStructureListContains("c", "const");
verify.getScriptLexicalStructureListContains("d", "const");
verify.getScriptLexicalStructureListContains("e", "var");
verify.getScriptLexicalStructureListContains("f", "var");
verify.getScriptLexicalStructureListContains("g", "var");
verify.navigationBarCount(12); // global (1) + variable declarations (4) + binding patterns (7)
verify.navigationBarContains("foo", "var");
verify.navigationBarContains("bar", "var");
verify.navigationBarContains("foo1", "let")
verify.navigationBarContains("a", "let");
verify.navigationBarContains("b", "let");
verify.navigationBarContains("bar1", "const");
verify.navigationBarContains("c", "const");
verify.navigationBarContains("d", "const");
verify.navigationBarContains("e", "var");
verify.navigationBarContains("f", "var");
verify.navigationBarContains("g", "var");
@@ -11,4 +11,4 @@
//// }
////}
verify.getScriptLexicalStructureListCount(6); // 2x(class + field + constructor)
verify.navigationBarCount(6); // 2x(class + field + constructor)
@@ -5,8 +5,8 @@
//// }
////}
verify.getScriptLexicalStructureListContains("Test", "class");
verify.getScriptLexicalStructureListContains("constructor", "constructor");
verify.navigationBarContains("Test", "class");
verify.navigationBarContains("constructor", "constructor");
// no other items
verify.getScriptLexicalStructureListCount(2);
verify.navigationBarCount(2);
@@ -11,8 +11,8 @@
test.markers().forEach((marker) => {
if (marker.data) {
verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
}
});
verify.getScriptLexicalStructureListCount(4);
verify.navigationBarCount(4);
@@ -17,7 +17,7 @@
////}
test.markers().forEach((marker) => {
verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
});
verify.getScriptLexicalStructureListCount(8); // 4 functions + global. Note: there are 8 because of the functions show up at the top level and as child items.
verify.navigationBarCount(8); // 4 functions + global. Note: there are 8 because of the functions show up at the top level and as child items.
@@ -6,7 +6,7 @@
////}
test.markers().forEach((marker) => {
verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
});
verify.getScriptLexicalStructureListCount(3); // <global> and 'f'.
verify.navigationBarCount(3); // <global> and 'f'.
@@ -7,7 +7,7 @@
////}
test.markers().forEach((marker) => {
verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
});
verify.getScriptLexicalStructureListCount(3); // <global> and 'f'
verify.navigationBarCount(3); // <global> and 'f'
@@ -18,8 +18,8 @@
test.markers().forEach((marker) => {
if (marker.data) {
verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
}
});
verify.getScriptLexicalStructureListCount(9);
verify.navigationBarCount(9);
@@ -35,8 +35,8 @@
////}
test.markers().forEach((marker) => {
verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
});
// no other items
verify.getScriptLexicalStructureListCount(17);
verify.navigationBarCount(17);
@@ -45,8 +45,8 @@
test.markers().forEach((marker) => {
if (marker.data) {
verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
}
});
verify.getScriptLexicalStructureListCount(23);
verify.navigationBarCount(23);
@@ -8,5 +8,5 @@ edit.insertLine("module A");
edit.insert("export class ");
// should not crash
verify.getScriptLexicalStructureListCount(2);
verify.navigationBarCount(2);
@@ -30,15 +30,15 @@
////}
goTo.marker("file1");
verify.getScriptLexicalStructureListCount(0);
verify.navigationBarCount(0);
goTo.marker("file2");
verify.getScriptLexicalStructureListContains("<global>", "module");
verify.getScriptLexicalStructureListContains("x", "var");
verify.getScriptLexicalStructureListCount(2);
verify.navigationBarContains("<global>", "module");
verify.navigationBarContains("x", "var");
verify.navigationBarCount(2);
goTo.marker("file3");
verify.getScriptLexicalStructureListContains("<global>", "module");
verify.getScriptLexicalStructureListContains("foo", "function");
verify.getScriptLexicalStructureListContains("bar", "function");
verify.getScriptLexicalStructureListCount(5);
verify.navigationBarContains("<global>", "module");
verify.navigationBarContains("foo", "function");
verify.navigationBarContains("bar", "function");
verify.navigationBarCount(5);
@@ -5,7 +5,7 @@
////}
test.markers().forEach((marker) => {
verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
});
verify.getScriptLexicalStructureListCount(2); // external module node + class + property
verify.navigationBarCount(2); // external module node + class + property
@@ -9,7 +9,7 @@
////export var x: number;
test.markers().forEach((marker) => {
verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
});
verify.getScriptLexicalStructureListCount(4); // external module node + variable in module + class + property
verify.navigationBarCount(4); // external module node + variable in module + class + property
@@ -9,7 +9,7 @@
////export var x: number;
test.markers().forEach((marker) => {
verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
});
verify.getScriptLexicalStructureListCount(4); // external module node + variable in module + class + property
verify.navigationBarCount(4); // external module node + variable in module + class + property
@@ -19,12 +19,12 @@
//// export var z = 0;
////}
goTo.marker("file1");
verify.getScriptLexicalStructureListContains("Module1", "module");
verify.getScriptLexicalStructureListContains("x", "var");
verify.navigationBarContains("Module1", "module");
verify.navigationBarContains("x", "var");
// nothing else should show up
verify.getScriptLexicalStructureListCount(2);
verify.navigationBarCount(2);
goTo.marker("file2");
verify.getScriptLexicalStructureListContains("Module1.SubModule", "module");
verify.getScriptLexicalStructureListContains("y", "var");
verify.getScriptLexicalStructureListCount(2);
verify.navigationBarContains("Module1.SubModule", "module");
verify.navigationBarContains("y", "var");
verify.navigationBarCount(2);
@@ -9,8 +9,8 @@
test.markers().forEach((marker) => {
verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
});
/// Only have two named elements.
verify.getScriptLexicalStructureListCount(2);
verify.navigationBarCount(2);
@@ -8,4 +8,4 @@
// The class is unnamed, so its method is not included either.
verify.getScriptLexicalStructureListCount(2);
verify.navigationBarCount(2);
@@ -39,10 +39,10 @@
test.markers().forEach((marker) => {
verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
});
/// We have 8 module keywords, and 4 var keywords.
/// The declarations of A.B.C.x do not get merged, so the 4 vars are independent.
/// The two 'A' modules, however, do get merged, so in reality we have 7 modules.
verify.getScriptLexicalStructureListCount(11);
verify.navigationBarCount(11);
@@ -35,7 +35,7 @@
test.markers().forEach((marker) => {
verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
});
verify.getScriptLexicalStructureListCount(9); // interface w/ 2 properties, class w/ 2 properties, 3 modules
verify.navigationBarCount(9); // interface w/ 2 properties, class w/ 2 properties, 3 modules
@@ -6,10 +6,10 @@
//// }
////}
verify.getScriptLexicalStructureListContains("List", "class");
verify.getScriptLexicalStructureListContains("constructor", "constructor");
verify.getScriptLexicalStructureListContains("a", "property");
verify.getScriptLexicalStructureListContains("b", "property");
verify.navigationBarContains("List", "class");
verify.navigationBarContains("constructor", "constructor");
verify.navigationBarContains("a", "property");
verify.navigationBarContains("b", "property");
// no other items
verify.getScriptLexicalStructureListCount(4);
verify.navigationBarCount(4);
@@ -11,7 +11,7 @@
////}
test.markers().forEach(marker => {
verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
});
verify.getScriptLexicalStructureListCount(test.markers().length);
verify.navigationBarCount(test.markers().length);
@@ -9,7 +9,7 @@
////}
test.markers().forEach(marker => {
verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
});
verify.getScriptLexicalStructureListCount(test.markers().length);
verify.navigationBarCount(test.markers().length);
@@ -7,7 +7,7 @@
////}
test.markers().forEach(marker => {
verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
});
verify.getScriptLexicalStructureListCount(test.markers().length);
verify.navigationBarCount(test.markers().length);
@@ -0,0 +1,6 @@
/// <reference path="fourslash.ts"/>
////type T = number | string;
verify.navigationBarCount(1);
verify.navigationBarContains("T", "type");
+2 -2
View File
@@ -45,8 +45,8 @@
test.markers().forEach((marker) => {
if (marker.data) {
verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
verify.navigationBarContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName);
}
});
verify.getScriptLexicalStructureListCount(23);
verify.navigationBarCount(23);
@@ -3,7 +3,7 @@
//// {| "itemName": "c", "kind": "const", "parentName": "" |}const c = 0;
test.markers().forEach(marker => {
verify.getScriptLexicalStructureListContains(
verify.navigationBarContains(
marker.data.itemName,
marker.data.kind,
marker.fileName,
@@ -3,7 +3,7 @@
//// {| "itemName": "c", "kind": "const", "parentName": "" |}const c = 0;
test.markers().forEach(marker => {
verify.getScriptLexicalStructureListContains(
verify.navigationBarContains(
marker.data.itemName,
marker.data.kind,
marker.fileName,