Merge branch 'master' into dev/aozgaa/tsserverVersion

This commit is contained in:
Arthur Ozga 2017-12-06 14:02:30 -08:00
commit 03e93d832e
98 changed files with 4602 additions and 1577 deletions

View file

@ -795,7 +795,7 @@ compileFile(
/*prereqs*/[builtLocalDirectory, tscFile, tsserverLibraryFile].concat(libraryTargets).concat(servicesSources).concat(harnessSources),
/*prefixes*/[],
/*useBuiltCompiler:*/ true,
/*opts*/ { types: ["node", "mocha", "chai"], lib: "es6" });
/*opts*/ { types: ["node", "mocha"], lib: "es6" });
var internalTests = "internal/";

567
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -30,7 +30,6 @@
},
"devDependencies": {
"@types/browserify": "latest",
"@types/chai": "latest",
"@types/colors": "latest",
"@types/convert-source-map": "latest",
"@types/del": "latest",
@ -53,7 +52,6 @@
"xml2js": "^0.4.19",
"browser-resolve": "^1.11.2",
"browserify": "latest",
"chai": "latest",
"convert-source-map": "latest",
"del": "latest",
"gulp": "3.X",

View file

@ -749,6 +749,10 @@ namespace ts {
return expr1.kind === SyntaxKind.TypeOfExpression && isNarrowableOperand((<TypeOfExpression>expr1).expression) && expr2.kind === SyntaxKind.StringLiteral;
}
function isNarrowableInOperands(left: Expression, right: Expression) {
return left.kind === SyntaxKind.StringLiteral && isNarrowingExpression(right);
}
function isNarrowingBinaryExpression(expr: BinaryExpression) {
switch (expr.operatorToken.kind) {
case SyntaxKind.EqualsToken:
@ -761,6 +765,8 @@ namespace ts {
isNarrowingTypeofOperands(expr.right, expr.left) || isNarrowingTypeofOperands(expr.left, expr.right);
case SyntaxKind.InstanceOfKeyword:
return isNarrowableOperand(expr.left);
case SyntaxKind.InKeyword:
return isNarrowableInOperands(expr.left, expr.right);
case SyntaxKind.CommaToken:
return isNarrowingExpression(expr.right);
}

View file

@ -468,9 +468,9 @@ namespace ts {
}
function getReferencedByPaths(referencedFilePath: Path) {
return mapDefinedIter(references.entries(), ([filePath, referencesInFile]) =>
return arrayFrom(mapDefinedIterator(references.entries(), ([filePath, referencesInFile]) =>
referencesInFile.has(referencedFilePath) ? filePath as Path : undefined
);
));
}
function getFilesAffectedByUpdatedShape(program: Program, sourceFile: SourceFile): ReadonlyArray<SourceFile> {
@ -504,7 +504,7 @@ namespace ts {
}
// Return array of values that needs emit
return flatMapIter(seenFileNamesMap.values(), value => value);
return arrayFrom(mapDefinedIterator(seenFileNamesMap.values(), value => value));
}
}
}

View file

@ -210,7 +210,18 @@ namespace ts {
getEmitResolver,
getExportsOfModule: getExportsOfModuleAsArray,
getExportsAndPropertiesOfModule,
getSymbolWalker: createGetSymbolWalker(getRestTypeOfSignature, getReturnTypeOfSignature, getBaseTypes, resolveStructuredTypeMembers, getTypeOfSymbol, getResolvedSymbol, getIndexTypeOfStructuredType, getConstraintFromTypeParameter, getFirstIdentifier),
getSymbolWalker: createGetSymbolWalker(
getRestTypeOfSignature,
getTypePredicateOfSignature,
getReturnTypeOfSignature,
getBaseTypes,
resolveStructuredTypeMembers,
getTypeOfSymbol,
getResolvedSymbol,
getIndexTypeOfStructuredType,
getConstraintFromTypeParameter,
getFirstIdentifier,
),
getAmbientModules,
getAllAttributesTypeFromJsxOpeningLikeElement: node => {
node = getParseTreeNode(node, isJsxOpeningLikeElement);
@ -312,10 +323,12 @@ namespace ts {
markerSubType.constraint = markerSuperType;
const markerOtherType = <TypeParameter>createType(TypeFlags.TypeParameter);
const anySignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
const unknownSignature = createSignature(undefined, undefined, undefined, emptyArray, unknownType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
const resolvingSignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
const silentNeverSignature = createSignature(undefined, undefined, undefined, emptyArray, silentNeverType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
const noTypePredicate = createIdentifierTypePredicate("<<unresolved>>", 0, anyType);
const anySignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
const unknownSignature = createSignature(undefined, undefined, undefined, emptyArray, unknownType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
const resolvingSignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
const silentNeverSignature = createSignature(undefined, undefined, undefined, emptyArray, silentNeverType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
const enumNumberIndexInfo = createIndexInfo(stringType, /*isReadonly*/ true);
const jsObjectLiteralIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
@ -1007,7 +1020,7 @@ namespace ts {
// It's an external module. First see if the module has an export default and if the local
// name of that export default matches.
if (result = moduleExports.get("default" as __String)) {
if (result = moduleExports.get(InternalSymbolName.Default)) {
const localSymbol = getLocalSymbolForExportDefault(result);
if (localSymbol && (result.flags & meaning) && localSymbol.escapedName === name) {
break loop;
@ -1461,8 +1474,8 @@ namespace ts {
else {
const exportValue = moduleSymbol.exports.get("export=" as __String);
exportDefaultSymbol = exportValue
? getPropertyOfType(getTypeOfSymbol(exportValue), "default" as __String)
: resolveSymbol(moduleSymbol.exports.get("default" as __String), dontResolveAlias);
? getPropertyOfType(getTypeOfSymbol(exportValue), InternalSymbolName.Default)
: resolveSymbol(moduleSymbol.exports.get(InternalSymbolName.Default), dontResolveAlias);
}
if (!exportDefaultSymbol && !allowSyntheticDefaultImports) {
@ -1551,7 +1564,7 @@ namespace ts {
symbolFromVariable = resolveSymbol(symbolFromVariable, dontResolveAlias);
let symbolFromModule = getExportOfModule(targetSymbol, name.escapedText, dontResolveAlias);
// If the export member we're looking for is default, and there is no real default but allowSyntheticDefaultImports is on, return the entire module as the default
if (!symbolFromModule && allowSyntheticDefaultImports && name.escapedText === "default") {
if (!symbolFromModule && allowSyntheticDefaultImports && name.escapedText === InternalSymbolName.Default) {
symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
}
const symbol = symbolFromModule && symbolFromVariable ?
@ -1938,7 +1951,7 @@ namespace ts {
function extendExportSymbols(target: SymbolTable, source: SymbolTable | undefined, lookupTable?: ExportCollisionTrackerTable, exportNode?: ExportDeclaration) {
if (!source) return;
source.forEach((sourceSymbol, id) => {
if (id === "default") return;
if (id === InternalSymbolName.Default) return;
const targetSymbol = target.get(id);
if (!targetSymbol) {
@ -2926,8 +2939,8 @@ namespace ts {
parameters.unshift(thisParameter);
}
let returnTypeNode: TypeNode;
if (signature.typePredicate) {
const typePredicate = signature.typePredicate;
const typePredicate = getTypePredicateOfSignature(signature);
if (typePredicate) {
const parameterName = typePredicate.kind === TypePredicateKind.Identifier ?
setEmitFlags(createIdentifier((<IdentifierTypePredicate>typePredicate).parameterName), EmitFlags.NoAsciiEscaping) :
createThisTypeNode();
@ -3208,7 +3221,7 @@ namespace ts {
* ensuring that any names written with literals use element accesses.
*/
function appendPropertyOrElementAccessForSymbol(symbol: Symbol, writer: SymbolWriter): void {
const symbolName = symbol.escapedName === "default" ? "default" : getNameOfSymbolAsWritten(symbol);
const symbolName = symbol.escapedName === InternalSymbolName.Default ? InternalSymbolName.Default : getNameOfSymbolAsWritten(symbol);
const firstChar = symbolName.charCodeAt(0);
const needsElementAccess = !isIdentifierStart(firstChar, languageVersion);
@ -3887,8 +3900,9 @@ namespace ts {
}
writeSpace(writer);
if (signature.typePredicate) {
buildTypePredicateDisplay(signature.typePredicate, writer, enclosingDeclaration, flags, symbolStack);
const typePredicate = getTypePredicateOfSignature(signature);
if (typePredicate) {
buildTypePredicateDisplay(typePredicate, writer, enclosingDeclaration, flags, symbolStack);
}
else {
buildTypeDisplay(returnType, writer, enclosingDeclaration, flags, symbolStack);
@ -5783,15 +5797,24 @@ namespace ts {
resolveObjectTypeMembers(type, source, typeParameters, typeArguments);
}
function createSignature(declaration: SignatureDeclaration, typeParameters: TypeParameter[], thisParameter: Symbol | undefined, parameters: Symbol[],
resolvedReturnType: Type, typePredicate: TypePredicate, minArgumentCount: number, hasRestParameter: boolean, hasLiteralTypes: boolean): Signature {
function createSignature(
declaration: SignatureDeclaration,
typeParameters: TypeParameter[],
thisParameter: Symbol | undefined,
parameters: Symbol[],
resolvedReturnType: Type | undefined,
resolvedTypePredicate: TypePredicate | undefined,
minArgumentCount: number,
hasRestParameter: boolean,
hasLiteralTypes: boolean,
): Signature {
const sig = new Signature(checker);
sig.declaration = declaration;
sig.typeParameters = typeParameters;
sig.parameters = parameters;
sig.thisParameter = thisParameter;
sig.resolvedReturnType = resolvedReturnType;
sig.typePredicate = typePredicate;
sig.resolvedTypePredicate = resolvedTypePredicate;
sig.minArgumentCount = minArgumentCount;
sig.hasRestParameter = hasRestParameter;
sig.hasLiteralTypes = hasLiteralTypes;
@ -5799,15 +5822,15 @@ namespace ts {
}
function cloneSignature(sig: Signature): Signature {
return createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, sig.resolvedReturnType,
sig.typePredicate, sig.minArgumentCount, sig.hasRestParameter, sig.hasLiteralTypes);
return createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, /*resolvedReturnType*/ undefined,
/*resolvedTypePredicate*/ undefined, sig.minArgumentCount, sig.hasRestParameter, sig.hasLiteralTypes);
}
function getDefaultConstructSignatures(classType: InterfaceType): Signature[] {
const baseConstructorType = getBaseConstructorTypeOfClass(classType);
const baseSignatures = getSignaturesOfType(baseConstructorType, SignatureKind.Construct);
if (baseSignatures.length === 0) {
return [createSignature(undefined, classType.localTypeParameters, undefined, emptyArray, classType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false)];
return [createSignature(undefined, classType.localTypeParameters, undefined, emptyArray, classType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false)];
}
const baseTypeNode = getBaseTypeNodeOfClass(classType);
const isJavaScript = isInJavaScriptFile(baseTypeNode);
@ -5817,7 +5840,7 @@ namespace ts {
for (const baseSig of baseSignatures) {
const minTypeArgumentCount = getMinTypeArgumentCount(baseSig.typeParameters);
const typeParamCount = length(baseSig.typeParameters);
if (isJavaScript || (typeArgCount >= minTypeArgumentCount && typeArgCount <= typeParamCount)) {
if (isJavaScript || typeArgCount >= minTypeArgumentCount && typeArgCount <= typeParamCount) {
const sig = typeParamCount ? createSignatureInstantiation(baseSig, fillMissingTypeArguments(typeArguments, baseSig.typeParameters, minTypeArgumentCount, isJavaScript)) : cloneSignature(baseSig);
sig.typeParameters = classType.localTypeParameters;
sig.resolvedReturnType = classType;
@ -5877,13 +5900,13 @@ namespace ts {
let s = signature;
// Union the result types when more than one signature matches
if (unionSignatures.length > 1) {
s = cloneSignature(signature);
let thisParameter = signature.thisParameter;
if (forEach(unionSignatures, sig => sig.thisParameter)) {
const thisType = getUnionType(map(unionSignatures, sig => getTypeOfSymbol(sig.thisParameter) || anyType), /*subtypeReduction*/ true);
s.thisParameter = createSymbolWithType(signature.thisParameter, thisType);
thisParameter = createSymbolWithType(signature.thisParameter, thisType);
}
// Clear resolved return type we possibly got from cloneSignature
s.resolvedReturnType = undefined;
s = cloneSignature(signature);
s.thisParameter = thisParameter;
s.unionSignatures = unionSignatures;
}
(result || (result = [])).push(s);
@ -6434,14 +6457,13 @@ namespace ts {
function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: __String): Symbol {
let props: Symbol[];
const types = containingType.types;
const isUnion = containingType.flags & TypeFlags.Union;
const excludeModifiers = isUnion ? ModifierFlags.NonPublicAccessibilityModifier : 0;
// Flags we want to propagate to the result if they exist in all source symbols
let commonFlags = isUnion ? SymbolFlags.None : SymbolFlags.Optional;
let syntheticFlag = CheckFlags.SyntheticMethod;
let checkFlags = 0;
for (const current of types) {
for (const current of containingType.types) {
const type = getApparentType(current);
if (type !== unknownType) {
const prop = getPropertyOfType(type, name);
@ -6674,22 +6696,26 @@ namespace ts {
function createTypePredicateFromTypePredicateNode(node: TypePredicateNode): IdentifierTypePredicate | ThisTypePredicate {
const { parameterName } = node;
const type = getTypeFromTypeNode(node.type);
if (parameterName.kind === SyntaxKind.Identifier) {
return {
kind: TypePredicateKind.Identifier,
parameterName: parameterName ? parameterName.escapedText : undefined,
parameterIndex: parameterName ? getTypePredicateParameterIndex((node.parent as SignatureDeclaration).parameters, parameterName) : undefined,
type: getTypeFromTypeNode(node.type)
} as IdentifierTypePredicate;
return createIdentifierTypePredicate(
parameterName && parameterName.escapedText as string, // TODO: GH#18217
parameterName && getTypePredicateParameterIndex((node.parent as SignatureDeclaration).parameters, parameterName),
type);
}
else {
return {
kind: TypePredicateKind.This,
type: getTypeFromTypeNode(node.type)
};
return createThisTypePredicate(type);
}
}
function createIdentifierTypePredicate(parameterName: string | undefined, parameterIndex: number | undefined, type: Type): IdentifierTypePredicate {
return { kind: TypePredicateKind.Identifier, parameterName, parameterIndex, type };
}
function createThisTypePredicate(type: Type): ThisTypePredicate {
return { kind: TypePredicateKind.This, type };
}
/**
* Gets the minimum number of type arguments needed to satisfy all non-optional type
* parameters.
@ -6805,11 +6831,8 @@ namespace ts {
: undefined;
const typeParameters = classType ? classType.localTypeParameters : getTypeParametersFromDeclaration(declaration);
const returnType = getSignatureReturnTypeFromDeclaration(declaration, isJSConstructSignature, classType);
const typePredicate = declaration.type && declaration.type.kind === SyntaxKind.TypePredicate ?
createTypePredicateFromTypePredicateNode(declaration.type as TypePredicateNode) :
undefined;
const hasRestLikeParameter = hasRestParameter(declaration) || isInJavaScriptFile(declaration) && maybeAddJsSyntheticRestParameter(declaration, parameters);
links.resolvedSignature = createSignature(declaration, typeParameters, thisParameter, parameters, returnType, typePredicate, minArgumentCount, hasRestLikeParameter, hasLiteralTypes);
links.resolvedSignature = createSignature(declaration, typeParameters, thisParameter, parameters, returnType, /*resolvedTypePredicate*/ undefined, minArgumentCount, hasRestLikeParameter, hasLiteralTypes);
}
return links.resolvedSignature;
}
@ -6946,6 +6969,30 @@ namespace ts {
}
}
function signatureHasTypePredicate(signature: Signature): boolean {
return getTypePredicateOfSignature(signature) !== undefined;
}
function getTypePredicateOfSignature(signature: Signature): TypePredicate | undefined {
if (!signature.resolvedTypePredicate) {
if (signature.target) {
const targetTypePredicate = getTypePredicateOfSignature(signature.target);
signature.resolvedTypePredicate = targetTypePredicate ? instantiateTypePredicate(targetTypePredicate, signature.mapper) : noTypePredicate;
}
else if (signature.unionSignatures) {
signature.resolvedTypePredicate = getUnionTypePredicate(signature.unionSignatures) || noTypePredicate;
}
else {
const declaration = signature.declaration;
signature.resolvedTypePredicate = declaration && declaration.type && declaration.type.kind === SyntaxKind.TypePredicate ?
createTypePredicateFromTypePredicateNode(declaration.type as TypePredicateNode) :
noTypePredicate;
}
Debug.assert(!!signature.resolvedTypePredicate);
}
return signature.resolvedTypePredicate === noTypePredicate ? undefined : signature.resolvedTypePredicate;
}
function getReturnTypeOfSignature(signature: Signature): Type {
if (!signature.resolvedReturnType) {
if (!pushTypeResolution(signature, TypeSystemPropertyName.ResolvedReturnType)) {
@ -7824,6 +7871,42 @@ namespace ts {
return getUnionTypeFromSortedList(typeSet, aliasSymbol, aliasTypeArguments);
}
function getUnionTypePredicate(signatures: ReadonlyArray<Signature>): TypePredicate {
let first: TypePredicate | undefined;
const types: Type[] = [];
for (const sig of signatures) {
const pred = getTypePredicateOfSignature(sig);
if (!pred) {
continue;
}
if (first) {
if (!typePredicateKindsMatch(first, pred)) {
// No common type predicate.
return undefined;
}
}
else {
first = pred;
}
types.push(pred.type);
}
if (!first) {
// No union signatures had a type predicate.
return undefined;
}
const unionType = getUnionType(types);
return isIdentifierTypePredicate(first)
? createIdentifierTypePredicate(first.parameterName, first.parameterIndex, unionType)
: createThisTypePredicate(unionType);
}
function typePredicateKindsMatch(a: TypePredicate, b: TypePredicate): boolean {
return isIdentifierTypePredicate(a)
? isIdentifierTypePredicate(b) && a.parameterIndex === b.parameterIndex
: !isIdentifierTypePredicate(b);
}
// This function assumes the constituent type list is sorted and deduplicated.
function getUnionTypeFromSortedList(types: Type[], aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
if (types.length === 0) {
@ -8574,7 +8657,7 @@ namespace ts {
return result;
}
function cloneTypePredicate(predicate: TypePredicate, mapper: TypeMapper): ThisTypePredicate | IdentifierTypePredicate {
function instantiateTypePredicate(predicate: TypePredicate, mapper: TypeMapper): ThisTypePredicate | IdentifierTypePredicate {
if (isIdentifierTypePredicate(predicate)) {
return {
kind: TypePredicateKind.Identifier,
@ -8593,7 +8676,6 @@ namespace ts {
function instantiateSignature(signature: Signature, mapper: TypeMapper, eraseTypeParameters?: boolean): Signature {
let freshTypeParameters: TypeParameter[];
let freshTypePredicate: TypePredicate;
if (signature.typeParameters && !eraseTypeParameters) {
// First create a fresh set of type parameters, then include a mapping from the old to the
// new type parameters in the mapper function. Finally store this mapper in the new type
@ -8604,15 +8686,17 @@ namespace ts {
tp.mapper = mapper;
}
}
if (signature.typePredicate) {
freshTypePredicate = cloneTypePredicate(signature.typePredicate, mapper);
}
// Don't compute resolvedReturnType and resolvedTypePredicate now,
// because using `mapper` now could trigger inferences to become fixed. (See `createInferenceContext`.)
// See GH#17600.
const result = createSignature(signature.declaration, freshTypeParameters,
signature.thisParameter && instantiateSymbol(signature.thisParameter, mapper),
instantiateList(signature.parameters, mapper, instantiateSymbol),
/*resolvedReturnType*/ undefined,
freshTypePredicate,
signature.minArgumentCount, signature.hasRestParameter, signature.hasLiteralTypes);
/*resolvedTypePredicate*/ undefined,
signature.minArgumentCount,
signature.hasRestParameter,
signature.hasLiteralTypes);
result.target = signature;
result.mapper = mapper;
return result;
@ -9006,7 +9090,7 @@ namespace ts {
// with respect to T.
const sourceSig = callbackCheck ? undefined : getSingleCallSignature(getNonNullableType(sourceType));
const targetSig = callbackCheck ? undefined : getSingleCallSignature(getNonNullableType(targetType));
const callbacks = sourceSig && targetSig && !sourceSig.typePredicate && !targetSig.typePredicate &&
const callbacks = sourceSig && targetSig && !signatureHasTypePredicate(sourceSig) && !signatureHasTypePredicate(targetSig) &&
(getFalsyFlags(sourceType) & TypeFlags.Nullable) === (getFalsyFlags(targetType) & TypeFlags.Nullable);
const related = callbacks ?
compareSignaturesRelated(targetSig, sourceSig, strictVariance ? CallbackCheck.Strict : CallbackCheck.Bivariant, /*ignoreReturnTypes*/ false, reportErrors, errorReporter, compareTypes) :
@ -9030,11 +9114,13 @@ namespace ts {
const sourceReturnType = getReturnTypeOfSignature(source);
// The following block preserves behavior forbidding boolean returning functions from being assignable to type guard returning functions
if (target.typePredicate) {
if (source.typePredicate) {
result &= compareTypePredicateRelatedTo(source.typePredicate, target.typePredicate, source.declaration, target.declaration, reportErrors, errorReporter, compareTypes);
const targetTypePredicate = getTypePredicateOfSignature(target);
if (targetTypePredicate) {
const sourceTypePredicate = getTypePredicateOfSignature(source);
if (sourceTypePredicate) {
result &= compareTypePredicateRelatedTo(sourceTypePredicate, targetTypePredicate, source.declaration, target.declaration, reportErrors, errorReporter, compareTypes);
}
else if (isIdentifierTypePredicate(target.typePredicate)) {
else if (isIdentifierTypePredicate(targetTypePredicate)) {
if (reportErrors) {
errorReporter(Diagnostics.Signature_0_must_be_a_type_predicate, signatureToString(source));
}
@ -10579,11 +10665,20 @@ namespace ts {
result &= related;
}
if (!ignoreReturnTypes) {
result &= compareTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
const sourceTypePredicate = getTypePredicateOfSignature(source);
const targetTypePredicate = getTypePredicateOfSignature(target);
result &= sourceTypePredicate !== undefined || targetTypePredicate !== undefined
? compareTypePredicatesIdentical(sourceTypePredicate, targetTypePredicate, compareTypes)
// If they're both type predicates their return types will both be `boolean`, so no need to compare those.
: compareTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
}
return result;
}
function compareTypePredicatesIdentical(source: TypePredicate | undefined, target: TypePredicate | undefined, compareTypes: (s: Type, t: Type) => Ternary): Ternary {
return source === undefined || target === undefined || !typePredicateKindsMatch(source, target) ? Ternary.False : compareTypes(source.type, target.type);
}
function isRestParameterIndex(signature: Signature, parameterIndex: number) {
return signature.hasRestParameter && parameterIndex >= signature.parameters.length - 1;
}
@ -11448,8 +11543,10 @@ namespace ts {
function inferFromSignature(source: Signature, target: Signature) {
forEachMatchingParameterType(source, target, inferFromContravariantTypes);
if (source.typePredicate && target.typePredicate && source.typePredicate.kind === target.typePredicate.kind) {
inferFromTypes(source.typePredicate.type, target.typePredicate.type);
const sourceTypePredicate = getTypePredicateOfSignature(source);
const targetTypePredicate = getTypePredicateOfSignature(target);
if (sourceTypePredicate && targetTypePredicate && sourceTypePredicate.kind === targetTypePredicate.kind) {
inferFromTypes(sourceTypePredicate.type, targetTypePredicate.type);
}
else {
inferFromTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
@ -12264,10 +12361,7 @@ namespace ts {
const funcType = checkNonNullExpression(node.expression);
if (funcType !== silentNeverType) {
const apparentType = getApparentType(funcType);
if (apparentType !== unknownType) {
const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call);
return !!forEach(callSignatures, sig => sig.typePredicate);
}
return apparentType !== unknownType && some(getSignaturesOfType(apparentType, SignatureKind.Call), signatureHasTypePredicate);
}
}
return false;
@ -12628,6 +12722,22 @@ namespace ts {
return type;
}
function isTypePresencePossible(type: Type, propName: __String, assumeTrue: boolean) {
const prop = getPropertyOfType(type, propName);
if (prop) {
return (prop.flags & SymbolFlags.Optional) ? true : assumeTrue;
}
return !assumeTrue;
}
function narrowByInKeyword(type: Type, literal: LiteralExpression, assumeTrue: boolean) {
if ((type.flags & (TypeFlags.Union | TypeFlags.Object)) || (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType)) {
const propName = escapeLeadingUnderscores(literal.text);
return filterType(type, t => isTypePresencePossible(t, propName, /* assumeTrue */ assumeTrue));
}
return type;
}
function narrowTypeByBinaryExpression(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type {
switch (expr.operatorToken.kind) {
case SyntaxKind.EqualsToken:
@ -12663,6 +12773,12 @@ namespace ts {
break;
case SyntaxKind.InstanceOfKeyword:
return narrowTypeByInstanceof(type, expr, assumeTrue);
case SyntaxKind.InKeyword:
const target = getReferenceCandidate(expr.right);
if (expr.left.kind === SyntaxKind.StringLiteral && isMatchingReference(reference, target)) {
return narrowByInKeyword(type, <LiteralExpression>expr.left, assumeTrue);
}
break;
case SyntaxKind.CommaToken:
return narrowType(type, expr.right, assumeTrue);
}
@ -12840,7 +12956,7 @@ namespace ts {
return type;
}
const signature = getResolvedSignature(callExpression);
const predicate = signature.typePredicate;
const predicate = getTypePredicateOfSignature(signature);
if (!predicate) {
return type;
}
@ -14251,8 +14367,6 @@ namespace ts {
let result: Signature;
if (signatureList) {
result = cloneSignature(signatureList[0]);
// Clear resolved return type we possibly got from cloneSignature
result.resolvedReturnType = undefined;
result.unionSignatures = signatureList;
}
return result;
@ -19305,7 +19419,7 @@ namespace ts {
return;
}
const typePredicate = getSignatureFromDeclaration(parent).typePredicate;
const typePredicate = getTypePredicateOfSignature(getSignatureFromDeclaration(parent));
if (!typePredicate) {
return;
}
@ -22915,6 +23029,7 @@ namespace ts {
case SyntaxKind.PlusToken: return left + right;
case SyntaxKind.MinusToken: return left - right;
case SyntaxKind.PercentToken: return left % right;
case SyntaxKind.AsteriskAsteriskToken: return left ** right;
}
}
break;

View file

@ -191,6 +191,19 @@ namespace ts {
return undefined;
}
export function firstDefinedIterator<T, U>(iter: Iterator<T>, callback: (element: T) => U | undefined): U | undefined {
while (true) {
const { value, done } = iter.next();
if (done) {
return undefined;
}
const result = callback(value);
if (result !== undefined) {
return result;
}
}
}
/**
* Iterates through the parent chain of a node and performs the callback on each parent until the callback
* returns a truthy value, then returns that value.
@ -474,22 +487,32 @@ namespace ts {
return result;
}
export function flatMapIter<T, U>(iter: Iterator<T>, mapfn: (x: T) => U | U[] | undefined): U[] {
const result: U[] = [];
while (true) {
const { value, done } = iter.next();
if (done) break;
const res = mapfn(value);
if (res) {
if (isArray(res)) {
result.push(...res);
}
else {
result.push(res);
}
}
export function flatMapIterator<T, U>(iter: Iterator<T>, mapfn: (x: T) => U[] | Iterator<U> | undefined): Iterator<U> {
const first = iter.next();
if (first.done) {
return emptyIterator;
}
let currentIter = getIterator(first.value);
return {
next() {
while (true) {
const currentRes = currentIter.next();
if (!currentRes.done) {
return currentRes;
}
const iterRes = iter.next();
if (iterRes.done) {
return iterRes;
}
currentIter = getIterator(iterRes.value);
}
},
};
function getIterator(x: T): Iterator<U> {
const res = mapfn(x);
return res === undefined ? emptyIterator : isArray(res) ? arrayIterator(res) : res;
}
return result;
}
/**
@ -537,17 +560,34 @@ namespace ts {
return result;
}
export function mapDefinedIter<T, U>(iter: Iterator<T>, mapFn: (x: T) => U | undefined): U[] {
const result: U[] = [];
while (true) {
const { value, done } = iter.next();
if (done) break;
const res = mapFn(value);
if (res !== undefined) {
result.push(res);
export function mapDefinedIterator<T, U>(iter: Iterator<T>, mapFn: (x: T) => U | undefined): Iterator<U> {
return {
next() {
while (true) {
const res = iter.next();
if (res.done) {
return res;
}
const value = mapFn(res.value);
if (value !== undefined) {
return { value, done: false };
}
}
}
}
return result;
};
}
export const emptyIterator: Iterator<never> = { next: () => ({ value: undefined as never, done: true }) };
export function singleIterator<T>(value: T): Iterator<T> {
let done = false;
return {
next() {
const wasDone = done;
done = true;
return wasDone ? { value: undefined as never, done: true } : { value, done: false };
}
};
}
/**
@ -1360,7 +1400,7 @@ namespace ts {
/**
* Tests whether a value is an array.
*/
export function isArray(value: any): value is ReadonlyArray<any> {
export function isArray(value: any): value is ReadonlyArray<{}> {
return Array.isArray ? Array.isArray(value) : value instanceof Array;
}

View file

@ -2828,6 +2828,10 @@
"category": "Message",
"code": 6030
},
"Starting compilation in watch mode...": {
"category": "Message",
"code": 6031
},
"File change detected. Starting incremental compilation...": {
"category": "Message",
"code": 6032

View file

@ -64,9 +64,9 @@ namespace ts {
return { fileName: resolved.path, packageId: resolved.packageId };
}
function createResolvedModuleWithFailedLookupLocations(resolved: Resolved | undefined, isExternalLibraryImport: boolean, failedLookupLocations: string[]): ResolvedModuleWithFailedLookupLocations {
function createResolvedModuleWithFailedLookupLocations(resolved: Resolved | undefined, originalPath: string | undefined, isExternalLibraryImport: boolean, failedLookupLocations: string[]): ResolvedModuleWithFailedLookupLocations {
return {
resolvedModule: resolved && { resolvedFileName: resolved.path, extension: resolved.extension, isExternalLibraryImport, packageId: resolved.packageId },
resolvedModule: resolved && { resolvedFileName: resolved.path, originalPath, extension: resolved.extension, isExternalLibraryImport, packageId: resolved.packageId },
failedLookupLocations
};
}
@ -732,12 +732,12 @@ namespace ts {
const result = jsOnly ? tryResolve(Extensions.JavaScript) : (tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript));
if (result && result.value) {
const { resolved, isExternalLibraryImport } = result.value;
return createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations);
const { resolved, originalPath, isExternalLibraryImport } = result.value;
return createResolvedModuleWithFailedLookupLocations(resolved, originalPath, isExternalLibraryImport, failedLookupLocations);
}
return { resolvedModule: undefined, failedLookupLocations };
function tryResolve(extensions: Extensions): SearchResult<{ resolved: Resolved, isExternalLibraryImport: boolean }> {
function tryResolve(extensions: Extensions): SearchResult<{ resolved: Resolved, originalPath?: string, isExternalLibraryImport: boolean }> {
const loader: ResolutionKindSpecificLoader = (extensions, candidate, failedLookupLocations, onlyRecordFailures, state) => nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, /*considerPackageJson*/ true);
const resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state);
if (resolved) {
@ -752,11 +752,17 @@ namespace ts {
if (!resolved) return undefined;
let resolvedValue = resolved.value;
if (!compilerOptions.preserveSymlinks) {
resolvedValue = resolvedValue && { ...resolved.value, path: realPath(resolved.value.path, host, traceEnabled), extension: resolved.value.extension };
let originalPath: string | undefined;
if (!compilerOptions.preserveSymlinks && resolvedValue) {
originalPath = resolvedValue.path;
const path = realPath(resolved.value.path, host, traceEnabled);
if (path === originalPath) {
originalPath = undefined;
}
resolvedValue = { ...resolvedValue, path };
}
// For node_modules lookups, get the real path so that multiple accesses to an `npm link`-ed module do not create duplicate files.
return { value: resolvedValue && { resolved: resolvedValue, isExternalLibraryImport: true } };
return { value: resolvedValue && { resolved: resolvedValue, originalPath, isExternalLibraryImport: true } };
}
else {
const { path: candidate, parts } = normalizePathAndParts(combinePaths(containingDirectory, moduleName));
@ -1115,7 +1121,8 @@ namespace ts {
const containingDirectory = getDirectoryPath(containingFile);
const resolved = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript);
return createResolvedModuleWithFailedLookupLocations(resolved && resolved.value, /*isExternalLibraryImport*/ false, failedLookupLocations);
// No originalPath because classic resolution doesn't resolve realPath
return createResolvedModuleWithFailedLookupLocations(resolved && resolved.value, /*originalPath*/ undefined, /*isExternalLibraryImport*/ false, failedLookupLocations);
function tryResolve(extensions: Extensions): SearchResult<Resolved> {
const resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFileNoPackageId, failedLookupLocations, state);
@ -1162,7 +1169,7 @@ namespace ts {
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled };
const failedLookupLocations: string[] = [];
const resolved = loadModuleFromNodeModulesOneLevel(Extensions.DtsOnly, moduleName, globalCache, failedLookupLocations, state);
return createResolvedModuleWithFailedLookupLocations(resolved, /*isExternalLibraryImport*/ true, failedLookupLocations);
return createResolvedModuleWithFailedLookupLocations(resolved, /*originalPath*/ undefined, /*isExternalLibraryImport*/ true, failedLookupLocations);
}
/**

View file

@ -2,6 +2,7 @@
namespace ts {
export function createGetSymbolWalker(
getRestTypeOfSignature: (sig: Signature) => Type,
getTypePredicateOfSignature: (sig: Signature) => TypePredicate | undefined,
getReturnTypeOfSignature: (sig: Signature) => Type,
getBaseTypes: (type: Type) => Type[],
resolveStructuredTypeMembers: (type: ObjectType) => ResolvedType,
@ -117,8 +118,9 @@ namespace ts {
}
function visitSignature(signature: Signature): void {
if (signature.typePredicate) {
visitType(signature.typePredicate.type);
const typePredicate = getTypePredicateOfSignature(signature);
if (typePredicate) {
visitType(typePredicate.type);
}
forEach(signature.typeParameters, visitType);

View file

@ -2478,7 +2478,7 @@ namespace ts {
// Stores a mapping 'external module reference text' -> 'resolved file name' | undefined
// It is used to resolve module names in the checker.
// Content of this field should never be used directly - use getResolvedModuleFileName/setResolvedModuleFileName functions instead
/* @internal */ resolvedModules: Map<ResolvedModuleFull>;
/* @internal */ resolvedModules: Map<ResolvedModuleFull | undefined>;
/* @internal */ resolvedTypeReferenceDirectiveNames: Map<ResolvedTypeReferenceDirective>;
/* @internal */ imports: ReadonlyArray<StringLiteral>;
// Identifier only if `declare global`
@ -2791,7 +2791,17 @@ namespace ts {
/* @internal */ createPromiseType(type: Type): Type;
/* @internal */ createAnonymousType(symbol: Symbol, members: SymbolTable, callSignatures: Signature[], constructSignatures: Signature[], stringIndexInfo: IndexInfo, numberIndexInfo: IndexInfo): Type;
/* @internal */ createSignature(declaration: SignatureDeclaration, typeParameters: TypeParameter[], thisParameter: Symbol | undefined, parameters: Symbol[], resolvedReturnType: Type, typePredicate: TypePredicate, minArgumentCount: number, hasRestParameter: boolean, hasLiteralTypes: boolean): Signature;
/* @internal */ createSignature(
declaration: SignatureDeclaration,
typeParameters: TypeParameter[],
thisParameter: Symbol | undefined,
parameters: Symbol[],
resolvedReturnType: Type,
typePredicate: TypePredicate | undefined,
minArgumentCount: number,
hasRestParameter: boolean,
hasLiteralTypes: boolean,
): Signature;
/* @internal */ createSymbol(flags: SymbolFlags, name: __String): TransientSymbol;
/* @internal */ createIndexInfo(type: Type, isReadonly: boolean, declaration?: SignatureDeclaration): IndexInfo;
/* @internal */ isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags, shouldComputeAliasToMarkVisible: boolean): SymbolAccessibilityResult;
@ -3638,7 +3648,13 @@ namespace ts {
/* @internal */
thisParameter?: Symbol; // symbol of this-type parameter
/* @internal */
resolvedReturnType: Type; // Resolved return type
// See comment in `instantiateSignature` for why these are set lazily.
resolvedReturnType: Type | undefined; // Lazily set by `getReturnTypeOfSignature`.
/* @internal */
// Lazily set by `getTypePredicateOfSignature`.
// `undefined` indicates a type predicate that has not yet been computed.
// Uses a special `noTypePredicate` sentinel value to indicate that there is no type predicate. This looks like a TypePredicate at runtime to avoid polymorphism.
resolvedTypePredicate: TypePredicate | undefined;
/* @internal */
minArgumentCount: number; // Number of non-optional parameters
/* @internal */
@ -3658,8 +3674,6 @@ namespace ts {
/* @internal */
isolatedSignatureType?: ObjectType; // A manufactured type that just contains the signature for purposes of signature comparison
/* @internal */
typePredicate?: TypePredicate;
/* @internal */
instantiations?: Map<Signature>; // Generic signature instantiation cache
}
@ -4229,6 +4243,8 @@ namespace ts {
* If changing this, remember to change `moduleResolutionIsEqualTo`.
*/
export interface ResolvedModuleFull extends ResolvedModule {
/* @internal */
readonly originalPath?: string;
/**
* Extension of resolvedFileName. This must match what's at the end of resolvedFileName.
* This is optional for backwards-compatibility, but will be added if not provided.

View file

@ -101,6 +101,7 @@ namespace ts {
return oldResolution.isExternalLibraryImport === newResolution.isExternalLibraryImport &&
oldResolution.extension === newResolution.extension &&
oldResolution.resolvedFileName === newResolution.resolvedFileName &&
oldResolution.originalPath === newResolution.originalPath &&
packageIdIsEqual(oldResolution.packageId, newResolution.packageId);
}
@ -3696,6 +3697,10 @@ namespace ts {
export function typeHasCallOrConstructSignatures(type: Type, checker: TypeChecker) {
return checker.getSignaturesOfType(type, SignatureKind.Call).length !== 0 || checker.getSignaturesOfType(type, SignatureKind.Construct).length !== 0;
}
export function forSomeAncestorDirectory(directory: string, callback: (directory: string) => boolean): boolean {
return !!forEachAncestorDirectory(directory, d => callback(d) ? true : undefined);
}
}
namespace ts {

View file

@ -302,6 +302,8 @@ namespace ts {
// There is no extra check needed since we can just rely on the program to decide emit
const builder = createBuilder({ getCanonicalFileName, computeHash });
clearHostScreen();
reportWatchDiagnostic(createCompilerDiagnostic(Diagnostics.Starting_compilation_in_watch_mode));
synchronizeProgram();
// Update the wild card directory watch
@ -492,10 +494,14 @@ namespace ts {
scheduleProgramUpdate();
}
function updateProgram() {
function clearHostScreen() {
if (watchingHost.system.clearScreen) {
watchingHost.system.clearScreen();
}
}
function updateProgram() {
clearHostScreen();
timerToUpdateProgram = undefined;
reportWatchDiagnostic(createCompilerDiagnostic(Diagnostics.File_change_detected_Starting_incremental_compilation));

View file

@ -27,6 +27,7 @@ namespace FourSlash {
// The contents of the file (with markers, etc stripped out)
content: string;
fileName: string;
symlinks?: string[];
version: number;
// File-specific options (name/value pairs)
fileOptions: Harness.TestCaseParser.CompilerSettings;
@ -106,15 +107,16 @@ namespace FourSlash {
// Name of testcase metadata including ts.CompilerOptions properties that will be used by globalOptions
// To add additional option, add property into the testOptMetadataNames, refer the property in either globalMetadataNames or fileMetadataNames
// Add cases into convertGlobalOptionsToCompilationsSettings function for the compiler to acknowledge such option from meta data
const metadataOptionNames = {
baselineFile: "BaselineFile",
emitThisFile: "emitThisFile", // This flag is used for testing getEmitOutput feature. It allows test-cases to indicate what file to be output in multiple files project
fileName: "Filename",
resolveReference: "ResolveReference", // This flag is used to specify entry file for resolve file references. The flag is only allow once per test file
};
const enum MetadataOptionNames {
baselineFile = "BaselineFile",
emitThisFile = "emitThisFile", // This flag is used for testing getEmitOutput feature. It allows test-cases to indicate what file to be output in multiple files project
fileName = "Filename",
resolveReference = "ResolveReference", // This flag is used to specify entry file for resolve file references. The flag is only allow once per test file
symlink = "Symlink",
}
// List of allowed metadata names
const fileMetadataNames = [metadataOptionNames.fileName, metadataOptionNames.emitThisFile, metadataOptionNames.resolveReference];
const fileMetadataNames = [MetadataOptionNames.fileName, MetadataOptionNames.emitThisFile, MetadataOptionNames.resolveReference, MetadataOptionNames.symlink];
function convertGlobalOptionsToCompilerOptions(globalOptions: Harness.TestCaseParser.CompilerSettings): ts.CompilerOptions {
const settings: ts.CompilerOptions = { target: ts.ScriptTarget.ES5 };
@ -281,7 +283,7 @@ namespace FourSlash {
configFileName = file.fileName;
}
if (!startResolveFileRef && file.fileOptions[metadataOptionNames.resolveReference] === "true") {
if (!startResolveFileRef && file.fileOptions[MetadataOptionNames.resolveReference] === "true") {
startResolveFileRef = file;
}
else if (startResolveFileRef) {
@ -295,7 +297,7 @@ namespace FourSlash {
const host = new Utils.MockParseConfigHost(baseDir, /*ignoreCase*/ false, this.inputFiles);
const configJsonObj = ts.parseConfigFileTextToJson(configFileName, this.inputFiles.get(configFileName));
assert.isTrue(configJsonObj.config !== undefined);
assert(configJsonObj.config !== undefined);
const { options, errors } = ts.parseJsonConfigFileContent(configJsonObj.config, host, baseDir);
@ -354,6 +356,10 @@ namespace FourSlash {
Harness.Compiler.getDefaultLibrarySourceFile().text, /*isRootFile*/ false);
}
for (const file of testData.files) {
ts.forEach(file.symlinks, link => this.languageServiceAdapterHost.addSymlink(link, file.fileName));
}
this.formatCodeSettings = {
baseIndentSize: 0,
indentSize: 4,
@ -437,7 +443,7 @@ namespace FourSlash {
public goToEachMarker(action: () => void) {
const markers = this.getMarkers();
assert(markers.length);
assert(markers.length !== 0);
for (const marker of markers) {
this.goToMarker(marker);
action();
@ -446,7 +452,7 @@ namespace FourSlash {
public goToEachRange(action: () => void) {
const ranges = this.getRanges();
assert(ranges.length);
assert(ranges.length !== 0);
for (const range of ranges) {
this.goToRangeStart(range);
action();
@ -653,7 +659,7 @@ namespace FourSlash {
this.verifyGoToXPlain(arg0, endMarkerNames, getDefs);
}
else if (ts.isArray(arg0)) {
const pairs: ReadonlyArray<[string | string[], string | string[]]> = arg0;
const pairs = arg0 as ReadonlyArray<[string | string[], string | string[]]>;
for (const [start, end] of pairs) {
this.verifyGoToXPlain(start, end, getDefs);
}
@ -793,7 +799,7 @@ namespace FourSlash {
}
const entries = this.getCompletionListAtCaret().entries;
assert.isTrue(items.length <= entries.length, `Amount of expected items in completion list [ ${items.length} ] is greater than actual number of items in list [ ${entries.length} ]`);
assert(items.length <= entries.length, `Amount of expected items in completion list [ ${items.length} ] is greater than actual number of items in list [ ${entries.length} ]`);
ts.zipWith(entries, items, (entry, item) => {
assert.equal(entry.name, item, `Unexpected item in completion list`);
});
@ -947,7 +953,7 @@ namespace FourSlash {
public verifyCompletionEntryDetails(entryName: string, expectedText: string, expectedDocumentation?: string, kind?: string, tags?: ts.JSDocTagInfo[]) {
const details = this.getCompletionEntryDetails(entryName);
assert(details, "no completion entry available");
assert.isDefined(details, "no completion entry available");
assert.equal(ts.displayPartsToString(details.displayParts), expectedText, this.assertionMessageAtLastKnownMarker("completion entry details text"));
@ -1082,7 +1088,7 @@ namespace FourSlash {
public verifyRangesReferenceEachOther(ranges?: Range[]) {
ranges = ranges || this.getRanges();
assert(ranges.length);
assert(ranges.length !== 0);
for (const range of ranges) {
this.verifyReferencesOf(range, ranges);
}
@ -1368,7 +1374,6 @@ Actual: ${stringify(fullActual)}`);
public verifyCurrentParameterIsVariable(isVariable: boolean) {
const signature = this.getActiveSignatureHelpItem();
assert.isOk(signature);
assert.equal(isVariable, signature.isVariadic);
}
@ -1563,7 +1568,7 @@ Actual: ${stringify(fullActual)}`);
}
public baselineCurrentFileBreakpointLocations() {
let baselineFile = this.testData.globalOptions[metadataOptionNames.baselineFile];
let baselineFile = this.testData.globalOptions[MetadataOptionNames.baselineFile];
if (!baselineFile) {
baselineFile = this.activeFile.fileName.replace(this.basePath + "/breakpointValidation", "bpSpan");
baselineFile = baselineFile.replace(ts.Extension.Ts, ".baseline");
@ -1582,7 +1587,7 @@ Actual: ${stringify(fullActual)}`);
const allFourSlashFiles = this.testData.files;
for (const file of allFourSlashFiles) {
if (file.fileOptions[metadataOptionNames.emitThisFile] === "true") {
if (file.fileOptions[MetadataOptionNames.emitThisFile] === "true") {
// Find a file with the flag emitThisFile turned on
emitFiles.push(file);
}
@ -1594,7 +1599,7 @@ Actual: ${stringify(fullActual)}`);
}
Harness.Baseline.runBaseline(
this.testData.globalOptions[metadataOptionNames.baselineFile],
this.testData.globalOptions[MetadataOptionNames.baselineFile],
() => {
let resultString = "";
// Loop through all the emittedFiles and emit them one by one
@ -1634,7 +1639,7 @@ Actual: ${stringify(fullActual)}`);
}
public baselineQuickInfo() {
let baselineFile = this.testData.globalOptions[metadataOptionNames.baselineFile];
let baselineFile = this.testData.globalOptions[MetadataOptionNames.baselineFile];
if (!baselineFile) {
baselineFile = ts.getBaseFileName(this.activeFile.fileName).replace(ts.Extension.Ts, ".baseline");
}
@ -2019,7 +2024,7 @@ Actual: ${stringify(fullActual)}`);
const implementations = this.languageService.getImplementationAtPosition(this.activeFile.fileName, this.currentCaretPosition);
if (negative) {
assert.isTrue(implementations && implementations.length > 0, "Expected at least one implementation but got 0");
assert(implementations && implementations.length > 0, "Expected at least one implementation but got 0");
}
else {
assert.isUndefined(implementations, "Expected implementation list to be empty but implementations returned");
@ -2244,7 +2249,7 @@ Actual: ${stringify(fullActual)}`);
public baselineCurrentFileNameOrDottedNameSpans() {
Harness.Baseline.runBaseline(
this.testData.globalOptions[metadataOptionNames.baselineFile],
this.testData.globalOptions[MetadataOptionNames.baselineFile],
() => {
return this.baselineCurrentFileLocations(pos =>
this.getNameOrDottedNameSpan(pos));
@ -2472,7 +2477,7 @@ Actual: ${stringify(fullActual)}`);
}
private verifyNewContent(options: FourSlashInterface.NewContentOptions) {
if (options.newFileContent) {
if (options.newFileContent !== undefined) {
assert(!options.newRangeContent);
this.verifyCurrentFileContent(options.newFileContent);
}
@ -3110,7 +3115,7 @@ Actual: ${stringify(fullActual)}`);
if (spanIndex !== undefined) {
const span = this.getTextSpanForRangeAtIndex(spanIndex);
assert.isTrue(TestState.textSpansEqual(span, item.replacementSpan), this.assertionMessageAtLastKnownMarker(stringify(span) + " does not equal " + stringify(item.replacementSpan) + " replacement span for " + entryId));
assert(TestState.textSpansEqual(span, item.replacementSpan), this.assertionMessageAtLastKnownMarker(stringify(span) + " does not equal " + stringify(item.replacementSpan) + " replacement span for " + entryId));
}
assert.equal(item.hasAction, hasAction);
@ -3270,12 +3275,21 @@ ${code}
// Stuff related to the subfile we're parsing
let currentFileContent: string = undefined;
let currentFileName = fileName;
let currentFileSymlinks: string[] | undefined;
let currentFileOptions: { [s: string]: string } = {};
function resetLocalData() {
function nextFile() {
const file = parseFileContent(currentFileContent, currentFileName, markerPositions, markers, ranges);
file.fileOptions = currentFileOptions;
file.symlinks = currentFileSymlinks;
// Store result file
files.push(file);
currentFileContent = undefined;
currentFileOptions = {};
currentFileName = fileName;
currentFileSymlinks = undefined;
}
for (let line of lines) {
@ -3304,8 +3318,7 @@ ${code}
const match = optionRegex.exec(line.substr(2));
if (match) {
const [key, value] = match.slice(1);
const fileMetadataNamesIndex = fileMetadataNames.indexOf(key);
if (fileMetadataNamesIndex === -1) {
if (!ts.contains(fileMetadataNames, key)) {
// Check if the match is already existed in the global options
if (globalOptions[key] !== undefined) {
throw new Error(`Global option '${key}' already exists`);
@ -3313,24 +3326,22 @@ ${code}
globalOptions[key] = value;
}
else {
if (fileMetadataNamesIndex === fileMetadataNames.indexOf(metadataOptionNames.fileName)) {
// Found an @FileName directive, if this is not the first then create a new subfile
if (currentFileContent) {
const file = parseFileContent(currentFileContent, currentFileName, markerPositions, markers, ranges);
file.fileOptions = currentFileOptions;
switch (key) {
case MetadataOptionNames.fileName:
// Found an @FileName directive, if this is not the first then create a new subfile
if (currentFileContent) {
nextFile();
}
// Store result file
files.push(file);
resetLocalData();
}
currentFileName = ts.isRootedDiskPath(value) ? value : basePath + "/" + value;
currentFileOptions[key] = value;
}
else {
// Add other fileMetadata flag
currentFileOptions[key] = value;
currentFileName = ts.isRootedDiskPath(value) ? value : basePath + "/" + value;
currentFileOptions[key] = value;
break;
case MetadataOptionNames.symlink:
currentFileSymlinks = ts.append(currentFileSymlinks, value);
break;
default:
// Add other fileMetadata flag
currentFileOptions[key] = value;
}
}
}
@ -3342,13 +3353,7 @@ ${code}
else {
// Empty line or code line, terminate current subfile if there is one
if (currentFileContent) {
const file = parseFileContent(currentFileContent, currentFileName, markerPositions, markers, ranges);
file.fileOptions = currentFileOptions;
// Store result file
files.push(file);
resetLocalData();
nextFile();
}
}
}
@ -3383,7 +3388,7 @@ ${code}
function getNonFileNameOptionInObject(optionObject: { [s: string]: string }): string {
for (const option in optionObject) {
if (option !== metadataOptionNames.fileName) {
if (option !== MetadataOptionNames.fileName) {
return option;
}
}

View file

@ -23,18 +23,60 @@
/// <reference path="virtualFileSystem.ts" />
/// <reference types="node" />
/// <reference types="mocha" />
/// <reference types="chai" />
// Block scoped definitions work poorly for global variables, temporarily enable var
/* tslint:disable:no-var-keyword */
// this will work in the browser via browserify
var _chai: typeof chai = require("chai");
var assert: typeof _chai.assert = _chai.assert;
// chai's builtin `assert.isFalse` is featureful but slow - we don't use those features,
// so we'll just overwrite it as an alterative to migrating a bunch of code off of chai
assert.isFalse = (expr, msg) => { if (expr as any as boolean !== false) throw new Error(msg); };
function assert(expr: boolean, msg?: string | (() => string)): void {
if (!expr) {
throw new Error(typeof msg === "string" ? msg : msg());
}
}
namespace assert {
export function isFalse(expr: boolean, msg = "Expected value to be false."): void {
assert(!expr, msg);
}
export function equal<T>(a: T, b: T, msg = "Expected values to be equal."): void {
assert(a === b, msg);
}
export function notEqual<T>(a: T, b: T, msg = "Expected values to not be equal."): void {
assert(a !== b, msg);
}
export function isDefined(x: {} | null | undefined, msg = "Expected value to be defined."): void {
assert(x !== undefined && x !== null, msg);
}
export function isUndefined(x: {} | null | undefined, msg = "Expected value to be undefined."): void {
assert(x === undefined, msg);
}
export function deepEqual<T>(a: T, b: T, msg?: string): void {
assert(isDeepEqual(a, b), msg || (() => `Expected values to be deeply equal:\nExpected:\n${JSON.stringify(a, undefined, 4)}\nActual:\n${JSON.stringify(b, undefined, 4)}`));
}
export function lengthOf(a: ReadonlyArray<{}>, length: number, msg = "Expected length to match."): void {
assert(a.length === length, msg);
}
export function throws(cb: () => void, msg = "Expected callback to throw"): void {
let threw = false;
try {
cb();
}
catch {
threw = true;
}
assert(threw, msg);
}
function isDeepEqual<T>(a: T, b: T): boolean {
if (a === b) {
return true;
}
if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) {
return false;
}
const aKeys = Object.keys(a).sort();
const bKeys = Object.keys(b).sort();
return aKeys.length === bKeys.length && aKeys.every((key, i) => bKeys[i] === key && isDeepEqual((a as any)[key], (b as any)[key]));
}
}
declare var __dirname: string; // Node-specific
var global: NodeJS.Global = <any>Function("return this").call(undefined);
@ -347,8 +389,8 @@ namespace Utils {
return;
}
assert(array1, "array1");
assert(array2, "array2");
assert(!!array1, "array1");
assert(!!array2, "array2");
assert.equal(array1.length, array2.length, "array1.length !== array2.length");
@ -371,8 +413,8 @@ namespace Utils {
return;
}
assert(node1, "node1");
assert(node2, "node2");
assert(!!node1, "node1");
assert(!!node2, "node2");
assert.equal(node1.pos, node2.pos, "node1.pos !== node2.pos");
assert.equal(node1.end, node2.end, "node1.end !== node2.end");
assert.equal(node1.kind, node2.kind, "node1.kind !== node2.kind");
@ -402,8 +444,8 @@ namespace Utils {
return;
}
assert(array1, "array1");
assert(array2, "array2");
assert(!!array1, "array1");
assert(!!array2, "array2");
assert.equal(array1.pos, array2.pos, "array1.pos !== array2.pos");
assert.equal(array1.end, array2.end, "array1.end !== array2.end");
assert.equal(array1.length, array2.length, "array1.length !== array2.length");
@ -1259,7 +1301,7 @@ namespace Harness {
function findResultCodeFile(fileName: string) {
const sourceFile = result.program.getSourceFile(fileName);
assert(sourceFile, "Program has no source file with name '" + fileName + "'");
assert.isDefined(sourceFile, "Program has no source file with name '" + fileName + "'");
// Is this file going to be emitted separately
let sourceFileName: string;
const outFile = options.outFile || options.out;
@ -1942,7 +1984,7 @@ namespace Harness {
const data = testUnitData[i];
if (ts.getBaseFileName(data.name).toLowerCase() === "tsconfig.json") {
const configJson = ts.parseJsonText(data.name, data.content);
assert.isTrue(configJson.endOfFileToken !== undefined);
assert(configJson.endOfFileToken !== undefined);
let baseDir = ts.normalizePath(ts.getDirectoryPath(data.name));
if (rootDir) {
baseDir = ts.getNormalizedAbsolutePath(baseDir, rootDir);

View file

@ -122,7 +122,7 @@ namespace Harness.LanguageService {
getPreProcessedFileInfo(fileName: string, fileContents: string): ts.PreProcessedFileInfo;
}
export class LanguageServiceAdapterHost {
export abstract class LanguageServiceAdapterHost {
public typesRegistry: ts.Map<void> | undefined;
protected virtualFileSystem: Utils.VirtualFileSystem = new Utils.VirtualFileSystem(virtualFileSystemRoot, /*useCaseSensitiveFilenames*/false);
@ -166,6 +166,8 @@ namespace Harness.LanguageService {
throw new Error("No script with name '" + fileName + "'");
}
public abstract addSymlink(from: string, target: string): void;
public openFile(_fileName: string, _content?: string, _scriptKindName?: string): void { /*overridden*/ }
/**
@ -174,14 +176,15 @@ namespace Harness.LanguageService {
*/
public positionToLineAndCharacter(fileName: string, position: number): ts.LineAndCharacter {
const script: ScriptInfo = this.getScriptInfo(fileName);
assert.isOk(script);
assert(!!script);
return ts.computeLineAndCharacterOfPosition(script.getLineMap(), position);
}
}
/// Native adapter
class NativeLanguageServiceHost extends LanguageServiceAdapterHost implements ts.LanguageServiceHost {
class NativeLanguageServiceHost extends LanguageServiceAdapterHost implements ts.LanguageServiceHost, LanguageServiceAdapterHost {
symlinks = ts.createMap<string>();
isKnownTypesPackageName(name: string): boolean {
return this.typesRegistry && this.typesRegistry.has(name);
}
@ -212,13 +215,16 @@ namespace Harness.LanguageService {
}
directoryExists(dirName: string): boolean {
if (ts.forEachEntry(this.symlinks, (_, key) => ts.forSomeAncestorDirectory(key, ancestor => ancestor === dirName))) {
return true;
}
const fileEntry = this.virtualFileSystem.traversePath(dirName);
return fileEntry && fileEntry.isDirectory();
}
fileExists(fileName: string): boolean {
const script = this.getScriptSnapshot(fileName);
return script !== undefined;
return this.symlinks.has(fileName) || this.getScriptSnapshot(fileName) !== undefined;
}
readDirectory(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[] {
return ts.matchFiles(path, extensions, exclude, include,
@ -228,9 +234,19 @@ namespace Harness.LanguageService {
(p) => this.virtualFileSystem.getAccessibleFileSystemEntries(p));
}
readFile(path: string): string | undefined {
const target = this.symlinks.get(path);
if (target !== undefined) {
return this.readFile(target);
}
const snapshot = this.getScriptSnapshot(path);
return snapshot.getText(0, snapshot.getLength());
}
addSymlink(from: string, target: string) { this.symlinks.set(from, target); }
realpath(path: string): string {
const target = this.symlinks.get(path);
return target === undefined ? path : target;
}
getTypeRootsVersion() {
return 0;
}
@ -246,7 +262,7 @@ namespace Harness.LanguageService {
constructor(cancellationToken?: ts.HostCancellationToken, options?: ts.CompilerOptions) {
this.host = new NativeLanguageServiceHost(cancellationToken, options);
}
getHost() { return this.host; }
getHost(): LanguageServiceAdapterHost { return this.host; }
getLanguageService(): ts.LanguageService { return ts.createLanguageService(this.host); }
getClassifier(): ts.Classifier { return ts.createClassifier(); }
getPreProcessedFileInfo(fileName: string, fileContents: string): ts.PreProcessedFileInfo { return ts.preProcessFile(fileContents, /* readImportFiles */ true, ts.hasJavaScriptFileExtension(fileName)); }
@ -259,6 +275,8 @@ namespace Harness.LanguageService {
public getModuleResolutionsForFile: (fileName: string) => string;
public getTypeReferenceDirectiveResolutionsForFile: (fileName: string) => string;
addSymlink() { return ts.notImplemented(); }
constructor(preprocessToResolve: boolean, cancellationToken?: ts.HostCancellationToken, options?: ts.CompilerOptions) {
super(cancellationToken, options);
this.nativeHost = new NativeLanguageServiceHost(cancellationToken, options);
@ -360,7 +378,7 @@ namespace Harness.LanguageService {
classification: parseInt(result[i + 1])
};
assert.isTrue(t.length > 0, "Result length should be greater than 0, got :" + t.length);
assert(t.length > 0, "Result length should be greater than 0, got :" + t.length);
position += t.length;
}
const finalLexState = parseInt(result[result.length - 1]);

View file

@ -285,10 +285,10 @@ namespace Harness.SourceMapRecorder {
}
export function recordNewSourceFileSpan(sourceMapSpan: ts.SourceMapSpan, newSourceFileCode: string) {
assert.isTrue(spansOnSingleLine.length === 0 || spansOnSingleLine[0].sourceMapSpan.emittedLine !== sourceMapSpan.emittedLine, "new file source map span should be on new line. We currently handle only that scenario");
assert(spansOnSingleLine.length === 0 || spansOnSingleLine[0].sourceMapSpan.emittedLine !== sourceMapSpan.emittedLine, "new file source map span should be on new line. We currently handle only that scenario");
recordSourceMapSpan(sourceMapSpan);
assert.isTrue(spansOnSingleLine.length === 1);
assert(spansOnSingleLine.length === 1);
sourceMapRecorder.WriteLine("-------------------------------------------------------------------");
sourceMapRecorder.WriteLine("emittedFile:" + jsFile.fileName);
sourceMapRecorder.WriteLine("sourceFile:" + sourceMapSources[spansOnSingleLine[0].sourceMapSpan.sourceIndex]);
@ -331,7 +331,7 @@ namespace Harness.SourceMapRecorder {
function getMarkerId(markerIndex: number) {
let markerId = "";
if (spanMarkerContinues) {
assert.isTrue(markerIndex === 0);
assert(markerIndex === 0);
markerId = "1->";
}
else {

View file

@ -5,7 +5,7 @@
"outFile": "../../built/local/run.js",
"declaration": false,
"types": [
"node", "mocha", "chai"
"node", "mocha"
],
"lib": [
"es6",

View file

@ -12,7 +12,7 @@ namespace ts {
const parsedErrors = parsed.errors;
const expectedErrors = expectedParsedCommandLine.errors;
assert.isTrue(parsedErrors.length === expectedErrors.length, `Expected error: ${JSON.stringify(expectedErrors)}. Actual error: ${JSON.stringify(parsedErrors)}.`);
assert(parsedErrors.length === expectedErrors.length, `Expected error: ${JSON.stringify(expectedErrors)}. Actual error: ${JSON.stringify(parsedErrors)}.`);
for (let i = 0; i < parsedErrors.length; i++) {
const parsedError = parsedErrors[i];
const expectedError = expectedErrors[i];
@ -23,7 +23,7 @@ namespace ts {
const parsedFileNames = parsed.fileNames;
const expectedFileNames = expectedParsedCommandLine.fileNames;
assert.isTrue(parsedFileNames.length === expectedFileNames.length, `Expected fileNames: [${JSON.stringify(expectedFileNames)}]. Actual fileNames: [${JSON.stringify(parsedFileNames)}].`);
assert(parsedFileNames.length === expectedFileNames.length, `Expected fileNames: [${JSON.stringify(expectedFileNames)}]. Actual fileNames: [${JSON.stringify(parsedFileNames)}].`);
for (let i = 0; i < parsedFileNames.length; i++) {
const parsedFileName = parsedFileNames[i];
const expectedFileName = expectedFileNames[i];

View file

@ -25,7 +25,7 @@ namespace ts.projectSystem {
const actualResultSingleProjectFileNameList = actualResultSingleProject.fileNames.sort();
const expectedResultSingleProjectFileNameList = map(expectedResultSingleProject.files, f => f.path).sort();
assert.isTrue(
assert(
arrayIsEqualTo(actualResultSingleProjectFileNameList, expectedResultSingleProjectFileNameList),
`For project ${actualResultSingleProject.projectFileName}, the actual result is ${actualResultSingleProjectFileNameList}, while expected ${expectedResultSingleProjectFileNameList}`);
}
@ -563,7 +563,7 @@ namespace ts.projectSystem {
session.executeCommand(compileFileRequest);
const expectedEmittedFileName = "/a/b/f1.js";
assert.isTrue(host.fileExists(expectedEmittedFileName));
assert(host.fileExists(expectedEmittedFileName));
assert.equal(host.readFile(expectedEmittedFileName), `"use strict";\r\nexports.__esModule = true;\r\nfunction Foo() { return 10; }\r\nexports.Foo = Foo;\r\n`);
});
@ -600,11 +600,11 @@ namespace ts.projectSystem {
session.executeCommand(emitRequest);
const expectedOutFileName = "/a/b/dist.js";
assert.isTrue(host.fileExists(expectedOutFileName));
assert(host.fileExists(expectedOutFileName));
const outFileContent = host.readFile(expectedOutFileName);
assert.isTrue(outFileContent.indexOf(file1.content) !== -1);
assert.isTrue(outFileContent.indexOf(file2.content) === -1);
assert.isTrue(outFileContent.indexOf(file3.content) === -1);
assert(outFileContent.indexOf(file1.content) !== -1);
assert(outFileContent.indexOf(file2.content) === -1);
assert(outFileContent.indexOf(file3.content) === -1);
});
it("should use project root as current directory so that compile on save results in correct file mapping", () => {
@ -634,19 +634,19 @@ namespace ts.projectSystem {
// Verify js file
const expectedOutFileName = "/root/TypeScriptProject3/TypeScriptProject3/" + outFileName;
assert.isTrue(host.fileExists(expectedOutFileName));
assert(host.fileExists(expectedOutFileName));
const outFileContent = host.readFile(expectedOutFileName);
verifyContentHasString(outFileContent, file1.content);
verifyContentHasString(outFileContent, `//# ${"sourceMappingURL"}=${outFileName}.map`); // Sometimes tools can sometimes see this line as a source mapping url comment, so we obfuscate it a little
// Verify map file
const expectedMapFileName = expectedOutFileName + ".map";
assert.isTrue(host.fileExists(expectedMapFileName));
assert(host.fileExists(expectedMapFileName));
const mapFileContent = host.readFile(expectedMapFileName);
verifyContentHasString(mapFileContent, `"sources":["${inputFileName}"]`);
function verifyContentHasString(content: string, str: string) {
assert.isTrue(stringContains(content, str), `Expected "${content}" to have "${str}"`);
assert(stringContains(content, str), `Expected "${content}" to have "${str}"`);
}
});
});

View file

@ -113,7 +113,7 @@ namespace ts {
const caseSensitiveHost = new Utils.MockParseConfigHost(caseSensitiveBasePath, /*useCaseSensitiveFileNames*/ true, testContents);
function verifyDiagnostics(actual: Diagnostic[], expected: {code: number, category: DiagnosticCategory, messageText: string}[]) {
assert.isTrue(expected.length === actual.length, `Expected error: ${JSON.stringify(expected)}. Actual error: ${JSON.stringify(actual)}.`);
assert(expected.length === actual.length, `Expected error: ${JSON.stringify(expected)}. Actual error: ${JSON.stringify(actual)}.`);
for (let i = 0; i < actual.length; i++) {
const actualError = actual[i];
const expectedError = expected[i];

View file

@ -16,7 +16,7 @@ namespace ts {
assert.equal(parsedCompilerOptions, expectedCompilerOptions);
const expectedErrors = expectedResult.errors;
assert.isTrue(expectedResult.errors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedResult.errors)}. Actual error: ${JSON.stringify(actualErrors)}.`);
assert(expectedResult.errors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedResult.errors)}. Actual error: ${JSON.stringify(actualErrors)}.`);
for (let i = 0; i < actualErrors.length; i++) {
const actualError = actualErrors[i];
const expectedError = expectedErrors[i];
@ -42,15 +42,15 @@ namespace ts {
const actualErrors = filter(actualParseErrors, error => error.code !== Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code);
const expectedErrors = expectedResult.errors;
assert.isTrue(expectedResult.errors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedResult.errors)}. Actual error: ${JSON.stringify(actualErrors)}.`);
assert(expectedResult.errors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedResult.errors)}. Actual error: ${JSON.stringify(actualErrors)}.`);
for (let i = 0; i < actualErrors.length; i++) {
const actualError = actualErrors[i];
const expectedError = expectedErrors[i];
assert.equal(actualError.code, expectedError.code, `Expected error-code: ${JSON.stringify(expectedError.code)}. Actual error-code: ${JSON.stringify(actualError.code)}.`);
assert.equal(actualError.category, expectedError.category, `Expected error-category: ${JSON.stringify(expectedError.category)}. Actual error-category: ${JSON.stringify(actualError.category)}.`);
assert(actualError.file);
assert(actualError.start);
assert(actualError.length);
assert.isDefined(actualError.file);
assert(actualError.start > 0);
assert(actualError.length > 0);
}
}

View file

@ -17,16 +17,16 @@ namespace ts {
function verifyErrors(actualErrors: Diagnostic[], expectedResult: ExpectedResult, hasLocation?: boolean) {
const expectedErrors = expectedResult.errors;
assert.isTrue(expectedResult.errors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedResult.errors)}. Actual error: ${JSON.stringify(actualErrors)}.`);
assert(expectedResult.errors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedResult.errors)}. Actual error: ${JSON.stringify(actualErrors)}.`);
for (let i = 0; i < actualErrors.length; i++) {
const actualError = actualErrors[i];
const expectedError = expectedErrors[i];
assert.equal(actualError.code, expectedError.code, `Expected error-code: ${JSON.stringify(expectedError.code)}. Actual error-code: ${JSON.stringify(actualError.code)}.`);
assert.equal(actualError.category, expectedError.category, `Expected error-category: ${JSON.stringify(expectedError.category)}. Actual error-category: ${JSON.stringify(actualError.category)}.`);
if (hasLocation) {
assert(actualError.file);
assert(actualError.start);
assert(actualError.length);
assert.isDefined(actualError.file);
assert(actualError.start > 0);
assert(actualError.length > 0);
}
}
}

View file

@ -39,7 +39,7 @@ namespace ts {
assert.equal(end, expectedRange.end, "incorrect end of range");
}
else {
assert.isTrue(!result.targetRange, `expected range to extract to be undefined`);
assert(!result.targetRange, `expected range to extract to be undefined`);
}
}

View file

@ -47,7 +47,7 @@ namespace ts {
assert(!result.emitSkipped, "emit was skipped");
assert(result.outputFiles.length === 1, "a number of files other than 1 was output");
assert(result.outputFiles[0].name === "input.js", `Expected output file name input.js, but got ${result.outputFiles[0].name}`);
assert(result.outputFiles[0].text.match(options.newLine === NewLineKind.CarriageReturnLineFeed ? /\r\n/ : /[^\r]\n/), "expected to find appropriate newlines");
assert.isDefined(result.outputFiles[0].text.match(options.newLine === NewLineKind.CarriageReturnLineFeed ? /\r\n/ : /[^\r]\n/), "expected to find appropriate newlines");
assert(!result.outputFiles[0].text.match(options.newLine === NewLineKind.CarriageReturnLineFeed ? /[^\r]\n/ : /\r\n/), "expected not to find inappropriate newlines");
}

View file

@ -66,7 +66,7 @@ namespace ts {
assertSameDiagnostics(newTree, incrementalNewTree);
// There should be no reused nodes between two trees that are fully parsed.
assert.isTrue(reusedElements(oldTree, newTree) === 0);
assert(reusedElements(oldTree, newTree) === 0);
assert.equal(newTree.fileName, incrementalNewTree.fileName, "newTree.fileName !== incrementalNewTree.fileName");
assert.equal(newTree.text, incrementalNewTree.text, "newTree.text !== incrementalNewTree.text");

View file

@ -7,7 +7,7 @@ namespace ts {
function parsesCorrectly(name: string, content: string) {
it(name, () => {
const typeAndDiagnostics = ts.parseJSDocTypeExpressionForTests(content);
assert.isTrue(typeAndDiagnostics && typeAndDiagnostics.diagnostics.length === 0, "no errors issued");
assert(typeAndDiagnostics && typeAndDiagnostics.diagnostics.length === 0, "no errors issued");
Harness.Baseline.runBaseline("JSDocParsing/TypeExpressions.parsesCorrectly." + name + ".json",
() => Utils.sourceFileToJSON(typeAndDiagnostics.jsDocTypeExpression.type));
@ -17,7 +17,7 @@ namespace ts {
function parsesIncorrectly(name: string, content: string) {
it(name, () => {
const type = ts.parseJSDocTypeExpressionForTests(content);
assert.isTrue(!type || type.diagnostics.length > 0);
assert(!type || type.diagnostics.length > 0);
});
}
@ -106,7 +106,7 @@ namespace ts {
function parsesIncorrectly(name: string, content: string) {
it(name, () => {
const type = parseIsolatedJSDocComment(content);
assert.isTrue(!type || type.diagnostics.length > 0);
assert(!type || type.diagnostics.length > 0);
});
}

View file

@ -40,12 +40,9 @@ export function Component(x: Config): any;`
getDefaultLibFileName(options) {
return ts.getDefaultLibFilePath(options);
},
fileExists: noop as any,
readFile: noop as any,
readDirectory: noop as any,
});
const definitions = languageService.getDefinitionAtPosition("foo.ts", 160); // 160 is the latter `vueTemplateHtml` position
expect(definitions).to.exist; // tslint:disable-line no-unused-expression
assert.isDefined(definitions);
});
});
}

View file

@ -4,9 +4,9 @@ namespace ts {
export function checkResolvedModule(expected: ResolvedModuleFull, actual: ResolvedModuleFull): boolean {
if (!expected === !actual) {
if (expected) {
assert.isTrue(expected.resolvedFileName === actual.resolvedFileName, `'resolvedFileName': expected '${expected.resolvedFileName}' to be equal to '${actual.resolvedFileName}'`);
assert.isTrue(expected.extension === actual.extension, `'ext': expected '${expected.extension}' to be equal to '${actual.extension}'`);
assert.isTrue(expected.isExternalLibraryImport === actual.isExternalLibraryImport, `'isExternalLibraryImport': expected '${expected.isExternalLibraryImport}' to be equal to '${actual.isExternalLibraryImport}'`);
assert(expected.resolvedFileName === actual.resolvedFileName, `'resolvedFileName': expected '${expected.resolvedFileName}' to be equal to '${actual.resolvedFileName}'`);
assert(expected.extension === actual.extension, `'ext': expected '${expected.extension}' to be equal to '${actual.extension}'`);
assert(expected.isExternalLibraryImport === actual.isExternalLibraryImport, `'isExternalLibraryImport': expected '${expected.isExternalLibraryImport}' to be equal to '${actual.isExternalLibraryImport}'`);
}
return true;
}
@ -14,7 +14,7 @@ namespace ts {
}
export function checkResolvedModuleWithFailedLookupLocations(actual: ResolvedModuleWithFailedLookupLocations, expectedResolvedModule: ResolvedModuleFull, expectedFailedLookupLocations: string[]): void {
assert.isTrue(actual.resolvedModule !== undefined, "module should be resolved");
assert(actual.resolvedModule !== undefined, "module should be resolved");
checkResolvedModule(actual.resolvedModule, expectedResolvedModule);
assert.deepEqual(actual.failedLookupLocations, expectedFailedLookupLocations);
}
@ -58,7 +58,7 @@ namespace ts {
realpath,
directoryExists: path => directories.has(path),
fileExists: path => {
assert.isTrue(directories.has(getDirectoryPath(path)), `'fileExists' '${path}' request in non-existing directory`);
assert(directories.has(getDirectoryPath(path)), `'fileExists' '${path}' request in non-existing directory`);
return map.has(path);
}
};
@ -313,7 +313,7 @@ namespace ts {
const host = createModuleResolutionHost(/*hasDirectoryExists*/ true, { name: realFileName, symlinks: [symlinkFileName] });
const resolution = nodeModuleNameResolver("linked", "/app/app.ts", { preserveSymlinks }, host);
const resolvedFileName = preserveSymlinks ? symlinkFileName : realFileName;
checkResolvedModule(resolution.resolvedModule, { resolvedFileName, isExternalLibraryImport: true, extension: Extension.Dts });
checkResolvedModule(resolution.resolvedModule, createResolvedModule(resolvedFileName, /*isExternalLibraryImport*/ true));
});
}
});
@ -338,7 +338,7 @@ namespace ts {
const path = normalizePath(combinePaths(currentDirectory, fileName));
return files.has(path);
},
readFile: notImplemented
readFile: notImplemented,
};
const program = createProgram(rootFiles, options, host);
@ -351,7 +351,7 @@ namespace ts {
// try to get file using a relative name
for (const relativeFileName of relativeNamesToCheck) {
assert.isTrue(program.getSourceFile(relativeFileName) !== undefined, `expected to get file by relative name, got undefined`);
assert(program.getSourceFile(relativeFileName) !== undefined, `expected to get file by relative name, got undefined`);
}
}
@ -426,7 +426,7 @@ export = C;
const path = getCanonicalFileName(normalizePath(combinePaths(currentDirectory, fileName)));
return files.has(path);
},
readFile: notImplemented
readFile: notImplemented,
};
const program = createProgram(rootFiles, options, host);
const diagnostics = sortAndDeduplicateDiagnostics([...program.getSemanticDiagnostics(), ...program.getOptionsDiagnostics()]);
@ -1067,14 +1067,14 @@ import b = require("./moduleB");
readFile: fileName => {
const file = sourceFiles.get(fileName);
return file && file.text;
}
},
};
const program1 = createProgram(names, {}, compilerHost);
const diagnostics1 = program1.getFileProcessingDiagnostics().getDiagnostics();
assert.equal(diagnostics1.length, 1, "expected one diagnostic");
createProgram(names, {}, compilerHost, program1);
assert.isTrue(program1.structureIsReused === StructureIsReused.Completely);
assert(program1.structureIsReused === StructureIsReused.Completely);
const diagnostics2 = program1.getFileProcessingDiagnostics().getDiagnostics();
assert.equal(diagnostics2.length, 1, "expected one diagnostic");
assert.equal(diagnostics1[0].messageText, diagnostics2[0].messageText, "expected one diagnostic");

View file

@ -6,10 +6,10 @@ namespace ts {
const map = arrayToSet(expected) as Map<boolean>;
for (const missing of missingPaths) {
const value = map.get(missing);
assert.isTrue(value, `${missing} to be ${value === undefined ? "not present" : "present only once"}, in actual: ${missingPaths} expected: ${expected}`);
assert(value, `${missing} to be ${value === undefined ? "not present" : "present only once"}, in actual: ${missingPaths} expected: ${expected}`);
map.set(missing, false);
}
const notFound = mapDefinedIter(map.keys(), k => map.get(k) === true ? k : undefined);
const notFound = arrayFrom(mapDefinedIterator(map.keys(), k => map.get(k) === true ? k : undefined));
assert.equal(notFound.length, 0, `Not found ${notFound} in actual: ${missingPaths} expected: ${expected}`);
}

View file

@ -5,7 +5,7 @@
namespace ts.projectSystem {
describe("Project errors", () => {
function checkProjectErrors(projectFiles: server.ProjectFilesWithTSDiagnostics, expectedErrors: ReadonlyArray<string>): void {
assert.isTrue(projectFiles !== undefined, "missing project files");
assert(projectFiles !== undefined, "missing project files");
checkProjectErrorsWorker(projectFiles.projectErrors, expectedErrors);
}
@ -15,7 +15,7 @@ namespace ts.projectSystem {
for (let i = 0; i < errors.length; i++) {
const actualMessage = flattenDiagnosticMessageText(errors[i].messageText, "\n");
const expectedMessage = expectedErrors[i];
assert.isTrue(actualMessage.indexOf(expectedMessage) === 0, `error message does not match, expected ${actualMessage} to start with ${expectedMessage}`);
assert(actualMessage.indexOf(expectedMessage) === 0, `error message does not match, expected ${actualMessage} to start with ${expectedMessage}`);
}
}
}
@ -24,7 +24,7 @@ namespace ts.projectSystem {
assert.equal(errors ? errors.length : 0, expectedErrors.length, `expected ${expectedErrors.length} error in the list`);
if (expectedErrors.length) {
zipWith(errors, expectedErrors, ({ message: actualMessage }, expectedMessage) => {
assert.isTrue(startsWith(actualMessage, actualMessage), `error message does not match, expected ${actualMessage} to start with ${expectedMessage}`);
assert(startsWith(actualMessage, actualMessage), `error message does not match, expected ${actualMessage} to start with ${expectedMessage}`);
});
}
}
@ -137,13 +137,13 @@ namespace ts.projectSystem {
{
projectService.checkNumberOfProjects({ configuredProjects: 1 });
const configuredProject = forEach(projectService.synchronizeProjectList([]), f => f.info.projectName === corruptedConfig.path && f);
assert.isTrue(configuredProject !== undefined, "should find configured project");
assert(configuredProject !== undefined, "should find configured project");
checkProjectErrors(configuredProject, []);
const projectErrors = configuredProjectAt(projectService, 0).getAllProjectErrors();
checkProjectErrorsWorker(projectErrors, [
"'{' expected."
]);
assert.isNotNull(projectErrors[0].file);
assert.isDefined(projectErrors[0].file);
assert.equal(projectErrors[0].file.fileName, corruptedConfig.path);
}
// fix config and trigger watcher
@ -151,7 +151,7 @@ namespace ts.projectSystem {
{
projectService.checkNumberOfProjects({ configuredProjects: 1 });
const configuredProject = forEach(projectService.synchronizeProjectList([]), f => f.info.projectName === corruptedConfig.path && f);
assert.isTrue(configuredProject !== undefined, "should find configured project");
assert(configuredProject !== undefined, "should find configured project");
checkProjectErrors(configuredProject, []);
const projectErrors = configuredProjectAt(projectService, 0).getAllProjectErrors();
checkProjectErrorsWorker(projectErrors, []);
@ -182,7 +182,7 @@ namespace ts.projectSystem {
{
projectService.checkNumberOfProjects({ configuredProjects: 1 });
const configuredProject = forEach(projectService.synchronizeProjectList([]), f => f.info.projectName === corruptedConfig.path && f);
assert.isTrue(configuredProject !== undefined, "should find configured project");
assert(configuredProject !== undefined, "should find configured project");
checkProjectErrors(configuredProject, []);
const projectErrors = configuredProjectAt(projectService, 0).getAllProjectErrors();
checkProjectErrorsWorker(projectErrors, []);
@ -192,13 +192,13 @@ namespace ts.projectSystem {
{
projectService.checkNumberOfProjects({ configuredProjects: 1 });
const configuredProject = forEach(projectService.synchronizeProjectList([]), f => f.info.projectName === corruptedConfig.path && f);
assert.isTrue(configuredProject !== undefined, "should find configured project");
assert(configuredProject !== undefined, "should find configured project");
checkProjectErrors(configuredProject, []);
const projectErrors = configuredProjectAt(projectService, 0).getAllProjectErrors();
checkProjectErrorsWorker(projectErrors, [
"'{' expected."
]);
assert.isNotNull(projectErrors[0].file);
assert.isDefined(projectErrors[0].file);
assert.equal(projectErrors[0].file.fileName, corruptedConfig.path);
}
});

View file

@ -193,14 +193,14 @@ namespace ts {
function checkCache<T>(caption: string, program: Program, fileName: string, expectedContent: Map<T>, getCache: (f: SourceFile) => Map<T>, entryChecker: (expected: T, original: T) => boolean): void {
const file = program.getSourceFile(fileName);
assert.isTrue(file !== undefined, `cannot find file ${fileName}`);
assert(file !== undefined, `cannot find file ${fileName}`);
const cache = getCache(file);
if (expectedContent === undefined) {
assert.isTrue(cache === undefined, `expected ${caption} to be undefined`);
assert(cache === undefined, `expected ${caption} to be undefined`);
}
else {
assert.isTrue(cache !== undefined, `expected ${caption} to be set`);
assert.isTrue(mapsAreEqual(expectedContent, cache, entryChecker), `contents of ${caption} did not match the expected contents.`);
assert(cache !== undefined, `expected ${caption} to be set`);
assert(mapsAreEqual(expectedContent, cache, entryChecker), `contents of ${caption} did not match the expected contents.`);
}
}
@ -329,7 +329,7 @@ namespace ts {
const options: CompilerOptions = { target, noLib: true };
const program1 = newProgram(files, ["a.ts"], options);
assert.notDeepEqual(emptyArray, program1.getMissingFilePaths());
assert(program1.getMissingFilePaths().length !== 0);
const program2 = updateProgram(program1, ["a.ts"], options, noop);
assert.deepEqual(program1.getMissingFilePaths(), program2.getMissingFilePaths());
@ -341,11 +341,11 @@ namespace ts {
const options: CompilerOptions = { target, noLib: true };
const program1 = newProgram(files, ["a.ts"], options);
assert.notDeepEqual(emptyArray, program1.getMissingFilePaths());
assert(program1.getMissingFilePaths().length !== 0);
const newTexts: NamedSourceText[] = files.concat([{ name: "non-existing-file.ts", text: SourceText.New("", "", `var x = 1`) }]);
const program2 = updateProgram(program1, ["a.ts"], options, noop, newTexts);
assert.deepEqual(emptyArray, program2.getMissingFilePaths());
assert.lengthOf(program2.getMissingFilePaths(), 0);
assert.equal(StructureIsReused.Not, program1.structureIsReused);
});
@ -826,12 +826,12 @@ namespace ts {
updateProgramText(files, root, "const x = 1;");
});
assert.equal(program1.structureIsReused, StructureIsReused.Completely);
assert.deepEqual(program2.getSemanticDiagnostics(), emptyArray);
assert.lengthOf(program2.getSemanticDiagnostics(), 0);
});
it("Target changes -> redirect broken", () => {
const program1 = createRedirectProgram();
assert.deepEqual(program1.getSemanticDiagnostics(), emptyArray);
assert.lengthOf(program1.getSemanticDiagnostics(), 0);
const program2 = updateRedirectProgram(program1, files => {
updateProgramText(files, axIndex, "export default class X { private x: number; private y: number; }");
@ -860,7 +860,7 @@ namespace ts {
updateProgramText(files, bxPackage, JSON.stringify({ name: "x", version: "1.2.3" }));
});
assert.equal(program1.structureIsReused, StructureIsReused.Not);
assert.deepEqual(program2.getSemanticDiagnostics(), []);
assert.lengthOf(program2.getSemanticDiagnostics(), 0);
});
});
});
@ -888,7 +888,7 @@ namespace ts {
/*hasInvalidatedResolution*/ returnFalse,
/*hasChangedAutomaticTypeDirectiveNames*/ false
);
assert.isTrue(actual);
assert(actual);
}
function duplicate(options: CompilerOptions): CompilerOptions;

View file

@ -50,7 +50,7 @@ describe("Colorization", () => {
const actualEntry = getEntryAtPosition(result, actualEntryPosition);
assert(actualEntry, "Could not find classification entry for '" + expectedEntry.value + "' at position: " + actualEntryPosition);
assert.isDefined(actualEntry, "Could not find classification entry for '" + expectedEntry.value + "' at position: " + actualEntryPosition);
assert.equal(actualEntry.classification, expectedEntry.classification, "Classification class does not match expected. Expected: " + ts.TokenClass[expectedEntry.classification] + ", Actual: " + ts.TokenClass[actualEntry.classification]);
assert.equal(actualEntry.length, expectedEntry.value.length, "Classification length does not match expected. Expected: " + ts.TokenClass[expectedEntry.value.length] + ", Actual: " + ts.TokenClass[actualEntry.length]);
}

View file

@ -140,25 +140,25 @@ describe("PatternMatcher", () => {
it("PreferCaseSensitiveCamelCaseMatchToLongPattern1", () => {
const match = getFirstMatch("FogBar", "FBB");
assert.isTrue(match === undefined);
assert(match === undefined);
});
it("PreferCaseSensitiveCamelCaseMatchToLongPattern2", () => {
const match = getFirstMatch("FogBar", "FoooB");
assert.isTrue(match === undefined);
assert(match === undefined);
});
it("CamelCaseMatchPartiallyUnmatched", () => {
const match = getFirstMatch("FogBarBaz", "FZ");
assert.isTrue(match === undefined);
assert(match === undefined);
});
it("CamelCaseMatchCompletelyUnmatched", () => {
const match = getFirstMatch("FogBarBaz", "ZZ");
assert.isTrue(match === undefined);
assert(match === undefined);
});
it("TwoUppercaseCharacters", () => {
@ -220,7 +220,7 @@ describe("PatternMatcher", () => {
it("PreferCaseSensitiveMiddleUnderscore3", () => {
const match = getFirstMatch("Fog_Bar", "F__B");
assert.isTrue(undefined === match);
assert(undefined === match);
});
it("PreferCaseSensitiveMiddleUnderscore4", () => {
@ -264,25 +264,25 @@ describe("PatternMatcher", () => {
it("AllLowerPattern1", () => {
const match = getFirstMatch("FogBarChangedEventArgs", "changedeventargs");
assert.isTrue(undefined !== match);
assert(undefined !== match);
});
it("AllLowerPattern2", () => {
const match = getFirstMatch("FogBarChangedEventArgs", "changedeventarrrgh");
assert.isTrue(undefined === match);
assert(undefined === match);
});
it("AllLowerPattern3", () => {
const match = getFirstMatch("ABCDEFGH", "bcd");
assert.isTrue(undefined !== match);
assert(undefined !== match);
});
it("AllLowerPattern4", () => {
const match = getFirstMatch("AbcdefghijEfgHij", "efghij");
assert.isTrue(undefined === match);
assert(undefined === match);
});
});
@ -370,13 +370,13 @@ describe("PatternMatcher", () => {
it("BlankPattern", () => {
const matches = getAllMatches("AddMetadataReference", "");
assert.isTrue(matches === undefined);
assert(matches === undefined);
});
it("WhitespaceOnlyPattern", () => {
const matches = getAllMatches("AddMetadataReference", " ");
assert.isTrue(matches === undefined);
assert(matches === undefined);
});
it("EachWordSeparately1", () => {
@ -403,13 +403,13 @@ describe("PatternMatcher", () => {
it("MixedCasing", () => {
const matches = getAllMatches("AddMetadataReference", "mEta");
assert.isTrue(matches === undefined);
assert(matches === undefined);
});
it("MixedCasing2", () => {
const matches = getAllMatches("AddMetadataReference", "Data");
assert.isTrue(matches === undefined);
assert(matches === undefined);
});
it("AsteriskSplit", () => {
@ -421,7 +421,7 @@ describe("PatternMatcher", () => {
it("LowercaseSubstring1", () => {
const matches = getAllMatches("Operator", "a");
assert.isTrue(matches === undefined);
assert(matches === undefined);
});
it("LowercaseSubstring2", () => {
@ -441,7 +441,7 @@ describe("PatternMatcher", () => {
it("DottedPattern2", () => {
const match = getFirstMatchForDottedPattern("Foo.Bar.Baz", "Quux", "C.Q");
assert.isTrue(match === undefined);
assert(match === undefined);
});
it("DottedPattern3", () => {
@ -464,13 +464,13 @@ describe("PatternMatcher", () => {
it("DottedPattern6", () => {
const match = getFirstMatchForDottedPattern("Foo.Bar.Baz", "Quux", "F.F.B.B.Quux");
assert.isTrue(match === undefined);
assert(match === undefined);
});
it("DottedPattern7", () => {
let match = getFirstMatch("UIElement", "UIElement");
match = getFirstMatch("GetKeyword", "UIElement");
assert.isTrue(match === undefined);
assert(match === undefined);
});
});
@ -508,8 +508,8 @@ describe("PatternMatcher", () => {
}
function assertInRange(val: number, low: number, high: number) {
assert.isTrue(val >= low);
assert.isTrue(val <= high);
assert(val >= low);
assert(val <= high);
}
function verifyBreakIntoCharacterSpans(original: string, ...parts: string[]): void {
@ -521,6 +521,6 @@ describe("PatternMatcher", () => {
}
function assertContainsKind(kind: ts.PatternMatchKind, results: ts.PatternMatch[]) {
assert.isTrue(ts.forEach(results, r => r.kind === kind));
assert(ts.forEach(results, r => r.kind === kind));
}
});

View file

@ -18,7 +18,7 @@ describe("PreProcessFile:", () => {
return;
}
if (!expected) {
assert.isTrue(false, `Expected ${JSON.stringify(expected)}, got ${JSON.stringify(actual)}`);
assert(false, `Expected ${JSON.stringify(expected)}, got ${JSON.stringify(actual)}`);
}
assert.equal(actual.length, expected.length, `[${kind}] Actual array's length does not match expected length. Expected files: ${JSON.stringify(expected)}, actual files: ${JSON.stringify(actual)}`);

View file

@ -1,7 +1,5 @@
/// <reference path="..\harness.ts" />
const expect: typeof _chai.expect = _chai.expect;
namespace ts.server {
let lastWrittenToHost: string;
const mockHost: ServerHost = {
@ -82,7 +80,7 @@ namespace ts.server {
}
};
expect(() => session.executeCommand(req)).to.throw();
assert.throws(() => session.executeCommand(req));
});
it("should output an error response when a command does not exist", () => {
const req: protocol.Request = {
@ -101,7 +99,7 @@ namespace ts.server {
request_seq: 0,
success: false
};
expect(lastSent).to.deep.equal(expected);
assert.deepEqual(lastSent, expected);
});
it("should return a tuple containing the response and if a response is required on success", () => {
const req: protocol.ConfigureRequest = {
@ -116,17 +114,18 @@ namespace ts.server {
}
};
expect(session.executeCommand(req)).to.deep.equal({
assert.deepEqual(session.executeCommand(req), {
responseRequired: false
});
expect(lastSent).to.deep.equal({
const expected: protocol.Response = {
command: CommandNames.Configure,
type: "response",
success: true,
request_seq: 0,
seq: 0,
body: undefined
});
};
assert.deepEqual(lastSent, expected);
});
it("should handle literal types in request", () => {
const configureRequest: protocol.ConfigureRequest = {
@ -297,14 +296,15 @@ namespace ts.server {
session.onMessage(JSON.stringify(req));
expect(lastSent).to.deep.equal(<protocol.ConfigureResponse>{
const expected: protocol.ConfigureResponse = {
command: CommandNames.Configure,
type: "response",
success: true,
request_seq: 0,
seq: 0,
body: undefined
});
};
assert.deepEqual(lastSent, expected);
});
});
@ -316,9 +316,9 @@ namespace ts.server {
const resultMsg = `Content-Length: ${len}\r\n\r\n${strmsg}\n`;
session.send = Session.prototype.send;
assert(session.send);
expect(session.send(msg)).to.not.exist; // tslint:disable-line no-unused-expression
expect(lastWrittenToHost).to.equal(resultMsg);
assert.isDefined(session.send);
session.send(msg);
assert.equal(lastWrittenToHost, resultMsg);
});
});
@ -335,11 +335,7 @@ namespace ts.server {
session.addProtocolHandler(command, () => result);
expect(session.executeCommand({
command,
seq: 0,
type: "request"
})).to.deep.equal(result);
assert.deepEqual(session.executeCommand({ command, seq: 0, type: "request" }), result);
});
it("throws when a duplicate handler is passed", () => {
const respBody = {
@ -353,8 +349,7 @@ namespace ts.server {
session.addProtocolHandler(command, () => resp);
expect(() => session.addProtocolHandler(command, () => resp))
.to.throw(`Protocol handler already exists for command "${command}"`);
assert.throws(() => session.addProtocolHandler(command, () => resp), `Protocol handler already exists for command "${command}"`);
});
});
@ -367,12 +362,13 @@ namespace ts.server {
session.event(info, evt);
expect(lastSent).to.deep.equal({
const expected: protocol.Event = {
type: "event",
seq: 0,
event: evt,
body: info
});
};
assert.deepEqual(lastSent, expected);
});
});
@ -387,14 +383,15 @@ namespace ts.server {
session.output(body, command, /*reqSeq*/ 0);
expect(lastSent).to.deep.equal({
const expected: protocol.Response = {
seq: 0,
request_seq: 0,
type: "response",
command,
body,
success: true
});
};
assert.deepEqual(lastSent, expected);
});
});
});
@ -455,14 +452,16 @@ namespace ts.server {
session.onMessage(JSON.stringify(request));
const lastSent = session.lastSent as protocol.Response;
expect(lastSent).to.contain({
assert.deepEqual({ ...lastSent, message: undefined }, {
request_seq: 0,
seq: 0,
type: "response",
command,
success: false
success: false,
message: undefined,
});
expect(lastSent.message).has.string("myMessage").and.has.string("f1");
assert(ts.stringContains(lastSent.message, "myMessage") && ts.stringContains(lastSent.message, "f1"));
});
});
@ -502,23 +501,24 @@ namespace ts.server {
session.output(body, command, /*reqSeq*/ 0);
expect(session.lastSent).to.deep.equal({
const expected: protocol.Response = {
seq: 0,
request_seq: 0,
type: "response",
command,
body,
success: true
});
};
assert.deepEqual(session.lastSent, expected);
});
it("can add and respond to new protocol handlers", () => {
const session = new TestSession();
expect(session.executeCommand({
assert.deepEqual(session.executeCommand({
seq: 0,
type: "request",
command: session.customHandler
})).to.deep.equal({
}), {
response: undefined,
responseRequired: true
});
@ -528,8 +528,7 @@ namespace ts.server {
new class extends TestSession {
constructor() {
super();
assert(this.projectService);
expect(this.projectService).to.be.instanceOf(ProjectService);
assert(this.projectService instanceof ProjectService);
}
}();
});
@ -653,9 +652,9 @@ namespace ts.server {
// Add an event handler
cli.on("testevent", (eventinfo) => {
expect(eventinfo).to.equal(toEvent);
assert.equal(eventinfo, toEvent);
responses++;
expect(responses).to.equal(1);
assert.equal(responses, 1);
});
// Trigger said event from the server
@ -665,8 +664,8 @@ namespace ts.server {
cli.execute("echo", toEcho, (resp) => {
assert(resp.success, resp.message);
responses++;
expect(responses).to.equal(2);
expect(resp.body).to.deep.equal(toEcho);
assert.equal(responses, 2);
assert.deepEqual(resp.body, toEcho);
});
// Queue a configure command
@ -678,7 +677,7 @@ namespace ts.server {
}, (resp) => {
assert(resp.success, resp.message);
responses++;
expect(responses).to.equal(3);
assert.equal(responses, 3);
done();
});

View file

@ -33,20 +33,20 @@ namespace ts.textStorage {
for (let offset = 0; offset < end - start; offset++) {
const pos1 = ts1.lineOffsetToPosition(line + 1, offset + 1);
const pos2 = ts2.lineOffsetToPosition(line + 1, offset + 1);
assert.isTrue(pos1 === pos2, `lineOffsetToPosition ${line + 1}-${offset + 1}: expected ${pos1} to equal ${pos2}`);
assert(pos1 === pos2, `lineOffsetToPosition ${line + 1}-${offset + 1}: expected ${pos1} to equal ${pos2}`);
}
const {start: start1, length: length1 } = ts1.lineToTextSpan(line);
const {start: start2, length: length2 } = ts2.lineToTextSpan(line);
assert.isTrue(start1 === start2, `lineToTextSpan ${line}::start:: expected ${start1} to equal ${start2}`);
assert.isTrue(length1 === length2, `lineToTextSpan ${line}::length:: expected ${length1} to equal ${length2}`);
assert(start1 === start2, `lineToTextSpan ${line}::start:: expected ${start1} to equal ${start2}`);
assert(length1 === length2, `lineToTextSpan ${line}::length:: expected ${length1} to equal ${length2}`);
}
for (let pos = 0; pos < f.content.length; pos++) {
const { line: line1, offset: offset1 } = ts1.positionToLineOffset(pos);
const { line: line2, offset: offset2 } = ts2.positionToLineOffset(pos);
assert.isTrue(line1 === line2, `positionToLineOffset ${pos}::line:: expected ${line1} to equal ${line2}`);
assert.isTrue(offset1 === offset2, `positionToLineOffset ${pos}::offset:: expected ${offset1} to equal ${offset2}`);
assert(line1 === line2, `positionToLineOffset ${pos}::line:: expected ${line1} to equal ${line2}`);
assert(offset1 === offset2, `positionToLineOffset ${pos}::offset:: expected ${offset1} to equal ${offset2}`);
}
});
@ -55,16 +55,16 @@ namespace ts.textStorage {
const ts1 = new server.TextStorage(host, server.asNormalizedPath(f.path));
ts1.getSnapshot();
assert.isTrue(!ts1.hasScriptVersionCache_TestOnly(), "should not have script version cache - 1");
assert(!ts1.hasScriptVersionCache_TestOnly(), "should not have script version cache - 1");
ts1.edit(0, 5, " ");
assert.isTrue(ts1.hasScriptVersionCache_TestOnly(), "have script version cache - 1");
assert(ts1.hasScriptVersionCache_TestOnly(), "have script version cache - 1");
ts1.useText();
assert.isTrue(!ts1.hasScriptVersionCache_TestOnly(), "should not have script version cache - 2");
assert(!ts1.hasScriptVersionCache_TestOnly(), "should not have script version cache - 2");
ts1.getLineInfo(0);
assert.isTrue(ts1.hasScriptVersionCache_TestOnly(), "have script version cache - 2");
assert(ts1.hasScriptVersionCache_TestOnly(), "have script version cache - 2");
});
});
}

View file

@ -80,20 +80,47 @@ namespace ts.tscWatch {
checkOutputDoesNotContain(host, expectedNonAffectedFiles);
}
function checkOutputErrors(host: WatchedSystem, errors: ReadonlyArray<Diagnostic>, isInitial?: true, skipWaiting?: true) {
enum ExpectedOutputErrorsPosition {
BeforeCompilationStarts,
AfterCompilationStarting,
AfterFileChangeDetected
}
function checkOutputErrors(
host: WatchedSystem,
errors: ReadonlyArray<Diagnostic>,
errorsPosition: ExpectedOutputErrorsPosition,
skipWaiting?: true
) {
const outputs = host.getOutput();
const expectedOutputCount = (isInitial ? 0 : 1) + errors.length + (skipWaiting ? 0 : 1);
const expectedOutputCount = errors.length + (skipWaiting ? 0 : 1) + 1;
assert.equal(outputs.length, expectedOutputCount, "Outputs = " + outputs.toString());
let index = 0;
if (!isInitial) {
assertWatchDiagnosticAt(host, index, Diagnostics.File_change_detected_Starting_incremental_compilation);
index++;
let index: number;
switch (errorsPosition) {
case ExpectedOutputErrorsPosition.AfterCompilationStarting:
assertWatchDiagnosticAt(host, 0, Diagnostics.Starting_compilation_in_watch_mode);
index = 1;
break;
case ExpectedOutputErrorsPosition.AfterFileChangeDetected:
assertWatchDiagnosticAt(host, 0, Diagnostics.File_change_detected_Starting_incremental_compilation);
index = 1;
break;
case ExpectedOutputErrorsPosition.BeforeCompilationStarts:
assertWatchDiagnosticAt(host, errors.length, Diagnostics.Starting_compilation_in_watch_mode);
index = 0;
break;
}
forEach(errors, error => {
assertDiagnosticAt(host, index, error);
index++;
});
if (!skipWaiting) {
if (errorsPosition === ExpectedOutputErrorsPosition.BeforeCompilationStarts) {
assertWatchDiagnosticAt(host, index, ts.Diagnostics.Starting_compilation_in_watch_mode);
index += 1;
}
assertWatchDiagnosticAt(host, index, Diagnostics.Compilation_complete_Watching_for_file_changes);
}
host.clearOutput();
@ -106,7 +133,7 @@ namespace ts.tscWatch {
function assertWatchDiagnosticAt(host: WatchedSystem, outputAt: number, diagnosticMessage: DiagnosticMessage) {
const output = host.getOutput()[outputAt];
assert.isTrue(endsWith(output, getWatchDiagnosticWithoutDate(host, diagnosticMessage)), "outputs[" + outputAt + "] is " + output);
assert(endsWith(output, getWatchDiagnosticWithoutDate(host, diagnosticMessage)), "outputs[" + outputAt + "] is " + output);
}
function getWatchDiagnosticWithoutDate(host: WatchedSystem, diagnosticMessage: DiagnosticMessage) {
@ -333,13 +360,13 @@ namespace ts.tscWatch {
checkOutputErrors(host, [
getDiagnosticOfFileFromProgram(watch(), file1.path, file1.content.indexOf(commonFile2Name), commonFile2Name.length, Diagnostics.File_0_not_found, commonFile2.path),
getDiagnosticOfFileFromProgram(watch(), file1.path, file1.content.indexOf("y"), 1, Diagnostics.Cannot_find_name_0, "y")
], /*isInitial*/ true);
], /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterCompilationStarting);
host.reloadFS([file1, commonFile2, libFile]);
host.runQueuedTimeoutCallbacks();
checkProgramRootFiles(watch(), [file1.path]);
checkProgramActualFiles(watch(), [file1.path, libFile.path, commonFile2.path]);
checkOutputErrors(host, emptyArray);
checkOutputErrors(host, emptyArray, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterFileChangeDetected);
});
it("should reflect change in config file", () => {
@ -667,7 +694,7 @@ namespace ts.tscWatch {
const watch = createWatchModeWithConfigFile(config.path, host);
checkProgramActualFiles(watch(), [file1.path, file2.path, libFile.path]);
checkOutputErrors(host, emptyArray, /*isInitial*/ true);
checkOutputErrors(host, emptyArray, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterCompilationStarting);
host.reloadFS([file1, file2, libFile]);
host.checkTimeoutQueueLengthAndRun(1);
@ -675,7 +702,7 @@ namespace ts.tscWatch {
assert.equal(host.exitCode, ExitStatus.DiagnosticsPresent_OutputsSkipped);
checkOutputErrors(host, [
getDiagnosticWithoutFile(Diagnostics.File_0_not_found, config.path)
], /*isInitial*/ undefined, /*skipWaiting*/ true);
], /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterFileChangeDetected, /*skipWaiting*/ true);
});
it("Proper errors: document is not contained in project", () => {
@ -778,7 +805,7 @@ namespace ts.tscWatch {
};
const host = createWatchedSystem([moduleFile, file1, libFile]);
const watch = createWatchModeWithoutConfigFile([file1.path], host);
checkOutputErrors(host, emptyArray, /*isInitial*/ true);
checkOutputErrors(host, emptyArray, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterCompilationStarting);
const moduleFileOldPath = moduleFile.path;
const moduleFileNewPath = "/a/b/moduleFile1.ts";
@ -787,12 +814,12 @@ namespace ts.tscWatch {
host.runQueuedTimeoutCallbacks();
checkOutputErrors(host, [
getDiagnosticModuleNotFoundOfFile(watch(), file1, "./moduleFile")
]);
], /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterFileChangeDetected);
moduleFile.path = moduleFileOldPath;
host.reloadFS([moduleFile, file1, libFile]);
host.runQueuedTimeoutCallbacks();
checkOutputErrors(host, emptyArray);
checkOutputErrors(host, emptyArray, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterFileChangeDetected);
});
it("rename a module file and rename back should restore the states for configured projects", () => {
@ -810,7 +837,7 @@ namespace ts.tscWatch {
};
const host = createWatchedSystem([moduleFile, file1, configFile, libFile]);
const watch = createWatchModeWithConfigFile(configFile.path, host);
checkOutputErrors(host, emptyArray, /*isInitial*/ true);
checkOutputErrors(host, emptyArray, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterCompilationStarting);
const moduleFileOldPath = moduleFile.path;
const moduleFileNewPath = "/a/b/moduleFile1.ts";
@ -819,12 +846,12 @@ namespace ts.tscWatch {
host.runQueuedTimeoutCallbacks();
checkOutputErrors(host, [
getDiagnosticModuleNotFoundOfFile(watch(), file1, "./moduleFile")
]);
], /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterFileChangeDetected);
moduleFile.path = moduleFileOldPath;
host.reloadFS([moduleFile, file1, configFile, libFile]);
host.runQueuedTimeoutCallbacks();
checkOutputErrors(host, emptyArray);
checkOutputErrors(host, emptyArray, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterFileChangeDetected);
});
it("types should load from config file path if config exists", () => {
@ -863,11 +890,11 @@ namespace ts.tscWatch {
checkOutputErrors(host, [
getDiagnosticModuleNotFoundOfFile(watch(), file1, "./moduleFile")
], /*isInitial*/ true);
], /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterCompilationStarting);
host.reloadFS([file1, moduleFile, libFile]);
host.runQueuedTimeoutCallbacks();
checkOutputErrors(host, emptyArray);
checkOutputErrors(host, emptyArray, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterFileChangeDetected);
});
it("Configure file diagnostics events are generated when the config file has errors", () => {
@ -890,7 +917,7 @@ namespace ts.tscWatch {
checkOutputErrors(host, [
getUnknownCompilerOption(watch(), configFile, "foo"),
getUnknownCompilerOption(watch(), configFile, "allowJS")
], /*isInitial*/ true);
], /*errorsPosition*/ ExpectedOutputErrorsPosition.BeforeCompilationStarts);
});
it("If config file doesnt have errors, they are not reported", () => {
@ -907,7 +934,7 @@ namespace ts.tscWatch {
const host = createWatchedSystem([file, configFile, libFile]);
createWatchModeWithConfigFile(configFile.path, host);
checkOutputErrors(host, emptyArray, /*isInitial*/ true);
checkOutputErrors(host, emptyArray, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterCompilationStarting);
});
it("Reports errors when the config file changes", () => {
@ -924,7 +951,7 @@ namespace ts.tscWatch {
const host = createWatchedSystem([file, configFile, libFile]);
const watch = createWatchModeWithConfigFile(configFile.path, host);
checkOutputErrors(host, emptyArray, /*isInitial*/ true);
checkOutputErrors(host, emptyArray, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterCompilationStarting);
configFile.content = `{
"compilerOptions": {
@ -935,14 +962,14 @@ namespace ts.tscWatch {
host.runQueuedTimeoutCallbacks();
checkOutputErrors(host, [
getUnknownCompilerOption(watch(), configFile, "haha")
]);
], /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterFileChangeDetected);
configFile.content = `{
"compilerOptions": {}
}`;
host.reloadFS([file, configFile, libFile]);
host.runQueuedTimeoutCallbacks();
checkOutputErrors(host, emptyArray);
checkOutputErrors(host, emptyArray, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterFileChangeDetected);
});
it("non-existing directories listed in config file input array should be tolerated without crashing the server", () => {
@ -1030,13 +1057,13 @@ namespace ts.tscWatch {
getDiagnosticOfFile(watch().getCompilerOptions().configFile, configFile.content.indexOf('"declaration"'), '"declaration"'.length, Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration")
];
const intialErrors = errors();
checkOutputErrors(host, intialErrors, /*isInitial*/ true);
checkOutputErrors(host, intialErrors, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterCompilationStarting);
configFile.content = configFileContentWithoutCommentLine;
host.reloadFS(files);
host.runQueuedTimeoutCallbacks();
const nowErrors = errors();
checkOutputErrors(host, nowErrors);
checkOutputErrors(host, nowErrors, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterFileChangeDetected);
assert.equal(nowErrors[0].start, intialErrors[0].start - configFileContentComment.length);
assert.equal(nowErrors[1].start, intialErrors[1].start - configFileContentComment.length);
});
@ -1516,11 +1543,11 @@ namespace ts.tscWatch {
function verifyEmittedFiles(host: WatchedSystem, emittedFiles: EmittedFile[]) {
for (const { path, content, shouldBeWritten } of emittedFiles) {
if (shouldBeWritten) {
assert.isTrue(host.fileExists(path), `Expected file ${path} to be present`);
assert(host.fileExists(path), `Expected file ${path} to be present`);
assert.equal(host.readFile(path), content, `Contents of file ${path} do not match`);
}
else {
assert.isNotTrue(host.fileExists(path), `Expected file ${path} to be absent`);
assert(!host.fileExists(path), `Expected file ${path} to be absent`);
}
}
}
@ -1667,7 +1694,7 @@ namespace ts.tscWatch {
const cannotFindFoo = getDiagnosticOfFileFromProgram(watch(), imported.path, imported.content.indexOf("foo"), "foo".length, Diagnostics.Cannot_find_name_0, "foo");
// ensure that imported file was found
checkOutputErrors(host, [f1IsNotModule, cannotFindFoo], /*isInitial*/ true);
checkOutputErrors(host, [f1IsNotModule, cannotFindFoo], /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterCompilationStarting);
const originalFileExists = host.fileExists;
{
@ -1687,7 +1714,7 @@ namespace ts.tscWatch {
f1IsNotModule,
getDiagnosticOfFileFromProgram(watch(), root.path, newContent.indexOf("var x") + "var ".length, "x".length, Diagnostics.Type_0_is_not_assignable_to_type_1, 1, "string"),
cannotFindFoo
]);
], /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterFileChangeDetected);
}
{
let fileExistsIsCalled = false;
@ -1696,7 +1723,7 @@ namespace ts.tscWatch {
return false;
}
fileExistsIsCalled = true;
assert.isTrue(fileName.indexOf("/f2.") !== -1);
assert(fileName.indexOf("/f2.") !== -1);
return originalFileExists.call(host, fileName);
};
@ -1709,9 +1736,9 @@ namespace ts.tscWatch {
// ensure file has correct number of errors after edit
checkOutputErrors(host, [
getDiagnosticModuleNotFoundOfFile(watch(), root, "f2")
]);
], /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterFileChangeDetected);
assert.isTrue(fileExistsIsCalled);
assert(fileExistsIsCalled);
}
{
let fileExistsCalled = false;
@ -1720,7 +1747,7 @@ namespace ts.tscWatch {
return false;
}
fileExistsCalled = true;
assert.isTrue(fileName.indexOf("/f1.") !== -1);
assert(fileName.indexOf("/f1.") !== -1);
return originalFileExists.call(host, fileName);
};
@ -1730,8 +1757,8 @@ namespace ts.tscWatch {
host.reloadFS(files);
host.runQueuedTimeoutCallbacks();
checkOutputErrors(host, [f1IsNotModule, cannotFindFoo]);
assert.isTrue(fileExistsCalled);
checkOutputErrors(host, [f1IsNotModule, cannotFindFoo], /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterFileChangeDetected);
assert(fileExistsCalled);
}
});
@ -1764,18 +1791,18 @@ namespace ts.tscWatch {
const watch = createWatchModeWithoutConfigFile([root.path], host, { module: ModuleKind.AMD });
assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called");
assert(fileExistsCalledForBar, "'fileExists' should be called");
checkOutputErrors(host, [
getDiagnosticModuleNotFoundOfFile(watch(), root, "bar")
], /*isInitial*/ true);
], /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterCompilationStarting);
fileExistsCalledForBar = false;
root.content = `import {y} from "bar"`;
host.reloadFS(files.concat(imported));
host.runQueuedTimeoutCallbacks();
assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called.");
checkOutputErrors(host, emptyArray);
checkOutputErrors(host, emptyArray, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterFileChangeDetected);
assert(fileExistsCalledForBar, "'fileExists' should be called.");
});
it("should compile correctly when resolved module goes missing and then comes back (module is not part of the root)", () => {
@ -1806,22 +1833,22 @@ namespace ts.tscWatch {
const watch = createWatchModeWithoutConfigFile([root.path], host, { module: ModuleKind.AMD });
assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called");
checkOutputErrors(host, emptyArray, /*isInitial*/ true);
assert(fileExistsCalledForBar, "'fileExists' should be called");
checkOutputErrors(host, emptyArray, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterCompilationStarting);
fileExistsCalledForBar = false;
host.reloadFS(files);
host.runQueuedTimeoutCallbacks();
assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called.");
assert(fileExistsCalledForBar, "'fileExists' should be called.");
checkOutputErrors(host, [
getDiagnosticModuleNotFoundOfFile(watch(), root, "bar")
]);
], /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterFileChangeDetected);
fileExistsCalledForBar = false;
host.reloadFS(filesWithImported);
host.checkTimeoutQueueLengthAndRun(1);
assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called.");
checkOutputErrors(host, emptyArray);
checkOutputErrors(host, emptyArray, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterFileChangeDetected);
assert(fileExistsCalledForBar, "'fileExists' should be called.");
});
it("works when module resolution changes to ambient module", () => {
@ -1857,11 +1884,11 @@ declare module "fs" {
checkOutputErrors(host, [
getDiagnosticModuleNotFoundOfFile(watch(), root, "fs")
], /*isInitial*/ true);
], /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterCompilationStarting);
host.reloadFS(filesWithNodeType);
host.runQueuedTimeoutCallbacks();
checkOutputErrors(host, emptyArray);
checkOutputErrors(host, emptyArray, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterFileChangeDetected);
});
it("works when included file with ambient module changes", () => {
@ -1899,12 +1926,12 @@ declare module "fs" {
checkOutputErrors(host, [
getDiagnosticModuleNotFoundOfFile(watch(), root, "fs")
], /*isInitial*/ true);
], /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterCompilationStarting);
file.content += fileContentWithFS;
host.reloadFS(files);
host.runQueuedTimeoutCallbacks();
checkOutputErrors(host, emptyArray);
checkOutputErrors(host, emptyArray, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterFileChangeDetected);
});
it("works when reusing program with files from external library", () => {
@ -1939,7 +1966,7 @@ declare module "fs" {
const host = createWatchedSystem(programFiles.concat(configFile), { currentDirectory: "/a/b/projects/myProject/" });
const watch = createWatchModeWithConfigFile(configFile.path, host);
checkProgramActualFiles(watch(), programFiles.map(f => f.path));
checkOutputErrors(host, emptyArray, /*isInitial*/ true);
checkOutputErrors(host, emptyArray, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterCompilationStarting);
const expectedFiles: ExpectedFile[] = [
createExpectedEmittedFile(file1),
createExpectedEmittedFile(file2),
@ -1958,7 +1985,7 @@ declare module "fs" {
host.reloadFS(programFiles.concat(configFile));
host.runQueuedTimeoutCallbacks();
checkProgramActualFiles(watch(), programFiles.map(f => f.path));
checkOutputErrors(host, emptyArray);
checkOutputErrors(host, emptyArray, /*errorsPosition*/ ExpectedOutputErrorsPosition.AfterFileChangeDetected);
verifyExpectedFiles(expectedFiles);
@ -2023,13 +2050,13 @@ declare module "fs" {
checkProgramActualFiles(watch(), mapDefined(files, f => f === configFile ? undefined : f.path));
const outputFile1 = changeExtension((outputFolder + getBaseFileName(file1.path)), ".js");
assert.isTrue(host.fileExists(outputFile1));
assert(host.fileExists(outputFile1));
assert.equal(host.readFile(outputFile1), file1.content + host.newLine);
});
});
describe("tsc-watch console clearing", () => {
it("doesn't clear the console when it starts", () => {
it("clears the console when it starts", () => {
const file = {
path: "f.ts",
content: ""
@ -2039,7 +2066,7 @@ declare module "fs" {
createWatchModeWithoutConfigFile([file.path], host);
host.runQueuedTimeoutCallbacks();
host.checkScreenClears(0);
host.checkScreenClears(1);
});
it("clears the console on recompile", () => {
@ -2057,7 +2084,7 @@ declare module "fs" {
host.reloadFS([modifiedFile]);
host.runQueuedTimeoutCallbacks();
host.checkScreenClears(1);
host.checkScreenClears(2);
});
});
}

View file

@ -11,20 +11,20 @@ namespace ts {
function assertParseError(jsonText: string) {
const parsed = ts.parseConfigFileTextToJson("/apath/tsconfig.json", jsonText);
assert.deepEqual(parsed.config, {});
assert.isTrue(undefined !== parsed.error);
assert(undefined !== parsed.error);
}
function assertParseErrorWithExcludesKeyword(jsonText: string) {
{
const parsed = ts.parseConfigFileTextToJson("/apath/tsconfig.json", jsonText);
const parsedCommand = ts.parseJsonConfigFileContent(parsed.config, ts.sys, "tests/cases/unittests");
assert.isTrue(parsedCommand.errors && parsedCommand.errors.length === 1 &&
assert(parsedCommand.errors && parsedCommand.errors.length === 1 &&
parsedCommand.errors[0].code === ts.Diagnostics.Unknown_option_excludes_Did_you_mean_exclude.code);
}
{
const parsed = ts.parseJsonText("/apath/tsconfig.json", jsonText);
const parsedCommand = ts.parseJsonSourceFileConfigFileContent(parsed, ts.sys, "tests/cases/unittests");
assert.isTrue(parsedCommand.errors && parsedCommand.errors.length === 1 &&
assert(parsedCommand.errors && parsedCommand.errors.length === 1 &&
parsedCommand.errors[0].code === ts.Diagnostics.Unknown_option_excludes_Did_you_mean_exclude.code);
}
}
@ -44,26 +44,26 @@ namespace ts {
function assertParseFileList(jsonText: string, configFileName: string, basePath: string, allFileList: string[], expectedFileList: string[]) {
{
const parsed = getParsedCommandJson(jsonText, configFileName, basePath, allFileList);
assert.isTrue(arrayIsEqualTo(parsed.fileNames.sort(), expectedFileList.sort()));
assert(arrayIsEqualTo(parsed.fileNames.sort(), expectedFileList.sort()));
}
{
const parsed = getParsedCommandJsonNode(jsonText, configFileName, basePath, allFileList);
assert.isTrue(arrayIsEqualTo(parsed.fileNames.sort(), expectedFileList.sort()));
assert(arrayIsEqualTo(parsed.fileNames.sort(), expectedFileList.sort()));
}
}
function assertParseFileDiagnostics(jsonText: string, configFileName: string, basePath: string, allFileList: string[], expectedDiagnosticCode: number, noLocation?: boolean) {
{
const parsed = getParsedCommandJson(jsonText, configFileName, basePath, allFileList);
assert.isTrue(parsed.errors.length >= 0);
assert.isTrue(parsed.errors.filter(e => e.code === expectedDiagnosticCode).length > 0, `Expected error code ${expectedDiagnosticCode} to be in ${JSON.stringify(parsed.errors)}`);
assert(parsed.errors.length >= 0);
assert(parsed.errors.filter(e => e.code === expectedDiagnosticCode).length > 0, `Expected error code ${expectedDiagnosticCode} to be in ${JSON.stringify(parsed.errors)}`);
}
{
const parsed = getParsedCommandJsonNode(jsonText, configFileName, basePath, allFileList);
assert.isTrue(parsed.errors.length >= 0);
assert.isTrue(parsed.errors.filter(e => e.code === expectedDiagnosticCode).length > 0, `Expected error code ${expectedDiagnosticCode} to be in ${JSON.stringify(parsed.errors)}`);
assert(parsed.errors.length >= 0);
assert(parsed.errors.filter(e => e.code === expectedDiagnosticCode).length > 0, `Expected error code ${expectedDiagnosticCode} to be in ${JSON.stringify(parsed.errors)}`);
if (!noLocation) {
assert.isTrue(parsed.errors.filter(e => e.code === expectedDiagnosticCode && e.file && e.start && e.length).length > 0, `Expected error code ${expectedDiagnosticCode} to be in ${JSON.stringify(parsed.errors)} with location information`);
assert(parsed.errors.filter(e => e.code === expectedDiagnosticCode && e.file && e.start && e.length).length > 0, `Expected error code ${expectedDiagnosticCode} to be in ${JSON.stringify(parsed.errors)} with location information`);
}
}
}
@ -241,7 +241,7 @@ namespace ts {
},
files: ["file1.ts"]
};
assert.isTrue(diagnostics.length === 2);
assert(diagnostics.length === 2);
assert.equal(JSON.stringify(configJsonObject), JSON.stringify(expectedResult));
});

View file

@ -468,12 +468,12 @@ namespace ts.projectSystem {
assert.equal(outputs[index], server.formatMessage(expectedEvent, nullLogger, Utils.byteLength, session.host.newLine));
if (isMostRecent) {
assert.strictEqual(events.length, index + 1, JSON.stringify(events));
assert.strictEqual(outputs.length, index + 1, JSON.stringify(outputs));
assert.equal(events.length, index + 1, JSON.stringify(events));
assert.equal(outputs.length, index + 1, JSON.stringify(outputs));
}
}
describe("tsserverProjectSystem", () => {
describe("tsserverProjectSystem general functionality", () => {
const commonFile1: FileOrFolder = {
path: "/a/b/commonFile1.ts",
content: "let x = 1"
@ -572,8 +572,8 @@ namespace ts.projectSystem {
const projectService = createProjectService(host);
const { configFileName, configFileErrors } = projectService.openClientFile(file1.path);
assert(configFileName, "should find config file");
assert.isTrue(!configFileErrors || configFileErrors.length === 0, `expect no errors in config file, got ${JSON.stringify(configFileErrors)}`);
assert.isDefined(configFileName, "should find config file");
assert(!configFileErrors || configFileErrors.length === 0, `expect no errors in config file, got ${JSON.stringify(configFileErrors)}`);
checkNumberOfInferredProjects(projectService, 0);
checkNumberOfConfiguredProjects(projectService, 1);
@ -612,8 +612,8 @@ namespace ts.projectSystem {
const projectService = createProjectService(host);
const { configFileName, configFileErrors } = projectService.openClientFile(file1.path);
assert(configFileName, "should find config file");
assert.isTrue(!configFileErrors || configFileErrors.length === 0, `expect no errors in config file, got ${JSON.stringify(configFileErrors)}`);
assert.isDefined(configFileName, "should find config file");
assert(!configFileErrors || configFileErrors.length === 0, `expect no errors in config file, got ${JSON.stringify(configFileErrors)}`);
checkNumberOfInferredProjects(projectService, 0);
checkNumberOfConfiguredProjects(projectService, 1);
@ -821,7 +821,7 @@ namespace ts.projectSystem {
host.reloadFS([file1, commonFile2, libFile]);
host.runQueuedTimeoutCallbacks();
checkNumberOfInferredProjects(projectService, 1);
assert.strictEqual(projectService.inferredProjects[0], project, "Inferred project should be same");
assert.equal(projectService.inferredProjects[0], project, "Inferred project should be same");
checkProjectRootFiles(project, [file1.path]);
checkProjectActualFiles(project, [file1.path, libFile.path, commonFile2.path]);
diags = session.executeCommand(getErrRequest).response as server.protocol.Diagnostic[];
@ -1024,11 +1024,11 @@ namespace ts.projectSystem {
projectService.openExternalProject({ rootFiles: toExternalFiles([file1.path]), options: {}, projectFileName: proj1name });
const proj1 = projectService.findProject(proj1name);
assert.isTrue(proj1.languageServiceEnabled);
assert(proj1.languageServiceEnabled);
projectService.openExternalProject({ rootFiles: toExternalFiles([file2.path]), options: {}, projectFileName: proj2name });
const proj2 = projectService.findProject(proj2name);
assert.isTrue(proj2.languageServiceEnabled);
assert(proj2.languageServiceEnabled);
projectService.openExternalProject({ rootFiles: toExternalFiles([file3.path]), options: {}, projectFileName: proj3name });
const proj3 = projectService.findProject(proj3name);
@ -1100,18 +1100,18 @@ namespace ts.projectSystem {
projectService.openClientFile(file1.path);
checkNumberOfConfiguredProjects(projectService, 1);
const project = projectService.configuredProjects.get(configFile.path);
assert.isTrue(project.hasOpenRef()); // file1
assert(project.hasOpenRef()); // file1
projectService.closeClientFile(file1.path);
checkNumberOfConfiguredProjects(projectService, 1);
assert.strictEqual(projectService.configuredProjects.get(configFile.path), project);
assert.equal(projectService.configuredProjects.get(configFile.path), project);
assert.isFalse(project.hasOpenRef()); // No open files
assert.isFalse(project.isClosed());
projectService.openClientFile(file2.path);
checkNumberOfConfiguredProjects(projectService, 1);
assert.strictEqual(projectService.configuredProjects.get(configFile.path), project);
assert.isTrue(project.hasOpenRef()); // file2
assert.equal(projectService.configuredProjects.get(configFile.path), project);
assert(project.hasOpenRef()); // file2
assert.isFalse(project.isClosed());
});
@ -1134,18 +1134,18 @@ namespace ts.projectSystem {
projectService.openClientFile(file1.path);
checkNumberOfConfiguredProjects(projectService, 1);
const project = projectService.configuredProjects.get(configFile.path);
assert.isTrue(project.hasOpenRef()); // file1
assert(project.hasOpenRef()); // file1
projectService.closeClientFile(file1.path);
checkNumberOfConfiguredProjects(projectService, 1);
assert.strictEqual(projectService.configuredProjects.get(configFile.path), project);
assert.equal(projectService.configuredProjects.get(configFile.path), project);
assert.isFalse(project.hasOpenRef()); // No files
assert.isFalse(project.isClosed());
projectService.openClientFile(libFile.path);
checkNumberOfConfiguredProjects(projectService, 0);
assert.isFalse(project.hasOpenRef()); // No files + project closed
assert.isTrue(project.isClosed());
assert(project.isClosed());
});
it("should not close external project with no open files", () => {
@ -1233,28 +1233,28 @@ namespace ts.projectSystem {
// open client file - should not lead to creation of inferred project
projectService.openClientFile(file1.path, file1.content);
checkNumberOfProjects(projectService, { configuredProjects: 2 });
assert.strictEqual(projectService.configuredProjects.get(config1.path), proj1);
assert.strictEqual(projectService.configuredProjects.get(config2.path), proj2);
assert.equal(projectService.configuredProjects.get(config1.path), proj1);
assert.equal(projectService.configuredProjects.get(config2.path), proj2);
projectService.openClientFile(file3.path, file3.content);
checkNumberOfProjects(projectService, { configuredProjects: 2, inferredProjects: 1 });
assert.strictEqual(projectService.configuredProjects.get(config1.path), proj1);
assert.strictEqual(projectService.configuredProjects.get(config2.path), proj2);
assert.equal(projectService.configuredProjects.get(config1.path), proj1);
assert.equal(projectService.configuredProjects.get(config2.path), proj2);
projectService.closeExternalProject(externalProjectName);
// open file 'file1' from configured project keeps project alive
checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 1 });
assert.strictEqual(projectService.configuredProjects.get(config1.path), proj1);
assert.equal(projectService.configuredProjects.get(config1.path), proj1);
assert.isUndefined(projectService.configuredProjects.get(config2.path));
projectService.closeClientFile(file3.path);
checkNumberOfProjects(projectService, { configuredProjects: 1 });
assert.strictEqual(projectService.configuredProjects.get(config1.path), proj1);
assert.equal(projectService.configuredProjects.get(config1.path), proj1);
assert.isUndefined(projectService.configuredProjects.get(config2.path));
projectService.closeClientFile(file1.path);
checkNumberOfProjects(projectService, { configuredProjects: 1 });
assert.strictEqual(projectService.configuredProjects.get(config1.path), proj1);
assert.equal(projectService.configuredProjects.get(config1.path), proj1);
assert.isUndefined(projectService.configuredProjects.get(config2.path));
projectService.openClientFile(file2.path, file2.content);
@ -1286,14 +1286,14 @@ namespace ts.projectSystem {
const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, { includeExternalModuleExports: false });
// should contain completions for string
assert.isTrue(completions1.entries.some(e => e.name === "charAt"), "should contain 'charAt'");
assert(completions1.entries.some(e => e.name === "charAt"), "should contain 'charAt'");
assert.isFalse(completions1.entries.some(e => e.name === "toExponential"), "should not contain 'toExponential'");
service.closeClientFile(f2.path);
const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 2, { includeExternalModuleExports: false });
// should contain completions for string
assert.isFalse(completions2.entries.some(e => e.name === "charAt"), "should not contain 'charAt'");
assert.isTrue(completions2.entries.some(e => e.name === "toExponential"), "should contain 'toExponential'");
assert(completions2.entries.some(e => e.name === "toExponential"), "should contain 'toExponential'");
});
it("clear mixed content file after closing", () => {
@ -1317,7 +1317,7 @@ namespace ts.projectSystem {
checkProjectActualFiles(service.externalProjects[0], [f1.path, f2.path, libFile.path]);
const completions1 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, { includeExternalModuleExports: false });
assert.isTrue(completions1.entries.some(e => e.name === "somelongname"), "should contain 'somelongname'");
assert(completions1.entries.some(e => e.name === "somelongname"), "should contain 'somelongname'");
service.closeClientFile(f2.path);
const completions2 = service.externalProjects[0].getLanguageService().getCompletionsAtPosition(f1.path, 0, { includeExternalModuleExports: false });
@ -1387,16 +1387,16 @@ namespace ts.projectSystem {
});
checkNumberOfProjects(projectService, { configuredProjects: 1 });
assert.strictEqual(projectService.configuredProjects.get(configFile.path), project);
assert.equal(projectService.configuredProjects.get(configFile.path), project);
projectService.closeExternalProject(externalProjectName);
// configured project is alive since file is still open
checkNumberOfProjects(projectService, { configuredProjects: 1 });
assert.strictEqual(projectService.configuredProjects.get(configFile.path), project);
assert.equal(projectService.configuredProjects.get(configFile.path), project);
projectService.closeClientFile(file1.path);
checkNumberOfProjects(projectService, { configuredProjects: 1 });
assert.strictEqual(projectService.configuredProjects.get(configFile.path), project);
assert.equal(projectService.configuredProjects.get(configFile.path), project);
projectService.openClientFile(file2.path);
checkNumberOfProjects(projectService, { inferredProjects: 1 });
@ -1910,7 +1910,7 @@ namespace ts.projectSystem {
// The configured project should now be updated to include html file
checkNumberOfProjects(projectService, { configuredProjects: 1 });
assert.strictEqual(configuredProjectAt(projectService, 0), configuredProj, "Same configured project should be updated");
assert.equal(configuredProjectAt(projectService, 0), configuredProj, "Same configured project should be updated");
checkProjectActualFiles(configuredProjectAt(projectService, 0), [file1.path, file2.path, config.path]);
// Open HTML file
@ -2176,18 +2176,18 @@ namespace ts.projectSystem {
projectService.openClientFile(file2.path);
checkNumberOfProjects(projectService, { configuredProjects: 1 });
const project1 = projectService.configuredProjects.get(tsconfig1.path);
assert.isTrue(project1.hasOpenRef(), "Has open ref count in project1 - 1"); // file2
assert(project1.hasOpenRef(), "Has open ref count in project1 - 1"); // file2
assert.equal(project1.getScriptInfo(file2.path).containingProjects.length, 1, "containing projects count");
assert.isFalse(project1.isClosed());
projectService.openClientFile(file1.path);
checkNumberOfProjects(projectService, { configuredProjects: 2 });
assert.isTrue(project1.hasOpenRef(), "Has open ref count in project1 - 2"); // file2
assert.strictEqual(projectService.configuredProjects.get(tsconfig1.path), project1);
assert(project1.hasOpenRef(), "Has open ref count in project1 - 2"); // file2
assert.equal(projectService.configuredProjects.get(tsconfig1.path), project1);
assert.isFalse(project1.isClosed());
const project2 = projectService.configuredProjects.get(tsconfig2.path);
assert.isTrue(project2.hasOpenRef(), "Has open ref count in project2 - 2"); // file1
assert(project2.hasOpenRef(), "Has open ref count in project2 - 2"); // file1
assert.isFalse(project2.isClosed());
assert.equal(project1.getScriptInfo(file1.path).containingProjects.length, 2, `${file1.path} containing projects count`);
@ -2196,9 +2196,9 @@ namespace ts.projectSystem {
projectService.closeClientFile(file2.path);
checkNumberOfProjects(projectService, { configuredProjects: 2 });
assert.isFalse(project1.hasOpenRef(), "Has open ref count in project1 - 3"); // No files
assert.isTrue(project2.hasOpenRef(), "Has open ref count in project2 - 3"); // file1
assert.strictEqual(projectService.configuredProjects.get(tsconfig1.path), project1);
assert.strictEqual(projectService.configuredProjects.get(tsconfig2.path), project2);
assert(project2.hasOpenRef(), "Has open ref count in project2 - 3"); // file1
assert.equal(projectService.configuredProjects.get(tsconfig1.path), project1);
assert.equal(projectService.configuredProjects.get(tsconfig2.path), project2);
assert.isFalse(project1.isClosed());
assert.isFalse(project2.isClosed());
@ -2206,18 +2206,18 @@ namespace ts.projectSystem {
checkNumberOfProjects(projectService, { configuredProjects: 2 });
assert.isFalse(project1.hasOpenRef(), "Has open ref count in project1 - 4"); // No files
assert.isFalse(project2.hasOpenRef(), "Has open ref count in project2 - 4"); // No files
assert.strictEqual(projectService.configuredProjects.get(tsconfig1.path), project1);
assert.strictEqual(projectService.configuredProjects.get(tsconfig2.path), project2);
assert.equal(projectService.configuredProjects.get(tsconfig1.path), project1);
assert.equal(projectService.configuredProjects.get(tsconfig2.path), project2);
assert.isFalse(project1.isClosed());
assert.isFalse(project2.isClosed());
projectService.openClientFile(file2.path);
checkNumberOfProjects(projectService, { configuredProjects: 1 });
assert.strictEqual(projectService.configuredProjects.get(tsconfig1.path), project1);
assert.equal(projectService.configuredProjects.get(tsconfig1.path), project1);
assert.isUndefined(projectService.configuredProjects.get(tsconfig2.path));
assert.isTrue(project1.hasOpenRef(), "Has open ref count in project1 - 5"); // file2
assert(project1.hasOpenRef(), "Has open ref count in project1 - 5"); // file2
assert.isFalse(project1.isClosed());
assert.isTrue(project2.isClosed());
assert(project2.isClosed());
});
it("Open ref of configured project when open file gets added to the project as part of configured file update", () => {
@ -2255,7 +2255,7 @@ namespace ts.projectSystem {
checkOpenFiles(projectService, files);
checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 2 });
const configProject1 = projectService.configuredProjects.get(configFile.path);
assert.isTrue(configProject1.hasOpenRef()); // file1 and file3
assert(configProject1.hasOpenRef()); // file1 and file3
checkProjectActualFiles(configProject1, [file1.path, file3.path, configFile.path]);
const inferredProject1 = projectService.inferredProjects[0];
checkProjectActualFiles(inferredProject1, [file2.path]);
@ -2272,7 +2272,7 @@ namespace ts.projectSystem {
checkNumberOfInferredProjects(projectService, 1);
const inferredProject3 = projectService.inferredProjects[0];
checkProjectActualFiles(inferredProject3, [file4.path]);
assert.strictEqual(inferredProject3, inferredProject2);
assert.equal(inferredProject3, inferredProject2);
projectService.closeClientFile(file1.path);
projectService.closeClientFile(file2.path);
@ -2298,7 +2298,7 @@ namespace ts.projectSystem {
checkNumberOfInferredProjects(projectService, 1);
const inferredProject5 = projectService.inferredProjects[0];
checkProjectActualFiles(inferredProject4, [file4.path]);
assert.strictEqual(inferredProject5, inferredProject4);
assert.equal(inferredProject5, inferredProject4);
const file5: FileOrFolder = {
path: "/file5.ts",
@ -2307,13 +2307,13 @@ namespace ts.projectSystem {
host.reloadFS(files.concat(configFile, file5));
projectService.openClientFile(file5.path);
verifyScriptInfosAreUndefined([file1, file2, file3]);
assert.strictEqual(projectService.getScriptInfoForPath(file4.path as Path), find(infos, info => info.path === file4.path));
assert.equal(projectService.getScriptInfoForPath(file4.path as Path), find(infos, info => info.path === file4.path));
assert.isDefined(projectService.getScriptInfoForPath(file5.path as Path));
checkOpenFiles(projectService, [file4, file5]);
checkNumberOfConfiguredProjects(projectService, 0);
function verifyScriptInfos() {
infos.forEach(info => assert.strictEqual(projectService.getScriptInfoForPath(info.path), info));
infos.forEach(info => assert.equal(projectService.getScriptInfoForPath(info.path), info));
}
function verifyScriptInfosAreUndefined(files: FileOrFolder[]) {
@ -2325,7 +2325,7 @@ namespace ts.projectSystem {
function verifyConfiguredProjectStateAfterUpdate(hasOpenRef: boolean) {
checkNumberOfConfiguredProjects(projectService, 1);
const configProject2 = projectService.configuredProjects.get(configFile.path);
assert.strictEqual(configProject2, configProject1);
assert.equal(configProject2, configProject1);
checkProjectActualFiles(configProject2, [file1.path, file2.path, file3.path, configFile.path]);
assert.equal(configProject2.hasOpenRef(), hasOpenRef);
}
@ -2364,7 +2364,7 @@ namespace ts.projectSystem {
checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 1 });
const configuredProject = projectService.configuredProjects.get(configFile.path);
assert.isTrue(configuredProject.hasOpenRef()); // file1 and file3
assert(configuredProject.hasOpenRef()); // file1 and file3
checkProjectActualFiles(configuredProject, [file1.path, file3.path, configFile.path]);
const inferredProject1 = projectService.inferredProjects[0];
checkProjectActualFiles(inferredProject1, [file2.path]);
@ -2376,23 +2376,23 @@ namespace ts.projectSystem {
configFile.content = "{}";
host.reloadFS(files.concat(configFile));
// Time out is not yet run so there is project update pending
assert.isTrue(configuredProject.hasOpenRef()); // Pending update and file2 might get into the project
assert(configuredProject.hasOpenRef()); // Pending update and file2 might get into the project
projectService.openClientFile(file4.path);
checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 2 });
assert.strictEqual(projectService.configuredProjects.get(configFile.path), configuredProject);
assert.isTrue(configuredProject.hasOpenRef()); // Pending update and F2 might get into the project
assert.strictEqual(projectService.inferredProjects[0], inferredProject1);
assert.equal(projectService.configuredProjects.get(configFile.path), configuredProject);
assert(configuredProject.hasOpenRef()); // Pending update and F2 might get into the project
assert.equal(projectService.inferredProjects[0], inferredProject1);
const inferredProject2 = projectService.inferredProjects[1];
checkProjectActualFiles(inferredProject2, [file4.path]);
host.runQueuedTimeoutCallbacks();
checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 1 });
assert.strictEqual(projectService.configuredProjects.get(configFile.path), configuredProject);
assert.isTrue(configuredProject.hasOpenRef()); // file2
assert.equal(projectService.configuredProjects.get(configFile.path), configuredProject);
assert(configuredProject.hasOpenRef()); // file2
checkProjectActualFiles(configuredProject, [file1.path, file2.path, file3.path, configFile.path]);
assert.strictEqual(projectService.inferredProjects[0], inferredProject2);
assert.equal(projectService.inferredProjects[0], inferredProject2);
checkProjectActualFiles(inferredProject2, [file4.path]);
});
@ -2427,7 +2427,7 @@ namespace ts.projectSystem {
options: {}
});
service.checkNumberOfProjects({ externalProjects: 1 });
assert.isTrue(service.externalProjects[0].languageServiceEnabled, "language service should be enabled");
assert(service.externalProjects[0].languageServiceEnabled, "language service should be enabled");
service.openExternalProject({
projectFileName,
@ -2464,12 +2464,12 @@ namespace ts.projectSystem {
projectService.openClientFile(f1.path);
projectService.checkNumberOfProjects({ configuredProjects: 1 });
const project = projectService.configuredProjects.get(config.path);
assert.isTrue(project.hasOpenRef()); // f1
assert(project.hasOpenRef()); // f1
assert.isFalse(project.isClosed());
projectService.closeClientFile(f1.path);
projectService.checkNumberOfProjects({ configuredProjects: 1 });
assert.strictEqual(projectService.configuredProjects.get(config.path), project);
assert.equal(projectService.configuredProjects.get(config.path), project);
assert.isFalse(project.hasOpenRef()); // No files
assert.isFalse(project.isClosed());
@ -2488,7 +2488,7 @@ namespace ts.projectSystem {
projectService.openClientFile(f4.path);
projectService.checkNumberOfProjects({ inferredProjects: 1 });
assert.isFalse(project.hasOpenRef()); // No files
assert.isTrue(project.isClosed());
assert(project.isClosed());
for (const f of [f1, f2, f3]) {
// All the script infos should not be present since the project is closed and orphan script infos are collected
@ -2540,7 +2540,7 @@ namespace ts.projectSystem {
checkNumberOfProjects(projectService, { configuredProjects: 1 });
const project = configuredProjectAt(projectService, 0);
assert.isFalse(project.languageServiceEnabled, "Language service enabled");
assert.isTrue(!!lastEvent, "should receive event");
assert(!!lastEvent, "should receive event");
assert.equal(lastEvent.data.project, project, "project name");
assert.equal(lastEvent.data.project.getProjectName(), config.path, "config path");
assert.isFalse(lastEvent.data.languageServiceEnabled, "Language service state");
@ -2548,9 +2548,9 @@ namespace ts.projectSystem {
host.reloadFS([f1, f2, configWithExclude]);
host.checkTimeoutQueueLengthAndRun(2);
checkNumberOfProjects(projectService, { configuredProjects: 1 });
assert.isTrue(project.languageServiceEnabled, "Language service enabled");
assert(project.languageServiceEnabled, "Language service enabled");
assert.equal(lastEvent.data.project, project, "project");
assert.isTrue(lastEvent.data.languageServiceEnabled, "Language service state");
assert(lastEvent.data.languageServiceEnabled, "Language service state");
});
it("syntactic features work even if language service is disabled", () => {
@ -2592,7 +2592,7 @@ namespace ts.projectSystem {
checkNumberOfProjects(projectService, { configuredProjects: 1 });
const project = configuredProjectAt(projectService, 0);
assert.isFalse(project.languageServiceEnabled, "Language service enabled");
assert.isTrue(!!lastEvent, "should receive event");
assert(!!lastEvent, "should receive event");
assert.equal(lastEvent.data.project, project, "project name");
assert.isFalse(lastEvent.data.languageServiceEnabled, "Language service state");
@ -2747,7 +2747,7 @@ namespace ts.projectSystem {
host.runQueuedTimeoutCallbacks();
watchedRecursiveDirectories.pop();
checkNumberOfProjects(projectService, { configuredProjects: 1 });
assert.strictEqual(projectService.configuredProjects.get(configFile.path), project);
assert.equal(projectService.configuredProjects.get(configFile.path), project);
checkProjectActualFiles(project, mapDefined(files, file => file === file2a ? undefined : file.path));
checkWatchedFiles(host, mapDefined(files, file => file === file1 ? undefined : file.path));
checkWatchedDirectories(host, [], /*recursive*/ false);
@ -2756,7 +2756,7 @@ namespace ts.projectSystem {
// On next file open the files file2a should be closed and not watched any more
projectService.openClientFile(file2.path);
checkNumberOfProjects(projectService, { configuredProjects: 1 });
assert.strictEqual(projectService.configuredProjects.get(configFile.path), project);
assert.equal(projectService.configuredProjects.get(configFile.path), project);
checkProjectActualFiles(project, mapDefined(files, file => file === file2a ? undefined : file.path));
checkWatchedFiles(host, [libFile.path, configFile.path]);
checkWatchedDirectories(host, [], /*recursive*/ false);
@ -2806,7 +2806,7 @@ namespace ts.projectSystem {
});
describe("Proper errors", () => {
describe("tsserverProjectSystem Proper errors", () => {
it("document is not contained in project", () => {
const file1 = {
path: "/a/b/app.ts",
@ -2960,7 +2960,7 @@ namespace ts.projectSystem {
});
});
describe("autoDiscovery", () => {
describe("tsserverProjectSystem autoDiscovery", () => {
it("does not depend on extension", () => {
const file1 = {
path: "/a/b/app.html",
@ -2979,11 +2979,11 @@ namespace ts.projectSystem {
});
projectService.checkNumberOfProjects({ externalProjects: 1 });
const typeAcquisition = projectService.externalProjects[0].getTypeAcquisition();
assert.isTrue(typeAcquisition.enable, "Typine acquisition should be enabled");
assert(typeAcquisition.enable, "Typine acquisition should be enabled");
});
});
describe("extra resolution pass in lshost", () => {
describe("tsserverProjectSystem extra resolution pass in lshost", () => {
it("can load typings that are proper modules", () => {
const file1 = {
path: "/a/b/app.js",
@ -3025,7 +3025,7 @@ namespace ts.projectSystem {
});
});
describe("navigate-to for javascript project", () => {
describe("tsserverProjectSystem navigate-to for javascript project", () => {
function containsNavToItem(items: protocol.NavtoItem[], itemName: string, itemKind: string) {
return find(items, item => item.name === itemName && item.kind === itemKind) !== undefined;
}
@ -3050,11 +3050,11 @@ namespace ts.projectSystem {
const localFunctionNavToRequst = makeSessionRequest<protocol.NavtoRequestArgs>(CommandNames.Navto, { searchValue: "foo", file: file1.path, projectFileName: configFile.path });
const items2 = session.executeCommand(localFunctionNavToRequst).response as protocol.NavtoItem[];
assert.isTrue(containsNavToItem(items2, "foo", "function"), `Cannot find function symbol "foo".`);
assert(containsNavToItem(items2, "foo", "function"), `Cannot find function symbol "foo".`);
});
});
describe("external projects", () => {
describe("tsserverProjectSystem external projects", () => {
it("correctly handling add/remove tsconfig - 1", () => {
const f1 = {
path: "/a/b/app.ts",
@ -3264,23 +3264,23 @@ namespace ts.projectSystem {
projectService.openClientFile(f.path);
projectService.checkNumberOfProjects({ configuredProjects: 1 });
const project = projectService.configuredProjects.get(config.path);
assert.isTrue(project.hasOpenRef()); // f
assert(project.hasOpenRef()); // f
projectService.closeClientFile(f.path);
projectService.checkNumberOfProjects({ configuredProjects: 1 });
assert.strictEqual(projectService.configuredProjects.get(config.path), project);
assert.equal(projectService.configuredProjects.get(config.path), project);
assert.isFalse(project.hasOpenRef()); // No files
assert.isFalse(project.isClosed());
projectService.openClientFile(f.path);
projectService.checkNumberOfProjects({ configuredProjects: 1 });
assert.strictEqual(projectService.configuredProjects.get(config.path), project);
assert.isTrue(project.hasOpenRef()); // f
assert.equal(projectService.configuredProjects.get(config.path), project);
assert(project.hasOpenRef()); // f
assert.isFalse(project.isClosed());
});
});
describe("prefer typings to js", () => {
describe("tsserverProjectSystem prefer typings to js", () => {
it("during second resolution pass", () => {
const typingsCacheLocation = "/a/typings";
const f1 = {
@ -3308,7 +3308,7 @@ namespace ts.projectSystem {
});
});
describe("format settings", () => {
describe("tsserverProjectSystem format settings", () => {
it("can be set globally", () => {
const f1 = {
path: "/a/b/app.ts",
@ -3349,7 +3349,7 @@ namespace ts.projectSystem {
});
});
describe("watching @types", () => {
describe("tsserverProjectSystem watching @types", () => {
it("works correctly when typings are added or removed", () => {
const f1 = {
path: "/a/b/app.ts",
@ -3395,7 +3395,7 @@ namespace ts.projectSystem {
});
});
describe("Open-file", () => {
describe("tsserverProjectSystem Open-file", () => {
it("can be reloaded with empty content", () => {
const f = {
path: "/a/b/app.ts",
@ -3470,7 +3470,7 @@ namespace ts.projectSystem {
});
});
describe("Language service", () => {
describe("tsserverProjectSystem Language service", () => {
it("should work correctly on case-sensitive file systems", () => {
const lib = {
path: "/a/Lib/lib.d.ts",
@ -3488,7 +3488,7 @@ namespace ts.projectSystem {
});
});
describe("rename a module file and rename back", () => {
describe("tsserverProjectSystem rename a module file and rename back", () => {
it("should restore the states for inferred projects", () => {
const moduleFile = {
path: "/a/b/moduleFile.ts",
@ -3623,7 +3623,7 @@ namespace ts.projectSystem {
});
});
describe("add the missing module file for inferred project", () => {
describe("tsserverProjectSystem add the missing module file for inferred project", () => {
it("should remove the `module not found` error", () => {
const moduleFile = {
path: "/a/b/moduleFile.ts",
@ -3729,7 +3729,7 @@ namespace ts.projectSystem {
});
});
describe("Configure file diagnostics events", () => {
describe("tsserverProjectSystem Configure file diagnostics events", () => {
it("are generated when the config file has errors", () => {
const file = {
@ -3845,7 +3845,7 @@ namespace ts.projectSystem {
});
});
describe("skipLibCheck", () => {
describe("tsserverProjectSystem skipLibCheck", () => {
it("should be turned on for js-only inferred projects", () => {
const file1 = {
path: "/a/b/file1.js",
@ -3872,16 +3872,16 @@ namespace ts.projectSystem {
{ file: file2.path }
);
let errorResult = <protocol.Diagnostic[]>session.executeCommand(file2GetErrRequest).response;
assert.isTrue(errorResult.length === 0);
assert(errorResult.length === 0);
const closeFileRequest = makeSessionRequest<protocol.FileRequestArgs>(CommandNames.Close, { file: file1.path });
session.executeCommand(closeFileRequest);
errorResult = <protocol.Diagnostic[]>session.executeCommand(file2GetErrRequest).response;
assert.isTrue(errorResult.length !== 0);
assert(errorResult.length !== 0);
openFilesForSession([file1], session);
errorResult = <protocol.Diagnostic[]>session.executeCommand(file2GetErrRequest).response;
assert.isTrue(errorResult.length === 0);
assert(errorResult.length === 0);
});
it("should be turned on for js-only external projects", () => {
@ -3917,7 +3917,7 @@ namespace ts.projectSystem {
{ file: dTsFile.path }
);
const errorResult = <protocol.Diagnostic[]>session.executeCommand(dTsFileGetErrRequest).response;
assert.isTrue(errorResult.length === 0);
assert(errorResult.length === 0);
});
it("should be turned on for js-only external projects with skipLibCheck=false", () => {
@ -3953,7 +3953,7 @@ namespace ts.projectSystem {
{ file: dTsFile.path }
);
const errorResult = <protocol.Diagnostic[]>session.executeCommand(dTsFileGetErrRequest).response;
assert.isTrue(errorResult.length === 0);
assert(errorResult.length === 0);
});
it("should not report bind errors for declaration files with skipLibCheck=true", () => {
@ -3984,14 +3984,14 @@ namespace ts.projectSystem {
{ file: dTsFile1.path }
);
const error1Result = <protocol.Diagnostic[]>session.executeCommand(dTsFile1GetErrRequest).response;
assert.isTrue(error1Result.length === 0);
assert(error1Result.length === 0);
const dTsFile2GetErrRequest = makeSessionRequest<protocol.SemanticDiagnosticsSyncRequestArgs>(
CommandNames.SemanticDiagnosticsSync,
{ file: dTsFile2.path }
);
const error2Result = <protocol.Diagnostic[]>session.executeCommand(dTsFile2GetErrRequest).response;
assert.isTrue(error2Result.length === 0);
assert(error2Result.length === 0);
});
it("should report semanitc errors for loose JS files with '// @ts-check' and skipLibCheck=true", () => {
@ -4012,7 +4012,7 @@ namespace ts.projectSystem {
{ file: jsFile.path }
);
const errorResult = <protocol.Diagnostic[]>session.executeCommand(getErrRequest).response;
assert.isTrue(errorResult.length === 1);
assert(errorResult.length === 1);
assert.equal(errorResult[0].code, Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2.code);
});
@ -4039,7 +4039,7 @@ namespace ts.projectSystem {
{ file: jsFile.path }
);
const errorResult = <protocol.Diagnostic[]>session.executeCommand(getErrRequest).response;
assert.isTrue(errorResult.length === 1);
assert(errorResult.length === 1);
assert.equal(errorResult[0].code, Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2.code);
});
@ -4068,12 +4068,12 @@ namespace ts.projectSystem {
{ file: jsFile.path }
);
const errorResult = <protocol.Diagnostic[]>session.executeCommand(getErrRequest).response;
assert.isTrue(errorResult.length === 1);
assert(errorResult.length === 1);
assert.equal(errorResult[0].code, Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2.code);
});
});
describe("non-existing directories listed in config file input array", () => {
describe("tsserverProjectSystem non-existing directories listed in config file input array", () => {
it("should be tolerated without crashing the server", () => {
const configFile = {
path: "/a/b/tsconfig.json",
@ -4096,7 +4096,7 @@ namespace ts.projectSystem {
checkNumberOfInferredProjects(projectService, 1);
const inferredProject = projectService.inferredProjects[0];
assert.isTrue(inferredProject.containsFile(<server.NormalizedPath>file1.path));
assert(inferredProject.containsFile(<server.NormalizedPath>file1.path));
});
it("should be able to handle @types if input file list is empty", () => {
@ -4128,7 +4128,7 @@ namespace ts.projectSystem {
});
});
describe("reload", () => {
describe("tsserverProjectSystem reload", () => {
it("should work with temp file", () => {
const f1 = {
path: "/a/b/app.ts",
@ -4236,7 +4236,7 @@ namespace ts.projectSystem {
arguments: { file: f1.path }
});
checkScriptInfoAndProjects(0, f1.content, "contents of closed file");
assert.strictEqual(info.getSnapshot(), snap);
assert.equal(info.getSnapshot(), snap);
// reload from temp file
session.executeCommandSeq(<server.protocol.ReloadRequest>{
@ -4244,7 +4244,7 @@ namespace ts.projectSystem {
arguments: { file: f1.path, tmpfile: tmp.path }
});
checkScriptInfoAndProjects(0, tmp.content, "contents of temp file");
assert.notStrictEqual(info.getSnapshot(), snap);
assert.notEqual(info.getSnapshot(), snap);
// reload from own file
session.executeCommandSeq(<server.protocol.ReloadRequest>{
@ -4252,11 +4252,11 @@ namespace ts.projectSystem {
arguments: { file: f1.path }
});
checkScriptInfoAndProjects(0, f1.content, "contents of closed file");
assert.notStrictEqual(info.getSnapshot(), snap);
assert.notEqual(info.getSnapshot(), snap);
function checkScriptInfoAndProjects(inferredProjects: number, contentsOfInfo: string, captionForContents: string) {
checkNumberOfProjects(projectService, { inferredProjects });
assert.strictEqual(projectService.getScriptInfo(f1.path), info);
assert.equal(projectService.getScriptInfo(f1.path), info);
checkScriptInfoContents(contentsOfInfo, captionForContents);
}
@ -4267,7 +4267,7 @@ namespace ts.projectSystem {
});
});
describe("Inferred projects", () => {
describe("tsserverProjectSystem Inferred projects", () => {
it("should support files without extensions", () => {
const f = {
path: "/a/compile",
@ -4495,7 +4495,7 @@ namespace ts.projectSystem {
});
});
describe("No overwrite emit error", () => {
describe("tsserverProjectSystem No overwrite emit error", () => {
it("for inferred project", () => {
const f1 = {
path: "/a/b/f1.js",
@ -4515,7 +4515,7 @@ namespace ts.projectSystem {
seq: 2,
arguments: { projectFileName: projectName }
}).response as ReadonlyArray<protocol.DiagnosticWithLinePosition>;
assert.isTrue(diags.length === 0);
assert(diags.length === 0);
session.executeCommand(<server.protocol.SetCompilerOptionsForInferredProjectsRequest>{
type: "request",
@ -4529,7 +4529,7 @@ namespace ts.projectSystem {
seq: 4,
arguments: { projectFileName: projectName }
}).response as ReadonlyArray<protocol.DiagnosticWithLinePosition>;
assert.isTrue(diagsAfterUpdate.length === 0);
assert(diagsAfterUpdate.length === 0);
});
it("for external project", () => {
@ -4556,7 +4556,7 @@ namespace ts.projectSystem {
seq: 2,
arguments: { projectFileName }
}).response as ReadonlyArray<ts.server.protocol.DiagnosticWithLinePosition>;
assert.isTrue(diags.length === 0);
assert(diags.length === 0);
session.executeCommand(<server.protocol.OpenExternalProjectRequest>{
type: "request",
@ -4574,11 +4574,11 @@ namespace ts.projectSystem {
seq: 4,
arguments: { projectFileName }
}).response as ReadonlyArray<ts.server.protocol.DiagnosticWithLinePosition>;
assert.isTrue(diagsAfterUpdate.length === 0);
assert(diagsAfterUpdate.length === 0);
});
});
describe("emit with outFile or out setting", () => {
describe("tsserverProjectSystem emit with outFile or out setting", () => {
function test(opts: CompilerOptions, expectedUsesOutFile: boolean) {
const f1 = {
path: "/a/a.ts",
@ -4626,7 +4626,7 @@ namespace ts.projectSystem {
});
});
describe("import helpers", () => {
describe("tsserverProjectSystem import helpers", () => {
it("should not crash in tsserver", () => {
const f1 = {
path: "/a/app.ts",
@ -4643,7 +4643,7 @@ namespace ts.projectSystem {
});
});
describe("searching for config file", () => {
describe("tsserverProjectSystem searching for config file", () => {
it("should stop at projectRootPath if given", () => {
const f1 = {
path: "/a/file1.ts",
@ -4735,7 +4735,7 @@ namespace ts.projectSystem {
});
});
describe("cancellationToken", () => {
describe("tsserverProjectSystem cancellationToken", () => {
// Disable sourcemap support for the duration of the test, as sourcemapping the errors generated during this test is slow and not something we care to test
let oldPrepare: ts.AnyFunction;
before(() => {
@ -4758,7 +4758,7 @@ namespace ts.projectSystem {
isCancellationRequested: () => false,
setRequest: requestId => {
if (expectedRequestId === undefined) {
assert.isTrue(false, "unexpected call");
assert(false, "unexpected call");
}
assert.equal(requestId, expectedRequestId);
},
@ -4998,7 +4998,7 @@ namespace ts.projectSystem {
});
});
describe("occurence highlight on string", () => {
describe("tsserverProjectSystem occurence highlight on string", () => {
it("should be marked if only on string values", () => {
const file1: FileOrFolder = {
path: "/a/b/file1.ts",
@ -5017,7 +5017,7 @@ namespace ts.projectSystem {
);
const highlightResponse = session.executeCommand(highlightRequest).response as protocol.OccurrencesResponseItem[];
const firstOccurence = highlightResponse[0];
assert.isTrue(firstOccurence.isInString, "Highlights should be marked with isInString");
assert(firstOccurence.isInString, "Highlights should be marked with isInString");
}
{
@ -5026,7 +5026,7 @@ namespace ts.projectSystem {
{ file: file1.path, line: 3, offset: 13 }
);
const highlightResponse = session.executeCommand(highlightRequest).response as protocol.OccurrencesResponseItem[];
assert.isTrue(highlightResponse.length === 2);
assert(highlightResponse.length === 2);
const firstOccurence = highlightResponse[0];
assert.isUndefined(firstOccurence.isInString, "Highlights should not be marked with isInString if on property name");
}
@ -5037,14 +5037,14 @@ namespace ts.projectSystem {
{ file: file1.path, line: 4, offset: 14 }
);
const highlightResponse = session.executeCommand(highlightRequest).response as protocol.OccurrencesResponseItem[];
assert.isTrue(highlightResponse.length === 2);
assert(highlightResponse.length === 2);
const firstOccurence = highlightResponse[0];
assert.isUndefined(firstOccurence.isInString, "Highlights should not be marked with isInString if on indexer");
}
});
});
describe("maxNodeModuleJsDepth for inferred projects", () => {
describe("tsserverProjectSystem maxNodeModuleJsDepth for inferred projects", () => {
it("should be set to 2 if the project has js root files", () => {
const file1: FileOrFolder = {
path: "/a/b/file1.js",
@ -5061,13 +5061,13 @@ namespace ts.projectSystem {
let project = projectService.inferredProjects[0];
let options = project.getCompilationSettings();
assert.isTrue(options.maxNodeModuleJsDepth === 2);
assert(options.maxNodeModuleJsDepth === 2);
// Assert the option sticks
projectService.setCompilerOptionsForInferredProjects({ target: ScriptTarget.ES2016 });
project = projectService.inferredProjects[0];
options = project.getCompilationSettings();
assert.isTrue(options.maxNodeModuleJsDepth === 2);
assert(options.maxNodeModuleJsDepth === 2);
});
it("should return to normal state when all js root files are removed from project", () => {
@ -5090,7 +5090,7 @@ namespace ts.projectSystem {
projectService.openClientFile(file2.path);
project = projectService.inferredProjects[0];
assert.isTrue(project.getCompilationSettings().maxNodeModuleJsDepth === 2);
assert(project.getCompilationSettings().maxNodeModuleJsDepth === 2);
projectService.closeClientFile(file2.path);
project = projectService.inferredProjects[0];
@ -5098,7 +5098,7 @@ namespace ts.projectSystem {
});
});
describe("Options Diagnostic locations reported correctly with changes in configFile contents", () => {
describe("tsserverProjectSystem Options Diagnostic locations reported correctly with changes in configFile contents", () => {
it("when options change", () => {
const file = {
path: "/a/b/app.ts",
@ -5134,7 +5134,7 @@ namespace ts.projectSystem {
seq: 2,
arguments: { file: configFile.path, projectFileName: projectName, includeLinePosition: true }
}).response as ReadonlyArray<server.protocol.DiagnosticWithLinePosition>;
assert.isTrue(diags.length === 2);
assert(diags.length === 2);
configFile.content = configFileContentWithoutCommentLine;
host.reloadFS([file, configFile]);
@ -5145,7 +5145,7 @@ namespace ts.projectSystem {
seq: 2,
arguments: { file: configFile.path, projectFileName: projectName, includeLinePosition: true }
}).response as ReadonlyArray<server.protocol.DiagnosticWithLinePosition>;
assert.isTrue(diagsAfterEdit.length === 2);
assert(diagsAfterEdit.length === 2);
verifyDiagnostic(diags[0], diagsAfterEdit[0]);
verifyDiagnostic(diags[1], diagsAfterEdit[1]);
@ -5162,7 +5162,7 @@ namespace ts.projectSystem {
});
});
describe("refactors", () => {
describe("tsserverProjectSystem refactors", () => {
it("use formatting options", () => {
const file = {
path: "/a.ts",
@ -5218,7 +5218,7 @@ namespace ts.projectSystem {
});
});
describe("CachingFileSystemInformation", () => {
describe("tsserverProjectSystem CachingFileSystemInformation", () => {
enum CalledMapsWithSingleArg {
fileExists = "fileExists",
directoryExists = "directoryExists",
@ -5271,7 +5271,7 @@ namespace ts.projectSystem {
function verifyCalledOn(callback: CalledMaps, name: string) {
const calledMap = calledMaps[callback];
const result = calledMap.get(name);
assert.isTrue(result && !!result.length, `${callback} should be called with name: ${name}: ${arrayFrom(calledMap.keys())}`);
assert(result && !!result.length, `${callback} should be called with name: ${name}: ${arrayFrom(calledMap.keys())}`);
}
function verifyNoCall(callback: CalledMaps) {
@ -5283,7 +5283,7 @@ namespace ts.projectSystem {
const calledMap = calledMaps[callback];
ts.TestFSWithWatch.verifyMapSize(callback, calledMap, arrayFrom(expectedKeys.keys()));
expectedKeys.forEach((called, name) => {
assert.isTrue(calledMap.has(name), `${callback} is expected to contain ${name}, actual keys: ${arrayFrom(calledMap.keys())}`);
assert(calledMap.has(name), `${callback} is expected to contain ${name}, actual keys: ${arrayFrom(calledMap.keys())}`);
assert.equal(calledMap.get(name).length, called, `${callback} is expected to be called ${called} times with ${name}. Actual entry: ${calledMap.get(name)}`);
});
}
@ -5356,10 +5356,10 @@ namespace ts.projectSystem {
try {
// trigger synchronization to make sure that LSHost will try to find 'f2' module on disk
verifyImportedDiagnostics();
assert.isTrue(false, `should not find file '${imported.path}'`);
assert(false, `should not find file '${imported.path}'`);
}
catch (e) {
assert.isTrue(e.message.indexOf(`Could not find file: '${imported.path}'.`) === 0);
assert(e.message.indexOf(`Could not find file: '${imported.path}'.`) === 0);
}
const f2Lookups = getLocationsForModuleLookup("f2");
callsTrackingHost.verifyCalledOnEachEntryNTimes(CalledMapsWithSingleArg.fileExists, f2Lookups, 1);
@ -5544,7 +5544,7 @@ namespace ts.projectSystem {
callsTrackingHost.verifyNoHostCallsExceptFileExistsOnce(["/a/b/models/tsconfig.json", "/a/b/models/jsconfig.json"]);
checkNumberOfConfiguredProjects(projectService, 1);
assert.strictEqual(projectService.configuredProjects.get(tsconfigFile.path), project);
assert.equal(projectService.configuredProjects.get(tsconfigFile.path), project);
});
describe("WatchDirectories for config file with", () => {
@ -5631,7 +5631,7 @@ namespace ts.projectSystem {
callsTrackingHost.verifyNoCall(CalledMapsWithFiveArgs.readDirectory);
checkNumberOfConfiguredProjects(projectService, 1);
assert.strictEqual(projectService.configuredProjects.get(canonicalConfigPath), project);
assert.equal(projectService.configuredProjects.get(canonicalConfigPath), project);
verifyProjectAndWatchedDirectories();
callsTrackingHost.clear();
@ -5640,7 +5640,7 @@ namespace ts.projectSystem {
assert.equal(configFile2, configFileName);
checkNumberOfConfiguredProjects(projectService, 1);
assert.strictEqual(projectService.configuredProjects.get(canonicalConfigPath), project);
assert.equal(projectService.configuredProjects.get(canonicalConfigPath), project);
verifyProjectAndWatchedDirectories();
callsTrackingHost.verifyNoHostCalls();
@ -5835,14 +5835,14 @@ namespace ts.projectSystem {
});
});
describe("ProjectsChangedInBackground", () => {
describe("tsserverProjectSystem ProjectsChangedInBackground", () => {
function verifyFiles(caption: string, actual: ReadonlyArray<string>, expected: ReadonlyArray<string>) {
assert.equal(actual.length, expected.length, `Incorrect number of ${caption}. Actual: ${actual} Expected: ${expected}`);
const seen = createMap<true>();
forEach(actual, f => {
assert.isFalse(seen.has(f), `${caption}: Found duplicate ${f}. Actual: ${actual} Expected: ${expected}`);
seen.set(f, true);
assert.isTrue(contains(expected, f), `${caption}: Expected not to contain ${f}. Actual: ${actual} Expected: ${expected}`);
assert(contains(expected, f), `${caption}: Expected not to contain ${f}. Actual: ${actual} Expected: ${expected}`);
});
}
@ -6313,7 +6313,7 @@ namespace ts.projectSystem {
else {
// file2 addition wont be detected
projectFiles.pop();
assert.isTrue(host.fileExists(file2.path));
assert(host.fileExists(file2.path));
}
verifyProject();
@ -6380,7 +6380,7 @@ namespace ts.projectSystem {
assert.equal(projectChangedEvents.length, expectedEvents.length, `Incorrect number of events Actual: ${eventsToString(projectChangedEvents)} Expected: ${eventsToString(expectedEvents)}`);
forEach(projectChangedEvents, (actualEvent, i) => {
const expectedEvent = expectedEvents[i];
assert.strictEqual(actualEvent.eventName, expectedEvent.eventName);
assert.equal(actualEvent.eventName, expectedEvent.eventName);
verifyFiles("openFiles", actualEvent.data.openFiles, expectedEvent.data.openFiles);
});
@ -6431,7 +6431,7 @@ namespace ts.projectSystem {
});
});
describe("Watched recursive directories with windows style file system", () => {
describe("tsserverProjectSystem Watched recursive directories with windows style file system", () => {
function verifyWatchedDirectories(useProjectAtRoot: boolean) {
const root = useProjectAtRoot ? "c:/" : "c:/myfolder/allproject/";
const configFile: FileOrFolder = {

View file

@ -292,7 +292,7 @@ namespace ts.projectSystem {
typeAcquisition: { enable: true, include: ["jquery"] }
});
assert.isTrue(enqueueIsCalled, "expected enqueueIsCalled to be true");
assert(enqueueIsCalled, "expected enqueueIsCalled to be true");
installer.installAll(/*expectedCount*/ 1);
// auto is set in type acquisition - use it even if project contains only .ts files
@ -598,7 +598,7 @@ namespace ts.projectSystem {
installer.executePendingCommands();
// expected all typings file to exist
for (const f of typingFiles) {
assert.isTrue(host.fileExists(f.path), `expected file ${f.path} to exist`);
assert(host.fileExists(f.path), `expected file ${f.path} to exist`);
}
host.checkTimeoutQueueLengthAndRun(2);
checkNumberOfProjects(projectService, { externalProjects: 1 });
@ -934,8 +934,8 @@ namespace ts.projectSystem {
installer.installAll(/*expectedCount*/1);
assert.isTrue(host.fileExists(node.path), "typings for 'node' should be created");
assert.isTrue(host.fileExists(commander.path), "typings for 'commander' should be created");
assert(host.fileExists(node.path), "typings for 'node' should be created");
assert(host.fileExists(commander.path), "typings for 'commander' should be created");
checkProjectActualFiles(service.inferredProjects[0], [file.path, node.path, commander.path]);
});
@ -1076,7 +1076,7 @@ namespace ts.projectSystem {
projectService.openClientFile(f1.path);
installer.checkPendingCommands(/*expectedCount*/ 0);
assert.isTrue(messages.indexOf("Package name '; say Hello from TypeScript! #' contains non URI safe characters") > 0, "should find package with invalid name");
assert(messages.indexOf("Package name '; say Hello from TypeScript! #' contains non URI safe characters") > 0, "should find package with invalid name");
});
});
@ -1225,7 +1225,7 @@ namespace ts.projectSystem {
installer.installAll(/*expectedCount*/ 1);
assert.isTrue(seenTelemetryEvent);
assert(seenTelemetryEvent);
host.checkTimeoutQueueLengthAndRun(2);
checkNumberOfProjects(projectService, { inferredProjects: 1 });
checkProjectActualFiles(projectService.inferredProjects[0], [f1.path, commander.path]);
@ -1276,10 +1276,10 @@ namespace ts.projectSystem {
installer.installAll(/*expectedCount*/ 1);
assert.isTrue(!!beginEvent);
assert.isTrue(!!endEvent);
assert.isTrue(beginEvent.eventId === endEvent.eventId);
assert.isTrue(endEvent.installSuccess);
assert(!!beginEvent);
assert(!!endEvent);
assert(beginEvent.eventId === endEvent.eventId);
assert(endEvent.installSuccess);
host.checkTimeoutQueueLengthAndRun(2);
checkNumberOfProjects(projectService, { inferredProjects: 1 });
checkProjectActualFiles(projectService.inferredProjects[0], [f1.path, commander.path]);
@ -1322,9 +1322,9 @@ namespace ts.projectSystem {
installer.installAll(/*expectedCount*/ 1);
assert.isTrue(!!beginEvent);
assert.isTrue(!!endEvent);
assert.isTrue(beginEvent.eventId === endEvent.eventId);
assert(!!beginEvent);
assert(!!endEvent);
assert(beginEvent.eventId === endEvent.eventId);
assert.isFalse(endEvent.installSuccess);
checkNumberOfProjects(projectService, { inferredProjects: 1 });
checkProjectActualFiles(projectService.inferredProjects[0], [f1.path]);

View file

@ -34,7 +34,7 @@ var p:Point=new Point();
var q:Point=<Point>p;`;
const { lines } = server.LineIndex.linesFromText(testContent);
assert.isTrue(lines.length > 0, "Failed to initialize test text. Expected text to have at least one line");
assert(lines.length > 0, "Failed to initialize test text. Expected text to have at least one line");
const lineIndex = new server.LineIndex();
lineIndex.load(lines);
@ -94,7 +94,7 @@ that was purple at the tips
and grew 1cm per day`;
({ lines, lineMap } = server.LineIndex.linesFromText(testContent));
assert.isTrue(lines.length > 0, "Failed to initialize test text. Expected text to have at least one line");
assert(lines.length > 0, "Failed to initialize test text. Expected text to have at least one line");
const lineIndex = new server.LineIndex();
lineIndex.load(lines);
@ -203,10 +203,10 @@ and grew 1cm per day`;
const testFileName = "src/compiler/scanner.ts";
testContent = Harness.IO.readFile(testFileName);
const totalChars = testContent.length;
assert.isTrue(totalChars > 0, "Failed to read test file.");
assert(totalChars > 0, "Failed to read test file.");
({ lines, lineMap } = server.LineIndex.linesFromText(testContent));
assert.isTrue(lines.length > 0, "Failed to initialize test text. Expected text to have at least one line");
assert(lines.length > 0, "Failed to initialize test text. Expected text to have at least one line");
lineIndex = new server.LineIndex();
lineIndex.load(lines);

View file

@ -139,7 +139,7 @@ interface Array<T> {}`
function checkMapKeys(caption: string, map: Map<any>, expectedKeys: ReadonlyArray<string>) {
verifyMapSize(caption, map, expectedKeys);
for (const name of expectedKeys) {
assert.isTrue(map.has(name), `${caption} is expected to contain ${name}, actual keys: ${arrayFrom(map.keys())}`);
assert(map.has(name), `${caption} is expected to contain ${name}, actual keys: ${arrayFrom(map.keys())}`);
}
}
@ -168,7 +168,7 @@ interface Array<T> {}`
mapSeen.set(f, true);
}
}
assert.equal(mapExpected.size, 0, `Output has missing ${JSON.stringify(flatMapIter(mapExpected.keys(), key => key))} in ${JSON.stringify(host.getOutput())}`);
assert.equal(mapExpected.size, 0, `Output has missing ${JSON.stringify(arrayFrom(mapExpected.keys()))} in ${JSON.stringify(host.getOutput())}`);
}
export function checkOutputDoesNotContain(host: TestServerHost, expectedToBeAbsent: string[] | ReadonlyArray<string>) {
@ -241,7 +241,7 @@ interface Array<T> {}`
ignoreWatchInvokedWithTriggerAsFileCreate: boolean;
}
export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost {
export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, ModuleResolutionHost {
args: string[] = [];
private readonly output: string[] = [];

View file

@ -856,49 +856,55 @@
</Item>
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}"]]></Val>
<Tgt Cat="Text" Stat="Update" Orig="New">
<Val><![CDATA[Dodaj element „{0}” do istniejącej deklaracji importu z elementu „{1}”.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_index_signature_for_property_0_90017" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add index signature for property '{0}'.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Add index signature for property '{0}']]></Val>
<Tgt Cat="Text" Stat="Update" Orig="New">
<Val><![CDATA[Dodaj sygnaturę indeksu dla właściwości „{0}”.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Add index signature for property '{0}'.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_missing_super_call_90001" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add missing 'super()' call.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Add missing 'super()' call]]></Val>
<Tgt Cat="Text" Stat="Update" Orig="New">
<Val><![CDATA[Dodaj brakujące wywołanie „super()”.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Add missing 'super()' call.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Add 'this.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Update" Orig="New">
<Val><![CDATA[Dodaj „this.” do nierozpoznanej zmiennej.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript__90009" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript__5068" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Dodanie pliku tsconfig.json pomoże w organizowaniu projektów, które zawierają pliki TypeScript i JavaScript. Dowiedz się więcej: https://aka.ms/tsconfig.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@ -1528,10 +1534,13 @@
</Item>
<Item ItemId=";Call_decorator_expression_90028" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Call decorator expression.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Call decorator expression]]></Val>
<Tgt Cat="Text" Stat="Update" Orig="New">
<Val><![CDATA[Wywołaj wyrażenie dekoratora.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Call decorator expression.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
@ -1942,31 +1951,37 @@
</Item>
<Item ItemId=";Change_0_to_1_90014" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Change '{0}' to '{1}'.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Change '{0}' to '{1}']]></Val>
<Tgt Cat="Text" Stat="Update" Orig="New">
<Val><![CDATA[Zmień element „{0}” na „{1}”.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Change {0} to {1}.]]></Val>
<Val><![CDATA[Change '{0}' to '{1}'.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Change_extends_to_implements_90003" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Change 'extends' to 'implements'.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Change 'extends' to 'implements']]></Val>
<Tgt Cat="Text" Stat="Update" Orig="New">
<Val><![CDATA[Zmień atrybut „extends” na „implements”.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Change 'extends' to 'implements'.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Change_spelling_to_0_90022" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Change spelling to '{0}'.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Change spelling to '{0}']]></Val>
<Tgt Cat="Text" Stat="Update" Orig="New">
<Val><![CDATA[Zmiana pisowni na „{0}”.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Change spelling to '{0}'.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
@ -2338,37 +2353,49 @@
</Item>
<Item ItemId=";Declare_method_0_90023" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Declare method '{0}'.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Declare method '{0}']]></Val>
<Tgt Cat="Text" Stat="Update" Orig="New">
<Val><![CDATA[Zadeklaruj metodę „{0}”.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Declare method '{0}'.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Declare_property_0_90016" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Declare property '{0}'.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Declare property '{0}']]></Val>
<Tgt Cat="Text" Stat="Update" Orig="New">
<Val><![CDATA[Zadeklaruj właściwość „{0}”.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Declare property '{0}'.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Declare_static_method_0_90024" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Declare static method '{0}'.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Declare static method '{0}']]></Val>
<Tgt Cat="Text" Stat="Update" Orig="New">
<Val><![CDATA[Zadeklaruj metodę statyczną „{0}”.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Declare static method '{0}'.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Declare_static_property_0_90027" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Declare static property '{0}'.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Declare static property '{0}']]></Val>
<Tgt Cat="Text" Stat="Update" Orig="New">
<Val><![CDATA[Zadeklaruj właściwość statyczną „{0}”.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Declare static property '{0}'.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
@ -2446,10 +2473,13 @@
</Item>
<Item ItemId=";Disable_checking_for_this_file_90018" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Disable checking for this file.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Disable checking for this file]]></Val>
<Tgt Cat="Text" Stat="Update" Orig="New">
<Val><![CDATA[Wyłącz sprawdzanie dla tego pliku.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Disable checking for this file.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
@ -3715,28 +3745,37 @@
</Item>
<Item ItemId=";Ignore_this_error_message_90019" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Ignore this error message.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Ignore this error message]]></Val>
<Tgt Cat="Text" Stat="Update" Orig="New">
<Val><![CDATA[Ignoruj ten komunikat o błędzie.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Ignore this error message.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Implement_inherited_abstract_class_90007" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Implement inherited abstract class.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Implement inherited abstract class]]></Val>
<Tgt Cat="Text" Stat="Update" Orig="New">
<Val><![CDATA[Implementuj odziedziczoną klasę abstrakcyjną.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Implement inherited abstract class.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Implement_interface_0_90006" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Implement interface '{0}'.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Implement interface '{0}']]></Val>
<Tgt Cat="Text" Stat="Update" Orig="New">
<Val><![CDATA[Implementuj interfejs „{0}”.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Implement interface '{0}'.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
@ -3751,10 +3790,13 @@
</Item>
<Item ItemId=";Import_0_from_module_1_90013" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Import '{0}' from module "{1}".]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Import '{0}' from module "{1}"]]></Val>
<Tgt Cat="Text" Stat="Update" Orig="New">
<Val><![CDATA[Import „{0}” z modułu „{1}”.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Import '{0}' from module "{1}".]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
@ -3901,37 +3943,49 @@
</Item>
<Item ItemId=";Infer_parameter_types_from_usage_95012" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Infer parameter types from usage.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Infer parameter types from usage]]></Val>
<Tgt Cat="Text" Stat="Update" Orig="New">
<Val><![CDATA[Wywnioskuj typy parametrów na podstawie użycia.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Infer parameter types from usage.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Infer_type_of_0_from_usage_95011" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Infer type of '{0}' from usage.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Infer type of '{0}' from usage]]></Val>
<Tgt Cat="Text" Stat="Update" Orig="New">
<Val><![CDATA[Wywnioskuj typ elementu „{0}” na podstawie użycia.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Infer type of '{0}' from usage.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Initialize_property_0_in_the_constructor_90020" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Initialize property '{0}' in the constructor.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Initialize property '{0}' in the constructor]]></Val>
<Tgt Cat="Text" Stat="Update" Orig="New">
<Val><![CDATA[Zainicjuj właściwość „{0}” w konstruktorze.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Initialize property '{0}' in the constructor.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Initialize_static_property_0_90021" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Initialize static property '{0}'.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Initialize static property '{0}']]></Val>
<Tgt Cat="Text" Stat="Update" Orig="New">
<Val><![CDATA[Zainicjuj właściwość statyczną „{0}”.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Initialize static property '{0}'.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
@ -4462,10 +4516,13 @@
</Item>
<Item ItemId=";Make_super_call_the_first_statement_in_the_constructor_90002" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Make 'super()' call the first statement in the constructor.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Make 'super()' call the first statement in the constructor]]></Val>
<Tgt Cat="Text" Stat="Update" Orig="New">
<Val><![CDATA[Ustaw wywołanie „super()” jako pierwszą instrukcję w konstruktorze.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Make 'super()' call the first statement in the constructor.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
@ -5374,10 +5431,13 @@
</Item>
<Item ItemId=";Prefix_0_with_an_underscore_90025" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Prefix '{0}' with an underscore.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Prefix '{0}' with an underscore]]></Val>
<Tgt Cat="Text" Stat="Update" Orig="New">
<Val><![CDATA[Prefiks „{0}” z podkreśleniem.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Prefix '{0}' with an underscore.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
@ -5827,10 +5887,13 @@
</Item>
<Item ItemId=";Remove_declaration_for_Colon_0_90004" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Remove declaration for: '{0}'.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Remove declaration for: '{0}']]></Val>
<Tgt Cat="Text" Stat="Update" Orig="New">
<Val><![CDATA[Usuń deklarację dla: „{0}”.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Remove declaration for: '{0}'.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
@ -6250,10 +6313,13 @@
</Item>
<Item ItemId=";Rewrite_as_the_indexed_access_type_0_90026" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Rewrite as the indexed access type '{0}'.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Rewrite as the indexed access type '{0}']]></Val>
<Tgt Cat="Text" Stat="Update" Orig="New">
<Val><![CDATA[Zapisz ponownie jako typ dostępu indeksowanego „{0}”.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Rewrite as the indexed access type '{0}'.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
@ -6365,12 +6431,9 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_or_ESNEXT_6015" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_ES2018_or_ESNEXT_6015" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Podaj wersję docelową języka ECMAScript: „ES3” (domyślna), „ES5”, „ES2015”, „ES2016”, „ES2017” lub „ESNEXT”.]]></Val>
</Tgt>
<Val><![CDATA[Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -6554,6 +6617,9 @@
<Item ItemId=";Subsequent_property_declarations_must_have_the_same_type_Property_0_must_be_of_type_1_but_here_has_t_2717" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Subsequent property declarations must have the same type. Property '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Kolejne deklaracje właściwości muszą być tego samego typu. Właściwość „{0}” musi być typu „{1}”, ale w tym miejscu jest typu „{2}”.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@ -7322,12 +7388,9 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated_90010" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated_2719" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Type '{0}' is not assignable to type '{1}'. Two different types with this name exist, but they are unrelated.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Typu „{0}” nie można przypisać do typu „{1}”. Istnieją dwa różne typy o tej nazwie, lecz są ze sobą niezwiązane.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>

View file

@ -1571,15 +1571,15 @@ namespace ts.server {
}
}
private applyCodeActionCommand(commandName: string, requestSeq: number, args: protocol.ApplyCodeActionCommandRequestArgs): void {
private applyCodeActionCommand(args: protocol.ApplyCodeActionCommandRequestArgs): {} {
const commands = args.command as CodeActionCommand | CodeActionCommand[]; // They should be sending back the command we sent them.
for (const command of toArray(commands)) {
const { project } = this.getFileAndProject(command);
const output = (success: boolean, message: string) => this.doOutput({}, commandName, requestSeq, success, message);
project.getLanguageService().applyCodeActionCommand(command).then(
result => { output(/*success*/ true, result.successMessage); },
error => { output(/*success*/ false, error); });
_result => { /* TODO: GH#20447 report success message? */ },
_error => { /* TODO: GH#20447 report errors */ });
}
return {};
}
private getStartAndEndPosition(args: protocol.FileRangeRequestArgs, scriptInfo: ScriptInfo) {
@ -1709,17 +1709,17 @@ namespace ts.server {
},
[CommandNames.OpenExternalProject]: (request: protocol.OpenExternalProjectRequest) => {
this.projectService.openExternalProject(request.arguments, /*suppressRefreshOfInferredProjects*/ false);
// TODO: report errors
// TODO: GH#20447 report errors
return this.requiredResponse(/*response*/ true);
},
[CommandNames.OpenExternalProjects]: (request: protocol.OpenExternalProjectsRequest) => {
this.projectService.openExternalProjects(request.arguments.projects);
// TODO: report errors
// TODO: GH#20447 report errors
return this.requiredResponse(/*response*/ true);
},
[CommandNames.CloseExternalProject]: (request: protocol.CloseExternalProjectRequest) => {
this.projectService.closeExternalProject(request.arguments.projectFileName);
// TODO: report errors
// TODO: GH#20447 report errors
return this.requiredResponse(/*response*/ true);
},
[CommandNames.SynchronizeProjectList]: (request: protocol.SynchronizeProjectListRequest) => {
@ -1961,8 +1961,7 @@ namespace ts.server {
return this.requiredResponse(this.getCodeFixes(request.arguments, /*simplifiedResult*/ false));
},
[CommandNames.ApplyCodeActionCommand]: (request: protocol.ApplyCodeActionCommandRequest) => {
this.applyCodeActionCommand(request.command, request.seq, request.arguments);
return this.notRequired(); // Response will come asynchronously.
return this.requiredResponse(this.applyCodeActionCommand(request.arguments));
},
[CommandNames.GetSupportedCodeFixes]: () => {
return this.requiredResponse(this.getSupportedCodeFixes());

View file

@ -62,7 +62,6 @@ namespace ts.codefix {
}
const classDeclarationSourceFile = getSourceFileOfNode(classDeclaration);
const classOpenBrace = getOpenBraceOfClassLike(classDeclaration, classDeclarationSourceFile);
return isInJavaScriptFile(classDeclarationSourceFile) ?
getActionsForAddMissingMemberInJavaScriptFile(classDeclaration, makeStatic) :
@ -154,7 +153,7 @@ namespace ts.codefix {
typeNode,
/*initializer*/ undefined);
const propertyChangeTracker = textChanges.ChangeTracker.fromContext(context);
propertyChangeTracker.insertNodeAfter(classDeclarationSourceFile, classOpenBrace, property, { suffix: context.newLineCharacter });
propertyChangeTracker.insertNodeAtClassStart(classDeclarationSourceFile, classDeclaration, property, context.newLineCharacter);
const diag = makeStatic ? Diagnostics.Declare_static_property_0 : Diagnostics.Declare_property_0;
actions = append(actions, {
@ -180,7 +179,7 @@ namespace ts.codefix {
typeNode);
const indexSignatureChangeTracker = textChanges.ChangeTracker.fromContext(context);
indexSignatureChangeTracker.insertNodeAfter(classDeclarationSourceFile, classOpenBrace, indexSignature, { suffix: context.newLineCharacter });
indexSignatureChangeTracker.insertNodeAtClassStart(classDeclarationSourceFile, classDeclaration, indexSignature, context.newLineCharacter);
actions.push({
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_index_signature_for_property_0), [tokenName]),
@ -197,7 +196,7 @@ namespace ts.codefix {
const methodDeclaration = createMethodFromCallExpression(callExpression, tokenName, includeTypeScriptSyntax, makeStatic);
const methodDeclarationChangeTracker = textChanges.ChangeTracker.fromContext(context);
methodDeclarationChangeTracker.insertNodeAfter(classDeclarationSourceFile, classOpenBrace, methodDeclaration, { suffix: context.newLineCharacter });
methodDeclarationChangeTracker.insertNodeAtClassStart(classDeclarationSourceFile, classDeclaration, methodDeclaration, context.newLineCharacter);
const diag = makeStatic ? Diagnostics.Declare_static_method_0 : Diagnostics.Declare_method_0;
return {
description: formatStringFromArgs(getLocaleSpecificMessage(diag), [tokenName]),

View file

@ -12,7 +12,7 @@ namespace ts.codefix {
const changeTracker = textChanges.ChangeTracker.fromContext(context);
const superCall = createStatement(createCall(createSuper(), /*typeArguments*/ undefined, /*argumentsArray*/ emptyArray));
changeTracker.insertNodeAfter(sourceFile, getOpenBrace(<ConstructorDeclaration>token.parent, sourceFile), superCall, { suffix: context.newLineCharacter });
changeTracker.insertNodeAtConstructorStart(sourceFile, <ConstructorDeclaration>token.parent, superCall, context.newLineCharacter);
return [{
description: getLocaleSpecificMessage(Diagnostics.Add_missing_super_call),

View file

@ -32,6 +32,7 @@ namespace ts.codefix {
interface ImportCodeFixContext extends SymbolAndTokenContext {
host: LanguageServiceHost;
program: Program;
checker: TypeChecker;
compilerOptions: CompilerOptions;
getCanonicalFileName: GetCanonicalFileName;
@ -161,15 +162,17 @@ namespace ts.codefix {
function convertToImportCodeFixContext(context: CodeFixContext): ImportCodeFixContext {
const useCaseSensitiveFileNames = context.host.useCaseSensitiveFileNames ? context.host.useCaseSensitiveFileNames() : false;
const checker = context.program.getTypeChecker();
const { program } = context;
const checker = program.getTypeChecker();
const symbolToken = getTokenAtPosition(context.sourceFile, context.span.start, /*includeJsDocComment*/ false);
return {
host: context.host,
newLineCharacter: context.newLineCharacter,
formatContext: context.formatContext,
sourceFile: context.sourceFile,
program,
checker,
compilerOptions: context.program.getCompilerOptions(),
compilerOptions: program.getCompilerOptions(),
cachedImportDeclarations: [],
getCanonicalFileName: createGetCanonicalFileName(useCaseSensitiveFileNames),
symbolName: symbolToken.getText(),
@ -309,6 +312,7 @@ namespace ts.codefix {
}
export function getModuleSpecifiersForNewImport(
program: Program,
sourceFile: SourceFile,
moduleSymbols: ReadonlyArray<Symbol>,
options: CompilerOptions,
@ -316,68 +320,79 @@ namespace ts.codefix {
host: LanguageServiceHost,
): string[] {
const { baseUrl, paths, rootDirs } = options;
const choicesForEachExportingModule = mapIterator(arrayIterator(moduleSymbols), moduleSymbol => {
const moduleFileName = moduleSymbol.valueDeclaration.getSourceFile().fileName;
const sourceDirectory = getDirectoryPath(sourceFile.fileName);
const global = tryGetModuleNameFromAmbientModule(moduleSymbol)
|| tryGetModuleNameFromTypeRoots(options, host, getCanonicalFileName, moduleFileName)
|| tryGetModuleNameAsNodeModule(options, moduleFileName, host, getCanonicalFileName, sourceDirectory)
|| rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName);
if (global) {
return [global];
}
const relativePath = removeExtensionAndIndexPostFix(getRelativePath(moduleFileName, sourceDirectory, getCanonicalFileName), options);
if (!baseUrl) {
return [relativePath];
}
const relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseUrl, getCanonicalFileName);
if (!relativeToBaseUrl) {
return [relativePath];
}
const importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, options);
if (paths) {
const fromPaths = tryGetModuleNameFromPaths(removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths);
if (fromPaths) {
return [fromPaths];
const choicesForEachExportingModule = flatMap(moduleSymbols, moduleSymbol =>
getAllModulePaths(program, moduleSymbol.valueDeclaration.getSourceFile()).map(moduleFileName => {
const sourceDirectory = getDirectoryPath(sourceFile.fileName);
const global = tryGetModuleNameFromAmbientModule(moduleSymbol)
|| tryGetModuleNameFromTypeRoots(options, host, getCanonicalFileName, moduleFileName)
|| tryGetModuleNameAsNodeModule(options, moduleFileName, host, getCanonicalFileName, sourceDirectory)
|| rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName);
if (global) {
return [global];
}
}
/*
Prefer a relative import over a baseUrl import if it doesn't traverse up to baseUrl.
const relativePath = removeExtensionAndIndexPostFix(getRelativePath(moduleFileName, sourceDirectory, getCanonicalFileName), options);
if (!baseUrl) {
return [relativePath];
}
Suppose we have:
baseUrl = /base
sourceDirectory = /base/a/b
moduleFileName = /base/foo/bar
Then:
relativePath = ../../foo/bar
getRelativePathNParents(relativePath) = 2
pathFromSourceToBaseUrl = ../../
getRelativePathNParents(pathFromSourceToBaseUrl) = 2
2 < 2 = false
In this case we should prefer using the baseUrl path "/a/b" instead of the relative path "../../foo/bar".
const relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseUrl, getCanonicalFileName);
if (!relativeToBaseUrl) {
return [relativePath];
}
Suppose we have:
baseUrl = /base
sourceDirectory = /base/foo/a
moduleFileName = /base/foo/bar
Then:
relativePath = ../a
getRelativePathNParents(relativePath) = 1
pathFromSourceToBaseUrl = ../../
getRelativePathNParents(pathFromSourceToBaseUrl) = 2
1 < 2 = true
In this case we should prefer using the relative path "../a" instead of the baseUrl path "foo/a".
*/
const pathFromSourceToBaseUrl = getRelativePath(baseUrl, sourceDirectory, getCanonicalFileName);
const relativeFirst = getRelativePathNParents(pathFromSourceToBaseUrl) < getRelativePathNParents(relativePath);
return relativeFirst ? [relativePath, importRelativeToBaseUrl] : [importRelativeToBaseUrl, relativePath];
});
const importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, options);
if (paths) {
const fromPaths = tryGetModuleNameFromPaths(removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths);
if (fromPaths) {
return [fromPaths];
}
}
/*
Prefer a relative import over a baseUrl import if it doesn't traverse up to baseUrl.
Suppose we have:
baseUrl = /base
sourceDirectory = /base/a/b
moduleFileName = /base/foo/bar
Then:
relativePath = ../../foo/bar
getRelativePathNParents(relativePath) = 2
pathFromSourceToBaseUrl = ../../
getRelativePathNParents(pathFromSourceToBaseUrl) = 2
2 < 2 = false
In this case we should prefer using the baseUrl path "/a/b" instead of the relative path "../../foo/bar".
Suppose we have:
baseUrl = /base
sourceDirectory = /base/foo/a
moduleFileName = /base/foo/bar
Then:
relativePath = ../a
getRelativePathNParents(relativePath) = 1
pathFromSourceToBaseUrl = ../../
getRelativePathNParents(pathFromSourceToBaseUrl) = 2
1 < 2 = true
In this case we should prefer using the relative path "../a" instead of the baseUrl path "foo/a".
*/
const pathFromSourceToBaseUrl = getRelativePath(baseUrl, sourceDirectory, getCanonicalFileName);
const relativeFirst = getRelativePathNParents(pathFromSourceToBaseUrl) < getRelativePathNParents(relativePath);
return relativeFirst ? [relativePath, importRelativeToBaseUrl] : [importRelativeToBaseUrl, relativePath];
}));
// Only return results for the re-export with the shortest possible path (and also give the other path even if that's long.)
return best(choicesForEachExportingModule, (a, b) => a[0].length < b[0].length);
return best(arrayIterator(choicesForEachExportingModule), (a, b) => a[0].length < b[0].length);
}
/**
* Looks for a existing imports that use symlinks to this module.
* Only if no symlink is available, the real path will be used.
*/
function getAllModulePaths(program: Program, { fileName }: SourceFile): ReadonlyArray<string> {
const symlinks = mapDefined(program.getSourceFiles(), sf =>
sf.resolvedModules && firstDefinedIterator(sf.resolvedModules.values(), res =>
res && res.resolvedFileName === fileName ? res.originalPath : undefined));
return symlinks.length === 0 ? [fileName] : symlinks;
}
function getRelativePathNParents(relativePath: string): number {
@ -613,7 +628,7 @@ namespace ts.codefix {
}
const existingDeclaration = firstDefined(declarations, moduleSpecifierFromAnyImport);
const moduleSpecifiers = existingDeclaration ? [existingDeclaration] : getModuleSpecifiersForNewImport(ctx.sourceFile, moduleSymbols, ctx.compilerOptions, ctx.getCanonicalFileName, ctx.host);
const moduleSpecifiers = existingDeclaration ? [existingDeclaration] : getModuleSpecifiersForNewImport(ctx.program, ctx.sourceFile, moduleSymbols, ctx.compilerOptions, ctx.getCanonicalFileName, ctx.host);
return moduleSpecifiers.map(spec => getCodeActionForNewImport(ctx, spec));
}
@ -746,7 +761,7 @@ namespace ts.codefix {
forEachExternalModuleToImportFrom(checker, sourceFile, allSourceFiles, moduleSymbol => {
cancellationToken.throwIfCancellationRequested();
// check the default export
const defaultExport = checker.tryGetMemberInModuleExports("default", moduleSymbol);
const defaultExport = checker.tryGetMemberInModuleExports(InternalSymbolName.Default, moduleSymbol);
if (defaultExport) {
const localSymbol = getLocalSymbolForExportDefault(defaultExport);
if ((localSymbol && localSymbol.escapedName === symbolName || moduleSymbolToValidIdentifier(moduleSymbol, context.compilerOptions.target) === symbolName)

View file

@ -39,6 +39,12 @@ namespace ts.Completions {
return getStringLiteralCompletionEntries(sourceFile, position, typeChecker, compilerOptions, host, log);
}
const contextToken = findPrecedingToken(position, sourceFile);
if (contextToken && isBreakOrContinueStatement(contextToken.parent)
&& (contextToken.kind === SyntaxKind.BreakKeyword || contextToken.kind === SyntaxKind.ContinueKeyword || contextToken.kind === SyntaxKind.Identifier)) {
return getLabelCompletionAtPosition(contextToken.parent);
}
const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, options, compilerOptions.target);
if (!completionData) {
return undefined;
@ -223,6 +229,13 @@ namespace ts.Completions {
return uniques;
}
function getLabelCompletionAtPosition(node: BreakOrContinueStatement): CompletionInfo | undefined {
const entries = getLabelStatementCompletions(node);
if (entries.length) {
return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries };
}
}
function getStringLiteralCompletionEntries(sourceFile: SourceFile, position: number, typeChecker: TypeChecker, compilerOptions: CompilerOptions, host: LanguageServiceHost, log: Log): CompletionInfo | undefined {
const node = findPrecedingToken(position, sourceFile);
if (!node || node.kind !== SyntaxKind.StringLiteral) {
@ -358,6 +371,32 @@ namespace ts.Completions {
return undefined;
}
function getLabelStatementCompletions(node: Node): CompletionEntry[] {
const entries: CompletionEntry[] = [];
const uniques = createMap<true>();
let current = node;
while (current) {
if (isFunctionLike(current)) {
break;
}
if (isLabeledStatement(current)) {
const name = current.label.text;
if (!uniques.has(name)) {
uniques.set(name, true);
entries.push({
name,
kindModifiers: ScriptElementKindModifier.none,
kind: ScriptElementKind.label,
sortText: "0"
});
}
}
current = current.parent;
}
return entries;
}
function addStringLiteralCompletionsFromType(type: Type, result: Push<CompletionEntry>, typeChecker: TypeChecker, uniques = createMap<true>()): void {
if (type && type.flags & TypeFlags.TypeParameter) {
type = typeChecker.getBaseConstraintOfType(type);
@ -416,7 +455,9 @@ namespace ts.Completions {
}
function getSymbolName(symbol: Symbol, origin: SymbolOriginInfo | undefined, target: ScriptTarget): string {
return origin && origin.isDefaultExport && symbol.name === "default" ? codefix.moduleSymbolToValidIdentifier(origin.moduleSymbol, target) : symbol.name;
return origin && origin.isDefaultExport && symbol.escapedName === InternalSymbolName.Default
? codefix.moduleSymbolToValidIdentifier(origin.moduleSymbol, target)
: symbol.name;
}
export interface CompletionEntryIdentifier {
@ -425,7 +466,7 @@ namespace ts.Completions {
}
export function getCompletionEntryDetails(
typeChecker: TypeChecker,
program: Program,
log: (message: string) => void,
compilerOptions: CompilerOptions,
sourceFile: SourceFile,
@ -436,6 +477,7 @@ namespace ts.Completions {
formatContext: formatting.FormatContext,
getCanonicalFileName: GetCanonicalFileName,
): CompletionEntryDetails {
const typeChecker = program.getTypeChecker();
const { name } = entryId;
// Compute all the completion symbols again.
const symbolCompletion = getSymbolCompletionFromEntryId(typeChecker, log, compilerOptions, sourceFile, position, entryId, allSourceFiles);
@ -455,7 +497,7 @@ namespace ts.Completions {
}
case "symbol": {
const { symbol, location, symbolToOriginInfoMap } = symbolCompletion;
const { codeActions, sourceDisplay } = getCompletionEntryCodeActionsAndSourceDisplay(symbolToOriginInfoMap, symbol, typeChecker, host, compilerOptions, sourceFile, formatContext, getCanonicalFileName, allSourceFiles);
const { codeActions, sourceDisplay } = getCompletionEntryCodeActionsAndSourceDisplay(symbolToOriginInfoMap, symbol, program, typeChecker, host, compilerOptions, sourceFile, formatContext, getCanonicalFileName, allSourceFiles);
const kindModifiers = SymbolDisplay.getSymbolModifiers(symbol);
const { displayParts, documentation, symbolKind, tags } = SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, location, location, SemanticMeaning.All);
return { name, kindModifiers, kind: symbolKind, displayParts, documentation, tags, codeActions, source: sourceDisplay };
@ -482,6 +524,7 @@ namespace ts.Completions {
function getCompletionEntryCodeActionsAndSourceDisplay(
symbolToOriginInfoMap: SymbolOriginInfoMap,
symbol: Symbol,
program: Program,
checker: TypeChecker,
host: LanguageServiceHost,
compilerOptions: CompilerOptions,
@ -500,9 +543,10 @@ namespace ts.Completions {
const moduleSymbols = getAllReExportingModules(exportedSymbol, checker, allSourceFiles);
Debug.assert(contains(moduleSymbols, moduleSymbol));
const sourceDisplay = [textPart(first(codefix.getModuleSpecifiersForNewImport(sourceFile, moduleSymbols, compilerOptions, getCanonicalFileName, host)))];
const sourceDisplay = [textPart(first(codefix.getModuleSpecifiersForNewImport(program, sourceFile, moduleSymbols, compilerOptions, getCanonicalFileName, host)))];
const codeActions = codefix.getCodeActionForImport(moduleSymbols, {
host,
program,
checker,
newLineCharacter: host.getNewLine(),
compilerOptions,
@ -1076,7 +1120,7 @@ namespace ts.Completions {
continue;
}
const isDefaultExport = name === "default";
const isDefaultExport = name === InternalSymbolName.Default;
if (isDefaultExport) {
const localSymbol = getLocalSymbolForExportDefault(symbol);
if (localSymbol) {
@ -1756,10 +1800,10 @@ namespace ts.Completions {
}
if (existingImportsOrExports.size === 0) {
return filter(exportsOfModule, e => e.escapedName !== "default");
return filter(exportsOfModule, e => e.escapedName !== InternalSymbolName.Default);
}
return filter(exportsOfModule, e => e.escapedName !== "default" && !existingImportsOrExports.get(e.escapedName));
return filter(exportsOfModule, e => e.escapedName !== InternalSymbolName.Default && !existingImportsOrExports.get(e.escapedName));
}
/**

View file

@ -290,7 +290,7 @@ namespace ts.FindAllReferences {
function isNameMatch(name: __String): boolean {
// Use name of "default" even in `export =` case because we may have allowSyntheticDefaultImports
return name === exportSymbol.escapedName || exportKind !== ExportKind.Named && name === "default";
return name === exportSymbol.escapedName || exportKind !== ExportKind.Named && name === InternalSymbolName.Default;
}
}
@ -534,7 +534,7 @@ namespace ts.FindAllReferences {
// If `importedName` is undefined, do continue searching as the export is anonymous.
// (All imports returned from this function will be ignored anyway if we are in rename and this is a not a named export.)
const importedName = symbolName(importedSymbol);
if (importedName === undefined || importedName === "default" || importedName === symbol.escapedName) {
if (importedName === undefined || importedName === InternalSymbolName.Default || importedName === symbol.escapedName) {
return { kind: ImportExport.Import, symbol: importedSymbol, ...isImport };
}
}
@ -604,7 +604,7 @@ namespace ts.FindAllReferences {
}
function symbolName(symbol: Symbol): __String | undefined {
if (symbol.escapedName !== "default") {
if (symbol.escapedName !== InternalSymbolName.Default) {
return symbol.escapedName;
}

View file

@ -33,8 +33,8 @@ namespace ts {
}
export function getApplicableRefactors(context: RefactorContext): ApplicableRefactorInfo[] {
return flatMapIter(refactors.values(), refactor =>
context.cancellationToken && context.cancellationToken.isCancellationRequested() ? undefined : refactor.getAvailableActions(context));
return arrayFrom(flatMapIterator(refactors.values(), refactor =>
context.cancellationToken && context.cancellationToken.isCancellationRequested() ? undefined : refactor.getAvailableActions(context)));
}
export function getEditsForRefactor(context: RefactorContext, refactorName: string, actionName: string): RefactorEditInfo | undefined {

View file

@ -488,6 +488,7 @@ namespace ts {
parameters: Symbol[];
thisParameter: Symbol;
resolvedReturnType: Type;
resolvedTypePredicate: TypePredicate | undefined;
minTypeArgumentCount: number;
minArgumentCount: number;
hasRestParameter: boolean;
@ -1268,6 +1269,7 @@ namespace ts {
}
return host.readFile && host.readFile(fileName);
},
realpath: host.realpath && (path => host.realpath(path)),
directoryExists: directoryName => {
return directoryProbablyExists(directoryName, host);
},
@ -1446,7 +1448,7 @@ namespace ts {
function getCompletionEntryDetails(fileName: string, position: number, name: string, formattingOptions?: FormatCodeSettings, source?: string): CompletionEntryDetails {
synchronizeHostData();
return Completions.getCompletionEntryDetails(
program.getTypeChecker(),
program,
log,
program.getCompilerOptions(),
getValidSourceFile(fileName),

View file

@ -330,7 +330,7 @@ namespace ts {
// if shimHost is a COM object then property check will become method call with no arguments.
// 'in' does not have this effect.
if ("getModuleResolutionsForFile" in this.shimHost) {
this.resolveModuleNames = (moduleNames: string[], containingFile: string) => {
this.resolveModuleNames = (moduleNames: string[], containingFile: string): ResolvedModuleFull[] => {
const resolutionsInFile = <MapLike<string>>JSON.parse(this.shimHost.getModuleResolutionsForFile(containingFile));
return map(moduleNames, name => {
const result = getProperty(resolutionsInFile, name);

View file

@ -337,8 +337,32 @@ namespace ts.textChanges {
return this.replaceWithSingle(sourceFile, startPosition, startPosition, newNode, options);
}
public insertNodeAfter(sourceFile: SourceFile, after: Node, newNode: Node, options: InsertNodeOptions & ConfigurableEnd = {}) {
if ((isStatementButNotDeclaration(after)) ||
public insertNodeAtConstructorStart(sourceFile: SourceFile, ctr: ConstructorDeclaration, newStatement: Statement, newLineCharacter: string): void {
const firstStatement = firstOrUndefined(ctr.body.statements);
if (!firstStatement || !ctr.body.multiLine) {
this.replaceNode(sourceFile, ctr.body, createBlock([newStatement, ...ctr.body.statements], /*multiLine*/ true), { useNonAdjustedEndPosition: true });
}
else {
this.insertNodeBefore(sourceFile, firstStatement, newStatement, { suffix: newLineCharacter });
}
}
public insertNodeAtClassStart(sourceFile: SourceFile, cls: ClassLikeDeclaration, newElement: ClassElement, newLineCharacter: string): void {
const firstMember = firstOrUndefined(cls.members);
if (!firstMember) {
const members = [newElement];
const newCls = cls.kind === SyntaxKind.ClassDeclaration
? updateClassDeclaration(cls, cls.decorators, cls.modifiers, cls.name, cls.typeParameters, cls.heritageClauses, members)
: updateClassExpression(cls, cls.modifiers, cls.name, cls.typeParameters, cls.heritageClauses, members);
this.replaceNode(sourceFile, cls, newCls, { useNonAdjustedEndPosition: true });
}
else {
this.insertNodeBefore(sourceFile, firstMember, newElement, { suffix: newLineCharacter });
}
}
public insertNodeAfter(sourceFile: SourceFile, after: Node, newNode: Node, options: InsertNodeOptions & ConfigurableEnd = {}): this {
if (isStatementButNotDeclaration(after) ||
after.kind === SyntaxKind.PropertyDeclaration ||
after.kind === SyntaxKind.PropertySignature ||
after.kind === SyntaxKind.MethodSignature) {

View file

@ -181,6 +181,7 @@ namespace ts {
*/
readDirectory?(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[];
readFile?(path: string, encoding?: string): string | undefined;
realpath?(path: string): string;
fileExists?(path: string): boolean;
/*

View file

@ -3925,6 +3925,7 @@ declare namespace ts {
useCaseSensitiveFileNames?(): boolean;
readDirectory?(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[];
readFile?(path: string, encoding?: string): string | undefined;
realpath?(path: string): string;
fileExists?(path: string): boolean;
getTypeRootsVersion?(): number;
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[];
@ -7088,7 +7089,7 @@ declare namespace ts.server {
private getApplicableRefactors(args);
private getEditsForRefactor(args, simplifiedResult);
private getCodeFixes(args, simplifiedResult);
private applyCodeActionCommand(commandName, requestSeq, args);
private applyCodeActionCommand(args);
private getStartAndEndPosition(args, scriptInfo);
private mapCodeAction({description, changes: unmappedChanges, commands}, scriptInfo);
private mapTextChangesToCodeEdits(project, textChanges);

View file

@ -3925,6 +3925,7 @@ declare namespace ts {
useCaseSensitiveFileNames?(): boolean;
readDirectory?(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[];
readFile?(path: string, encoding?: string): string | undefined;
realpath?(path: string): string;
fileExists?(path: string): boolean;
getTypeRootsVersion?(): number;
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[];

View file

@ -21,6 +21,7 @@ const enum Enum1 {
N = E << 1,
O = E >> B,
P = E >> 1,
PQ = E ** 2,
Q = -D,
R = C & 5,
S = 5 & C,
@ -128,6 +129,7 @@ function foo(x: Enum1) {
case Enum1.N:
case Enum1.O:
case Enum1.P:
case Enum1.PQ:
case Enum1.Q:
case Enum1.R:
case Enum1.S:
@ -200,6 +202,7 @@ function foo(x) {
case 2 /* N */:
case 0 /* O */:
case 0 /* P */:
case 1 /* PQ */:
case -1 /* Q */:
case 0 /* R */:
case 0 /* S */:

View file

@ -71,273 +71,277 @@ const enum Enum1 {
P = E >> 1,
>P : Symbol(Enum1.P, Decl(constEnums.ts, 20, 15))
>E : Symbol(Enum1.E, Decl(constEnums.ts, 9, 14))
PQ = E ** 2,
>PQ : Symbol(Enum1.PQ, Decl(constEnums.ts, 21, 15))
>E : Symbol(Enum1.E, Decl(constEnums.ts, 9, 14))
Q = -D,
>Q : Symbol(Enum1.Q, Decl(constEnums.ts, 21, 15))
>Q : Symbol(Enum1.Q, Decl(constEnums.ts, 22, 16))
>D : Symbol(Enum1.D, Decl(constEnums.ts, 8, 11))
R = C & 5,
>R : Symbol(Enum1.R, Decl(constEnums.ts, 22, 11))
>R : Symbol(Enum1.R, Decl(constEnums.ts, 23, 11))
>C : Symbol(Enum1.C, Decl(constEnums.ts, 7, 6))
S = 5 & C,
>S : Symbol(Enum1.S, Decl(constEnums.ts, 23, 14))
>S : Symbol(Enum1.S, Decl(constEnums.ts, 24, 14))
>C : Symbol(Enum1.C, Decl(constEnums.ts, 7, 6))
T = C | D,
>T : Symbol(Enum1.T, Decl(constEnums.ts, 24, 14))
>T : Symbol(Enum1.T, Decl(constEnums.ts, 25, 14))
>C : Symbol(Enum1.C, Decl(constEnums.ts, 7, 6))
>D : Symbol(Enum1.D, Decl(constEnums.ts, 8, 11))
U = C | 1,
>U : Symbol(Enum1.U, Decl(constEnums.ts, 25, 14))
>U : Symbol(Enum1.U, Decl(constEnums.ts, 26, 14))
>C : Symbol(Enum1.C, Decl(constEnums.ts, 7, 6))
V = 10 | D,
>V : Symbol(Enum1.V, Decl(constEnums.ts, 26, 14))
>V : Symbol(Enum1.V, Decl(constEnums.ts, 27, 14))
>D : Symbol(Enum1.D, Decl(constEnums.ts, 8, 11))
W = Enum1.V,
>W : Symbol(Enum1.W, Decl(constEnums.ts, 27, 15))
>Enum1.V : Symbol(Enum1.V, Decl(constEnums.ts, 26, 14))
>W : Symbol(Enum1.W, Decl(constEnums.ts, 28, 15))
>Enum1.V : Symbol(Enum1.V, Decl(constEnums.ts, 27, 14))
>Enum1 : Symbol(Enum1, Decl(constEnums.ts, 0, 0), Decl(constEnums.ts, 2, 1))
>V : Symbol(Enum1.V, Decl(constEnums.ts, 26, 14))
>V : Symbol(Enum1.V, Decl(constEnums.ts, 27, 14))
// correct cases: reference to the enum member from different enum declaration
W1 = A0,
>W1 : Symbol(Enum1.W1, Decl(constEnums.ts, 28, 16))
>W1 : Symbol(Enum1.W1, Decl(constEnums.ts, 29, 16))
>A0 : Symbol(Enum1.A0, Decl(constEnums.ts, 0, 18))
W2 = Enum1.A0,
>W2 : Symbol(Enum1.W2, Decl(constEnums.ts, 31, 12))
>W2 : Symbol(Enum1.W2, Decl(constEnums.ts, 32, 12))
>Enum1.A0 : Symbol(Enum1.A0, Decl(constEnums.ts, 0, 18))
>Enum1 : Symbol(Enum1, Decl(constEnums.ts, 0, 0), Decl(constEnums.ts, 2, 1))
>A0 : Symbol(Enum1.A0, Decl(constEnums.ts, 0, 18))
W3 = Enum1["A0"],
>W3 : Symbol(Enum1.W3, Decl(constEnums.ts, 32, 18))
>W3 : Symbol(Enum1.W3, Decl(constEnums.ts, 33, 18))
>Enum1 : Symbol(Enum1, Decl(constEnums.ts, 0, 0), Decl(constEnums.ts, 2, 1))
>"A0" : Symbol(Enum1.A0, Decl(constEnums.ts, 0, 18))
W4 = Enum1["W"],
>W4 : Symbol(Enum1.W4, Decl(constEnums.ts, 33, 21))
>W4 : Symbol(Enum1.W4, Decl(constEnums.ts, 34, 21))
>Enum1 : Symbol(Enum1, Decl(constEnums.ts, 0, 0), Decl(constEnums.ts, 2, 1))
>"W" : Symbol(Enum1.W, Decl(constEnums.ts, 27, 15))
>"W" : Symbol(Enum1.W, Decl(constEnums.ts, 28, 15))
}
module A {
>A : Symbol(A, Decl(constEnums.ts, 35, 1), Decl(constEnums.ts, 47, 1))
>A : Symbol(A, Decl(constEnums.ts, 36, 1), Decl(constEnums.ts, 48, 1))
export module B {
>B : Symbol(B, Decl(constEnums.ts, 38, 10), Decl(constEnums.ts, 49, 10))
>B : Symbol(B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10))
export module C {
>C : Symbol(C, Decl(constEnums.ts, 39, 21), Decl(constEnums.ts, 50, 21))
>C : Symbol(C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21))
export const enum E {
>E : Symbol(E, Decl(constEnums.ts, 40, 25), Decl(constEnums.ts, 51, 25))
>E : Symbol(E, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25))
V1 = 1,
>V1 : Symbol(I.V1, Decl(constEnums.ts, 41, 33))
>V1 : Symbol(I.V1, Decl(constEnums.ts, 42, 33))
V2 = A.B.C.E.V1 | 100
>V2 : Symbol(I.V2, Decl(constEnums.ts, 42, 23))
>A.B.C.E.V1 : Symbol(I.V1, Decl(constEnums.ts, 41, 33))
>A.B.C.E : Symbol(E, Decl(constEnums.ts, 40, 25), Decl(constEnums.ts, 51, 25))
>A.B.C : Symbol(C, Decl(constEnums.ts, 39, 21), Decl(constEnums.ts, 50, 21))
>A.B : Symbol(B, Decl(constEnums.ts, 38, 10), Decl(constEnums.ts, 49, 10))
>A : Symbol(A, Decl(constEnums.ts, 35, 1), Decl(constEnums.ts, 47, 1))
>B : Symbol(B, Decl(constEnums.ts, 38, 10), Decl(constEnums.ts, 49, 10))
>C : Symbol(C, Decl(constEnums.ts, 39, 21), Decl(constEnums.ts, 50, 21))
>E : Symbol(E, Decl(constEnums.ts, 40, 25), Decl(constEnums.ts, 51, 25))
>V1 : Symbol(I.V1, Decl(constEnums.ts, 41, 33))
>V2 : Symbol(I.V2, Decl(constEnums.ts, 43, 23))
>A.B.C.E.V1 : Symbol(I.V1, Decl(constEnums.ts, 42, 33))
>A.B.C.E : Symbol(E, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25))
>A.B.C : Symbol(C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21))
>A.B : Symbol(B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10))
>A : Symbol(A, Decl(constEnums.ts, 36, 1), Decl(constEnums.ts, 48, 1))
>B : Symbol(B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10))
>C : Symbol(C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21))
>E : Symbol(E, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25))
>V1 : Symbol(I.V1, Decl(constEnums.ts, 42, 33))
}
}
}
}
module A {
>A : Symbol(A, Decl(constEnums.ts, 35, 1), Decl(constEnums.ts, 47, 1))
>A : Symbol(A, Decl(constEnums.ts, 36, 1), Decl(constEnums.ts, 48, 1))
export module B {
>B : Symbol(B, Decl(constEnums.ts, 38, 10), Decl(constEnums.ts, 49, 10))
>B : Symbol(B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10))
export module C {
>C : Symbol(C, Decl(constEnums.ts, 39, 21), Decl(constEnums.ts, 50, 21))
>C : Symbol(C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21))
export const enum E {
>E : Symbol(E, Decl(constEnums.ts, 40, 25), Decl(constEnums.ts, 51, 25))
>E : Symbol(E, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25))
V3 = A.B.C.E["V2"] & 200,
>V3 : Symbol(I.V3, Decl(constEnums.ts, 52, 33))
>A.B.C.E : Symbol(E, Decl(constEnums.ts, 40, 25), Decl(constEnums.ts, 51, 25))
>A.B.C : Symbol(C, Decl(constEnums.ts, 39, 21), Decl(constEnums.ts, 50, 21))
>A.B : Symbol(B, Decl(constEnums.ts, 38, 10), Decl(constEnums.ts, 49, 10))
>A : Symbol(A, Decl(constEnums.ts, 35, 1), Decl(constEnums.ts, 47, 1))
>B : Symbol(B, Decl(constEnums.ts, 38, 10), Decl(constEnums.ts, 49, 10))
>C : Symbol(C, Decl(constEnums.ts, 39, 21), Decl(constEnums.ts, 50, 21))
>E : Symbol(E, Decl(constEnums.ts, 40, 25), Decl(constEnums.ts, 51, 25))
>"V2" : Symbol(I.V2, Decl(constEnums.ts, 42, 23))
>V3 : Symbol(I.V3, Decl(constEnums.ts, 53, 33))
>A.B.C.E : Symbol(E, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25))
>A.B.C : Symbol(C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21))
>A.B : Symbol(B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10))
>A : Symbol(A, Decl(constEnums.ts, 36, 1), Decl(constEnums.ts, 48, 1))
>B : Symbol(B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10))
>C : Symbol(C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21))
>E : Symbol(E, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25))
>"V2" : Symbol(I.V2, Decl(constEnums.ts, 43, 23))
}
}
}
}
module A1 {
>A1 : Symbol(A1, Decl(constEnums.ts, 57, 1))
>A1 : Symbol(A1, Decl(constEnums.ts, 58, 1))
export module B {
>B : Symbol(B, Decl(constEnums.ts, 59, 11))
>B : Symbol(B, Decl(constEnums.ts, 60, 11))
export module C {
>C : Symbol(C, Decl(constEnums.ts, 60, 21))
>C : Symbol(C, Decl(constEnums.ts, 61, 21))
export const enum E {
>E : Symbol(E, Decl(constEnums.ts, 61, 25))
>E : Symbol(E, Decl(constEnums.ts, 62, 25))
V1 = 10,
>V1 : Symbol(E.V1, Decl(constEnums.ts, 62, 33))
>V1 : Symbol(E.V1, Decl(constEnums.ts, 63, 33))
V2 = 110,
>V2 : Symbol(E.V2, Decl(constEnums.ts, 63, 24))
>V2 : Symbol(E.V2, Decl(constEnums.ts, 64, 24))
}
}
}
}
module A2 {
>A2 : Symbol(A2, Decl(constEnums.ts, 68, 1))
>A2 : Symbol(A2, Decl(constEnums.ts, 69, 1))
export module B {
>B : Symbol(B, Decl(constEnums.ts, 70, 11))
>B : Symbol(B, Decl(constEnums.ts, 71, 11))
export module C {
>C : Symbol(C, Decl(constEnums.ts, 71, 21), Decl(constEnums.ts, 77, 9))
>C : Symbol(C, Decl(constEnums.ts, 72, 21), Decl(constEnums.ts, 78, 9))
export const enum E {
>E : Symbol(E, Decl(constEnums.ts, 72, 25))
>E : Symbol(E, Decl(constEnums.ts, 73, 25))
V1 = 10,
>V1 : Symbol(E.V1, Decl(constEnums.ts, 73, 33))
>V1 : Symbol(E.V1, Decl(constEnums.ts, 74, 33))
V2 = 110,
>V2 : Symbol(E.V2, Decl(constEnums.ts, 74, 24))
>V2 : Symbol(E.V2, Decl(constEnums.ts, 75, 24))
}
}
// module C will be classified as value
export module C {
>C : Symbol(C, Decl(constEnums.ts, 71, 21), Decl(constEnums.ts, 77, 9))
>C : Symbol(C, Decl(constEnums.ts, 72, 21), Decl(constEnums.ts, 78, 9))
var x = 1
>x : Symbol(x, Decl(constEnums.ts, 80, 15))
>x : Symbol(x, Decl(constEnums.ts, 81, 15))
}
}
}
import I = A.B.C.E;
>I : Symbol(I, Decl(constEnums.ts, 83, 1))
>A : Symbol(A, Decl(constEnums.ts, 35, 1), Decl(constEnums.ts, 47, 1))
>B : Symbol(A.B, Decl(constEnums.ts, 38, 10), Decl(constEnums.ts, 49, 10))
>C : Symbol(A.B.C, Decl(constEnums.ts, 39, 21), Decl(constEnums.ts, 50, 21))
>E : Symbol(I, Decl(constEnums.ts, 40, 25), Decl(constEnums.ts, 51, 25))
>I : Symbol(I, Decl(constEnums.ts, 84, 1))
>A : Symbol(A, Decl(constEnums.ts, 36, 1), Decl(constEnums.ts, 48, 1))
>B : Symbol(A.B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10))
>C : Symbol(A.B.C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21))
>E : Symbol(I, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25))
import I1 = A1.B;
>I1 : Symbol(I1, Decl(constEnums.ts, 85, 19))
>A1 : Symbol(A1, Decl(constEnums.ts, 57, 1))
>B : Symbol(I1, Decl(constEnums.ts, 59, 11))
>I1 : Symbol(I1, Decl(constEnums.ts, 86, 19))
>A1 : Symbol(A1, Decl(constEnums.ts, 58, 1))
>B : Symbol(I1, Decl(constEnums.ts, 60, 11))
import I2 = A2.B;
>I2 : Symbol(I2, Decl(constEnums.ts, 86, 17))
>A2 : Symbol(A2, Decl(constEnums.ts, 68, 1))
>B : Symbol(I2, Decl(constEnums.ts, 70, 11))
>I2 : Symbol(I2, Decl(constEnums.ts, 87, 17))
>A2 : Symbol(A2, Decl(constEnums.ts, 69, 1))
>B : Symbol(I2, Decl(constEnums.ts, 71, 11))
function foo0(e: I): void {
>foo0 : Symbol(foo0, Decl(constEnums.ts, 87, 17))
>e : Symbol(e, Decl(constEnums.ts, 89, 14))
>I : Symbol(I, Decl(constEnums.ts, 83, 1))
>foo0 : Symbol(foo0, Decl(constEnums.ts, 88, 17))
>e : Symbol(e, Decl(constEnums.ts, 90, 14))
>I : Symbol(I, Decl(constEnums.ts, 84, 1))
if (e === I.V1) {
>e : Symbol(e, Decl(constEnums.ts, 89, 14))
>I.V1 : Symbol(I.V1, Decl(constEnums.ts, 41, 33))
>I : Symbol(I, Decl(constEnums.ts, 83, 1))
>V1 : Symbol(I.V1, Decl(constEnums.ts, 41, 33))
>e : Symbol(e, Decl(constEnums.ts, 90, 14))
>I.V1 : Symbol(I.V1, Decl(constEnums.ts, 42, 33))
>I : Symbol(I, Decl(constEnums.ts, 84, 1))
>V1 : Symbol(I.V1, Decl(constEnums.ts, 42, 33))
}
else if (e === I.V2) {
>e : Symbol(e, Decl(constEnums.ts, 89, 14))
>I.V2 : Symbol(I.V2, Decl(constEnums.ts, 42, 23))
>I : Symbol(I, Decl(constEnums.ts, 83, 1))
>V2 : Symbol(I.V2, Decl(constEnums.ts, 42, 23))
>e : Symbol(e, Decl(constEnums.ts, 90, 14))
>I.V2 : Symbol(I.V2, Decl(constEnums.ts, 43, 23))
>I : Symbol(I, Decl(constEnums.ts, 84, 1))
>V2 : Symbol(I.V2, Decl(constEnums.ts, 43, 23))
}
}
function foo1(e: I1.C.E): void {
>foo1 : Symbol(foo1, Decl(constEnums.ts, 94, 1))
>e : Symbol(e, Decl(constEnums.ts, 96, 14))
>I1 : Symbol(I1, Decl(constEnums.ts, 85, 19))
>C : Symbol(I1.C, Decl(constEnums.ts, 60, 21))
>E : Symbol(I1.C.E, Decl(constEnums.ts, 61, 25))
>foo1 : Symbol(foo1, Decl(constEnums.ts, 95, 1))
>e : Symbol(e, Decl(constEnums.ts, 97, 14))
>I1 : Symbol(I1, Decl(constEnums.ts, 86, 19))
>C : Symbol(I1.C, Decl(constEnums.ts, 61, 21))
>E : Symbol(I1.C.E, Decl(constEnums.ts, 62, 25))
if (e === I1.C.E.V1) {
>e : Symbol(e, Decl(constEnums.ts, 96, 14))
>I1.C.E.V1 : Symbol(I1.C.E.V1, Decl(constEnums.ts, 62, 33))
>I1.C.E : Symbol(I1.C.E, Decl(constEnums.ts, 61, 25))
>I1.C : Symbol(I1.C, Decl(constEnums.ts, 60, 21))
>I1 : Symbol(I1, Decl(constEnums.ts, 85, 19))
>C : Symbol(I1.C, Decl(constEnums.ts, 60, 21))
>E : Symbol(I1.C.E, Decl(constEnums.ts, 61, 25))
>V1 : Symbol(I1.C.E.V1, Decl(constEnums.ts, 62, 33))
>e : Symbol(e, Decl(constEnums.ts, 97, 14))
>I1.C.E.V1 : Symbol(I1.C.E.V1, Decl(constEnums.ts, 63, 33))
>I1.C.E : Symbol(I1.C.E, Decl(constEnums.ts, 62, 25))
>I1.C : Symbol(I1.C, Decl(constEnums.ts, 61, 21))
>I1 : Symbol(I1, Decl(constEnums.ts, 86, 19))
>C : Symbol(I1.C, Decl(constEnums.ts, 61, 21))
>E : Symbol(I1.C.E, Decl(constEnums.ts, 62, 25))
>V1 : Symbol(I1.C.E.V1, Decl(constEnums.ts, 63, 33))
}
else if (e === I1.C.E.V2) {
>e : Symbol(e, Decl(constEnums.ts, 96, 14))
>I1.C.E.V2 : Symbol(I1.C.E.V2, Decl(constEnums.ts, 63, 24))
>I1.C.E : Symbol(I1.C.E, Decl(constEnums.ts, 61, 25))
>I1.C : Symbol(I1.C, Decl(constEnums.ts, 60, 21))
>I1 : Symbol(I1, Decl(constEnums.ts, 85, 19))
>C : Symbol(I1.C, Decl(constEnums.ts, 60, 21))
>E : Symbol(I1.C.E, Decl(constEnums.ts, 61, 25))
>V2 : Symbol(I1.C.E.V2, Decl(constEnums.ts, 63, 24))
>e : Symbol(e, Decl(constEnums.ts, 97, 14))
>I1.C.E.V2 : Symbol(I1.C.E.V2, Decl(constEnums.ts, 64, 24))
>I1.C.E : Symbol(I1.C.E, Decl(constEnums.ts, 62, 25))
>I1.C : Symbol(I1.C, Decl(constEnums.ts, 61, 21))
>I1 : Symbol(I1, Decl(constEnums.ts, 86, 19))
>C : Symbol(I1.C, Decl(constEnums.ts, 61, 21))
>E : Symbol(I1.C.E, Decl(constEnums.ts, 62, 25))
>V2 : Symbol(I1.C.E.V2, Decl(constEnums.ts, 64, 24))
}
}
function foo2(e: I2.C.E): void {
>foo2 : Symbol(foo2, Decl(constEnums.ts, 101, 1))
>e : Symbol(e, Decl(constEnums.ts, 103, 14))
>I2 : Symbol(I2, Decl(constEnums.ts, 86, 17))
>C : Symbol(I2.C, Decl(constEnums.ts, 71, 21), Decl(constEnums.ts, 77, 9))
>E : Symbol(I2.C.E, Decl(constEnums.ts, 72, 25))
>foo2 : Symbol(foo2, Decl(constEnums.ts, 102, 1))
>e : Symbol(e, Decl(constEnums.ts, 104, 14))
>I2 : Symbol(I2, Decl(constEnums.ts, 87, 17))
>C : Symbol(I2.C, Decl(constEnums.ts, 72, 21), Decl(constEnums.ts, 78, 9))
>E : Symbol(I2.C.E, Decl(constEnums.ts, 73, 25))
if (e === I2.C.E.V1) {
>e : Symbol(e, Decl(constEnums.ts, 103, 14))
>I2.C.E.V1 : Symbol(I2.C.E.V1, Decl(constEnums.ts, 73, 33))
>I2.C.E : Symbol(I2.C.E, Decl(constEnums.ts, 72, 25))
>I2.C : Symbol(I2.C, Decl(constEnums.ts, 71, 21), Decl(constEnums.ts, 77, 9))
>I2 : Symbol(I2, Decl(constEnums.ts, 86, 17))
>C : Symbol(I2.C, Decl(constEnums.ts, 71, 21), Decl(constEnums.ts, 77, 9))
>E : Symbol(I2.C.E, Decl(constEnums.ts, 72, 25))
>V1 : Symbol(I2.C.E.V1, Decl(constEnums.ts, 73, 33))
>e : Symbol(e, Decl(constEnums.ts, 104, 14))
>I2.C.E.V1 : Symbol(I2.C.E.V1, Decl(constEnums.ts, 74, 33))
>I2.C.E : Symbol(I2.C.E, Decl(constEnums.ts, 73, 25))
>I2.C : Symbol(I2.C, Decl(constEnums.ts, 72, 21), Decl(constEnums.ts, 78, 9))
>I2 : Symbol(I2, Decl(constEnums.ts, 87, 17))
>C : Symbol(I2.C, Decl(constEnums.ts, 72, 21), Decl(constEnums.ts, 78, 9))
>E : Symbol(I2.C.E, Decl(constEnums.ts, 73, 25))
>V1 : Symbol(I2.C.E.V1, Decl(constEnums.ts, 74, 33))
}
else if (e === I2.C.E.V2) {
>e : Symbol(e, Decl(constEnums.ts, 103, 14))
>I2.C.E.V2 : Symbol(I2.C.E.V2, Decl(constEnums.ts, 74, 24))
>I2.C.E : Symbol(I2.C.E, Decl(constEnums.ts, 72, 25))
>I2.C : Symbol(I2.C, Decl(constEnums.ts, 71, 21), Decl(constEnums.ts, 77, 9))
>I2 : Symbol(I2, Decl(constEnums.ts, 86, 17))
>C : Symbol(I2.C, Decl(constEnums.ts, 71, 21), Decl(constEnums.ts, 77, 9))
>E : Symbol(I2.C.E, Decl(constEnums.ts, 72, 25))
>V2 : Symbol(I2.C.E.V2, Decl(constEnums.ts, 74, 24))
>e : Symbol(e, Decl(constEnums.ts, 104, 14))
>I2.C.E.V2 : Symbol(I2.C.E.V2, Decl(constEnums.ts, 75, 24))
>I2.C.E : Symbol(I2.C.E, Decl(constEnums.ts, 73, 25))
>I2.C : Symbol(I2.C, Decl(constEnums.ts, 72, 21), Decl(constEnums.ts, 78, 9))
>I2 : Symbol(I2, Decl(constEnums.ts, 87, 17))
>C : Symbol(I2.C, Decl(constEnums.ts, 72, 21), Decl(constEnums.ts, 78, 9))
>E : Symbol(I2.C.E, Decl(constEnums.ts, 73, 25))
>V2 : Symbol(I2.C.E.V2, Decl(constEnums.ts, 75, 24))
}
}
function foo(x: Enum1) {
>foo : Symbol(foo, Decl(constEnums.ts, 108, 1))
>x : Symbol(x, Decl(constEnums.ts, 111, 13))
>foo : Symbol(foo, Decl(constEnums.ts, 109, 1))
>x : Symbol(x, Decl(constEnums.ts, 112, 13))
>Enum1 : Symbol(Enum1, Decl(constEnums.ts, 0, 0), Decl(constEnums.ts, 2, 1))
switch (x) {
>x : Symbol(x, Decl(constEnums.ts, 111, 13))
>x : Symbol(x, Decl(constEnums.ts, 112, 13))
case Enum1.A:
>Enum1.A : Symbol(Enum1.A, Decl(constEnums.ts, 4, 18))
@ -419,106 +423,111 @@ function foo(x: Enum1) {
>Enum1 : Symbol(Enum1, Decl(constEnums.ts, 0, 0), Decl(constEnums.ts, 2, 1))
>P : Symbol(Enum1.P, Decl(constEnums.ts, 20, 15))
case Enum1.Q:
>Enum1.Q : Symbol(Enum1.Q, Decl(constEnums.ts, 21, 15))
case Enum1.PQ:
>Enum1.PQ : Symbol(Enum1.PQ, Decl(constEnums.ts, 21, 15))
>Enum1 : Symbol(Enum1, Decl(constEnums.ts, 0, 0), Decl(constEnums.ts, 2, 1))
>Q : Symbol(Enum1.Q, Decl(constEnums.ts, 21, 15))
>PQ : Symbol(Enum1.PQ, Decl(constEnums.ts, 21, 15))
case Enum1.Q:
>Enum1.Q : Symbol(Enum1.Q, Decl(constEnums.ts, 22, 16))
>Enum1 : Symbol(Enum1, Decl(constEnums.ts, 0, 0), Decl(constEnums.ts, 2, 1))
>Q : Symbol(Enum1.Q, Decl(constEnums.ts, 22, 16))
case Enum1.R:
>Enum1.R : Symbol(Enum1.R, Decl(constEnums.ts, 22, 11))
>Enum1.R : Symbol(Enum1.R, Decl(constEnums.ts, 23, 11))
>Enum1 : Symbol(Enum1, Decl(constEnums.ts, 0, 0), Decl(constEnums.ts, 2, 1))
>R : Symbol(Enum1.R, Decl(constEnums.ts, 22, 11))
>R : Symbol(Enum1.R, Decl(constEnums.ts, 23, 11))
case Enum1.S:
>Enum1.S : Symbol(Enum1.S, Decl(constEnums.ts, 23, 14))
>Enum1.S : Symbol(Enum1.S, Decl(constEnums.ts, 24, 14))
>Enum1 : Symbol(Enum1, Decl(constEnums.ts, 0, 0), Decl(constEnums.ts, 2, 1))
>S : Symbol(Enum1.S, Decl(constEnums.ts, 23, 14))
>S : Symbol(Enum1.S, Decl(constEnums.ts, 24, 14))
case Enum1["T"]:
>Enum1 : Symbol(Enum1, Decl(constEnums.ts, 0, 0), Decl(constEnums.ts, 2, 1))
>"T" : Symbol(Enum1.T, Decl(constEnums.ts, 24, 14))
>"T" : Symbol(Enum1.T, Decl(constEnums.ts, 25, 14))
case Enum1.U:
>Enum1.U : Symbol(Enum1.U, Decl(constEnums.ts, 25, 14))
>Enum1.U : Symbol(Enum1.U, Decl(constEnums.ts, 26, 14))
>Enum1 : Symbol(Enum1, Decl(constEnums.ts, 0, 0), Decl(constEnums.ts, 2, 1))
>U : Symbol(Enum1.U, Decl(constEnums.ts, 25, 14))
>U : Symbol(Enum1.U, Decl(constEnums.ts, 26, 14))
case Enum1.V:
>Enum1.V : Symbol(Enum1.V, Decl(constEnums.ts, 26, 14))
>Enum1.V : Symbol(Enum1.V, Decl(constEnums.ts, 27, 14))
>Enum1 : Symbol(Enum1, Decl(constEnums.ts, 0, 0), Decl(constEnums.ts, 2, 1))
>V : Symbol(Enum1.V, Decl(constEnums.ts, 26, 14))
>V : Symbol(Enum1.V, Decl(constEnums.ts, 27, 14))
case Enum1.W:
>Enum1.W : Symbol(Enum1.W, Decl(constEnums.ts, 27, 15))
>Enum1.W : Symbol(Enum1.W, Decl(constEnums.ts, 28, 15))
>Enum1 : Symbol(Enum1, Decl(constEnums.ts, 0, 0), Decl(constEnums.ts, 2, 1))
>W : Symbol(Enum1.W, Decl(constEnums.ts, 27, 15))
>W : Symbol(Enum1.W, Decl(constEnums.ts, 28, 15))
case Enum1.W1:
>Enum1.W1 : Symbol(Enum1.W1, Decl(constEnums.ts, 28, 16))
>Enum1.W1 : Symbol(Enum1.W1, Decl(constEnums.ts, 29, 16))
>Enum1 : Symbol(Enum1, Decl(constEnums.ts, 0, 0), Decl(constEnums.ts, 2, 1))
>W1 : Symbol(Enum1.W1, Decl(constEnums.ts, 28, 16))
>W1 : Symbol(Enum1.W1, Decl(constEnums.ts, 29, 16))
case Enum1.W2:
>Enum1.W2 : Symbol(Enum1.W2, Decl(constEnums.ts, 31, 12))
>Enum1.W2 : Symbol(Enum1.W2, Decl(constEnums.ts, 32, 12))
>Enum1 : Symbol(Enum1, Decl(constEnums.ts, 0, 0), Decl(constEnums.ts, 2, 1))
>W2 : Symbol(Enum1.W2, Decl(constEnums.ts, 31, 12))
>W2 : Symbol(Enum1.W2, Decl(constEnums.ts, 32, 12))
case Enum1.W3:
>Enum1.W3 : Symbol(Enum1.W3, Decl(constEnums.ts, 32, 18))
>Enum1.W3 : Symbol(Enum1.W3, Decl(constEnums.ts, 33, 18))
>Enum1 : Symbol(Enum1, Decl(constEnums.ts, 0, 0), Decl(constEnums.ts, 2, 1))
>W3 : Symbol(Enum1.W3, Decl(constEnums.ts, 32, 18))
>W3 : Symbol(Enum1.W3, Decl(constEnums.ts, 33, 18))
case Enum1.W4:
>Enum1.W4 : Symbol(Enum1.W4, Decl(constEnums.ts, 33, 21))
>Enum1.W4 : Symbol(Enum1.W4, Decl(constEnums.ts, 34, 21))
>Enum1 : Symbol(Enum1, Decl(constEnums.ts, 0, 0), Decl(constEnums.ts, 2, 1))
>W4 : Symbol(Enum1.W4, Decl(constEnums.ts, 33, 21))
>W4 : Symbol(Enum1.W4, Decl(constEnums.ts, 34, 21))
break;
}
}
function bar(e: A.B.C.E): number {
>bar : Symbol(bar, Decl(constEnums.ts, 142, 1))
>e : Symbol(e, Decl(constEnums.ts, 144, 13))
>A : Symbol(A, Decl(constEnums.ts, 35, 1), Decl(constEnums.ts, 47, 1))
>B : Symbol(A.B, Decl(constEnums.ts, 38, 10), Decl(constEnums.ts, 49, 10))
>C : Symbol(A.B.C, Decl(constEnums.ts, 39, 21), Decl(constEnums.ts, 50, 21))
>E : Symbol(I, Decl(constEnums.ts, 40, 25), Decl(constEnums.ts, 51, 25))
>bar : Symbol(bar, Decl(constEnums.ts, 144, 1))
>e : Symbol(e, Decl(constEnums.ts, 146, 13))
>A : Symbol(A, Decl(constEnums.ts, 36, 1), Decl(constEnums.ts, 48, 1))
>B : Symbol(A.B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10))
>C : Symbol(A.B.C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21))
>E : Symbol(I, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25))
switch (e) {
>e : Symbol(e, Decl(constEnums.ts, 144, 13))
>e : Symbol(e, Decl(constEnums.ts, 146, 13))
case A.B.C.E.V1: return 1;
>A.B.C.E.V1 : Symbol(I.V1, Decl(constEnums.ts, 41, 33))
>A.B.C.E : Symbol(I, Decl(constEnums.ts, 40, 25), Decl(constEnums.ts, 51, 25))
>A.B.C : Symbol(A.B.C, Decl(constEnums.ts, 39, 21), Decl(constEnums.ts, 50, 21))
>A.B : Symbol(A.B, Decl(constEnums.ts, 38, 10), Decl(constEnums.ts, 49, 10))
>A : Symbol(A, Decl(constEnums.ts, 35, 1), Decl(constEnums.ts, 47, 1))
>B : Symbol(A.B, Decl(constEnums.ts, 38, 10), Decl(constEnums.ts, 49, 10))
>C : Symbol(A.B.C, Decl(constEnums.ts, 39, 21), Decl(constEnums.ts, 50, 21))
>E : Symbol(I, Decl(constEnums.ts, 40, 25), Decl(constEnums.ts, 51, 25))
>V1 : Symbol(I.V1, Decl(constEnums.ts, 41, 33))
>A.B.C.E.V1 : Symbol(I.V1, Decl(constEnums.ts, 42, 33))
>A.B.C.E : Symbol(I, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25))
>A.B.C : Symbol(A.B.C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21))
>A.B : Symbol(A.B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10))
>A : Symbol(A, Decl(constEnums.ts, 36, 1), Decl(constEnums.ts, 48, 1))
>B : Symbol(A.B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10))
>C : Symbol(A.B.C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21))
>E : Symbol(I, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25))
>V1 : Symbol(I.V1, Decl(constEnums.ts, 42, 33))
case A.B.C.E.V2: return 1;
>A.B.C.E.V2 : Symbol(I.V2, Decl(constEnums.ts, 42, 23))
>A.B.C.E : Symbol(I, Decl(constEnums.ts, 40, 25), Decl(constEnums.ts, 51, 25))
>A.B.C : Symbol(A.B.C, Decl(constEnums.ts, 39, 21), Decl(constEnums.ts, 50, 21))
>A.B : Symbol(A.B, Decl(constEnums.ts, 38, 10), Decl(constEnums.ts, 49, 10))
>A : Symbol(A, Decl(constEnums.ts, 35, 1), Decl(constEnums.ts, 47, 1))
>B : Symbol(A.B, Decl(constEnums.ts, 38, 10), Decl(constEnums.ts, 49, 10))
>C : Symbol(A.B.C, Decl(constEnums.ts, 39, 21), Decl(constEnums.ts, 50, 21))
>E : Symbol(I, Decl(constEnums.ts, 40, 25), Decl(constEnums.ts, 51, 25))
>V2 : Symbol(I.V2, Decl(constEnums.ts, 42, 23))
>A.B.C.E.V2 : Symbol(I.V2, Decl(constEnums.ts, 43, 23))
>A.B.C.E : Symbol(I, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25))
>A.B.C : Symbol(A.B.C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21))
>A.B : Symbol(A.B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10))
>A : Symbol(A, Decl(constEnums.ts, 36, 1), Decl(constEnums.ts, 48, 1))
>B : Symbol(A.B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10))
>C : Symbol(A.B.C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21))
>E : Symbol(I, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25))
>V2 : Symbol(I.V2, Decl(constEnums.ts, 43, 23))
case A.B.C.E.V3: return 1;
>A.B.C.E.V3 : Symbol(I.V3, Decl(constEnums.ts, 52, 33))
>A.B.C.E : Symbol(I, Decl(constEnums.ts, 40, 25), Decl(constEnums.ts, 51, 25))
>A.B.C : Symbol(A.B.C, Decl(constEnums.ts, 39, 21), Decl(constEnums.ts, 50, 21))
>A.B : Symbol(A.B, Decl(constEnums.ts, 38, 10), Decl(constEnums.ts, 49, 10))
>A : Symbol(A, Decl(constEnums.ts, 35, 1), Decl(constEnums.ts, 47, 1))
>B : Symbol(A.B, Decl(constEnums.ts, 38, 10), Decl(constEnums.ts, 49, 10))
>C : Symbol(A.B.C, Decl(constEnums.ts, 39, 21), Decl(constEnums.ts, 50, 21))
>E : Symbol(I, Decl(constEnums.ts, 40, 25), Decl(constEnums.ts, 51, 25))
>V3 : Symbol(I.V3, Decl(constEnums.ts, 52, 33))
>A.B.C.E.V3 : Symbol(I.V3, Decl(constEnums.ts, 53, 33))
>A.B.C.E : Symbol(I, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25))
>A.B.C : Symbol(A.B.C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21))
>A.B : Symbol(A.B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10))
>A : Symbol(A, Decl(constEnums.ts, 36, 1), Decl(constEnums.ts, 48, 1))
>B : Symbol(A.B, Decl(constEnums.ts, 39, 10), Decl(constEnums.ts, 50, 10))
>C : Symbol(A.B.C, Decl(constEnums.ts, 40, 21), Decl(constEnums.ts, 51, 21))
>E : Symbol(I, Decl(constEnums.ts, 41, 25), Decl(constEnums.ts, 52, 25))
>V3 : Symbol(I.V3, Decl(constEnums.ts, 53, 33))
}
}

View file

@ -103,6 +103,12 @@ const enum Enum1 {
>E : Enum1
>1 : 1
PQ = E ** 2,
>PQ : Enum1
>E ** 2 : number
>E : Enum1
>2 : 2
Q = -D,
>Q : Enum1
>-D : number
@ -478,6 +484,11 @@ function foo(x: Enum1) {
>Enum1 : typeof Enum1
>P : Enum1
case Enum1.PQ:
>Enum1.PQ : Enum1
>Enum1 : typeof Enum1
>PQ : Enum1
case Enum1.Q:
>Enum1.Q : Enum1
>Enum1 : typeof Enum1

View file

@ -3,75 +3,76 @@ tests/cases/conformance/fixSignatureCaching.ts(284,10): error TS2339: Property '
tests/cases/conformance/fixSignatureCaching.ts(293,10): error TS2339: Property 'FALLBACK_PHONE' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(294,10): error TS2339: Property 'FALLBACK_TABLET' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(295,10): error TS2339: Property 'FALLBACK_MOBILE' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(327,74): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(366,10): error TS2339: Property 'findMatch' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(384,10): error TS2339: Property 'findMatches' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(404,10): error TS2339: Property 'getVersionStr' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(405,26): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(428,10): error TS2339: Property 'getVersion' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(429,28): error TS2339: Property 'getVersionStr' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(430,31): error TS2339: Property 'prepareVersionNo' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(440,10): error TS2339: Property 'prepareVersionNo' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(455,10): error TS2339: Property 'isMobileFallback' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(456,21): error TS2339: Property 'detectMobileBrowsers' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(457,18): error TS2339: Property 'detectMobileBrowsers' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(460,10): error TS2339: Property 'isTabletFallback' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(461,21): error TS2339: Property 'detectMobileBrowsers' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(464,10): error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(471,23): error TS2339: Property 'findMatch' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(471,38): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(478,22): error TS2339: Property 'findMatch' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(478,37): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(486,18): error TS2339: Property 'isMobileFallback' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(487,39): error TS2339: Property 'isPhoneSized' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
tests/cases/conformance/fixSignatureCaching.ts(489,37): error TS2339: Property 'FALLBACK_MOBILE' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(492,51): error TS2339: Property 'FALLBACK_PHONE' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(495,52): error TS2339: Property 'FALLBACK_TABLET' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(498,25): error TS2339: Property 'isTabletFallback' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(499,48): error TS2339: Property 'FALLBACK_TABLET' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(508,10): error TS2339: Property 'mobileGrade' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(633,10): error TS2339: Property 'detectOS' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(634,21): error TS2339: Property 'findMatch' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(634,36): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(635,18): error TS2339: Property 'findMatch' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(635,33): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(638,10): error TS2339: Property 'getDeviceSmallerSide' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(639,16): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(639,38): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(640,13): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(641,13): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(704,18): error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(734,18): error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(783,18): error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(805,46): error TS2339: Property 'findMatch' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(805,61): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(828,47): error TS2339: Property 'findMatches' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(828,64): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(845,39): error TS2339: Property 'detectOS' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(869,25): error TS2339: Property 'getVersion' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(890,25): error TS2339: Property 'getVersionStr' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(912,36): error TS2339: Property 'findMatches' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(912,53): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(941,33): error TS2339: Property 'isPhoneSized' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
tests/cases/conformance/fixSignatureCaching.ts(952,42): error TS2339: Property 'mobileGrade' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(959,16): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(959,42): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(960,22): error TS2339: Property 'isPhoneSized' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
tests/cases/conformance/fixSignatureCaching.ts(961,57): error TS2339: Property 'getDeviceSmallerSide' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(964,22): error TS2339: Property 'isPhoneSized' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
tests/cases/conformance/fixSignatureCaching.ts(968,18): error TS2339: Property '_impl' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
tests/cases/conformance/fixSignatureCaching.ts(970,18): error TS2339: Property 'version' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
tests/cases/conformance/fixSignatureCaching.ts(975,16): error TS2304: Cannot find name 'module'.
tests/cases/conformance/fixSignatureCaching.ts(975,42): error TS2304: Cannot find name 'module'.
tests/cases/conformance/fixSignatureCaching.ts(976,37): error TS2304: Cannot find name 'module'.
tests/cases/conformance/fixSignatureCaching.ts(977,23): error TS2304: Cannot find name 'define'.
tests/cases/conformance/fixSignatureCaching.ts(977,48): error TS2304: Cannot find name 'define'.
tests/cases/conformance/fixSignatureCaching.ts(978,16): error TS2304: Cannot find name 'define'.
tests/cases/conformance/fixSignatureCaching.ts(979,23): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(301,17): error TS2339: Property 'isArray' does not exist on type 'never'.
tests/cases/conformance/fixSignatureCaching.ts(330,74): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(369,10): error TS2339: Property 'findMatch' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(387,10): error TS2339: Property 'findMatches' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(407,10): error TS2339: Property 'getVersionStr' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(408,26): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(431,10): error TS2339: Property 'getVersion' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(432,28): error TS2339: Property 'getVersionStr' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(433,31): error TS2339: Property 'prepareVersionNo' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(443,10): error TS2339: Property 'prepareVersionNo' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(458,10): error TS2339: Property 'isMobileFallback' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(459,21): error TS2339: Property 'detectMobileBrowsers' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(460,18): error TS2339: Property 'detectMobileBrowsers' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(463,10): error TS2339: Property 'isTabletFallback' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(464,21): error TS2339: Property 'detectMobileBrowsers' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(467,10): error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(474,23): error TS2339: Property 'findMatch' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(474,38): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(481,22): error TS2339: Property 'findMatch' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(481,37): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(489,18): error TS2339: Property 'isMobileFallback' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(490,39): error TS2339: Property 'isPhoneSized' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
tests/cases/conformance/fixSignatureCaching.ts(492,37): error TS2339: Property 'FALLBACK_MOBILE' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(495,51): error TS2339: Property 'FALLBACK_PHONE' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(498,52): error TS2339: Property 'FALLBACK_TABLET' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(501,25): error TS2339: Property 'isTabletFallback' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(502,48): error TS2339: Property 'FALLBACK_TABLET' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(511,10): error TS2339: Property 'mobileGrade' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(636,10): error TS2339: Property 'detectOS' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(637,21): error TS2339: Property 'findMatch' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(637,36): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(638,18): error TS2339: Property 'findMatch' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(638,33): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(641,10): error TS2339: Property 'getDeviceSmallerSide' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(642,16): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(642,38): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(643,13): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(644,13): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(707,18): error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(737,18): error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(786,18): error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(808,46): error TS2339: Property 'findMatch' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(808,61): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(831,47): error TS2339: Property 'findMatches' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(831,64): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(848,39): error TS2339: Property 'detectOS' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(872,25): error TS2339: Property 'getVersion' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(893,25): error TS2339: Property 'getVersionStr' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(915,36): error TS2339: Property 'findMatches' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(915,53): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(944,33): error TS2339: Property 'isPhoneSized' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
tests/cases/conformance/fixSignatureCaching.ts(955,42): error TS2339: Property 'mobileGrade' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(962,16): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(962,42): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(963,22): error TS2339: Property 'isPhoneSized' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
tests/cases/conformance/fixSignatureCaching.ts(964,57): error TS2339: Property 'getDeviceSmallerSide' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(967,22): error TS2339: Property 'isPhoneSized' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
tests/cases/conformance/fixSignatureCaching.ts(971,18): error TS2339: Property '_impl' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
tests/cases/conformance/fixSignatureCaching.ts(973,18): error TS2339: Property 'version' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
tests/cases/conformance/fixSignatureCaching.ts(978,16): error TS2304: Cannot find name 'module'.
tests/cases/conformance/fixSignatureCaching.ts(978,42): error TS2304: Cannot find name 'module'.
tests/cases/conformance/fixSignatureCaching.ts(979,37): error TS2304: Cannot find name 'module'.
tests/cases/conformance/fixSignatureCaching.ts(980,23): error TS2304: Cannot find name 'define'.
tests/cases/conformance/fixSignatureCaching.ts(980,48): error TS2304: Cannot find name 'define'.
tests/cases/conformance/fixSignatureCaching.ts(981,16): error TS2304: Cannot find name 'define'.
tests/cases/conformance/fixSignatureCaching.ts(982,23): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(983,37): error TS2304: Cannot find name 'window'.
==== tests/cases/conformance/fixSignatureCaching.ts (71 errors) ====
==== tests/cases/conformance/fixSignatureCaching.ts (72 errors) ====
// Repro from #10697
(function (define, undefined) {
@ -380,6 +381,11 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin
isArray = ('isArray' in Array) ?
Array.isArray : function (value) { return Object.prototype.toString.call(value) === '[object Array]'; };
isArray = 'isArray' in Array
? function (value) { return Object.prototype.toString.call(value) === '[object Array]'; }
: Array.isArray;
~~~~~~~
!!! error TS2339: Property 'isArray' does not exist on type 'never'.
function equalIC(a, b) {
return a != null && b != null && a.toLowerCase() === b.toLowerCase();
@ -1164,7 +1170,7 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin
MobileDetect._impl = impl;
~~~~~
!!! error TS2339: Property '_impl' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
MobileDetect.version = '1.3.3 2016-07-31';
~~~~~~~
!!! error TS2339: Property 'version' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.

View file

@ -297,6 +297,9 @@ define(function () {
isArray = ('isArray' in Array) ?
Array.isArray : function (value) { return Object.prototype.toString.call(value) === '[object Array]'; };
isArray = 'isArray' in Array
? function (value) { return Object.prototype.toString.call(value) === '[object Array]'; }
: Array.isArray;
function equalIC(a, b) {
return a != null && b != null && a.toLowerCase() === b.toLowerCase();
@ -967,7 +970,7 @@ define(function () {
// should not be replaced by a completely new object - just overwrite existing methods
MobileDetect._impl = impl;
MobileDetect.version = '1.3.3 2016-07-31';
return MobileDetect;
@ -1276,6 +1279,9 @@ define(function () {
impl.FALLBACK_MOBILE = 'UnknownMobile';
isArray = ('isArray' in Array) ?
Array.isArray : function (value) { return Object.prototype.toString.call(value) === '[object Array]'; };
isArray = 'isArray' in Array
? function (value) { return Object.prototype.toString.call(value) === '[object Array]'; }
: Array.isArray;
function equalIC(a, b) {
return a != null && b != null && a.toLowerCase() === b.toLowerCase();
}

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,159 @@
tests/cases/compiler/inKeywordTypeguard.ts(6,11): error TS2339: Property 'b' does not exist on type 'A'.
tests/cases/compiler/inKeywordTypeguard.ts(8,11): error TS2339: Property 'a' does not exist on type 'B'.
tests/cases/compiler/inKeywordTypeguard.ts(14,11): error TS2339: Property 'b' does not exist on type 'A'.
tests/cases/compiler/inKeywordTypeguard.ts(16,11): error TS2339: Property 'a' does not exist on type 'B'.
tests/cases/compiler/inKeywordTypeguard.ts(27,11): error TS2339: Property 'b' does not exist on type 'AWithOptionalProp | BWithOptionalProp'.
Property 'b' does not exist on type 'AWithOptionalProp'.
tests/cases/compiler/inKeywordTypeguard.ts(42,11): error TS2339: Property 'b' does not exist on type 'AWithMethod'.
tests/cases/compiler/inKeywordTypeguard.ts(49,11): error TS2339: Property 'a' does not exist on type 'never'.
tests/cases/compiler/inKeywordTypeguard.ts(50,11): error TS2339: Property 'b' does not exist on type 'never'.
tests/cases/compiler/inKeywordTypeguard.ts(52,11): error TS2339: Property 'a' does not exist on type 'AWithMethod | BWithMethod'.
Property 'a' does not exist on type 'BWithMethod'.
tests/cases/compiler/inKeywordTypeguard.ts(53,11): error TS2339: Property 'b' does not exist on type 'AWithMethod | BWithMethod'.
Property 'b' does not exist on type 'AWithMethod'.
tests/cases/compiler/inKeywordTypeguard.ts(62,11): error TS2339: Property 'b' does not exist on type 'A | C | D'.
Property 'b' does not exist on type 'A'.
tests/cases/compiler/inKeywordTypeguard.ts(64,11): error TS2339: Property 'a' does not exist on type 'B'.
tests/cases/compiler/inKeywordTypeguard.ts(72,32): error TS2339: Property 'b' does not exist on type 'A'.
tests/cases/compiler/inKeywordTypeguard.ts(74,32): error TS2339: Property 'a' does not exist on type 'B'.
tests/cases/compiler/inKeywordTypeguard.ts(82,39): error TS2339: Property 'b' does not exist on type 'A'.
tests/cases/compiler/inKeywordTypeguard.ts(84,39): error TS2339: Property 'a' does not exist on type 'B'.
tests/cases/compiler/inKeywordTypeguard.ts(94,26): error TS2339: Property 'a' does not exist on type 'never'.
==== tests/cases/compiler/inKeywordTypeguard.ts (17 errors) ====
class A { a: string; }
class B { b: string; }
function negativeClassesTest(x: A | B) {
if ("a" in x) {
x.b = "1";
~
!!! error TS2339: Property 'b' does not exist on type 'A'.
} else {
x.a = "1";
~
!!! error TS2339: Property 'a' does not exist on type 'B'.
}
}
function positiveClassesTest(x: A | B) {
if ("a" in x) {
x.b = "1";
~
!!! error TS2339: Property 'b' does not exist on type 'A'.
} else {
x.a = "1";
~
!!! error TS2339: Property 'a' does not exist on type 'B'.
}
}
class AWithOptionalProp { a?: string; }
class BWithOptionalProp { b?: string; }
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
if ("a" in x) {
x.a = "1";
} else {
x.b = "1";
~
!!! error TS2339: Property 'b' does not exist on type 'AWithOptionalProp | BWithOptionalProp'.
!!! error TS2339: Property 'b' does not exist on type 'AWithOptionalProp'.
}
}
class AWithMethod {
a(): string { return ""; }
}
class BWithMethod {
b(): string { return ""; }
}
function negativeTestClassesWithMembers(x: AWithMethod | BWithMethod) {
if ("a" in x) {
x.a();
x.b();
~
!!! error TS2339: Property 'b' does not exist on type 'AWithMethod'.
} else {
}
}
function negativeTestClassesWithMemberMissingInBothClasses(x: AWithMethod | BWithMethod) {
if ("c" in x) {
x.a();
~
!!! error TS2339: Property 'a' does not exist on type 'never'.
x.b();
~
!!! error TS2339: Property 'b' does not exist on type 'never'.
} else {
x.a();
~
!!! error TS2339: Property 'a' does not exist on type 'AWithMethod | BWithMethod'.
!!! error TS2339: Property 'a' does not exist on type 'BWithMethod'.
x.b();
~
!!! error TS2339: Property 'b' does not exist on type 'AWithMethod | BWithMethod'.
!!! error TS2339: Property 'b' does not exist on type 'AWithMethod'.
}
}
class C { a: string; }
class D { a: string; }
function negativeMultipleClassesTest(x: A | B | C | D) {
if ("a" in x) {
x.b = "1";
~
!!! error TS2339: Property 'b' does not exist on type 'A | C | D'.
!!! error TS2339: Property 'b' does not exist on type 'A'.
} else {
x.a = "1";
~
!!! error TS2339: Property 'a' does not exist on type 'B'.
}
}
class ClassWithUnionProp { prop: A | B }
function negativePropTest(x: ClassWithUnionProp) {
if ("a" in x.prop) {
let y: string = x.prop.b;
~
!!! error TS2339: Property 'b' does not exist on type 'A'.
} else {
let z: string = x.prop.a;
~
!!! error TS2339: Property 'a' does not exist on type 'B'.
}
}
class NegativeClassTest {
protected prop: A | B;
inThis() {
if ("a" in this.prop) {
let z: number = this.prop.b;
~
!!! error TS2339: Property 'b' does not exist on type 'A'.
} else {
let y: string = this.prop.a;
~
!!! error TS2339: Property 'a' does not exist on type 'B'.
}
}
}
class UnreachableCodeDetection {
a: string;
inThis() {
if ("a" in this) {
} else {
let y = this.a;
~
!!! error TS2339: Property 'a' does not exist on type 'never'.
}
}
}

View file

@ -0,0 +1,230 @@
//// [inKeywordTypeguard.ts]
class A { a: string; }
class B { b: string; }
function negativeClassesTest(x: A | B) {
if ("a" in x) {
x.b = "1";
} else {
x.a = "1";
}
}
function positiveClassesTest(x: A | B) {
if ("a" in x) {
x.b = "1";
} else {
x.a = "1";
}
}
class AWithOptionalProp { a?: string; }
class BWithOptionalProp { b?: string; }
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
if ("a" in x) {
x.a = "1";
} else {
x.b = "1";
}
}
class AWithMethod {
a(): string { return ""; }
}
class BWithMethod {
b(): string { return ""; }
}
function negativeTestClassesWithMembers(x: AWithMethod | BWithMethod) {
if ("a" in x) {
x.a();
x.b();
} else {
}
}
function negativeTestClassesWithMemberMissingInBothClasses(x: AWithMethod | BWithMethod) {
if ("c" in x) {
x.a();
x.b();
} else {
x.a();
x.b();
}
}
class C { a: string; }
class D { a: string; }
function negativeMultipleClassesTest(x: A | B | C | D) {
if ("a" in x) {
x.b = "1";
} else {
x.a = "1";
}
}
class ClassWithUnionProp { prop: A | B }
function negativePropTest(x: ClassWithUnionProp) {
if ("a" in x.prop) {
let y: string = x.prop.b;
} else {
let z: string = x.prop.a;
}
}
class NegativeClassTest {
protected prop: A | B;
inThis() {
if ("a" in this.prop) {
let z: number = this.prop.b;
} else {
let y: string = this.prop.a;
}
}
}
class UnreachableCodeDetection {
a: string;
inThis() {
if ("a" in this) {
} else {
let y = this.a;
}
}
}
//// [inKeywordTypeguard.js]
var A = /** @class */ (function () {
function A() {
}
return A;
}());
var B = /** @class */ (function () {
function B() {
}
return B;
}());
function negativeClassesTest(x) {
if ("a" in x) {
x.b = "1";
}
else {
x.a = "1";
}
}
function positiveClassesTest(x) {
if ("a" in x) {
x.b = "1";
}
else {
x.a = "1";
}
}
var AWithOptionalProp = /** @class */ (function () {
function AWithOptionalProp() {
}
return AWithOptionalProp;
}());
var BWithOptionalProp = /** @class */ (function () {
function BWithOptionalProp() {
}
return BWithOptionalProp;
}());
function positiveTestClassesWithOptionalProperties(x) {
if ("a" in x) {
x.a = "1";
}
else {
x.b = "1";
}
}
var AWithMethod = /** @class */ (function () {
function AWithMethod() {
}
AWithMethod.prototype.a = function () { return ""; };
return AWithMethod;
}());
var BWithMethod = /** @class */ (function () {
function BWithMethod() {
}
BWithMethod.prototype.b = function () { return ""; };
return BWithMethod;
}());
function negativeTestClassesWithMembers(x) {
if ("a" in x) {
x.a();
x.b();
}
else {
}
}
function negativeTestClassesWithMemberMissingInBothClasses(x) {
if ("c" in x) {
x.a();
x.b();
}
else {
x.a();
x.b();
}
}
var C = /** @class */ (function () {
function C() {
}
return C;
}());
var D = /** @class */ (function () {
function D() {
}
return D;
}());
function negativeMultipleClassesTest(x) {
if ("a" in x) {
x.b = "1";
}
else {
x.a = "1";
}
}
var ClassWithUnionProp = /** @class */ (function () {
function ClassWithUnionProp() {
}
return ClassWithUnionProp;
}());
function negativePropTest(x) {
if ("a" in x.prop) {
var y = x.prop.b;
}
else {
var z = x.prop.a;
}
}
var NegativeClassTest = /** @class */ (function () {
function NegativeClassTest() {
}
NegativeClassTest.prototype.inThis = function () {
if ("a" in this.prop) {
var z = this.prop.b;
}
else {
var y = this.prop.a;
}
};
return NegativeClassTest;
}());
var UnreachableCodeDetection = /** @class */ (function () {
function UnreachableCodeDetection() {
}
UnreachableCodeDetection.prototype.inThis = function () {
if ("a" in this) {
}
else {
var y = this.a;
}
};
return UnreachableCodeDetection;
}());

View file

@ -0,0 +1,241 @@
=== tests/cases/compiler/inKeywordTypeguard.ts ===
class A { a: string; }
>A : Symbol(A, Decl(inKeywordTypeguard.ts, 0, 0))
>a : Symbol(A.a, Decl(inKeywordTypeguard.ts, 0, 9))
class B { b: string; }
>B : Symbol(B, Decl(inKeywordTypeguard.ts, 0, 22))
>b : Symbol(B.b, Decl(inKeywordTypeguard.ts, 1, 9))
function negativeClassesTest(x: A | B) {
>negativeClassesTest : Symbol(negativeClassesTest, Decl(inKeywordTypeguard.ts, 1, 22))
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 3, 29))
>A : Symbol(A, Decl(inKeywordTypeguard.ts, 0, 0))
>B : Symbol(B, Decl(inKeywordTypeguard.ts, 0, 22))
if ("a" in x) {
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 3, 29))
x.b = "1";
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 3, 29))
} else {
x.a = "1";
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 3, 29))
}
}
function positiveClassesTest(x: A | B) {
>positiveClassesTest : Symbol(positiveClassesTest, Decl(inKeywordTypeguard.ts, 9, 1))
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 11, 29))
>A : Symbol(A, Decl(inKeywordTypeguard.ts, 0, 0))
>B : Symbol(B, Decl(inKeywordTypeguard.ts, 0, 22))
if ("a" in x) {
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 11, 29))
x.b = "1";
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 11, 29))
} else {
x.a = "1";
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 11, 29))
}
}
class AWithOptionalProp { a?: string; }
>AWithOptionalProp : Symbol(AWithOptionalProp, Decl(inKeywordTypeguard.ts, 17, 1))
>a : Symbol(AWithOptionalProp.a, Decl(inKeywordTypeguard.ts, 19, 25))
class BWithOptionalProp { b?: string; }
>BWithOptionalProp : Symbol(BWithOptionalProp, Decl(inKeywordTypeguard.ts, 19, 39))
>b : Symbol(BWithOptionalProp.b, Decl(inKeywordTypeguard.ts, 20, 25))
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
>positiveTestClassesWithOptionalProperties : Symbol(positiveTestClassesWithOptionalProperties, Decl(inKeywordTypeguard.ts, 20, 39))
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 22, 51))
>AWithOptionalProp : Symbol(AWithOptionalProp, Decl(inKeywordTypeguard.ts, 17, 1))
>BWithOptionalProp : Symbol(BWithOptionalProp, Decl(inKeywordTypeguard.ts, 19, 39))
if ("a" in x) {
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 22, 51))
x.a = "1";
>x.a : Symbol(AWithOptionalProp.a, Decl(inKeywordTypeguard.ts, 19, 25))
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 22, 51))
>a : Symbol(AWithOptionalProp.a, Decl(inKeywordTypeguard.ts, 19, 25))
} else {
x.b = "1";
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 22, 51))
}
}
class AWithMethod {
>AWithMethod : Symbol(AWithMethod, Decl(inKeywordTypeguard.ts, 28, 1))
a(): string { return ""; }
>a : Symbol(AWithMethod.a, Decl(inKeywordTypeguard.ts, 30, 19))
}
class BWithMethod {
>BWithMethod : Symbol(BWithMethod, Decl(inKeywordTypeguard.ts, 32, 1))
b(): string { return ""; }
>b : Symbol(BWithMethod.b, Decl(inKeywordTypeguard.ts, 34, 19))
}
function negativeTestClassesWithMembers(x: AWithMethod | BWithMethod) {
>negativeTestClassesWithMembers : Symbol(negativeTestClassesWithMembers, Decl(inKeywordTypeguard.ts, 36, 1))
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 38, 40))
>AWithMethod : Symbol(AWithMethod, Decl(inKeywordTypeguard.ts, 28, 1))
>BWithMethod : Symbol(BWithMethod, Decl(inKeywordTypeguard.ts, 32, 1))
if ("a" in x) {
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 38, 40))
x.a();
>x.a : Symbol(AWithMethod.a, Decl(inKeywordTypeguard.ts, 30, 19))
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 38, 40))
>a : Symbol(AWithMethod.a, Decl(inKeywordTypeguard.ts, 30, 19))
x.b();
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 38, 40))
} else {
}
}
function negativeTestClassesWithMemberMissingInBothClasses(x: AWithMethod | BWithMethod) {
>negativeTestClassesWithMemberMissingInBothClasses : Symbol(negativeTestClassesWithMemberMissingInBothClasses, Decl(inKeywordTypeguard.ts, 44, 1))
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 46, 59))
>AWithMethod : Symbol(AWithMethod, Decl(inKeywordTypeguard.ts, 28, 1))
>BWithMethod : Symbol(BWithMethod, Decl(inKeywordTypeguard.ts, 32, 1))
if ("c" in x) {
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 46, 59))
x.a();
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 46, 59))
x.b();
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 46, 59))
} else {
x.a();
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 46, 59))
x.b();
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 46, 59))
}
}
class C { a: string; }
>C : Symbol(C, Decl(inKeywordTypeguard.ts, 54, 1))
>a : Symbol(C.a, Decl(inKeywordTypeguard.ts, 56, 9))
class D { a: string; }
>D : Symbol(D, Decl(inKeywordTypeguard.ts, 56, 22))
>a : Symbol(D.a, Decl(inKeywordTypeguard.ts, 57, 9))
function negativeMultipleClassesTest(x: A | B | C | D) {
>negativeMultipleClassesTest : Symbol(negativeMultipleClassesTest, Decl(inKeywordTypeguard.ts, 57, 22))
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 59, 37))
>A : Symbol(A, Decl(inKeywordTypeguard.ts, 0, 0))
>B : Symbol(B, Decl(inKeywordTypeguard.ts, 0, 22))
>C : Symbol(C, Decl(inKeywordTypeguard.ts, 54, 1))
>D : Symbol(D, Decl(inKeywordTypeguard.ts, 56, 22))
if ("a" in x) {
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 59, 37))
x.b = "1";
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 59, 37))
} else {
x.a = "1";
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 59, 37))
}
}
class ClassWithUnionProp { prop: A | B }
>ClassWithUnionProp : Symbol(ClassWithUnionProp, Decl(inKeywordTypeguard.ts, 65, 1))
>prop : Symbol(ClassWithUnionProp.prop, Decl(inKeywordTypeguard.ts, 67, 26))
>A : Symbol(A, Decl(inKeywordTypeguard.ts, 0, 0))
>B : Symbol(B, Decl(inKeywordTypeguard.ts, 0, 22))
function negativePropTest(x: ClassWithUnionProp) {
>negativePropTest : Symbol(negativePropTest, Decl(inKeywordTypeguard.ts, 67, 40))
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 69, 26))
>ClassWithUnionProp : Symbol(ClassWithUnionProp, Decl(inKeywordTypeguard.ts, 65, 1))
if ("a" in x.prop) {
>x.prop : Symbol(ClassWithUnionProp.prop, Decl(inKeywordTypeguard.ts, 67, 26))
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 69, 26))
>prop : Symbol(ClassWithUnionProp.prop, Decl(inKeywordTypeguard.ts, 67, 26))
let y: string = x.prop.b;
>y : Symbol(y, Decl(inKeywordTypeguard.ts, 71, 11))
>x.prop : Symbol(ClassWithUnionProp.prop, Decl(inKeywordTypeguard.ts, 67, 26))
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 69, 26))
>prop : Symbol(ClassWithUnionProp.prop, Decl(inKeywordTypeguard.ts, 67, 26))
} else {
let z: string = x.prop.a;
>z : Symbol(z, Decl(inKeywordTypeguard.ts, 73, 11))
>x.prop : Symbol(ClassWithUnionProp.prop, Decl(inKeywordTypeguard.ts, 67, 26))
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 69, 26))
>prop : Symbol(ClassWithUnionProp.prop, Decl(inKeywordTypeguard.ts, 67, 26))
}
}
class NegativeClassTest {
>NegativeClassTest : Symbol(NegativeClassTest, Decl(inKeywordTypeguard.ts, 75, 1))
protected prop: A | B;
>prop : Symbol(NegativeClassTest.prop, Decl(inKeywordTypeguard.ts, 77, 25))
>A : Symbol(A, Decl(inKeywordTypeguard.ts, 0, 0))
>B : Symbol(B, Decl(inKeywordTypeguard.ts, 0, 22))
inThis() {
>inThis : Symbol(NegativeClassTest.inThis, Decl(inKeywordTypeguard.ts, 78, 26))
if ("a" in this.prop) {
>this.prop : Symbol(NegativeClassTest.prop, Decl(inKeywordTypeguard.ts, 77, 25))
>this : Symbol(NegativeClassTest, Decl(inKeywordTypeguard.ts, 75, 1))
>prop : Symbol(NegativeClassTest.prop, Decl(inKeywordTypeguard.ts, 77, 25))
let z: number = this.prop.b;
>z : Symbol(z, Decl(inKeywordTypeguard.ts, 81, 15))
>this.prop : Symbol(NegativeClassTest.prop, Decl(inKeywordTypeguard.ts, 77, 25))
>this : Symbol(NegativeClassTest, Decl(inKeywordTypeguard.ts, 75, 1))
>prop : Symbol(NegativeClassTest.prop, Decl(inKeywordTypeguard.ts, 77, 25))
} else {
let y: string = this.prop.a;
>y : Symbol(y, Decl(inKeywordTypeguard.ts, 83, 15))
>this.prop : Symbol(NegativeClassTest.prop, Decl(inKeywordTypeguard.ts, 77, 25))
>this : Symbol(NegativeClassTest, Decl(inKeywordTypeguard.ts, 75, 1))
>prop : Symbol(NegativeClassTest.prop, Decl(inKeywordTypeguard.ts, 77, 25))
}
}
}
class UnreachableCodeDetection {
>UnreachableCodeDetection : Symbol(UnreachableCodeDetection, Decl(inKeywordTypeguard.ts, 86, 1))
a: string;
>a : Symbol(UnreachableCodeDetection.a, Decl(inKeywordTypeguard.ts, 88, 32))
inThis() {
>inThis : Symbol(UnreachableCodeDetection.inThis, Decl(inKeywordTypeguard.ts, 89, 14))
if ("a" in this) {
>this : Symbol(UnreachableCodeDetection, Decl(inKeywordTypeguard.ts, 86, 1))
} else {
let y = this.a;
>y : Symbol(y, Decl(inKeywordTypeguard.ts, 93, 15))
}
}
}

View file

@ -0,0 +1,318 @@
=== tests/cases/compiler/inKeywordTypeguard.ts ===
class A { a: string; }
>A : A
>a : string
class B { b: string; }
>B : B
>b : string
function negativeClassesTest(x: A | B) {
>negativeClassesTest : (x: A | B) => void
>x : A | B
>A : A
>B : B
if ("a" in x) {
>"a" in x : boolean
>"a" : "a"
>x : A | B
x.b = "1";
>x.b = "1" : "1"
>x.b : any
>x : A
>b : any
>"1" : "1"
} else {
x.a = "1";
>x.a = "1" : "1"
>x.a : any
>x : B
>a : any
>"1" : "1"
}
}
function positiveClassesTest(x: A | B) {
>positiveClassesTest : (x: A | B) => void
>x : A | B
>A : A
>B : B
if ("a" in x) {
>"a" in x : boolean
>"a" : "a"
>x : A | B
x.b = "1";
>x.b = "1" : "1"
>x.b : any
>x : A
>b : any
>"1" : "1"
} else {
x.a = "1";
>x.a = "1" : "1"
>x.a : any
>x : B
>a : any
>"1" : "1"
}
}
class AWithOptionalProp { a?: string; }
>AWithOptionalProp : AWithOptionalProp
>a : string
class BWithOptionalProp { b?: string; }
>BWithOptionalProp : BWithOptionalProp
>b : string
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
>positiveTestClassesWithOptionalProperties : (x: AWithOptionalProp | BWithOptionalProp) => void
>x : AWithOptionalProp | BWithOptionalProp
>AWithOptionalProp : AWithOptionalProp
>BWithOptionalProp : BWithOptionalProp
if ("a" in x) {
>"a" in x : boolean
>"a" : "a"
>x : AWithOptionalProp | BWithOptionalProp
x.a = "1";
>x.a = "1" : "1"
>x.a : string
>x : AWithOptionalProp
>a : string
>"1" : "1"
} else {
x.b = "1";
>x.b = "1" : "1"
>x.b : any
>x : AWithOptionalProp | BWithOptionalProp
>b : any
>"1" : "1"
}
}
class AWithMethod {
>AWithMethod : AWithMethod
a(): string { return ""; }
>a : () => string
>"" : ""
}
class BWithMethod {
>BWithMethod : BWithMethod
b(): string { return ""; }
>b : () => string
>"" : ""
}
function negativeTestClassesWithMembers(x: AWithMethod | BWithMethod) {
>negativeTestClassesWithMembers : (x: AWithMethod | BWithMethod) => void
>x : AWithMethod | BWithMethod
>AWithMethod : AWithMethod
>BWithMethod : BWithMethod
if ("a" in x) {
>"a" in x : boolean
>"a" : "a"
>x : AWithMethod | BWithMethod
x.a();
>x.a() : string
>x.a : () => string
>x : AWithMethod
>a : () => string
x.b();
>x.b() : any
>x.b : any
>x : AWithMethod
>b : any
} else {
}
}
function negativeTestClassesWithMemberMissingInBothClasses(x: AWithMethod | BWithMethod) {
>negativeTestClassesWithMemberMissingInBothClasses : (x: AWithMethod | BWithMethod) => void
>x : AWithMethod | BWithMethod
>AWithMethod : AWithMethod
>BWithMethod : BWithMethod
if ("c" in x) {
>"c" in x : boolean
>"c" : "c"
>x : AWithMethod | BWithMethod
x.a();
>x.a() : any
>x.a : any
>x : never
>a : any
x.b();
>x.b() : any
>x.b : any
>x : never
>b : any
} else {
x.a();
>x.a() : any
>x.a : any
>x : AWithMethod | BWithMethod
>a : any
x.b();
>x.b() : any
>x.b : any
>x : AWithMethod | BWithMethod
>b : any
}
}
class C { a: string; }
>C : C
>a : string
class D { a: string; }
>D : D
>a : string
function negativeMultipleClassesTest(x: A | B | C | D) {
>negativeMultipleClassesTest : (x: A | B | C | D) => void
>x : A | B | C | D
>A : A
>B : B
>C : C
>D : D
if ("a" in x) {
>"a" in x : boolean
>"a" : "a"
>x : A | B | C | D
x.b = "1";
>x.b = "1" : "1"
>x.b : any
>x : A | C | D
>b : any
>"1" : "1"
} else {
x.a = "1";
>x.a = "1" : "1"
>x.a : any
>x : B
>a : any
>"1" : "1"
}
}
class ClassWithUnionProp { prop: A | B }
>ClassWithUnionProp : ClassWithUnionProp
>prop : A | B
>A : A
>B : B
function negativePropTest(x: ClassWithUnionProp) {
>negativePropTest : (x: ClassWithUnionProp) => void
>x : ClassWithUnionProp
>ClassWithUnionProp : ClassWithUnionProp
if ("a" in x.prop) {
>"a" in x.prop : boolean
>"a" : "a"
>x.prop : A | B
>x : ClassWithUnionProp
>prop : A | B
let y: string = x.prop.b;
>y : string
>x.prop.b : any
>x.prop : A
>x : ClassWithUnionProp
>prop : A
>b : any
} else {
let z: string = x.prop.a;
>z : string
>x.prop.a : any
>x.prop : B
>x : ClassWithUnionProp
>prop : B
>a : any
}
}
class NegativeClassTest {
>NegativeClassTest : NegativeClassTest
protected prop: A | B;
>prop : A | B
>A : A
>B : B
inThis() {
>inThis : () => void
if ("a" in this.prop) {
>"a" in this.prop : boolean
>"a" : "a"
>this.prop : A | B
>this : this
>prop : A | B
let z: number = this.prop.b;
>z : number
>this.prop.b : any
>this.prop : A
>this : this
>prop : A
>b : any
} else {
let y: string = this.prop.a;
>y : string
>this.prop.a : any
>this.prop : B
>this : this
>prop : B
>a : any
}
}
}
class UnreachableCodeDetection {
>UnreachableCodeDetection : UnreachableCodeDetection
a: string;
>a : string
inThis() {
>inThis : () => void
if ("a" in this) {
>"a" in this : boolean
>"a" : "a"
>this : this
} else {
let y = this.a;
>y : any
>this.a : any
>this : never
>a : any
}
}
}

View file

@ -0,0 +1,218 @@
//// [typeGuardOfFromPropNameInUnionType.ts]
class A { a: string; }
class B { b: number; }
class C { b: Object; }
class D { a: Date; }
function namedClasses(x: A | B) {
if ("a" in x) {
x.a = "1";
} else {
x.b = 1;
}
}
function multipleClasses(x: A | B | C | D) {
if ("a" in x) {
let y: string | Date = x.a;
} else {
let z: number | Object = x.b;
}
}
function anonymousClasses(x: { a: string; } | { b: number; }) {
if ("a" in x) {
let y: string = x.a;
} else {
let z: number = x.b;
}
}
class AWithOptionalProp { a?: string; }
class BWithOptionalProp { b?: string; }
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
if ("a" in x) {
x.a = "1";
} else {
const y: string = x instanceof AWithOptionalProp
? x.a
: x.b
}
}
function inParenthesizedExpression(x: A | B) {
if ("a" in (x)) {
let y: string = x.a;
} else {
let z: number = x.b;
}
}
class ClassWithUnionProp { prop: A | B; }
function inProperty(x: ClassWithUnionProp) {
if ("a" in x.prop) {
let y: string = x.prop.a;
} else {
let z: number = x.prop.b;
}
}
class NestedClassWithProp { outer: ClassWithUnionProp; }
function innestedProperty(x: NestedClassWithProp) {
if ("a" in x.outer.prop) {
let y: string = x.outer.prop.a;
} else {
let z: number = x.outer.prop.b;
}
}
class InMemberOfClass {
protected prop: A | B;
inThis() {
if ("a" in this.prop) {
let y: string = this.prop.a;
} else {
let z: number = this.prop.b;
}
}
}
// added for completeness
class SelfAssert {
a: string;
inThis() {
if ("a" in this) {
let y: string = this.a;
} else {
}
}
}
//// [typeGuardOfFromPropNameInUnionType.js]
var A = /** @class */ (function () {
function A() {
}
return A;
}());
var B = /** @class */ (function () {
function B() {
}
return B;
}());
var C = /** @class */ (function () {
function C() {
}
return C;
}());
var D = /** @class */ (function () {
function D() {
}
return D;
}());
function namedClasses(x) {
if ("a" in x) {
x.a = "1";
}
else {
x.b = 1;
}
}
function multipleClasses(x) {
if ("a" in x) {
var y = x.a;
}
else {
var z = x.b;
}
}
function anonymousClasses(x) {
if ("a" in x) {
var y = x.a;
}
else {
var z = x.b;
}
}
var AWithOptionalProp = /** @class */ (function () {
function AWithOptionalProp() {
}
return AWithOptionalProp;
}());
var BWithOptionalProp = /** @class */ (function () {
function BWithOptionalProp() {
}
return BWithOptionalProp;
}());
function positiveTestClassesWithOptionalProperties(x) {
if ("a" in x) {
x.a = "1";
}
else {
var y = x instanceof AWithOptionalProp
? x.a
: x.b;
}
}
function inParenthesizedExpression(x) {
if ("a" in (x)) {
var y = x.a;
}
else {
var z = x.b;
}
}
var ClassWithUnionProp = /** @class */ (function () {
function ClassWithUnionProp() {
}
return ClassWithUnionProp;
}());
function inProperty(x) {
if ("a" in x.prop) {
var y = x.prop.a;
}
else {
var z = x.prop.b;
}
}
var NestedClassWithProp = /** @class */ (function () {
function NestedClassWithProp() {
}
return NestedClassWithProp;
}());
function innestedProperty(x) {
if ("a" in x.outer.prop) {
var y = x.outer.prop.a;
}
else {
var z = x.outer.prop.b;
}
}
var InMemberOfClass = /** @class */ (function () {
function InMemberOfClass() {
}
InMemberOfClass.prototype.inThis = function () {
if ("a" in this.prop) {
var y = this.prop.a;
}
else {
var z = this.prop.b;
}
};
return InMemberOfClass;
}());
// added for completeness
var SelfAssert = /** @class */ (function () {
function SelfAssert() {
}
SelfAssert.prototype.inThis = function () {
if ("a" in this) {
var y = this.a;
}
else {
}
};
return SelfAssert;
}());

View file

@ -0,0 +1,291 @@
=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFromPropNameInUnionType.ts ===
class A { a: string; }
>A : Symbol(A, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 0))
>a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
class B { b: number; }
>B : Symbol(B, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 22))
>b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
class C { b: Object; }
>C : Symbol(C, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 22))
>b : Symbol(C.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 2, 9))
>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
class D { a: Date; }
>D : Symbol(D, Decl(typeGuardOfFromPropNameInUnionType.ts, 2, 22))
>a : Symbol(D.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 3, 9))
>Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
function namedClasses(x: A | B) {
>namedClasses : Symbol(namedClasses, Decl(typeGuardOfFromPropNameInUnionType.ts, 3, 20))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 5, 22))
>A : Symbol(A, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 0))
>B : Symbol(B, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 22))
if ("a" in x) {
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 5, 22))
x.a = "1";
>x.a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 5, 22))
>a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
} else {
x.b = 1;
>x.b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 5, 22))
>b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
}
}
function multipleClasses(x: A | B | C | D) {
>multipleClasses : Symbol(multipleClasses, Decl(typeGuardOfFromPropNameInUnionType.ts, 11, 1))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 13, 25))
>A : Symbol(A, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 0))
>B : Symbol(B, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 22))
>C : Symbol(C, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 22))
>D : Symbol(D, Decl(typeGuardOfFromPropNameInUnionType.ts, 2, 22))
if ("a" in x) {
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 13, 25))
let y: string | Date = x.a;
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 15, 11))
>Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>x.a : Symbol(a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9), Decl(typeGuardOfFromPropNameInUnionType.ts, 3, 9))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 13, 25))
>a : Symbol(a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9), Decl(typeGuardOfFromPropNameInUnionType.ts, 3, 9))
} else {
let z: number | Object = x.b;
>z : Symbol(z, Decl(typeGuardOfFromPropNameInUnionType.ts, 17, 11))
>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>x.b : Symbol(b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9), Decl(typeGuardOfFromPropNameInUnionType.ts, 2, 9))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 13, 25))
>b : Symbol(b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9), Decl(typeGuardOfFromPropNameInUnionType.ts, 2, 9))
}
}
function anonymousClasses(x: { a: string; } | { b: number; }) {
>anonymousClasses : Symbol(anonymousClasses, Decl(typeGuardOfFromPropNameInUnionType.ts, 19, 1))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 26))
>a : Symbol(a, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 30))
>b : Symbol(b, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 47))
if ("a" in x) {
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 26))
let y: string = x.a;
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 23, 11))
>x.a : Symbol(a, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 30))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 26))
>a : Symbol(a, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 30))
} else {
let z: number = x.b;
>z : Symbol(z, Decl(typeGuardOfFromPropNameInUnionType.ts, 25, 11))
>x.b : Symbol(b, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 47))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 26))
>b : Symbol(b, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 47))
}
}
class AWithOptionalProp { a?: string; }
>AWithOptionalProp : Symbol(AWithOptionalProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 27, 1))
>a : Symbol(AWithOptionalProp.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 29, 25))
class BWithOptionalProp { b?: string; }
>BWithOptionalProp : Symbol(BWithOptionalProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 29, 39))
>b : Symbol(BWithOptionalProp.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 30, 25))
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
>positiveTestClassesWithOptionalProperties : Symbol(positiveTestClassesWithOptionalProperties, Decl(typeGuardOfFromPropNameInUnionType.ts, 30, 39))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 32, 51))
>AWithOptionalProp : Symbol(AWithOptionalProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 27, 1))
>BWithOptionalProp : Symbol(BWithOptionalProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 29, 39))
if ("a" in x) {
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 32, 51))
x.a = "1";
>x.a : Symbol(AWithOptionalProp.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 29, 25))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 32, 51))
>a : Symbol(AWithOptionalProp.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 29, 25))
} else {
const y: string = x instanceof AWithOptionalProp
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 36, 13))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 32, 51))
>AWithOptionalProp : Symbol(AWithOptionalProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 27, 1))
? x.a
>x.a : Symbol(AWithOptionalProp.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 29, 25))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 32, 51))
>a : Symbol(AWithOptionalProp.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 29, 25))
: x.b
>x.b : Symbol(BWithOptionalProp.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 30, 25))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 32, 51))
>b : Symbol(BWithOptionalProp.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 30, 25))
}
}
function inParenthesizedExpression(x: A | B) {
>inParenthesizedExpression : Symbol(inParenthesizedExpression, Decl(typeGuardOfFromPropNameInUnionType.ts, 40, 1))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 42, 35))
>A : Symbol(A, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 0))
>B : Symbol(B, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 22))
if ("a" in (x)) {
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 42, 35))
let y: string = x.a;
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 44, 11))
>x.a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 42, 35))
>a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
} else {
let z: number = x.b;
>z : Symbol(z, Decl(typeGuardOfFromPropNameInUnionType.ts, 46, 11))
>x.b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 42, 35))
>b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
}
}
class ClassWithUnionProp { prop: A | B; }
>ClassWithUnionProp : Symbol(ClassWithUnionProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 48, 1))
>prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
>A : Symbol(A, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 0))
>B : Symbol(B, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 22))
function inProperty(x: ClassWithUnionProp) {
>inProperty : Symbol(inProperty, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 41))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 52, 20))
>ClassWithUnionProp : Symbol(ClassWithUnionProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 48, 1))
if ("a" in x.prop) {
>x.prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 52, 20))
>prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
let y: string = x.prop.a;
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 54, 11))
>x.prop.a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
>x.prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 52, 20))
>prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
>a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
} else {
let z: number = x.prop.b;
>z : Symbol(z, Decl(typeGuardOfFromPropNameInUnionType.ts, 56, 11))
>x.prop.b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
>x.prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 52, 20))
>prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
>b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
}
}
class NestedClassWithProp { outer: ClassWithUnionProp; }
>NestedClassWithProp : Symbol(NestedClassWithProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 58, 1))
>outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 60, 27))
>ClassWithUnionProp : Symbol(ClassWithUnionProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 48, 1))
function innestedProperty(x: NestedClassWithProp) {
>innestedProperty : Symbol(innestedProperty, Decl(typeGuardOfFromPropNameInUnionType.ts, 60, 56))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 62, 26))
>NestedClassWithProp : Symbol(NestedClassWithProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 58, 1))
if ("a" in x.outer.prop) {
>x.outer.prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
>x.outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 60, 27))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 62, 26))
>outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 60, 27))
>prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
let y: string = x.outer.prop.a;
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 64, 11))
>x.outer.prop.a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
>x.outer.prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
>x.outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 60, 27))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 62, 26))
>outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 60, 27))
>prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
>a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
} else {
let z: number = x.outer.prop.b;
>z : Symbol(z, Decl(typeGuardOfFromPropNameInUnionType.ts, 66, 11))
>x.outer.prop.b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
>x.outer.prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
>x.outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 60, 27))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 62, 26))
>outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 60, 27))
>prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
>b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
}
}
class InMemberOfClass {
>InMemberOfClass : Symbol(InMemberOfClass, Decl(typeGuardOfFromPropNameInUnionType.ts, 68, 1))
protected prop: A | B;
>prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 70, 23))
>A : Symbol(A, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 0))
>B : Symbol(B, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 22))
inThis() {
>inThis : Symbol(InMemberOfClass.inThis, Decl(typeGuardOfFromPropNameInUnionType.ts, 71, 26))
if ("a" in this.prop) {
>this.prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 70, 23))
>this : Symbol(InMemberOfClass, Decl(typeGuardOfFromPropNameInUnionType.ts, 68, 1))
>prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 70, 23))
let y: string = this.prop.a;
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 74, 15))
>this.prop.a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
>this.prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 70, 23))
>this : Symbol(InMemberOfClass, Decl(typeGuardOfFromPropNameInUnionType.ts, 68, 1))
>prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 70, 23))
>a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
} else {
let z: number = this.prop.b;
>z : Symbol(z, Decl(typeGuardOfFromPropNameInUnionType.ts, 76, 15))
>this.prop.b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
>this.prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 70, 23))
>this : Symbol(InMemberOfClass, Decl(typeGuardOfFromPropNameInUnionType.ts, 68, 1))
>prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 70, 23))
>b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
}
}
}
// added for completeness
class SelfAssert {
>SelfAssert : Symbol(SelfAssert, Decl(typeGuardOfFromPropNameInUnionType.ts, 79, 1))
a: string;
>a : Symbol(SelfAssert.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 82, 18))
inThis() {
>inThis : Symbol(SelfAssert.inThis, Decl(typeGuardOfFromPropNameInUnionType.ts, 83, 14))
if ("a" in this) {
>this : Symbol(SelfAssert, Decl(typeGuardOfFromPropNameInUnionType.ts, 79, 1))
let y: string = this.a;
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 86, 15))
>this.a : Symbol(SelfAssert.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 82, 18))
>this : Symbol(SelfAssert, Decl(typeGuardOfFromPropNameInUnionType.ts, 79, 1))
>a : Symbol(SelfAssert.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 82, 18))
} else {
}
}
}

View file

@ -0,0 +1,318 @@
=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFromPropNameInUnionType.ts ===
class A { a: string; }
>A : A
>a : string
class B { b: number; }
>B : B
>b : number
class C { b: Object; }
>C : C
>b : Object
>Object : Object
class D { a: Date; }
>D : D
>a : Date
>Date : Date
function namedClasses(x: A | B) {
>namedClasses : (x: A | B) => void
>x : A | B
>A : A
>B : B
if ("a" in x) {
>"a" in x : boolean
>"a" : "a"
>x : A | B
x.a = "1";
>x.a = "1" : "1"
>x.a : string
>x : A
>a : string
>"1" : "1"
} else {
x.b = 1;
>x.b = 1 : 1
>x.b : number
>x : B
>b : number
>1 : 1
}
}
function multipleClasses(x: A | B | C | D) {
>multipleClasses : (x: A | B | C | D) => void
>x : A | B | C | D
>A : A
>B : B
>C : C
>D : D
if ("a" in x) {
>"a" in x : boolean
>"a" : "a"
>x : A | B | C | D
let y: string | Date = x.a;
>y : string | Date
>Date : Date
>x.a : string | Date
>x : A | D
>a : string | Date
} else {
let z: number | Object = x.b;
>z : number | Object
>Object : Object
>x.b : number | Object
>x : B | C
>b : number | Object
}
}
function anonymousClasses(x: { a: string; } | { b: number; }) {
>anonymousClasses : (x: { a: string; } | { b: number; }) => void
>x : { a: string; } | { b: number; }
>a : string
>b : number
if ("a" in x) {
>"a" in x : boolean
>"a" : "a"
>x : { a: string; } | { b: number; }
let y: string = x.a;
>y : string
>x.a : string
>x : { a: string; }
>a : string
} else {
let z: number = x.b;
>z : number
>x.b : number
>x : { b: number; }
>b : number
}
}
class AWithOptionalProp { a?: string; }
>AWithOptionalProp : AWithOptionalProp
>a : string
class BWithOptionalProp { b?: string; }
>BWithOptionalProp : BWithOptionalProp
>b : string
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
>positiveTestClassesWithOptionalProperties : (x: AWithOptionalProp | BWithOptionalProp) => void
>x : AWithOptionalProp | BWithOptionalProp
>AWithOptionalProp : AWithOptionalProp
>BWithOptionalProp : BWithOptionalProp
if ("a" in x) {
>"a" in x : boolean
>"a" : "a"
>x : AWithOptionalProp | BWithOptionalProp
x.a = "1";
>x.a = "1" : "1"
>x.a : string
>x : AWithOptionalProp
>a : string
>"1" : "1"
} else {
const y: string = x instanceof AWithOptionalProp
>y : string
>x instanceof AWithOptionalProp ? x.a : x.b : string
>x instanceof AWithOptionalProp : boolean
>x : AWithOptionalProp | BWithOptionalProp
>AWithOptionalProp : typeof AWithOptionalProp
? x.a
>x.a : string
>x : AWithOptionalProp
>a : string
: x.b
>x.b : string
>x : BWithOptionalProp
>b : string
}
}
function inParenthesizedExpression(x: A | B) {
>inParenthesizedExpression : (x: A | B) => void
>x : A | B
>A : A
>B : B
if ("a" in (x)) {
>"a" in (x) : boolean
>"a" : "a"
>(x) : A | B
>x : A | B
let y: string = x.a;
>y : string
>x.a : string
>x : A
>a : string
} else {
let z: number = x.b;
>z : number
>x.b : number
>x : B
>b : number
}
}
class ClassWithUnionProp { prop: A | B; }
>ClassWithUnionProp : ClassWithUnionProp
>prop : A | B
>A : A
>B : B
function inProperty(x: ClassWithUnionProp) {
>inProperty : (x: ClassWithUnionProp) => void
>x : ClassWithUnionProp
>ClassWithUnionProp : ClassWithUnionProp
if ("a" in x.prop) {
>"a" in x.prop : boolean
>"a" : "a"
>x.prop : A | B
>x : ClassWithUnionProp
>prop : A | B
let y: string = x.prop.a;
>y : string
>x.prop.a : string
>x.prop : A
>x : ClassWithUnionProp
>prop : A
>a : string
} else {
let z: number = x.prop.b;
>z : number
>x.prop.b : number
>x.prop : B
>x : ClassWithUnionProp
>prop : B
>b : number
}
}
class NestedClassWithProp { outer: ClassWithUnionProp; }
>NestedClassWithProp : NestedClassWithProp
>outer : ClassWithUnionProp
>ClassWithUnionProp : ClassWithUnionProp
function innestedProperty(x: NestedClassWithProp) {
>innestedProperty : (x: NestedClassWithProp) => void
>x : NestedClassWithProp
>NestedClassWithProp : NestedClassWithProp
if ("a" in x.outer.prop) {
>"a" in x.outer.prop : boolean
>"a" : "a"
>x.outer.prop : A | B
>x.outer : ClassWithUnionProp
>x : NestedClassWithProp
>outer : ClassWithUnionProp
>prop : A | B
let y: string = x.outer.prop.a;
>y : string
>x.outer.prop.a : string
>x.outer.prop : A
>x.outer : ClassWithUnionProp
>x : NestedClassWithProp
>outer : ClassWithUnionProp
>prop : A
>a : string
} else {
let z: number = x.outer.prop.b;
>z : number
>x.outer.prop.b : number
>x.outer.prop : B
>x.outer : ClassWithUnionProp
>x : NestedClassWithProp
>outer : ClassWithUnionProp
>prop : B
>b : number
}
}
class InMemberOfClass {
>InMemberOfClass : InMemberOfClass
protected prop: A | B;
>prop : A | B
>A : A
>B : B
inThis() {
>inThis : () => void
if ("a" in this.prop) {
>"a" in this.prop : boolean
>"a" : "a"
>this.prop : A | B
>this : this
>prop : A | B
let y: string = this.prop.a;
>y : string
>this.prop.a : string
>this.prop : A
>this : this
>prop : A
>a : string
} else {
let z: number = this.prop.b;
>z : number
>this.prop.b : number
>this.prop : B
>this : this
>prop : B
>b : number
}
}
}
// added for completeness
class SelfAssert {
>SelfAssert : SelfAssert
a: string;
>a : string
inThis() {
>inThis : () => void
if ("a" in this) {
>"a" in this : boolean
>"a" : "a"
>this : this
let y: string = this.a;
>y : string
>this.a : string
>this : this
>a : string
} else {
}
}
}

View file

@ -0,0 +1,9 @@
//// [typeInferenceTypePredicate.ts]
declare function f<T>(predicate: (x: {}) => x is T): T;
// 'res' should be of type 'number'.
const res = f((n): n is number => true);
//// [typeInferenceTypePredicate.js]
// 'res' should be of type 'number'.
var res = f(function (n) { return true; });

View file

@ -0,0 +1,17 @@
=== tests/cases/compiler/typeInferenceTypePredicate.ts ===
declare function f<T>(predicate: (x: {}) => x is T): T;
>f : Symbol(f, Decl(typeInferenceTypePredicate.ts, 0, 0))
>T : Symbol(T, Decl(typeInferenceTypePredicate.ts, 0, 19))
>predicate : Symbol(predicate, Decl(typeInferenceTypePredicate.ts, 0, 22))
>x : Symbol(x, Decl(typeInferenceTypePredicate.ts, 0, 34))
>x : Symbol(x, Decl(typeInferenceTypePredicate.ts, 0, 34))
>T : Symbol(T, Decl(typeInferenceTypePredicate.ts, 0, 19))
>T : Symbol(T, Decl(typeInferenceTypePredicate.ts, 0, 19))
// 'res' should be of type 'number'.
const res = f((n): n is number => true);
>res : Symbol(res, Decl(typeInferenceTypePredicate.ts, 2, 5))
>f : Symbol(f, Decl(typeInferenceTypePredicate.ts, 0, 0))
>n : Symbol(n, Decl(typeInferenceTypePredicate.ts, 2, 15))
>n : Symbol(n, Decl(typeInferenceTypePredicate.ts, 2, 15))

View file

@ -0,0 +1,20 @@
=== tests/cases/compiler/typeInferenceTypePredicate.ts ===
declare function f<T>(predicate: (x: {}) => x is T): T;
>f : <T>(predicate: (x: {}) => x is T) => T
>T : T
>predicate : (x: {}) => x is T
>x : {}
>x : any
>T : T
>T : T
// 'res' should be of type 'number'.
const res = f((n): n is number => true);
>res : number
>f((n): n is number => true) : number
>f : <T>(predicate: (x: {}) => x is T) => T
>(n): n is number => true : (n: {}) => n is number
>n : {}
>n : any
>true : true

View file

@ -0,0 +1,10 @@
//// [typeInferenceTypePredicate2.ts]
[true, true, false, null]
.filter((thing): thing is boolean => thing !== null)
.map(thing => thing.toString());
//// [typeInferenceTypePredicate2.js]
[true, true, false, null]
.filter(function (thing) { return thing !== null; })
.map(function (thing) { return thing.toString(); });

View file

@ -0,0 +1,18 @@
=== tests/cases/compiler/typeInferenceTypePredicate2.ts ===
[true, true, false, null]
>[true, true, false, null] .filter((thing): thing is boolean => thing !== null) .map : Symbol(Array.map, Decl(lib.d.ts, --, --))
>[true, true, false, null] .filter : Symbol(Array.filter, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
.filter((thing): thing is boolean => thing !== null)
>filter : Symbol(Array.filter, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>thing : Symbol(thing, Decl(typeInferenceTypePredicate2.ts, 1, 13))
>thing : Symbol(thing, Decl(typeInferenceTypePredicate2.ts, 1, 13))
>thing : Symbol(thing, Decl(typeInferenceTypePredicate2.ts, 1, 13))
.map(thing => thing.toString());
>map : Symbol(Array.map, Decl(lib.d.ts, --, --))
>thing : Symbol(thing, Decl(typeInferenceTypePredicate2.ts, 2, 9))
>thing.toString : Symbol(Object.toString, Decl(lib.d.ts, --, --))
>thing : Symbol(thing, Decl(typeInferenceTypePredicate2.ts, 2, 9))
>toString : Symbol(Object.toString, Decl(lib.d.ts, --, --))

View file

@ -0,0 +1,30 @@
=== tests/cases/compiler/typeInferenceTypePredicate2.ts ===
[true, true, false, null]
>[true, true, false, null] .filter((thing): thing is boolean => thing !== null) .map(thing => thing.toString()) : string[]
>[true, true, false, null] .filter((thing): thing is boolean => thing !== null) .map : <U>(callbackfn: (value: boolean, index: number, array: boolean[]) => U, thisArg?: any) => U[]
>[true, true, false, null] .filter((thing): thing is boolean => thing !== null) : boolean[]
>[true, true, false, null] .filter : { <S extends boolean>(callbackfn: (value: boolean, index: number, array: boolean[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: boolean, index: number, array: boolean[]) => any, thisArg?: any): boolean[]; }
>[true, true, false, null] : boolean[]
>true : true
>true : true
>false : false
>null : null
.filter((thing): thing is boolean => thing !== null)
>filter : { <S extends boolean>(callbackfn: (value: boolean, index: number, array: boolean[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: boolean, index: number, array: boolean[]) => any, thisArg?: any): boolean[]; }
>(thing): thing is boolean => thing !== null : (thing: boolean) => thing is boolean
>thing : boolean
>thing : any
>thing !== null : boolean
>thing : boolean
>null : null
.map(thing => thing.toString());
>map : <U>(callbackfn: (value: boolean, index: number, array: boolean[]) => U, thisArg?: any) => U[]
>thing => thing.toString() : (thing: boolean) => string
>thing : boolean
>thing.toString() : string
>thing.toString : () => string
>thing : boolean
>toString : () => string

View file

@ -0,0 +1,23 @@
//// [typePredicatesInUnion.ts]
interface A {
pred(x: {}): x is boolean;
}
interface B {
pred(x: {}): x is string;
}
type Or = A | B;
function f(o: Or, x: {}) {
if (o.pred(x)) {
x;
}
}
//// [typePredicatesInUnion.js]
function f(o, x) {
if (o.pred(x)) {
x;
}
}

View file

@ -0,0 +1,40 @@
=== tests/cases/compiler/typePredicatesInUnion.ts ===
interface A {
>A : Symbol(A, Decl(typePredicatesInUnion.ts, 0, 0))
pred(x: {}): x is boolean;
>pred : Symbol(A.pred, Decl(typePredicatesInUnion.ts, 0, 13))
>x : Symbol(x, Decl(typePredicatesInUnion.ts, 1, 9))
>x : Symbol(x, Decl(typePredicatesInUnion.ts, 1, 9))
}
interface B {
>B : Symbol(B, Decl(typePredicatesInUnion.ts, 2, 1))
pred(x: {}): x is string;
>pred : Symbol(B.pred, Decl(typePredicatesInUnion.ts, 3, 13))
>x : Symbol(x, Decl(typePredicatesInUnion.ts, 4, 9))
>x : Symbol(x, Decl(typePredicatesInUnion.ts, 4, 9))
}
type Or = A | B;
>Or : Symbol(Or, Decl(typePredicatesInUnion.ts, 5, 1))
>A : Symbol(A, Decl(typePredicatesInUnion.ts, 0, 0))
>B : Symbol(B, Decl(typePredicatesInUnion.ts, 2, 1))
function f(o: Or, x: {}) {
>f : Symbol(f, Decl(typePredicatesInUnion.ts, 7, 16))
>o : Symbol(o, Decl(typePredicatesInUnion.ts, 9, 11))
>Or : Symbol(Or, Decl(typePredicatesInUnion.ts, 5, 1))
>x : Symbol(x, Decl(typePredicatesInUnion.ts, 9, 17))
if (o.pred(x)) {
>o.pred : Symbol(pred, Decl(typePredicatesInUnion.ts, 0, 13), Decl(typePredicatesInUnion.ts, 3, 13))
>o : Symbol(o, Decl(typePredicatesInUnion.ts, 9, 11))
>pred : Symbol(pred, Decl(typePredicatesInUnion.ts, 0, 13), Decl(typePredicatesInUnion.ts, 3, 13))
>x : Symbol(x, Decl(typePredicatesInUnion.ts, 9, 17))
x;
>x : Symbol(x, Decl(typePredicatesInUnion.ts, 9, 17))
}
}

View file

@ -0,0 +1,41 @@
=== tests/cases/compiler/typePredicatesInUnion.ts ===
interface A {
>A : A
pred(x: {}): x is boolean;
>pred : (x: {}) => x is boolean
>x : {}
>x : any
}
interface B {
>B : B
pred(x: {}): x is string;
>pred : (x: {}) => x is string
>x : {}
>x : any
}
type Or = A | B;
>Or : Or
>A : A
>B : B
function f(o: Or, x: {}) {
>f : (o: Or, x: {}) => void
>o : Or
>Or : Or
>x : {}
if (o.pred(x)) {
>o.pred(x) : boolean
>o.pred : ((x: {}) => x is boolean) | ((x: {}) => x is string)
>o : Or
>pred : ((x: {}) => x is boolean) | ((x: {}) => x is string)
>x : {}
x;
>x : string | boolean
}
}

View file

@ -0,0 +1,11 @@
//// [typePredicatesInUnion2.ts]
declare function isString(x: any): x is string;
declare function isNumber(x: any): x is number;
declare function f(p: typeof isString | typeof isNumber): void;
f(isString);
f(isNumber);
//// [typePredicatesInUnion2.js]
f(isString);
f(isNumber);

View file

@ -0,0 +1,25 @@
=== tests/cases/compiler/typePredicatesInUnion2.ts ===
declare function isString(x: any): x is string;
>isString : Symbol(isString, Decl(typePredicatesInUnion2.ts, 0, 0))
>x : Symbol(x, Decl(typePredicatesInUnion2.ts, 0, 26))
>x : Symbol(x, Decl(typePredicatesInUnion2.ts, 0, 26))
declare function isNumber(x: any): x is number;
>isNumber : Symbol(isNumber, Decl(typePredicatesInUnion2.ts, 0, 47))
>x : Symbol(x, Decl(typePredicatesInUnion2.ts, 1, 26))
>x : Symbol(x, Decl(typePredicatesInUnion2.ts, 1, 26))
declare function f(p: typeof isString | typeof isNumber): void;
>f : Symbol(f, Decl(typePredicatesInUnion2.ts, 1, 47))
>p : Symbol(p, Decl(typePredicatesInUnion2.ts, 2, 19))
>isString : Symbol(isString, Decl(typePredicatesInUnion2.ts, 0, 0))
>isNumber : Symbol(isNumber, Decl(typePredicatesInUnion2.ts, 0, 47))
f(isString);
>f : Symbol(f, Decl(typePredicatesInUnion2.ts, 1, 47))
>isString : Symbol(isString, Decl(typePredicatesInUnion2.ts, 0, 0))
f(isNumber);
>f : Symbol(f, Decl(typePredicatesInUnion2.ts, 1, 47))
>isNumber : Symbol(isNumber, Decl(typePredicatesInUnion2.ts, 0, 47))

View file

@ -0,0 +1,27 @@
=== tests/cases/compiler/typePredicatesInUnion2.ts ===
declare function isString(x: any): x is string;
>isString : (x: any) => x is string
>x : any
>x : any
declare function isNumber(x: any): x is number;
>isNumber : (x: any) => x is number
>x : any
>x : any
declare function f(p: typeof isString | typeof isNumber): void;
>f : (p: ((x: any) => x is string) | ((x: any) => x is number)) => void
>p : ((x: any) => x is string) | ((x: any) => x is number)
>isString : (x: any) => x is string
>isNumber : (x: any) => x is number
f(isString);
>f(isString) : void
>f : (p: ((x: any) => x is string) | ((x: any) => x is number)) => void
>isString : (x: any) => x is string
f(isNumber);
>f(isNumber) : void
>f : (p: ((x: any) => x is string) | ((x: any) => x is number)) => void
>isNumber : (x: any) => x is number

View file

@ -0,0 +1,25 @@
//// [typePredicatesInUnion_noMatch.ts]
interface A {
pred(x: {}, y: {}): x is boolean;
}
interface B {
pred(x: {}, y: {}): y is string;
}
type Or = A | B;
function f(o: Or, x: {}, y: {}) {
if (o.pred(x, y)) {
x;
y;
}
}
//// [typePredicatesInUnion_noMatch.js]
function f(o, x, y) {
if (o.pred(x, y)) {
x;
y;
}
}

View file

@ -0,0 +1,47 @@
=== tests/cases/compiler/typePredicatesInUnion_noMatch.ts ===
interface A {
>A : Symbol(A, Decl(typePredicatesInUnion_noMatch.ts, 0, 0))
pred(x: {}, y: {}): x is boolean;
>pred : Symbol(A.pred, Decl(typePredicatesInUnion_noMatch.ts, 0, 13))
>x : Symbol(x, Decl(typePredicatesInUnion_noMatch.ts, 1, 9))
>y : Symbol(y, Decl(typePredicatesInUnion_noMatch.ts, 1, 15))
>x : Symbol(x, Decl(typePredicatesInUnion_noMatch.ts, 1, 9))
}
interface B {
>B : Symbol(B, Decl(typePredicatesInUnion_noMatch.ts, 2, 1))
pred(x: {}, y: {}): y is string;
>pred : Symbol(B.pred, Decl(typePredicatesInUnion_noMatch.ts, 3, 13))
>x : Symbol(x, Decl(typePredicatesInUnion_noMatch.ts, 4, 9))
>y : Symbol(y, Decl(typePredicatesInUnion_noMatch.ts, 4, 15))
>y : Symbol(y, Decl(typePredicatesInUnion_noMatch.ts, 4, 15))
}
type Or = A | B;
>Or : Symbol(Or, Decl(typePredicatesInUnion_noMatch.ts, 5, 1))
>A : Symbol(A, Decl(typePredicatesInUnion_noMatch.ts, 0, 0))
>B : Symbol(B, Decl(typePredicatesInUnion_noMatch.ts, 2, 1))
function f(o: Or, x: {}, y: {}) {
>f : Symbol(f, Decl(typePredicatesInUnion_noMatch.ts, 7, 16))
>o : Symbol(o, Decl(typePredicatesInUnion_noMatch.ts, 9, 11))
>Or : Symbol(Or, Decl(typePredicatesInUnion_noMatch.ts, 5, 1))
>x : Symbol(x, Decl(typePredicatesInUnion_noMatch.ts, 9, 17))
>y : Symbol(y, Decl(typePredicatesInUnion_noMatch.ts, 9, 24))
if (o.pred(x, y)) {
>o.pred : Symbol(pred, Decl(typePredicatesInUnion_noMatch.ts, 0, 13), Decl(typePredicatesInUnion_noMatch.ts, 3, 13))
>o : Symbol(o, Decl(typePredicatesInUnion_noMatch.ts, 9, 11))
>pred : Symbol(pred, Decl(typePredicatesInUnion_noMatch.ts, 0, 13), Decl(typePredicatesInUnion_noMatch.ts, 3, 13))
>x : Symbol(x, Decl(typePredicatesInUnion_noMatch.ts, 9, 17))
>y : Symbol(y, Decl(typePredicatesInUnion_noMatch.ts, 9, 24))
x;
>x : Symbol(x, Decl(typePredicatesInUnion_noMatch.ts, 9, 17))
y;
>y : Symbol(y, Decl(typePredicatesInUnion_noMatch.ts, 9, 24))
}
}

View file

@ -0,0 +1,48 @@
=== tests/cases/compiler/typePredicatesInUnion_noMatch.ts ===
interface A {
>A : A
pred(x: {}, y: {}): x is boolean;
>pred : (x: {}, y: {}) => x is boolean
>x : {}
>y : {}
>x : any
}
interface B {
>B : B
pred(x: {}, y: {}): y is string;
>pred : (x: {}, y: {}) => y is string
>x : {}
>y : {}
>y : any
}
type Or = A | B;
>Or : Or
>A : A
>B : B
function f(o: Or, x: {}, y: {}) {
>f : (o: Or, x: {}, y: {}) => void
>o : Or
>Or : Or
>x : {}
>y : {}
if (o.pred(x, y)) {
>o.pred(x, y) : boolean
>o.pred : ((x: {}, y: {}) => x is boolean) | ((x: {}, y: {}) => y is string)
>o : Or
>pred : ((x: {}, y: {}) => x is boolean) | ((x: {}, y: {}) => y is string)
>x : {}
>y : {}
x;
>x : {}
y;
>y : {}
}
}

View file

@ -20,6 +20,7 @@ const enum Enum1 {
N = E << 1,
O = E >> B,
P = E >> 1,
PQ = E ** 2,
Q = -D,
R = C & 5,
S = 5 & C,
@ -127,6 +128,7 @@ function foo(x: Enum1) {
case Enum1.N:
case Enum1.O:
case Enum1.P:
case Enum1.PQ:
case Enum1.Q:
case Enum1.R:
case Enum1.S:

View file

@ -0,0 +1,97 @@
class A { a: string; }
class B { b: string; }
function negativeClassesTest(x: A | B) {
if ("a" in x) {
x.b = "1";
} else {
x.a = "1";
}
}
function positiveClassesTest(x: A | B) {
if ("a" in x) {
x.b = "1";
} else {
x.a = "1";
}
}
class AWithOptionalProp { a?: string; }
class BWithOptionalProp { b?: string; }
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
if ("a" in x) {
x.a = "1";
} else {
x.b = "1";
}
}
class AWithMethod {
a(): string { return ""; }
}
class BWithMethod {
b(): string { return ""; }
}
function negativeTestClassesWithMembers(x: AWithMethod | BWithMethod) {
if ("a" in x) {
x.a();
x.b();
} else {
}
}
function negativeTestClassesWithMemberMissingInBothClasses(x: AWithMethod | BWithMethod) {
if ("c" in x) {
x.a();
x.b();
} else {
x.a();
x.b();
}
}
class C { a: string; }
class D { a: string; }
function negativeMultipleClassesTest(x: A | B | C | D) {
if ("a" in x) {
x.b = "1";
} else {
x.a = "1";
}
}
class ClassWithUnionProp { prop: A | B }
function negativePropTest(x: ClassWithUnionProp) {
if ("a" in x.prop) {
let y: string = x.prop.b;
} else {
let z: string = x.prop.a;
}
}
class NegativeClassTest {
protected prop: A | B;
inThis() {
if ("a" in this.prop) {
let z: number = this.prop.b;
} else {
let y: string = this.prop.a;
}
}
}
class UnreachableCodeDetection {
a: string;
inThis() {
if ("a" in this) {
} else {
let y = this.a;
}
}
}

View file

@ -0,0 +1,3 @@
declare function f<T>(predicate: (x: {}) => x is T): T;
// 'res' should be of type 'number'.
const res = f((n): n is number => true);

View file

@ -0,0 +1,3 @@
[true, true, false, null]
.filter((thing): thing is boolean => thing !== null)
.map(thing => thing.toString());

View file

@ -0,0 +1,14 @@
interface A {
pred(x: {}): x is boolean;
}
interface B {
pred(x: {}): x is string;
}
type Or = A | B;
function f(o: Or, x: {}) {
if (o.pred(x)) {
x;
}
}

View file

@ -0,0 +1,5 @@
declare function isString(x: any): x is string;
declare function isNumber(x: any): x is number;
declare function f(p: typeof isString | typeof isNumber): void;
f(isString);
f(isNumber);

View file

@ -0,0 +1,15 @@
interface A {
pred(x: {}, y: {}): x is boolean;
}
interface B {
pred(x: {}, y: {}): y is string;
}
type Or = A | B;
function f(o: Or, x: {}, y: {}) {
if (o.pred(x, y)) {
x;
y;
}
}

View file

@ -0,0 +1,91 @@
class A { a: string; }
class B { b: number; }
class C { b: Object; }
class D { a: Date; }
function namedClasses(x: A | B) {
if ("a" in x) {
x.a = "1";
} else {
x.b = 1;
}
}
function multipleClasses(x: A | B | C | D) {
if ("a" in x) {
let y: string | Date = x.a;
} else {
let z: number | Object = x.b;
}
}
function anonymousClasses(x: { a: string; } | { b: number; }) {
if ("a" in x) {
let y: string = x.a;
} else {
let z: number = x.b;
}
}
class AWithOptionalProp { a?: string; }
class BWithOptionalProp { b?: string; }
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
if ("a" in x) {
x.a = "1";
} else {
const y: string = x instanceof AWithOptionalProp
? x.a
: x.b
}
}
function inParenthesizedExpression(x: A | B) {
if ("a" in (x)) {
let y: string = x.a;
} else {
let z: number = x.b;
}
}
class ClassWithUnionProp { prop: A | B; }
function inProperty(x: ClassWithUnionProp) {
if ("a" in x.prop) {
let y: string = x.prop.a;
} else {
let z: number = x.prop.b;
}
}
class NestedClassWithProp { outer: ClassWithUnionProp; }
function innestedProperty(x: NestedClassWithProp) {
if ("a" in x.outer.prop) {
let y: string = x.outer.prop.a;
} else {
let z: number = x.outer.prop.b;
}
}
class InMemberOfClass {
protected prop: A | B;
inThis() {
if ("a" in this.prop) {
let y: string = this.prop.a;
} else {
let z: number = this.prop.b;
}
}
}
// added for completeness
class SelfAssert {
a: string;
inThis() {
if ("a" in this) {
let y: string = this.a;
} else {
}
}
}

View file

@ -296,6 +296,9 @@ define(function () {
isArray = ('isArray' in Array) ?
Array.isArray : function (value) { return Object.prototype.toString.call(value) === '[object Array]'; };
isArray = 'isArray' in Array
? function (value) { return Object.prototype.toString.call(value) === '[object Array]'; }
: Array.isArray;
function equalIC(a, b) {
return a != null && b != null && a.toLowerCase() === b.toLowerCase();
@ -966,7 +969,7 @@ define(function () {
// should not be replaced by a completely new object - just overwrite existing methods
MobileDetect._impl = impl;
MobileDetect.version = '1.3.3 2016-07-31';
return MobileDetect;

View file

@ -3,10 +3,18 @@
////class Base{
////}
////class C extends Base{
//// constructor() {[|
//// |]}
//// constructor() {}
////}
// TODO: GH#18445
verify.rangeAfterCodeFix(`
verify.codeFix({
description: "Add missing 'super()' call",
// TODO: GH#18445
newFileContent:
`class Base{
}
class C extends Base{
constructor() {\r
super();\r
`, /*includeWhitespace*/ true);
}
}`,
});

View file

@ -0,0 +1,44 @@
/// <reference path="fourslash.ts"/>
//// label: while (true) {
//// break /*1*/
//// continue /*2*/
//// testlabel: while (true) {
//// break /*3*/
//// continue /*4*/
//// break tes/*5*/
//// continue tes/*6*/
//// }
//// break /*7*/
//// break; /*8*/
////}
goTo.marker("1");
verify.completionListContains("label");
goTo.marker("2");
verify.completionListContains("label");
verify.not.completionListContains("testlabel");
goTo.marker("3");
verify.completionListContains("label");
verify.completionListContains("testlabel");
goTo.marker("4");
verify.completionListContains("label");
verify.completionListContains("testlabel");
goTo.marker("5");
verify.completionListContains("testlabel");
verify.completionListContains("label");
goTo.marker("6");
verify.completionListContains("testlabel");
verify.completionListContains("label");
goTo.marker("7");
verify.completionListContains("label");
verify.not.completionListContains("testlabel");
goTo.marker("8");
verify.not.completionListContains("label");

View file

@ -0,0 +1,22 @@
/// <reference path="fourslash.ts" />
// @moduleResolution: node
// @noLib: true
// @Filename: /node_modules/real/index.d.ts
// @Symlink: /node_modules/link/index.d.ts
////export const foo: number;
// @Filename: /a.ts
////import { foo } from "link";
// @Filename: /b.ts
////[|foo/**/;|]
// Uses "link" instead of "real" because `a` did.
goTo.file("/b.ts");
verify.importFixAtPosition([
`import { foo } from "link";
foo;`,
]);