mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into codefix_add_missing_new_operator
This commit is contained in:
commit
58b262e987
217 files changed
+10761
-6531
No files matched your search
@@ -16,7 +16,7 @@ Please fill in the *entire* template below.
|
||||
-->
|
||||
|
||||
<!-- Please try to reproduce the issue with `typescript@next`. It may have already been fixed. -->
|
||||
**TypeScript Version:** 3.1.0-dev.201xxxxx
|
||||
**TypeScript Version:** 3.2.0-dev.201xxxxx
|
||||
|
||||
<!-- Search terms you tried before logging this (so others can find this issue more easily) -->
|
||||
**Search Terms:**
|
||||
|
||||
@@ -20,6 +20,7 @@ branches:
|
||||
- release-2.8
|
||||
- release-2.9
|
||||
- release-3.0
|
||||
- release-3.1
|
||||
|
||||
install:
|
||||
- npm uninstall typescript --no-save
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
"name": "typescript",
|
||||
"author": "Microsoft Corp.",
|
||||
"homepage": "http://typescriptlang.org/",
|
||||
"version": "3.1.0",
|
||||
"version": "3.2.0",
|
||||
"license": "Apache-2.0",
|
||||
"description": "TypeScript is a language for application scale JavaScript development",
|
||||
"keywords": [
|
||||
|
||||
@@ -640,6 +640,7 @@ namespace ts {
|
||||
function bindChildrenWorker(node: Node): void {
|
||||
if (checkUnreachable(node)) {
|
||||
bindEachChild(node);
|
||||
bindJSDoc(node);
|
||||
return;
|
||||
}
|
||||
switch (node.kind) {
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace ts.BuilderState {
|
||||
function getReferencedFileFromImportedModuleSymbol(symbol: Symbol) {
|
||||
if (symbol.declarations && symbol.declarations[0]) {
|
||||
const declarationSourceFile = getSourceFileOfNode(symbol.declarations[0]);
|
||||
return declarationSourceFile && (declarationSourceFile.resolvedPath || declarationSourceFile.path);
|
||||
return declarationSourceFile && declarationSourceFile.resolvedPath;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+180
-57
@@ -77,6 +77,7 @@ namespace ts {
|
||||
const allowSyntheticDefaultImports = getAllowSyntheticDefaultImports(compilerOptions);
|
||||
const strictNullChecks = getStrictOptionValue(compilerOptions, "strictNullChecks");
|
||||
const strictFunctionTypes = getStrictOptionValue(compilerOptions, "strictFunctionTypes");
|
||||
const strictBindCallApply = getStrictOptionValue(compilerOptions, "strictBindCallApply");
|
||||
const strictPropertyInitialization = getStrictOptionValue(compilerOptions, "strictPropertyInitialization");
|
||||
const noImplicitAny = getStrictOptionValue(compilerOptions, "noImplicitAny");
|
||||
const noImplicitThis = getStrictOptionValue(compilerOptions, "noImplicitThis");
|
||||
@@ -476,6 +477,8 @@ namespace ts {
|
||||
|
||||
let globalObjectType: ObjectType;
|
||||
let globalFunctionType: ObjectType;
|
||||
let globalCallableFunctionType: ObjectType;
|
||||
let globalNewableFunctionType: ObjectType;
|
||||
let globalArrayType: GenericType;
|
||||
let globalReadonlyArrayType: GenericType;
|
||||
let globalStringType: ObjectType;
|
||||
@@ -495,6 +498,7 @@ namespace ts {
|
||||
let deferredGlobalESSymbolType: ObjectType;
|
||||
let deferredGlobalTypedPropertyDescriptorType: GenericType;
|
||||
let deferredGlobalPromiseType: GenericType;
|
||||
let deferredGlobalPromiseLikeType: GenericType;
|
||||
let deferredGlobalPromiseConstructorSymbol: Symbol | undefined;
|
||||
let deferredGlobalPromiseConstructorLikeType: ObjectType;
|
||||
let deferredGlobalIterableType: GenericType;
|
||||
@@ -1707,7 +1711,9 @@ namespace ts {
|
||||
function checkResolvedBlockScopedVariable(result: Symbol, errorLocation: Node): void {
|
||||
Debug.assert(!!(result.flags & SymbolFlags.BlockScopedVariable || result.flags & SymbolFlags.Class || result.flags & SymbolFlags.Enum));
|
||||
// Block-scoped variables cannot be used before their definition
|
||||
const declaration = forEach(result.declarations, d => isBlockOrCatchScoped(d) || isClassLike(d) || (d.kind === SyntaxKind.EnumDeclaration) ? d : undefined);
|
||||
const declaration = find(
|
||||
result.declarations,
|
||||
d => isBlockOrCatchScoped(d) || isClassLike(d) || (d.kind === SyntaxKind.EnumDeclaration) || isInJSFile(d) && !!getJSDocEnumTag(d));
|
||||
|
||||
if (declaration === undefined) return Debug.fail("Declaration to checkResolvedBlockScopedVariable is undefined");
|
||||
|
||||
@@ -2338,7 +2344,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getCommonJsExportEquals(exported: Symbol | undefined, moduleSymbol: Symbol): Symbol | undefined {
|
||||
if (!exported || moduleSymbol.exports!.size === 1) {
|
||||
if (!exported || exported === unknownSymbol || moduleSymbol.exports!.size === 1) {
|
||||
return exported;
|
||||
}
|
||||
const merged = cloneSymbol(exported);
|
||||
@@ -7390,8 +7396,12 @@ namespace ts {
|
||||
if (symbol && symbolIsValue(symbol)) {
|
||||
return symbol;
|
||||
}
|
||||
if (resolved === anyFunctionType || resolved.callSignatures.length || resolved.constructSignatures.length) {
|
||||
const symbol = getPropertyOfObjectType(globalFunctionType, name);
|
||||
const functionType = resolved === anyFunctionType ? globalFunctionType :
|
||||
resolved.callSignatures.length ? globalCallableFunctionType :
|
||||
resolved.constructSignatures.length ? globalNewableFunctionType :
|
||||
undefined;
|
||||
if (functionType) {
|
||||
const symbol = getPropertyOfObjectType(functionType, name);
|
||||
if (symbol) {
|
||||
return symbol;
|
||||
}
|
||||
@@ -8158,7 +8168,7 @@ namespace ts {
|
||||
const isJs = isInJSFile(node);
|
||||
const isJsImplicitAny = !noImplicitAny && isJs;
|
||||
if (!isJsImplicitAny && (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length)) {
|
||||
const missingAugmentsTag = isJs && node.parent.kind !== SyntaxKind.JSDocAugmentsTag;
|
||||
const missingAugmentsTag = isJs && isExpressionWithTypeArguments(node) && !isJSDocAugmentsTag(node.parent);
|
||||
const diag = minTypeArgumentCount === typeParameters.length
|
||||
? missingAugmentsTag
|
||||
? Diagnostics.Expected_0_type_arguments_provide_these_with_an_extends_tag
|
||||
@@ -8538,6 +8548,10 @@ namespace ts {
|
||||
return deferredGlobalPromiseType || (deferredGlobalPromiseType = getGlobalType("Promise" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType;
|
||||
}
|
||||
|
||||
function getGlobalPromiseLikeType(reportErrors: boolean) {
|
||||
return deferredGlobalPromiseLikeType || (deferredGlobalPromiseLikeType = getGlobalType("PromiseLike" as __String, /*arity*/ 1, reportErrors)) || emptyGenericType;
|
||||
}
|
||||
|
||||
function getGlobalPromiseConstructorSymbol(reportErrors: boolean): Symbol | undefined {
|
||||
return deferredGlobalPromiseConstructorSymbol || (deferredGlobalPromiseConstructorSymbol = getGlobalValueSymbol("Promise" as __String, reportErrors));
|
||||
}
|
||||
@@ -8868,7 +8882,7 @@ namespace ts {
|
||||
}
|
||||
switch (unionReduction) {
|
||||
case UnionReduction.Literal:
|
||||
if (includes & TypeFlags.StringOrNumberLiteralOrUnique) {
|
||||
if (includes & TypeFlags.StringOrNumberLiteralOrUnique | TypeFlags.BooleanLiteral) {
|
||||
removeRedundantLiteralTypes(typeSet, includes);
|
||||
}
|
||||
break;
|
||||
@@ -9369,12 +9383,24 @@ namespace ts {
|
||||
// '{ [P in T]: { [Q in U]: number } }[T][U]' we want to first simplify the inner indexed access type.
|
||||
const objectType = getSimplifiedType(type.objectType);
|
||||
const indexType = getSimplifiedType(type.indexType);
|
||||
if (objectType.flags & TypeFlags.Union) {
|
||||
return type.simplified = mapType(objectType, t => getSimplifiedType(getIndexedAccessType(t, indexType)));
|
||||
// T[A | B] -> T[A] | T[B]
|
||||
if (indexType.flags & TypeFlags.Union) {
|
||||
return type.simplified = mapType(indexType, t => getSimplifiedType(getIndexedAccessType(objectType, t)));
|
||||
}
|
||||
if (objectType.flags & TypeFlags.Intersection) {
|
||||
return type.simplified = getIntersectionType(map((objectType as IntersectionType).types, t => getSimplifiedType(getIndexedAccessType(t, indexType))));
|
||||
// Only do the inner distributions if the index can no longer be instantiated to cause index distribution again
|
||||
if (!(indexType.flags & TypeFlags.Instantiable)) {
|
||||
// (T | U)[K] -> T[K] | U[K]
|
||||
if (objectType.flags & TypeFlags.Union) {
|
||||
return type.simplified = mapType(objectType, t => getSimplifiedType(getIndexedAccessType(t, indexType)));
|
||||
}
|
||||
// (T & U)[K] -> T[K] & U[K]
|
||||
if (objectType.flags & TypeFlags.Intersection) {
|
||||
return type.simplified = getIntersectionType(map((objectType as IntersectionType).types, t => getSimplifiedType(getIndexedAccessType(t, indexType))));
|
||||
}
|
||||
}
|
||||
// So ultimately:
|
||||
// ((A & B) | C)[K1 | K2] -> ((A & B) | C)[K1] | ((A & B) | C)[K2] -> (A & B)[K1] | C[K1] | (A & B)[K2] | C[K2] -> (A[K1] & B[K1]) | C[K1] | (A[K2] & B[K2]) | C[K2]
|
||||
|
||||
// If the object type is a mapped type { [P in K]: E }, where K is generic, instantiate E using a mapper
|
||||
// that substitutes the index type for P. For example, for an index access { [P in K]: Box<T[P]> }[X], we
|
||||
// construct the type Box<T[X]>. We do not further simplify the result because mapped types can be recursive
|
||||
@@ -10569,6 +10595,7 @@ namespace ts {
|
||||
function isTypeDerivedFrom(source: Type, target: Type): boolean {
|
||||
return source.flags & TypeFlags.Union ? every((<UnionType>source).types, t => isTypeDerivedFrom(t, target)) :
|
||||
target.flags & TypeFlags.Union ? some((<UnionType>target).types, t => isTypeDerivedFrom(source, t)) :
|
||||
source.flags & TypeFlags.Primitive && !(target.flags & TypeFlags.Primitive) ? false :
|
||||
source.flags & TypeFlags.InstantiableNonPrimitive ? isTypeDerivedFrom(getBaseConstraintOfType(source) || emptyObjectType, target) :
|
||||
target === globalObjectType || target === globalFunctionType ? isTypeSubtypeOf(source, target) :
|
||||
hasBaseType(source, getTargetType(target));
|
||||
@@ -12921,8 +12948,8 @@ namespace ts {
|
||||
function getDefinitelyFalsyPartOfType(type: Type): Type {
|
||||
return type.flags & TypeFlags.String ? emptyStringType :
|
||||
type.flags & TypeFlags.Number ? zeroType :
|
||||
type.flags & TypeFlags.Boolean || type === regularFalseType ? regularFalseType :
|
||||
type === falseType ? falseType :
|
||||
type === regularFalseType ||
|
||||
type === falseType ||
|
||||
type.flags & (TypeFlags.Void | TypeFlags.Undefined | TypeFlags.Null) ||
|
||||
type.flags & TypeFlags.StringLiteral && (<LiteralType>type).value === "" ||
|
||||
type.flags & TypeFlags.NumberLiteral && (<LiteralType>type).value === 0 ? type :
|
||||
@@ -13233,10 +13260,8 @@ namespace ts {
|
||||
const targetCount = getParameterCount(target);
|
||||
const sourceRestType = getEffectiveRestType(source);
|
||||
const targetRestType = getEffectiveRestType(target);
|
||||
const paramCount = targetRestType ? Math.min(targetCount - 1, sourceCount) :
|
||||
sourceRestType ? targetCount :
|
||||
Math.min(sourceCount, targetCount);
|
||||
|
||||
const targetNonRestCount = targetRestType ? targetCount - 1 : targetCount;
|
||||
const paramCount = sourceRestType ? targetNonRestCount : Math.min(sourceCount, targetNonRestCount);
|
||||
const sourceThisType = getThisTypeOfSignature(source);
|
||||
if (sourceThisType) {
|
||||
const targetThisType = getThisTypeOfSignature(target);
|
||||
@@ -13438,7 +13463,9 @@ namespace ts {
|
||||
let symbolStack: Symbol[];
|
||||
let visited: Map<boolean>;
|
||||
let contravariant = false;
|
||||
let bivariant = false;
|
||||
let propagationType: Type;
|
||||
let allowComplexConstraintInference = true;
|
||||
inferFromTypes(originalSource, originalTarget);
|
||||
|
||||
function inferFromTypes(source: Type, target: Type): void {
|
||||
@@ -13523,11 +13550,13 @@ namespace ts {
|
||||
}
|
||||
if (priority === inference.priority) {
|
||||
const candidate = propagationType || source;
|
||||
if (contravariant) {
|
||||
inference.contraCandidates = append(inference.contraCandidates, candidate);
|
||||
// We make contravariant inferences only if we are in a pure contravariant position,
|
||||
// i.e. only if we have not descended into a bivariant position.
|
||||
if (contravariant && !bivariant) {
|
||||
inference.contraCandidates = appendIfUnique(inference.contraCandidates, candidate);
|
||||
}
|
||||
else {
|
||||
inference.candidates = append(inference.candidates, candidate);
|
||||
inference.candidates = appendIfUnique(inference.candidates, candidate);
|
||||
}
|
||||
}
|
||||
if (!(priority & InferencePriority.ReturnType) && target.flags & TypeFlags.TypeParameter && !isTypeParameterAtTopLevel(originalTarget, <TypeParameter>target)) {
|
||||
@@ -13616,7 +13645,15 @@ namespace ts {
|
||||
// getApparentType can return _any_ type, since an indexed access or conditional may simplify to any other type.
|
||||
// If that occurs and it doesn't simplify to an object or intersection, we'll need to restart `inferFromTypes`
|
||||
// with the simplified source.
|
||||
if (apparentSource !== source && !(apparentSource.flags & (TypeFlags.Object | TypeFlags.Intersection))) {
|
||||
if (apparentSource !== source && allowComplexConstraintInference && !(apparentSource.flags & (TypeFlags.Object | TypeFlags.Intersection))) {
|
||||
// TODO: The `allowComplexConstraintInference` flag is a hack! This forbids inference from complex constraints within constraints!
|
||||
// This isn't required algorithmically, but rather is used to lower the memory burden caused by performing inference
|
||||
// that is _too good_ in projects with complicated constraints (eg, fp-ts). In such cases, if we did not limit ourselves
|
||||
// here, we might produce more valid inferences for types, causing us to do more checks and perform more instantiations
|
||||
// (in addition to the extra stack depth here) which, in turn, can push the already close process over its limit.
|
||||
// TL;DR: If we ever become generally more memory efficienct (or our resource budget ever increases), we should just
|
||||
// remove this `allowComplexConstraintInference` flag.
|
||||
allowComplexConstraintInference = false;
|
||||
return inferFromTypes(apparentSource, target);
|
||||
}
|
||||
source = apparentSource;
|
||||
@@ -13767,7 +13804,12 @@ namespace ts {
|
||||
|
||||
function inferFromSignature(source: Signature, target: Signature, skipParameters: boolean) {
|
||||
if (!skipParameters) {
|
||||
const saveBivariant = bivariant;
|
||||
const kind = target.declaration ? target.declaration.kind : SyntaxKind.Unknown;
|
||||
// Once we descend into a bivariant signature we remain bivariant for all nested inferences
|
||||
bivariant = bivariant || kind === SyntaxKind.MethodDeclaration || kind === SyntaxKind.MethodSignature || kind === SyntaxKind.Constructor;
|
||||
forEachMatchingParameterType(source, target, inferFromContravariantTypes);
|
||||
bivariant = saveBivariant;
|
||||
}
|
||||
const sourceTypePredicate = getTypePredicateOfSignature(source);
|
||||
const targetTypePredicate = getTypePredicateOfSignature(target);
|
||||
@@ -13874,15 +13916,17 @@ namespace ts {
|
||||
if (!inferredType) {
|
||||
const signature = context.signature;
|
||||
if (signature) {
|
||||
if (inference.contraCandidates && (!inference.candidates || inference.candidates.length === 1 && inference.candidates[0].flags & TypeFlags.Never)) {
|
||||
// If we have contravariant inferences, but no covariant inferences or a single
|
||||
// covariant inference of 'never', we find the best common subtype and treat that
|
||||
// as a single covariant candidate.
|
||||
inference.candidates = [getContravariantInference(inference)];
|
||||
inference.contraCandidates = undefined;
|
||||
const inferredCovariantType = inference.candidates ? getCovariantInference(inference, signature) : undefined;
|
||||
if (inference.contraCandidates) {
|
||||
const inferredContravariantType = getContravariantInference(inference);
|
||||
// If we have both co- and contra-variant inferences, we prefer the contra-variant inference
|
||||
// unless the co-variant inference is a subtype and not 'never'.
|
||||
inferredType = inferredCovariantType && !(inferredCovariantType.flags & TypeFlags.Never) &&
|
||||
isTypeSubtypeOf(inferredCovariantType, inferredContravariantType) ?
|
||||
inferredCovariantType : inferredContravariantType;
|
||||
}
|
||||
if (inference.candidates) {
|
||||
inferredType = getCovariantInference(inference, signature);
|
||||
else if (inferredCovariantType) {
|
||||
inferredType = inferredCovariantType;
|
||||
}
|
||||
else if (context.flags & InferenceFlags.NoDefault) {
|
||||
// We use silentNeverType as the wildcard that signals no inferences.
|
||||
@@ -14188,7 +14232,7 @@ namespace ts {
|
||||
return assignedType;
|
||||
}
|
||||
let reducedType = filterType(declaredType, t => typeMaybeAssignableTo(assignedType, t));
|
||||
if (assignedType.flags & (TypeFlags.FreshLiteral | TypeFlags.Literal)) {
|
||||
if (assignedType.flags & TypeFlags.FreshLiteral && assignedType.flags & TypeFlags.BooleanLiteral) {
|
||||
reducedType = mapType(reducedType, getFreshTypeOfLiteralType); // Ensure that if the assignment is a fresh type, that we narrow to fresh types
|
||||
}
|
||||
// Our crude heuristic produces an invalid result in some cases: see GH#26130.
|
||||
@@ -15709,6 +15753,10 @@ namespace ts {
|
||||
return !!findAncestor(node, n => n === threshold ? "quit" : isFunctionLike(n));
|
||||
}
|
||||
|
||||
function getPartOfForStatementContainingNode(node: Node, container: ForStatement) {
|
||||
return findAncestor(node, n => n === container ? "quit" : n === container.initializer || n === container.condition || n === container.incrementor || n === container.statement);
|
||||
}
|
||||
|
||||
function checkNestedBlockScopedBinding(node: Identifier, symbol: Symbol): void {
|
||||
if (languageVersion >= ScriptTarget.ES2015 ||
|
||||
(symbol.flags & (SymbolFlags.BlockScopedVariable | SymbolFlags.Class)) === 0 ||
|
||||
@@ -15737,7 +15785,25 @@ namespace ts {
|
||||
if (containedInIterationStatement) {
|
||||
if (usedInFunction) {
|
||||
// mark iteration statement as containing block-scoped binding captured in some function
|
||||
getNodeLinks(current).flags |= NodeCheckFlags.LoopWithCapturedBlockScopedBinding;
|
||||
let capturesBlockScopeBindingInLoopBody = true;
|
||||
if (isForStatement(container) &&
|
||||
getAncestor(symbol.valueDeclaration, SyntaxKind.VariableDeclarationList)!.parent === container) {
|
||||
const part = getPartOfForStatementContainingNode(node.parent, container);
|
||||
if (part) {
|
||||
const links = getNodeLinks(part);
|
||||
links.flags |= NodeCheckFlags.ContainsCapturedBlockScopeBinding;
|
||||
|
||||
const capturedBindings = links.capturedBlockScopeBindings || (links.capturedBlockScopeBindings = []);
|
||||
pushIfUnique(capturedBindings, symbol);
|
||||
|
||||
if (part === container.initializer) {
|
||||
capturesBlockScopeBindingInLoopBody = false; // Initializer is outside of loop body
|
||||
}
|
||||
}
|
||||
}
|
||||
if (capturesBlockScopeBindingInLoopBody) {
|
||||
getNodeLinks(current).flags |= NodeCheckFlags.LoopWithCapturedBlockScopedBinding;
|
||||
}
|
||||
}
|
||||
|
||||
// mark variables that are declared in loop initializer and reassigned inside the body of ForStatement.
|
||||
@@ -15757,6 +15823,11 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function isBindingCapturedByNode(node: Node, decl: VariableDeclaration | BindingElement) {
|
||||
const links = getNodeLinks(node);
|
||||
return !!links && contains(links.capturedBlockScopeBindings, getSymbolOfNode(decl));
|
||||
}
|
||||
|
||||
function isAssignedInBodyOfForStatement(node: Identifier, container: ForStatement): boolean {
|
||||
// skip parenthesized nodes
|
||||
let current: Node = node;
|
||||
@@ -16372,9 +16443,22 @@ namespace ts {
|
||||
}
|
||||
|
||||
const contextualReturnType = getContextualReturnType(func);
|
||||
return functionFlags & FunctionFlags.Async
|
||||
? contextualReturnType && getAwaitedTypeOfPromise(contextualReturnType) // Async function
|
||||
: contextualReturnType; // Regular function
|
||||
if (contextualReturnType) {
|
||||
if (functionFlags & FunctionFlags.Async) { // Async function
|
||||
const contextualAwaitedType = getAwaitedTypeOfPromise(contextualReturnType);
|
||||
return contextualAwaitedType && getUnionType([contextualAwaitedType, createPromiseLikeType(contextualAwaitedType)]);
|
||||
}
|
||||
return contextualReturnType; // Regular function
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getContextualTypeForAwaitOperand(node: AwaitExpression): Type | undefined {
|
||||
const contextualType = getContextualType(node);
|
||||
if (contextualType) {
|
||||
const contextualAwaitedType = getAwaitedType(contextualType);
|
||||
return contextualAwaitedType && getUnionType([contextualAwaitedType, createPromiseLikeType(contextualAwaitedType)]);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
@@ -16740,7 +16824,9 @@ namespace ts {
|
||||
return getContextualTypeForReturnExpression(node);
|
||||
case SyntaxKind.YieldExpression:
|
||||
return getContextualTypeForYieldOperand(<YieldExpression>parent);
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.AwaitExpression:
|
||||
return getContextualTypeForAwaitOperand(<AwaitExpression>parent);
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
return getContextualTypeForArgument(<CallExpression | NewExpression>parent, node);
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
@@ -16786,6 +16872,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getContextualJsxElementAttributesType(node: JsxOpeningLikeElement) {
|
||||
if (isJsxOpeningElement(node) && node.parent.contextualType) {
|
||||
// Contextually applied type is moved from attributes up to the outer jsx attributes so when walking up from the children they get hit
|
||||
// _However_ to hit them from the _attributes_ we must look for them here; otherwise we'll used the declared type
|
||||
// (as below) instead!
|
||||
return node.parent.contextualType;
|
||||
}
|
||||
if (isJsxIntrinsicIdentifier(node.tagName)) {
|
||||
return getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node);
|
||||
}
|
||||
@@ -18487,7 +18579,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strictNullChecks && prop && prop.valueDeclaration && isPropertyAccessExpression(prop.valueDeclaration) && getAssignmentDeclarationPropertyAccessKind(prop.valueDeclaration)) {
|
||||
else if (strictNullChecks && prop && prop.valueDeclaration &&
|
||||
isPropertyAccessExpression(prop.valueDeclaration) &&
|
||||
getAssignmentDeclarationPropertyAccessKind(prop.valueDeclaration) &&
|
||||
getControlFlowContainer(node) === getControlFlowContainer(prop.valueDeclaration)) {
|
||||
assumeUninitialized = true;
|
||||
}
|
||||
const flowType = getFlowTypeOfReference(node, propType, assumeUninitialized ? getOptionalType(propType) : propType);
|
||||
@@ -19645,7 +19740,10 @@ namespace ts {
|
||||
checkCandidate = candidate;
|
||||
}
|
||||
if (!checkApplicableSignature(node, args, checkCandidate, relation, excludeArgument, /*reportErrors*/ false)) {
|
||||
candidateForArgumentError = checkCandidate;
|
||||
// Give preference to error candidates that have no rest parameters (as they are more specific)
|
||||
if (!candidateForArgumentError || getEffectiveRestType(candidateForArgumentError) || !getEffectiveRestType(checkCandidate)) {
|
||||
candidateForArgumentError = checkCandidate;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (excludeArgument) {
|
||||
@@ -19658,7 +19756,10 @@ namespace ts {
|
||||
checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration));
|
||||
}
|
||||
if (!checkApplicableSignature(node, args, checkCandidate, relation, excludeArgument, /*reportErrors*/ false)) {
|
||||
candidateForArgumentError = checkCandidate;
|
||||
// Give preference to error candidates that have no rest parameters (as they are more specific)
|
||||
if (!candidateForArgumentError || getEffectiveRestType(candidateForArgumentError) || !getEffectiveRestType(checkCandidate)) {
|
||||
candidateForArgumentError = checkCandidate;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -20772,6 +20873,18 @@ namespace ts {
|
||||
return emptyObjectType;
|
||||
}
|
||||
|
||||
function createPromiseLikeType(promisedType: Type): Type {
|
||||
// creates a `PromiseLike<T>` type where `T` is the promisedType argument
|
||||
const globalPromiseLikeType = getGlobalPromiseLikeType(/*reportErrors*/ true);
|
||||
if (globalPromiseLikeType !== emptyGenericType) {
|
||||
// if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type
|
||||
promisedType = getAwaitedType(promisedType) || emptyObjectType;
|
||||
return createTypeReference(globalPromiseLikeType, [promisedType]);
|
||||
}
|
||||
|
||||
return emptyObjectType;
|
||||
}
|
||||
|
||||
function createPromiseReturnType(func: FunctionLikeDeclaration | ImportCall, promisedType: Type) {
|
||||
const promiseType = createPromiseType(promisedType);
|
||||
if (promiseType === emptyObjectType) {
|
||||
@@ -25257,14 +25370,18 @@ namespace ts {
|
||||
|
||||
if (allowSyncIterables) {
|
||||
if (typeAsIterable.iteratedTypeOfIterable) {
|
||||
return typeAsIterable.iteratedTypeOfIterable;
|
||||
return allowAsyncIterables
|
||||
? typeAsIterable.iteratedTypeOfAsyncIterable = getAwaitedType(typeAsIterable.iteratedTypeOfIterable)
|
||||
: typeAsIterable.iteratedTypeOfIterable;
|
||||
}
|
||||
|
||||
// As an optimization, if the type is an instantiation of the global `Iterable<T>` or
|
||||
// `IterableIterator<T>` then just grab its type argument.
|
||||
if (isReferenceToType(type, getGlobalIterableType(/*reportErrors*/ false)) ||
|
||||
isReferenceToType(type, getGlobalIterableIteratorType(/*reportErrors*/ false))) {
|
||||
return typeAsIterable.iteratedTypeOfIterable = (<GenericType>type).typeArguments![0];
|
||||
return allowAsyncIterables
|
||||
? typeAsIterable.iteratedTypeOfAsyncIterable = getAwaitedType((<GenericType>type).typeArguments![0])
|
||||
: typeAsIterable.iteratedTypeOfIterable = (<GenericType>type).typeArguments![0];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25295,9 +25412,11 @@ namespace ts {
|
||||
: createIterableType(iteratedType), errorNode);
|
||||
}
|
||||
|
||||
return asyncMethodType
|
||||
? typeAsIterable.iteratedTypeOfAsyncIterable = iteratedType
|
||||
: typeAsIterable.iteratedTypeOfIterable = iteratedType;
|
||||
if (iteratedType) {
|
||||
return allowAsyncIterables
|
||||
? typeAsIterable.iteratedTypeOfAsyncIterable = asyncMethodType ? iteratedType : getAwaitedType(iteratedType)
|
||||
: typeAsIterable.iteratedTypeOfIterable = iteratedType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26173,6 +26292,8 @@ namespace ts {
|
||||
|
||||
function isPropertyInitializedInConstructor(propName: Identifier, propType: Type, constructor: ConstructorDeclaration) {
|
||||
const reference = createPropertyAccess(createThis(), propName);
|
||||
reference.expression.parent = reference;
|
||||
reference.parent = constructor;
|
||||
reference.flowNode = constructor.returnFlowNode;
|
||||
const flowType = getFlowTypeOfReference(reference, propType, getOptionalType(propType));
|
||||
return !(getFalsyFlags(flowType) & TypeFlags.Undefined);
|
||||
@@ -27819,24 +27940,20 @@ namespace ts {
|
||||
return errorType;
|
||||
}
|
||||
|
||||
const classDecl = tryGetClassImplementingOrExtendingExpressionWithTypeArguments(node);
|
||||
const classType = classDecl && getDeclaredTypeOfClassOrInterface(getSymbolOfNode(classDecl.class));
|
||||
if (isPartOfTypeNode(node)) {
|
||||
const typeFromTypeNode = getTypeFromTypeNode(<TypeNode>node);
|
||||
|
||||
if (isExpressionWithTypeArgumentsInClassImplementsClause(node)) {
|
||||
return getTypeWithThisArgument(typeFromTypeNode, getTypeOfClassContainingHeritageClause(node).thisType);
|
||||
}
|
||||
|
||||
return typeFromTypeNode;
|
||||
return classType ? getTypeWithThisArgument(typeFromTypeNode, classType.thisType) : typeFromTypeNode;
|
||||
}
|
||||
|
||||
if (isExpressionNode(node)) {
|
||||
return getRegularTypeOfExpression(<Expression>node);
|
||||
}
|
||||
|
||||
if (isExpressionWithTypeArgumentsInClassExtendsClause(node)) {
|
||||
if (classType && !classDecl!.isImplements) {
|
||||
// A SyntaxKind.ExpressionWithTypeArguments is considered a type node, except when it occurs in the
|
||||
// extends clause of a class. We handle that case here.
|
||||
const classType = getTypeOfClassContainingHeritageClause(node);
|
||||
const baseType = firstOrUndefined(getBaseTypes(classType));
|
||||
return baseType ? getTypeWithThisArgument(baseType, classType.thisType) : errorType;
|
||||
}
|
||||
@@ -27878,10 +27995,6 @@ namespace ts {
|
||||
return errorType;
|
||||
}
|
||||
|
||||
function getTypeOfClassContainingHeritageClause(node: ExpressionWithTypeArguments): InterfaceType {
|
||||
return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node.parent.parent));
|
||||
}
|
||||
|
||||
// Gets the type of object literal or array literal of destructuring assignment.
|
||||
// { a } from
|
||||
// for ( { a } of elems) {
|
||||
@@ -27970,8 +28083,11 @@ namespace ts {
|
||||
function getAugmentedPropertiesOfType(type: Type): Symbol[] {
|
||||
type = getApparentType(type);
|
||||
const propsByName = createSymbolTable(getPropertiesOfType(type));
|
||||
if (typeHasCallOrConstructSignatures(type)) {
|
||||
forEach(getPropertiesOfType(globalFunctionType), p => {
|
||||
const functionType = getSignaturesOfType(type, SignatureKind.Call).length ? globalCallableFunctionType :
|
||||
getSignaturesOfType(type, SignatureKind.Construct).length ? globalNewableFunctionType :
|
||||
undefined;
|
||||
if (functionType) {
|
||||
forEach(getPropertiesOfType(functionType), p => {
|
||||
if (!propsByName.has(p.escapedName)) {
|
||||
propsByName.set(p.escapedName, p);
|
||||
}
|
||||
@@ -28590,7 +28706,12 @@ namespace ts {
|
||||
getAccessor
|
||||
};
|
||||
},
|
||||
getSymbolOfExternalModuleSpecifier: moduleName => resolveExternalModuleNameWorker(moduleName, moduleName, /*moduleNotFoundError*/ undefined)
|
||||
getSymbolOfExternalModuleSpecifier: moduleName => resolveExternalModuleNameWorker(moduleName, moduleName, /*moduleNotFoundError*/ undefined),
|
||||
isBindingCapturedByNode: (node, decl) => {
|
||||
const parseNode = getParseTreeNode(node);
|
||||
const parseDecl = getParseTreeNode(decl);
|
||||
return !!parseNode && !!parseDecl && (isVariableDeclaration(parseDecl) || isBindingElement(parseDecl)) && isBindingCapturedByNode(parseNode, parseDecl);
|
||||
}
|
||||
};
|
||||
|
||||
function isInHeritageClause(node: PropertyAccessEntityNameExpression) {
|
||||
@@ -28751,6 +28872,8 @@ namespace ts {
|
||||
globalArrayType = getGlobalType("Array" as __String, /*arity*/ 1, /*reportErrors*/ true);
|
||||
globalObjectType = getGlobalType("Object" as __String, /*arity*/ 0, /*reportErrors*/ true);
|
||||
globalFunctionType = getGlobalType("Function" as __String, /*arity*/ 0, /*reportErrors*/ true);
|
||||
globalCallableFunctionType = strictBindCallApply && getGlobalType("CallableFunction" as __String, /*arity*/ 0, /*reportErrors*/ true) || globalFunctionType;
|
||||
globalNewableFunctionType = strictBindCallApply && getGlobalType("NewableFunction" as __String, /*arity*/ 0, /*reportErrors*/ true) || globalFunctionType;
|
||||
globalStringType = getGlobalType("String" as __String, /*arity*/ 0, /*reportErrors*/ true);
|
||||
globalNumberType = getGlobalType("Number" as __String, /*arity*/ 0, /*reportErrors*/ true);
|
||||
globalBooleanType = getGlobalType("Boolean" as __String, /*arity*/ 0, /*reportErrors*/ true);
|
||||
|
||||
@@ -77,6 +77,14 @@ namespace ts {
|
||||
shortName: "?",
|
||||
type: "boolean"
|
||||
},
|
||||
{
|
||||
name: "watch",
|
||||
shortName: "w",
|
||||
type: "boolean",
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Command_line_Options,
|
||||
description: Diagnostics.Watch_input_files,
|
||||
},
|
||||
{
|
||||
name: "preserveWatchOutput",
|
||||
type: "boolean",
|
||||
@@ -96,13 +104,12 @@ namespace ts {
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Print_names_of_generated_files_part_of_the_compilation
|
||||
},
|
||||
|
||||
{
|
||||
name: "watch",
|
||||
shortName: "w",
|
||||
name: "traceResolution",
|
||||
type: "boolean",
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Command_line_Options,
|
||||
description: Diagnostics.Watch_input_files,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Enable_tracing_of_the_name_resolution_process
|
||||
},
|
||||
];
|
||||
|
||||
@@ -366,6 +373,14 @@ namespace ts {
|
||||
category: Diagnostics.Strict_Type_Checking_Options,
|
||||
description: Diagnostics.Enable_strict_checking_of_function_types
|
||||
},
|
||||
{
|
||||
name: "strictBindCallApply",
|
||||
type: "boolean",
|
||||
strictFlag: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Strict_Type_Checking_Options,
|
||||
description: Diagnostics.Enable_strict_bind_call_and_apply_methods_on_functions
|
||||
},
|
||||
{
|
||||
name: "strictPropertyInitialization",
|
||||
type: "boolean",
|
||||
@@ -581,12 +596,6 @@ namespace ts {
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Show_verbose_diagnostic_information
|
||||
},
|
||||
{
|
||||
name: "traceResolution",
|
||||
type: "boolean",
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Enable_tracing_of_the_name_resolution_process
|
||||
},
|
||||
{
|
||||
name: "resolveJsonModule",
|
||||
type: "boolean",
|
||||
@@ -1520,7 +1529,12 @@ namespace ts {
|
||||
elements: NodeArray<Expression>,
|
||||
elementOption: CommandLineOption | undefined
|
||||
): any[] | void {
|
||||
return (returnValue ? elements.map : elements.forEach).call(elements, (element: Expression) => convertPropertyValueToJson(element, elementOption));
|
||||
if (!returnValue) {
|
||||
return elements.forEach(element => convertPropertyValueToJson(element, elementOption));
|
||||
}
|
||||
|
||||
// Filter out invalid values
|
||||
return filter(elements.map(element => convertPropertyValueToJson(element, elementOption)), v => v !== undefined);
|
||||
}
|
||||
|
||||
function convertPropertyValueToJson(valueExpression: Expression, option: CommandLineOption | undefined): any {
|
||||
@@ -1886,7 +1900,8 @@ namespace ts {
|
||||
filesSpecs = <ReadonlyArray<string>>raw.files;
|
||||
const hasReferences = hasProperty(raw, "references") && !isNullOrUndefined(raw.references);
|
||||
const hasZeroOrNoReferences = !hasReferences || raw.references.length === 0;
|
||||
if (filesSpecs.length === 0 && hasZeroOrNoReferences) {
|
||||
const hasExtends = hasProperty(raw, "extends");
|
||||
if (filesSpecs.length === 0 && hasZeroOrNoReferences && !hasExtends) {
|
||||
if (sourceFile) {
|
||||
const fileName = configFileName || "tsconfig.json";
|
||||
const diagnosticMessage = Diagnostics.The_files_list_in_config_file_0_is_empty;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace ts {
|
||||
// WARNING: The script `configureNightly.ts` uses a regexp to parse out these values.
|
||||
// If changing the text in this section, be sure to test `configureNightly` too.
|
||||
export const versionMajorMinor = "3.1";
|
||||
export const versionMajorMinor = "3.2";
|
||||
/** The version of the TypeScript compiler release */
|
||||
export const version = `${versionMajorMinor}.0-dev`;
|
||||
}
|
||||
|
||||
+4693
-4689
File diff suppressed because it is too large.
Load diff
@@ -381,8 +381,13 @@ namespace ts {
|
||||
// tslint:disable-next-line:no-null-keyword
|
||||
const isNotNeededPackage = host.fileExists(packageJsonPath) && (readJson(packageJsonPath, host) as PackageJson).typings === null;
|
||||
if (!isNotNeededPackage) {
|
||||
// Return just the type directive names
|
||||
result.push(getBaseFileName(normalized));
|
||||
const baseFileName = getBaseFileName(normalized);
|
||||
|
||||
// At this stage, skip results with leading dot.
|
||||
if (baseFileName.charCodeAt(0) !== CharacterCodes.dot) {
|
||||
// Return just the type directive names
|
||||
result.push(baseFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
-12
@@ -7725,7 +7725,7 @@ namespace ts {
|
||||
/*@internal*/
|
||||
export function processCommentPragmas(context: PragmaContext, sourceText: string): void {
|
||||
const triviaScanner = createScanner(context.languageVersion, /*skipTrivia*/ false, LanguageVariant.Standard, sourceText);
|
||||
const pragmas: PragmaPsuedoMapEntry[] = [];
|
||||
const pragmas: PragmaPseudoMapEntry[] = [];
|
||||
|
||||
// Keep scanning all the leading trivia in the file until we get to something that
|
||||
// isn't trivia. Any single line comment will be analyzed to see if it is a
|
||||
@@ -7780,7 +7780,7 @@ namespace ts {
|
||||
const referencedFiles = context.referencedFiles;
|
||||
const typeReferenceDirectives = context.typeReferenceDirectives;
|
||||
const libReferenceDirectives = context.libReferenceDirectives;
|
||||
forEach(toArray(entryOrList), (arg: PragmaPsuedoMap["reference"]) => {
|
||||
forEach(toArray(entryOrList), (arg: PragmaPseudoMap["reference"]) => {
|
||||
// TODO: GH#18217
|
||||
if (arg!.arguments["no-default-lib"]) {
|
||||
context.hasNoDefaultLib = true;
|
||||
@@ -7803,7 +7803,7 @@ namespace ts {
|
||||
case "amd-dependency": {
|
||||
context.amdDependencies = map(
|
||||
toArray(entryOrList),
|
||||
(x: PragmaPsuedoMap["amd-dependency"]) => ({ name: x!.arguments.name!, path: x!.arguments.path })); // TODO: GH#18217
|
||||
(x: PragmaPseudoMap["amd-dependency"]) => ({ name: x!.arguments.name!, path: x!.arguments.path })); // TODO: GH#18217
|
||||
break;
|
||||
}
|
||||
case "amd-module": {
|
||||
@@ -7813,11 +7813,11 @@ namespace ts {
|
||||
// TODO: It's probably fine to issue this diagnostic on all instances of the pragma
|
||||
reportDiagnostic(entry!.range.pos, entry!.range.end - entry!.range.pos, Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments);
|
||||
}
|
||||
context.moduleName = (entry as PragmaPsuedoMap["amd-module"])!.arguments.name;
|
||||
context.moduleName = (entry as PragmaPseudoMap["amd-module"])!.arguments.name;
|
||||
}
|
||||
}
|
||||
else {
|
||||
context.moduleName = (entryOrList as PragmaPsuedoMap["amd-module"])!.arguments.name;
|
||||
context.moduleName = (entryOrList as PragmaPseudoMap["amd-module"])!.arguments.name;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -7853,10 +7853,10 @@ namespace ts {
|
||||
|
||||
const tripleSlashXMLCommentStartRegEx = /^\/\/\/\s*<(\S+)\s.*?\/>/im;
|
||||
const singleLinePragmaRegEx = /^\/\/\/?\s*@(\S+)\s*(.*)\s*$/im;
|
||||
function extractPragmas(pragmas: PragmaPsuedoMapEntry[], range: CommentRange, text: string) {
|
||||
function extractPragmas(pragmas: PragmaPseudoMapEntry[], range: CommentRange, text: string) {
|
||||
const tripleSlash = range.kind === SyntaxKind.SingleLineCommentTrivia && tripleSlashXMLCommentStartRegEx.exec(text);
|
||||
if (tripleSlash) {
|
||||
const name = tripleSlash[1].toLowerCase() as keyof PragmaPsuedoMap; // Technically unsafe cast, but we do it so the below check to make it safe typechecks
|
||||
const name = tripleSlash[1].toLowerCase() as keyof PragmaPseudoMap; // Technically unsafe cast, but we do it so the below check to make it safe typechecks
|
||||
const pragma = commentPragmas[name] as PragmaDefinition;
|
||||
if (!pragma || !(pragma.kind! & PragmaKindFlags.TripleSlashXML)) {
|
||||
return;
|
||||
@@ -7883,10 +7883,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
pragmas.push({ name, args: { arguments: argument, range } } as PragmaPsuedoMapEntry);
|
||||
pragmas.push({ name, args: { arguments: argument, range } } as PragmaPseudoMapEntry);
|
||||
}
|
||||
else {
|
||||
pragmas.push({ name, args: { arguments: {}, range } } as PragmaPsuedoMapEntry);
|
||||
pragmas.push({ name, args: { arguments: {}, range } } as PragmaPseudoMapEntry);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -7905,9 +7905,9 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function addPragmaForMatch(pragmas: PragmaPsuedoMapEntry[], range: CommentRange, kind: PragmaKindFlags, match: RegExpExecArray) {
|
||||
function addPragmaForMatch(pragmas: PragmaPseudoMapEntry[], range: CommentRange, kind: PragmaKindFlags, match: RegExpExecArray) {
|
||||
if (!match) return;
|
||||
const name = match[1].toLowerCase() as keyof PragmaPsuedoMap; // Technically unsafe cast, but we do it so they below check to make it safe typechecks
|
||||
const name = match[1].toLowerCase() as keyof PragmaPseudoMap; // Technically unsafe cast, but we do it so they below check to make it safe typechecks
|
||||
const pragma = commentPragmas[name] as PragmaDefinition;
|
||||
if (!pragma || !(pragma.kind! & kind)) {
|
||||
return;
|
||||
@@ -7915,7 +7915,7 @@ namespace ts {
|
||||
const args = match[2]; // Split on spaces and match up positionally with definition
|
||||
const argument = getNamedPragmaArguments(pragma, args);
|
||||
if (argument === "fail") return; // Missing required argument, fail to parse it
|
||||
pragmas.push({ name, args: { arguments: argument, range } } as PragmaPsuedoMapEntry);
|
||||
pragmas.push({ name, args: { arguments: argument, range } } as PragmaPseudoMapEntry);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+45
-39
@@ -207,7 +207,7 @@ namespace ts {
|
||||
...program.getSemanticDiagnostics(sourceFile, cancellationToken)
|
||||
];
|
||||
|
||||
if (program.getCompilerOptions().declaration) {
|
||||
if (getEmitDeclarations(program.getCompilerOptions())) {
|
||||
addRange(diagnostics, program.getDeclarationDiagnostics(sourceFile, cancellationToken));
|
||||
}
|
||||
|
||||
@@ -485,11 +485,11 @@ namespace ts {
|
||||
|
||||
function sourceFileNotUptoDate(sourceFile: SourceFile) {
|
||||
return !sourceFileVersionUptoDate(sourceFile) ||
|
||||
hasInvalidatedResolution(sourceFile.resolvedPath || sourceFile.path);
|
||||
hasInvalidatedResolution(sourceFile.resolvedPath);
|
||||
}
|
||||
|
||||
function sourceFileVersionUptoDate(sourceFile: SourceFile) {
|
||||
return sourceFile.version === getSourceVersion(sourceFile.resolvedPath || sourceFile.path);
|
||||
return sourceFile.version === getSourceVersion(sourceFile.resolvedPath);
|
||||
}
|
||||
|
||||
function projectReferenceUptoDate(oldRef: ProjectReference, newRef: ProjectReference, index: number) {
|
||||
@@ -663,7 +663,7 @@ namespace ts {
|
||||
|
||||
// A parallel array to projectReferences storing the results of reading in the referenced tsconfig files
|
||||
let resolvedProjectReferences: (ResolvedProjectReference | undefined)[] | undefined = projectReferences ? [] : undefined;
|
||||
const projectReferenceRedirects: Map<string> = createMap();
|
||||
let projectReferenceRedirects: ParsedCommandLine[] | undefined;
|
||||
|
||||
const shouldCreateNewSourceFile = shouldProgramCreateNewSourceFiles(oldProgram, options);
|
||||
const structuralIsReused = tryReuseStructureFromOldProgram();
|
||||
@@ -681,7 +681,7 @@ namespace ts {
|
||||
const dtsOutfile = changeExtension(out, ".d.ts");
|
||||
processSourceFile(dtsOutfile, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, /*packageId*/ undefined);
|
||||
}
|
||||
addProjectReferenceRedirects(parsedRef.commandLine, projectReferenceRedirects);
|
||||
addProjectReferenceRedirects(parsedRef.commandLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -817,9 +817,9 @@ namespace ts {
|
||||
// If a rootDir is specified use it as the commonSourceDirectory
|
||||
commonSourceDirectory = getNormalizedAbsolutePath(options.rootDir, currentDirectory);
|
||||
}
|
||||
else if (options.composite) {
|
||||
else if (options.composite && options.configFilePath) {
|
||||
// Project compilations never infer their root from the input source paths
|
||||
commonSourceDirectory = getDirectoryPath(normalizeSlashes(options.configFilePath!)); // TODO: GH#18217
|
||||
commonSourceDirectory = getDirectoryPath(normalizeSlashes(options.configFilePath));
|
||||
checkSourceFilesBelongToPath(emittedFiles, commonSourceDirectory);
|
||||
}
|
||||
else {
|
||||
@@ -1079,7 +1079,7 @@ namespace ts {
|
||||
|
||||
for (const oldSourceFile of oldSourceFiles) {
|
||||
let newSourceFile = host.getSourceFileByPath
|
||||
? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.resolvedPath || oldSourceFile.path, options.target!, /*onError*/ undefined, shouldCreateNewSourceFile)
|
||||
? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.resolvedPath, options.target!, /*onError*/ undefined, shouldCreateNewSourceFile)
|
||||
: host.getSourceFile(oldSourceFile.fileName, options.target!, /*onError*/ undefined, shouldCreateNewSourceFile); // TODO: GH#18217
|
||||
|
||||
if (!newSourceFile) {
|
||||
@@ -1110,7 +1110,11 @@ namespace ts {
|
||||
fileChanged = newSourceFile !== oldSourceFile;
|
||||
}
|
||||
|
||||
// Since the project references havent changed, its right to set originalFileName and resolvedPath here
|
||||
newSourceFile.path = oldSourceFile.path;
|
||||
newSourceFile.originalFileName = oldSourceFile.originalFileName;
|
||||
newSourceFile.resolvedPath = oldSourceFile.resolvedPath;
|
||||
newSourceFile.fileName = oldSourceFile.fileName;
|
||||
filePaths.push(newSourceFile.path);
|
||||
|
||||
const packageName = oldProgram.sourceFileToPackageName.get(oldSourceFile.path);
|
||||
@@ -1187,7 +1191,7 @@ namespace ts {
|
||||
modifiedFilePaths = modifiedSourceFiles.map(f => f.newFile.path);
|
||||
// try to verify results of module resolution
|
||||
for (const { oldFile: oldSourceFile, newFile: newSourceFile } of modifiedSourceFiles) {
|
||||
const newSourceFilePath = getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory);
|
||||
const newSourceFilePath = getNormalizedAbsolutePath(newSourceFile.originalFileName, currentDirectory);
|
||||
if (resolveModuleNamesWorker) {
|
||||
const moduleNames = getModuleNames(newSourceFile);
|
||||
const oldProgramState: OldProgramState = { program: oldProgram, oldSourceFile, modifiedFilePaths };
|
||||
@@ -1248,7 +1252,7 @@ namespace ts {
|
||||
if (resolvedProjectReferences) {
|
||||
resolvedProjectReferences.forEach(ref => {
|
||||
if (ref) {
|
||||
addProjectReferenceRedirects(ref.commandLine, projectReferenceRedirects);
|
||||
addProjectReferenceRedirects(ref.commandLine);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1388,7 +1392,7 @@ namespace ts {
|
||||
...program.getSemanticDiagnostics(sourceFile, cancellationToken)
|
||||
];
|
||||
|
||||
if (diagnostics.length === 0 && program.getCompilerOptions().declaration) {
|
||||
if (diagnostics.length === 0 && getEmitDeclarations(program.getCompilerOptions())) {
|
||||
declarationDiagnostics = program.getDeclarationDiagnostics(/*sourceFile*/ undefined, cancellationToken);
|
||||
}
|
||||
|
||||
@@ -2040,6 +2044,7 @@ namespace ts {
|
||||
|
||||
// Get source file from normalized fileName
|
||||
function findSourceFile(fileName: string, path: Path, isDefaultLib: boolean, ignoreNoDefaultLib: boolean, refFile: SourceFile, refPos: number, refEnd: number, packageId: PackageId | undefined): SourceFile | undefined {
|
||||
const originalFileName = fileName;
|
||||
if (filesByName.has(path)) {
|
||||
const file = filesByName.get(path);
|
||||
// try to check if we've already seen this file but with a different casing in path
|
||||
@@ -2136,6 +2141,7 @@ namespace ts {
|
||||
sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0);
|
||||
file.path = path;
|
||||
file.resolvedPath = toPath(fileName);
|
||||
file.originalFileName = originalFileName;
|
||||
|
||||
if (host.useCaseSensitiveFileNames()) {
|
||||
const pathLowerCase = path.toLowerCase();
|
||||
@@ -2173,25 +2179,29 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getProjectReferenceRedirect(fileName: string): string | undefined {
|
||||
const path = toPath(fileName);
|
||||
// Ignore dts or any of the non ts files
|
||||
if (!projectReferenceRedirects || fileExtensionIs(fileName, Extension.Dts) || !fileExtensionIsOneOf(fileName, supportedTSExtensions)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// If this file is produced by a referenced project, we need to rewrite it to
|
||||
// look in the output folder of the referenced project rather than the input
|
||||
const normalized = getNormalizedAbsolutePath(fileName, path);
|
||||
let result: string | undefined;
|
||||
projectReferenceRedirects.forEach((v, k) => {
|
||||
if (result !== undefined) {
|
||||
return forEach(projectReferenceRedirects, referencedProject => {
|
||||
// not input file from the referenced project, ignore
|
||||
if (!contains(referencedProject.fileNames, fileName, isSameFile)) {
|
||||
return undefined;
|
||||
}
|
||||
if (normalized.indexOf(k) === 0) {
|
||||
result = changeExtension(fileName.replace(k, v), ".d.ts");
|
||||
}
|
||||
|
||||
const out = referencedProject.options.outFile || referencedProject.options.out;
|
||||
return out ?
|
||||
changeExtension(out, Extension.Dts) :
|
||||
getOutputDeclarationFileName(fileName, referencedProject);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
function processReferencedFiles(file: SourceFile, isDefaultLib: boolean) {
|
||||
forEach(file.referencedFiles, ref => {
|
||||
const referencedFileName = resolveTripleslashReference(ref.fileName, file.fileName);
|
||||
const referencedFileName = resolveTripleslashReference(ref.fileName, file.originalFileName);
|
||||
processSourceFile(referencedFileName, isDefaultLib, /*ignoreNoDefaultLib*/ false, /*packageId*/ undefined, file, ref.pos, ref.end);
|
||||
});
|
||||
}
|
||||
@@ -2203,7 +2213,7 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
|
||||
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeDirectives, file.fileName);
|
||||
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeDirectives, file.originalFileName);
|
||||
|
||||
for (let i = 0; i < typeDirectives.length; i++) {
|
||||
const ref = file.typeReferenceDirectives[i];
|
||||
@@ -2299,7 +2309,7 @@ namespace ts {
|
||||
// Because global augmentation doesn't have string literal name, we can check for global augmentation as such.
|
||||
const moduleNames = getModuleNames(file);
|
||||
const oldProgramState: OldProgramState = { program: oldProgram, oldSourceFile: oldProgram && oldProgram.getSourceFile(file.fileName), modifiedFilePaths };
|
||||
const resolutions = resolveModuleNamesReusingOldState(moduleNames, getNormalizedAbsolutePath(file.fileName, currentDirectory), file, oldProgramState);
|
||||
const resolutions = resolveModuleNamesReusingOldState(moduleNames, getNormalizedAbsolutePath(file.originalFileName, currentDirectory), file, oldProgramState);
|
||||
Debug.assert(resolutions.length === moduleNames.length);
|
||||
for (let i = 0; i < moduleNames.length; i++) {
|
||||
const resolution = resolutions[i];
|
||||
@@ -2390,15 +2400,8 @@ namespace ts {
|
||||
return { commandLine, sourceFile };
|
||||
}
|
||||
|
||||
function addProjectReferenceRedirects(referencedProject: ParsedCommandLine, target: Map<string>) {
|
||||
const rootDir = normalizePath(referencedProject.options.rootDir || getDirectoryPath(referencedProject.options.configFilePath!)); // TODO: GH#18217
|
||||
target.set(rootDir, getDeclarationOutputDirectory(referencedProject));
|
||||
}
|
||||
|
||||
function getDeclarationOutputDirectory(proj: ParsedCommandLine) {
|
||||
return proj.options.declarationDir ||
|
||||
proj.options.outDir ||
|
||||
getDirectoryPath(proj.options.configFilePath!); // TODO: GH#18217
|
||||
function addProjectReferenceRedirects(referencedProject: ParsedCommandLine) {
|
||||
(projectReferenceRedirects || (projectReferenceRedirects = [])).push(referencedProject);
|
||||
}
|
||||
|
||||
function verifyCompilerOptions() {
|
||||
@@ -2407,8 +2410,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (options.isolatedModules) {
|
||||
if (options.declaration) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "declaration", "isolatedModules");
|
||||
if (getEmitDeclarations(options)) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, getEmitDeclarationOptionName(options), "isolatedModules");
|
||||
}
|
||||
|
||||
if (options.noEmitOnError) {
|
||||
@@ -2533,7 +2536,7 @@ namespace ts {
|
||||
|
||||
if (options.declarationDir) {
|
||||
if (!getEmitDeclarations(options)) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "declarationDir", "declaration");
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "declarationDir", "declaration", "composite");
|
||||
}
|
||||
if (options.out || options.outFile) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "declarationDir", options.out ? "out" : "outFile");
|
||||
@@ -2541,7 +2544,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (options.declarationMap && !getEmitDeclarations(options)) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "declarationMap", "declaration");
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "declarationMap", "declaration", "composite");
|
||||
}
|
||||
|
||||
if (options.lib && options.noLib) {
|
||||
@@ -2610,7 +2613,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (!options.noEmit && options.allowJs && getEmitDeclarations(options)) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", options.declaration ? "declaration" : "composite");
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", getEmitDeclarationOptionName(options));
|
||||
}
|
||||
|
||||
if (options.checkJs && !options.allowJs) {
|
||||
@@ -2618,8 +2621,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (options.emitDeclarationOnly) {
|
||||
if (!options.declaration) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDeclarationOnly", "declaration");
|
||||
if (!getEmitDeclarations(options)) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "emitDeclarationOnly", "declaration", "composite");
|
||||
}
|
||||
|
||||
if (options.noEmit) {
|
||||
@@ -2877,6 +2880,9 @@ namespace ts {
|
||||
return resolveConfigFileProjectName(passedInRef.path);
|
||||
}
|
||||
|
||||
function getEmitDeclarationOptionName(options: CompilerOptions) {
|
||||
return options.declaration ? "declaration" : "composite";
|
||||
}
|
||||
/* @internal */
|
||||
/**
|
||||
* Returns a DiagnosticMessage if we won't include a resolved module due to its extension.
|
||||
|
||||
@@ -434,7 +434,7 @@ namespace ts {
|
||||
// Heritage clause is written by user so it can always be named
|
||||
if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) {
|
||||
// Class or Interface implemented/extended is inaccessible
|
||||
diagnosticMessage = (node as ExpressionWithTypeArguments).parent.token === SyntaxKind.ImplementsKeyword ?
|
||||
diagnosticMessage = isHeritageClause(node.parent) && node.parent.token === SyntaxKind.ImplementsKeyword ?
|
||||
Diagnostics.Implements_clause_of_exported_class_0_has_or_is_using_private_name_1 :
|
||||
Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1;
|
||||
}
|
||||
@@ -446,7 +446,7 @@ namespace ts {
|
||||
return {
|
||||
diagnosticMessage,
|
||||
errorNode: node,
|
||||
typeName: getNameOfDeclaration((node as ExpressionWithTypeArguments).parent.parent)
|
||||
typeName: getNameOfDeclaration(node.parent.parent as Declaration)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+454
-157
@@ -46,10 +46,16 @@ namespace ts {
|
||||
* so nobody can observe this new value.
|
||||
*/
|
||||
interface LoopOutParameter {
|
||||
flags: LoopOutParameterFlags;
|
||||
originalName: Identifier;
|
||||
outParamName: Identifier;
|
||||
}
|
||||
|
||||
const enum LoopOutParameterFlags {
|
||||
Body = 1 << 0, // Modified in the body of the iteration statement
|
||||
Initializer = 1 << 1, // Set in the initializer of a ForStatement
|
||||
}
|
||||
|
||||
const enum CopyDirection {
|
||||
ToOriginal,
|
||||
ToOutParameter
|
||||
@@ -129,10 +135,14 @@ namespace ts {
|
||||
*/
|
||||
hoistedLocalVariables?: Identifier[];
|
||||
|
||||
conditionVariable?: Identifier;
|
||||
|
||||
loopParameters: ParameterDeclaration[];
|
||||
|
||||
/**
|
||||
* List of loop out parameters - detailed descripion can be found in the comment to LoopOutParameter
|
||||
*/
|
||||
loopOutParameters?: LoopOutParameter[];
|
||||
loopOutParameters: LoopOutParameter[];
|
||||
}
|
||||
|
||||
const enum SuperCaptureResult {
|
||||
@@ -347,7 +357,7 @@ namespace ts {
|
||||
return (node.transformFlags & TransformFlags.ContainsES2015) !== 0
|
||||
|| convertedLoopState !== undefined
|
||||
|| (hierarchyFacts & HierarchyFacts.ConstructorWithCapturedSuper && (isStatement(node) || (node.kind === SyntaxKind.Block)))
|
||||
|| (isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatementBody(node))
|
||||
|| (isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatement(node))
|
||||
|| (getEmitFlags(node) & EmitFlags.TypeScriptClassWrapper) !== 0;
|
||||
}
|
||||
|
||||
@@ -646,8 +656,8 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
let returnExpression: Expression = createLiteral(labelMarker);
|
||||
if (convertedLoopState.loopOutParameters!.length) {
|
||||
const outParams = convertedLoopState.loopOutParameters!;
|
||||
if (convertedLoopState.loopOutParameters.length) {
|
||||
const outParams = convertedLoopState.loopOutParameters;
|
||||
let expr: Expression | undefined;
|
||||
for (let i = 0; i < outParams.length; i++) {
|
||||
const copyExpr = copyOutParameter(outParams[i], CopyDirection.ToOutParameter);
|
||||
@@ -2610,7 +2620,40 @@ namespace ts {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function shouldConvertIterationStatementBody(node: IterationStatement): boolean {
|
||||
interface ForStatementWithConvertibleInitializer extends ForStatement {
|
||||
initializer: VariableDeclarationList;
|
||||
}
|
||||
|
||||
interface ForStatementWithConvertibleCondition extends ForStatement {
|
||||
condition: Expression;
|
||||
}
|
||||
|
||||
interface ForStatementWithConvertibleIncrementor extends ForStatement {
|
||||
incrementor: Expression;
|
||||
}
|
||||
|
||||
function shouldConvertPartOfIterationStatement(node: Node) {
|
||||
return (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ContainsCapturedBlockScopeBinding) !== 0;
|
||||
}
|
||||
|
||||
function shouldConvertInitializerOfForStatement(node: IterationStatement): node is ForStatementWithConvertibleInitializer {
|
||||
return isForStatement(node) && !!node.initializer && shouldConvertPartOfIterationStatement(node.initializer);
|
||||
}
|
||||
|
||||
function shouldConvertConditionOfForStatement(node: IterationStatement): node is ForStatementWithConvertibleCondition {
|
||||
return isForStatement(node) && !!node.condition && shouldConvertPartOfIterationStatement(node.condition);
|
||||
}
|
||||
|
||||
function shouldConvertIncrementorOfForStatement(node: IterationStatement): node is ForStatementWithConvertibleIncrementor {
|
||||
return isForStatement(node) && !!node.incrementor && shouldConvertPartOfIterationStatement(node.incrementor);
|
||||
}
|
||||
|
||||
function shouldConvertIterationStatement(node: IterationStatement) {
|
||||
return shouldConvertBodyOfIterationStatement(node)
|
||||
|| shouldConvertInitializerOfForStatement(node);
|
||||
}
|
||||
|
||||
function shouldConvertBodyOfIterationStatement(node: IterationStatement): boolean {
|
||||
return (resolver.getNodeCheckFlags(node) & NodeCheckFlags.LoopWithCapturedBlockScopedBinding) !== 0;
|
||||
}
|
||||
|
||||
@@ -2639,7 +2682,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function convertIterationStatementBodyIfNecessary(node: IterationStatement, outermostLabeledStatement: LabeledStatement | undefined, convert?: LoopConverter): VisitResult<Statement> {
|
||||
if (!shouldConvertIterationStatementBody(node)) {
|
||||
if (!shouldConvertIterationStatement(node)) {
|
||||
let saveAllowedNonLabeledJumps: Jump | undefined;
|
||||
if (convertedLoopState) {
|
||||
// we get here if we are trying to emit normal loop loop inside converted loop
|
||||
@@ -2658,7 +2701,102 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
const functionName = createUniqueName("_loop");
|
||||
const currentState = createConvertedLoopState(node);
|
||||
const statements: Statement[] = [];
|
||||
|
||||
const outerConvertedLoopState = convertedLoopState;
|
||||
convertedLoopState = currentState;
|
||||
|
||||
const initializerFunction = shouldConvertInitializerOfForStatement(node) ? createFunctionForInitializerOfForStatement(node, currentState) : undefined;
|
||||
const bodyFunction = shouldConvertBodyOfIterationStatement(node) ? createFunctionForBodyOfIterationStatement(node, currentState, outerConvertedLoopState) : undefined;
|
||||
|
||||
convertedLoopState = outerConvertedLoopState;
|
||||
|
||||
if (initializerFunction) statements.push(initializerFunction.functionDeclaration);
|
||||
if (bodyFunction) statements.push(bodyFunction.functionDeclaration);
|
||||
|
||||
addExtraDeclarationsForConvertedLoop(statements, currentState, outerConvertedLoopState);
|
||||
|
||||
if (initializerFunction) {
|
||||
statements.push(generateCallToConvertedLoopInitializer(initializerFunction.functionName, initializerFunction.containsYield));
|
||||
}
|
||||
|
||||
let loop: Statement;
|
||||
if (bodyFunction) {
|
||||
if (convert) {
|
||||
loop = convert(node, outermostLabeledStatement, bodyFunction.part);
|
||||
}
|
||||
else {
|
||||
const clone = convertIterationStatementCore(node, initializerFunction, createBlock(bodyFunction.part, /*multiLine*/ true));
|
||||
aggregateTransformFlags(clone);
|
||||
loop = restoreEnclosingLabel(clone, outermostLabeledStatement, convertedLoopState && resetLabel);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const clone = convertIterationStatementCore(node, initializerFunction, visitNode(node.statement, visitor, isStatement, liftToBlock));
|
||||
aggregateTransformFlags(clone);
|
||||
loop = restoreEnclosingLabel(clone, outermostLabeledStatement, convertedLoopState && resetLabel);
|
||||
}
|
||||
|
||||
statements.push(loop);
|
||||
return statements;
|
||||
}
|
||||
|
||||
function convertIterationStatementCore(node: IterationStatement, initializerFunction: IterationStatementPartFunction<VariableDeclarationList> | undefined, convertedLoopBody: Statement) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ForStatement: return convertForStatement(node as ForStatement, initializerFunction, convertedLoopBody);
|
||||
case SyntaxKind.ForInStatement: return convertForInStatement(node as ForInStatement, convertedLoopBody);
|
||||
case SyntaxKind.ForOfStatement: return convertForOfStatement(node as ForOfStatement, convertedLoopBody);
|
||||
case SyntaxKind.DoStatement: return convertDoStatement(node as DoStatement, convertedLoopBody);
|
||||
case SyntaxKind.WhileStatement: return convertWhileStatement(node as WhileStatement, convertedLoopBody);
|
||||
default: return Debug.failBadSyntaxKind(node, "IterationStatement expected");
|
||||
}
|
||||
}
|
||||
|
||||
function convertForStatement(node: ForStatement, initializerFunction: IterationStatementPartFunction<VariableDeclarationList> | undefined, convertedLoopBody: Statement) {
|
||||
const shouldConvertCondition = node.condition && shouldConvertPartOfIterationStatement(node.condition);
|
||||
const shouldConvertIncrementor = shouldConvertCondition || node.incrementor && shouldConvertPartOfIterationStatement(node.incrementor);
|
||||
return updateFor(
|
||||
node,
|
||||
visitNode(initializerFunction ? initializerFunction.part : node.initializer, visitor, isForInitializer),
|
||||
visitNode(shouldConvertCondition ? undefined : node.condition, visitor, isExpression),
|
||||
visitNode(shouldConvertIncrementor ? undefined : node.incrementor, visitor, isExpression),
|
||||
convertedLoopBody
|
||||
);
|
||||
}
|
||||
|
||||
function convertForOfStatement(node: ForOfStatement, convertedLoopBody: Statement) {
|
||||
return updateForOf(
|
||||
node,
|
||||
/*awaitModifier*/ undefined,
|
||||
visitNode(node.initializer, visitor, isForInitializer),
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
convertedLoopBody);
|
||||
}
|
||||
|
||||
function convertForInStatement(node: ForInStatement, convertedLoopBody: Statement) {
|
||||
return updateForIn(
|
||||
node,
|
||||
visitNode(node.initializer, visitor, isForInitializer),
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
convertedLoopBody);
|
||||
}
|
||||
|
||||
function convertDoStatement(node: DoStatement, convertedLoopBody: Statement) {
|
||||
return updateDo(
|
||||
node,
|
||||
convertedLoopBody,
|
||||
visitNode(node.expression, visitor, isExpression));
|
||||
}
|
||||
|
||||
function convertWhileStatement(node: WhileStatement, convertedLoopBody: Statement) {
|
||||
return updateWhile(
|
||||
node,
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
convertedLoopBody);
|
||||
}
|
||||
|
||||
function createConvertedLoopState(node: IterationStatement) {
|
||||
let loopInitializer: VariableDeclarationList | undefined;
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ForStatement:
|
||||
@@ -2670,74 +2808,311 @@ namespace ts {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// variables that will be passed to the loop as parameters
|
||||
const loopParameters: ParameterDeclaration[] = [];
|
||||
// variables declared in the loop initializer that will be changed inside the loop
|
||||
const loopOutParameters: LoopOutParameter[] = [];
|
||||
if (loopInitializer && (getCombinedNodeFlags(loopInitializer) & NodeFlags.BlockScoped)) {
|
||||
const hasCapturedBindingsInForInitializer = shouldConvertInitializerOfForStatement(node);
|
||||
for (const decl of loopInitializer.declarations) {
|
||||
processLoopVariableDeclaration(decl, loopParameters, loopOutParameters);
|
||||
processLoopVariableDeclaration(node, decl, loopParameters, loopOutParameters, hasCapturedBindingsInForInitializer);
|
||||
}
|
||||
}
|
||||
|
||||
const outerConvertedLoopState = convertedLoopState;
|
||||
convertedLoopState = { loopOutParameters };
|
||||
if (outerConvertedLoopState) {
|
||||
const currentState: ConvertedLoopState = { loopParameters, loopOutParameters };
|
||||
if (convertedLoopState) {
|
||||
// convertedOuterLoopState !== undefined means that this converted loop is nested in another converted loop.
|
||||
// if outer converted loop has already accumulated some state - pass it through
|
||||
if (outerConvertedLoopState.argumentsName) {
|
||||
if (convertedLoopState.argumentsName) {
|
||||
// outer loop has already used 'arguments' so we've already have some name to alias it
|
||||
// use the same name in all nested loops
|
||||
convertedLoopState.argumentsName = outerConvertedLoopState.argumentsName;
|
||||
currentState.argumentsName = convertedLoopState.argumentsName;
|
||||
}
|
||||
if (outerConvertedLoopState.thisName) {
|
||||
if (convertedLoopState.thisName) {
|
||||
// outer loop has already used 'this' so we've already have some name to alias it
|
||||
// use the same name in all nested loops
|
||||
convertedLoopState.thisName = outerConvertedLoopState.thisName;
|
||||
currentState.thisName = convertedLoopState.thisName;
|
||||
}
|
||||
if (outerConvertedLoopState.hoistedLocalVariables) {
|
||||
if (convertedLoopState.hoistedLocalVariables) {
|
||||
// we've already collected some non-block scoped variable declarations in enclosing loop
|
||||
// use the same storage in nested loop
|
||||
convertedLoopState.hoistedLocalVariables = outerConvertedLoopState.hoistedLocalVariables;
|
||||
currentState.hoistedLocalVariables = convertedLoopState.hoistedLocalVariables;
|
||||
}
|
||||
}
|
||||
return currentState;
|
||||
}
|
||||
|
||||
function addExtraDeclarationsForConvertedLoop(statements: Statement[], state: ConvertedLoopState, outerState: ConvertedLoopState | undefined) {
|
||||
let extraVariableDeclarations: VariableDeclaration[] | undefined;
|
||||
// propagate state from the inner loop to the outer loop if necessary
|
||||
if (state.argumentsName) {
|
||||
// if alias for arguments is set
|
||||
if (outerState) {
|
||||
// pass it to outer converted loop
|
||||
outerState.argumentsName = state.argumentsName;
|
||||
}
|
||||
else {
|
||||
// this is top level converted loop and we need to create an alias for 'arguments' object
|
||||
(extraVariableDeclarations || (extraVariableDeclarations = [])).push(
|
||||
createVariableDeclaration(
|
||||
state.argumentsName,
|
||||
/*type*/ undefined,
|
||||
createIdentifier("arguments")
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (state.thisName) {
|
||||
// if alias for this is set
|
||||
if (outerState) {
|
||||
// pass it to outer converted loop
|
||||
outerState.thisName = state.thisName;
|
||||
}
|
||||
else {
|
||||
// this is top level converted loop so we need to create an alias for 'this' here
|
||||
// NOTE:
|
||||
// if converted loops were all nested in arrow function then we'll always emit '_this' so convertedLoopState.thisName will not be set.
|
||||
// If it is set this means that all nested loops are not nested in arrow function and it is safe to capture 'this'.
|
||||
(extraVariableDeclarations || (extraVariableDeclarations = [])).push(
|
||||
createVariableDeclaration(
|
||||
state.thisName,
|
||||
/*type*/ undefined,
|
||||
createIdentifier("this")
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (state.hoistedLocalVariables) {
|
||||
// if hoistedLocalVariables !== undefined this means that we've possibly collected some variable declarations to be hoisted later
|
||||
if (outerState) {
|
||||
// pass them to outer converted loop
|
||||
outerState.hoistedLocalVariables = state.hoistedLocalVariables;
|
||||
}
|
||||
else {
|
||||
if (!extraVariableDeclarations) {
|
||||
extraVariableDeclarations = [];
|
||||
}
|
||||
// hoist collected variable declarations
|
||||
for (const identifier of state.hoistedLocalVariables) {
|
||||
extraVariableDeclarations.push(createVariableDeclaration(identifier));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add extra variables to hold out parameters if necessary
|
||||
if (state.loopOutParameters.length) {
|
||||
if (!extraVariableDeclarations) {
|
||||
extraVariableDeclarations = [];
|
||||
}
|
||||
for (const outParam of state.loopOutParameters) {
|
||||
extraVariableDeclarations.push(createVariableDeclaration(outParam.outParamName));
|
||||
}
|
||||
}
|
||||
|
||||
if (state.conditionVariable) {
|
||||
if (!extraVariableDeclarations) {
|
||||
extraVariableDeclarations = [];
|
||||
}
|
||||
extraVariableDeclarations.push(createVariableDeclaration(state.conditionVariable, /*type*/ undefined, createFalse()));
|
||||
}
|
||||
|
||||
// create variable statement to hold all introduced variable declarations
|
||||
if (extraVariableDeclarations) {
|
||||
statements.push(createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList(extraVariableDeclarations)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
interface IterationStatementPartFunction<T> {
|
||||
functionName: Identifier;
|
||||
functionDeclaration: Statement;
|
||||
containsYield: boolean;
|
||||
part: T;
|
||||
}
|
||||
|
||||
function createOutVariable(p: LoopOutParameter) {
|
||||
return createVariableDeclaration(p.originalName, /*type*/ undefined, p.outParamName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a `_loop_init` function for a `ForStatement` with a block-scoped initializer
|
||||
* that is captured in a closure inside of the initializer. The `_loop_init` function is
|
||||
* used to preserve the per-iteration environment semantics of
|
||||
* [13.7.4.8 RS: ForBodyEvaluation](https://tc39.github.io/ecma262/#sec-forbodyevaluation).
|
||||
*/
|
||||
function createFunctionForInitializerOfForStatement(node: ForStatementWithConvertibleInitializer, currentState: ConvertedLoopState): IterationStatementPartFunction<VariableDeclarationList> {
|
||||
const functionName = createUniqueName("_loop_init");
|
||||
|
||||
const containsYield = (node.initializer.transformFlags & TransformFlags.ContainsYield) !== 0;
|
||||
let emitFlags = EmitFlags.None;
|
||||
if (currentState.containsLexicalThis) emitFlags |= EmitFlags.CapturesThis;
|
||||
if (containsYield && hierarchyFacts & HierarchyFacts.AsyncFunctionBody) emitFlags |= EmitFlags.AsyncFunctionBody;
|
||||
|
||||
const statements: Statement[] = [];
|
||||
statements.push(createVariableStatement(/*modifiers*/ undefined, node.initializer));
|
||||
copyOutParameters(currentState.loopOutParameters, LoopOutParameterFlags.Initializer, CopyDirection.ToOutParameter, statements);
|
||||
|
||||
// This transforms the following ES2015 syntax:
|
||||
//
|
||||
// for (let i = (setImmediate(() => console.log(i)), 0); i < 2; i++) {
|
||||
// // loop body
|
||||
// }
|
||||
//
|
||||
// Into the following ES5 syntax:
|
||||
//
|
||||
// var _loop_init_1 = function () {
|
||||
// var i = (setImmediate(() => console.log(i)), 0);
|
||||
// out_i_1 = i;
|
||||
// };
|
||||
// var out_i_1;
|
||||
// _loop_init_1();
|
||||
// for (var i = out_i_1; i < 2; i++) {
|
||||
// // loop body
|
||||
// }
|
||||
//
|
||||
// Which prevents mutations to `i` in the per-iteration environment of the body
|
||||
// from affecting the initial value for `i` outside of the per-iteration environment.
|
||||
|
||||
const functionDeclaration = createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
setEmitFlags(
|
||||
createVariableDeclarationList([
|
||||
createVariableDeclaration(
|
||||
functionName,
|
||||
/*type*/ undefined,
|
||||
setEmitFlags(
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
containsYield ? createToken(SyntaxKind.AsteriskToken) : undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
/*parameters*/ undefined,
|
||||
/*type*/ undefined,
|
||||
visitNode(
|
||||
createBlock(statements, /*multiLine*/ true),
|
||||
visitor,
|
||||
isBlock
|
||||
)
|
||||
),
|
||||
emitFlags
|
||||
)
|
||||
)
|
||||
]),
|
||||
EmitFlags.NoHoisting
|
||||
)
|
||||
);
|
||||
|
||||
const part = createVariableDeclarationList(map(currentState.loopOutParameters, createOutVariable));
|
||||
return { functionName, containsYield, functionDeclaration, part };
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a `_loop` function for an `IterationStatement` with a block-scoped initializer
|
||||
* that is captured in a closure inside of the loop body. The `_loop` function is used to
|
||||
* preserve the per-iteration environment semantics of
|
||||
* [13.7.4.8 RS: ForBodyEvaluation](https://tc39.github.io/ecma262/#sec-forbodyevaluation).
|
||||
*/
|
||||
function createFunctionForBodyOfIterationStatement(node: IterationStatement, currentState: ConvertedLoopState, outerState: ConvertedLoopState | undefined): IterationStatementPartFunction<Statement[]> {
|
||||
const functionName = createUniqueName("_loop");
|
||||
startLexicalEnvironment();
|
||||
let loopBody = visitNode(node.statement, visitor, isStatement, liftToBlock);
|
||||
const statement = visitNode(node.statement, visitor, isStatement, liftToBlock);
|
||||
const lexicalEnvironment = endLexicalEnvironment();
|
||||
|
||||
const currentState = convertedLoopState;
|
||||
convertedLoopState = outerConvertedLoopState;
|
||||
const statements: Statement[] = [];
|
||||
if (shouldConvertConditionOfForStatement(node) || shouldConvertIncrementorOfForStatement(node)) {
|
||||
// If a block-scoped variable declared in the initializer of `node` is captured in
|
||||
// the condition or incrementor, we must move the condition and incrementor into
|
||||
// the body of the for loop.
|
||||
//
|
||||
// This transforms the following ES2015 syntax:
|
||||
//
|
||||
// for (let i = 0; setImmediate(() => console.log(i)), i < 2; setImmediate(() => console.log(i)), i++) {
|
||||
// // loop body
|
||||
// }
|
||||
//
|
||||
// Into the following ES5 syntax:
|
||||
//
|
||||
// var _loop_1 = function (i) {
|
||||
// if (inc_1)
|
||||
// setImmediate(() => console.log(i)), i++;
|
||||
// else
|
||||
// inc_1 = true;
|
||||
// if (!(setImmediate(() => console.log(i)), i < 2))
|
||||
// return out_i_1 = i, "break";
|
||||
// // loop body
|
||||
// out_i_1 = i;
|
||||
// }
|
||||
// var out_i_1, inc_1 = false;
|
||||
// for (var i = 0;;) {
|
||||
// var state_1 = _loop_1(i);
|
||||
// i = out_i_1;
|
||||
// if (state_1 === "break")
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// Which prevents mutations to `i` in the per-iteration environment of the body
|
||||
// from affecting the value of `i` in the previous per-iteration environment.
|
||||
//
|
||||
// Note that the incrementor of a `for` loop is evaluated in a *new* per-iteration
|
||||
// environment that is carried over to the next iteration of the loop. As a result,
|
||||
// we must indicate whether this is the first evaluation of the loop body so that
|
||||
// we only evaluate the incrementor on subsequent evaluations.
|
||||
|
||||
if (loopOutParameters.length || lexicalEnvironment) {
|
||||
const statements = isBlock(loopBody) ? loopBody.statements.slice() : [loopBody];
|
||||
if (loopOutParameters.length) {
|
||||
copyOutParameters(loopOutParameters, CopyDirection.ToOutParameter, statements);
|
||||
currentState.conditionVariable = createUniqueName("inc");
|
||||
statements.push(createIf(
|
||||
currentState.conditionVariable,
|
||||
createStatement(visitNode(node.incrementor, visitor, isExpression)),
|
||||
createStatement(createAssignment(currentState.conditionVariable, createTrue()))
|
||||
));
|
||||
|
||||
if (shouldConvertConditionOfForStatement(node)) {
|
||||
statements.push(createIf(
|
||||
createPrefix(SyntaxKind.ExclamationToken, visitNode(node.condition, visitor, isExpression)),
|
||||
visitNode(createBreak(), visitor, isStatement)
|
||||
));
|
||||
}
|
||||
addStatementsAfterPrologue(statements, lexicalEnvironment);
|
||||
loopBody = createBlock(statements, /*multiline*/ true);
|
||||
}
|
||||
|
||||
if (isBlock(loopBody)) {
|
||||
loopBody.multiLine = true;
|
||||
if (isBlock(statement)) {
|
||||
addRange(statements, statement.statements);
|
||||
}
|
||||
else {
|
||||
loopBody = createBlock([loopBody], /*multiline*/ true);
|
||||
statements.push(statement);
|
||||
}
|
||||
|
||||
copyOutParameters(currentState.loopOutParameters, LoopOutParameterFlags.Body, CopyDirection.ToOutParameter, statements);
|
||||
addStatementsAfterPrologue(statements, lexicalEnvironment);
|
||||
|
||||
const loopBody = createBlock(statements, /*multiLine*/ true);
|
||||
if (isBlock(statement)) setOriginalNode(loopBody, statement);
|
||||
|
||||
const containsYield = (node.statement.transformFlags & TransformFlags.ContainsYield) !== 0;
|
||||
const isAsyncBlockContainingAwait = containsYield && (hierarchyFacts & HierarchyFacts.AsyncFunctionBody) !== 0;
|
||||
|
||||
let loopBodyFlags: EmitFlags = 0;
|
||||
if (currentState.containsLexicalThis) {
|
||||
loopBodyFlags |= EmitFlags.CapturesThis;
|
||||
}
|
||||
let emitFlags: EmitFlags = 0;
|
||||
if (currentState.containsLexicalThis) emitFlags |= EmitFlags.CapturesThis;
|
||||
if (containsYield && (hierarchyFacts & HierarchyFacts.AsyncFunctionBody) !== 0) emitFlags |= EmitFlags.AsyncFunctionBody;
|
||||
|
||||
if (isAsyncBlockContainingAwait) {
|
||||
loopBodyFlags |= EmitFlags.AsyncFunctionBody;
|
||||
}
|
||||
// This transforms the following ES2015 syntax (in addition to other variations):
|
||||
//
|
||||
// for (let i = 0; i < 2; i++) {
|
||||
// setImmediate(() => console.log(i));
|
||||
// }
|
||||
//
|
||||
// Into the following ES5 syntax:
|
||||
//
|
||||
// var _loop_1 = function (i) {
|
||||
// setImmediate(() => console.log(i));
|
||||
// };
|
||||
// for (var i = 0; i < 2; i++) {
|
||||
// _loop_1(i);
|
||||
// }
|
||||
|
||||
const convertedLoopVariable =
|
||||
const functionDeclaration =
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
setEmitFlags(
|
||||
@@ -2752,11 +3127,11 @@ namespace ts {
|
||||
containsYield ? createToken(SyntaxKind.AsteriskToken) : undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
loopParameters,
|
||||
currentState.loopParameters,
|
||||
/*type*/ undefined,
|
||||
<Block>loopBody
|
||||
loopBody
|
||||
),
|
||||
loopBodyFlags
|
||||
emitFlags
|
||||
)
|
||||
)
|
||||
]
|
||||
@@ -2765,106 +3140,8 @@ namespace ts {
|
||||
)
|
||||
);
|
||||
|
||||
const statements: Statement[] = [convertedLoopVariable];
|
||||
|
||||
let extraVariableDeclarations: VariableDeclaration[] | undefined;
|
||||
// propagate state from the inner loop to the outer loop if necessary
|
||||
if (currentState.argumentsName) {
|
||||
// if alias for arguments is set
|
||||
if (outerConvertedLoopState) {
|
||||
// pass it to outer converted loop
|
||||
outerConvertedLoopState.argumentsName = currentState.argumentsName;
|
||||
}
|
||||
else {
|
||||
// this is top level converted loop and we need to create an alias for 'arguments' object
|
||||
(extraVariableDeclarations || (extraVariableDeclarations = [])).push(
|
||||
createVariableDeclaration(
|
||||
currentState.argumentsName,
|
||||
/*type*/ undefined,
|
||||
createIdentifier("arguments")
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (currentState.thisName) {
|
||||
// if alias for this is set
|
||||
if (outerConvertedLoopState) {
|
||||
// pass it to outer converted loop
|
||||
outerConvertedLoopState.thisName = currentState.thisName;
|
||||
}
|
||||
else {
|
||||
// this is top level converted loop so we need to create an alias for 'this' here
|
||||
// NOTE:
|
||||
// if converted loops were all nested in arrow function then we'll always emit '_this' so convertedLoopState.thisName will not be set.
|
||||
// If it is set this means that all nested loops are not nested in arrow function and it is safe to capture 'this'.
|
||||
(extraVariableDeclarations || (extraVariableDeclarations = [])).push(
|
||||
createVariableDeclaration(
|
||||
currentState.thisName,
|
||||
/*type*/ undefined,
|
||||
createIdentifier("this")
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (currentState.hoistedLocalVariables) {
|
||||
// if hoistedLocalVariables !== undefined this means that we've possibly collected some variable declarations to be hoisted later
|
||||
if (outerConvertedLoopState) {
|
||||
// pass them to outer converted loop
|
||||
outerConvertedLoopState.hoistedLocalVariables = currentState.hoistedLocalVariables;
|
||||
}
|
||||
else {
|
||||
if (!extraVariableDeclarations) {
|
||||
extraVariableDeclarations = [];
|
||||
}
|
||||
// hoist collected variable declarations
|
||||
for (const identifier of currentState.hoistedLocalVariables) {
|
||||
extraVariableDeclarations.push(createVariableDeclaration(identifier));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add extra variables to hold out parameters if necessary
|
||||
if (loopOutParameters.length) {
|
||||
if (!extraVariableDeclarations) {
|
||||
extraVariableDeclarations = [];
|
||||
}
|
||||
for (const outParam of loopOutParameters) {
|
||||
extraVariableDeclarations.push(createVariableDeclaration(outParam.outParamName));
|
||||
}
|
||||
}
|
||||
|
||||
// create variable statement to hold all introduced variable declarations
|
||||
if (extraVariableDeclarations) {
|
||||
statements.push(createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList(extraVariableDeclarations)
|
||||
));
|
||||
}
|
||||
|
||||
const convertedLoopBodyStatements = generateCallToConvertedLoop(functionName, loopParameters, currentState, containsYield);
|
||||
|
||||
let loop: Statement;
|
||||
if (convert) {
|
||||
loop = convert(node, outermostLabeledStatement, convertedLoopBodyStatements);
|
||||
}
|
||||
else {
|
||||
let clone = getMutableClone(node);
|
||||
// clean statement part
|
||||
clone.statement = undefined!;
|
||||
// visit childnodes to transform initializer/condition/incrementor parts
|
||||
clone = visitEachChild(clone, visitor, context);
|
||||
// set loop statement
|
||||
clone.statement = createBlock(convertedLoopBodyStatements, /*multiline*/ true);
|
||||
// reset and re-aggregate the transform flags
|
||||
clone.transformFlags = 0;
|
||||
aggregateTransformFlags(clone);
|
||||
loop = restoreEnclosingLabel(clone, outermostLabeledStatement, convertedLoopState && resetLabel);
|
||||
}
|
||||
|
||||
statements.push(loop);
|
||||
return statements;
|
||||
const part = generateCallToConvertedLoop(functionName, currentState, outerState, containsYield);
|
||||
return { functionName, containsYield, functionDeclaration, part };
|
||||
}
|
||||
|
||||
function copyOutParameter(outParam: LoopOutParameter, copyDirection: CopyDirection): BinaryExpression {
|
||||
@@ -2873,14 +3150,26 @@ namespace ts {
|
||||
return createBinary(target, SyntaxKind.EqualsToken, source);
|
||||
}
|
||||
|
||||
function copyOutParameters(outParams: LoopOutParameter[], copyDirection: CopyDirection, statements: Statement[]): void {
|
||||
function copyOutParameters(outParams: LoopOutParameter[], partFlags: LoopOutParameterFlags, copyDirection: CopyDirection, statements: Statement[]): void {
|
||||
for (const outParam of outParams) {
|
||||
statements.push(createExpressionStatement(copyOutParameter(outParam, copyDirection)));
|
||||
if (outParam.flags & partFlags) {
|
||||
statements.push(createExpressionStatement(copyOutParameter(outParam, copyDirection)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function generateCallToConvertedLoop(loopFunctionExpressionName: Identifier, parameters: ParameterDeclaration[], state: ConvertedLoopState, isAsyncBlockContainingAwait: boolean): Statement[] {
|
||||
const outerConvertedLoopState = convertedLoopState;
|
||||
function generateCallToConvertedLoopInitializer(initFunctionExpressionName: Identifier, containsYield: boolean): Statement {
|
||||
const call = createCall(initFunctionExpressionName, /*typeArguments*/ undefined, []);
|
||||
const callResult = containsYield
|
||||
? createYield(
|
||||
createToken(SyntaxKind.AsteriskToken),
|
||||
setEmitFlags(call, EmitFlags.Iterator)
|
||||
)
|
||||
: call;
|
||||
return createStatement(callResult);
|
||||
}
|
||||
|
||||
function generateCallToConvertedLoop(loopFunctionExpressionName: Identifier, state: ConvertedLoopState, outerState: ConvertedLoopState | undefined, containsYield: boolean): Statement[] {
|
||||
|
||||
const statements: Statement[] = [];
|
||||
// loop is considered simple if it does not have any return statements or break\continue that transfer control outside of the loop
|
||||
@@ -2891,8 +3180,8 @@ namespace ts {
|
||||
!state.labeledNonLocalBreaks &&
|
||||
!state.labeledNonLocalContinues;
|
||||
|
||||
const call = createCall(loopFunctionExpressionName, /*typeArguments*/ undefined, map(parameters, p => <Identifier>p.name));
|
||||
const callResult = isAsyncBlockContainingAwait
|
||||
const call = createCall(loopFunctionExpressionName, /*typeArguments*/ undefined, map(state.loopParameters, p => <Identifier>p.name));
|
||||
const callResult = containsYield
|
||||
? createYield(
|
||||
createToken(SyntaxKind.AsteriskToken),
|
||||
setEmitFlags(call, EmitFlags.Iterator)
|
||||
@@ -2900,7 +3189,7 @@ namespace ts {
|
||||
: call;
|
||||
if (isSimpleLoop) {
|
||||
statements.push(createExpressionStatement(callResult));
|
||||
copyOutParameters(state.loopOutParameters!, CopyDirection.ToOriginal, statements);
|
||||
copyOutParameters(state.loopOutParameters, LoopOutParameterFlags.Body, CopyDirection.ToOriginal, statements);
|
||||
}
|
||||
else {
|
||||
const loopResultName = createUniqueName("state");
|
||||
@@ -2911,12 +3200,12 @@ namespace ts {
|
||||
)
|
||||
);
|
||||
statements.push(stateVariable);
|
||||
copyOutParameters(state.loopOutParameters!, CopyDirection.ToOriginal, statements);
|
||||
copyOutParameters(state.loopOutParameters, LoopOutParameterFlags.Body, CopyDirection.ToOriginal, statements);
|
||||
|
||||
if (state.nonLocalJumps! & Jump.Return) {
|
||||
let returnStatement: ReturnStatement;
|
||||
if (outerConvertedLoopState) {
|
||||
outerConvertedLoopState.nonLocalJumps! |= Jump.Return;
|
||||
if (outerState) {
|
||||
outerState.nonLocalJumps! |= Jump.Return;
|
||||
returnStatement = createReturn(loopResultName);
|
||||
}
|
||||
else {
|
||||
@@ -2949,8 +3238,8 @@ namespace ts {
|
||||
|
||||
if (state.labeledNonLocalBreaks || state.labeledNonLocalContinues) {
|
||||
const caseClauses: CaseClause[] = [];
|
||||
processLabeledJumps(state.labeledNonLocalBreaks!, /*isBreak*/ true, loopResultName, outerConvertedLoopState, caseClauses);
|
||||
processLabeledJumps(state.labeledNonLocalContinues!, /*isBreak*/ false, loopResultName, outerConvertedLoopState, caseClauses);
|
||||
processLabeledJumps(state.labeledNonLocalBreaks!, /*isBreak*/ true, loopResultName, outerState, caseClauses);
|
||||
processLabeledJumps(state.labeledNonLocalContinues!, /*isBreak*/ false, loopResultName, outerState, caseClauses);
|
||||
statements.push(
|
||||
createSwitch(
|
||||
loopResultName,
|
||||
@@ -2998,20 +3287,28 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
|
||||
function processLoopVariableDeclaration(decl: VariableDeclaration | BindingElement, loopParameters: ParameterDeclaration[], loopOutParameters: LoopOutParameter[]) {
|
||||
function processLoopVariableDeclaration(container: IterationStatement, decl: VariableDeclaration | BindingElement, loopParameters: ParameterDeclaration[], loopOutParameters: LoopOutParameter[], hasCapturedBindingsInForInitializer: boolean) {
|
||||
const name = decl.name;
|
||||
if (isBindingPattern(name)) {
|
||||
for (const element of name.elements) {
|
||||
if (!isOmittedExpression(element)) {
|
||||
processLoopVariableDeclaration(element, loopParameters, loopOutParameters);
|
||||
processLoopVariableDeclaration(container, element, loopParameters, loopOutParameters, hasCapturedBindingsInForInitializer);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
loopParameters.push(createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, name));
|
||||
if (resolver.getNodeCheckFlags(decl) & NodeCheckFlags.NeedsLoopOutParameter) {
|
||||
const checkFlags = resolver.getNodeCheckFlags(decl);
|
||||
if (checkFlags & NodeCheckFlags.NeedsLoopOutParameter || hasCapturedBindingsInForInitializer) {
|
||||
const outParamName = createUniqueName("out_" + idText(name));
|
||||
loopOutParameters.push({ originalName: name, outParamName });
|
||||
let flags: LoopOutParameterFlags = 0;
|
||||
if (checkFlags & NodeCheckFlags.NeedsLoopOutParameter) {
|
||||
flags |= LoopOutParameterFlags.Body;
|
||||
}
|
||||
if (isForStatement(container) && container.initializer && resolver.isBindingCapturedByNode(container.initializer, decl)) {
|
||||
flags |= LoopOutParameterFlags.Initializer;
|
||||
}
|
||||
loopOutParameters.push({ flags, originalName: name, outParamName });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,7 +248,7 @@ namespace ts {
|
||||
return getOrCreateValueFromConfigFileMap<Map<T>>(configFileMap, resolved, createMap);
|
||||
}
|
||||
|
||||
function getOutputDeclarationFileName(inputFileName: string, configFile: ParsedCommandLine) {
|
||||
export function getOutputDeclarationFileName(inputFileName: string, configFile: ParsedCommandLine) {
|
||||
const relativePath = getRelativePathFromDirectory(rootDirOfOptions(configFile.options, configFile.options.configFilePath!), inputFileName, /*ignoreCase*/ true);
|
||||
const outputPath = resolvePath(configFile.options.declarationDir || configFile.options.outDir || getDirectoryPath(configFile.options.configFilePath!), relativePath);
|
||||
return changeExtension(outputPath, Extension.Dts);
|
||||
|
||||
+28
-18
@@ -1708,7 +1708,7 @@ namespace ts {
|
||||
|
||||
export interface ExpressionWithTypeArguments extends NodeWithTypeArguments {
|
||||
kind: SyntaxKind.ExpressionWithTypeArguments;
|
||||
parent: HeritageClause;
|
||||
parent: HeritageClause | JSDocAugmentsTag;
|
||||
expression: LeftHandSideExpression;
|
||||
}
|
||||
|
||||
@@ -2557,6 +2557,12 @@ namespace ts {
|
||||
* path = input file's path
|
||||
*/
|
||||
/* @internal */ resolvedPath: Path;
|
||||
/** Original file name that can be different from fileName,
|
||||
* when file is included through project reference is mapped to its output instead of source
|
||||
* in that case originalFileName = name of input file
|
||||
* fileName = output file's name
|
||||
*/
|
||||
/* @internal */ originalFileName: string;
|
||||
|
||||
/**
|
||||
* If two source files are for the same version of the same package, one will redirect to the other.
|
||||
@@ -3414,6 +3420,7 @@ namespace ts {
|
||||
getJsxFactoryEntity(location?: Node): EntityName | undefined;
|
||||
getAllAccessorDeclarations(declaration: AccessorDeclaration): AllAccessorDeclarations;
|
||||
getSymbolOfExternalModuleSpecifier(node: StringLiteralLike): Symbol | undefined;
|
||||
isBindingCapturedByNode(node: Node, decl: VariableDeclaration | BindingElement): boolean;
|
||||
}
|
||||
|
||||
export const enum SymbolFlags {
|
||||
@@ -3662,14 +3669,15 @@ namespace ts {
|
||||
EnumValuesComputed = 0x00004000, // Values for enum members have been computed, and any errors have been reported for them.
|
||||
LexicalModuleMergesWithClass = 0x00008000, // Instantiated lexical module declaration is merged with a previous class declaration.
|
||||
LoopWithCapturedBlockScopedBinding = 0x00010000, // Loop that contains block scoped variable captured in closure
|
||||
CapturedBlockScopedBinding = 0x00020000, // Block-scoped binding that is captured in some function
|
||||
BlockScopedBindingInLoop = 0x00040000, // Block-scoped binding with declaration nested inside iteration statement
|
||||
ClassWithBodyScopedClassBinding = 0x00080000, // Decorated class that contains a binding to itself inside of the class body.
|
||||
BodyScopedClassBinding = 0x00100000, // Binding to a decorated class inside of the class's body.
|
||||
NeedsLoopOutParameter = 0x00200000, // Block scoped binding whose value should be explicitly copied outside of the converted loop
|
||||
AssignmentsMarked = 0x00400000, // Parameter assignments have been marked
|
||||
ClassWithConstructorReference = 0x00800000, // Class that contains a binding to its constructor inside of the class body.
|
||||
ConstructorReferenceInClass = 0x01000000, // Binding to a class constructor inside of the class's body.
|
||||
ContainsCapturedBlockScopeBinding = 0x00020000, // Part of a loop that contains block scoped variable captured in closure
|
||||
CapturedBlockScopedBinding = 0x00040000, // Block-scoped binding that is captured in some function
|
||||
BlockScopedBindingInLoop = 0x00080000, // Block-scoped binding with declaration nested inside iteration statement
|
||||
ClassWithBodyScopedClassBinding = 0x00100000, // Decorated class that contains a binding to itself inside of the class body.
|
||||
BodyScopedClassBinding = 0x00200000, // Binding to a decorated class inside of the class's body.
|
||||
NeedsLoopOutParameter = 0x00400000, // Block scoped binding whose value should be explicitly copied outside of the converted loop
|
||||
AssignmentsMarked = 0x00800000, // Parameter assignments have been marked
|
||||
ClassWithConstructorReference = 0x01000000, // Class that contains a binding to its constructor inside of the class body.
|
||||
ConstructorReferenceInClass = 0x02000000, // Binding to a class constructor inside of the class's body.
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -3694,6 +3702,7 @@ namespace ts {
|
||||
switchTypes?: Type[]; // Cached array of switch case expression types
|
||||
jsxNamespace?: Symbol | false; // Resolved jsx namespace symbol for this node
|
||||
contextFreeType?: Type; // Cached context-free type used by the first pass of inference; used when a function's return is partially contextually sensitive
|
||||
capturedBlockScopeBindings?: Symbol[]; // Block-scoped bindings captured beneath this part of an IterationStatement
|
||||
}
|
||||
|
||||
export const enum TypeFlags {
|
||||
@@ -4421,6 +4430,7 @@ namespace ts {
|
||||
sourceRoot?: string;
|
||||
strict?: boolean;
|
||||
strictFunctionTypes?: boolean; // Always combine with strict property
|
||||
strictBindCallApply?: boolean; // Always combine with strict property
|
||||
strictNullChecks?: boolean; // Always combine with strict property
|
||||
strictPropertyInitialization?: boolean; // Always combine with strict property
|
||||
stripInternal?: boolean;
|
||||
@@ -5606,15 +5616,15 @@ namespace ts {
|
||||
type ConcretePragmaSpecs = typeof commentPragmas;
|
||||
|
||||
/* @internal */
|
||||
export type PragmaPsuedoMap = {[K in keyof ConcretePragmaSpecs]?: {arguments: PragmaArgumentType<ConcretePragmaSpecs[K]>, range: CommentRange}};
|
||||
export type PragmaPseudoMap = {[K in keyof ConcretePragmaSpecs]?: {arguments: PragmaArgumentType<ConcretePragmaSpecs[K]>, range: CommentRange}};
|
||||
|
||||
/* @internal */
|
||||
export type PragmaPsuedoMapEntry = {[K in keyof PragmaPsuedoMap]: {name: K, args: PragmaPsuedoMap[K]}}[keyof PragmaPsuedoMap];
|
||||
export type PragmaPseudoMapEntry = {[K in keyof PragmaPseudoMap]: {name: K, args: PragmaPseudoMap[K]}}[keyof PragmaPseudoMap];
|
||||
|
||||
/* @internal */
|
||||
export interface ReadonlyPragmaMap extends ReadonlyMap<PragmaPsuedoMap[keyof PragmaPsuedoMap] | PragmaPsuedoMap[keyof PragmaPsuedoMap][]> {
|
||||
get<TKey extends keyof PragmaPsuedoMap>(key: TKey): PragmaPsuedoMap[TKey] | PragmaPsuedoMap[TKey][];
|
||||
forEach(action: <TKey extends keyof PragmaPsuedoMap>(value: PragmaPsuedoMap[TKey] | PragmaPsuedoMap[TKey][], key: TKey) => void): void;
|
||||
export interface ReadonlyPragmaMap extends ReadonlyMap<PragmaPseudoMap[keyof PragmaPseudoMap] | PragmaPseudoMap[keyof PragmaPseudoMap][]> {
|
||||
get<TKey extends keyof PragmaPseudoMap>(key: TKey): PragmaPseudoMap[TKey] | PragmaPseudoMap[TKey][];
|
||||
forEach(action: <TKey extends keyof PragmaPseudoMap>(value: PragmaPseudoMap[TKey] | PragmaPseudoMap[TKey][], key: TKey) => void): void;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5623,10 +5633,10 @@ namespace ts {
|
||||
* in multiple places
|
||||
*/
|
||||
/* @internal */
|
||||
export interface PragmaMap extends Map<PragmaPsuedoMap[keyof PragmaPsuedoMap] | PragmaPsuedoMap[keyof PragmaPsuedoMap][]>, ReadonlyPragmaMap {
|
||||
set<TKey extends keyof PragmaPsuedoMap>(key: TKey, value: PragmaPsuedoMap[TKey] | PragmaPsuedoMap[TKey][]): this;
|
||||
get<TKey extends keyof PragmaPsuedoMap>(key: TKey): PragmaPsuedoMap[TKey] | PragmaPsuedoMap[TKey][];
|
||||
forEach(action: <TKey extends keyof PragmaPsuedoMap>(value: PragmaPsuedoMap[TKey] | PragmaPsuedoMap[TKey][], key: TKey) => void): void;
|
||||
export interface PragmaMap extends Map<PragmaPseudoMap[keyof PragmaPseudoMap] | PragmaPseudoMap[keyof PragmaPseudoMap][]>, ReadonlyPragmaMap {
|
||||
set<TKey extends keyof PragmaPseudoMap>(key: TKey, value: PragmaPseudoMap[TKey] | PragmaPseudoMap[TKey][]): this;
|
||||
get<TKey extends keyof PragmaPseudoMap>(key: TKey): PragmaPseudoMap[TKey] | PragmaPseudoMap[TKey][];
|
||||
forEach(action: <TKey extends keyof PragmaPseudoMap>(value: PragmaPseudoMap[TKey] | PragmaPseudoMap[TKey][], key: TKey) => void): void;
|
||||
}
|
||||
|
||||
export interface UserPreferences {
|
||||
|
||||
+15
-15
@@ -3734,11 +3734,20 @@ namespace ts {
|
||||
|
||||
/** Get `C` given `N` if `N` is in the position `class C extends N` where `N` is an ExpressionWithTypeArguments. */
|
||||
export function tryGetClassExtendingExpressionWithTypeArguments(node: Node): ClassLikeDeclaration | undefined {
|
||||
if (isExpressionWithTypeArguments(node) &&
|
||||
node.parent.token === SyntaxKind.ExtendsKeyword &&
|
||||
isClassLike(node.parent.parent)) {
|
||||
return node.parent.parent;
|
||||
}
|
||||
const cls = tryGetClassImplementingOrExtendingExpressionWithTypeArguments(node);
|
||||
return cls && !cls.isImplements ? cls.class : undefined;
|
||||
}
|
||||
|
||||
export interface ClassImplementingOrExtendingExpressionWithTypeArguments {
|
||||
readonly class: ClassLikeDeclaration;
|
||||
readonly isImplements: boolean;
|
||||
}
|
||||
export function tryGetClassImplementingOrExtendingExpressionWithTypeArguments(node: Node): ClassImplementingOrExtendingExpressionWithTypeArguments | undefined {
|
||||
return isExpressionWithTypeArguments(node)
|
||||
&& isHeritageClause(node.parent)
|
||||
&& isClassLike(node.parent.parent)
|
||||
? { class: node.parent.parent, isImplements: node.parent.token === SyntaxKind.ImplementsKeyword }
|
||||
: undefined;
|
||||
}
|
||||
|
||||
export function isAssignmentExpression(node: Node, excludeCompoundAssignment: true): node is AssignmentExpression<EqualsToken>;
|
||||
@@ -3765,15 +3774,6 @@ namespace ts {
|
||||
return tryGetClassExtendingExpressionWithTypeArguments(node) !== undefined;
|
||||
}
|
||||
|
||||
export function isExpressionWithTypeArgumentsInClassImplementsClause(node: Node): node is ExpressionWithTypeArguments {
|
||||
return node.kind === SyntaxKind.ExpressionWithTypeArguments
|
||||
&& isEntityNameExpression((node as ExpressionWithTypeArguments).expression)
|
||||
&& node.parent
|
||||
&& (<HeritageClause>node.parent).token === SyntaxKind.ImplementsKeyword
|
||||
&& node.parent.parent
|
||||
&& isClassLike(node.parent.parent);
|
||||
}
|
||||
|
||||
export function isEntityNameExpression(node: Node): node is EntityNameExpression {
|
||||
return node.kind === SyntaxKind.Identifier || isPropertyAccessEntityNameExpression(node);
|
||||
}
|
||||
@@ -7085,7 +7085,7 @@ namespace ts {
|
||||
return !!(compilerOptions.declaration || compilerOptions.composite);
|
||||
}
|
||||
|
||||
export type StrictOptionName = "noImplicitAny" | "noImplicitThis" | "strictNullChecks" | "strictFunctionTypes" | "strictPropertyInitialization" | "alwaysStrict";
|
||||
export type StrictOptionName = "noImplicitAny" | "noImplicitThis" | "strictNullChecks" | "strictFunctionTypes" | "strictBindCallApply" | "strictPropertyInitialization" | "alwaysStrict";
|
||||
|
||||
export function getStrictOptionValue(compilerOptions: CompilerOptions, flag: StrictOptionName): boolean {
|
||||
return compilerOptions[flag] === undefined ? !!compilerOptions.strict : !!compilerOptions[flag];
|
||||
|
||||
+35
-25
@@ -3,12 +3,15 @@ namespace ts.server {
|
||||
writeMessage(message: string): void;
|
||||
}
|
||||
|
||||
interface RenameEntry extends RenameInfo {
|
||||
fileName: string;
|
||||
position: number;
|
||||
locations: RenameLocation[];
|
||||
findInStrings: boolean;
|
||||
findInComments: boolean;
|
||||
interface RenameEntry {
|
||||
readonly renameInfo: RenameInfo;
|
||||
readonly inputs: {
|
||||
readonly fileName: string;
|
||||
readonly position: number;
|
||||
readonly findInStrings: boolean;
|
||||
readonly findInComments: boolean;
|
||||
};
|
||||
readonly locations: RenameLocation[];
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -390,34 +393,41 @@ namespace ts.server {
|
||||
const locations: RenameLocation[] = [];
|
||||
for (const entry of body.locs) {
|
||||
const fileName = entry.file;
|
||||
for (const loc of entry.locs) {
|
||||
locations.push({ textSpan: this.decodeSpan(loc, fileName), fileName });
|
||||
for (const { start, end, ...prefixSuffixText } of entry.locs) {
|
||||
locations.push({ textSpan: this.decodeSpan({ start, end }, fileName), fileName, ...prefixSuffixText });
|
||||
}
|
||||
}
|
||||
|
||||
return this.lastRenameEntry = {
|
||||
canRename: body.info.canRename,
|
||||
fileToRename: body.info.fileToRename,
|
||||
displayName: body.info.displayName,
|
||||
fullDisplayName: body.info.fullDisplayName,
|
||||
kind: body.info.kind,
|
||||
kindModifiers: body.info.kindModifiers,
|
||||
localizedErrorMessage: body.info.localizedErrorMessage,
|
||||
triggerSpan: createTextSpanFromBounds(position, position),
|
||||
fileName,
|
||||
position,
|
||||
findInStrings: !!findInStrings,
|
||||
findInComments: !!findInComments,
|
||||
const renameInfo = body.info.canRename
|
||||
? identity<RenameInfoSuccess>({
|
||||
canRename: body.info.canRename,
|
||||
fileToRename: body.info.fileToRename,
|
||||
displayName: body.info.displayName,
|
||||
fullDisplayName: body.info.fullDisplayName,
|
||||
kind: body.info.kind,
|
||||
kindModifiers: body.info.kindModifiers,
|
||||
triggerSpan: createTextSpanFromBounds(position, position),
|
||||
})
|
||||
: identity<RenameInfoFailure>({ canRename: false, localizedErrorMessage: body.info.localizedErrorMessage });
|
||||
this.lastRenameEntry = {
|
||||
renameInfo,
|
||||
inputs: {
|
||||
fileName,
|
||||
position,
|
||||
findInStrings: !!findInStrings,
|
||||
findInComments: !!findInComments,
|
||||
},
|
||||
locations,
|
||||
};
|
||||
return renameInfo;
|
||||
}
|
||||
|
||||
findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[] {
|
||||
if (!this.lastRenameEntry ||
|
||||
this.lastRenameEntry.fileName !== fileName ||
|
||||
this.lastRenameEntry.position !== position ||
|
||||
this.lastRenameEntry.findInStrings !== findInStrings ||
|
||||
this.lastRenameEntry.findInComments !== findInComments) {
|
||||
this.lastRenameEntry.inputs.fileName !== fileName ||
|
||||
this.lastRenameEntry.inputs.position !== position ||
|
||||
this.lastRenameEntry.inputs.findInStrings !== findInStrings ||
|
||||
this.lastRenameEntry.inputs.findInComments !== findInComments) {
|
||||
this.getRenameInfo(fileName, position, findInStrings, findInComments);
|
||||
}
|
||||
|
||||
|
||||
@@ -1395,7 +1395,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
}
|
||||
|
||||
public verifyRenameLocations(startRanges: ArrayOrSingle<Range>, options: ReadonlyArray<Range> | { findInStrings?: boolean, findInComments?: boolean, ranges: ReadonlyArray<Range> }) {
|
||||
public verifyRenameLocations(startRanges: ArrayOrSingle<Range>, options: FourSlashInterface.RenameLocationsOptions) {
|
||||
const { findInStrings = false, findInComments = false, ranges = this.getRanges() } = ts.isArray(options) ? { findInStrings: false, findInComments: false, ranges: options } : options;
|
||||
|
||||
for (const startRange of toArray(startRanges)) {
|
||||
@@ -1412,7 +1412,10 @@ Actual: ${stringify(fullActual)}`);
|
||||
|
||||
const sort = (locations: ReadonlyArray<ts.RenameLocation> | undefined) =>
|
||||
locations && ts.sort(locations, (r1, r2) => ts.compareStringsCaseSensitive(r1.fileName, r2.fileName) || r1.textSpan.start - r2.textSpan.start);
|
||||
assert.deepEqual(sort(references), sort(ranges.map((r): ts.RenameLocation => ({ fileName: r.fileName, textSpan: ts.createTextSpanFromRange(r) }))));
|
||||
assert.deepEqual(sort(references), sort(ranges.map((rangeOrOptions): ts.RenameLocation => {
|
||||
const { range, ...prefixSuffixText } = "range" in rangeOrOptions ? rangeOrOptions : { range: rangeOrOptions };
|
||||
return { fileName: range.fileName, textSpan: ts.createTextSpanFromRange(range), ...prefixSuffixText };
|
||||
})));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1534,7 +1537,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
public verifyRenameInfoSucceeded(displayName: string | undefined, fullDisplayName: string | undefined, kind: string | undefined, kindModifiers: string | undefined, fileToRename: string | undefined, expectedRange: Range | undefined): void {
|
||||
const renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition);
|
||||
if (!renameInfo.canRename) {
|
||||
this.raiseError("Rename did not succeed");
|
||||
throw this.raiseError("Rename did not succeed");
|
||||
}
|
||||
|
||||
this.validate("displayName", displayName, renameInfo.displayName);
|
||||
@@ -1560,9 +1563,8 @@ Actual: ${stringify(fullActual)}`);
|
||||
public verifyRenameInfoFailed(message?: string) {
|
||||
const renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition);
|
||||
if (renameInfo.canRename) {
|
||||
this.raiseError("Rename was expected to fail");
|
||||
throw this.raiseError("Rename was expected to fail");
|
||||
}
|
||||
|
||||
this.validate("error", message, renameInfo.localizedErrorMessage);
|
||||
}
|
||||
|
||||
@@ -4484,7 +4486,7 @@ namespace FourSlashInterface {
|
||||
this.state.verifyRenameInfoFailed(message);
|
||||
}
|
||||
|
||||
public renameLocations(startRanges: ArrayOrSingle<FourSlash.Range>, options: FourSlash.Range[] | { findInStrings?: boolean, findInComments?: boolean, ranges: FourSlash.Range[] }) {
|
||||
public renameLocations(startRanges: ArrayOrSingle<FourSlash.Range>, options: RenameLocationsOptions) {
|
||||
this.state.verifyRenameLocations(startRanges, options);
|
||||
}
|
||||
|
||||
@@ -4959,4 +4961,11 @@ namespace FourSlashInterface {
|
||||
readonly newFileContents: { readonly [fileName: string]: string };
|
||||
readonly preferences?: ts.UserPreferences;
|
||||
}
|
||||
|
||||
export type RenameLocationsOptions = ReadonlyArray<RenameLocationOptions> | {
|
||||
readonly findInStrings?: boolean;
|
||||
readonly findInComments?: boolean;
|
||||
readonly ranges: ReadonlyArray<RenameLocationOptions>;
|
||||
};
|
||||
export type RenameLocationOptions = FourSlash.Range | { readonly range: FourSlash.Range, readonly prefixText?: string, readonly suffixText?: string };
|
||||
}
|
||||
@@ -4,6 +4,8 @@ namespace ts.TestFSWithWatch {
|
||||
content: `/// <reference no-default-lib="true"/>
|
||||
interface Boolean {}
|
||||
interface Function {}
|
||||
interface CallableFunction {}
|
||||
interface NewableFunction {}
|
||||
interface IArguments {}
|
||||
interface Number { toExponential: any; }
|
||||
interface Object {}
|
||||
|
||||
Vendored
+60
@@ -295,6 +295,66 @@ interface FunctionConstructor {
|
||||
|
||||
declare const Function: FunctionConstructor;
|
||||
|
||||
interface CallableFunction extends Function {
|
||||
/**
|
||||
* Calls the function with the specified object as the this value and the elements of specified array as the arguments.
|
||||
* @param thisArg The object to be used as the this object.
|
||||
* @param args An array of argument values to be passed to the function.
|
||||
*/
|
||||
apply<T, R>(this: (this: T) => R, thisArg: T): R;
|
||||
apply<T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, args: A): R;
|
||||
|
||||
/**
|
||||
* Calls the function with the specified object as the this value and the specified rest arguments as the arguments.
|
||||
* @param thisArg The object to be used as the this object.
|
||||
* @param args Argument values to be passed to the function.
|
||||
*/
|
||||
call<T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A): R;
|
||||
|
||||
/**
|
||||
* For a given function, creates a bound function that has the same body as the original function.
|
||||
* The this object of the bound function is associated with the specified object, and has the specified initial parameters.
|
||||
* @param thisArg The object to be used as the this object.
|
||||
* @param args Arguments to bind to the parameters of the function.
|
||||
*/
|
||||
bind<T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T): (...args: A) => R;
|
||||
bind<T, A0, A extends any[], R>(this: (this: T, arg0: A0, ...args: A) => R, thisArg: T, arg0: A0): (...args: A) => R;
|
||||
bind<T, A0, A1, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1): (...args: A) => R;
|
||||
bind<T, A0, A1, A2, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, arg2: A2, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1, arg2: A2): (...args: A) => R;
|
||||
bind<T, A0, A1, A2, A3, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, arg2: A2, arg3: A3, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1, arg2: A2, arg3: A3): (...args: A) => R;
|
||||
bind<T, AX, R>(this: (this: T, ...args: AX[]) => R, thisArg: T, ...args: AX[]): (...args: AX[]) => R;
|
||||
}
|
||||
|
||||
interface NewableFunction extends Function {
|
||||
/**
|
||||
* Calls the function with the specified object as the this value and the elements of specified array as the arguments.
|
||||
* @param thisArg The object to be used as the this object.
|
||||
* @param args An array of argument values to be passed to the function.
|
||||
*/
|
||||
apply<T>(this: new () => T, thisArg: T): void;
|
||||
apply<T, A extends any[]>(this: new (...args: A) => T, thisArg: T, args: A): void;
|
||||
|
||||
/**
|
||||
* Calls the function with the specified object as the this value and the specified rest arguments as the arguments.
|
||||
* @param thisArg The object to be used as the this object.
|
||||
* @param args Argument values to be passed to the function.
|
||||
*/
|
||||
call<T, A extends any[]>(this: new (...args: A) => T, thisArg: T, ...args: A): void;
|
||||
|
||||
/**
|
||||
* For a given function, creates a bound function that has the same body as the original function.
|
||||
* The this object of the bound function is associated with the specified object, and has the specified initial parameters.
|
||||
* @param thisArg The object to be used as the this object.
|
||||
* @param args Arguments to bind to the parameters of the function.
|
||||
*/
|
||||
bind<A extends any[], R>(this: new (...args: A) => R, thisArg: any): new (...args: A) => R;
|
||||
bind<A0, A extends any[], R>(this: new (arg0: A0, ...args: A) => R, thisArg: any, arg0: A0): new (...args: A) => R;
|
||||
bind<A0, A1, A extends any[], R>(this: new (arg0: A0, arg1: A1, ...args: A) => R, thisArg: any, arg0: A0, arg1: A1): new (...args: A) => R;
|
||||
bind<A0, A1, A2, A extends any[], R>(this: new (arg0: A0, arg1: A1, arg2: A2, ...args: A) => R, thisArg: any, arg0: A0, arg1: A1, arg2: A2): new (...args: A) => R;
|
||||
bind<A0, A1, A2, A3, A extends any[], R>(this: new (arg0: A0, arg1: A1, arg2: A2, arg3: A3, ...args: A) => R, thisArg: any, arg0: A0, arg1: A1, arg2: A2, arg3: A3): new (...args: A) => R;
|
||||
bind<AX, R>(this: new (...args: AX[]) => R, thisArg: any, ...args: AX[]): new (...args: AX[]) => R;
|
||||
}
|
||||
|
||||
interface IArguments {
|
||||
[index: number]: any;
|
||||
length: number;
|
||||
|
||||
@@ -44,6 +44,24 @@ namespace ts.server {
|
||||
readonly data: ProjectInfoTelemetryEventData;
|
||||
}
|
||||
|
||||
/* __GDPR__
|
||||
"projectInfo" : {
|
||||
"${include}": ["${TypeScriptCommonProperties}"],
|
||||
"projectId": { "classification": "EndUserPseudonymizedInformation", "purpose": "FeatureInsight", "endpoint": "ProjectId" },
|
||||
"fileStats": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"compilerOptions": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"extends": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"files": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"include": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"exclude": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"compileOnSave": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"typeAcquisition": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"configFileName": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"projectType": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"languageServiceEnabled": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"version": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
export interface ProjectInfoTelemetryEventData {
|
||||
/** Cryptographically secure hash of project file location. */
|
||||
readonly projectId: string;
|
||||
|
||||
@@ -662,7 +662,7 @@ namespace ts.server {
|
||||
return this.rootFiles;
|
||||
}
|
||||
return map(this.program.getSourceFiles(), sourceFile => {
|
||||
const scriptInfo = this.projectService.getScriptInfoForPath(sourceFile.resolvedPath || sourceFile.path);
|
||||
const scriptInfo = this.projectService.getScriptInfoForPath(sourceFile.resolvedPath);
|
||||
Debug.assert(!!scriptInfo, "getScriptInfo", () => `scriptInfo for a file '${sourceFile.fileName}' Path: '${sourceFile.path}' / '${sourceFile.resolvedPath}' is missing.`);
|
||||
return scriptInfo!;
|
||||
});
|
||||
|
||||
+24
-9
@@ -1087,23 +1087,18 @@ namespace ts.server.protocol {
|
||||
/**
|
||||
* Information about the item to be renamed.
|
||||
*/
|
||||
export interface RenameInfo {
|
||||
export type RenameInfo = RenameInfoSuccess | RenameInfoFailure;
|
||||
export interface RenameInfoSuccess {
|
||||
/**
|
||||
* True if item can be renamed.
|
||||
*/
|
||||
canRename: boolean;
|
||||
|
||||
canRename: true;
|
||||
/**
|
||||
* File or directory to rename.
|
||||
* If set, `getEditsForFileRename` should be called instead of `findRenameLocations`.
|
||||
*/
|
||||
fileToRename?: string;
|
||||
|
||||
/**
|
||||
* Error message if item can not be renamed.
|
||||
*/
|
||||
localizedErrorMessage?: string;
|
||||
|
||||
/**
|
||||
* Display name of the item to be renamed.
|
||||
*/
|
||||
@@ -1127,6 +1122,13 @@ namespace ts.server.protocol {
|
||||
/** Span of text to rename. */
|
||||
triggerSpan: TextSpan;
|
||||
}
|
||||
export interface RenameInfoFailure {
|
||||
canRename: false;
|
||||
/**
|
||||
* Error message if item can not be renamed.
|
||||
*/
|
||||
localizedErrorMessage: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A group of text spans, all in 'file'.
|
||||
@@ -1135,7 +1137,12 @@ namespace ts.server.protocol {
|
||||
/** The file to which the spans apply */
|
||||
file: string;
|
||||
/** The text spans in this group */
|
||||
locs: TextSpan[];
|
||||
locs: RenameTextSpan[];
|
||||
}
|
||||
|
||||
export interface RenameTextSpan extends TextSpan {
|
||||
readonly prefixText?: string;
|
||||
readonly suffixText?: string;
|
||||
}
|
||||
|
||||
export interface RenameResponseBody {
|
||||
@@ -2737,6 +2744,14 @@ namespace ts.server.protocol {
|
||||
payload: TypingsInstalledTelemetryEventPayload;
|
||||
}
|
||||
|
||||
/* __GDPR__
|
||||
"typingsinstalled" : {
|
||||
"${include}": ["${TypeScriptCommonProperties}"],
|
||||
"installedPackages": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
|
||||
"installSuccess": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"typingsInstallerVersion": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
export interface TypingsInstalledTelemetryEventPayload {
|
||||
/**
|
||||
* Comma separated list of installed typing packages
|
||||
|
||||
+35
-6
@@ -490,6 +490,7 @@ namespace ts.server {
|
||||
globalPlugins?: ReadonlyArray<string>;
|
||||
pluginProbeLocations?: ReadonlyArray<string>;
|
||||
allowLocalPluginLoads?: boolean;
|
||||
typesMapLocation?: string;
|
||||
}
|
||||
|
||||
export class Session implements EventSender {
|
||||
@@ -550,6 +551,7 @@ namespace ts.server {
|
||||
globalPlugins: opts.globalPlugins,
|
||||
pluginProbeLocations: opts.pluginProbeLocations,
|
||||
allowLocalPluginLoads: opts.allowLocalPluginLoads,
|
||||
typesMapLocation: opts.typesMapLocation,
|
||||
syntaxOnly: opts.syntaxOnly,
|
||||
};
|
||||
this.projectService = new ProjectService(settings);
|
||||
@@ -619,7 +621,11 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
public logError(err: Error, cmd: string) {
|
||||
public logError(err: Error, cmd: string): void {
|
||||
this.logErrorWorker(err, cmd);
|
||||
}
|
||||
|
||||
private logErrorWorker(err: Error, cmd: string, fileRequest?: protocol.FileRequestArgs): void {
|
||||
let msg = "Exception on executing command " + cmd;
|
||||
if (err.message) {
|
||||
msg += ":\n" + indent(err.message);
|
||||
@@ -627,6 +633,19 @@ namespace ts.server {
|
||||
msg += "\n" + indent((<StackTraceError>err).stack!);
|
||||
}
|
||||
}
|
||||
|
||||
if (fileRequest && this.logger.hasLevel(LogLevel.verbose)) {
|
||||
try {
|
||||
const { file, project } = this.getFileAndProject(fileRequest);
|
||||
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
|
||||
if (scriptInfo) {
|
||||
const text = getSnapshotText(scriptInfo.getSnapshot());
|
||||
msg += `\n\nFile text of ${fileRequest.file}:${indent(text)}\n`;
|
||||
}
|
||||
}
|
||||
catch {} // tslint:disable-line no-empty
|
||||
}
|
||||
|
||||
this.logger.msg(msg, Msg.Err);
|
||||
}
|
||||
|
||||
@@ -1165,16 +1184,24 @@ namespace ts.server {
|
||||
return { info: renameInfo, locs: this.toSpanGroups(locations) };
|
||||
}
|
||||
|
||||
private mapRenameInfo({ canRename, localizedErrorMessage, displayName, fullDisplayName, kind, kindModifiers, triggerSpan }: RenameInfo, scriptInfo: ScriptInfo): protocol.RenameInfo {
|
||||
return { canRename, localizedErrorMessage, displayName, fullDisplayName, kind, kindModifiers, triggerSpan: this.toLocationTextSpan(triggerSpan, scriptInfo) };
|
||||
private mapRenameInfo(info: RenameInfo, scriptInfo: ScriptInfo): protocol.RenameInfo {
|
||||
if (info.canRename) {
|
||||
const { canRename, fileToRename, displayName, fullDisplayName, kind, kindModifiers, triggerSpan } = info;
|
||||
return identity<protocol.RenameInfoSuccess>(
|
||||
{ canRename, fileToRename, displayName, fullDisplayName, kind, kindModifiers, triggerSpan: this.toLocationTextSpan(triggerSpan, scriptInfo) });
|
||||
}
|
||||
else {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
private toSpanGroups(locations: ReadonlyArray<RenameLocation>): ReadonlyArray<protocol.SpanGroup> {
|
||||
const map = createMap<protocol.SpanGroup>();
|
||||
for (const { fileName, textSpan } of locations) {
|
||||
for (const { fileName, textSpan, originalTextSpan: _, originalFileName: _1, ...prefixSuffixText } of locations) {
|
||||
let group = map.get(fileName);
|
||||
if (!group) map.set(fileName, group = { file: fileName, locs: [] });
|
||||
group.locs.push(this.toLocationTextSpan(textSpan, Debug.assertDefined(this.projectService.getScriptInfo(fileName))));
|
||||
const scriptInfo = Debug.assertDefined(this.projectService.getScriptInfo(fileName));
|
||||
group.locs.push({ ...this.toLocationTextSpan(textSpan, scriptInfo), ...prefixSuffixText });
|
||||
}
|
||||
return arrayFrom(map.values());
|
||||
}
|
||||
@@ -2321,8 +2348,10 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
let request: protocol.Request | undefined;
|
||||
let relevantFile: protocol.FileRequestArgs | undefined;
|
||||
try {
|
||||
request = <protocol.Request>JSON.parse(message);
|
||||
relevantFile = request.arguments && (request as protocol.FileRequest).arguments.file ? (request as protocol.FileRequest).arguments : undefined;
|
||||
const { response, responseRequired } = this.executeCommand(request);
|
||||
|
||||
if (this.logger.hasLevel(LogLevel.requestTime)) {
|
||||
@@ -2348,7 +2377,7 @@ namespace ts.server {
|
||||
this.doOutput({ canceled: true }, request!.command, request!.seq, /*success*/ true);
|
||||
return;
|
||||
}
|
||||
this.logError(err, message);
|
||||
this.logErrorWorker(err, message, relevantFile);
|
||||
this.doOutput(
|
||||
/*info*/ undefined,
|
||||
request ? request.command : CommandNames.Unknown,
|
||||
|
||||
@@ -246,14 +246,16 @@ namespace ts.server {
|
||||
return index === 0 || value !== array[index - 1];
|
||||
}
|
||||
|
||||
const indentStr = "\n ";
|
||||
|
||||
/* @internal */
|
||||
export function indent(str: string): string {
|
||||
return "\n " + str;
|
||||
return indentStr + str.replace(/\n/g, indentStr);
|
||||
}
|
||||
|
||||
/** Put stringified JSON on the next line, indented. */
|
||||
/* @internal */
|
||||
export function stringifyIndented(json: {}): string {
|
||||
return "\n " + JSON.stringify(json);
|
||||
return indentStr + JSON.stringify(json);
|
||||
}
|
||||
}
|
||||
@@ -15,24 +15,24 @@ namespace ts.codefix {
|
||||
});
|
||||
|
||||
interface SynthIdentifier {
|
||||
identifier: Identifier;
|
||||
types: Type[];
|
||||
readonly identifier: Identifier;
|
||||
readonly types: Type[];
|
||||
numberOfAssignmentsOriginal: number; // number of times the variable should be assigned in the refactor
|
||||
}
|
||||
|
||||
interface SymbolAndIdentifier {
|
||||
identifier: Identifier;
|
||||
symbol: Symbol;
|
||||
readonly identifier: Identifier;
|
||||
readonly symbol: Symbol;
|
||||
}
|
||||
|
||||
interface Transformer {
|
||||
checker: TypeChecker;
|
||||
synthNamesMap: Map<SynthIdentifier>; // keys are the symbol id of the identifier
|
||||
allVarNames: SymbolAndIdentifier[];
|
||||
setOfExpressionsToReturn: Map<true>; // keys are the node ids of the expressions
|
||||
constIdentifiers: Identifier[];
|
||||
originalTypeMap: Map<Type>; // keys are the node id of the identifier
|
||||
isInJSFile: boolean;
|
||||
readonly checker: TypeChecker;
|
||||
readonly synthNamesMap: Map<SynthIdentifier>; // keys are the symbol id of the identifier
|
||||
readonly allVarNames: ReadonlyArray<SymbolAndIdentifier>;
|
||||
readonly setOfExpressionsToReturn: ReadonlyMap<true>; // keys are the node ids of the expressions
|
||||
readonly constIdentifiers: Identifier[];
|
||||
readonly originalTypeMap: ReadonlyMap<Type>; // keys are the node id of the identifier
|
||||
readonly isInJSFile: boolean;
|
||||
}
|
||||
|
||||
function convertToAsyncFunction(changes: textChanges.ChangeTracker, sourceFile: SourceFile, position: number, checker: TypeChecker, context: CodeFixContextBase): void {
|
||||
@@ -61,7 +61,7 @@ namespace ts.codefix {
|
||||
const functionToConvertRenamed: FunctionLikeDeclaration = renameCollidingVarNames(functionToConvert, checker, synthNamesMap, context, setOfExpressionsToReturn, originalTypeMap, allVarNames);
|
||||
const constIdentifiers = getConstIdentifiers(synthNamesMap);
|
||||
const returnStatements = getReturnStatementsWithPromiseHandlers(functionToConvertRenamed);
|
||||
const transformer = { checker, synthNamesMap, allVarNames, setOfExpressionsToReturn, constIdentifiers, originalTypeMap, isInJSFile: isInJavascript };
|
||||
const transformer: Transformer = { checker, synthNamesMap, allVarNames, setOfExpressionsToReturn, constIdentifiers, originalTypeMap, isInJSFile: isInJavascript };
|
||||
|
||||
if (!returnStatements.length) {
|
||||
return;
|
||||
@@ -88,7 +88,7 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
// Returns the identifiers that are never reassigned in the refactor
|
||||
function getConstIdentifiers(synthNamesMap: Map<SynthIdentifier>): Identifier[] {
|
||||
function getConstIdentifiers(synthNamesMap: ReadonlyMap<SynthIdentifier>): Identifier[] {
|
||||
const constIdentifiers: Identifier[] = [];
|
||||
synthNamesMap.forEach((val) => {
|
||||
if (val.numberOfAssignmentsOriginal === 0) {
|
||||
@@ -249,8 +249,8 @@ namespace ts.codefix {
|
||||
}
|
||||
}
|
||||
|
||||
function getNewNameIfConflict(name: Identifier, originalNames: Map<Symbol[]>): SynthIdentifier {
|
||||
const numVarsSameName = (originalNames.get(name.text) || []).length;
|
||||
function getNewNameIfConflict(name: Identifier, originalNames: ReadonlyMap<Symbol[]>): SynthIdentifier {
|
||||
const numVarsSameName = (originalNames.get(name.text) || emptyArray).length;
|
||||
const numberOfAssignmentsOriginal = 0;
|
||||
const identifier = numVarsSameName === 0 ? name : createIdentifier(name.text + "_" + numVarsSameName);
|
||||
return { identifier, types: [], numberOfAssignmentsOriginal };
|
||||
@@ -258,9 +258,9 @@ namespace ts.codefix {
|
||||
|
||||
// dispatch function to recursively build the refactoring
|
||||
// should be kept up to date with isFixablePromiseHandler in suggestionDiagnostics.ts
|
||||
function transformExpression(node: Expression, transformer: Transformer, outermostParent: CallExpression, prevArgName?: SynthIdentifier): Statement[] {
|
||||
function transformExpression(node: Expression, transformer: Transformer, outermostParent: CallExpression, prevArgName?: SynthIdentifier): ReadonlyArray<Statement> {
|
||||
if (!node) {
|
||||
return [];
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
const originalType = isIdentifier(node) && transformer.originalTypeMap.get(getNodeId(node).toString());
|
||||
@@ -280,10 +280,10 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
codeActionSucceeded = false;
|
||||
return [];
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
function transformCatch(node: CallExpression, transformer: Transformer, prevArgName?: SynthIdentifier): Statement[] {
|
||||
function transformCatch(node: CallExpression, transformer: Transformer, prevArgName?: SynthIdentifier): ReadonlyArray<Statement> {
|
||||
const func = node.arguments[0];
|
||||
const argName = getArgName(func, transformer);
|
||||
const shouldReturn = transformer.setOfExpressionsToReturn.get(getNodeId(node).toString());
|
||||
@@ -336,7 +336,7 @@ namespace ts.codefix {
|
||||
return newSynthName;
|
||||
}
|
||||
|
||||
function transformThen(node: CallExpression, transformer: Transformer, outermostParent: CallExpression, prevArgName?: SynthIdentifier): Statement[] {
|
||||
function transformThen(node: CallExpression, transformer: Transformer, outermostParent: CallExpression, prevArgName?: SynthIdentifier): ReadonlyArray<Statement> {
|
||||
const [res, rej] = node.arguments;
|
||||
|
||||
if (!res) {
|
||||
@@ -356,18 +356,18 @@ namespace ts.codefix {
|
||||
const catchArg = argNameRej ? argNameRej.identifier.text : "e";
|
||||
const catchClause = createCatchClause(catchArg, createBlock(transformationBody2));
|
||||
|
||||
return [createTry(tryBlock, catchClause, /* finallyBlock */ undefined) as Statement];
|
||||
return [createTry(tryBlock, catchClause, /* finallyBlock */ undefined)];
|
||||
}
|
||||
|
||||
return transformExpression(node.expression, transformer, node, argNameRes).concat(transformationBody);
|
||||
}
|
||||
|
||||
function getFlagOfIdentifier(node: Identifier, constIdentifiers: Identifier[]): NodeFlags {
|
||||
function getFlagOfIdentifier(node: Identifier, constIdentifiers: ReadonlyArray<Identifier>): NodeFlags {
|
||||
const inArr: boolean = constIdentifiers.some(elem => elem.text === node.text);
|
||||
return inArr ? NodeFlags.Const : NodeFlags.Let;
|
||||
}
|
||||
|
||||
function transformPromiseCall(node: Expression, transformer: Transformer, prevArgName?: SynthIdentifier): Statement[] {
|
||||
function transformPromiseCall(node: Expression, transformer: Transformer, prevArgName?: SynthIdentifier): ReadonlyArray<Statement> {
|
||||
const shouldReturn = transformer.setOfExpressionsToReturn.get(getNodeId(node).toString());
|
||||
// the identifier is empty when the handler (.then()) ignores the argument - In this situation we do not need to save the result of the promise returning call
|
||||
const originalNodeParent = node.original ? node.original.parent : node.parent;
|
||||
@@ -381,23 +381,23 @@ namespace ts.codefix {
|
||||
return [createReturn(getSynthesizedDeepClone(node))];
|
||||
}
|
||||
|
||||
function createTransformedStatement(prevArgName: SynthIdentifier | undefined, rightHandSide: Expression, transformer: Transformer): MutableNodeArray<Statement> {
|
||||
function createTransformedStatement(prevArgName: SynthIdentifier | undefined, rightHandSide: Expression, transformer: Transformer): ReadonlyArray<Statement> {
|
||||
if (!prevArgName || prevArgName.identifier.text.length === 0) {
|
||||
// if there's no argName to assign to, there still might be side effects
|
||||
return createNodeArray([createStatement(rightHandSide)]);
|
||||
return [createStatement(rightHandSide)];
|
||||
}
|
||||
|
||||
if (prevArgName.types.length < prevArgName.numberOfAssignmentsOriginal) {
|
||||
// if the variable has already been declared, we don't need "let" or "const"
|
||||
return createNodeArray([createStatement(createAssignment(getSynthesizedDeepClone(prevArgName.identifier), rightHandSide))]);
|
||||
return [createStatement(createAssignment(getSynthesizedDeepClone(prevArgName.identifier), rightHandSide))];
|
||||
}
|
||||
|
||||
return createNodeArray([createVariableStatement(/*modifiers*/ undefined,
|
||||
(createVariableDeclarationList([createVariableDeclaration(getSynthesizedDeepClone(prevArgName.identifier), /*type*/ undefined, rightHandSide)], getFlagOfIdentifier(prevArgName.identifier, transformer.constIdentifiers))))]);
|
||||
return [createVariableStatement(/*modifiers*/ undefined,
|
||||
(createVariableDeclarationList([createVariableDeclaration(getSynthesizedDeepClone(prevArgName.identifier), /*type*/ undefined, rightHandSide)], getFlagOfIdentifier(prevArgName.identifier, transformer.constIdentifiers))))];
|
||||
}
|
||||
|
||||
// should be kept up to date with isFixablePromiseArgument in suggestionDiagnostics.ts
|
||||
function getTransformationBody(func: Expression, prevArgName: SynthIdentifier | undefined, argName: SynthIdentifier | undefined, parent: CallExpression, transformer: Transformer): NodeArray<Statement> {
|
||||
function getTransformationBody(func: Expression, prevArgName: SynthIdentifier | undefined, argName: SynthIdentifier | undefined, parent: CallExpression, transformer: Transformer): ReadonlyArray<Statement> {
|
||||
|
||||
const shouldReturn = transformer.setOfExpressionsToReturn.get(getNodeId(parent).toString());
|
||||
switch (func.kind) {
|
||||
@@ -410,9 +410,9 @@ namespace ts.codefix {
|
||||
break;
|
||||
}
|
||||
|
||||
const synthCall = createCall(getSynthesizedDeepClone(func) as Identifier, /*typeArguments*/ undefined, argName ? [argName.identifier] : []);
|
||||
const synthCall = createCall(getSynthesizedDeepClone(func as Identifier), /*typeArguments*/ undefined, argName ? [argName.identifier] : emptyArray);
|
||||
if (shouldReturn) {
|
||||
return createNodeArray([createReturn(synthCall)]);
|
||||
return [createReturn(synthCall)];
|
||||
}
|
||||
|
||||
const type = transformer.originalTypeMap.get(getNodeId(func).toString()) || transformer.checker.getTypeAtLocation(func);
|
||||
@@ -450,15 +450,19 @@ namespace ts.codefix {
|
||||
}
|
||||
}
|
||||
|
||||
return shouldReturn ? getSynthesizedDeepClones(createNodeArray(refactoredStmts)) :
|
||||
removeReturns(createNodeArray(refactoredStmts), prevArgName!.identifier, transformer, seenReturnStatement);
|
||||
return shouldReturn ? refactoredStmts.map(s => getSynthesizedDeepClone(s)) :
|
||||
removeReturns(
|
||||
refactoredStmts,
|
||||
prevArgName === undefined ? undefined : prevArgName.identifier,
|
||||
transformer,
|
||||
seenReturnStatement);
|
||||
}
|
||||
else {
|
||||
const innerRetStmts = getReturnStatementsWithPromiseHandlers(createReturn(funcBody));
|
||||
const innerCbBody = getInnerTransformationBody(transformer, innerRetStmts, prevArgName);
|
||||
|
||||
if (innerCbBody.length > 0) {
|
||||
return createNodeArray(innerCbBody);
|
||||
return innerCbBody;
|
||||
}
|
||||
|
||||
if (!shouldReturn) {
|
||||
@@ -473,7 +477,7 @@ namespace ts.codefix {
|
||||
return transformedStatement;
|
||||
}
|
||||
else {
|
||||
return createNodeArray([createReturn(getSynthesizedDeepClone(funcBody))]);
|
||||
return [createReturn(getSynthesizedDeepClone(funcBody))];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -482,7 +486,7 @@ namespace ts.codefix {
|
||||
codeActionSucceeded = false;
|
||||
break;
|
||||
}
|
||||
return createNodeArray([]);
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
function getLastCallSignature(type: Type, checker: TypeChecker): Signature | undefined {
|
||||
@@ -491,14 +495,19 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
|
||||
function removeReturns(stmts: NodeArray<Statement>, prevArgName: Identifier, transformer: Transformer, seenReturnStatement: boolean): NodeArray<Statement> {
|
||||
function removeReturns(stmts: ReadonlyArray<Statement>, prevArgName: Identifier | undefined, transformer: Transformer, seenReturnStatement: boolean): ReadonlyArray<Statement> {
|
||||
const ret: Statement[] = [];
|
||||
for (const stmt of stmts) {
|
||||
if (isReturnStatement(stmt)) {
|
||||
if (stmt.expression) {
|
||||
const possiblyAwaitedExpression = isPromiseReturningExpression(stmt.expression, transformer.checker) ? createAwait(stmt.expression) : stmt.expression;
|
||||
ret.push(createVariableStatement(/*modifiers*/ undefined,
|
||||
(createVariableDeclarationList([createVariableDeclaration(prevArgName, /*type*/ undefined, possiblyAwaitedExpression)], getFlagOfIdentifier(prevArgName, transformer.constIdentifiers)))));
|
||||
if (prevArgName === undefined) {
|
||||
ret.push(createExpressionStatement(possiblyAwaitedExpression));
|
||||
}
|
||||
else {
|
||||
ret.push(createVariableStatement(/*modifiers*/ undefined,
|
||||
(createVariableDeclarationList([createVariableDeclaration(prevArgName, /*type*/ undefined, possiblyAwaitedExpression)], getFlagOfIdentifier(prevArgName, transformer.constIdentifiers)))));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -507,20 +516,20 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
// if block has no return statement, need to define prevArgName as undefined to prevent undeclared variables
|
||||
if (!seenReturnStatement) {
|
||||
if (!seenReturnStatement && prevArgName !== undefined) {
|
||||
ret.push(createVariableStatement(/*modifiers*/ undefined,
|
||||
(createVariableDeclarationList([createVariableDeclaration(prevArgName, /*type*/ undefined, createIdentifier("undefined"))], getFlagOfIdentifier(prevArgName, transformer.constIdentifiers)))));
|
||||
}
|
||||
|
||||
return createNodeArray(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
function getInnerTransformationBody(transformer: Transformer, innerRetStmts: Node[], prevArgName?: SynthIdentifier) {
|
||||
function getInnerTransformationBody(transformer: Transformer, innerRetStmts: ReadonlyArray<Node>, prevArgName?: SynthIdentifier) {
|
||||
|
||||
let innerCbBody: Statement[] = [];
|
||||
for (const stmt of innerRetStmts) {
|
||||
forEachChild(stmt, function visit(node: Node) {
|
||||
forEachChild(stmt, function visit(node) {
|
||||
if (isCallExpression(node)) {
|
||||
const temp = transformExpression(node, transformer, node, prevArgName);
|
||||
innerCbBody = innerCbBody.concat(temp);
|
||||
|
||||
@@ -196,7 +196,7 @@ namespace ts.codefix {
|
||||
function getReferences(token: PropertyName | Token<SyntaxKind.ConstructorKeyword>, program: Program, cancellationToken: CancellationToken): ReadonlyArray<Identifier> {
|
||||
// Position shouldn't matter since token is not a SourceFile.
|
||||
return mapDefined(FindAllReferences.getReferenceEntriesForNode(-1, token, program, program.getSourceFiles(), cancellationToken), entry =>
|
||||
entry.type === "node" ? tryCast(entry.node, isIdentifier) : undefined);
|
||||
entry.kind !== FindAllReferences.EntryKind.Span ? tryCast(entry.node, isIdentifier) : undefined);
|
||||
}
|
||||
|
||||
function inferTypeForVariableFromUsage(token: Identifier, program: Program, cancellationToken: CancellationToken): Type | undefined {
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
const contextToken = findPrecedingToken(position, sourceFile);
|
||||
if (triggerCharacter && (!contextToken || !isValidTrigger(sourceFile, triggerCharacter, contextToken, position))) return undefined;
|
||||
if (triggerCharacter && !isValidTrigger(sourceFile, triggerCharacter, contextToken, position)) return undefined;
|
||||
|
||||
if (isInString(sourceFile, position, contextToken)) {
|
||||
return !contextToken || !isStringLiteralLike(contextToken)
|
||||
@@ -1713,6 +1713,9 @@ namespace ts.Completions {
|
||||
break;
|
||||
case SyntaxKind.AsteriskToken:
|
||||
return isMethodDeclaration(parent) ? tryCast(parent.parent, isObjectLiteralExpression) : undefined;
|
||||
case SyntaxKind.Identifier:
|
||||
return (contextToken as Identifier).text === "async" && isShorthandPropertyAssignment(contextToken.parent)
|
||||
? contextToken.parent.parent : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1928,7 +1931,6 @@ namespace ts.Completions {
|
||||
// Previous token may have been a keyword that was converted to an identifier.
|
||||
switch (keywordForNode(contextToken)) {
|
||||
case SyntaxKind.AbstractKeyword:
|
||||
case SyntaxKind.AsyncKeyword:
|
||||
case SyntaxKind.ClassKeyword:
|
||||
case SyntaxKind.ConstKeyword:
|
||||
case SyntaxKind.DeclareKeyword:
|
||||
@@ -1943,6 +1945,8 @@ namespace ts.Completions {
|
||||
case SyntaxKind.VarKeyword:
|
||||
case SyntaxKind.YieldKeyword:
|
||||
return true;
|
||||
case SyntaxKind.AsyncKeyword:
|
||||
return isPropertyDeclaration(contextToken.parent);
|
||||
}
|
||||
|
||||
return isDeclarationName(contextToken)
|
||||
@@ -2272,7 +2276,7 @@ namespace ts.Completions {
|
||||
return !!type.getStringIndexType() || !!type.getNumberIndexType();
|
||||
}
|
||||
|
||||
function isValidTrigger(sourceFile: SourceFile, triggerCharacter: CompletionsTriggerCharacter, contextToken: Node, position: number): boolean {
|
||||
function isValidTrigger(sourceFile: SourceFile, triggerCharacter: CompletionsTriggerCharacter, contextToken: Node | undefined, position: number): boolean {
|
||||
switch (triggerCharacter) {
|
||||
case ".":
|
||||
case "@":
|
||||
@@ -2281,14 +2285,14 @@ namespace ts.Completions {
|
||||
case "'":
|
||||
case "`":
|
||||
// Only automatically bring up completions if this is an opening quote.
|
||||
return isStringLiteralOrTemplate(contextToken) && position === contextToken.getStart(sourceFile) + 1;
|
||||
return !!contextToken && isStringLiteralOrTemplate(contextToken) && position === contextToken.getStart(sourceFile) + 1;
|
||||
case "<":
|
||||
// Opening JSX tag
|
||||
return contextToken.kind === SyntaxKind.LessThanToken && (!isBinaryExpression(contextToken.parent) || binaryExpressionMayBeOpenTag(contextToken.parent));
|
||||
return !!contextToken && contextToken.kind === SyntaxKind.LessThanToken && (!isBinaryExpression(contextToken.parent) || binaryExpressionMayBeOpenTag(contextToken.parent));
|
||||
case "/":
|
||||
return isStringLiteralLike(contextToken)
|
||||
return !!contextToken && (isStringLiteralLike(contextToken)
|
||||
? !!tryGetImportFromModuleSpecifier(contextToken)
|
||||
: contextToken.kind === SyntaxKind.SlashToken && isJsxClosingElement(contextToken.parent);
|
||||
: contextToken.kind === SyntaxKind.SlashToken && isJsxClosingElement(contextToken.parent));
|
||||
default:
|
||||
return Debug.assertNever(triggerCharacter);
|
||||
}
|
||||
|
||||
@@ -13,19 +13,20 @@ namespace ts.FindAllReferences {
|
||||
| { readonly type: DefinitionKind.This; readonly node: Node }
|
||||
| { readonly type: DefinitionKind.String; readonly node: StringLiteral };
|
||||
|
||||
export const enum EntryKind { Span, Node, StringLiteral, SearchedLocalFoundProperty, SearchedPropertyFoundLocal }
|
||||
export type NodeEntryKind = EntryKind.Node | EntryKind.StringLiteral | EntryKind.SearchedLocalFoundProperty | EntryKind.SearchedPropertyFoundLocal;
|
||||
export type Entry = NodeEntry | SpanEntry;
|
||||
export interface NodeEntry {
|
||||
type: "node";
|
||||
node: Node;
|
||||
isInString?: true;
|
||||
readonly kind: NodeEntryKind;
|
||||
readonly node: Node;
|
||||
}
|
||||
export interface SpanEntry {
|
||||
type: "span";
|
||||
fileName: string;
|
||||
textSpan: TextSpan;
|
||||
readonly kind: EntryKind.Span;
|
||||
readonly fileName: string;
|
||||
readonly textSpan: TextSpan;
|
||||
}
|
||||
export function nodeEntry(node: Node, isInString?: true): NodeEntry {
|
||||
return { type: "node", node: (node as NamedDeclaration).name || node, isInString };
|
||||
export function nodeEntry(node: Node, kind: NodeEntryKind = EntryKind.Node): NodeEntry {
|
||||
return { kind, node: (node as NamedDeclaration).name || node };
|
||||
}
|
||||
|
||||
export interface Options {
|
||||
@@ -33,7 +34,7 @@ namespace ts.FindAllReferences {
|
||||
readonly findInComments?: boolean;
|
||||
/**
|
||||
* True if we are renaming the symbol.
|
||||
* If so, we will find fewer references -- if it is referenced by several different names, we sill only find references for the original name.
|
||||
* If so, we will find fewer references -- if it is referenced by several different names, we still only find references for the original name.
|
||||
*/
|
||||
readonly isForRename?: boolean;
|
||||
/** True if we are searching for implementations. We will have a different method of adding references if so. */
|
||||
@@ -84,10 +85,15 @@ namespace ts.FindAllReferences {
|
||||
}
|
||||
}
|
||||
|
||||
export function findReferencedEntries(program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray<SourceFile>, node: Node, position: number, options: Options | undefined): ReferenceEntry[] | undefined {
|
||||
return map(flattenEntries(Core.getReferencedSymbolsForNode(position, node, program, sourceFiles, cancellationToken, options)), toReferenceEntry);
|
||||
export function findReferenceOrRenameEntries<T>(
|
||||
program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray<SourceFile>, node: Node, position: number, options: Options | undefined,
|
||||
convertEntry: ToReferenceOrRenameEntry<T>,
|
||||
): T[] | undefined {
|
||||
return map(flattenEntries(Core.getReferencedSymbolsForNode(position, node, program, sourceFiles, cancellationToken, options)), entry => convertEntry(entry, node));
|
||||
}
|
||||
|
||||
export type ToReferenceOrRenameEntry<T> = (entry: Entry, originalNode: Node) => T;
|
||||
|
||||
export function getReferenceEntriesForNode(position: number, node: Node, program: Program, sourceFiles: ReadonlyArray<SourceFile>, cancellationToken: CancellationToken, options: Options = {}, sourceFilesSet: ReadonlyMap<true> = arrayToSet(sourceFiles, f => f.fileName)): Entry[] | undefined {
|
||||
return flattenEntries(Core.getReferencedSymbolsForNode(position, node, program, sourceFiles, cancellationToken, options, sourceFilesSet));
|
||||
}
|
||||
@@ -143,26 +149,64 @@ namespace ts.FindAllReferences {
|
||||
return { displayParts, kind: symbolKind };
|
||||
}
|
||||
|
||||
function toReferenceEntry(entry: Entry): ReferenceEntry {
|
||||
if (entry.type === "span") {
|
||||
return { textSpan: entry.textSpan, fileName: entry.fileName, isWriteAccess: false, isDefinition: false };
|
||||
}
|
||||
export function toRenameLocation(entry: Entry, originalNode: Node): RenameLocation {
|
||||
return { ...entryToDocumentSpan(entry), ...getPrefixAndSuffixText(entry, originalNode) };
|
||||
}
|
||||
|
||||
const { node, isInString } = entry;
|
||||
const sourceFile = node.getSourceFile();
|
||||
export function toReferenceEntry(entry: Entry): ReferenceEntry {
|
||||
const { textSpan, fileName } = entryToDocumentSpan(entry);
|
||||
if (entry.kind === EntryKind.Span) {
|
||||
return { textSpan, fileName, isWriteAccess: false, isDefinition: false };
|
||||
}
|
||||
const { kind, node } = entry;
|
||||
return {
|
||||
fileName: sourceFile.fileName,
|
||||
textSpan: getTextSpan(node, sourceFile),
|
||||
textSpan,
|
||||
fileName,
|
||||
isWriteAccess: isWriteAccessForReference(node),
|
||||
isDefinition: node.kind === SyntaxKind.DefaultKeyword
|
||||
|| !!getDeclarationFromName(node)
|
||||
|| isLiteralComputedPropertyDeclarationName(node),
|
||||
isInString,
|
||||
isInString: kind === EntryKind.StringLiteral ? true : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
function entryToDocumentSpan(entry: Entry): DocumentSpan {
|
||||
if (entry.kind === EntryKind.Span) {
|
||||
return { textSpan: entry.textSpan, fileName: entry.fileName };
|
||||
}
|
||||
else {
|
||||
const sourceFile = entry.node.getSourceFile();
|
||||
return { textSpan: getTextSpan(entry.node, sourceFile), fileName: sourceFile.fileName };
|
||||
}
|
||||
}
|
||||
|
||||
function getPrefixAndSuffixText(entry: Entry, originalNode: Node): { readonly prefixText?: string, readonly suffixText?: string } {
|
||||
if (entry.kind !== EntryKind.Span && isIdentifier(originalNode)) {
|
||||
const { node, kind } = entry;
|
||||
const name = originalNode.text;
|
||||
const isShorthandAssignment = isShorthandPropertyAssignment(node.parent);
|
||||
if (isShorthandAssignment || isObjectBindingElementWithoutPropertyName(node.parent)) {
|
||||
if (kind === EntryKind.SearchedLocalFoundProperty) {
|
||||
return { prefixText: name + ": " };
|
||||
}
|
||||
else if (kind === EntryKind.SearchedPropertyFoundLocal) {
|
||||
return { suffixText: ": " + name };
|
||||
}
|
||||
else {
|
||||
return isShorthandAssignment
|
||||
// In `const o = { x }; o.x`, symbolAtLocation at `x` in `{ x }` is the property symbol.
|
||||
? { suffixText: ": " + name }
|
||||
// For a binding element `const { x } = o;`, symbolAtLocation at `x` is the property symbol.
|
||||
: { prefixText: name + ": " };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return emptyOptions;
|
||||
}
|
||||
|
||||
function toImplementationLocation(entry: Entry, checker: TypeChecker): ImplementationLocation {
|
||||
if (entry.type === "node") {
|
||||
if (entry.kind !== EntryKind.Span) {
|
||||
const { node } = entry;
|
||||
const sourceFile = node.getSourceFile();
|
||||
return { textSpan: getTextSpan(node, sourceFile), fileName: sourceFile.fileName, ...implementationKindDisplayParts(node, checker) };
|
||||
@@ -196,18 +240,18 @@ namespace ts.FindAllReferences {
|
||||
}
|
||||
|
||||
export function toHighlightSpan(entry: Entry): { fileName: string, span: HighlightSpan } {
|
||||
if (entry.type === "span") {
|
||||
if (entry.kind === EntryKind.Span) {
|
||||
const { fileName, textSpan } = entry;
|
||||
return { fileName, span: { textSpan, kind: HighlightSpanKind.reference } };
|
||||
}
|
||||
|
||||
const { node, isInString } = entry;
|
||||
const { node, kind } = entry;
|
||||
const sourceFile = node.getSourceFile();
|
||||
const writeAccess = isWriteAccessForReference(node);
|
||||
const span: HighlightSpan = {
|
||||
textSpan: getTextSpan(node, sourceFile),
|
||||
kind: writeAccess ? HighlightSpanKind.writtenReference : HighlightSpanKind.reference,
|
||||
isInString
|
||||
isInString: kind === EntryKind.StringLiteral ? true : undefined,
|
||||
};
|
||||
return { fileName: sourceFile.fileName, span };
|
||||
}
|
||||
@@ -348,11 +392,11 @@ namespace ts.FindAllReferences.Core {
|
||||
}
|
||||
}
|
||||
// import("foo") with no qualifier will reference the `export =` of the module, which may be referenced anyway.
|
||||
return { type: "node", node: reference.literal };
|
||||
return nodeEntry(reference.literal);
|
||||
}
|
||||
else {
|
||||
return {
|
||||
type: "span",
|
||||
kind: EntryKind.Span,
|
||||
fileName: reference.referencingFile.fileName,
|
||||
textSpan: createTextSpanFromRange(reference.ref),
|
||||
};
|
||||
@@ -366,7 +410,7 @@ namespace ts.FindAllReferences.Core {
|
||||
break;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
if (sourceFilesSet.has(decl.getSourceFile().fileName)) {
|
||||
references.push({ type: "node", node: (decl as ModuleDeclaration).name });
|
||||
references.push(nodeEntry((decl as ModuleDeclaration).name));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -422,7 +466,7 @@ namespace ts.FindAllReferences.Core {
|
||||
searchForImportsOfExport(node, symbol, { exportingModuleSymbol: Debug.assertDefined(symbol.parent, "Expected export symbol to have a parent"), exportKind: ExportKind.Default }, state);
|
||||
}
|
||||
else {
|
||||
const search = state.createSearch(node, symbol, /*comingFrom*/ undefined, { allSearchSymbols: node ? populateSearchSymbolSet(symbol, node, checker, !!options.implementations) : [symbol] });
|
||||
const search = state.createSearch(node, symbol, /*comingFrom*/ undefined, { allSearchSymbols: node ? populateSearchSymbolSet(symbol, node, checker, !!options.isForRename, !!options.implementations) : [symbol] });
|
||||
|
||||
// Try to get the smallest valid scope that we can limit our search to;
|
||||
// otherwise we'll need to search globally (i.e. include each file).
|
||||
@@ -581,21 +625,21 @@ namespace ts.FindAllReferences.Core {
|
||||
* Callback to add references for a particular searched symbol.
|
||||
* This initializes a reference group, so only call this if you will add at least one reference.
|
||||
*/
|
||||
referenceAdder(searchSymbol: Symbol): (node: Node) => void {
|
||||
referenceAdder(searchSymbol: Symbol): (node: Node, kind?: NodeEntryKind) => void {
|
||||
const symbolId = getSymbolId(searchSymbol);
|
||||
let references = this.symbolIdToReferences[symbolId];
|
||||
if (!references) {
|
||||
references = this.symbolIdToReferences[symbolId] = [];
|
||||
this.result.push({ definition: { type: DefinitionKind.Symbol, symbol: searchSymbol }, references });
|
||||
}
|
||||
return node => references.push(nodeEntry(node));
|
||||
return (node, kind) => references.push(nodeEntry(node, kind));
|
||||
}
|
||||
|
||||
/** Add a reference with no associated definition. */
|
||||
addStringOrCommentReference(fileName: string, textSpan: TextSpan): void {
|
||||
this.result.push({
|
||||
definition: undefined,
|
||||
references: [{ type: "span", fileName, textSpan }]
|
||||
references: [{ kind: EntryKind.Span, fileName, textSpan }]
|
||||
});
|
||||
}
|
||||
|
||||
@@ -707,21 +751,6 @@ namespace ts.FindAllReferences.Core {
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function getObjectBindingElementWithoutPropertyName(symbol: Symbol): BindingElement & { name: Identifier } | undefined {
|
||||
const bindingElement = getDeclarationOfKind<BindingElement>(symbol, SyntaxKind.BindingElement);
|
||||
if (bindingElement &&
|
||||
bindingElement.parent.kind === SyntaxKind.ObjectBindingPattern &&
|
||||
isIdentifier(bindingElement.name) &&
|
||||
!bindingElement.propertyName) {
|
||||
return bindingElement as BindingElement & { name: Identifier };
|
||||
}
|
||||
}
|
||||
|
||||
function getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol: Symbol, checker: TypeChecker): Symbol | undefined {
|
||||
const bindingElement = getObjectBindingElementWithoutPropertyName(symbol);
|
||||
return bindingElement && getPropertySymbolFromBindingElement(checker, bindingElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the smallest scope in which a symbol may have named references.
|
||||
* Note that not every construct has been accounted for. This function can
|
||||
@@ -754,7 +783,7 @@ namespace ts.FindAllReferences.Core {
|
||||
|
||||
// If symbol is of object binding pattern element without property name we would want to
|
||||
// look for property too and that could be anywhere
|
||||
if (getObjectBindingElementWithoutPropertyName(symbol)) {
|
||||
if (declarations.some(isObjectBindingElementWithoutPropertyName)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -1099,13 +1128,14 @@ namespace ts.FindAllReferences.Core {
|
||||
}
|
||||
}
|
||||
|
||||
function addReference(referenceLocation: Node, relatedSymbol: Symbol, state: State): void {
|
||||
const addRef = state.referenceAdder(relatedSymbol);
|
||||
function addReference(referenceLocation: Node, relatedSymbol: Symbol | RelatedSymbol, state: State): void {
|
||||
const { kind, symbol } = "kind" in relatedSymbol ? relatedSymbol : { kind: undefined, symbol: relatedSymbol };
|
||||
const addRef = state.referenceAdder(symbol);
|
||||
if (state.options.implementations) {
|
||||
addImplementationReferences(referenceLocation, addRef, state);
|
||||
}
|
||||
else {
|
||||
addRef(referenceLocation);
|
||||
addRef(referenceLocation, kind);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1428,7 +1458,7 @@ namespace ts.FindAllReferences.Core {
|
||||
const references = flatMap(sourceFiles, sourceFile => {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
return mapDefined(getPossibleSymbolReferenceNodes(sourceFile, node.text), ref =>
|
||||
isStringLiteral(ref) && ref.text === node.text ? nodeEntry(ref, /*isInString*/ true) : undefined);
|
||||
isStringLiteral(ref) && ref.text === node.text ? nodeEntry(ref, EntryKind.StringLiteral) : undefined);
|
||||
});
|
||||
|
||||
return [{
|
||||
@@ -1439,35 +1469,21 @@ namespace ts.FindAllReferences.Core {
|
||||
|
||||
// For certain symbol kinds, we need to include other symbols in the search set.
|
||||
// This is not needed when searching for re-exports.
|
||||
function populateSearchSymbolSet(symbol: Symbol, location: Node, checker: TypeChecker, implementations: boolean): Symbol[] {
|
||||
function populateSearchSymbolSet(symbol: Symbol, location: Node, checker: TypeChecker, isForRename: boolean, implementations: boolean): Symbol[] {
|
||||
const result: Symbol[] = [];
|
||||
forEachRelatedSymbol<void>(symbol, location, checker,
|
||||
forEachRelatedSymbol<void>(symbol, location, checker, isForRename,
|
||||
(sym, root, base) => { result.push(base || root || sym); },
|
||||
/*allowBaseTypes*/ () => !implementations);
|
||||
return result;
|
||||
}
|
||||
|
||||
function forEachRelatedSymbol<T>(
|
||||
symbol: Symbol, location: Node, checker: TypeChecker,
|
||||
cbSymbol: (symbol: Symbol, rootSymbol?: Symbol, baseSymbol?: Symbol) => T | undefined,
|
||||
symbol: Symbol, location: Node, checker: TypeChecker, isForRenamePopulateSearchSymbolSet: boolean,
|
||||
cbSymbol: (symbol: Symbol, rootSymbol?: Symbol, baseSymbol?: Symbol, kind?: NodeEntryKind) => T | undefined,
|
||||
allowBaseTypes: (rootSymbol: Symbol) => boolean,
|
||||
): T | undefined {
|
||||
const containingObjectLiteralElement = getContainingObjectLiteralElement(location);
|
||||
if (containingObjectLiteralElement) {
|
||||
// If the location is in a context sensitive location (i.e. in an object literal) try
|
||||
// to get a contextual type for it, and add the property symbol from the contextual
|
||||
// type to the search set
|
||||
const contextualType = checker.getContextualType(containingObjectLiteralElement.parent);
|
||||
const res = contextualType && firstDefined(getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker, contextualType, /*unionSymbolOk*/ true), fromRoot);
|
||||
if (res) return res;
|
||||
|
||||
// If the location is name of property symbol from object literal destructuring pattern
|
||||
// Search the property symbol
|
||||
// for ( { property: p2 } of elems) { }
|
||||
const propertySymbol = getPropertySymbolOfDestructuringAssignment(location, checker);
|
||||
const res1 = propertySymbol && cbSymbol(propertySymbol);
|
||||
if (res1) return res1;
|
||||
|
||||
/* Because in short-hand property assignment, location has two meaning : property name and as value of the property
|
||||
* When we do findAllReference at the position of the short-hand property assignment, we would want to have references to position of
|
||||
* property name and variable declaration of the identifier.
|
||||
@@ -1479,8 +1495,29 @@ namespace ts.FindAllReferences.Core {
|
||||
* so that when matching with potential reference symbol, both symbols from property declaration and variable declaration
|
||||
* will be included correctly.
|
||||
*/
|
||||
const shorthandValueSymbol = checker.getShorthandAssignmentValueSymbol(location.parent);
|
||||
const res2 = shorthandValueSymbol && cbSymbol(shorthandValueSymbol);
|
||||
const shorthandValueSymbol = checker.getShorthandAssignmentValueSymbol(location.parent); // gets the local symbol
|
||||
if (shorthandValueSymbol && isForRenamePopulateSearchSymbolSet) {
|
||||
// When renaming 'x' in `const o = { x }`, just rename the local variable, not the property.
|
||||
return cbSymbol(shorthandValueSymbol, /*rootSymbol*/ undefined, /*baseSymbol*/ undefined, EntryKind.SearchedLocalFoundProperty);
|
||||
}
|
||||
|
||||
// If the location is in a context sensitive location (i.e. in an object literal) try
|
||||
// to get a contextual type for it, and add the property symbol from the contextual
|
||||
// type to the search set
|
||||
const contextualType = checker.getContextualType(containingObjectLiteralElement.parent);
|
||||
const res = contextualType && firstDefined(
|
||||
getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker, contextualType, /*unionSymbolOk*/ true),
|
||||
sym => fromRoot(sym, EntryKind.SearchedPropertyFoundLocal));
|
||||
if (res) return res;
|
||||
|
||||
// If the location is name of property symbol from object literal destructuring pattern
|
||||
// Search the property symbol
|
||||
// for ( { property: p2 } of elems) { }
|
||||
const propertySymbol = getPropertySymbolOfDestructuringAssignment(location, checker);
|
||||
const res1 = propertySymbol && cbSymbol(propertySymbol, /*rootSymbol*/ undefined, /*baseSymbol*/ undefined, EntryKind.SearchedPropertyFoundLocal);
|
||||
if (res1) return res1;
|
||||
|
||||
const res2 = shorthandValueSymbol && cbSymbol(shorthandValueSymbol, /*rootSymbol*/ undefined, /*baseSymbol*/ undefined, EntryKind.SearchedLocalFoundProperty);
|
||||
if (res2) return res2;
|
||||
}
|
||||
|
||||
@@ -1494,12 +1531,14 @@ namespace ts.FindAllReferences.Core {
|
||||
return fromRoot(symbol.flags & SymbolFlags.FunctionScopedVariable ? paramProps[1] : paramProps[0]);
|
||||
}
|
||||
|
||||
// If this is symbol of binding element without propertyName declaration in Object binding pattern
|
||||
// Include the property in the search
|
||||
const bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol, checker);
|
||||
return bindingElementPropertySymbol && fromRoot(bindingElementPropertySymbol);
|
||||
// symbolAtLocation for a binding element is the local symbol. See if the search symbol is the property.
|
||||
// Don't do this when populating search set for a rename -- just rename the local.
|
||||
if (!isForRenamePopulateSearchSymbolSet) {
|
||||
const bindingElementPropertySymbol = isObjectBindingElementWithoutPropertyName(location.parent) ? getPropertySymbolFromBindingElement(checker, location.parent) : undefined;
|
||||
return bindingElementPropertySymbol && fromRoot(bindingElementPropertySymbol, EntryKind.SearchedPropertyFoundLocal);
|
||||
}
|
||||
|
||||
function fromRoot(sym: Symbol): T | undefined {
|
||||
function fromRoot(sym: Symbol, kind?: NodeEntryKind): T | undefined {
|
||||
// If this is a union property:
|
||||
// - In populateSearchSymbolsSet we will add all the symbols from all its source symbols in all unioned types.
|
||||
// - In findRelatedSymbol, we will just use the union symbol if any source symbol is included in the search.
|
||||
@@ -1507,20 +1546,24 @@ namespace ts.FindAllReferences.Core {
|
||||
// - In populateSearchSymbolsSet, add the root the list
|
||||
// - In findRelatedSymbol, return the source symbol if that is in the search. (Do not return the instantiation symbol.)
|
||||
return firstDefined(checker.getRootSymbols(sym), rootSymbol =>
|
||||
cbSymbol(sym, rootSymbol)
|
||||
cbSymbol(sym, rootSymbol, /*baseSymbol*/ undefined, kind)
|
||||
// Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions
|
||||
|| (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface) && allowBaseTypes(rootSymbol)
|
||||
? getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, checker, base => cbSymbol(sym, rootSymbol, base))
|
||||
? getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, checker, base => cbSymbol(sym, rootSymbol, base, kind))
|
||||
: undefined));
|
||||
}
|
||||
}
|
||||
|
||||
function getRelatedSymbol(search: Search, referenceSymbol: Symbol, referenceLocation: Node, state: State): Symbol | undefined {
|
||||
interface RelatedSymbol {
|
||||
readonly symbol: Symbol;
|
||||
readonly kind: NodeEntryKind | undefined;
|
||||
}
|
||||
function getRelatedSymbol(search: Search, referenceSymbol: Symbol, referenceLocation: Node, state: State): RelatedSymbol | undefined {
|
||||
const { checker } = state;
|
||||
return forEachRelatedSymbol(referenceSymbol, referenceLocation, checker,
|
||||
(sym, rootSymbol, baseSymbol) => search.includes(baseSymbol || rootSymbol || sym)
|
||||
return forEachRelatedSymbol(referenceSymbol, referenceLocation, checker, /*isForRenamePopulateSearchSymbolSet*/ false,
|
||||
(sym, rootSymbol, baseSymbol, kind): RelatedSymbol | undefined => search.includes(baseSymbol || rootSymbol || sym)
|
||||
// For a base type, use the symbol for the derived type. For a synthetic (e.g. union) property, use the union symbol.
|
||||
? rootSymbol && !(getCheckFlags(sym) & CheckFlags.Synthetic) ? rootSymbol : sym
|
||||
? { symbol: rootSymbol && !(getCheckFlags(sym) & CheckFlags.Synthetic) ? rootSymbol : sym, kind }
|
||||
: undefined,
|
||||
/*allowBaseTypes*/ rootSymbol =>
|
||||
!(search.parents && !search.parents.some(parent => explicitlyInheritsFrom(rootSymbol.parent!, parent, state.inheritsFromCache, checker))));
|
||||
|
||||
@@ -631,28 +631,50 @@ namespace ts.NavigationBar {
|
||||
}
|
||||
|
||||
function getFunctionOrClassName(node: FunctionExpression | FunctionDeclaration | ArrowFunction | ClassLikeDeclaration): string {
|
||||
const { parent } = node;
|
||||
if (node.name && getFullWidth(node.name) > 0) {
|
||||
return declarationNameToString(node.name);
|
||||
}
|
||||
// See if it is a var initializer. If so, use the var name.
|
||||
else if (node.parent.kind === SyntaxKind.VariableDeclaration) {
|
||||
return declarationNameToString((node.parent as VariableDeclaration).name);
|
||||
else if (isVariableDeclaration(parent)) {
|
||||
return declarationNameToString(parent.name);
|
||||
}
|
||||
// See if it is of the form "<expr> = function(){...}". If so, use the text from the left-hand side.
|
||||
else if (node.parent.kind === SyntaxKind.BinaryExpression &&
|
||||
(node.parent as BinaryExpression).operatorToken.kind === SyntaxKind.EqualsToken) {
|
||||
return nodeText((node.parent as BinaryExpression).left).replace(whiteSpaceRegex, "");
|
||||
else if (isBinaryExpression(parent) && parent.operatorToken.kind === SyntaxKind.EqualsToken) {
|
||||
return nodeText(parent.left).replace(whiteSpaceRegex, "");
|
||||
}
|
||||
// See if it is a property assignment, and if so use the property name
|
||||
else if (node.parent.kind === SyntaxKind.PropertyAssignment && (node.parent as PropertyAssignment).name) {
|
||||
return nodeText((node.parent as PropertyAssignment).name);
|
||||
else if (isPropertyAssignment(parent)) {
|
||||
return nodeText(parent.name);
|
||||
}
|
||||
// Default exports are named "default"
|
||||
else if (getModifierFlags(node) & ModifierFlags.Default) {
|
||||
return "default";
|
||||
}
|
||||
else if (isClassLike(node)) {
|
||||
return "<class>";
|
||||
}
|
||||
else if (isCallExpression(parent)) {
|
||||
const name = getCalledExpressionName(parent.expression);
|
||||
if (name !== undefined) {
|
||||
const args = mapDefined(parent.arguments, a => isStringLiteral(a) ? a.getText(curSourceFile) : undefined).join(", ");
|
||||
return `${name}(${args}) callback`;
|
||||
}
|
||||
}
|
||||
return "<function>";
|
||||
}
|
||||
|
||||
function getCalledExpressionName(expr: Expression): string | undefined {
|
||||
if (isIdentifier(expr)) {
|
||||
return expr.text;
|
||||
}
|
||||
else if (isPropertyAccessExpression(expr)) {
|
||||
const left = getCalledExpressionName(expr.expression);
|
||||
const right = expr.name.text;
|
||||
return left === undefined ? right : `${left}.${right}`;
|
||||
}
|
||||
else {
|
||||
return isClassLike(node) ? "<class>" : "<function>";
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -226,7 +226,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
|
||||
const { file, program, cancellationToken } = context;
|
||||
|
||||
const referenceEntries = mapDefined(FindAllReferences.getReferenceEntriesForNode(originalName.parent.pos, originalName, program, [file], cancellationToken!), entry => // TODO: GH#18217
|
||||
(entry.type === "node" && rangeContainsRange(constructor, entry.node) && isIdentifier(entry.node) && isWriteAccess(entry.node)) ? entry.node : undefined);
|
||||
(entry.kind !== FindAllReferences.EntryKind.Span && rangeContainsRange(constructor, entry.node) && isIdentifier(entry.node) && isWriteAccess(entry.node)) ? entry.node : undefined);
|
||||
|
||||
forEach(referenceEntries, entry => {
|
||||
const parent = entry.parent;
|
||||
|
||||
@@ -158,7 +158,7 @@ namespace ts.refactor {
|
||||
|
||||
const shouldMove = (name: Identifier): boolean => {
|
||||
const symbol = isBindingElement(name.parent)
|
||||
? getPropertySymbolFromBindingElement(checker, name.parent as BindingElement & { name: Identifier })
|
||||
? getPropertySymbolFromBindingElement(checker, name.parent as ObjectBindingElementWithoutPropertyName)
|
||||
: skipAlias(checker.getSymbolAtLocation(name)!, checker); // TODO: GH#18217
|
||||
return !!symbol && movedSymbols.has(symbol);
|
||||
};
|
||||
|
||||
+3
-14
@@ -56,37 +56,26 @@ namespace ts.Rename {
|
||||
fileToRename: name,
|
||||
kind,
|
||||
displayName: name,
|
||||
localizedErrorMessage: undefined,
|
||||
fullDisplayName: name,
|
||||
kindModifiers: ScriptElementKindModifier.none,
|
||||
triggerSpan,
|
||||
};
|
||||
}
|
||||
|
||||
function getRenameInfoSuccess(displayName: string, fullDisplayName: string, kind: ScriptElementKind, kindModifiers: string, node: Node, sourceFile: SourceFile): RenameInfo {
|
||||
function getRenameInfoSuccess(displayName: string, fullDisplayName: string, kind: ScriptElementKind, kindModifiers: string, node: Node, sourceFile: SourceFile): RenameInfoSuccess {
|
||||
return {
|
||||
canRename: true,
|
||||
fileToRename: undefined,
|
||||
kind,
|
||||
displayName,
|
||||
localizedErrorMessage: undefined,
|
||||
fullDisplayName,
|
||||
kindModifiers,
|
||||
triggerSpan: createTriggerSpanForNode(node, sourceFile)
|
||||
};
|
||||
}
|
||||
|
||||
function getRenameInfoError(diagnostic: DiagnosticMessage): RenameInfo {
|
||||
// TODO: GH#18217
|
||||
return {
|
||||
canRename: false,
|
||||
localizedErrorMessage: getLocaleSpecificMessage(diagnostic),
|
||||
displayName: undefined!,
|
||||
fullDisplayName: undefined!,
|
||||
kind: undefined!,
|
||||
kindModifiers: undefined!,
|
||||
triggerSpan: undefined!
|
||||
};
|
||||
function getRenameInfoError(diagnostic: DiagnosticMessage): RenameInfoFailure {
|
||||
return { canRename: false, localizedErrorMessage: getLocaleSpecificMessage(diagnostic) };
|
||||
}
|
||||
|
||||
function createTriggerSpanForNode(node: Node, sourceFile: SourceFile) {
|
||||
|
||||
@@ -541,6 +541,7 @@ namespace ts {
|
||||
public fileName: string;
|
||||
public path: Path;
|
||||
public resolvedPath: Path;
|
||||
public originalFileName: string;
|
||||
public text: string;
|
||||
public scriptSnapshot: IScriptSnapshot;
|
||||
public lineMap: ReadonlyArray<number>;
|
||||
@@ -1382,7 +1383,7 @@ namespace ts {
|
||||
// Therefore only get diagnostics for given file.
|
||||
|
||||
const semanticDiagnostics = program.getSemanticDiagnostics(targetSourceFile, cancellationToken);
|
||||
if (!program.getCompilerOptions().declaration) {
|
||||
if (!getEmitDeclarations(program.getCompilerOptions())) {
|
||||
return semanticDiagnostics.slice();
|
||||
}
|
||||
|
||||
@@ -1543,20 +1544,20 @@ namespace ts {
|
||||
const node = getTouchingPropertyName(sourceFile, position);
|
||||
if (isIdentifier(node) && isJsxOpeningElement(node.parent) || isJsxClosingElement(node.parent)) {
|
||||
const { openingElement, closingElement } = node.parent.parent;
|
||||
return [openingElement, closingElement].map((node): RenameLocation => ({ fileName: sourceFile.fileName, textSpan: createTextSpanFromNode(node.tagName, sourceFile) }));
|
||||
return [openingElement, closingElement].map((node): RenameLocation =>
|
||||
({ fileName: sourceFile.fileName, textSpan: createTextSpanFromNode(node.tagName, sourceFile) }));
|
||||
}
|
||||
else {
|
||||
const refs = getReferences(node, position, { findInStrings, findInComments, isForRename: true });
|
||||
return refs && refs.map(({ fileName, textSpan }): RenameLocation => ({ fileName, textSpan }));
|
||||
return getReferencesWorker(node, position, { findInStrings, findInComments, isForRename: true }, FindAllReferences.toRenameLocation);
|
||||
}
|
||||
}
|
||||
|
||||
function getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[] | undefined {
|
||||
synchronizeHostData();
|
||||
return getReferences(getTouchingPropertyName(getValidSourceFile(fileName), position), position);
|
||||
return getReferencesWorker(getTouchingPropertyName(getValidSourceFile(fileName), position), position, {}, FindAllReferences.toReferenceEntry);
|
||||
}
|
||||
|
||||
function getReferences(node: Node, position: number, options?: FindAllReferences.Options): ReferenceEntry[] | undefined {
|
||||
function getReferencesWorker<T>(node: Node, position: number, options: FindAllReferences.Options, cb: FindAllReferences.ToReferenceOrRenameEntry<T>): T[] | undefined {
|
||||
synchronizeHostData();
|
||||
|
||||
// Exclude default library when renaming as commonly user don't want to change that file.
|
||||
@@ -1564,7 +1565,7 @@ namespace ts {
|
||||
? program.getSourceFiles().filter(sourceFile => !program.isSourceFileDefaultLibrary(sourceFile))
|
||||
: program.getSourceFiles();
|
||||
|
||||
return FindAllReferences.findReferencedEntries(program, cancellationToken, sourceFiles, node, position, options);
|
||||
return FindAllReferences.findReferenceOrRenameEntries(program, cancellationToken, sourceFiles, node, position, options, cb);
|
||||
}
|
||||
|
||||
function findReferences(fileName: string, position: number): ReferencedSymbol[] | undefined {
|
||||
|
||||
@@ -48,6 +48,7 @@ namespace ts {
|
||||
options.paths = undefined;
|
||||
options.rootDirs = undefined;
|
||||
options.declaration = undefined;
|
||||
options.composite = undefined;
|
||||
options.declarationDir = undefined;
|
||||
options.out = undefined;
|
||||
options.outFile = undefined;
|
||||
|
||||
@@ -619,6 +619,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
export interface RenameLocation extends DocumentSpan {
|
||||
readonly prefixText?: string;
|
||||
readonly suffixText?: string;
|
||||
}
|
||||
|
||||
export interface ReferenceEntry extends DocumentSpan {
|
||||
@@ -819,20 +821,24 @@ namespace ts {
|
||||
tags?: JSDocTagInfo[];
|
||||
}
|
||||
|
||||
export interface RenameInfo {
|
||||
canRename: boolean;
|
||||
export type RenameInfo = RenameInfoSuccess | RenameInfoFailure;
|
||||
export interface RenameInfoSuccess {
|
||||
canRename: true;
|
||||
/**
|
||||
* File or directory to rename.
|
||||
* If set, `getEditsForFileRename` should be called instead of `findRenameLocations`.
|
||||
*/
|
||||
fileToRename?: string;
|
||||
localizedErrorMessage?: string;
|
||||
displayName: string;
|
||||
fullDisplayName: string;
|
||||
kind: ScriptElementKind;
|
||||
kindModifiers: string;
|
||||
triggerSpan: TextSpan;
|
||||
}
|
||||
export interface RenameInfoFailure {
|
||||
canRename: false;
|
||||
localizedErrorMessage: string;
|
||||
}
|
||||
|
||||
export interface SignatureHelpParameter {
|
||||
name: string;
|
||||
|
||||
@@ -1325,7 +1325,16 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
|
||||
export function getPropertySymbolFromBindingElement(checker: TypeChecker, bindingElement: BindingElement & { name: Identifier }) {
|
||||
export type ObjectBindingElementWithoutPropertyName = BindingElement & { name: Identifier };
|
||||
|
||||
export function isObjectBindingElementWithoutPropertyName(bindingElement: Node): bindingElement is ObjectBindingElementWithoutPropertyName {
|
||||
return isBindingElement(bindingElement) &&
|
||||
isObjectBindingPattern(bindingElement.parent) &&
|
||||
isIdentifier(bindingElement.name) &&
|
||||
!bindingElement.propertyName;
|
||||
}
|
||||
|
||||
export function getPropertySymbolFromBindingElement(checker: TypeChecker, bindingElement: ObjectBindingElementWithoutPropertyName) {
|
||||
const typeOfPattern = checker.getTypeAtLocation(bindingElement.parent);
|
||||
const propSymbol = typeOfPattern && checker.getPropertyOfType(typeOfPattern, bindingElement.name.text);
|
||||
if (propSymbol && propSymbol.flags & SymbolFlags.Accessor) {
|
||||
|
||||
@@ -138,7 +138,6 @@ function handleTestConfig() {
|
||||
case "compiler":
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Regressions));
|
||||
runners.push(new project.ProjectRunner());
|
||||
break;
|
||||
case "conformance":
|
||||
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
|
||||
|
||||
@@ -96,6 +96,11 @@ namespace ts {
|
||||
include: null,
|
||||
files: ["../main.ts"]
|
||||
}),
|
||||
"dev/configs/fifth.json": JSON.stringify({
|
||||
extends: "./fourth",
|
||||
include: ["../tests/utils.ts"],
|
||||
files: []
|
||||
}),
|
||||
"dev/extends.json": JSON.stringify({ extends: 42 }),
|
||||
"dev/extends2.json": JSON.stringify({ extends: "configs/base" }),
|
||||
"dev/main.ts": "",
|
||||
@@ -245,6 +250,15 @@ namespace ts {
|
||||
combinePaths(basePath, "main.ts")
|
||||
]);
|
||||
|
||||
testSuccess("can overwrite top-level files using extended []", "configs/fifth.json", {
|
||||
allowJs: true,
|
||||
noImplicitAny: true,
|
||||
strictNullChecks: true,
|
||||
module: ModuleKind.System
|
||||
}, [
|
||||
combinePaths(basePath, "tests/utils.ts")
|
||||
]);
|
||||
|
||||
it("adds extendedSourceFiles only once", () => {
|
||||
const sourceFile = readJsonConfigFile("configs/fourth.json", (path) => host.readFile(path));
|
||||
const dir = combinePaths(basePath, "configs");
|
||||
|
||||
@@ -1,33 +1,50 @@
|
||||
namespace ts {
|
||||
describe("convertCompilerOptionsFromJson", () => {
|
||||
function assertCompilerOptions(json: any, configFileName: string, expectedResult: { compilerOptions: CompilerOptions, errors: Diagnostic[] }) {
|
||||
const formatDiagnosticHost: FormatDiagnosticsHost = {
|
||||
getCurrentDirectory: () => "/apath/",
|
||||
getCanonicalFileName: createGetCanonicalFileName(/*useCaseSensitiveFileNames*/ true),
|
||||
getNewLine: () => "\n"
|
||||
};
|
||||
|
||||
interface ExpectedResultWithParsingSuccess {
|
||||
compilerOptions: CompilerOptions;
|
||||
errors: ReadonlyArray<Diagnostic>;
|
||||
}
|
||||
|
||||
interface ExpectedResultWithParsingFailure {
|
||||
compilerOptions: CompilerOptions;
|
||||
hasParseErrors: true;
|
||||
}
|
||||
|
||||
type ExpectedResult = ExpectedResultWithParsingSuccess | ExpectedResultWithParsingFailure;
|
||||
|
||||
function isExpectedResultWithParsingFailure(expectedResult: ExpectedResult): expectedResult is ExpectedResultWithParsingFailure {
|
||||
return !!(expectedResult as ExpectedResultWithParsingFailure).hasParseErrors;
|
||||
}
|
||||
|
||||
function assertCompilerOptions(json: any, configFileName: string, expectedResult: ExpectedResultWithParsingSuccess) {
|
||||
assertCompilerOptionsWithJson(json, configFileName, expectedResult);
|
||||
assertCompilerOptionsWithJsonNode(json, configFileName, expectedResult);
|
||||
}
|
||||
|
||||
function assertCompilerOptionsWithJson(json: any, configFileName: string, expectedResult: { compilerOptions: CompilerOptions, errors: Diagnostic[] }) {
|
||||
const { options: actualCompilerOptions, errors: actualErrors} = convertCompilerOptionsFromJson(json.compilerOptions, "/apath/", configFileName);
|
||||
function assertCompilerOptionsWithJson(json: any, configFileName: string, expectedResult: ExpectedResultWithParsingSuccess) {
|
||||
const { options: actualCompilerOptions, errors: actualErrors } = convertCompilerOptionsFromJson(json.compilerOptions, "/apath/", configFileName);
|
||||
|
||||
const parsedCompilerOptions = JSON.stringify(actualCompilerOptions);
|
||||
const expectedCompilerOptions = JSON.stringify({ ...expectedResult.compilerOptions, configFilePath: configFileName });
|
||||
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)}.`);
|
||||
for (let i = 0; i < actualErrors.length; i++) {
|
||||
const actualError = actualErrors[i];
|
||||
const expectedError = expectedErrors[i];
|
||||
assert.equal(actualError.code, expectedError.code);
|
||||
assert.equal(actualError.category, expectedError.category);
|
||||
assert.equal(actualError.messageText, expectedError.messageText);
|
||||
}
|
||||
verifyErrors(actualErrors, expectedResult.errors, /*ignoreLocation*/ true);
|
||||
}
|
||||
|
||||
function assertCompilerOptionsWithJsonNode(json: any, configFileName: string, expectedResult: { compilerOptions: CompilerOptions, errors: Diagnostic[] }) {
|
||||
const fileText = JSON.stringify(json);
|
||||
function assertCompilerOptionsWithJsonNode(json: any, configFileName: string, expectedResult: ExpectedResultWithParsingSuccess) {
|
||||
assertCompilerOptionsWithJsonText(JSON.stringify(json), configFileName, expectedResult);
|
||||
}
|
||||
|
||||
function assertCompilerOptionsWithJsonText(fileText: string, configFileName: string, expectedResult: ExpectedResult) {
|
||||
const result = parseJsonText(configFileName, fileText);
|
||||
assert(!result.parseDiagnostics.length);
|
||||
assert(!!result.endOfFileToken);
|
||||
assert.equal(!!result.parseDiagnostics.length, isExpectedResultWithParsingFailure(expectedResult));
|
||||
const host: ParseConfigHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: "/apath/" }));
|
||||
const { options: actualCompilerOptions, errors: actualParseErrors } = parseJsonSourceFileConfigFileContent(result, host, "/apath/", /*existingOptions*/ undefined, configFileName);
|
||||
expectedResult.compilerOptions.configFilePath = configFileName;
|
||||
@@ -37,17 +54,32 @@ namespace ts {
|
||||
assert.equal(parsedCompilerOptions, expectedCompilerOptions);
|
||||
assert.equal(actualCompilerOptions.configFile, result);
|
||||
|
||||
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)}.`);
|
||||
if (!isExpectedResultWithParsingFailure(expectedResult)) {
|
||||
verifyErrors(actualParseErrors.filter(error => error.code !== Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code), expectedResult.errors);
|
||||
}
|
||||
}
|
||||
|
||||
function verifyErrors(actualErrors: Diagnostic[], expectedErrors: ReadonlyArray<Diagnostic>, ignoreLocation?: boolean) {
|
||||
assert.isTrue(expectedErrors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedErrors.map(getDiagnosticString), undefined, " ")}. Actual error: ${JSON.stringify(actualErrors.map(getDiagnosticString), undefined, " ")}.`);
|
||||
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);
|
||||
if (!ignoreLocation) {
|
||||
assert(actualError.file);
|
||||
assert(actualError.start);
|
||||
assert(actualError.length);
|
||||
}
|
||||
}
|
||||
|
||||
function getDiagnosticString(diagnostic: Diagnostic) {
|
||||
if (ignoreLocation) {
|
||||
const { file, ...rest } = diagnostic;
|
||||
diagnostic = { file: undefined, ...rest };
|
||||
}
|
||||
return formatDiagnostic(diagnostic, formatDiagnosticHost);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -539,5 +571,37 @@ namespace ts {
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it("Convert tsconfig options when there are multiple invalid strings", () => {
|
||||
assertCompilerOptionsWithJsonText(`{
|
||||
"compilerOptions": {
|
||||
"target": "<%- options.useTsWithBabel ? 'esnext' : 'es5' %>",
|
||||
"module": "esnext",
|
||||
<%_ if (options.classComponent) { _%>
|
||||
"experimentalDecorators": true,
|
||||
<%_ } _%>
|
||||
"sourceMap": true,
|
||||
"types": [
|
||||
"webpack-env"<% if (hasMocha || hasJest) { %>,<% } %>
|
||||
<%_ if (hasMocha) { _%>
|
||||
"mocha",
|
||||
"chai"
|
||||
<%_ } else if (hasJest) { _%>
|
||||
"jest"
|
||||
<%_ } _%>
|
||||
]
|
||||
}
|
||||
}
|
||||
`, "tsconfig.json",
|
||||
{
|
||||
compilerOptions: {
|
||||
target: undefined,
|
||||
module: ModuleKind.ESNext,
|
||||
types: []
|
||||
},
|
||||
hasParseErrors: true
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1241,6 +1241,19 @@ _testConvertToAsyncFunction("convertToAsyncFunction_nestedPromises", `
|
||||
function [#|f|]() {
|
||||
return fetch('https://typescriptlang.org').then(x => Promise.resolve(3).then(y => Promise.resolve(x.statusText.length + y)));
|
||||
}
|
||||
`);
|
||||
_testConvertToAsyncFunction("convertToAsyncFunction_noArgs", `
|
||||
function delay(millis: number): Promise<void> {
|
||||
throw "no"
|
||||
}
|
||||
|
||||
function [#|main2|]() {
|
||||
console.log("Please wait. Loading.");
|
||||
return delay(500)
|
||||
.then(() => { console.log("."); return delay(500); })
|
||||
.then(() => { console.log("."); return delay(500); })
|
||||
.then(() => { console.log("."); return delay(500); })
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
@@ -1251,4 +1264,4 @@ function [#|f|]() {
|
||||
function _testConvertToAsyncFunctionFailed(caption: string, text: string) {
|
||||
testConvertToAsyncFunction(caption, text, "convertToAsyncFunction", /*includeLib*/ true, /*expectFailure*/ true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,42 @@ namespace ts {
|
||||
assert(fs.existsSync(output), `Expect file ${output} to exist`);
|
||||
}
|
||||
});
|
||||
|
||||
it("builds correctly when outDir is specified", () => {
|
||||
const fs = projFs.shadow();
|
||||
fs.writeFileSync("/src/logic/tsconfig.json", JSON.stringify({
|
||||
compilerOptions: { composite: true, declaration: true, sourceMap: true, outDir: "outDir" },
|
||||
references: [{ path: "../core" }]
|
||||
}));
|
||||
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/tests"], {});
|
||||
builder.buildAllProjects();
|
||||
host.assertDiagnosticMessages(/*empty*/);
|
||||
const expectedOutputs = allExpectedOutputs.map(f => f.replace("/logic/", "/logic/outDir/"));
|
||||
// Check for outputs. Not an exhaustive list
|
||||
for (const output of expectedOutputs) {
|
||||
assert(fs.existsSync(output), `Expect file ${output} to exist`);
|
||||
}
|
||||
});
|
||||
|
||||
it("builds correctly when declarationDir is specified", () => {
|
||||
const fs = projFs.shadow();
|
||||
fs.writeFileSync("/src/logic/tsconfig.json", JSON.stringify({
|
||||
compilerOptions: { composite: true, declaration: true, sourceMap: true, declarationDir: "out/decls" },
|
||||
references: [{ path: "../core" }]
|
||||
}));
|
||||
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/tests"], {});
|
||||
builder.buildAllProjects();
|
||||
host.assertDiagnosticMessages(/*empty*/);
|
||||
const expectedOutputs = allExpectedOutputs.map(f => f.replace("/logic/index.d.ts", "/logic/out/decls/index.d.ts"));
|
||||
// Check for outputs. Not an exhaustive list
|
||||
for (const output of expectedOutputs) {
|
||||
assert(fs.existsSync(output), `Expect file ${output} to exist`);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("tsbuild - dry builds", () => {
|
||||
@@ -321,6 +357,25 @@ export class cNew {}`);
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("tsbuild - with rootDir of project reference in parentDirectory", () => {
|
||||
const projFs = loadProjectFromDisk("tests/projects/projectReferenceWithRootDirInParent");
|
||||
const allExpectedOutputs = [
|
||||
"/src/dist/other/other.js", "/src/dist/other/other.d.ts",
|
||||
"/src/dist/main/a.js", "/src/dist/main/a.d.ts",
|
||||
"/src/dist/main/b.js", "/src/dist/main/b.d.ts"
|
||||
];
|
||||
it("verify that it builds correctly", () => {
|
||||
const fs = projFs.shadow();
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/src/main", "/src/src/other"], {});
|
||||
builder.buildAllProjects();
|
||||
host.assertDiagnosticMessages(/*empty*/);
|
||||
for (const output of allExpectedOutputs) {
|
||||
assert(fs.existsSync(output), `Expect file ${output} to exist`);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export namespace OutFile {
|
||||
|
||||
@@ -486,11 +486,7 @@ export function gfoo() {
|
||||
solutionBuilder.buildInvalidatedProject();
|
||||
|
||||
host.checkTimeoutQueueLengthAndRun(1);
|
||||
checkOutputErrorsIncremental(host, [
|
||||
// TODO: #26036
|
||||
// The error is reported in d.ts file because it isnt resolved from ts file path, but is resolved from .d.ts file
|
||||
"sample1/logic/decls/index.d.ts(2,22): error TS2307: Cannot find module '../core/anotherModule'.\n"
|
||||
]);
|
||||
checkOutputErrorsIncremental(host, emptyArray);
|
||||
checkProgramActualFiles(watch().getProgram(), [tests[1].path, libFile.path, coreIndexDts, coreAnotherModuleDts, projectFilePath(SubProject.logic, "decls/index.d.ts")]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -449,6 +449,14 @@ namespace ts.projectSystem {
|
||||
const toLocation = protocolToLocation(str);
|
||||
return { start: toLocation(span.start), end: toLocation(textSpanEnd(span)) };
|
||||
}
|
||||
function protocolRenameSpanFromSubstring(
|
||||
str: string,
|
||||
substring: string,
|
||||
options?: SpanFromSubstringOptions,
|
||||
prefixSuffixText?: { readonly prefixText?: string, readonly suffixText?: string },
|
||||
): protocol.RenameTextSpan {
|
||||
return { ...protocolTextSpanFromSubstring(str, substring, options), ...prefixSuffixText };
|
||||
}
|
||||
function textSpanFromSubstring(str: string, substring: string, options?: SpanFromSubstringOptions): TextSpan {
|
||||
const start = nthIndexOf(str, substring, options ? options.index : 0);
|
||||
Debug.assert(start !== -1);
|
||||
@@ -463,6 +471,9 @@ namespace ts.projectSystem {
|
||||
function documentSpanFromSubstring(file: File, substring: string, options?: SpanFromSubstringOptions): DocumentSpan {
|
||||
return { fileName: file.path, textSpan: textSpanFromSubstring(file.content, substring, options) };
|
||||
}
|
||||
function renameLocation(file: File, substring: string, options?: SpanFromSubstringOptions): RenameLocation {
|
||||
return documentSpanFromSubstring(file, substring, options);
|
||||
}
|
||||
interface SpanFromSubstringOptions {
|
||||
readonly index: number;
|
||||
}
|
||||
@@ -8284,21 +8295,21 @@ namespace ts.projectSystem {
|
||||
const response = executeSessionRequest<protocol.RenameRequest, protocol.RenameResponse>(session, protocol.CommandTypes.Rename, { file: aFc, ...protocolLocationFromSubstring(cFile.content, "C") });
|
||||
|
||||
assert.equal(aFile.content, bFile.content);
|
||||
const abLocs: protocol.TextSpan[] = [
|
||||
protocolTextSpanFromSubstring(aFile.content, "C"),
|
||||
protocolTextSpanFromSubstring(aFile.content, "C", { index: 1 }),
|
||||
const abLocs: protocol.RenameTextSpan[] = [
|
||||
protocolRenameSpanFromSubstring(aFile.content, "C"),
|
||||
protocolRenameSpanFromSubstring(aFile.content, "C", { index: 1 }),
|
||||
];
|
||||
const span = protocolTextSpanFromSubstring(cFile.content, "C");
|
||||
const cLocs: protocol.TextSpan[] = [span];
|
||||
const span = protocolRenameSpanFromSubstring(cFile.content, "C");
|
||||
const cLocs: protocol.RenameTextSpan[] = [span];
|
||||
assert.deepEqual<protocol.RenameResponseBody | undefined>(response, {
|
||||
info: {
|
||||
canRename: true,
|
||||
displayName: "C",
|
||||
fileToRename: undefined,
|
||||
fullDisplayName: '"/users/username/projects/a/c/fc".C',
|
||||
kind: ScriptElementKind.constElement,
|
||||
kindModifiers: ScriptElementKindModifier.exportedModifier,
|
||||
localizedErrorMessage: undefined,
|
||||
triggerSpan: span,
|
||||
triggerSpan: protocolTextSpanFromSubstring(cFile.content, "C"),
|
||||
},
|
||||
locs: [
|
||||
{ file: aFc, locs: cLocs },
|
||||
@@ -9462,8 +9473,7 @@ export function Test2() {
|
||||
content: "{}",
|
||||
};
|
||||
|
||||
const host = createServerHost([aTs, bTs, tsconfig]);
|
||||
const session = createSession(host);
|
||||
const session = createSession(createServerHost([aTs, bTs, tsconfig]));
|
||||
openFilesForSession([aTs, bTs], session);
|
||||
|
||||
const requestLocation: protocol.FileLocationRequestArgs = {
|
||||
@@ -9569,6 +9579,58 @@ export function Test2() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("tsserverProjectSystem rename", () => {
|
||||
it("works with fileToRename", () => {
|
||||
const aTs: File = { path: "/a.ts", content: "export const a = 0;" };
|
||||
const bTs: File = { path: "/b.ts", content: 'import { a } from "./a";' };
|
||||
|
||||
const session = createSession(createServerHost([aTs, bTs]));
|
||||
openFilesForSession([bTs], session);
|
||||
|
||||
const response = executeSessionRequest<protocol.RenameRequest, protocol.RenameResponse>(session, protocol.CommandTypes.Rename, protocolFileLocationFromSubstring(bTs, 'a";'));
|
||||
assert.deepEqual<protocol.RenameResponseBody | undefined>(response, {
|
||||
info: {
|
||||
canRename: true,
|
||||
fileToRename: aTs.path,
|
||||
displayName: aTs.path,
|
||||
fullDisplayName: aTs.path,
|
||||
kind: ScriptElementKind.moduleElement,
|
||||
kindModifiers: "",
|
||||
triggerSpan: protocolTextSpanFromSubstring(bTs.content, "a", { index: 1 }),
|
||||
},
|
||||
locs: [{ file: bTs.path, locs: [protocolRenameSpanFromSubstring(bTs.content, "./a")] }],
|
||||
});
|
||||
});
|
||||
|
||||
it("works with prefixText and suffixText", () => {
|
||||
const aTs: File = { path: "/a.ts", content: "const x = 0; const o = { x };" };
|
||||
const session = createSession(createServerHost([aTs]));
|
||||
openFilesForSession([aTs], session);
|
||||
|
||||
const response = executeSessionRequest<protocol.RenameRequest, protocol.RenameResponse>(session, protocol.CommandTypes.Rename, protocolFileLocationFromSubstring(aTs, "x"));
|
||||
assert.deepEqual<protocol.RenameResponseBody | undefined>(response, {
|
||||
info: {
|
||||
canRename: true,
|
||||
fileToRename: undefined,
|
||||
displayName: "x",
|
||||
fullDisplayName: "x",
|
||||
kind: ScriptElementKind.constElement,
|
||||
kindModifiers: ScriptElementKindModifier.none,
|
||||
triggerSpan: protocolTextSpanFromSubstring(aTs.content, "x"),
|
||||
},
|
||||
locs: [
|
||||
{
|
||||
file: aTs.path,
|
||||
locs: [
|
||||
protocolRenameSpanFromSubstring(aTs.content, "x"),
|
||||
protocolRenameSpanFromSubstring(aTs.content, "x", { index: 1 }, { prefixText: "x: " }),
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("tsserverProjectSystem typeReferenceDirectives", () => {
|
||||
it("when typeReferenceDirective contains UpperCasePackage", () => {
|
||||
const projectLocation = "/user/username/projects/myproject";
|
||||
@@ -10045,13 +10107,13 @@ declare class TestLib {
|
||||
|
||||
const renameATs = (aTs: File): protocol.SpanGroup => ({
|
||||
file: aTs.path,
|
||||
locs: [protocolTextSpanFromSubstring(aTs.content, "fnA")],
|
||||
locs: [protocolRenameSpanFromSubstring(aTs.content, "fnA")],
|
||||
});
|
||||
const renameUserTs = (userTs: File): protocol.SpanGroup => ({
|
||||
file: userTs.path,
|
||||
locs: [
|
||||
protocolTextSpanFromSubstring(userTs.content, "fnA"),
|
||||
protocolTextSpanFromSubstring(userTs.content, "fnA", { index: 1 }),
|
||||
protocolRenameSpanFromSubstring(userTs.content, "fnA"),
|
||||
protocolRenameSpanFromSubstring(userTs.content, "fnA", { index: 1 }),
|
||||
],
|
||||
});
|
||||
|
||||
@@ -10062,10 +10124,10 @@ declare class TestLib {
|
||||
info: {
|
||||
canRename: true,
|
||||
displayName: "fnA",
|
||||
fileToRename: undefined,
|
||||
fullDisplayName: "fnA",
|
||||
kind: ScriptElementKind.alias,
|
||||
kindModifiers: ScriptElementKindModifier.none,
|
||||
localizedErrorMessage: undefined,
|
||||
triggerSpan: protocolTextSpanFromSubstring(userTs.content, "fnA", { index: 1 }),
|
||||
},
|
||||
locs: [renameUserTs(userTs), renameATs(aTs)],
|
||||
@@ -10081,10 +10143,10 @@ declare class TestLib {
|
||||
info: {
|
||||
canRename: true,
|
||||
displayName: "fnA",
|
||||
fileToRename: undefined,
|
||||
fullDisplayName: '"/a/a".fnA',
|
||||
kind: ScriptElementKind.functionElement,
|
||||
kindModifiers: ScriptElementKindModifier.exportedModifier,
|
||||
localizedErrorMessage: undefined,
|
||||
triggerSpan: protocolTextSpanFromSubstring(aTs.content, "fnA"),
|
||||
},
|
||||
locs: [renameATs(aTs), renameUserTs(userTs)],
|
||||
@@ -10096,9 +10158,9 @@ declare class TestLib {
|
||||
const session = makeSampleProjects();
|
||||
const response = executeSessionRequest<protocol.RenameFullRequest, protocol.RenameFullResponse>(session, protocol.CommandTypes.RenameLocationsFull, protocolFileLocationFromSubstring(userTs, "fnA()"));
|
||||
assert.deepEqual<ReadonlyArray<RenameLocation>>(response, [
|
||||
documentSpanFromSubstring(userTs, "fnA"),
|
||||
documentSpanFromSubstring(userTs, "fnA", { index: 1 }),
|
||||
documentSpanFromSubstring(aTs, "fnA"),
|
||||
renameLocation(userTs, "fnA"),
|
||||
renameLocation(userTs, "fnA", { index: 1 }),
|
||||
renameLocation(aTs, "fnA"),
|
||||
]);
|
||||
verifyATsConfigOriginalProject(session);
|
||||
});
|
||||
@@ -10110,23 +10172,23 @@ declare class TestLib {
|
||||
info: {
|
||||
canRename: true,
|
||||
displayName: "fnB",
|
||||
fileToRename: undefined,
|
||||
fullDisplayName: "fnB",
|
||||
kind: ScriptElementKind.alias,
|
||||
kindModifiers: ScriptElementKindModifier.none,
|
||||
localizedErrorMessage: undefined,
|
||||
triggerSpan: protocolTextSpanFromSubstring(userTs.content, "fnB", { index: 1 }),
|
||||
},
|
||||
locs: [
|
||||
{
|
||||
file: userTs.path,
|
||||
locs: [
|
||||
protocolTextSpanFromSubstring(userTs.content, "fnB"),
|
||||
protocolTextSpanFromSubstring(userTs.content, "fnB", { index: 1 }),
|
||||
protocolRenameSpanFromSubstring(userTs.content, "fnB"),
|
||||
protocolRenameSpanFromSubstring(userTs.content, "fnB", { index: 1 }),
|
||||
],
|
||||
},
|
||||
{
|
||||
file: bDts.path,
|
||||
locs: [protocolTextSpanFromSubstring(bDts.content, "fnB")],
|
||||
locs: [protocolRenameSpanFromSubstring(bDts.content, "fnB")],
|
||||
}
|
||||
],
|
||||
});
|
||||
|
||||
@@ -520,6 +520,7 @@ namespace ts.server {
|
||||
globalPlugins,
|
||||
pluginProbeLocations,
|
||||
allowLocalPluginLoads,
|
||||
typesMapLocation,
|
||||
});
|
||||
|
||||
this.eventPort = eventPort;
|
||||
|
||||
+29
-12
@@ -14,7 +14,7 @@ and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
declare namespace ts {
|
||||
const versionMajorMinor = "3.1";
|
||||
const versionMajorMinor = "3.2";
|
||||
/** The version of the TypeScript compiler release */
|
||||
const version: string;
|
||||
}
|
||||
@@ -1082,7 +1082,7 @@ declare namespace ts {
|
||||
}
|
||||
interface ExpressionWithTypeArguments extends NodeWithTypeArguments {
|
||||
kind: SyntaxKind.ExpressionWithTypeArguments;
|
||||
parent: HeritageClause;
|
||||
parent: HeritageClause | JSDocAugmentsTag;
|
||||
expression: LeftHandSideExpression;
|
||||
}
|
||||
interface NewExpression extends PrimaryExpression, Declaration {
|
||||
@@ -2494,6 +2494,7 @@ declare namespace ts {
|
||||
sourceRoot?: string;
|
||||
strict?: boolean;
|
||||
strictFunctionTypes?: boolean;
|
||||
strictBindCallApply?: boolean;
|
||||
strictNullChecks?: boolean;
|
||||
strictPropertyInitialization?: boolean;
|
||||
stripInternal?: boolean;
|
||||
@@ -4959,6 +4960,8 @@ declare namespace ts {
|
||||
originalFileName?: string;
|
||||
}
|
||||
interface RenameLocation extends DocumentSpan {
|
||||
readonly prefixText?: string;
|
||||
readonly suffixText?: string;
|
||||
}
|
||||
interface ReferenceEntry extends DocumentSpan {
|
||||
isWriteAccess: boolean;
|
||||
@@ -5111,20 +5114,24 @@ declare namespace ts {
|
||||
documentation?: SymbolDisplayPart[];
|
||||
tags?: JSDocTagInfo[];
|
||||
}
|
||||
interface RenameInfo {
|
||||
canRename: boolean;
|
||||
type RenameInfo = RenameInfoSuccess | RenameInfoFailure;
|
||||
interface RenameInfoSuccess {
|
||||
canRename: true;
|
||||
/**
|
||||
* File or directory to rename.
|
||||
* If set, `getEditsForFileRename` should be called instead of `findRenameLocations`.
|
||||
*/
|
||||
fileToRename?: string;
|
||||
localizedErrorMessage?: string;
|
||||
displayName: string;
|
||||
fullDisplayName: string;
|
||||
kind: ScriptElementKind;
|
||||
kindModifiers: string;
|
||||
triggerSpan: TextSpan;
|
||||
}
|
||||
interface RenameInfoFailure {
|
||||
canRename: false;
|
||||
localizedErrorMessage: string;
|
||||
}
|
||||
interface SignatureHelpParameter {
|
||||
name: string;
|
||||
documentation: SymbolDisplayPart[];
|
||||
@@ -6434,20 +6441,17 @@ declare namespace ts.server.protocol {
|
||||
/**
|
||||
* Information about the item to be renamed.
|
||||
*/
|
||||
interface RenameInfo {
|
||||
type RenameInfo = RenameInfoSuccess | RenameInfoFailure;
|
||||
interface RenameInfoSuccess {
|
||||
/**
|
||||
* True if item can be renamed.
|
||||
*/
|
||||
canRename: boolean;
|
||||
canRename: true;
|
||||
/**
|
||||
* File or directory to rename.
|
||||
* If set, `getEditsForFileRename` should be called instead of `findRenameLocations`.
|
||||
*/
|
||||
fileToRename?: string;
|
||||
/**
|
||||
* Error message if item can not be renamed.
|
||||
*/
|
||||
localizedErrorMessage?: string;
|
||||
/**
|
||||
* Display name of the item to be renamed.
|
||||
*/
|
||||
@@ -6467,6 +6471,13 @@ declare namespace ts.server.protocol {
|
||||
/** Span of text to rename. */
|
||||
triggerSpan: TextSpan;
|
||||
}
|
||||
interface RenameInfoFailure {
|
||||
canRename: false;
|
||||
/**
|
||||
* Error message if item can not be renamed.
|
||||
*/
|
||||
localizedErrorMessage: string;
|
||||
}
|
||||
/**
|
||||
* A group of text spans, all in 'file'.
|
||||
*/
|
||||
@@ -6474,7 +6485,11 @@ declare namespace ts.server.protocol {
|
||||
/** The file to which the spans apply */
|
||||
file: string;
|
||||
/** The text spans in this group */
|
||||
locs: TextSpan[];
|
||||
locs: RenameTextSpan[];
|
||||
}
|
||||
interface RenameTextSpan extends TextSpan {
|
||||
readonly prefixText?: string;
|
||||
readonly suffixText?: string;
|
||||
}
|
||||
interface RenameResponseBody {
|
||||
/**
|
||||
@@ -8679,6 +8694,7 @@ declare namespace ts.server {
|
||||
globalPlugins?: ReadonlyArray<string>;
|
||||
pluginProbeLocations?: ReadonlyArray<string>;
|
||||
allowLocalPluginLoads?: boolean;
|
||||
typesMapLocation?: string;
|
||||
}
|
||||
class Session implements EventSender {
|
||||
private readonly gcTimer;
|
||||
@@ -8701,6 +8717,7 @@ declare namespace ts.server {
|
||||
private defaultEventHandler;
|
||||
private projectsUpdatedInBackgroundEvent;
|
||||
logError(err: Error, cmd: string): void;
|
||||
private logErrorWorker;
|
||||
send(msg: protocol.Message): void;
|
||||
event<T extends object>(body: T, eventName: string): void;
|
||||
/** @deprecated */
|
||||
|
||||
+12
-5
@@ -14,7 +14,7 @@ and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
declare namespace ts {
|
||||
const versionMajorMinor = "3.1";
|
||||
const versionMajorMinor = "3.2";
|
||||
/** The version of the TypeScript compiler release */
|
||||
const version: string;
|
||||
}
|
||||
@@ -1082,7 +1082,7 @@ declare namespace ts {
|
||||
}
|
||||
interface ExpressionWithTypeArguments extends NodeWithTypeArguments {
|
||||
kind: SyntaxKind.ExpressionWithTypeArguments;
|
||||
parent: HeritageClause;
|
||||
parent: HeritageClause | JSDocAugmentsTag;
|
||||
expression: LeftHandSideExpression;
|
||||
}
|
||||
interface NewExpression extends PrimaryExpression, Declaration {
|
||||
@@ -2494,6 +2494,7 @@ declare namespace ts {
|
||||
sourceRoot?: string;
|
||||
strict?: boolean;
|
||||
strictFunctionTypes?: boolean;
|
||||
strictBindCallApply?: boolean;
|
||||
strictNullChecks?: boolean;
|
||||
strictPropertyInitialization?: boolean;
|
||||
stripInternal?: boolean;
|
||||
@@ -4959,6 +4960,8 @@ declare namespace ts {
|
||||
originalFileName?: string;
|
||||
}
|
||||
interface RenameLocation extends DocumentSpan {
|
||||
readonly prefixText?: string;
|
||||
readonly suffixText?: string;
|
||||
}
|
||||
interface ReferenceEntry extends DocumentSpan {
|
||||
isWriteAccess: boolean;
|
||||
@@ -5111,20 +5114,24 @@ declare namespace ts {
|
||||
documentation?: SymbolDisplayPart[];
|
||||
tags?: JSDocTagInfo[];
|
||||
}
|
||||
interface RenameInfo {
|
||||
canRename: boolean;
|
||||
type RenameInfo = RenameInfoSuccess | RenameInfoFailure;
|
||||
interface RenameInfoSuccess {
|
||||
canRename: true;
|
||||
/**
|
||||
* File or directory to rename.
|
||||
* If set, `getEditsForFileRename` should be called instead of `findRenameLocations`.
|
||||
*/
|
||||
fileToRename?: string;
|
||||
localizedErrorMessage?: string;
|
||||
displayName: string;
|
||||
fullDisplayName: string;
|
||||
kind: ScriptElementKind;
|
||||
kindModifiers: string;
|
||||
triggerSpan: TextSpan;
|
||||
}
|
||||
interface RenameInfoFailure {
|
||||
canRename: false;
|
||||
localizedErrorMessage: string;
|
||||
}
|
||||
interface SignatureHelpParameter {
|
||||
name: string;
|
||||
documentation: SymbolDisplayPart[];
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
//// [bivariantInferences.ts]
|
||||
// Repro from #27337
|
||||
|
||||
interface Array<T> {
|
||||
equalsShallow<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>): boolean;
|
||||
}
|
||||
|
||||
declare const a: (string | number)[] | null[] | undefined[] | {}[];
|
||||
declare const b: (string | number)[] | null[] | undefined[] | {}[];
|
||||
|
||||
let x = a.equalsShallow(b);
|
||||
|
||||
|
||||
//// [bivariantInferences.js]
|
||||
"use strict";
|
||||
// Repro from #27337
|
||||
var x = a.equalsShallow(b);
|
||||
@@ -0,0 +1,31 @@
|
||||
=== tests/cases/conformance/types/typeRelationships/typeInference/bivariantInferences.ts ===
|
||||
// Repro from #27337
|
||||
|
||||
interface Array<T> {
|
||||
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(bivariantInferences.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(lib.es5.d.ts, --, --), Decl(bivariantInferences.ts, 2, 16))
|
||||
|
||||
equalsShallow<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>): boolean;
|
||||
>equalsShallow : Symbol(Array.equalsShallow, Decl(bivariantInferences.ts, 2, 20))
|
||||
>T : Symbol(T, Decl(bivariantInferences.ts, 3, 18))
|
||||
>this : Symbol(this, Decl(bivariantInferences.ts, 3, 21))
|
||||
>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(bivariantInferences.ts, 3, 18))
|
||||
>other : Symbol(other, Decl(bivariantInferences.ts, 3, 44))
|
||||
>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(bivariantInferences.ts, 3, 18))
|
||||
}
|
||||
|
||||
declare const a: (string | number)[] | null[] | undefined[] | {}[];
|
||||
>a : Symbol(a, Decl(bivariantInferences.ts, 6, 13))
|
||||
|
||||
declare const b: (string | number)[] | null[] | undefined[] | {}[];
|
||||
>b : Symbol(b, Decl(bivariantInferences.ts, 7, 13))
|
||||
|
||||
let x = a.equalsShallow(b);
|
||||
>x : Symbol(x, Decl(bivariantInferences.ts, 9, 3))
|
||||
>a.equalsShallow : Symbol(equalsShallow, Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20))
|
||||
>a : Symbol(a, Decl(bivariantInferences.ts, 6, 13))
|
||||
>equalsShallow : Symbol(equalsShallow, Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20))
|
||||
>b : Symbol(b, Decl(bivariantInferences.ts, 7, 13))
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
=== tests/cases/conformance/types/typeRelationships/typeInference/bivariantInferences.ts ===
|
||||
// Repro from #27337
|
||||
|
||||
interface Array<T> {
|
||||
equalsShallow<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>): boolean;
|
||||
>equalsShallow : <T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean
|
||||
>this : ReadonlyArray<T>
|
||||
>other : ReadonlyArray<T>
|
||||
}
|
||||
|
||||
declare const a: (string | number)[] | null[] | undefined[] | {}[];
|
||||
>a : (string | number)[] | null[] | undefined[] | {}[]
|
||||
>null : null
|
||||
|
||||
declare const b: (string | number)[] | null[] | undefined[] | {}[];
|
||||
>b : (string | number)[] | null[] | undefined[] | {}[]
|
||||
>null : null
|
||||
|
||||
let x = a.equalsShallow(b);
|
||||
>x : boolean
|
||||
>a.equalsShallow(b) : boolean
|
||||
>a.equalsShallow : (<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean) | (<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean) | (<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean) | (<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean)
|
||||
>a : (string | number)[] | null[] | undefined[] | {}[]
|
||||
>equalsShallow : (<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean) | (<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean) | (<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean) | (<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean)
|
||||
>b : (string | number)[] | null[] | undefined[] | {}[]
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
error TS2318: Cannot find global type 'CallableFunction'.
|
||||
error TS2318: Cannot find global type 'NewableFunction'.
|
||||
|
||||
|
||||
!!! error TS2318: Cannot find global type 'CallableFunction'.
|
||||
!!! error TS2318: Cannot find global type 'NewableFunction'.
|
||||
==== tests/cases/compiler/booleanLiteralsContextuallyTypedFromUnion.tsx (0 errors) ====
|
||||
interface A { isIt: true; text: string; }
|
||||
interface B { isIt: false; value: number; }
|
||||
type C = A | B;
|
||||
const isIt = Math.random() > 0.5;
|
||||
const c: C = isIt ? { isIt, text: 'hey' } : { isIt, value: 123 };
|
||||
const cc: C = isIt ? { isIt: isIt, text: 'hey' } : { isIt: isIt, value: 123 };
|
||||
|
||||
type ComponentProps =
|
||||
| {
|
||||
optionalBool: true;
|
||||
mandatoryFn: () => void;
|
||||
}
|
||||
| {
|
||||
optionalBool: false;
|
||||
};
|
||||
|
||||
let Funk = (_props: ComponentProps) => <div>Hello</div>;
|
||||
|
||||
let Fail1 = () => <Funk mandatoryFn={() => { }} optionalBool={true} />
|
||||
let Fail2 = () => <Funk mandatoryFn={() => { }} optionalBool={true as true} />
|
||||
let True = true as true;
|
||||
let Fail3 = () => <Funk mandatoryFn={() => { }} optionalBool={True} />
|
||||
let attrs2 = { optionalBool: true as true, mandatoryFn: () => { } }
|
||||
let Success = () => <Funk {...attrs2} />
|
||||
@@ -1,4 +1,6 @@
|
||||
//// [capturedLetConstInLoop1.ts]
|
||||
declare function use(x: any): any;
|
||||
|
||||
//==== let
|
||||
for (let x in {}) {
|
||||
(function() { return x});
|
||||
@@ -56,6 +58,19 @@ for (let y = 0; y < 1; ++y) {
|
||||
(() => x + y);
|
||||
}
|
||||
|
||||
for (let y = (use(() => y), 0); y < 1; ++y) {
|
||||
}
|
||||
|
||||
for (let y = 0; use(() => y), y < 1; ++y) {
|
||||
}
|
||||
|
||||
for (let y = 0; y < 1; use(() => y), ++y) {
|
||||
}
|
||||
|
||||
for (let y = (use(() => y), 0); use(() => y), y < 1; use(() => y), ++y) {
|
||||
use(() => y);
|
||||
}
|
||||
|
||||
//=========const
|
||||
for (const x in {}) {
|
||||
(function() { return x});
|
||||
@@ -202,93 +217,145 @@ var _loop_10 = function (y) {
|
||||
for (var y = 0; y < 1; ++y) {
|
||||
_loop_10(y);
|
||||
}
|
||||
var _loop_11 = function (x) {
|
||||
var _loop_init_1 = function () {
|
||||
var y = (use(function () { return y; }), 0);
|
||||
out_y_1 = y;
|
||||
};
|
||||
var out_y_1;
|
||||
_loop_init_1();
|
||||
for (var y = out_y_1; y < 1; ++y) {
|
||||
}
|
||||
var _loop_11 = function (y) {
|
||||
if (inc_1)
|
||||
++y;
|
||||
else
|
||||
inc_1 = true;
|
||||
if (!(use(function () { return y; }), y < 1))
|
||||
return "break";
|
||||
};
|
||||
var inc_1 = false;
|
||||
for (var y = 0;;) {
|
||||
var state_1 = _loop_11(y);
|
||||
if (state_1 === "break")
|
||||
break;
|
||||
}
|
||||
var _loop_12 = function (y) {
|
||||
if (inc_2)
|
||||
use(function () { return y; }), ++y;
|
||||
else
|
||||
inc_2 = true;
|
||||
};
|
||||
var inc_2 = false;
|
||||
for (var y = 0; y < 1;) {
|
||||
_loop_12(y);
|
||||
}
|
||||
var _loop_init_2 = function () {
|
||||
var y = (use(function () { return y; }), 0);
|
||||
out_y_2 = y;
|
||||
};
|
||||
var _loop_13 = function (y) {
|
||||
if (inc_3)
|
||||
use(function () { return y; }), ++y;
|
||||
else
|
||||
inc_3 = true;
|
||||
if (!(use(function () { return y; }), y < 1))
|
||||
return out_y_2 = y, "break";
|
||||
use(function () { return y; });
|
||||
};
|
||||
var out_y_2, inc_3 = false;
|
||||
_loop_init_2();
|
||||
for (var y = out_y_2;;) {
|
||||
var state_2 = _loop_13(y);
|
||||
if (state_2 === "break")
|
||||
break;
|
||||
}
|
||||
var _loop_14 = function (x) {
|
||||
(function () { return x; });
|
||||
(function () { return x; });
|
||||
};
|
||||
//=========const
|
||||
for (var x in {}) {
|
||||
_loop_11(x);
|
||||
_loop_14(x);
|
||||
}
|
||||
var _loop_12 = function (x) {
|
||||
var _loop_15 = function (x) {
|
||||
(function () { return x; });
|
||||
(function () { return x; });
|
||||
};
|
||||
for (var _b = 0, _c = []; _b < _c.length; _b++) {
|
||||
var x = _c[_b];
|
||||
_loop_12(x);
|
||||
_loop_15(x);
|
||||
}
|
||||
var _loop_13 = function (x) {
|
||||
var _loop_16 = function (x) {
|
||||
(function () { return x; });
|
||||
(function () { return x; });
|
||||
};
|
||||
for (var x = 0; x < 1;) {
|
||||
_loop_13(x);
|
||||
_loop_16(x);
|
||||
}
|
||||
var _loop_14 = function () {
|
||||
var _loop_17 = function () {
|
||||
var x = 1;
|
||||
(function () { return x; });
|
||||
(function () { return x; });
|
||||
};
|
||||
while (1 === 1) {
|
||||
_loop_14();
|
||||
_loop_17();
|
||||
}
|
||||
var _loop_15 = function () {
|
||||
var _loop_18 = function () {
|
||||
var x = 1;
|
||||
(function () { return x; });
|
||||
(function () { return x; });
|
||||
};
|
||||
do {
|
||||
_loop_15();
|
||||
_loop_18();
|
||||
} while (1 === 1);
|
||||
var _loop_16 = function (y) {
|
||||
var _loop_19 = function (y) {
|
||||
var x = 1;
|
||||
(function () { return x; });
|
||||
(function () { return x; });
|
||||
};
|
||||
for (var y = 0; y < 1;) {
|
||||
_loop_16(y);
|
||||
_loop_19(y);
|
||||
}
|
||||
var _loop_17 = function (x, y) {
|
||||
var _loop_20 = function (x, y) {
|
||||
(function () { return x + y; });
|
||||
(function () { return x + y; });
|
||||
};
|
||||
for (var x = 0, y = 1; x < 1;) {
|
||||
_loop_17(x, y);
|
||||
_loop_20(x, y);
|
||||
}
|
||||
var _loop_18 = function () {
|
||||
var _loop_21 = function () {
|
||||
var x = 1, y = 1;
|
||||
(function () { return x + y; });
|
||||
(function () { return x + y; });
|
||||
};
|
||||
while (1 === 1) {
|
||||
_loop_18();
|
||||
_loop_21();
|
||||
}
|
||||
var _loop_19 = function () {
|
||||
var _loop_22 = function () {
|
||||
var x = 1, y = 1;
|
||||
(function () { return x + y; });
|
||||
(function () { return x + y; });
|
||||
};
|
||||
do {
|
||||
_loop_19();
|
||||
_loop_22();
|
||||
} while (1 === 1);
|
||||
var _loop_20 = function (y) {
|
||||
var _loop_23 = function (y) {
|
||||
var x = 1;
|
||||
(function () { return x + y; });
|
||||
(function () { return x + y; });
|
||||
};
|
||||
for (var y = 0; y < 1;) {
|
||||
_loop_20(y);
|
||||
_loop_23(y);
|
||||
}
|
||||
var _loop_21 = function (sx) {
|
||||
var _loop_24 = function (sx) {
|
||||
(function () { return sobj[sx]; });
|
||||
};
|
||||
for (var sx in sobj) {
|
||||
_loop_21(sx);
|
||||
_loop_24(sx);
|
||||
}
|
||||
var _loop_22 = function (ix) {
|
||||
var _loop_25 = function (ix) {
|
||||
(function () { return iobj[ix]; });
|
||||
};
|
||||
for (var ix in iobj) {
|
||||
_loop_22(ix);
|
||||
_loop_25(ix);
|
||||
}
|
||||
@@ -1,286 +1,330 @@
|
||||
=== tests/cases/compiler/capturedLetConstInLoop1.ts ===
|
||||
declare function use(x: any): any;
|
||||
>use : Symbol(use, Decl(capturedLetConstInLoop1.ts, 0, 0))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 0, 21))
|
||||
|
||||
//==== let
|
||||
for (let x in {}) {
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 1, 8))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 3, 8))
|
||||
|
||||
(function() { return x});
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 1, 8))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 3, 8))
|
||||
|
||||
(() => x);
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 1, 8))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 3, 8))
|
||||
}
|
||||
|
||||
for (let x of []) {
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 6, 8))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 8, 8))
|
||||
|
||||
(function() { return x});
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 6, 8))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 8, 8))
|
||||
|
||||
(() => x);
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 6, 8))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 8, 8))
|
||||
}
|
||||
|
||||
for (let x = 0; x < 1; ++x) {
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 11, 8))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 11, 8))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 11, 8))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 13, 8))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 13, 8))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 13, 8))
|
||||
|
||||
(function() { return x});
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 11, 8))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 13, 8))
|
||||
|
||||
(() => x);
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 11, 8))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 13, 8))
|
||||
}
|
||||
|
||||
while (1 === 1) {
|
||||
let x;
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 17, 7))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 19, 7))
|
||||
|
||||
(function() { return x});
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 17, 7))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 19, 7))
|
||||
|
||||
(() => x);
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 17, 7))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 19, 7))
|
||||
}
|
||||
|
||||
do {
|
||||
let x;
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 23, 7))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 25, 7))
|
||||
|
||||
(function() { return x});
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 23, 7))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 25, 7))
|
||||
|
||||
(() => x);
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 23, 7))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 25, 7))
|
||||
|
||||
} while (1 === 1)
|
||||
|
||||
for (let y = 0; y < 1; ++y) {
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 28, 8))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 28, 8))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 28, 8))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 30, 8))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 30, 8))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 30, 8))
|
||||
|
||||
let x = 1;
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 29, 7))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 31, 7))
|
||||
|
||||
(function() { return x});
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 29, 7))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 31, 7))
|
||||
|
||||
(() => x);
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 29, 7))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 31, 7))
|
||||
}
|
||||
|
||||
for (let x = 0, y = 1; x < 1; ++x) {
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 34, 8))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 34, 15))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 34, 8))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 34, 8))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 36, 8))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 36, 15))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 36, 8))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 36, 8))
|
||||
|
||||
(function() { return x + y});
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 34, 8))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 34, 15))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 36, 8))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 36, 15))
|
||||
|
||||
(() => x + y);
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 34, 8))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 34, 15))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 36, 8))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 36, 15))
|
||||
}
|
||||
|
||||
while (1 === 1) {
|
||||
let x, y;
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 40, 7))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 40, 10))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 42, 7))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 42, 10))
|
||||
|
||||
(function() { return x + y});
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 40, 7))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 40, 10))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 42, 7))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 42, 10))
|
||||
|
||||
(() => x + y);
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 40, 7))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 40, 10))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 42, 7))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 42, 10))
|
||||
}
|
||||
|
||||
do {
|
||||
let x, y;
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 46, 7))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 46, 10))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 48, 7))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 48, 10))
|
||||
|
||||
(function() { return x + y});
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 46, 7))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 46, 10))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 48, 7))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 48, 10))
|
||||
|
||||
(() => x + y);
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 46, 7))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 46, 10))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 48, 7))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 48, 10))
|
||||
|
||||
} while (1 === 1)
|
||||
|
||||
for (let y = 0; y < 1; ++y) {
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 51, 8))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 51, 8))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 51, 8))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 53, 8))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 53, 8))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 53, 8))
|
||||
|
||||
let x = 1;
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 52, 7))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 54, 7))
|
||||
|
||||
(function() { return x + y});
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 52, 7))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 51, 8))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 54, 7))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 53, 8))
|
||||
|
||||
(() => x + y);
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 52, 7))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 51, 8))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 54, 7))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 53, 8))
|
||||
}
|
||||
|
||||
for (let y = (use(() => y), 0); y < 1; ++y) {
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 59, 8))
|
||||
>use : Symbol(use, Decl(capturedLetConstInLoop1.ts, 0, 0))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 59, 8))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 59, 8))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 59, 8))
|
||||
}
|
||||
|
||||
for (let y = 0; use(() => y), y < 1; ++y) {
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 62, 8))
|
||||
>use : Symbol(use, Decl(capturedLetConstInLoop1.ts, 0, 0))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 62, 8))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 62, 8))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 62, 8))
|
||||
}
|
||||
|
||||
for (let y = 0; y < 1; use(() => y), ++y) {
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 65, 8))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 65, 8))
|
||||
>use : Symbol(use, Decl(capturedLetConstInLoop1.ts, 0, 0))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 65, 8))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 65, 8))
|
||||
}
|
||||
|
||||
for (let y = (use(() => y), 0); use(() => y), y < 1; use(() => y), ++y) {
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 68, 8))
|
||||
>use : Symbol(use, Decl(capturedLetConstInLoop1.ts, 0, 0))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 68, 8))
|
||||
>use : Symbol(use, Decl(capturedLetConstInLoop1.ts, 0, 0))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 68, 8))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 68, 8))
|
||||
>use : Symbol(use, Decl(capturedLetConstInLoop1.ts, 0, 0))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 68, 8))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 68, 8))
|
||||
|
||||
use(() => y);
|
||||
>use : Symbol(use, Decl(capturedLetConstInLoop1.ts, 0, 0))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 68, 8))
|
||||
}
|
||||
|
||||
//=========const
|
||||
for (const x in {}) {
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 58, 10))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 73, 10))
|
||||
|
||||
(function() { return x});
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 58, 10))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 73, 10))
|
||||
|
||||
(() => x);
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 58, 10))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 73, 10))
|
||||
}
|
||||
|
||||
for (const x of []) {
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 63, 10))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 78, 10))
|
||||
|
||||
(function() { return x});
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 63, 10))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 78, 10))
|
||||
|
||||
(() => x);
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 63, 10))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 78, 10))
|
||||
}
|
||||
|
||||
for (const x = 0; x < 1;) {
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 68, 10))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 68, 10))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 83, 10))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 83, 10))
|
||||
|
||||
(function() { return x});
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 68, 10))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 83, 10))
|
||||
|
||||
(() => x);
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 68, 10))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 83, 10))
|
||||
}
|
||||
|
||||
while (1 === 1) {
|
||||
const x = 1;
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 74, 9))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 89, 9))
|
||||
|
||||
(function() { return x});
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 74, 9))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 89, 9))
|
||||
|
||||
(() => x);
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 74, 9))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 89, 9))
|
||||
}
|
||||
|
||||
do {
|
||||
const x = 1;
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 80, 9))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 95, 9))
|
||||
|
||||
(function() { return x});
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 80, 9))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 95, 9))
|
||||
|
||||
(() => x);
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 80, 9))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 95, 9))
|
||||
|
||||
} while (1 === 1)
|
||||
|
||||
for (const y = 0; y < 1;) {
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 85, 10))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 85, 10))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 100, 10))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 100, 10))
|
||||
|
||||
const x = 1;
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 86, 9))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 101, 9))
|
||||
|
||||
(function() { return x});
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 86, 9))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 101, 9))
|
||||
|
||||
(() => x);
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 86, 9))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 101, 9))
|
||||
}
|
||||
|
||||
for (const x = 0, y = 1; x < 1;) {
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 91, 10))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 91, 17))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 91, 10))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 106, 10))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 106, 17))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 106, 10))
|
||||
|
||||
(function() { return x + y});
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 91, 10))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 91, 17))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 106, 10))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 106, 17))
|
||||
|
||||
(() => x + y);
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 91, 10))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 91, 17))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 106, 10))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 106, 17))
|
||||
}
|
||||
|
||||
while (1 === 1) {
|
||||
const x = 1, y = 1;
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 97, 9))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 97, 16))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 112, 9))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 112, 16))
|
||||
|
||||
(function() { return x + y});
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 97, 9))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 97, 16))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 112, 9))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 112, 16))
|
||||
|
||||
(() => x + y);
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 97, 9))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 97, 16))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 112, 9))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 112, 16))
|
||||
}
|
||||
|
||||
do {
|
||||
const x = 1, y = 1;
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 103, 9))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 103, 16))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 118, 9))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 118, 16))
|
||||
|
||||
(function() { return x + y});
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 103, 9))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 103, 16))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 118, 9))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 118, 16))
|
||||
|
||||
(() => x + y);
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 103, 9))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 103, 16))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 118, 9))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 118, 16))
|
||||
|
||||
} while (1 === 1)
|
||||
|
||||
for (const y = 0; y < 1;) {
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 108, 10))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 108, 10))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 123, 10))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 123, 10))
|
||||
|
||||
const x = 1;
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 109, 9))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 124, 9))
|
||||
|
||||
(function() { return x + y});
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 109, 9))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 108, 10))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 124, 9))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 123, 10))
|
||||
|
||||
(() => x + y);
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 109, 9))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 108, 10))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 124, 9))
|
||||
>y : Symbol(y, Decl(capturedLetConstInLoop1.ts, 123, 10))
|
||||
}
|
||||
|
||||
// https://github.com/Microsoft/TypeScript/issues/20594
|
||||
declare const sobj: { [x: string]: any };
|
||||
>sobj : Symbol(sobj, Decl(capturedLetConstInLoop1.ts, 115, 13))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 115, 23))
|
||||
>sobj : Symbol(sobj, Decl(capturedLetConstInLoop1.ts, 130, 13))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 130, 23))
|
||||
|
||||
for (let sx in sobj) {
|
||||
>sx : Symbol(sx, Decl(capturedLetConstInLoop1.ts, 116, 8))
|
||||
>sobj : Symbol(sobj, Decl(capturedLetConstInLoop1.ts, 115, 13))
|
||||
>sx : Symbol(sx, Decl(capturedLetConstInLoop1.ts, 131, 8))
|
||||
>sobj : Symbol(sobj, Decl(capturedLetConstInLoop1.ts, 130, 13))
|
||||
|
||||
(() => sobj[sx]);
|
||||
>sobj : Symbol(sobj, Decl(capturedLetConstInLoop1.ts, 115, 13))
|
||||
>sx : Symbol(sx, Decl(capturedLetConstInLoop1.ts, 116, 8))
|
||||
>sobj : Symbol(sobj, Decl(capturedLetConstInLoop1.ts, 130, 13))
|
||||
>sx : Symbol(sx, Decl(capturedLetConstInLoop1.ts, 131, 8))
|
||||
}
|
||||
declare const iobj: { [x: number]: any };
|
||||
>iobj : Symbol(iobj, Decl(capturedLetConstInLoop1.ts, 119, 13))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 119, 23))
|
||||
>iobj : Symbol(iobj, Decl(capturedLetConstInLoop1.ts, 134, 13))
|
||||
>x : Symbol(x, Decl(capturedLetConstInLoop1.ts, 134, 23))
|
||||
|
||||
for (let ix in iobj) {
|
||||
>ix : Symbol(ix, Decl(capturedLetConstInLoop1.ts, 120, 8))
|
||||
>iobj : Symbol(iobj, Decl(capturedLetConstInLoop1.ts, 119, 13))
|
||||
>ix : Symbol(ix, Decl(capturedLetConstInLoop1.ts, 135, 8))
|
||||
>iobj : Symbol(iobj, Decl(capturedLetConstInLoop1.ts, 134, 13))
|
||||
|
||||
(() => iobj[ix]);
|
||||
>iobj : Symbol(iobj, Decl(capturedLetConstInLoop1.ts, 119, 13))
|
||||
>ix : Symbol(ix, Decl(capturedLetConstInLoop1.ts, 120, 8))
|
||||
>iobj : Symbol(iobj, Decl(capturedLetConstInLoop1.ts, 134, 13))
|
||||
>ix : Symbol(ix, Decl(capturedLetConstInLoop1.ts, 135, 8))
|
||||
}
|
||||
@@ -1,4 +1,8 @@
|
||||
=== tests/cases/compiler/capturedLetConstInLoop1.ts ===
|
||||
declare function use(x: any): any;
|
||||
>use : (x: any) => any
|
||||
>x : any
|
||||
|
||||
//==== let
|
||||
for (let x in {}) {
|
||||
>x : string
|
||||
@@ -214,6 +218,84 @@ for (let y = 0; y < 1; ++y) {
|
||||
>y : number
|
||||
}
|
||||
|
||||
for (let y = (use(() => y), 0); y < 1; ++y) {
|
||||
>y : number
|
||||
>(use(() => y), 0) : 0
|
||||
>use(() => y), 0 : 0
|
||||
>use(() => y) : any
|
||||
>use : (x: any) => any
|
||||
>() => y : () => number
|
||||
>y : number
|
||||
>0 : 0
|
||||
>y < 1 : boolean
|
||||
>y : number
|
||||
>1 : 1
|
||||
>++y : number
|
||||
>y : number
|
||||
}
|
||||
|
||||
for (let y = 0; use(() => y), y < 1; ++y) {
|
||||
>y : number
|
||||
>0 : 0
|
||||
>use(() => y), y < 1 : boolean
|
||||
>use(() => y) : any
|
||||
>use : (x: any) => any
|
||||
>() => y : () => number
|
||||
>y : number
|
||||
>y < 1 : boolean
|
||||
>y : number
|
||||
>1 : 1
|
||||
>++y : number
|
||||
>y : number
|
||||
}
|
||||
|
||||
for (let y = 0; y < 1; use(() => y), ++y) {
|
||||
>y : number
|
||||
>0 : 0
|
||||
>y < 1 : boolean
|
||||
>y : number
|
||||
>1 : 1
|
||||
>use(() => y), ++y : number
|
||||
>use(() => y) : any
|
||||
>use : (x: any) => any
|
||||
>() => y : () => number
|
||||
>y : number
|
||||
>++y : number
|
||||
>y : number
|
||||
}
|
||||
|
||||
for (let y = (use(() => y), 0); use(() => y), y < 1; use(() => y), ++y) {
|
||||
>y : number
|
||||
>(use(() => y), 0) : 0
|
||||
>use(() => y), 0 : 0
|
||||
>use(() => y) : any
|
||||
>use : (x: any) => any
|
||||
>() => y : () => number
|
||||
>y : number
|
||||
>0 : 0
|
||||
>use(() => y), y < 1 : boolean
|
||||
>use(() => y) : any
|
||||
>use : (x: any) => any
|
||||
>() => y : () => number
|
||||
>y : number
|
||||
>y < 1 : boolean
|
||||
>y : number
|
||||
>1 : 1
|
||||
>use(() => y), ++y : number
|
||||
>use(() => y) : any
|
||||
>use : (x: any) => any
|
||||
>() => y : () => number
|
||||
>y : number
|
||||
>++y : number
|
||||
>y : number
|
||||
|
||||
use(() => y);
|
||||
>use(() => y) : any
|
||||
>use : (x: any) => any
|
||||
>() => y : () => number
|
||||
>y : number
|
||||
}
|
||||
|
||||
//=========const
|
||||
for (const x in {}) {
|
||||
>x : string
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
//// [contextualTypeOfIndexedAccessParameter.ts]
|
||||
type Keys = "a" | "b";
|
||||
|
||||
type OptionsForKey = { a: { cb: (p: number) => number } } & { b: {} };
|
||||
|
||||
declare function f<K extends Keys>(key: K, options: OptionsForKey[K]): void;
|
||||
|
||||
f("a", {
|
||||
cb: p => p,
|
||||
});
|
||||
|
||||
function g<
|
||||
K extends "a" | "b">(x: ({ a: string } & { b: string })[K], y: string) {
|
||||
x = y;
|
||||
}
|
||||
|
||||
|
||||
//// [contextualTypeOfIndexedAccessParameter.js]
|
||||
"use strict";
|
||||
f("a", {
|
||||
cb: function (p) { return p; }
|
||||
});
|
||||
function g(x, y) {
|
||||
x = y;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
=== tests/cases/compiler/contextualTypeOfIndexedAccessParameter.ts ===
|
||||
type Keys = "a" | "b";
|
||||
>Keys : Symbol(Keys, Decl(contextualTypeOfIndexedAccessParameter.ts, 0, 0))
|
||||
|
||||
type OptionsForKey = { a: { cb: (p: number) => number } } & { b: {} };
|
||||
>OptionsForKey : Symbol(OptionsForKey, Decl(contextualTypeOfIndexedAccessParameter.ts, 0, 22))
|
||||
>a : Symbol(a, Decl(contextualTypeOfIndexedAccessParameter.ts, 2, 22))
|
||||
>cb : Symbol(cb, Decl(contextualTypeOfIndexedAccessParameter.ts, 2, 27))
|
||||
>p : Symbol(p, Decl(contextualTypeOfIndexedAccessParameter.ts, 2, 33))
|
||||
>b : Symbol(b, Decl(contextualTypeOfIndexedAccessParameter.ts, 2, 61))
|
||||
|
||||
declare function f<K extends Keys>(key: K, options: OptionsForKey[K]): void;
|
||||
>f : Symbol(f, Decl(contextualTypeOfIndexedAccessParameter.ts, 2, 70))
|
||||
>K : Symbol(K, Decl(contextualTypeOfIndexedAccessParameter.ts, 4, 19))
|
||||
>Keys : Symbol(Keys, Decl(contextualTypeOfIndexedAccessParameter.ts, 0, 0))
|
||||
>key : Symbol(key, Decl(contextualTypeOfIndexedAccessParameter.ts, 4, 35))
|
||||
>K : Symbol(K, Decl(contextualTypeOfIndexedAccessParameter.ts, 4, 19))
|
||||
>options : Symbol(options, Decl(contextualTypeOfIndexedAccessParameter.ts, 4, 42))
|
||||
>OptionsForKey : Symbol(OptionsForKey, Decl(contextualTypeOfIndexedAccessParameter.ts, 0, 22))
|
||||
>K : Symbol(K, Decl(contextualTypeOfIndexedAccessParameter.ts, 4, 19))
|
||||
|
||||
f("a", {
|
||||
>f : Symbol(f, Decl(contextualTypeOfIndexedAccessParameter.ts, 2, 70))
|
||||
|
||||
cb: p => p,
|
||||
>cb : Symbol(cb, Decl(contextualTypeOfIndexedAccessParameter.ts, 6, 8))
|
||||
>p : Symbol(p, Decl(contextualTypeOfIndexedAccessParameter.ts, 7, 7))
|
||||
>p : Symbol(p, Decl(contextualTypeOfIndexedAccessParameter.ts, 7, 7))
|
||||
|
||||
});
|
||||
|
||||
function g<
|
||||
>g : Symbol(g, Decl(contextualTypeOfIndexedAccessParameter.ts, 8, 3))
|
||||
|
||||
K extends "a" | "b">(x: ({ a: string } & { b: string })[K], y: string) {
|
||||
>K : Symbol(K, Decl(contextualTypeOfIndexedAccessParameter.ts, 10, 11))
|
||||
>x : Symbol(x, Decl(contextualTypeOfIndexedAccessParameter.ts, 11, 25))
|
||||
>a : Symbol(a, Decl(contextualTypeOfIndexedAccessParameter.ts, 11, 30))
|
||||
>b : Symbol(b, Decl(contextualTypeOfIndexedAccessParameter.ts, 11, 46))
|
||||
>K : Symbol(K, Decl(contextualTypeOfIndexedAccessParameter.ts, 10, 11))
|
||||
>y : Symbol(y, Decl(contextualTypeOfIndexedAccessParameter.ts, 11, 63))
|
||||
|
||||
x = y;
|
||||
>x : Symbol(x, Decl(contextualTypeOfIndexedAccessParameter.ts, 11, 25))
|
||||
>y : Symbol(y, Decl(contextualTypeOfIndexedAccessParameter.ts, 11, 63))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
=== tests/cases/compiler/contextualTypeOfIndexedAccessParameter.ts ===
|
||||
type Keys = "a" | "b";
|
||||
>Keys : Keys
|
||||
|
||||
type OptionsForKey = { a: { cb: (p: number) => number } } & { b: {} };
|
||||
>OptionsForKey : OptionsForKey
|
||||
>a : { cb: (p: number) => number; }
|
||||
>cb : (p: number) => number
|
||||
>p : number
|
||||
>b : {}
|
||||
|
||||
declare function f<K extends Keys>(key: K, options: OptionsForKey[K]): void;
|
||||
>f : <K extends Keys>(key: K, options: OptionsForKey[K]) => void
|
||||
>key : K
|
||||
>options : OptionsForKey[K]
|
||||
|
||||
f("a", {
|
||||
>f("a", { cb: p => p,}) : void
|
||||
>f : <K extends Keys>(key: K, options: OptionsForKey[K]) => void
|
||||
>"a" : "a"
|
||||
>{ cb: p => p,} : { cb: (p: number) => number; }
|
||||
|
||||
cb: p => p,
|
||||
>cb : (p: number) => number
|
||||
>p => p : (p: number) => number
|
||||
>p : number
|
||||
>p : number
|
||||
|
||||
});
|
||||
|
||||
function g<
|
||||
>g : <K extends Keys>(x: ({ a: string; } & { b: string; })[K], y: string) => void
|
||||
|
||||
K extends "a" | "b">(x: ({ a: string } & { b: string })[K], y: string) {
|
||||
>x : ({ a: string; } & { b: string; })[K]
|
||||
>a : string
|
||||
>b : string
|
||||
>y : string
|
||||
|
||||
x = y;
|
||||
>x = y : string
|
||||
>x : ({ a: string; } & { b: string; })[K]
|
||||
>y : string
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
=== tests/cases/conformance/types/contextualTypes/asyncFunctions/contextuallyTypeAsyncFunctionAwaitOperand.ts ===
|
||||
interface Obj { key: "value"; }
|
||||
>Obj : Symbol(Obj, Decl(contextuallyTypeAsyncFunctionAwaitOperand.ts, 0, 0))
|
||||
>key : Symbol(Obj.key, Decl(contextuallyTypeAsyncFunctionAwaitOperand.ts, 0, 15))
|
||||
|
||||
async function fn1(): Promise<Obj> {
|
||||
>fn1 : Symbol(fn1, Decl(contextuallyTypeAsyncFunctionAwaitOperand.ts, 0, 31))
|
||||
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --))
|
||||
>Obj : Symbol(Obj, Decl(contextuallyTypeAsyncFunctionAwaitOperand.ts, 0, 0))
|
||||
|
||||
const obj1: Obj = await { key: "value" };
|
||||
>obj1 : Symbol(obj1, Decl(contextuallyTypeAsyncFunctionAwaitOperand.ts, 3, 9))
|
||||
>Obj : Symbol(Obj, Decl(contextuallyTypeAsyncFunctionAwaitOperand.ts, 0, 0))
|
||||
>key : Symbol(key, Decl(contextuallyTypeAsyncFunctionAwaitOperand.ts, 3, 29))
|
||||
|
||||
const obj2: Obj = await new Promise(resolve => resolve({ key: "value" }));
|
||||
>obj2 : Symbol(obj2, Decl(contextuallyTypeAsyncFunctionAwaitOperand.ts, 4, 9))
|
||||
>Obj : Symbol(Obj, Decl(contextuallyTypeAsyncFunctionAwaitOperand.ts, 0, 0))
|
||||
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --))
|
||||
>resolve : Symbol(resolve, Decl(contextuallyTypeAsyncFunctionAwaitOperand.ts, 4, 40))
|
||||
>resolve : Symbol(resolve, Decl(contextuallyTypeAsyncFunctionAwaitOperand.ts, 4, 40))
|
||||
>key : Symbol(key, Decl(contextuallyTypeAsyncFunctionAwaitOperand.ts, 4, 60))
|
||||
|
||||
return await { key: "value" };
|
||||
>key : Symbol(key, Decl(contextuallyTypeAsyncFunctionAwaitOperand.ts, 5, 18))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
=== tests/cases/conformance/types/contextualTypes/asyncFunctions/contextuallyTypeAsyncFunctionAwaitOperand.ts ===
|
||||
interface Obj { key: "value"; }
|
||||
>key : "value"
|
||||
|
||||
async function fn1(): Promise<Obj> {
|
||||
>fn1 : () => Promise<Obj>
|
||||
|
||||
const obj1: Obj = await { key: "value" };
|
||||
>obj1 : Obj
|
||||
>await { key: "value" } : { key: "value"; }
|
||||
>{ key: "value" } : { key: "value"; }
|
||||
>key : "value"
|
||||
>"value" : "value"
|
||||
|
||||
const obj2: Obj = await new Promise(resolve => resolve({ key: "value" }));
|
||||
>obj2 : Obj
|
||||
>await new Promise(resolve => resolve({ key: "value" })) : Obj
|
||||
>new Promise(resolve => resolve({ key: "value" })) : Promise<Obj>
|
||||
>Promise : PromiseConstructor
|
||||
>resolve => resolve({ key: "value" }) : (resolve: (value?: Obj | PromiseLike<Obj>) => void) => void
|
||||
>resolve : (value?: Obj | PromiseLike<Obj>) => void
|
||||
>resolve({ key: "value" }) : void
|
||||
>resolve : (value?: Obj | PromiseLike<Obj>) => void
|
||||
>{ key: "value" } : { key: "value"; }
|
||||
>key : "value"
|
||||
>"value" : "value"
|
||||
|
||||
return await { key: "value" };
|
||||
>await { key: "value" } : { key: "value"; }
|
||||
>{ key: "value" } : { key: "value"; }
|
||||
>key : "value"
|
||||
>"value" : "value"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
=== tests/cases/conformance/types/contextualTypes/asyncFunctions/contextuallyTypeAsyncFunctionReturnType.ts ===
|
||||
interface Obj { key: "value"; }
|
||||
>Obj : Symbol(Obj, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 0, 0))
|
||||
>key : Symbol(Obj.key, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 0, 15))
|
||||
|
||||
async function fn1(): Promise<Obj> {
|
||||
>fn1 : Symbol(fn1, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 0, 31))
|
||||
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --))
|
||||
>Obj : Symbol(Obj, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 0, 0))
|
||||
|
||||
return { key: "value" };
|
||||
>key : Symbol(key, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 3, 12))
|
||||
}
|
||||
|
||||
async function fn2(): Promise<Obj> {
|
||||
>fn2 : Symbol(fn2, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 4, 1))
|
||||
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --))
|
||||
>Obj : Symbol(Obj, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 0, 0))
|
||||
|
||||
return new Promise(resolve => {
|
||||
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --))
|
||||
>resolve : Symbol(resolve, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 7, 23))
|
||||
|
||||
resolve({ key: "value" });
|
||||
>resolve : Symbol(resolve, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 7, 23))
|
||||
>key : Symbol(key, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 8, 17))
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
async function fn3(): Promise<Obj> {
|
||||
>fn3 : Symbol(fn3, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 10, 1))
|
||||
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --))
|
||||
>Obj : Symbol(Obj, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 0, 0))
|
||||
|
||||
return await { key: "value" };
|
||||
>key : Symbol(key, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 13, 18))
|
||||
}
|
||||
|
||||
async function fn4(): Promise<Obj> {
|
||||
>fn4 : Symbol(fn4, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 14, 1))
|
||||
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --))
|
||||
>Obj : Symbol(Obj, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 0, 0))
|
||||
|
||||
return await new Promise(resolve => {
|
||||
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --))
|
||||
>resolve : Symbol(resolve, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 17, 29))
|
||||
|
||||
resolve({ key: "value" });
|
||||
>resolve : Symbol(resolve, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 17, 29))
|
||||
>key : Symbol(key, Decl(contextuallyTypeAsyncFunctionReturnType.ts, 18, 17))
|
||||
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
=== tests/cases/conformance/types/contextualTypes/asyncFunctions/contextuallyTypeAsyncFunctionReturnType.ts ===
|
||||
interface Obj { key: "value"; }
|
||||
>key : "value"
|
||||
|
||||
async function fn1(): Promise<Obj> {
|
||||
>fn1 : () => Promise<Obj>
|
||||
|
||||
return { key: "value" };
|
||||
>{ key: "value" } : { key: "value"; }
|
||||
>key : "value"
|
||||
>"value" : "value"
|
||||
}
|
||||
|
||||
async function fn2(): Promise<Obj> {
|
||||
>fn2 : () => Promise<Obj>
|
||||
|
||||
return new Promise(resolve => {
|
||||
>new Promise(resolve => { resolve({ key: "value" }); }) : Promise<Obj>
|
||||
>Promise : PromiseConstructor
|
||||
>resolve => { resolve({ key: "value" }); } : (resolve: (value?: Obj | PromiseLike<Obj>) => void) => void
|
||||
>resolve : (value?: Obj | PromiseLike<Obj>) => void
|
||||
|
||||
resolve({ key: "value" });
|
||||
>resolve({ key: "value" }) : void
|
||||
>resolve : (value?: Obj | PromiseLike<Obj>) => void
|
||||
>{ key: "value" } : { key: "value"; }
|
||||
>key : "value"
|
||||
>"value" : "value"
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
async function fn3(): Promise<Obj> {
|
||||
>fn3 : () => Promise<Obj>
|
||||
|
||||
return await { key: "value" };
|
||||
>await { key: "value" } : { key: "value"; }
|
||||
>{ key: "value" } : { key: "value"; }
|
||||
>key : "value"
|
||||
>"value" : "value"
|
||||
}
|
||||
|
||||
async function fn4(): Promise<Obj> {
|
||||
>fn4 : () => Promise<Obj>
|
||||
|
||||
return await new Promise(resolve => {
|
||||
>await new Promise(resolve => { resolve({ key: "value" }); }) : Obj
|
||||
>new Promise(resolve => { resolve({ key: "value" }); }) : Promise<Obj>
|
||||
>Promise : PromiseConstructor
|
||||
>resolve => { resolve({ key: "value" }); } : (resolve: (value?: Obj | PromiseLike<Obj>) => void) => void
|
||||
>resolve : (value?: Obj | PromiseLike<Obj>) => void
|
||||
|
||||
resolve({ key: "value" });
|
||||
>resolve({ key: "value" }) : void
|
||||
>resolve : (value?: Obj | PromiseLike<Obj>) => void
|
||||
>{ key: "value" } : { key: "value"; }
|
||||
>key : "value"
|
||||
>"value" : "value"
|
||||
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
//// [controlFlowInstanceOfGuardPrimitives.ts]
|
||||
function distinguish(thing: string | number | Date) {
|
||||
if (thing instanceof Object) {
|
||||
console.log("Aha!! It's a Date in " + thing.getFullYear());
|
||||
} else if (typeof thing === 'string') {
|
||||
console.log("Aha!! It's a string of length " + thing.length);
|
||||
} else {
|
||||
console.log("Aha!! It's the number " + thing.toPrecision(3));
|
||||
}
|
||||
}
|
||||
|
||||
distinguish(new Date());
|
||||
distinguish("beef");
|
||||
distinguish(3.14159265);
|
||||
|
||||
//// [controlFlowInstanceOfGuardPrimitives.js]
|
||||
function distinguish(thing) {
|
||||
if (thing instanceof Object) {
|
||||
console.log("Aha!! It's a Date in " + thing.getFullYear());
|
||||
}
|
||||
else if (typeof thing === 'string') {
|
||||
console.log("Aha!! It's a string of length " + thing.length);
|
||||
}
|
||||
else {
|
||||
console.log("Aha!! It's the number " + thing.toPrecision(3));
|
||||
}
|
||||
}
|
||||
distinguish(new Date());
|
||||
distinguish("beef");
|
||||
distinguish(3.14159265);
|
||||
@@ -0,0 +1,50 @@
|
||||
=== tests/cases/conformance/controlFlow/controlFlowInstanceOfGuardPrimitives.ts ===
|
||||
function distinguish(thing: string | number | Date) {
|
||||
>distinguish : Symbol(distinguish, Decl(controlFlowInstanceOfGuardPrimitives.ts, 0, 0))
|
||||
>thing : Symbol(thing, Decl(controlFlowInstanceOfGuardPrimitives.ts, 0, 21))
|
||||
>Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --))
|
||||
|
||||
if (thing instanceof Object) {
|
||||
>thing : Symbol(thing, Decl(controlFlowInstanceOfGuardPrimitives.ts, 0, 21))
|
||||
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
console.log("Aha!! It's a Date in " + thing.getFullYear());
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>thing.getFullYear : Symbol(Date.getFullYear, Decl(lib.es5.d.ts, --, --))
|
||||
>thing : Symbol(thing, Decl(controlFlowInstanceOfGuardPrimitives.ts, 0, 21))
|
||||
>getFullYear : Symbol(Date.getFullYear, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
} else if (typeof thing === 'string') {
|
||||
>thing : Symbol(thing, Decl(controlFlowInstanceOfGuardPrimitives.ts, 0, 21))
|
||||
|
||||
console.log("Aha!! It's a string of length " + thing.length);
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>thing.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
>thing : Symbol(thing, Decl(controlFlowInstanceOfGuardPrimitives.ts, 0, 21))
|
||||
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
} else {
|
||||
console.log("Aha!! It's the number " + thing.toPrecision(3));
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>thing.toPrecision : Symbol(Number.toPrecision, Decl(lib.es5.d.ts, --, --))
|
||||
>thing : Symbol(thing, Decl(controlFlowInstanceOfGuardPrimitives.ts, 0, 21))
|
||||
>toPrecision : Symbol(Number.toPrecision, Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
}
|
||||
|
||||
distinguish(new Date());
|
||||
>distinguish : Symbol(distinguish, Decl(controlFlowInstanceOfGuardPrimitives.ts, 0, 0))
|
||||
>Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --))
|
||||
|
||||
distinguish("beef");
|
||||
>distinguish : Symbol(distinguish, Decl(controlFlowInstanceOfGuardPrimitives.ts, 0, 0))
|
||||
|
||||
distinguish(3.14159265);
|
||||
>distinguish : Symbol(distinguish, Decl(controlFlowInstanceOfGuardPrimitives.ts, 0, 0))
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
=== tests/cases/conformance/controlFlow/controlFlowInstanceOfGuardPrimitives.ts ===
|
||||
function distinguish(thing: string | number | Date) {
|
||||
>distinguish : (thing: string | number | Date) => void
|
||||
>thing : string | number | Date
|
||||
|
||||
if (thing instanceof Object) {
|
||||
>thing instanceof Object : boolean
|
||||
>thing : string | number | Date
|
||||
>Object : ObjectConstructor
|
||||
|
||||
console.log("Aha!! It's a Date in " + thing.getFullYear());
|
||||
>console.log("Aha!! It's a Date in " + thing.getFullYear()) : void
|
||||
>console.log : (message?: any, ...optionalParams: any[]) => void
|
||||
>console : Console
|
||||
>log : (message?: any, ...optionalParams: any[]) => void
|
||||
>"Aha!! It's a Date in " + thing.getFullYear() : string
|
||||
>"Aha!! It's a Date in " : "Aha!! It's a Date in "
|
||||
>thing.getFullYear() : number
|
||||
>thing.getFullYear : () => number
|
||||
>thing : Date
|
||||
>getFullYear : () => number
|
||||
|
||||
} else if (typeof thing === 'string') {
|
||||
>typeof thing === 'string' : boolean
|
||||
>typeof thing : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>thing : string | number
|
||||
>'string' : "string"
|
||||
|
||||
console.log("Aha!! It's a string of length " + thing.length);
|
||||
>console.log("Aha!! It's a string of length " + thing.length) : void
|
||||
>console.log : (message?: any, ...optionalParams: any[]) => void
|
||||
>console : Console
|
||||
>log : (message?: any, ...optionalParams: any[]) => void
|
||||
>"Aha!! It's a string of length " + thing.length : string
|
||||
>"Aha!! It's a string of length " : "Aha!! It's a string of length "
|
||||
>thing.length : number
|
||||
>thing : string
|
||||
>length : number
|
||||
|
||||
} else {
|
||||
console.log("Aha!! It's the number " + thing.toPrecision(3));
|
||||
>console.log("Aha!! It's the number " + thing.toPrecision(3)) : void
|
||||
>console.log : (message?: any, ...optionalParams: any[]) => void
|
||||
>console : Console
|
||||
>log : (message?: any, ...optionalParams: any[]) => void
|
||||
>"Aha!! It's the number " + thing.toPrecision(3) : string
|
||||
>"Aha!! It's the number " : "Aha!! It's the number "
|
||||
>thing.toPrecision(3) : string
|
||||
>thing.toPrecision : (precision?: number) => string
|
||||
>thing : number
|
||||
>toPrecision : (precision?: number) => string
|
||||
>3 : 3
|
||||
}
|
||||
}
|
||||
|
||||
distinguish(new Date());
|
||||
>distinguish(new Date()) : void
|
||||
>distinguish : (thing: string | number | Date) => void
|
||||
>new Date() : Date
|
||||
>Date : DateConstructor
|
||||
|
||||
distinguish("beef");
|
||||
>distinguish("beef") : void
|
||||
>distinguish : (thing: string | number | Date) => void
|
||||
>"beef" : "beef"
|
||||
|
||||
distinguish(3.14159265);
|
||||
>distinguish(3.14159265) : void
|
||||
>distinguish : (thing: string | number | Date) => void
|
||||
>3.14159265 : 3.14159265
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
// ==ORIGINAL==
|
||||
|
||||
function delay(millis) {
|
||||
throw "no"
|
||||
}
|
||||
|
||||
function /*[#|*/main2/*|]*/() {
|
||||
console.log("Please wait. Loading.");
|
||||
return delay(500)
|
||||
.then(() => { console.log("."); return delay(500); })
|
||||
.then(() => { console.log("."); return delay(500); })
|
||||
.then(() => { console.log("."); return delay(500); })
|
||||
}
|
||||
|
||||
// ==ASYNC FUNCTION::Convert to async function==
|
||||
|
||||
function delay(millis) {
|
||||
throw "no"
|
||||
}
|
||||
|
||||
async function main2() {
|
||||
console.log("Please wait. Loading.");
|
||||
await delay(500);
|
||||
console.log(".");
|
||||
await delay(500);
|
||||
console.log(".");
|
||||
await delay(500);
|
||||
console.log(".");
|
||||
return delay(500);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// ==ORIGINAL==
|
||||
|
||||
function delay(millis: number): Promise<void> {
|
||||
throw "no"
|
||||
}
|
||||
|
||||
function /*[#|*/main2/*|]*/() {
|
||||
console.log("Please wait. Loading.");
|
||||
return delay(500)
|
||||
.then(() => { console.log("."); return delay(500); })
|
||||
.then(() => { console.log("."); return delay(500); })
|
||||
.then(() => { console.log("."); return delay(500); })
|
||||
}
|
||||
|
||||
// ==ASYNC FUNCTION::Convert to async function==
|
||||
|
||||
function delay(millis: number): Promise<void> {
|
||||
throw "no"
|
||||
}
|
||||
|
||||
async function main2() {
|
||||
console.log("Please wait. Loading.");
|
||||
await delay(500);
|
||||
console.log(".");
|
||||
await delay(500);
|
||||
console.log(".");
|
||||
await delay(500);
|
||||
console.log(".");
|
||||
return delay(500);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
error TS5052: Option 'emitDeclarationOnly' cannot be specified without specifying option 'declaration'.
|
||||
error TS5069: Option 'emitDeclarationOnly' cannot be specified without specifying option 'declaration' or option 'composite'.
|
||||
|
||||
|
||||
!!! error TS5052: Option 'emitDeclarationOnly' cannot be specified without specifying option 'declaration'.
|
||||
!!! error TS5069: Option 'emitDeclarationOnly' cannot be specified without specifying option 'declaration' or option 'composite'.
|
||||
==== tests/cases/compiler/hello.ts (0 errors) ====
|
||||
var hello = "yo!";
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
error TS5052: Option 'emitDeclarationOnly' cannot be specified without specifying option 'declaration'.
|
||||
error TS5053: Option 'emitDeclarationOnly' cannot be specified with option 'noEmit'.
|
||||
error TS5069: Option 'emitDeclarationOnly' cannot be specified without specifying option 'declaration' or option 'composite'.
|
||||
|
||||
|
||||
!!! error TS5052: Option 'emitDeclarationOnly' cannot be specified without specifying option 'declaration'.
|
||||
!!! error TS5053: Option 'emitDeclarationOnly' cannot be specified with option 'noEmit'.
|
||||
!!! error TS5069: Option 'emitDeclarationOnly' cannot be specified without specifying option 'declaration' or option 'composite'.
|
||||
==== tests/cases/compiler/hello.ts (0 errors) ====
|
||||
var hello = "yo!";
|
||||
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
/foo/tsconfig.json(2,26): error TS5052: Option 'declarationDir' cannot be specified without specifying option 'declaration'.
|
||||
/foo/tsconfig.json(2,26): error TS5069: Option 'declarationDir' cannot be specified without specifying option 'declaration' or option 'composite'.
|
||||
|
||||
|
||||
==== /foo/tsconfig.json (1 errors) ====
|
||||
{
|
||||
"compilerOptions": { "declarationDir": "out" }
|
||||
~~~~~~~~~~~~~~~~
|
||||
!!! error TS5052: Option 'declarationDir' cannot be specified without specifying option 'declaration'.
|
||||
!!! error TS5069: Option 'declarationDir' cannot be specified without specifying option 'declaration' or option 'composite'.
|
||||
}
|
||||
|
||||
==== /foo/test.ts (0 errors) ====
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
error TS5052: Option 'declarationMap' cannot be specified without specifying option 'declaration'.
|
||||
error TS5069: Option 'declarationMap' cannot be specified without specifying option 'declaration' or option 'composite'.
|
||||
|
||||
|
||||
!!! error TS5052: Option 'declarationMap' cannot be specified without specifying option 'declaration'.
|
||||
!!! error TS5069: Option 'declarationMap' cannot be specified without specifying option 'declaration' or option 'composite'.
|
||||
==== tests/cases/compiler/declarationMapsWithoutDeclaration.ts (0 errors) ====
|
||||
module m2 {
|
||||
export interface connectModule {
|
||||
|
||||
@@ -41,7 +41,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(
|
||||
a1(...array2); // Error parameter type is (number|string)[]
|
||||
~~~~~~
|
||||
!!! error TS2552: Cannot find name 'array2'. Did you mean 'Array'?
|
||||
!!! related TS2728 /.ts/lib.es5.d.ts:1298:15: 'Array' is declared here.
|
||||
!!! related TS2728 /.ts/lib.es5.d.ts:1358:15: 'Array' is declared here.
|
||||
a5([1, 2, "string", false, true]); // Error, parameter type is [any, any, [[any]]]
|
||||
~~~~~~~~
|
||||
!!! error TS2322: Type 'string' is not assignable to type '[[any]]'.
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
=== tests/cases/conformance/jsdoc/bug27134.js ===
|
||||
/**
|
||||
* @enum {number}
|
||||
*/
|
||||
var foo = { };
|
||||
>foo : Symbol(foo, Decl(bug27134.js, 3, 3))
|
||||
|
||||
/**
|
||||
* @type {foo}
|
||||
*/
|
||||
var s;
|
||||
>s : Symbol(s, Decl(bug27134.js, 8, 3))
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
=== tests/cases/conformance/jsdoc/bug27134.js ===
|
||||
/**
|
||||
* @enum {number}
|
||||
*/
|
||||
var foo = { };
|
||||
>foo : typeof foo
|
||||
>{ } : {}
|
||||
|
||||
/**
|
||||
* @type {foo}
|
||||
*/
|
||||
var s;
|
||||
>s : number
|
||||
|
||||
@@ -69,20 +69,20 @@ tests/cases/compiler/externModule.ts(37,3): error TS2552: Cannot find name 'XDat
|
||||
var d=new XDate();
|
||||
~~~~~
|
||||
!!! error TS2552: Cannot find name 'XDate'. Did you mean 'Date'?
|
||||
!!! related TS2728 /.ts/lib.es5.d.ts:837:15: 'Date' is declared here.
|
||||
!!! related TS2728 /.ts/lib.es5.d.ts:897:15: 'Date' is declared here.
|
||||
d.getDay();
|
||||
d=new XDate(1978,2);
|
||||
~~~~~
|
||||
!!! error TS2552: Cannot find name 'XDate'. Did you mean 'Date'?
|
||||
!!! related TS2728 /.ts/lib.es5.d.ts:837:15: 'Date' is declared here.
|
||||
!!! related TS2728 /.ts/lib.es5.d.ts:897:15: 'Date' is declared here.
|
||||
d.getXDate();
|
||||
var n=XDate.parse("3/2/2004");
|
||||
~~~~~
|
||||
!!! error TS2552: Cannot find name 'XDate'. Did you mean 'Date'?
|
||||
!!! related TS2728 /.ts/lib.es5.d.ts:837:15: 'Date' is declared here.
|
||||
!!! related TS2728 /.ts/lib.es5.d.ts:897:15: 'Date' is declared here.
|
||||
n=XDate.UTC(1964,2,1);
|
||||
~~~~~
|
||||
!!! error TS2552: Cannot find name 'XDate'. Did you mean 'Date'?
|
||||
!!! related TS2728 /.ts/lib.es5.d.ts:837:15: 'Date' is declared here.
|
||||
!!! related TS2728 /.ts/lib.es5.d.ts:897:15: 'Date' is declared here.
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
tests/cases/conformance/types/rest/genericRestArityStrict.ts(7,6): error TS2345: Argument of type '(x: number, y: number) => number' is not assignable to parameter of type '() => void'.
|
||||
tests/cases/conformance/types/rest/genericRestArityStrict.ts(7,1): error TS2554: Expected 3 arguments, but got 1.
|
||||
tests/cases/conformance/types/rest/genericRestArityStrict.ts(8,1): error TS2554: Expected 3 arguments, but got 8.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/rest/genericRestArityStrict.ts (1 errors) ====
|
||||
==== tests/cases/conformance/types/rest/genericRestArityStrict.ts (2 errors) ====
|
||||
// Repro from #25559
|
||||
|
||||
declare function call<TS extends unknown[]>(
|
||||
@@ -9,7 +10,10 @@ tests/cases/conformance/types/rest/genericRestArityStrict.ts(7,6): error TS2345:
|
||||
...args: TS): void;
|
||||
|
||||
call((x: number, y: number) => x + y);
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type '(x: number, y: number) => number' is not assignable to parameter of type '() => void'.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2554: Expected 3 arguments, but got 1.
|
||||
!!! related TS6210 tests/cases/conformance/types/rest/genericRestArityStrict.ts:5:5: An argument for 'args' was not provided.
|
||||
call((x: number, y: number) => x + y, 1, 2, 3, 4, 5, 6, 7);
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2554: Expected 3 arguments, but got 8.
|
||||
|
||||
@@ -22,7 +22,7 @@ call((x: number, y: number) => x + y);
|
||||
>y : number
|
||||
|
||||
call((x: number, y: number) => x + y, 1, 2, 3, 4, 5, 6, 7);
|
||||
>call((x: number, y: number) => x + y, 1, 2, 3, 4, 5, 6, 7) : void
|
||||
>call((x: number, y: number) => x + y, 1, 2, 3, 4, 5, 6, 7) : any
|
||||
>call : <TS extends unknown[]>(handler: (...args: TS) => void, ...args: TS) => void
|
||||
>(x: number, y: number) => x + y : (x: number, y: number) => number
|
||||
>x : number
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
error TS2321: Excessive stack depth comparing types 'Extract<T[Exclude<keyof T, string | number | symbol>], Record<"val", string>>["val"]' and 'Extract<T[Exclude<keyof T, Exclude<keyof T, string | number | symbol>>], Record<"val", string>>["val"]'.
|
||||
error TS2321: Excessive stack depth comparing types 'Extract<T[Exclude<keyof T, number>], Record<"val", string>>["val"]' and 'Extract<T[Exclude<keyof T, Exclude<keyof T, number>>], Record<"val", string>>["val"]'.
|
||||
error TS2321: Excessive stack depth comparing types 'Extract<T[Exclude<keyof T, string>], Record<"val", string>>["val"]' and 'Extract<T[Exclude<keyof T, Exclude<keyof T, string>>], Record<"val", string>>["val"]'.
|
||||
error TS2321: Excessive stack depth comparing types 'Extract<T[Exclude<keyof T, symbol>], Record<"val", string>>["val"]' and 'Extract<T[Exclude<keyof T, Exclude<keyof T, symbol>>], Record<"val", string>>["val"]'.
|
||||
tests/cases/compiler/infiniteConstraints.ts(4,37): error TS2536: Type '"val"' cannot be used to index type 'B[Exclude<keyof B, K>]'.
|
||||
tests/cases/compiler/infiniteConstraints.ts(27,37): error TS2322: Type 'Record<"val", "test">' is not assignable to type 'never'.
|
||||
tests/cases/compiler/infiniteConstraints.ts(27,58): error TS2322: Type 'Record<"val", "test2">' is not assignable to type 'never'.
|
||||
@@ -8,7 +10,9 @@ tests/cases/compiler/infiniteConstraints.ts(31,63): error TS2322: Type 'Record<"
|
||||
tests/cases/compiler/infiniteConstraints.ts(36,71): error TS2536: Type '"foo"' cannot be used to index type 'T[keyof T]'.
|
||||
|
||||
|
||||
!!! error TS2321: Excessive stack depth comparing types 'Extract<T[Exclude<keyof T, string | number | symbol>], Record<"val", string>>["val"]' and 'Extract<T[Exclude<keyof T, Exclude<keyof T, string | number | symbol>>], Record<"val", string>>["val"]'.
|
||||
!!! error TS2321: Excessive stack depth comparing types 'Extract<T[Exclude<keyof T, number>], Record<"val", string>>["val"]' and 'Extract<T[Exclude<keyof T, Exclude<keyof T, number>>], Record<"val", string>>["val"]'.
|
||||
!!! error TS2321: Excessive stack depth comparing types 'Extract<T[Exclude<keyof T, string>], Record<"val", string>>["val"]' and 'Extract<T[Exclude<keyof T, Exclude<keyof T, string>>], Record<"val", string>>["val"]'.
|
||||
!!! error TS2321: Excessive stack depth comparing types 'Extract<T[Exclude<keyof T, symbol>], Record<"val", string>>["val"]' and 'Extract<T[Exclude<keyof T, Exclude<keyof T, symbol>>], Record<"val", string>>["val"]'.
|
||||
==== tests/cases/compiler/infiniteConstraints.ts (7 errors) ====
|
||||
// Both of the following types trigger the recursion limiter in getImmediateBaseConstraint
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
=== tests/cases/conformance/jsdoc/bug27341.js ===
|
||||
if (false) {
|
||||
/**
|
||||
* @param {string} s
|
||||
*/
|
||||
const x = function (s) {
|
||||
>x : Symbol(x, Decl(bug27341.js, 4, 9))
|
||||
>s : Symbol(s, Decl(bug27341.js, 4, 24))
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
=== tests/cases/conformance/jsdoc/bug27341.js ===
|
||||
if (false) {
|
||||
>false : false
|
||||
|
||||
/**
|
||||
* @param {string} s
|
||||
*/
|
||||
const x = function (s) {
|
||||
>x : (s: string) => void
|
||||
>function (s) { } : (s: string) => void
|
||||
>s : string
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/a.js(4,13): error TS2314: Generic type 'C<T>' requires 1 type argument(s).
|
||||
|
||||
|
||||
==== /a.js (1 errors) ====
|
||||
/** @template T */
|
||||
class C {}
|
||||
|
||||
/** @param {C} p */
|
||||
~
|
||||
!!! error TS2314: Generic type 'C<T>' requires 1 type argument(s).
|
||||
function f(p) {}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
=== /a.js ===
|
||||
/** @template T */
|
||||
class C {}
|
||||
>C : Symbol(C, Decl(a.js, 0, 0))
|
||||
|
||||
/** @param {C} p */
|
||||
function f(p) {}
|
||||
>f : Symbol(f, Decl(a.js, 1, 10))
|
||||
>p : Symbol(p, Decl(a.js, 4, 11))
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
=== /a.js ===
|
||||
/** @template T */
|
||||
class C {}
|
||||
>C : C<T>
|
||||
|
||||
/** @param {C} p */
|
||||
function f(p) {}
|
||||
>f : (p: C<any>) => void
|
||||
>p : C<any>
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
tests/cases/compiler/jsxChildrenGenericContextualTypes.tsx(20,46): error TS2322: Type '"y"' is not assignable to type '"x"'.
|
||||
tests/cases/compiler/jsxChildrenGenericContextualTypes.tsx(21,19): error TS2322: Type '{ children: (p: IntrinsicAttributes & LitProps<"x">) => "y"; prop: "x"; }' is not assignable to type 'IntrinsicAttributes & LitProps<"x" | "y">'.
|
||||
Type '{ children: (p: IntrinsicAttributes & LitProps<"x">) => "y"; prop: "x"; }' is not assignable to type 'LitProps<"x" | "y">'.
|
||||
tests/cases/compiler/jsxChildrenGenericContextualTypes.tsx(21,19): error TS2322: Type '{ children: (p: LitProps<"x">) => "y"; prop: "x"; }' is not assignable to type 'IntrinsicAttributes & LitProps<"x">'.
|
||||
Type '{ children: (p: LitProps<"x">) => "y"; prop: "x"; }' is not assignable to type 'LitProps<"x">'.
|
||||
Types of property 'children' are incompatible.
|
||||
Type '(p: IntrinsicAttributes & LitProps<"x">) => "y"' is not assignable to type '(x: LitProps<"x" | "y">) => "x" | "y"'.
|
||||
Types of parameters 'p' and 'x' are incompatible.
|
||||
Type 'LitProps<"x" | "y">' is not assignable to type 'IntrinsicAttributes & LitProps<"x">'.
|
||||
Type 'LitProps<"x" | "y">' is not assignable to type 'LitProps<"x">'.
|
||||
Types of property 'prop' are incompatible.
|
||||
Type '"x" | "y"' is not assignable to type '"x"'.
|
||||
Type '"y"' is not assignable to type '"x"'.
|
||||
Type '(p: LitProps<"x">) => "y"' is not assignable to type '(x: LitProps<"x">) => "x"'.
|
||||
Type '"y"' is not assignable to type '"x"'.
|
||||
tests/cases/compiler/jsxChildrenGenericContextualTypes.tsx(22,21): error TS2322: Type '{ children: () => number; prop: "x"; }' is not assignable to type 'IntrinsicAttributes & LitProps<"x">'.
|
||||
Type '{ children: () => number; prop: "x"; }' is not assignable to type 'LitProps<"x">'.
|
||||
Types of property 'children' are incompatible.
|
||||
@@ -42,16 +37,11 @@ tests/cases/compiler/jsxChildrenGenericContextualTypes.tsx(22,21): error TS2322:
|
||||
!!! related TS6502 tests/cases/compiler/jsxChildrenGenericContextualTypes.tsx:13:44: The expected type comes from the return type of this signature.
|
||||
const argchild = <ElemLit prop="x">{p => "y"}</ElemLit>
|
||||
~~~~~~~
|
||||
!!! error TS2322: Type '{ children: (p: IntrinsicAttributes & LitProps<"x">) => "y"; prop: "x"; }' is not assignable to type 'IntrinsicAttributes & LitProps<"x" | "y">'.
|
||||
!!! error TS2322: Type '{ children: (p: IntrinsicAttributes & LitProps<"x">) => "y"; prop: "x"; }' is not assignable to type 'LitProps<"x" | "y">'.
|
||||
!!! error TS2322: Type '{ children: (p: LitProps<"x">) => "y"; prop: "x"; }' is not assignable to type 'IntrinsicAttributes & LitProps<"x">'.
|
||||
!!! error TS2322: Type '{ children: (p: LitProps<"x">) => "y"; prop: "x"; }' is not assignable to type 'LitProps<"x">'.
|
||||
!!! error TS2322: Types of property 'children' are incompatible.
|
||||
!!! error TS2322: Type '(p: IntrinsicAttributes & LitProps<"x">) => "y"' is not assignable to type '(x: LitProps<"x" | "y">) => "x" | "y"'.
|
||||
!!! error TS2322: Types of parameters 'p' and 'x' are incompatible.
|
||||
!!! error TS2322: Type 'LitProps<"x" | "y">' is not assignable to type 'IntrinsicAttributes & LitProps<"x">'.
|
||||
!!! error TS2322: Type 'LitProps<"x" | "y">' is not assignable to type 'LitProps<"x">'.
|
||||
!!! error TS2322: Types of property 'prop' are incompatible.
|
||||
!!! error TS2322: Type '"x" | "y"' is not assignable to type '"x"'.
|
||||
!!! error TS2322: Type '"y"' is not assignable to type '"x"'.
|
||||
!!! error TS2322: Type '(p: LitProps<"x">) => "y"' is not assignable to type '(x: LitProps<"x">) => "x"'.
|
||||
!!! error TS2322: Type '"y"' is not assignable to type '"x"'.
|
||||
const mismatched = <ElemLit prop="x">{() => 12}</ElemLit>
|
||||
~~~~~~~
|
||||
!!! error TS2322: Type '{ children: () => number; prop: "x"; }' is not assignable to type 'IntrinsicAttributes & LitProps<"x">'.
|
||||
|
||||
@@ -127,8 +127,8 @@ const argchild = <ElemLit prop="x">{p => "y"}</ElemLit>
|
||||
><ElemLit prop="x">{p => "y"}</ElemLit> : JSX.Element
|
||||
>ElemLit : <T extends string>(p: LitProps<T>) => JSX.Element
|
||||
>prop : "x"
|
||||
>p => "y" : (p: JSX.IntrinsicAttributes & LitProps<"x">) => "y"
|
||||
>p : JSX.IntrinsicAttributes & LitProps<"x">
|
||||
>p => "y" : (p: LitProps<"x">) => "y"
|
||||
>p : LitProps<"x">
|
||||
>"y" : "y"
|
||||
>ElemLit : <T extends string>(p: LitProps<T>) => JSX.Element
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
tests/cases/compiler/literalFreshnessPropagationOnNarrowing.ts(37,5): error TS2322: Type '"y"' is not assignable to type '"x"'.
|
||||
tests/cases/compiler/literalFreshnessPropagationOnNarrowing.ts(60,5): error TS2322: Type 'string[]' is not assignable to type 'XY[]'.
|
||||
Type 'string' is not assignable to type 'XY'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/literalFreshnessPropagationOnNarrowing.ts (2 errors) ====
|
||||
function f1() {
|
||||
let b = true;
|
||||
let obj = { b };
|
||||
// Desired: OK
|
||||
// 3.0: OK
|
||||
// 3.1 as-is: OK
|
||||
// 3.1 minus widening propagation: error
|
||||
obj.b = false;
|
||||
}
|
||||
|
||||
function f2() {
|
||||
type Element = (string | false);
|
||||
type ElementOrArray = Element | Element[];
|
||||
let el: Element = null as any;
|
||||
let arr: Element[] = null as any;
|
||||
let elOrA: ElementOrArray = null as any;
|
||||
|
||||
// Desired/actual: All OK
|
||||
let a1: ElementOrArray = el;
|
||||
let a2: ElementOrArray = arr;
|
||||
let a3: ElementOrArray = [el];
|
||||
let a4: ElementOrArray = Array.isArray(elOrA) ? elOrA : [elOrA];
|
||||
|
||||
// Desired: OK
|
||||
// 3.0: Error
|
||||
// 3.1: OK
|
||||
let a5: ElementOrArray = [...Array.isArray(elOrA) ? elOrA : [elOrA]];
|
||||
}
|
||||
|
||||
function f3() {
|
||||
type XY = 'x' | 'y';
|
||||
const x: XY = 'x';
|
||||
let x2 = x;
|
||||
// Desired: OK (up for debate?)
|
||||
// 3.0: Error
|
||||
// 3.1 as-is: OK
|
||||
x2 = 'y';
|
||||
~~
|
||||
!!! error TS2322: Type '"y"' is not assignable to type '"x"'.
|
||||
|
||||
// Desired/actual: All OK
|
||||
let x3: XY = x;
|
||||
x3 = 'y';
|
||||
}
|
||||
|
||||
function f4() {
|
||||
const x: boolean = true;
|
||||
let x1 = x;
|
||||
// Desired: OK
|
||||
// 3.0: OK
|
||||
// 3.1: OK
|
||||
// 3.1 minus widening propagation: error
|
||||
x1 = false;
|
||||
}
|
||||
|
||||
function f5() {
|
||||
type XY = 'x' | 'y';
|
||||
let arr: XY[] = ['x'];
|
||||
arr = ['y'];
|
||||
// Desired: OK
|
||||
// Error in all extant branches
|
||||
arr = [...['y']];
|
||||
~~~
|
||||
!!! error TS2322: Type 'string[]' is not assignable to type 'XY[]'.
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'XY'.
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
//// [literalFreshnessPropagationOnNarrowing.ts]
|
||||
function f1() {
|
||||
let b = true;
|
||||
let obj = { b };
|
||||
// Desired: OK
|
||||
// 3.0: OK
|
||||
// 3.1 as-is: OK
|
||||
// 3.1 minus widening propagation: error
|
||||
obj.b = false;
|
||||
}
|
||||
|
||||
function f2() {
|
||||
type Element = (string | false);
|
||||
type ElementOrArray = Element | Element[];
|
||||
let el: Element = null as any;
|
||||
let arr: Element[] = null as any;
|
||||
let elOrA: ElementOrArray = null as any;
|
||||
|
||||
// Desired/actual: All OK
|
||||
let a1: ElementOrArray = el;
|
||||
let a2: ElementOrArray = arr;
|
||||
let a3: ElementOrArray = [el];
|
||||
let a4: ElementOrArray = Array.isArray(elOrA) ? elOrA : [elOrA];
|
||||
|
||||
// Desired: OK
|
||||
// 3.0: Error
|
||||
// 3.1: OK
|
||||
let a5: ElementOrArray = [...Array.isArray(elOrA) ? elOrA : [elOrA]];
|
||||
}
|
||||
|
||||
function f3() {
|
||||
type XY = 'x' | 'y';
|
||||
const x: XY = 'x';
|
||||
let x2 = x;
|
||||
// Desired: OK (up for debate?)
|
||||
// 3.0: Error
|
||||
// 3.1 as-is: OK
|
||||
x2 = 'y';
|
||||
|
||||
// Desired/actual: All OK
|
||||
let x3: XY = x;
|
||||
x3 = 'y';
|
||||
}
|
||||
|
||||
function f4() {
|
||||
const x: boolean = true;
|
||||
let x1 = x;
|
||||
// Desired: OK
|
||||
// 3.0: OK
|
||||
// 3.1: OK
|
||||
// 3.1 minus widening propagation: error
|
||||
x1 = false;
|
||||
}
|
||||
|
||||
function f5() {
|
||||
type XY = 'x' | 'y';
|
||||
let arr: XY[] = ['x'];
|
||||
arr = ['y'];
|
||||
// Desired: OK
|
||||
// Error in all extant branches
|
||||
arr = [...['y']];
|
||||
}
|
||||
|
||||
//// [literalFreshnessPropagationOnNarrowing.js]
|
||||
function f1() {
|
||||
var b = true;
|
||||
var obj = { b: b };
|
||||
// Desired: OK
|
||||
// 3.0: OK
|
||||
// 3.1 as-is: OK
|
||||
// 3.1 minus widening propagation: error
|
||||
obj.b = false;
|
||||
}
|
||||
function f2() {
|
||||
var el = null;
|
||||
var arr = null;
|
||||
var elOrA = null;
|
||||
// Desired/actual: All OK
|
||||
var a1 = el;
|
||||
var a2 = arr;
|
||||
var a3 = [el];
|
||||
var a4 = Array.isArray(elOrA) ? elOrA : [elOrA];
|
||||
// Desired: OK
|
||||
// 3.0: Error
|
||||
// 3.1: OK
|
||||
var a5 = (Array.isArray(elOrA) ? elOrA : [elOrA]).slice();
|
||||
}
|
||||
function f3() {
|
||||
var x = 'x';
|
||||
var x2 = x;
|
||||
// Desired: OK (up for debate?)
|
||||
// 3.0: Error
|
||||
// 3.1 as-is: OK
|
||||
x2 = 'y';
|
||||
// Desired/actual: All OK
|
||||
var x3 = x;
|
||||
x3 = 'y';
|
||||
}
|
||||
function f4() {
|
||||
var x = true;
|
||||
var x1 = x;
|
||||
// Desired: OK
|
||||
// 3.0: OK
|
||||
// 3.1: OK
|
||||
// 3.1 minus widening propagation: error
|
||||
x1 = false;
|
||||
}
|
||||
function f5() {
|
||||
var arr = ['x'];
|
||||
arr = ['y'];
|
||||
// Desired: OK
|
||||
// Error in all extant branches
|
||||
arr = ['y'];
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
=== tests/cases/compiler/literalFreshnessPropagationOnNarrowing.ts ===
|
||||
function f1() {
|
||||
>f1 : Symbol(f1, Decl(literalFreshnessPropagationOnNarrowing.ts, 0, 0))
|
||||
|
||||
let b = true;
|
||||
>b : Symbol(b, Decl(literalFreshnessPropagationOnNarrowing.ts, 1, 7))
|
||||
|
||||
let obj = { b };
|
||||
>obj : Symbol(obj, Decl(literalFreshnessPropagationOnNarrowing.ts, 2, 7))
|
||||
>b : Symbol(b, Decl(literalFreshnessPropagationOnNarrowing.ts, 2, 15))
|
||||
|
||||
// Desired: OK
|
||||
// 3.0: OK
|
||||
// 3.1 as-is: OK
|
||||
// 3.1 minus widening propagation: error
|
||||
obj.b = false;
|
||||
>obj.b : Symbol(b, Decl(literalFreshnessPropagationOnNarrowing.ts, 2, 15))
|
||||
>obj : Symbol(obj, Decl(literalFreshnessPropagationOnNarrowing.ts, 2, 7))
|
||||
>b : Symbol(b, Decl(literalFreshnessPropagationOnNarrowing.ts, 2, 15))
|
||||
}
|
||||
|
||||
function f2() {
|
||||
>f2 : Symbol(f2, Decl(literalFreshnessPropagationOnNarrowing.ts, 8, 1))
|
||||
|
||||
type Element = (string | false);
|
||||
>Element : Symbol(Element, Decl(literalFreshnessPropagationOnNarrowing.ts, 10, 15))
|
||||
|
||||
type ElementOrArray = Element | Element[];
|
||||
>ElementOrArray : Symbol(ElementOrArray, Decl(literalFreshnessPropagationOnNarrowing.ts, 11, 36))
|
||||
>Element : Symbol(Element, Decl(literalFreshnessPropagationOnNarrowing.ts, 10, 15))
|
||||
>Element : Symbol(Element, Decl(literalFreshnessPropagationOnNarrowing.ts, 10, 15))
|
||||
|
||||
let el: Element = null as any;
|
||||
>el : Symbol(el, Decl(literalFreshnessPropagationOnNarrowing.ts, 13, 7))
|
||||
>Element : Symbol(Element, Decl(literalFreshnessPropagationOnNarrowing.ts, 10, 15))
|
||||
|
||||
let arr: Element[] = null as any;
|
||||
>arr : Symbol(arr, Decl(literalFreshnessPropagationOnNarrowing.ts, 14, 7))
|
||||
>Element : Symbol(Element, Decl(literalFreshnessPropagationOnNarrowing.ts, 10, 15))
|
||||
|
||||
let elOrA: ElementOrArray = null as any;
|
||||
>elOrA : Symbol(elOrA, Decl(literalFreshnessPropagationOnNarrowing.ts, 15, 7))
|
||||
>ElementOrArray : Symbol(ElementOrArray, Decl(literalFreshnessPropagationOnNarrowing.ts, 11, 36))
|
||||
|
||||
// Desired/actual: All OK
|
||||
let a1: ElementOrArray = el;
|
||||
>a1 : Symbol(a1, Decl(literalFreshnessPropagationOnNarrowing.ts, 18, 7))
|
||||
>ElementOrArray : Symbol(ElementOrArray, Decl(literalFreshnessPropagationOnNarrowing.ts, 11, 36))
|
||||
>el : Symbol(el, Decl(literalFreshnessPropagationOnNarrowing.ts, 13, 7))
|
||||
|
||||
let a2: ElementOrArray = arr;
|
||||
>a2 : Symbol(a2, Decl(literalFreshnessPropagationOnNarrowing.ts, 19, 7))
|
||||
>ElementOrArray : Symbol(ElementOrArray, Decl(literalFreshnessPropagationOnNarrowing.ts, 11, 36))
|
||||
>arr : Symbol(arr, Decl(literalFreshnessPropagationOnNarrowing.ts, 14, 7))
|
||||
|
||||
let a3: ElementOrArray = [el];
|
||||
>a3 : Symbol(a3, Decl(literalFreshnessPropagationOnNarrowing.ts, 20, 7))
|
||||
>ElementOrArray : Symbol(ElementOrArray, Decl(literalFreshnessPropagationOnNarrowing.ts, 11, 36))
|
||||
>el : Symbol(el, Decl(literalFreshnessPropagationOnNarrowing.ts, 13, 7))
|
||||
|
||||
let a4: ElementOrArray = Array.isArray(elOrA) ? elOrA : [elOrA];
|
||||
>a4 : Symbol(a4, Decl(literalFreshnessPropagationOnNarrowing.ts, 21, 7))
|
||||
>ElementOrArray : Symbol(ElementOrArray, Decl(literalFreshnessPropagationOnNarrowing.ts, 11, 36))
|
||||
>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
|
||||
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
|
||||
>elOrA : Symbol(elOrA, Decl(literalFreshnessPropagationOnNarrowing.ts, 15, 7))
|
||||
>elOrA : Symbol(elOrA, Decl(literalFreshnessPropagationOnNarrowing.ts, 15, 7))
|
||||
>elOrA : Symbol(elOrA, Decl(literalFreshnessPropagationOnNarrowing.ts, 15, 7))
|
||||
|
||||
// Desired: OK
|
||||
// 3.0: Error
|
||||
// 3.1: OK
|
||||
let a5: ElementOrArray = [...Array.isArray(elOrA) ? elOrA : [elOrA]];
|
||||
>a5 : Symbol(a5, Decl(literalFreshnessPropagationOnNarrowing.ts, 26, 7))
|
||||
>ElementOrArray : Symbol(ElementOrArray, Decl(literalFreshnessPropagationOnNarrowing.ts, 11, 36))
|
||||
>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
|
||||
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
|
||||
>elOrA : Symbol(elOrA, Decl(literalFreshnessPropagationOnNarrowing.ts, 15, 7))
|
||||
>elOrA : Symbol(elOrA, Decl(literalFreshnessPropagationOnNarrowing.ts, 15, 7))
|
||||
>elOrA : Symbol(elOrA, Decl(literalFreshnessPropagationOnNarrowing.ts, 15, 7))
|
||||
}
|
||||
|
||||
function f3() {
|
||||
>f3 : Symbol(f3, Decl(literalFreshnessPropagationOnNarrowing.ts, 27, 1))
|
||||
|
||||
type XY = 'x' | 'y';
|
||||
>XY : Symbol(XY, Decl(literalFreshnessPropagationOnNarrowing.ts, 29, 15))
|
||||
|
||||
const x: XY = 'x';
|
||||
>x : Symbol(x, Decl(literalFreshnessPropagationOnNarrowing.ts, 31, 9))
|
||||
>XY : Symbol(XY, Decl(literalFreshnessPropagationOnNarrowing.ts, 29, 15))
|
||||
|
||||
let x2 = x;
|
||||
>x2 : Symbol(x2, Decl(literalFreshnessPropagationOnNarrowing.ts, 32, 7))
|
||||
>x : Symbol(x, Decl(literalFreshnessPropagationOnNarrowing.ts, 31, 9))
|
||||
|
||||
// Desired: OK (up for debate?)
|
||||
// 3.0: Error
|
||||
// 3.1 as-is: OK
|
||||
x2 = 'y';
|
||||
>x2 : Symbol(x2, Decl(literalFreshnessPropagationOnNarrowing.ts, 32, 7))
|
||||
|
||||
// Desired/actual: All OK
|
||||
let x3: XY = x;
|
||||
>x3 : Symbol(x3, Decl(literalFreshnessPropagationOnNarrowing.ts, 39, 7))
|
||||
>XY : Symbol(XY, Decl(literalFreshnessPropagationOnNarrowing.ts, 29, 15))
|
||||
>x : Symbol(x, Decl(literalFreshnessPropagationOnNarrowing.ts, 31, 9))
|
||||
|
||||
x3 = 'y';
|
||||
>x3 : Symbol(x3, Decl(literalFreshnessPropagationOnNarrowing.ts, 39, 7))
|
||||
}
|
||||
|
||||
function f4() {
|
||||
>f4 : Symbol(f4, Decl(literalFreshnessPropagationOnNarrowing.ts, 41, 1))
|
||||
|
||||
const x: boolean = true;
|
||||
>x : Symbol(x, Decl(literalFreshnessPropagationOnNarrowing.ts, 44, 9))
|
||||
|
||||
let x1 = x;
|
||||
>x1 : Symbol(x1, Decl(literalFreshnessPropagationOnNarrowing.ts, 45, 7))
|
||||
>x : Symbol(x, Decl(literalFreshnessPropagationOnNarrowing.ts, 44, 9))
|
||||
|
||||
// Desired: OK
|
||||
// 3.0: OK
|
||||
// 3.1: OK
|
||||
// 3.1 minus widening propagation: error
|
||||
x1 = false;
|
||||
>x1 : Symbol(x1, Decl(literalFreshnessPropagationOnNarrowing.ts, 45, 7))
|
||||
}
|
||||
|
||||
function f5() {
|
||||
>f5 : Symbol(f5, Decl(literalFreshnessPropagationOnNarrowing.ts, 51, 1))
|
||||
|
||||
type XY = 'x' | 'y';
|
||||
>XY : Symbol(XY, Decl(literalFreshnessPropagationOnNarrowing.ts, 53, 15))
|
||||
|
||||
let arr: XY[] = ['x'];
|
||||
>arr : Symbol(arr, Decl(literalFreshnessPropagationOnNarrowing.ts, 55, 7))
|
||||
>XY : Symbol(XY, Decl(literalFreshnessPropagationOnNarrowing.ts, 53, 15))
|
||||
|
||||
arr = ['y'];
|
||||
>arr : Symbol(arr, Decl(literalFreshnessPropagationOnNarrowing.ts, 55, 7))
|
||||
|
||||
// Desired: OK
|
||||
// Error in all extant branches
|
||||
arr = [...['y']];
|
||||
>arr : Symbol(arr, Decl(literalFreshnessPropagationOnNarrowing.ts, 55, 7))
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
=== tests/cases/compiler/literalFreshnessPropagationOnNarrowing.ts ===
|
||||
function f1() {
|
||||
>f1 : () => void
|
||||
|
||||
let b = true;
|
||||
>b : boolean
|
||||
>true : true
|
||||
|
||||
let obj = { b };
|
||||
>obj : { b: boolean; }
|
||||
>{ b } : { b: boolean; }
|
||||
>b : boolean
|
||||
|
||||
// Desired: OK
|
||||
// 3.0: OK
|
||||
// 3.1 as-is: OK
|
||||
// 3.1 minus widening propagation: error
|
||||
obj.b = false;
|
||||
>obj.b = false : false
|
||||
>obj.b : boolean
|
||||
>obj : { b: boolean; }
|
||||
>b : boolean
|
||||
>false : false
|
||||
}
|
||||
|
||||
function f2() {
|
||||
>f2 : () => void
|
||||
|
||||
type Element = (string | false);
|
||||
>Element : string | false
|
||||
>false : false
|
||||
|
||||
type ElementOrArray = Element | Element[];
|
||||
>ElementOrArray : string | false | (string | false)[]
|
||||
|
||||
let el: Element = null as any;
|
||||
>el : string | false
|
||||
>null as any : any
|
||||
>null : null
|
||||
|
||||
let arr: Element[] = null as any;
|
||||
>arr : (string | false)[]
|
||||
>null as any : any
|
||||
>null : null
|
||||
|
||||
let elOrA: ElementOrArray = null as any;
|
||||
>elOrA : string | false | (string | false)[]
|
||||
>null as any : any
|
||||
>null : null
|
||||
|
||||
// Desired/actual: All OK
|
||||
let a1: ElementOrArray = el;
|
||||
>a1 : string | false | (string | false)[]
|
||||
>el : string | false
|
||||
|
||||
let a2: ElementOrArray = arr;
|
||||
>a2 : string | false | (string | false)[]
|
||||
>arr : (string | false)[]
|
||||
|
||||
let a3: ElementOrArray = [el];
|
||||
>a3 : string | false | (string | false)[]
|
||||
>[el] : (string | false)[]
|
||||
>el : string | false
|
||||
|
||||
let a4: ElementOrArray = Array.isArray(elOrA) ? elOrA : [elOrA];
|
||||
>a4 : string | false | (string | false)[]
|
||||
>Array.isArray(elOrA) ? elOrA : [elOrA] : (string | false)[]
|
||||
>Array.isArray(elOrA) : boolean
|
||||
>Array.isArray : (arg: any) => arg is any[]
|
||||
>Array : ArrayConstructor
|
||||
>isArray : (arg: any) => arg is any[]
|
||||
>elOrA : string | false | (string | false)[]
|
||||
>elOrA : (string | false)[]
|
||||
>[elOrA] : (string | false)[]
|
||||
>elOrA : string | false
|
||||
|
||||
// Desired: OK
|
||||
// 3.0: Error
|
||||
// 3.1: OK
|
||||
let a5: ElementOrArray = [...Array.isArray(elOrA) ? elOrA : [elOrA]];
|
||||
>a5 : string | false | (string | false)[]
|
||||
>[...Array.isArray(elOrA) ? elOrA : [elOrA]] : (string | false)[]
|
||||
>...Array.isArray(elOrA) ? elOrA : [elOrA] : string | false
|
||||
>Array.isArray(elOrA) ? elOrA : [elOrA] : (string | false)[]
|
||||
>Array.isArray(elOrA) : boolean
|
||||
>Array.isArray : (arg: any) => arg is any[]
|
||||
>Array : ArrayConstructor
|
||||
>isArray : (arg: any) => arg is any[]
|
||||
>elOrA : string | false | (string | false)[]
|
||||
>elOrA : (string | false)[]
|
||||
>[elOrA] : (string | false)[]
|
||||
>elOrA : string | false
|
||||
}
|
||||
|
||||
function f3() {
|
||||
>f3 : () => void
|
||||
|
||||
type XY = 'x' | 'y';
|
||||
>XY : "x" | "y"
|
||||
|
||||
const x: XY = 'x';
|
||||
>x : "x" | "y"
|
||||
>'x' : "x"
|
||||
|
||||
let x2 = x;
|
||||
>x2 : "x"
|
||||
>x : "x"
|
||||
|
||||
// Desired: OK (up for debate?)
|
||||
// 3.0: Error
|
||||
// 3.1 as-is: OK
|
||||
x2 = 'y';
|
||||
>x2 = 'y' : "y"
|
||||
>x2 : "x"
|
||||
>'y' : "y"
|
||||
|
||||
// Desired/actual: All OK
|
||||
let x3: XY = x;
|
||||
>x3 : "x" | "y"
|
||||
>x : "x"
|
||||
|
||||
x3 = 'y';
|
||||
>x3 = 'y' : "y"
|
||||
>x3 : "x" | "y"
|
||||
>'y' : "y"
|
||||
}
|
||||
|
||||
function f4() {
|
||||
>f4 : () => void
|
||||
|
||||
const x: boolean = true;
|
||||
>x : boolean
|
||||
>true : true
|
||||
|
||||
let x1 = x;
|
||||
>x1 : boolean
|
||||
>x : true
|
||||
|
||||
// Desired: OK
|
||||
// 3.0: OK
|
||||
// 3.1: OK
|
||||
// 3.1 minus widening propagation: error
|
||||
x1 = false;
|
||||
>x1 = false : false
|
||||
>x1 : boolean
|
||||
>false : false
|
||||
}
|
||||
|
||||
function f5() {
|
||||
>f5 : () => void
|
||||
|
||||
type XY = 'x' | 'y';
|
||||
>XY : "x" | "y"
|
||||
|
||||
let arr: XY[] = ['x'];
|
||||
>arr : ("x" | "y")[]
|
||||
>['x'] : "x"[]
|
||||
>'x' : "x"
|
||||
|
||||
arr = ['y'];
|
||||
>arr = ['y'] : "y"[]
|
||||
>arr : ("x" | "y")[]
|
||||
>['y'] : "y"[]
|
||||
>'y' : "y"
|
||||
|
||||
// Desired: OK
|
||||
// Error in all extant branches
|
||||
arr = [...['y']];
|
||||
>arr = [...['y']] : string[]
|
||||
>arr : ("x" | "y")[]
|
||||
>[...['y']] : string[]
|
||||
>...['y'] : string
|
||||
>['y'] : string[]
|
||||
>'y' : "y"
|
||||
}
|
||||
+1
-1
@@ -41,7 +41,7 @@ tests/cases/compiler/modularizeLibrary_ErrorFromUsingES6FeaturesWithOnlyES5Lib.t
|
||||
Math.sign(1);
|
||||
~~~~
|
||||
!!! error TS2551: Property 'sign' does not exist on type 'Math'. Did you mean 'sin'?
|
||||
!!! related TS2728 /.ts/lib.es5.d.ts:643:5: 'sin' is declared here.
|
||||
!!! related TS2728 /.ts/lib.es5.d.ts:703:5: 'sin' is declared here.
|
||||
|
||||
// Using ES6 object
|
||||
var o = {
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
tests/cases/conformance/salsa/bug27025.js(1,25): error TS2339: Property 'nonprop' does not exist on type 'Window'.
|
||||
tests/cases/conformance/salsa/bug27025.js(2,15): error TS2304: Cannot find name 'bar'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/salsa/bug27025.js (2 errors) ====
|
||||
module.exports = window.nonprop;
|
||||
~~~~~~~
|
||||
!!! error TS2339: Property 'nonprop' does not exist on type 'Window'.
|
||||
exports.foo = bar;
|
||||
~~~
|
||||
!!! error TS2304: Cannot find name 'bar'.
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
=== tests/cases/conformance/salsa/bug27025.js ===
|
||||
module.exports = window.nonprop;
|
||||
>module.exports : Symbol("tests/cases/conformance/salsa/bug27025", Decl(bug27025.js, 0, 0))
|
||||
>module : Symbol(export=, Decl(bug27025.js, 0, 0))
|
||||
>exports : Symbol(export=, Decl(bug27025.js, 0, 0))
|
||||
>window : Symbol(window, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
exports.foo = bar;
|
||||
>exports : Symbol(foo, Decl(bug27025.js, 0, 32))
|
||||
>foo : Symbol(foo, Decl(bug27025.js, 0, 32))
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
=== tests/cases/conformance/salsa/bug27025.js ===
|
||||
module.exports = window.nonprop;
|
||||
>module.exports = window.nonprop : any
|
||||
>module.exports : any
|
||||
>module : { "tests/cases/conformance/salsa/bug27025": any; }
|
||||
>exports : any
|
||||
>window.nonprop : any
|
||||
>window : Window
|
||||
>nonprop : any
|
||||
|
||||
exports.foo = bar;
|
||||
>exports.foo = bar : any
|
||||
>exports.foo : any
|
||||
>exports : any
|
||||
>foo : any
|
||||
>bar : any
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
//// [tests/cases/compiler/moduleResolution_automaticTypeDirectiveNames.ts] ////
|
||||
|
||||
//// [index.d.ts]
|
||||
declare const a: number;
|
||||
|
||||
//// [index.d.ts]
|
||||
declare const a: string;
|
||||
|
||||
//// [a.ts]
|
||||
a;
|
||||
|
||||
|
||||
//// [a.js]
|
||||
a;
|
||||
@@ -0,0 +1,8 @@
|
||||
=== /a.ts ===
|
||||
a;
|
||||
>a : Symbol(a, Decl(index.d.ts, 0, 13))
|
||||
|
||||
=== /node_modules/@types/a/index.d.ts ===
|
||||
declare const a: string;
|
||||
>a : Symbol(a, Decl(index.d.ts, 0, 13))
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
=== /a.ts ===
|
||||
a;
|
||||
>a : string
|
||||
|
||||
=== /node_modules/@types/a/index.d.ts ===
|
||||
declare const a: string;
|
||||
>a : string
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
//// [tests/cases/compiler/moduleResolution_noLeadingDot.ts] ////
|
||||
|
||||
//// [README.md]
|
||||
This is a test.
|
||||
|
||||
//// [a.ts]
|
||||
true;
|
||||
|
||||
|
||||
//// [a.js]
|
||||
true;
|
||||
@@ -0,0 +1,4 @@
|
||||
=== /a.ts ===
|
||||
true;
|
||||
No type information for this code.
|
||||
No type information for this code.
|
||||
@@ -0,0 +1,4 @@
|
||||
=== /a.ts ===
|
||||
true;
|
||||
>true : true
|
||||
|
||||
@@ -24,7 +24,7 @@ tests/cases/conformance/types/any/narrowExceptionVariableInCatchClause.ts(16,17)
|
||||
err.massage; // ERROR: Property 'massage' does not exist on type 'Error'
|
||||
~~~~~~~
|
||||
!!! error TS2551: Property 'massage' does not exist on type 'Error'. Did you mean 'message'?
|
||||
!!! related TS2728 /.ts/lib.es5.d.ts:904:5: 'message' is declared here.
|
||||
!!! related TS2728 /.ts/lib.es5.d.ts:964:5: 'message' is declared here.
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
Loaded 100 of 217 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user