Merge branch 'master' into vfs

This commit is contained in:
Ron Buckton committed 2018-05-01 18:58:31 -07:00
commit d62a11ffc0
244 files changed
+7414 -2974

No files matched your search

-50
View File
@@ -1,50 +0,0 @@
workflows:
version: 2
main:
jobs:
- node9
- node8
- node6
nightly:
triggers:
- schedule:
cron: "0 8 * * *"
filters:
branches:
only: master
jobs:
- node9:
context: nightlies
- node8:
context: nightlies
- node6:
context: nightlies
base: &base
environment:
- workerCount: 4
- timeout: 400000
steps:
- checkout
- run: |
git submodule update --init --recursive
npm uninstall typescript --no-save
npm uninstall tslint --no-save
npm install
#npm update Appeared in Jenkins only
npm test
version: 2
jobs:
node9:
docker:
- image: circleci/node:9
<<: *base
node8:
docker:
- image: circleci/node:8
<<: *base
node6:
docker:
- image: circleci/node:6
<<: *base
+2 -1
View File
@@ -146,7 +146,8 @@ const es2017LibrarySourceMap = es2017LibrarySource.map(source =>
const es2018LibrarySource = [
"es2018.regexp.d.ts",
"es2018.promise.d.ts"
"es2018.promise.d.ts",
"es2018.intl.d.ts"
];
const es2018LibrarySourceMap = es2018LibrarySource.map(source =>
({ target: "lib." + source, sources: ["header.d.ts", source] }));
+2 -1
View File
@@ -128,7 +128,8 @@ var es2017LibrarySourceMap = es2017LibrarySource.map(function (source) {
var es2018LibrarySource = [
"es2018.regexp.d.ts",
"es2018.promise.d.ts"
"es2018.promise.d.ts",
"es2018.intl.d.ts"
];
var es2018LibrarySourceMap = es2018LibrarySource.map(function (source) {
+1
View File
@@ -1,4 +1,5 @@
[![Build Status](https://travis-ci.org/Microsoft/TypeScript.svg?branch=master)](https://travis-ci.org/Microsoft/TypeScript)
[![VSTS Build Status](https://typescript.visualstudio.com/_apis/public/build/definitions/cf7ac146-d525-443c-b23c-0d58337efebc/4/badge)](https://typescript.visualstudio.com/TypeScript/_build/index?context=allDefinitions&path=%5C&definitionId=4&_a=completed)
[![npm version](https://badge.fury.io/js/typescript.svg)](https://www.npmjs.com/package/typescript)
[![Downloads](https://img.shields.io/npm/dm/typescript.svg)](https://www.npmjs.com/package/typescript)
+1 -1
View File
@@ -24,7 +24,7 @@ Please help us by doing the following steps before logging an issue:
-->
<!-- Please try to reproduce the issue with `typescript@next`. It may have already been fixed. -->
**TypeScript Version:** 2.7.0-dev.201xxxxx
**TypeScript Version:** 2.9.0-dev.201xxxxx
<!-- Search terms you tried before logging this (so others can find this issue more easily) -->
**Search Terms:**
-13
View File
@@ -1,13 +0,0 @@
#!/usr/bin/env bash
# Set up NVM
export NVM_DIR="/home/dotnet-bot/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
nvm install $1
npm uninstall typescript --no-save
npm uninstall tslint --no-save
npm install
npm update
npm test
-22
View File
@@ -1,22 +0,0 @@
// Import the utility functionality.
import jobs.generation.Utilities;
// Defines a the new of the repo, used elsewhere in the file
def project = GithubProject
def branch = GithubBranchName
def nodeVersions = ['stable', '8', '6']
nodeVersions.each { nodeVer ->
def newJobName = "typescript_node.${nodeVer}"
def newJob = job(Utilities.getFullJobName(project, newJobName, true)) {
steps {
shell("./jenkins.sh ${nodeVer}")
}
}
Utilities.standardJobSetup(newJob, project, true, "*/${branch}")
Utilities.setMachineAffinity(newJob, 'Ubuntu14.04', '20161020')
Utilities.addGithubPRTriggerForBranch(newJob, branch, "TypeScript Test Run ${newJobName}")
}
+978 -978
View File
File diff suppressed because it is too large. Load diff
+28 -5
View File
@@ -118,6 +118,7 @@ namespace ts {
let thisParentContainer: Node; // Container one level up
let blockScopeContainer: Node;
let lastContainer: Node;
let delayedTypedefs: { typedef: JSDocTypedefTag, container: Node, lastContainer: Node, blockScopeContainer: Node, parent: Node }[];
let seenThisKeyword: boolean;
// state used by control flow analysis
@@ -176,6 +177,7 @@ namespace ts {
bind(file);
file.symbolCount = symbolCount;
file.classifiableNames = classifiableNames;
delayedBindJSDocTypedefTag();
}
file = undefined;
@@ -186,6 +188,7 @@ namespace ts {
thisParentContainer = undefined;
blockScopeContainer = undefined;
lastContainer = undefined;
delayedTypedefs = undefined;
seenThisKeyword = false;
currentFlow = undefined;
currentBreakTarget = undefined;
@@ -450,8 +453,7 @@ namespace ts {
// and this case is specially handled. Module augmentations should only be merged with original module definition
// and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed.
if (node.kind === SyntaxKind.JSDocTypedefTag) Debug.assert(isInJavaScriptFile(node)); // We shouldn't add symbols for JSDoc nodes if not in a JS file.
const isJSDocTypedefInJSDocNamespace = isJSDocTypedefTag(node) && node.name && node.name.kind === SyntaxKind.Identifier && node.name.isInJSDocNamespace;
if ((!isAmbientModule(node) && (hasExportModifier || container.flags & NodeFlags.ExportContext)) || isJSDocTypedefInJSDocNamespace) {
if ((!isAmbientModule(node) && (hasExportModifier || container.flags & NodeFlags.ExportContext)) || isJSDocTypedefTag(node)) {
if (hasModifier(node, ModifierFlags.Default) && !getDeclarationName(node)) {
return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); // No local symbol for an unnamed default!
}
@@ -1727,7 +1729,7 @@ namespace ts {
declareModuleMember(node, symbolFlags, symbolExcludes);
break;
case SyntaxKind.SourceFile:
if (isExternalModule(<SourceFile>container)) {
if (isExternalOrCommonJsModule(<SourceFile>container)) {
declareModuleMember(node, symbolFlags, symbolExcludes);
break;
}
@@ -1745,6 +1747,24 @@ namespace ts {
bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes);
}
function delayedBindJSDocTypedefTag() {
if (!delayedTypedefs) {
return;
}
const saveContainer = container;
const saveLastContainer = lastContainer;
const saveBlockScopeContainer = blockScopeContainer;
const saveParent = parent;
for (const delay of delayedTypedefs) {
({ container, lastContainer, blockScopeContainer, parent } = delay);
bindBlockScopedDeclaration(delay.typedef, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes);
}
container = saveContainer;
lastContainer = saveLastContainer;
blockScopeContainer = saveBlockScopeContainer;
parent = saveParent;
}
// The binder visits every node in the syntax tree so it is a convenient place to perform a single localized
// check for reserved words used as identifiers in strict mode code.
function checkStrictModeIdentifier(node: Identifier) {
@@ -2194,7 +2214,7 @@ namespace ts {
case SyntaxKind.JSDocTypedefTag: {
const { fullName } = node as JSDocTypedefTag;
if (!fullName || fullName.kind === SyntaxKind.Identifier) {
return bindBlockScopedDeclaration(<Declaration>node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes);
(delayedTypedefs || (delayedTypedefs = [])).push({ typedef: node as JSDocTypedefTag, container, lastContainer, blockScopeContainer, parent });
}
break;
}
@@ -2304,7 +2324,10 @@ namespace ts {
return s;
});
if (symbol) {
declareSymbol(symbol.exports, symbol, lhs, SymbolFlags.Property | SymbolFlags.ExportValue, SymbolFlags.None);
const flags = isClassExpression(node.right) ?
SymbolFlags.Property | SymbolFlags.ExportValue | SymbolFlags.Class :
SymbolFlags.Property | SymbolFlags.ExportValue;
declareSymbol(symbol.exports, symbol, lhs, flags, SymbolFlags.None);
}
}
+1 -1
View File
@@ -249,7 +249,7 @@ namespace ts {
export function createBuilderProgram(kind: BuilderProgramKind, { newProgram, host, oldProgram, configFileParsingDiagnostics }: BuilderCreationParameters) {
// Return same program if underlying program doesnt change
let oldState = oldProgram && oldProgram.getState();
if (oldState && newProgram === oldState.program && configFileParsingDiagnostics !== newProgram.getConfigFileParsingDiagnostics()) {
if (oldState && newProgram === oldState.program && configFileParsingDiagnostics === newProgram.getConfigFileParsingDiagnostics()) {
newProgram = undefined;
oldState = undefined;
return oldProgram;
+315 -147
View File
@@ -60,7 +60,7 @@ namespace ts {
const compilerOptions = host.getCompilerOptions();
const languageVersion = getEmitScriptTarget(compilerOptions);
const modulekind = getEmitModuleKind(compilerOptions);
const moduleKind = getEmitModuleKind(compilerOptions);
const allowSyntheticDefaultImports = getAllowSyntheticDefaultImports(compilerOptions);
const strictNullChecks = getStrictOptionValue(compilerOptions, "strictNullChecks");
const strictFunctionTypes = getStrictOptionValue(compilerOptions, "strictFunctionTypes");
@@ -75,6 +75,8 @@ namespace ts {
const undefinedSymbol = createSymbol(SymbolFlags.Property, "undefined" as __String);
undefinedSymbol.declarations = [];
const argumentsSymbol = createSymbol(SymbolFlags.Property, "arguments" as __String);
const requireSymbol = createSymbol(SymbolFlags.Property, "require" as __String);
const moduleSymbol = createSymbol(SymbolFlags.Property, "module" as __String);
/** This will be set during calls to `getResolvedSignature` where services determines an apparent number of arguments greater than what is actually provided. */
let apparentArgumentCount: number | undefined;
@@ -443,6 +445,7 @@ namespace ts {
let deferredGlobalAsyncIteratorType: GenericType;
let deferredGlobalAsyncIterableIteratorType: GenericType;
let deferredGlobalTemplateStringsArrayType: ObjectType;
let deferredGlobalImportMetaType: ObjectType;
let deferredGlobalExtractSymbol: Symbol;
let deferredNodes: Node[];
@@ -617,22 +620,6 @@ namespace ts {
Both = Source | Target,
}
const enum TypeIncludes {
Any = 1 << 0,
Undefined = 1 << 1,
Null = 1 << 2,
Never = 1 << 3,
NonWideningType = 1 << 4,
String = 1 << 5,
Number = 1 << 6,
ESSymbol = 1 << 7,
LiteralOrUniqueESSymbol = 1 << 8,
ObjectType = 1 << 9,
EmptyObject = 1 << 10,
Union = 1 << 11,
Wildcard = 1 << 12,
}
const enum MembersOrExportsResolutionKind {
resolvedExports = "resolvedExports",
resolvedMembers = "resolvedMembers"
@@ -1094,7 +1081,7 @@ namespace ts {
const declarationFile = getSourceFileOfNode(declaration);
const useFile = getSourceFileOfNode(usage);
if (declarationFile !== useFile) {
if ((modulekind && (declarationFile.externalModuleIndicator || useFile.externalModuleIndicator)) ||
if ((moduleKind && (declarationFile.externalModuleIndicator || useFile.externalModuleIndicator)) ||
(!compilerOptions.outFile && !compilerOptions.out) ||
isInTypeQuery(usage) ||
declaration.flags & NodeFlags.Ambient) {
@@ -1126,6 +1113,10 @@ namespace ts {
// still might be illegal if usage is in the initializer of the variable declaration (eg var a = a)
return !isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration as VariableDeclaration, usage);
}
else if (isClassDeclaration(declaration)) {
// still might be illegal if the usage is within a computed property name in the class (eg class A { static p = "a"; [A.p]() {} })
return !findAncestor(usage, n => isComputedPropertyName(n) && n.parent.parent === declaration);
}
return true;
}
@@ -1481,7 +1472,17 @@ namespace ts {
result = lookup(globals, name, meaning);
}
}
if (!result) {
if (originalLocation && isInJavaScriptFile(originalLocation) && originalLocation.parent) {
if (isRequireCall(originalLocation.parent, /*checkArgumentIsStringLiteralLike*/ false)) {
return requireSymbol;
}
if (isIdentifier(originalLocation) && isPropertyAccessExpression(originalLocation.parent) &&
originalLocation.escapedText === "module" && originalLocation.parent.name.escapedText === "exports") {
return moduleSymbol;
}
}
}
if (!result) {
if (nameNotFoundMessage) {
if (!errorLocation ||
@@ -4180,7 +4181,7 @@ namespace ts {
const isPrivate = getDeclarationModifierFlagsFromSymbol(prop) & (ModifierFlags.Private | ModifierFlags.Protected);
const isSetOnlyAccessor = prop.flags & SymbolFlags.SetAccessor && !(prop.flags & SymbolFlags.GetAccessor);
if (!inNamesToRemove && !isPrivate && !isClassMethod(prop) && !isSetOnlyAccessor) {
members.set(prop.escapedName, prop);
members.set(prop.escapedName, getNonReadonlySymbol(prop));
}
}
const stringIndexInfo = getIndexInfoOfType(source, IndexKind.String);
@@ -4227,12 +4228,29 @@ namespace ts {
const isLate = isLateBindableName(name);
const isWellKnown = isComputedPropertyName(name) && isWellKnownSymbolSyntactically(name.expression);
if (!isLate && !isWellKnown && isComputedNonLiteralName(name)) {
return anyType;
const exprType = checkExpression((name as ComputedPropertyName).expression);
if (isTypeAssignableToKind(exprType, TypeFlags.ESSymbolLike)) {
if (noImplicitAny) {
error(declaration, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(exprType), typeToString(parentType));
}
return anyType;
}
const indexerType = isTypeAssignableToKind(exprType, TypeFlags.NumberLike) && getIndexTypeOfType(parentType, IndexKind.Number) || getIndexTypeOfType(parentType, IndexKind.String);
if (!indexerType && noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors) {
if (getIndexTypeOfType(parentType, IndexKind.Number)) {
error(declaration, Diagnostics.Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number);
}
else {
error(declaration, Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature, typeToString(parentType));
}
}
return indexerType || anyType;
}
// Use type of the specified property, or otherwise, for a numeric name, the type of the numeric index signature,
// or otherwise the type of the string index signature.
const text = isLate ? getLateBoundNameFromType(checkComputedPropertyName(name as ComputedPropertyName) as LiteralType | UniqueESSymbolType) :
const nameType = isLate && checkComputedPropertyName(name as ComputedPropertyName) as LiteralType | UniqueESSymbolType;
const text = isLate ? getLateBoundNameFromType(nameType) :
isWellKnown ? getPropertyNameForKnownSymbolName(idText(((name as ComputedPropertyName).expression as PropertyAccessExpression).name)) :
getTextOfPropertyName(name);
@@ -4240,6 +4258,12 @@ namespace ts {
if (strictNullChecks && declaration.flags & NodeFlags.Ambient && isParameterDeclaration(declaration)) {
parentType = getNonNullableType(parentType);
}
if (isLate && nameType && !getPropertyOfType(parentType, text) && isTypeAssignableToKind(nameType, TypeFlags.ESSymbolLike)) {
if (noImplicitAny) {
error(declaration, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(nameType), typeToString(parentType));
}
return anyType;
}
const declaredType = getConstraintForLocation(getTypeOfPropertyOfType(parentType, text), declaration.name);
type = declaredType && getFlowTypeOfReference(declaration, declaredType) ||
isNumericLiteralName(text) && getIndexTypeOfType(parentType, IndexKind.Number) ||
@@ -4671,6 +4695,10 @@ namespace ts {
if (symbol.flags & SymbolFlags.Prototype) {
return links.type = getTypeOfPrototypeProperty(symbol);
}
// CommonsJS require/module/exports all have type any.
if (symbol === requireSymbol || symbol === moduleSymbol) {
return links.type = anyType;
}
// Handle catch clause variables
const declaration = symbol.valueDeclaration;
if (isCatchClauseVariableDeclarationOrBindingElement(declaration)) {
@@ -6470,6 +6498,47 @@ namespace ts {
return getConstraintOfDistributiveConditionalType(type) || getDefaultConstraintOfConditionalType(type);
}
function getUnionConstraintOfIntersection(type: IntersectionType, targetIsUnion: boolean) {
let constraints: Type[];
let hasDisjointDomainType = false;
for (const t of type.types) {
if (t.flags & TypeFlags.Instantiable) {
// We keep following constraints as long as we have an instantiable type that is known
// not to be circular or infinite (hence we stop on index access types).
let constraint = getConstraintOfType(t);
while (constraint && constraint.flags & (TypeFlags.TypeParameter | TypeFlags.Index | TypeFlags.Conditional)) {
constraint = getConstraintOfType(constraint);
}
if (constraint) {
// A constraint that isn't a union type implies that the final type would be a non-union
// type as well. Since non-union constraints are of no interest, we can exit here.
if (!(constraint.flags & TypeFlags.Union)) {
return undefined;
}
constraints = append(constraints, constraint);
}
}
else if (t.flags & TypeFlags.DisjointDomains) {
hasDisjointDomainType = true;
}
}
// If the target is a union type or if we are intersecting with types belonging to one of the
// disjoint domans, we may end up producing a constraint that hasn't been examined before.
if (constraints && (targetIsUnion || hasDisjointDomainType)) {
if (hasDisjointDomainType) {
// We add any types belong to one of the disjoint domans because they might cause the final
// intersection operation to reduce the union constraints.
for (const t of type.types) {
if (t.flags & TypeFlags.DisjointDomains) {
constraints = append(constraints, t);
}
}
}
return getIntersectionType(constraints);
}
return undefined;
}
function getBaseConstraintOfInstantiableNonPrimitiveUnionOrIntersection(type: Type) {
if (type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.UnionOrIntersection)) {
const constraint = getResolvedBaseConstraint(<InstantiableType | UnionOrIntersectionType>type);
@@ -7573,23 +7642,38 @@ namespace ts {
return unknownType;
}
// A jsdoc TypeReference may have resolved to a value (as opposed to a type). If
// the symbol is a constructor function, return the inferred class type; otherwise,
// the type of this reference is just the type of the value we resolved to.
const assignedType = getAssignedClassType(symbol);
const valueType = getTypeOfSymbol(symbol);
const referenceType = valueType.symbol && !isInferredClassType(valueType) && getTypeReferenceTypeWorker(node, valueType.symbol, typeArguments);
if (referenceType || assignedType) {
return referenceType && assignedType ? getIntersectionType([assignedType, referenceType]) : referenceType || assignedType;
const jsdocType = getJSDocTypeReference(node, symbol, typeArguments);
if (jsdocType) {
return jsdocType;
}
// Resolve the type reference as a Type for the purpose of reporting errors.
resolveTypeReferenceName(getTypeReferenceName(node), SymbolFlags.Type);
return valueType;
return getTypeOfSymbol(symbol);
}
/**
* A jsdoc TypeReference may have resolved to a value (as opposed to a type). If
* the symbol is a constructor function, return the inferred class type; otherwise,
* the type of this reference is just the type of the value we resolved to.
*/
function getJSDocTypeReference(node: NodeWithTypeArguments, symbol: Symbol, typeArguments: Type[]): Type | undefined {
const assignedType = getAssignedClassType(symbol);
const valueType = getTypeOfSymbol(symbol);
const referenceType = valueType.symbol && valueType.symbol !== symbol && !isInferredClassType(valueType) && getTypeReferenceTypeWorker(node, valueType.symbol, typeArguments);
if (referenceType || assignedType) {
return referenceType && assignedType ? getIntersectionType([assignedType, referenceType]) : referenceType || assignedType;
}
}
function getTypeReferenceTypeWorker(node: NodeWithTypeArguments, symbol: Symbol, typeArguments: Type[]): Type | undefined {
if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
if (symbol.valueDeclaration && isBinaryExpression(symbol.valueDeclaration.parent)) {
const jsdocType = getJSDocTypeReference(node, symbol, typeArguments);
if (jsdocType) {
return jsdocType;
}
}
return getTypeFromClassOrInterfaceReference(node, symbol, typeArguments);
}
@@ -7796,6 +7880,10 @@ namespace ts {
return deferredGlobalTemplateStringsArrayType || (deferredGlobalTemplateStringsArrayType = getGlobalType("TemplateStringsArray" as __String, /*arity*/ 0, /*reportErrors*/ true)) || emptyObjectType;
}
function getGlobalImportMetaType() {
return deferredGlobalImportMetaType || (deferredGlobalImportMetaType = getGlobalType("ImportMeta" as __String, /*arity*/ 0, /*reportErrors*/ true)) || emptyObjectType;
}
function getGlobalESSymbolConstructorSymbol(reportErrors: boolean) {
return deferredGlobalESSymbolConstructorSymbol || (deferredGlobalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol" as __String, reportErrors));
}
@@ -7951,8 +8039,14 @@ namespace ts {
return binarySearch(types, type, getTypeId, compareValues) >= 0;
}
// Return true if the given intersection type contains (a) more than one unit type or (b) an object
// type and a nullable type (null or undefined).
// Return true if the given intersection type contains
// more than one unit type or,
// an object type and a nullable type (null or undefined), or
// a string-like type and a type known to be non-string-like, or
// a number-like type and a type known to be non-number-like, or
// a symbol-like type and a type known to be non-symbol-like, or
// a void-like type and a type known to be non-void-like, or
// a non-primitive type and a type known to be primitive.
function isEmptyIntersectionType(type: IntersectionType) {
let combined: TypeFlags = 0;
for (const t of type.types) {
@@ -7960,42 +8054,43 @@ namespace ts {
return true;
}
combined |= t.flags;
if (combined & TypeFlags.Nullable && combined & (TypeFlags.Object | TypeFlags.NonPrimitive)) {
if (combined & TypeFlags.Nullable && combined & (TypeFlags.Object | TypeFlags.NonPrimitive) ||
combined & TypeFlags.NonPrimitive && combined & (TypeFlags.DisjointDomains & ~TypeFlags.NonPrimitive) ||
combined & TypeFlags.StringLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.StringLike) ||
combined & TypeFlags.NumberLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.NumberLike) ||
combined & TypeFlags.ESSymbolLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.ESSymbolLike) ||
combined & TypeFlags.VoidLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.VoidLike)) {
return true;
}
}
return false;
}
function addTypeToUnion(typeSet: Type[], includes: TypeIncludes, type: Type) {
function addTypeToUnion(typeSet: Type[], includes: TypeFlags, type: Type) {
const flags = type.flags;
if (flags & TypeFlags.Union) {
includes = addTypesToUnion(typeSet, includes, (<UnionType>type).types);
return addTypesToUnion(typeSet, includes, (<UnionType>type).types);
}
else if (flags & TypeFlags.Any) {
includes |= TypeIncludes.Any;
if (type === wildcardType) includes |= TypeIncludes.Wildcard;
}
else if (!strictNullChecks && flags & TypeFlags.Nullable) {
if (flags & TypeFlags.Undefined) includes |= TypeIncludes.Undefined;
if (flags & TypeFlags.Null) includes |= TypeIncludes.Null;
if (!(flags & TypeFlags.ContainsWideningType)) includes |= TypeIncludes.NonWideningType;
}
else if (!(flags & TypeFlags.Never || flags & TypeFlags.Intersection && isEmptyIntersectionType(<IntersectionType>type))) {
// We ignore 'never' types in unions. Likewise, we ignore intersections of unit types as they are
// another form of 'never' (in that they have an empty value domain). We could in theory turn
// intersections of unit types into 'never' upon construction, but deferring the reduction makes it
// easier to reason about their origin.
if (flags & TypeFlags.String) includes |= TypeIncludes.String;
if (flags & TypeFlags.Number) includes |= TypeIncludes.Number;
if (flags & TypeFlags.ESSymbol) includes |= TypeIncludes.ESSymbol;
if (flags & TypeFlags.StringOrNumberLiteralOrUnique) includes |= TypeIncludes.LiteralOrUniqueESSymbol;
const len = typeSet.length;
const index = len && type.id > typeSet[len - 1].id ? ~len : binarySearch(typeSet, type, getTypeId, compareValues);
if (index < 0) {
if (!(flags & TypeFlags.Object && (<ObjectType>type).objectFlags & ObjectFlags.Anonymous &&
type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && containsIdenticalType(typeSet, type))) {
typeSet.splice(~index, 0, type);
// We ignore 'never' types in unions. Likewise, we ignore intersections of unit types as they are
// another form of 'never' (in that they have an empty value domain). We could in theory turn
// intersections of unit types into 'never' upon construction, but deferring the reduction makes it
// easier to reason about their origin.
if (!(flags & TypeFlags.Never || flags & TypeFlags.Intersection && isEmptyIntersectionType(<IntersectionType>type))) {
includes |= flags & ~TypeFlags.ConstructionFlags;
if (flags & TypeFlags.Any) {
if (type === wildcardType) includes |= TypeFlags.Wildcard;
}
else if (!strictNullChecks && flags & TypeFlags.Nullable) {
if (!(flags & TypeFlags.ContainsWideningType)) includes |= TypeFlags.NonWideningType;
}
else {
const len = typeSet.length;
const index = len && type.id > typeSet[len - 1].id ? ~len : binarySearch(typeSet, type, getTypeId, compareValues);
if (index < 0) {
if (!(flags & TypeFlags.Object && (<ObjectType>type).objectFlags & ObjectFlags.Anonymous &&
type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && containsIdenticalType(typeSet, type))) {
typeSet.splice(~index, 0, type);
}
}
}
}
@@ -8004,7 +8099,7 @@ namespace ts {
// Add the given types to the given type set. Order is preserved, duplicates are removed,
// and nested types of the given kind are flattened into the set.
function addTypesToUnion(typeSet: Type[], includes: TypeIncludes, types: Type[]): TypeIncludes {
function addTypesToUnion(typeSet: Type[], includes: TypeFlags, types: Type[]): TypeFlags {
for (const type of types) {
includes = addTypeToUnion(typeSet, includes, type);
}
@@ -8061,15 +8156,15 @@ namespace ts {
}
}
function removeRedundantLiteralTypes(types: Type[], includes: TypeIncludes) {
function removeRedundantLiteralTypes(types: Type[], includes: TypeFlags) {
let i = types.length;
while (i > 0) {
i--;
const t = types[i];
const remove =
t.flags & TypeFlags.StringLiteral && includes & TypeIncludes.String ||
t.flags & TypeFlags.NumberLiteral && includes & TypeIncludes.Number ||
t.flags & TypeFlags.UniqueESSymbol && includes & TypeIncludes.ESSymbol ||
t.flags & TypeFlags.StringLiteral && includes & TypeFlags.String ||
t.flags & TypeFlags.NumberLiteral && includes & TypeFlags.Number ||
t.flags & TypeFlags.UniqueESSymbol && includes & TypeFlags.ESSymbol ||
t.flags & TypeFlags.StringOrNumberLiteral && t.flags & TypeFlags.FreshLiteral && containsType(types, (<LiteralType>t).regularType);
if (remove) {
orderedRemoveItemAt(types, i);
@@ -8093,12 +8188,12 @@ namespace ts {
}
const typeSet: Type[] = [];
const includes = addTypesToUnion(typeSet, 0, types);
if (includes & TypeIncludes.Any) {
return includes & TypeIncludes.Wildcard ? wildcardType : anyType;
if (includes & TypeFlags.Any) {
return includes & TypeFlags.Wildcard ? wildcardType : anyType;
}
switch (unionReduction) {
case UnionReduction.Literal:
if (includes & TypeIncludes.LiteralOrUniqueESSymbol) {
if (includes & TypeFlags.StringOrNumberLiteralOrUnique) {
removeRedundantLiteralTypes(typeSet, includes);
}
break;
@@ -8107,8 +8202,8 @@ namespace ts {
break;
}
if (typeSet.length === 0) {
return includes & TypeIncludes.Null ? includes & TypeIncludes.NonWideningType ? nullType : nullWideningType :
includes & TypeIncludes.Undefined ? includes & TypeIncludes.NonWideningType ? undefinedType : undefinedWideningType :
return includes & TypeFlags.Null ? includes & TypeFlags.NonWideningType ? nullType : nullWideningType :
includes & TypeFlags.Undefined ? includes & TypeFlags.NonWideningType ? undefinedType : undefinedWideningType :
neverType;
}
return getUnionTypeFromSortedList(typeSet, aliasSymbol, aliasTypeArguments);
@@ -8186,30 +8281,23 @@ namespace ts {
return links.resolvedType;
}
function addTypeToIntersection(typeSet: Type[], includes: TypeIncludes, type: Type) {
function addTypeToIntersection(typeSet: Type[], includes: TypeFlags, type: Type) {
const flags = type.flags;
if (flags & TypeFlags.Intersection) {
includes = addTypesToIntersection(typeSet, includes, (<IntersectionType>type).types);
return addTypesToIntersection(typeSet, includes, (<IntersectionType>type).types);
}
else if (flags & TypeFlags.Any) {
includes |= TypeIncludes.Any;
if (type === wildcardType) includes |= TypeIncludes.Wildcard;
if (getObjectFlags(type) & ObjectFlags.Anonymous && isEmptyObjectType(type)) {
includes |= TypeFlags.EmptyObject;
}
else if (flags & TypeFlags.Never) {
includes |= TypeIncludes.Never;
}
else if (getObjectFlags(type) & ObjectFlags.Anonymous && isEmptyObjectType(type)) {
includes |= TypeIncludes.EmptyObject;
}
else if ((strictNullChecks || !(flags & TypeFlags.Nullable)) && !contains(typeSet, type)) {
if (flags & TypeFlags.Object) {
includes |= TypeIncludes.ObjectType;
else {
includes |= flags & ~TypeFlags.ConstructionFlags;
if (flags & TypeFlags.Any) {
if (type === wildcardType) includes |= TypeFlags.Wildcard;
}
if (flags & TypeFlags.Union) {
includes |= TypeIncludes.Union;
}
if (!(flags & TypeFlags.Object && (<ObjectType>type).objectFlags & ObjectFlags.Anonymous &&
type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && containsIdenticalType(typeSet, type))) {
else if ((strictNullChecks || !(flags & TypeFlags.Nullable)) && !contains(typeSet, type) &&
!(flags & TypeFlags.Object && (<ObjectType>type).objectFlags & ObjectFlags.Anonymous &&
type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) &&
containsIdenticalType(typeSet, type))) {
typeSet.push(type);
}
}
@@ -8218,13 +8306,28 @@ namespace ts {
// Add the given types to the given type set. Order is preserved, freshness is removed from literal
// types, duplicates are removed, and nested types of the given kind are flattened into the set.
function addTypesToIntersection(typeSet: Type[], includes: TypeIncludes, types: Type[]) {
function addTypesToIntersection(typeSet: Type[], includes: TypeFlags, types: Type[]) {
for (const type of types) {
includes = addTypeToIntersection(typeSet, includes, getRegularTypeOfLiteralType(type));
}
return includes;
}
function removeRedundantPrimitiveTypes(types: Type[], includes: TypeFlags) {
let i = types.length;
while (i > 0) {
i--;
const t = types[i];
const remove =
t.flags & TypeFlags.String && includes & TypeFlags.StringLiteral ||
t.flags & TypeFlags.Number && includes & TypeFlags.NumberLiteral ||
t.flags & TypeFlags.ESSymbol && includes & TypeFlags.UniqueESSymbol;
if (remove) {
orderedRemoveItemAt(types, i);
}
}
}
// We normalize combinations of intersection and union types based on the distributive property of the '&'
// operator. Specifically, because X & (A | B) is equivalent to X & A | X & B, we can transform intersection
// types with union type constituents into equivalent union types with intersection type constituents and
@@ -8241,19 +8344,24 @@ namespace ts {
}
const typeSet: Type[] = [];
const includes = addTypesToIntersection(typeSet, 0, types);
if (includes & TypeIncludes.Never) {
if (includes & TypeFlags.Never) {
return neverType;
}
if (includes & TypeIncludes.Any) {
return includes & TypeIncludes.Wildcard ? wildcardType : anyType;
if (includes & TypeFlags.Any) {
return includes & TypeFlags.Wildcard ? wildcardType : anyType;
}
if (includes & TypeIncludes.EmptyObject && !(includes & TypeIncludes.ObjectType)) {
if (includes & TypeFlags.String && includes & TypeFlags.StringLiteral ||
includes & TypeFlags.Number && includes & TypeFlags.NumberLiteral ||
includes & TypeFlags.ESSymbol && includes & TypeFlags.UniqueESSymbol) {
removeRedundantPrimitiveTypes(typeSet, includes);
}
if (includes & TypeFlags.EmptyObject && !(includes & TypeFlags.Object)) {
typeSet.push(emptyObjectType);
}
if (typeSet.length === 1) {
return typeSet[0];
}
if (includes & TypeIncludes.Union) {
if (includes & TypeFlags.Union) {
// We are attempting to construct a type of the form X & (A | B) & Y. Transform this into a type of
// the form X & A & Y | X & B & Y and recursively reduce until no union type constituents remain.
const unionIndex = findIndex(typeSet, t => (t.flags & TypeFlags.Union) !== 0);
@@ -10180,6 +10288,23 @@ namespace ts {
}
}
}
if (!result && source.flags & TypeFlags.Intersection) {
// The combined constraint of an intersection type is the intersection of the constraints of
// the constituents. When an intersection type contains instantiable types with union type
// constraints, there are situations where we need to examine the combined constraint. One is
// when the target is a union type. Another is when the intersection contains types belonging
// to one of the disjoint domains. For example, given type variables T and U, each with the
// constraint 'string | number', the combined constraint of 'T & U' is 'string | number' and
// we need to check this constraint against a union on the target side. Also, given a type
// variable V constrained to 'string | number', 'V & number' has a combined constraint of
// 'string & number | number & number' which reduces to just 'number'.
const constraint = getUnionConstraintOfIntersection(<IntersectionType>source, !!(target.flags & TypeFlags.Union));
if (constraint) {
if (result = isRelatedTo(constraint, target, reportErrors)) {
errorInfo = saveErrorInfo;
}
}
}
isIntersectionConstituent = saveIsIntersectionConstituent;
@@ -10537,11 +10662,14 @@ namespace ts {
}
}
// A type S is assignable to keyof T if S is assignable to keyof C, where C is the
// constraint of T.
const constraint = getConstraintForRelation((<IndexType>target).type);
if (constraint) {
if (result = isRelatedTo(source, getIndexType(constraint, (target as IndexType).stringsOnly), reportErrors)) {
return result;
// simplified form of T or, if T doesn't simplify, the constraint of T.
if (relation !== definitelyAssignableRelation) {
const simplified = getSimplifiedType((<IndexType>target).type);
const constraint = simplified !== (<IndexType>target).type ? simplified : getConstraintOfType((<IndexType>target).type);
if (constraint) {
if (result = isRelatedTo(source, getIndexType(constraint, (target as IndexType).stringsOnly), reportErrors)) {
return result;
}
}
}
}
@@ -10577,23 +10705,8 @@ namespace ts {
}
}
if (source.flags & TypeFlags.TypeParameter) {
let constraint = getConstraintForRelation(<TypeParameter>source);
// A type parameter with no constraint is not related to the non-primitive object type.
if (constraint || !(target.flags & TypeFlags.NonPrimitive)) {
if (!constraint || constraint.flags & TypeFlags.Any) {
constraint = emptyObjectType;
}
// Report constraint errors only if the constraint is not the empty object type
const reportConstraintErrors = reportErrors && constraint !== emptyObjectType;
if (result = isRelatedTo(constraint, target, reportConstraintErrors)) {
errorInfo = saveErrorInfo;
return result;
}
}
}
else if (source.flags & TypeFlags.IndexedAccess) {
if (target.flags & TypeFlags.IndexedAccess) {
if (source.flags & TypeFlags.TypeVariable) {
if (source.flags & TypeFlags.IndexedAccess && target.flags & TypeFlags.IndexedAccess) {
// A type S[K] is related to a type T[J] if S is related to T and K is related to J.
if (result = isRelatedTo((<IndexedAccessType>source).objectType, (<IndexedAccessType>target).objectType, reportErrors)) {
result &= isRelatedTo((<IndexedAccessType>source).indexType, (<IndexedAccessType>target).indexType, reportErrors);
@@ -10603,15 +10716,18 @@ namespace ts {
return result;
}
}
// A type S[K] is related to a type T if C is related to T, where C is the
// constraint of S[K].
const constraint = getConstraintForRelation(<IndexedAccessType>source);
if (constraint) {
if (result = isRelatedTo(constraint, target, reportErrors)) {
const constraint = getConstraintForRelation(<TypeParameter>source);
if (!constraint || constraint.flags & TypeFlags.Any) {
// A type variable with no constraint is not related to the non-primitive object type.
if (result = isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~TypeFlags.NonPrimitive))) {
errorInfo = saveErrorInfo;
return result;
}
}
else if (result = isRelatedTo(constraint, target, reportErrors)) {
errorInfo = saveErrorInfo;
return result;
}
}
else if (source.flags & TypeFlags.Index) {
if (result = isRelatedTo(keyofConstraintType, target, reportErrors)) {
@@ -11475,6 +11591,10 @@ namespace ts {
return !!getPropertyOfType(type, "0" as __String);
}
function isNeitherUnitTypeNorNever(type: Type): boolean {
return !(type.flags & (TypeFlags.Unit | TypeFlags.Never));
}
function isUnitType(type: Type): boolean {
return !!(type.flags & TypeFlags.Unit);
}
@@ -12954,8 +13074,7 @@ namespace ts {
function getTypeOfSwitchClause(clause: CaseClause | DefaultClause) {
if (clause.kind === SyntaxKind.CaseClause) {
const caseType = getRegularTypeOfLiteralType(getTypeOfExpression(clause.expression));
return isUnitType(caseType) ? caseType : undefined;
return getRegularTypeOfLiteralType(getTypeOfExpression(clause.expression));
}
return neverType;
}
@@ -12963,15 +13082,9 @@ namespace ts {
function getSwitchClauseTypes(switchStatement: SwitchStatement): Type[] {
const links = getNodeLinks(switchStatement);
if (!links.switchTypes) {
// If all case clauses specify expressions that have unit types, we return an array
// of those unit types. Otherwise we return an empty array.
links.switchTypes = [];
for (const clause of switchStatement.caseBlock.clauses) {
const type = getTypeOfSwitchClause(clause);
if (type === undefined) {
return links.switchTypes = emptyArray;
}
links.switchTypes.push(type);
links.switchTypes.push(getTypeOfSwitchClause(clause));
}
}
return links.switchTypes;
@@ -13611,7 +13724,7 @@ namespace ts {
const doubleEquals = operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsToken;
const facts = doubleEquals ?
assumeTrue ? TypeFacts.EQUndefinedOrNull : TypeFacts.NEUndefinedOrNull :
value.kind === SyntaxKind.NullKeyword ?
valueType.flags & TypeFlags.Null ?
assumeTrue ? TypeFacts.EQNull : TypeFacts.NENull :
assumeTrue ? TypeFacts.EQUndefined : TypeFacts.NEUndefined;
return getTypeWithFacts(type, facts);
@@ -18758,11 +18871,10 @@ namespace ts {
// Make sure require is not a local function
if (!isIdentifier(node.expression)) return Debug.fail();
const resolvedRequire = resolveName(node.expression, node.expression.escapedText, SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true);
if (!resolvedRequire) {
// project does not contain symbol named 'require' - assume commonjs require
if (resolvedRequire === requireSymbol) {
return true;
}
// project includes symbol named 'require' - make sure that it it ambient and local non-alias
// project includes symbol named 'require' - make sure that it is ambient and local non-alias
if (resolvedRequire.flags & SymbolFlags.Alias) {
return false;
}
@@ -18813,6 +18925,17 @@ namespace ts {
function checkMetaProperty(node: MetaProperty) {
checkGrammarMetaProperty(node);
if (node.keywordToken === SyntaxKind.NewKeyword) {
return checkNewTargetMetaProperty(node);
}
if (node.keywordToken === SyntaxKind.ImportKeyword) {
return checkImportMetaProperty(node);
}
}
function checkNewTargetMetaProperty(node: MetaProperty) {
const container = getNewTargetContainer(node);
if (!container) {
error(node, Diagnostics.Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constructor, "new.target");
@@ -18828,6 +18951,16 @@ namespace ts {
}
}
function checkImportMetaProperty(node: MetaProperty) {
if (languageVersion < ScriptTarget.ESNext || moduleKind < ModuleKind.ESNext) {
error(node, Diagnostics.The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_options);
}
const file = getSourceFileOfNode(node);
Debug.assert(!!(file.flags & NodeFlags.PossiblyContainsImportMeta), "Containing file is missing import meta node flag.");
Debug.assert(!!file.externalModuleIndicator, "Containing file should be a module.");
return node.name.escapedText === "meta" ? getGlobalImportMetaType() : unknownType;
}
function getTypeOfParameter(symbol: Symbol) {
const type = getTypeOfSymbol(symbol);
if (strictNullChecks) {
@@ -19075,7 +19208,7 @@ namespace ts {
return false;
}
const switchTypes = getSwitchClauseTypes(node);
if (!switchTypes.length) {
if (!switchTypes.length || some(switchTypes, isNeitherUnitTypeNorNever)) {
return false;
}
return eachTypeContainedIn(mapType(type, getRegularTypeOfLiteralType), switchTypes);
@@ -19927,6 +20060,7 @@ namespace ts {
getUnionType([removeDefinitelyFalsyTypes(leftType), rightType], UnionReduction.Subtype) :
leftType;
case SyntaxKind.EqualsToken:
checkSpecialAssignment(left, right);
checkAssignmentOperator(rightType);
return getRegularTypeOfObjectLiteral(rightType);
case SyntaxKind.CommaToken:
@@ -19936,6 +20070,24 @@ namespace ts {
return rightType;
}
function checkSpecialAssignment(left: Node, right: Expression) {
const special = getSpecialPropertyAssignmentKind(left.parent as BinaryExpression);
if (special === SpecialPropertyAssignmentKind.ModuleExports) {
const rightType = checkExpression(right, checkMode);
for (const prop of getPropertiesOfObjectType(rightType)) {
const propType = getTypeOfSymbol(prop);
if (propType.symbol && propType.symbol.flags & SymbolFlags.Class) {
const name = prop.escapedName;
const symbol = resolveName(prop.valueDeclaration, name, SymbolFlags.Type, undefined, name, /*isUse*/ false);
if (symbol) {
grammarErrorOnNode(symbol.declarations[0], Diagnostics.Duplicate_identifier_0, unescapeLeadingUnderscores(name));
return grammarErrorOnNode(prop.valueDeclaration, Diagnostics.Duplicate_identifier_0, unescapeLeadingUnderscores(name));
}
}
}
}
}
function isEvalNode(node: Expression) {
return node.kind === SyntaxKind.Identifier && (node as Identifier).escapedText === "eval";
}
@@ -21459,7 +21611,8 @@ namespace ts {
ExportType = 1 << 1,
ExportNamespace = 1 << 2,
}
function getDeclarationSpaces(d: Declaration): DeclarationSpaces {
function getDeclarationSpaces(decl: Declaration): DeclarationSpaces {
let d = decl as Node;
switch (d.kind) {
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.TypeAliasDeclaration:
@@ -21475,6 +21628,13 @@ namespace ts {
return DeclarationSpaces.ExportType | DeclarationSpaces.ExportValue;
case SyntaxKind.SourceFile:
return DeclarationSpaces.ExportType | DeclarationSpaces.ExportValue | DeclarationSpaces.ExportNamespace;
case SyntaxKind.ExportAssignment:
// Export assigned entity name expressions act as aliases and should fall through, otherwise they export values
if (!isEntityNameExpression((d as ExportAssignment).expression)) {
return DeclarationSpaces.ExportValue;
}
d = (d as ExportAssignment).expression;
/* falls through */
// The below options all declare an Alias, which is allowed to merge with other values within the importing module
case SyntaxKind.ImportEqualsDeclaration:
case SyntaxKind.NamespaceImport:
@@ -22450,7 +22610,7 @@ namespace ts {
function checkCollisionWithRequireExportsInGeneratedCode(node: Node, name: Identifier) {
// No need to check for require or exports for ES6 modules and later
if (modulekind >= ModuleKind.ES2015 || compilerOptions.noEmit) {
if (moduleKind >= ModuleKind.ES2015 || compilerOptions.noEmit) {
return;
}
@@ -24646,7 +24806,7 @@ namespace ts {
}
}
else {
if (modulekind >= ModuleKind.ES2015 && !(node.flags & NodeFlags.Ambient)) {
if (moduleKind >= ModuleKind.ES2015 && !(node.flags & NodeFlags.Ambient)) {
// Import equals declaration is deprecated in es6 or above
grammarErrorOnNode(node, Diagnostics.Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead);
}
@@ -24684,7 +24844,7 @@ namespace ts {
error(node.moduleSpecifier, Diagnostics.Module_0_uses_export_and_cannot_be_used_with_export_Asterisk, symbolToString(moduleSymbol));
}
if (modulekind !== ModuleKind.System && modulekind !== ModuleKind.ES2015 && modulekind !== ModuleKind.ESNext) {
if (moduleKind !== ModuleKind.System && moduleKind !== ModuleKind.ES2015 && moduleKind !== ModuleKind.ESNext) {
checkExternalEmitHelpers(node, ExternalEmitHelpers.ExportStar);
}
}
@@ -24757,11 +24917,11 @@ namespace ts {
}
if (node.isExportEquals && !(node.flags & NodeFlags.Ambient)) {
if (modulekind >= ModuleKind.ES2015) {
if (moduleKind >= ModuleKind.ES2015) {
// export assignment is not supported in es6 modules
grammarErrorOnNode(node, Diagnostics.Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or_another_module_format_instead);
}
else if (modulekind === ModuleKind.System) {
else if (moduleKind === ModuleKind.System) {
// system modules does not support export assignment
grammarErrorOnNode(node, Diagnostics.Export_assignment_is_not_supported_when_module_flag_is_system);
}
@@ -27709,10 +27869,18 @@ namespace ts {
}
function checkGrammarMetaProperty(node: MetaProperty) {
if (node.keywordToken === SyntaxKind.NewKeyword) {
if (node.name.escapedText !== "target") {
return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, node.name.escapedText, tokenToString(node.keywordToken), "target");
}
const escapedText = node.name.escapedText;
switch (node.keywordToken) {
case SyntaxKind.NewKeyword:
if (escapedText !== "target") {
return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, node.name.escapedText, tokenToString(node.keywordToken), "target");
}
break;
case SyntaxKind.ImportKeyword:
if (escapedText !== "meta") {
return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, node.name.escapedText, tokenToString(node.keywordToken), "meta");
}
break;
}
}
@@ -27911,7 +28079,7 @@ namespace ts {
}
function checkGrammarImportCallExpression(node: ImportCall): boolean {
if (modulekind === ModuleKind.ES2015) {
if (moduleKind === ModuleKind.ES2015) {
return grammarErrorOnNode(node, Diagnostics.Dynamic_import_cannot_be_used_when_targeting_ECMAScript_2015_modules);
}
+1
View File
@@ -145,6 +145,7 @@ namespace ts {
"es2017.string": "lib.es2017.string.d.ts",
"es2017.intl": "lib.es2017.intl.d.ts",
"es2017.typedarrays": "lib.es2017.typedarrays.d.ts",
"es2018.intl": "lib.es2018.intl.d.ts",
"es2018.promise": "lib.es2018.promise.d.ts",
"es2018.regexp": "lib.es2018.regexp.d.ts",
"esnext.array": "lib.esnext.array.d.ts",
+6 -2
View File
@@ -1762,6 +1762,10 @@ namespace ts {
return compareComparableValues(a, b);
}
export function getStringComparer(ignoreCase?: boolean) {
return ignoreCase ? compareStringsCaseInsensitive : compareStringsCaseSensitive;
}
/**
* Creates a string comparer for use with string collation in the UI.
*/
@@ -2459,7 +2463,7 @@ namespace ts {
else if (typeof currentDirectory === "boolean") {
ignoreCase = currentDirectory;
}
return comparePathsWorker(a, b, ignoreCase ? compareStringsCaseInsensitive : compareStringsCaseSensitive);
return comparePathsWorker(a, b, getStringComparer(ignoreCase));
}
export function containsPath(parent: string, child: string, ignoreCase?: boolean): boolean;
@@ -2799,7 +2803,7 @@ namespace ts {
}
// Sort the offsets array using either the literal or canonical path representations.
includeBasePaths.sort(useCaseSensitiveFileNames ? compareStringsCaseSensitive : compareStringsCaseInsensitive);
includeBasePaths.sort(getStringComparer(!useCaseSensitiveFileNames));
// Iterate over each include base path and include unique base paths that are not a
// subpath of an existing base path
+16
View File
@@ -971,6 +971,10 @@
"category": "Error",
"code": 1342
},
"The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.": {
"category": "Error",
"code": 1343
},
"Duplicate identifier '{0}'.": {
"category": "Error",
@@ -3898,6 +3902,10 @@
"category": "Suggestion",
"code": 80004
},
"'require' call may be converted to an import.": {
"category": "Suggestion",
"code": 80005
},
"Add missing 'super()' call": {
"category": "Message",
@@ -4174,5 +4182,13 @@
"Generate 'get' and 'set' accessors": {
"category": "Message",
"code": 95046
},
"Convert 'require' to 'import'": {
"category": "Message",
"code": 95047
},
"Convert all 'require' to 'import'": {
"category": "Message",
"code": 95048
}
}
+72 -20
View File
@@ -540,7 +540,7 @@ namespace ts {
const newSourceFile = IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks);
// Because new source file node is created, it may not have the flag PossiblyContainDynamicImport. This is the case if there is no new edit to add dynamic import.
// We will manually port the flag to the new source file.
newSourceFile.flags |= (sourceFile.flags & NodeFlags.PossiblyContainsDynamicImport);
newSourceFile.flags |= (sourceFile.flags & NodeFlags.PermanentlySetIncrementalFlags);
return newSourceFile;
}
@@ -2625,6 +2625,20 @@ namespace ts {
return token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken;
}
function nextTokenIsDot() {
return nextToken() === SyntaxKind.DotToken;
}
function nextTokenIsOpenParenOrLessThanOrDot() {
switch (nextToken()) {
case SyntaxKind.OpenParenToken:
case SyntaxKind.LessThanToken:
case SyntaxKind.DotToken:
return true;
}
return false;
}
function parseTypeLiteral(): TypeLiteralNode {
const node = <TypeLiteralNode>createNode(SyntaxKind.TypeLiteral);
node.members = parseObjectTypeMembers();
@@ -3093,7 +3107,7 @@ namespace ts {
case SyntaxKind.Identifier:
return true;
case SyntaxKind.ImportKeyword:
return lookAhead(nextTokenIsOpenParenOrLessThan);
return lookAhead(nextTokenIsOpenParenOrLessThanOrDot);
default:
return isIdentifier();
}
@@ -3955,14 +3969,31 @@ namespace ts {
// 3)we have a MemberExpression which either completes the LeftHandSideExpression,
// or starts the beginning of the first four CallExpression productions.
let expression: MemberExpression;
if (token() === SyntaxKind.ImportKeyword && lookAhead(nextTokenIsOpenParenOrLessThan)) {
// We don't want to eagerly consume all import keyword as import call expression so we look a head to find "("
// For example:
// var foo3 = require("subfolder
// import * as foo1 from "module-from-node
// We want this import to be a statement rather than import call expression
sourceFile.flags |= NodeFlags.PossiblyContainsDynamicImport;
expression = parseTokenNode<PrimaryExpression>();
if (token() === SyntaxKind.ImportKeyword) {
if (lookAhead(nextTokenIsOpenParenOrLessThan)) {
// We don't want to eagerly consume all import keyword as import call expression so we look ahead to find "("
// For example:
// var foo3 = require("subfolder
// import * as foo1 from "module-from-node
// We want this import to be a statement rather than import call expression
sourceFile.flags |= NodeFlags.PossiblyContainsDynamicImport;
expression = parseTokenNode<PrimaryExpression>();
}
else if (lookAhead(nextTokenIsDot)) {
// This is an 'import.*' metaproperty (i.e. 'import.meta')
const fullStart = scanner.getStartPos();
nextToken(); // advance past the 'import'
nextToken(); // advance past the dot
const node = createNode(SyntaxKind.MetaProperty, fullStart) as MetaProperty;
node.keywordToken = SyntaxKind.ImportKeyword;
node.name = parseIdentifierName();
expression = finishNode(node);
sourceFile.flags |= NodeFlags.PossiblyContainsImportMeta;
}
else {
expression = parseMemberExpressionOrHigher();
}
}
else {
expression = token() === SyntaxKind.SuperKeyword ? parseSuperExpression() : parseMemberExpressionOrHigher();
@@ -4523,7 +4554,7 @@ namespace ts {
case SyntaxKind.FunctionKeyword:
return parseFunctionExpression();
case SyntaxKind.NewKeyword:
return parseNewExpression();
return parseNewExpressionOrNewDotTarget();
case SyntaxKind.SlashToken:
case SyntaxKind.SlashEqualsToken:
if (reScanSlashToken() === SyntaxKind.RegularExpressionLiteral) {
@@ -4674,7 +4705,7 @@ namespace ts {
return isIdentifier() ? parseIdentifier() : undefined;
}
function parseNewExpression(): NewExpression | MetaProperty {
function parseNewExpressionOrNewDotTarget(): NewExpression | MetaProperty {
const fullStart = scanner.getStartPos();
parseExpected(SyntaxKind.NewKeyword);
if (parseOptional(SyntaxKind.DotToken)) {
@@ -5122,7 +5153,7 @@ namespace ts {
return true;
case SyntaxKind.ImportKeyword:
return isStartOfDeclaration() || lookAhead(nextTokenIsOpenParenOrLessThan);
return isStartOfDeclaration() || lookAhead(nextTokenIsOpenParenOrLessThanOrDot);
case SyntaxKind.ConstKeyword:
case SyntaxKind.ExportKeyword:
@@ -6108,14 +6139,35 @@ namespace ts {
}
function setExternalModuleIndicator(sourceFile: SourceFile) {
sourceFile.externalModuleIndicator = forEach(sourceFile.statements, node =>
hasModifier(node, ModifierFlags.Export)
|| node.kind === SyntaxKind.ImportEqualsDeclaration && (<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference
|| node.kind === SyntaxKind.ImportDeclaration
|| node.kind === SyntaxKind.ExportAssignment
|| node.kind === SyntaxKind.ExportDeclaration
// Try to use the first top-level import/export when available, then
// fall back to looking for an 'import.meta' somewhere in the tree if necessary.
sourceFile.externalModuleIndicator =
forEach(sourceFile.statements, isAnExternalModuleIndicatorNode) ||
getImportMetaIfNecessary(sourceFile);
}
function isAnExternalModuleIndicatorNode(node: Node) {
return hasModifier(node, ModifierFlags.Export)
|| node.kind === SyntaxKind.ImportEqualsDeclaration && (<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference
|| node.kind === SyntaxKind.ImportDeclaration
|| node.kind === SyntaxKind.ExportAssignment
|| node.kind === SyntaxKind.ExportDeclaration
? node
: undefined);
: undefined;
}
function getImportMetaIfNecessary(sourceFile: SourceFile) {
return sourceFile.flags & NodeFlags.PossiblyContainsImportMeta ?
walkTreeForExternalModuleIndicators(sourceFile) :
undefined;
}
function walkTreeForExternalModuleIndicators(node: Node): Node {
return isImportMeta(node) ? node : forEachChild(node, walkTreeForExternalModuleIndicators);
}
function isImportMeta(node: Node): boolean {
return isMetaProperty(node) && node.keywordToken === SyntaxKind.ImportKeyword && node.name.escapedText === "meta";
}
const enum ParsingContext {
+5 -1
View File
@@ -986,7 +986,7 @@ namespace ts {
// moduleAugmentations has changed
oldProgram.structureIsReused = StructureIsReused.SafeModules;
}
if ((oldSourceFile.flags & NodeFlags.PossiblyContainsDynamicImport) !== (newSourceFile.flags & NodeFlags.PossiblyContainsDynamicImport)) {
if ((oldSourceFile.flags & NodeFlags.PermanentlySetIncrementalFlags) !== (newSourceFile.flags & NodeFlags.PermanentlySetIncrementalFlags)) {
// dynamicImport has changed
oldProgram.structureIsReused = StructureIsReused.SafeModules;
}
@@ -2062,6 +2062,10 @@ namespace ts {
}
function verifyCompilerOptions() {
if (options.strictPropertyInitialization && !options.strictNullChecks) {
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "strictPropertyInitialization", "strictNullChecks");
}
if (options.isolatedModules) {
if (options.declaration) {
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "declaration", "isolatedModules");
+1 -1
View File
@@ -698,7 +698,7 @@ namespace ts {
createWatchDirectoryUsing(dynamicPollingWatchFile || createDynamicPriorityPollingWatchFile({ getModifiedTime, setTimeout })) :
watchDirectoryUsingFsWatch;
const watchDirectoryRecursively = createRecursiveDirectoryWatcher({
filePathComparer: useCaseSensitiveFileNames ? compareStringsCaseSensitive : compareStringsCaseInsensitive,
filePathComparer: getStringComparer(!useCaseSensitiveFileNames),
directoryExists,
getAccessibleSortedChildDirectories: path => getAccessibleFileSystemEntries(path).directories,
watchDirectory,
+1 -1
View File
@@ -46,7 +46,7 @@ namespace ts {
value = node.right;
}
else {
return value;
return visitNode(value, visitor, isExpression);
}
}
}
+6 -3
View File
@@ -154,9 +154,12 @@ namespace ts {
function updateWatchCompilationHost(watchCompilerHost: WatchCompilerHost<EmitAndSemanticDiagnosticsBuilderProgram>) {
const compileUsingBuilder = watchCompilerHost.createProgram;
watchCompilerHost.createProgram = (rootNames, options, host, oldProgram) => {
enableStatistics(options);
return compileUsingBuilder(rootNames, options, host, oldProgram);
watchCompilerHost.createProgram = (rootNames, options, host, oldProgram, configFileParsingDiagnostics) => {
Debug.assert(rootNames !== undefined || (options === undefined && !!oldProgram));
if (options !== undefined) {
enableStatistics(options);
}
return compileUsingBuilder(rootNames, options, host, oldProgram, configFileParsingDiagnostics);
};
const emitFilesUsingBuilder = watchCompilerHost.afterProgramCreate;
watchCompilerHost.afterProgramCreate = builderProgram => {
+34 -12
View File
@@ -490,19 +490,21 @@ namespace ts {
ThisNodeOrAnySubNodesHasError = 1 << 17, // If this node or any of its children had an error
HasAggregatedChildData = 1 << 18, // If we've computed data from children and cached it in this node
// This flag will be set when the parser encounters a dynamic import expression so that module resolution
// will not have to walk the tree if the flag is not set. However, this flag is just a approximation because
// once it is set, the flag never gets cleared (hence why it's named "PossiblyContainsDynamicImport").
// During editing, if dynamic import is removed, incremental parsing will *NOT* update this flag. This means that the tree will always be traversed
// during module resolution. However, the removal operation should not occur often and in the case of the
// These flags will be set when the parser encounters a dynamic import expression or 'import.meta' to avoid
// walking the tree if the flags are not set. However, these flags are just a approximation
// (hence why it's named "PossiblyContainsDynamicImport") because once set, the flags never get cleared.
// During editing, if a dynamic import is removed, incremental parsing will *NOT* clear this flag.
// This means that the tree will always be traversed during module resolution, or when looking for external module indicators.
// However, the removal operation should not occur often and in the case of the
// removal, it is likely that users will add the import anyway.
// The advantage of this approach is its simplicity. For the case of batch compilation,
// we guarantee that users won't have to pay the price of walking the tree if a dynamic import isn't used.
/* @internal */
PossiblyContainsDynamicImport = 1 << 19,
JSDoc = 1 << 20, // If node was parsed inside jsdoc
/* @internal */ Ambient = 1 << 21, // If node was inside an ambient context -- a declaration file, or inside something with the `declare` modifier.
/* @internal */ InWithStatement = 1 << 22, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`)
/* @internal */ PossiblyContainsDynamicImport = 1 << 19,
/* @internal */ PossiblyContainsImportMeta = 1 << 20,
JSDoc = 1 << 21, // If node was parsed inside jsdoc
/* @internal */ Ambient = 1 << 22, // If node was inside an ambient context -- a declaration file, or inside something with the `declare` modifier.
/* @internal */ InWithStatement = 1 << 23, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`)
BlockScoped = Let | Const,
@@ -514,6 +516,11 @@ namespace ts {
// Exclude these flags when parsing a Type
TypeExcludesFlags = YieldContext | AwaitContext,
// Represents all flags that are potentially set once and
// never cleared on SourceFiles which get re-used in between incremental parses.
// See the comment above on `PossiblyContainsDynamicImport` and `PossiblyContainsImportMeta`.
/* @internal */ PermanentlySetIncrementalFlags = PossiblyContainsDynamicImport | PossiblyContainsImportMeta,
}
export const enum ModifierFlags {
@@ -1756,7 +1763,7 @@ namespace ts {
// for the same reasons we treat NewExpression as a PrimaryExpression.
export interface MetaProperty extends PrimaryExpression {
kind: SyntaxKind.MetaProperty;
keywordToken: SyntaxKind.NewKeyword;
keywordToken: SyntaxKind.NewKeyword | SyntaxKind.ImportKeyword;
name: Identifier;
}
@@ -2557,7 +2564,11 @@ namespace ts {
languageVersion: ScriptTarget;
/* @internal */ scriptKind: ScriptKind;
// The first node that causes this file to be an external module
/**
* The first "most obvious" node that makes a file an external module.
* This is intended to be the first top-level import/export,
* but could be arbitrarily nested (e.g. `import.meta`).
*/
/* @internal */ externalModuleIndicator: Node;
// The first node that causes this file to be a CommonJS module
/* @internal */ commonJsModuleIndicator: Node;
@@ -3620,6 +3631,9 @@ namespace ts {
BooleanLike = Boolean | BooleanLiteral,
EnumLike = Enum | EnumLiteral,
ESSymbolLike = ESSymbol | UniqueESSymbol,
VoidLike = Void | Undefined,
/* @internal */
DisjointDomains = NonPrimitive | StringLike | NumberLike | BooleanLike | ESSymbolLike | VoidLike | Null,
UnionOrIntersection = Union | Intersection,
StructuredType = Object | Union | Intersection,
TypeVariable = TypeParameter | IndexedAccess,
@@ -3636,7 +3650,15 @@ namespace ts {
RequiresWidening = ContainsWideningType | ContainsObjectLiteral,
/* @internal */
PropagatingFlags = ContainsWideningType | ContainsObjectLiteral | ContainsAnyFunctionType,
// The following flags are used for different purposes during union and intersection type construction
/* @internal */
NonWideningType = ContainsWideningType,
/* @internal */
Wildcard = ContainsObjectLiteral,
/* @internal */
EmptyObject = ContainsAnyFunctionType,
/* @internal */
ConstructionFlags = NonWideningType | Wildcard | EmptyObject
}
export type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression;
+23 -19
View File
@@ -531,13 +531,13 @@ namespace ts {
const watchLogLevel = trace ? compilerOptions.extendedDiagnostics ? WatchLogLevel.Verbose :
compilerOptions.diagnostis ? WatchLogLevel.TriggerOnly : WatchLogLevel.None : WatchLogLevel.None;
const writeLog: (s: string) => void = watchLogLevel !== WatchLogLevel.None ? trace : noop;
const { watchFile, watchFilePath, watchDirectory: watchDirectoryWorker } = getWatchFactory(watchLogLevel, writeLog);
const { watchFile, watchFilePath, watchDirectory } = getWatchFactory<string>(watchLogLevel, writeLog);
const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
writeLog(`Current directory: ${currentDirectory} CaseSensitiveFileNames: ${useCaseSensitiveFileNames}`);
if (configFileName) {
watchFile(host, configFileName, scheduleProgramReload, PollingInterval.High);
watchFile(host, configFileName, scheduleProgramReload, PollingInterval.High, "Config file");
}
const compilerHost: CompilerHost & ResolutionCacheHost = {
@@ -563,8 +563,8 @@ namespace ts {
// Members for ResolutionCacheHost
toPath,
getCompilationSettings: () => compilerOptions,
watchDirectoryOfFailedLookupLocation: watchDirectory,
watchTypeRootsDirectory: watchDirectory,
watchDirectoryOfFailedLookupLocation: (dir, cb, flags) => watchDirectory(host, dir, cb, flags, "Failed Lookup Locations"),
watchTypeRootsDirectory: (dir, cb, flags) => watchDirectory(host, dir, cb, flags, "Type roots"),
getCachedDirectoryStructureHost: () => cachedDirectoryStructureHost,
onInvalidatedResolution: scheduleProgramUpdate,
onChangedAutomaticTypeDirectiveNames: () => {
@@ -625,9 +625,19 @@ namespace ts {
builderProgram = createProgram(/*rootNames*/ undefined, /*options*/ undefined, compilerHost, builderProgram, configFileParsingDiagnostics);
hasChangedConfigFileParsingErrors = false;
}
return builderProgram;
}
else {
createNewProgram(program, hasInvalidatedResolution);
}
if (host.afterProgramCreate) {
host.afterProgramCreate(builderProgram);
}
return builderProgram;
}
function createNewProgram(program: Program, hasInvalidatedResolution: HasInvalidatedResolution) {
// Compile the program
if (watchLogLevel !== WatchLogLevel.None) {
writeLog("CreatingProgramWith::");
@@ -663,12 +673,6 @@ namespace ts {
}
missingFilePathsRequestedForRelease = undefined;
}
if (host.afterProgramCreate) {
host.afterProgramCreate(builderProgram);
}
return builderProgram;
}
function updateRootFileNames(files: string[]) {
@@ -724,7 +728,7 @@ namespace ts {
(hostSourceFile as FilePresentOnHost).sourceFile = sourceFile;
sourceFile.version = hostSourceFile.version.toString();
if (!(hostSourceFile as FilePresentOnHost).fileWatcher) {
(hostSourceFile as FilePresentOnHost).fileWatcher = watchFilePath(host, fileName, onSourceFileChange, PollingInterval.Low, path);
(hostSourceFile as FilePresentOnHost).fileWatcher = watchFilePath(host, fileName, onSourceFileChange, PollingInterval.Low, path, "Source file");
}
}
else {
@@ -738,7 +742,7 @@ namespace ts {
else {
if (sourceFile) {
sourceFile.version = initialVersion.toString();
const fileWatcher = watchFilePath(host, fileName, onSourceFileChange, PollingInterval.Low, path);
const fileWatcher = watchFilePath(host, fileName, onSourceFileChange, PollingInterval.Low, path, "Source file");
sourceFilesCache.set(path, { sourceFile, version: initialVersion, fileWatcher });
}
else {
@@ -823,6 +827,7 @@ namespace ts {
if (timerToUpdateProgram) {
host.clearTimeout(timerToUpdateProgram);
}
writeLog("Scheduling update");
timerToUpdateProgram = host.setTimeout(updateProgram, 250);
}
@@ -848,6 +853,7 @@ namespace ts {
}
function reloadFileNamesFromConfigFile() {
writeLog("Reloading new file names and options");
const result = getFileNamesFromConfigSpecs(configFileSpecs, getDirectoryPath(configFileName), compilerOptions, parseConfigFileHost);
if (result.fileNames.length) {
configFileParsingDiagnostics = filter(configFileParsingDiagnostics, error => !isErrorNoInputFiles(error));
@@ -909,12 +915,8 @@ namespace ts {
}
}
function watchDirectory(directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags) {
return watchDirectoryWorker(host, directory, cb, flags);
}
function watchMissingFilePath(missingFilePath: Path) {
return watchFilePath(host, missingFilePath, onMissingFileChange, PollingInterval.Medium, missingFilePath);
return watchFilePath(host, missingFilePath, onMissingFileChange, PollingInterval.Medium, missingFilePath, "Missing file");
}
function onMissingFileChange(fileName: string, eventKind: FileWatcherEventKind, missingFilePath: Path) {
@@ -947,6 +949,7 @@ namespace ts {
function watchWildcardDirectory(directory: string, flags: WatchDirectoryFlags) {
return watchDirectory(
host,
directory,
fileOrDirectory => {
Debug.assert(!!configFileName);
@@ -974,7 +977,8 @@ namespace ts {
scheduleProgramUpdate();
}
},
flags
flags,
"Wild card directories"
);
}
+4 -4
View File
@@ -353,11 +353,11 @@ namespace ts {
watchDirectory: WatchDirectory<X, Y>;
}
export function getWatchFactory<X = undefined, Y = undefined>(watchLogLevel: WatchLogLevel, log: (s: string) => void, getDetailWatchInfo?: GetDetailWatchInfo<X, Y>): WatchFactory<X, Y> {
export function getWatchFactory<X, Y = undefined>(watchLogLevel: WatchLogLevel, log: (s: string) => void, getDetailWatchInfo?: GetDetailWatchInfo<X, Y>): WatchFactory<X, Y> {
return getWatchFactoryWith(watchLogLevel, log, getDetailWatchInfo, watchFile, watchDirectory);
}
function getWatchFactoryWith<X = undefined, Y = undefined>(watchLogLevel: WatchLogLevel, log: (s: string) => void, getDetailWatchInfo: GetDetailWatchInfo<X, Y> | undefined,
function getWatchFactoryWith<X, Y = undefined>(watchLogLevel: WatchLogLevel, log: (s: string) => void, getDetailWatchInfo: GetDetailWatchInfo<X, Y> | undefined,
watchFile: (host: WatchFileHost, file: string, callback: FileWatcherCallback, watchPriority: PollingInterval) => FileWatcher,
watchDirectory: (host: WatchDirectoryHost, directory: string, callback: DirectoryWatcherCallback, flags: WatchDirectoryFlags) => FileWatcher): WatchFactory<X, Y> {
const createFileWatcher: CreateFileWatcher<WatchFileHost, PollingInterval, FileWatcherEventKind, undefined, X, Y> = getCreateFileWatcher(watchLogLevel, watchFile);
@@ -423,8 +423,8 @@ namespace ts {
}, flags);
}
function getWatchInfo<T, X, Y>(file: string, flags: T, detailInfo1: X | undefined, detailInfo2: Y | undefined, getDetailWatchInfo: GetDetailWatchInfo<X, Y> | undefined) {
return `WatchInfo: ${file} ${flags} ${getDetailWatchInfo ? getDetailWatchInfo(detailInfo1, detailInfo2) : ""}`;
function getWatchInfo<T, X, Y>(file: string, flags: T, detailInfo1: X, detailInfo2: Y | undefined, getDetailWatchInfo: GetDetailWatchInfo<X, Y> | undefined) {
return `WatchInfo: ${file} ${flags} ${getDetailWatchInfo ? getDetailWatchInfo(detailInfo1, detailInfo2) : detailInfo1}`;
}
export function closeFileWatcherOf<T extends { watcher: FileWatcher; }>(objWithWatcher: T) {
+154 -50
View File
@@ -23,6 +23,8 @@
namespace FourSlash {
ts.disableIncrementalParsing = false;
import Many = FourSlashInterface.Many;
// Represents a parsed source file with metadata
interface FourSlashFile {
// The contents of the file (with markers, etc stripped out)
@@ -331,8 +333,10 @@ namespace FourSlash {
this.languageServiceAdapterHost.addScript(fileName, file, /*isRootFile*/ true);
}
});
this.languageServiceAdapterHost.addScript(Harness.Compiler.defaultLibFileName,
Harness.Compiler.getDefaultLibrarySourceFile().text, /*isRootFile*/ false);
if (!compilationOptions.noLib) {
this.languageServiceAdapterHost.addScript(Harness.Compiler.defaultLibFileName,
Harness.Compiler.getDefaultLibrarySourceFile().text, /*isRootFile*/ false);
}
}
for (const file of testData.files) {
@@ -623,11 +627,11 @@ namespace FourSlash {
}
}
public verifyGoToDefinitionIs(endMarker: string | string[]) {
public verifyGoToDefinitionIs(endMarker: Many<string>) {
this.verifyGoToXWorker(toArray(endMarker), () => this.getGoToDefinition());
}
public verifyGoToDefinition(arg0: any, endMarkerNames?: string | string[]) {
public verifyGoToDefinition(arg0: any, endMarkerNames?: Many<string>) {
this.verifyGoToX(arg0, endMarkerNames, () => this.getGoToDefinitionAndBoundSpan());
}
@@ -639,23 +643,23 @@ namespace FourSlash {
return this.languageService.getDefinitionAndBoundSpan(this.activeFile.fileName, this.currentCaretPosition);
}
public verifyGoToType(arg0: any, endMarkerNames?: string | string[]) {
public verifyGoToType(arg0: any, endMarkerNames?: Many<string>) {
this.verifyGoToX(arg0, endMarkerNames, () =>
this.languageService.getTypeDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition));
}
private verifyGoToX(arg0: any, endMarkerNames: string | string[] | undefined, getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) {
private verifyGoToX(arg0: any, endMarkerNames: Many<string> | undefined, getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) {
if (endMarkerNames) {
this.verifyGoToXPlain(arg0, endMarkerNames, getDefs);
}
else if (ts.isArray(arg0)) {
const pairs = arg0 as ReadonlyArray<[string | string[], string | string[]]>;
const pairs = arg0 as ReadonlyArray<[Many<string>, Many<string>]>;
for (const [start, end] of pairs) {
this.verifyGoToXPlain(start, end, getDefs);
}
}
else {
const obj: { [startMarkerName: string]: string | string[] } = arg0;
const obj: { [startMarkerName: string]: Many<string> } = arg0;
for (const startMarkerName in obj) {
if (ts.hasProperty(obj, startMarkerName)) {
this.verifyGoToXPlain(startMarkerName, obj[startMarkerName], getDefs);
@@ -664,7 +668,7 @@ namespace FourSlash {
}
}
private verifyGoToXPlain(startMarkerNames: string | string[], endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) {
private verifyGoToXPlain(startMarkerNames: Many<string>, endMarkerNames: Many<string>, getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) {
for (const start of toArray(startMarkerNames)) {
this.verifyGoToXSingle(start, endMarkerNames, getDefs);
}
@@ -676,17 +680,17 @@ namespace FourSlash {
}
}
private verifyGoToXSingle(startMarkerName: string, endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) {
private verifyGoToXSingle(startMarkerName: string, endMarkerNames: Many<string>, getDefs: () => ReadonlyArray<ts.DefinitionInfo> | ts.DefinitionInfoAndBoundSpan | undefined) {
this.goToMarker(startMarkerName);
this.verifyGoToXWorker(toArray(endMarkerNames), getDefs, startMarkerName);
}
private verifyGoToXWorker(endMarkers: string[], getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined, startMarkerName?: string) {
private verifyGoToXWorker(endMarkers: ReadonlyArray<string>, getDefs: () => ReadonlyArray<ts.DefinitionInfo> | ts.DefinitionInfoAndBoundSpan | undefined, startMarkerName?: string) {
const defs = getDefs();
let definitions: ts.DefinitionInfo[] | ReadonlyArray<ts.DefinitionInfo>;
let definitions: ReadonlyArray<ts.DefinitionInfo>;
let testName: string;
if (!defs || Array.isArray(defs)) {
if (!defs || ts.isArray(defs)) {
definitions = defs as ts.DefinitionInfo[] || [];
testName = "goToDefinitions";
}
@@ -838,48 +842,121 @@ namespace FourSlash {
}
}
public verifyCompletionsAt(markerName: string | ReadonlyArray<string>, expected: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntry>, options?: FourSlashInterface.CompletionsAtOptions) {
if (typeof markerName !== "string") {
for (const m of markerName) this.verifyCompletionsAt(m, expected, options);
return;
public verifyCompletions(options: FourSlashInterface.VerifyCompletionsOptions) {
if (options.at !== undefined) {
if (typeof options.at === "string") {
this.goToMarker(options.at);
}
else {
for (const a of options.at) this.verifyCompletions({ ...options, at: a });
return;
}
}
this.goToMarker(markerName);
const actualCompletions = this.getCompletionListAtCaret(options);
const actualCompletions = this.getCompletionListAtCaret({ ...options.preferences, triggerCharacter: options.triggerCharacter });
if (!actualCompletions) {
if (expected === undefined) return;
if (options.are === undefined) return;
this.raiseError(`No completions at position '${this.currentCaretPosition}'.`);
}
if (actualCompletions.isNewIdentifierLocation !== (options && options.isNewIdentifierLocation || false)) {
this.raiseError(`Expected 'isNewIdentifierLocation' to be ${options && options.isNewIdentifierLocation}, got ${actualCompletions.isNewIdentifierLocation}`);
if (actualCompletions.isNewIdentifierLocation !== (options.isNewIdentifierLocation || false)) {
this.raiseError(`Expected 'isNewIdentifierLocation' to be ${options.isNewIdentifierLocation || false}, got ${actualCompletions.isNewIdentifierLocation}`);
}
const actual = actualCompletions.entries;
const actualByName = ts.createMap<ts.CompletionEntry>();
for (const entry of actualCompletions.entries) {
if (actualByName.has(entry.name)) {
// TODO: GH#23587
if (entry.name !== "undefined" && entry.name !== "require") this.raiseError(`Duplicate completions for ${entry.name}`);
}
else {
actualByName.set(entry.name, entry);
}
}
if ("are" in options) {
if (options.are === undefined) this.raiseError("Expected no completions");
this.verifyCompletionsAreExactly(actualCompletions.entries, toArray(options.are));
}
else {
if (options.includes) {
for (const include of toArray(options.includes)) {
const name = typeof include === "string" ? include : include.name;
const found = actualByName.get(name);
if (!found) this.raiseError(`No completion ${name} found`);
this.verifyCompletionEntry(found, include);
}
}
else {
for (const exclude of toArray(options.excludes)) {
if (typeof exclude === "string") {
if (actualByName.has(exclude)) {
this.raiseError(`Did not expect to get a completion named ${exclude}`);
}
}
else {
const found = actualByName.get(exclude.name);
if (found.source === exclude.source) {
this.raiseError(`Did not expect to get a completion named ${exclude.name} with source ${exclude.source}`);
}
}
}
}
}
}
private verifyCompletionEntry(actual: ts.CompletionEntry, expected: FourSlashInterface.ExpectedCompletionEntry) {
const { insertText, replacementSpan, hasAction, kind, text, documentation, sourceDisplay } = typeof expected === "string"
? { insertText: undefined, replacementSpan: undefined, hasAction: undefined, kind: undefined, text: undefined, documentation: undefined, sourceDisplay: undefined }
: expected;
if (actual.insertText !== insertText) {
this.raiseError(`Expected completion insert text to be ${insertText}, got ${actual.insertText}`);
}
const convertedReplacementSpan = replacementSpan && ts.createTextSpanFromRange(replacementSpan);
try {
assert.deepEqual(actual.replacementSpan, convertedReplacementSpan);
}
catch {
this.raiseError(`Expected completion replacementSpan to be ${stringify(convertedReplacementSpan)}, got ${stringify(actual.replacementSpan)}`);
}
if (kind !== undefined) assert.equal(actual.kind, kind);
assert.equal(actual.hasAction, hasAction);
if (text) {
const actualDetails = this.getCompletionEntryDetails(actual.name, actual.source);
assert.equal(ts.displayPartsToString(actualDetails.displayParts), text);
assert.equal(ts.displayPartsToString(actualDetails.documentation), documentation || "");
// TODO: GH#23587
// assert.equal(actualDetails.kind, actual.kind);
assert.equal(actualDetails.kindModifiers, actual.kindModifiers);
assert.equal(actualDetails.source && ts.displayPartsToString(actualDetails.source), sourceDisplay);
}
else {
assert(documentation === undefined && sourceDisplay === undefined, "If specifying completion details, should specify 'text'");
}
}
private verifyCompletionsAreExactly(actual: ReadonlyArray<ts.CompletionEntry>, expected: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntry>) {
if (actual.length !== expected.length) {
this.raiseError(`Expected ${expected.length} completions, got ${actual.length} (${actual.map(a => a.name)}).`);
}
ts.zipWith(actual, expected, (completion, expectedCompletion, index) => {
const { name, insertText, replacementSpan } = typeof expectedCompletion === "string" ? { name: expectedCompletion, insertText: undefined, replacementSpan: undefined } : expectedCompletion;
const name = typeof expectedCompletion === "string" ? expectedCompletion : expectedCompletion.name;
if (completion.name !== name) {
this.raiseError(`Expected completion at index ${index} to be ${name}, got ${completion.name}`);
}
if (completion.insertText !== insertText) {
this.raiseError(`Expected completion insert text at index ${index} to be ${insertText}, got ${completion.insertText}`);
}
const convertedReplacementSpan = replacementSpan && ts.createTextSpanFromRange(replacementSpan);
try {
assert.deepEqual(completion.replacementSpan, convertedReplacementSpan);
}
catch {
this.raiseError(`Expected completion replacementSpan at index ${index} to be ${stringify(convertedReplacementSpan)}, got ${stringify(completion.replacementSpan)}`);
}
this.verifyCompletionEntry(completion, expectedCompletion);
});
}
public verifyCompletionsAt(markerName: string | ReadonlyArray<string>, expected: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntry>, options?: FourSlashInterface.CompletionsAtOptions) {
this.verifyCompletions({ at: markerName, are: expected, isNewIdentifierLocation: options && options.isNewIdentifierLocation, preferences: options, triggerCharacter: options && options.triggerCharacter });
}
public verifyCompletionListContains(entryId: ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string | { kind?: string, kindModifiers?: string }, spanIndex?: number, hasAction?: boolean, options?: FourSlashInterface.VerifyCompletionListContainsOptions) {
const completions = this.getCompletionListAtCaret(options);
if (completions) {
@@ -1113,7 +1190,7 @@ namespace FourSlash {
}
}
public verifyReferenceGroups(starts: string | string[] | Range | Range[], parts: FourSlashInterface.ReferenceGroup[] | undefined): void {
public verifyReferenceGroups(starts: Many<string> | Many<Range>, parts: ReadonlyArray<FourSlashInterface.ReferenceGroup> | undefined): void {
interface ReferenceGroupJson {
definition: string | { text: string, range: ts.TextSpan };
references: ts.ReferenceEntry[];
@@ -1251,7 +1328,7 @@ Actual: ${stringify(fullActual)}`);
this.raiseError(`verifyReferencesAtPositionListContains failed - could not find the item: ${stringify(missingItem)} in the returned list: (${stringify(references)})`);
}
private getCompletionListAtCaret(options?: FourSlashInterface.CompletionsAtOptions): ts.CompletionInfo {
private getCompletionListAtCaret(options?: ts.GetCompletionsAtPositionOptions): ts.CompletionInfo {
return this.languageService.getCompletionsAtPosition(this.activeFile.fileName, this.currentCaretPosition, options);
}
@@ -1348,7 +1425,7 @@ Actual: ${stringify(fullActual)}`);
}
}
public verifyRenameLocations(startRanges: Range | Range[], options: Range[] | { findInStrings?: boolean, findInComments?: boolean, ranges: Range[] }) {
public verifyRenameLocations(startRanges: Many<Range>, options: Range[] | { findInStrings?: boolean, findInComments?: boolean, ranges: Range[] }) {
let findInStrings: boolean, findInComments: boolean, ranges: Range[];
if (ts.isArray(options)) {
findInStrings = findInComments = false;
@@ -3738,7 +3815,7 @@ ${code}
return ts.arrayFrom(set.keys());
}
function toArray<T>(x: T | T[]): T[] {
function toArray<T>(x: Many<T>): ReadonlyArray<T> {
return ts.isArray(x) ? x : [x];
}
@@ -4026,10 +4103,16 @@ namespace FourSlashInterface {
super(state);
}
public completionsAt(markerName: string | ReadonlyArray<string>, completions: ReadonlyArray<ExpectedCompletionEntry>, options?: CompletionsAtOptions) {
public completionsAt(markerName: Many<string>, completions: ReadonlyArray<ExpectedCompletionEntry>, options?: CompletionsAtOptions) {
this.state.verifyCompletionsAt(markerName, completions, options);
}
public completions(...optionsArray: VerifyCompletionsOptions[]) {
for (const options of optionsArray) {
this.state.verifyCompletions(options);
}
}
public quickInfoIs(expectedText: string, expectedDocumentation?: string) {
this.state.verifyQuickInfoString(expectedText, expectedDocumentation);
}
@@ -4075,19 +4158,19 @@ namespace FourSlashInterface {
this.state.verifyCurrentFileContent(text);
}
public goToDefinitionIs(endMarkers: string | string[]) {
public goToDefinitionIs(endMarkers: Many<string>) {
this.state.verifyGoToDefinitionIs(endMarkers);
}
public goToDefinition(startMarkerName: string | string[], endMarkerName: string | string[], range?: FourSlash.Range): void;
public goToDefinition(startsAndEnds: [string | string[], string | string[]][] | { [startMarkerName: string]: string | string[] }): void;
public goToDefinition(arg0: any, endMarkerName?: string | string[]) {
public goToDefinition(startMarkerName: Many<string>, endMarkerName: Many<string>, range?: FourSlash.Range): void;
public goToDefinition(startsAndEnds: [Many<string>, Many<string>][] | { [startMarkerName: string]: Many<string> }): void;
public goToDefinition(arg0: any, endMarkerName?: Many<string>) {
this.state.verifyGoToDefinition(arg0, endMarkerName);
}
public goToType(startMarkerName: string | string[], endMarkerName: string | string[]): void;
public goToType(startsAndEnds: [string | string[], string | string[]][] | { [startMarkerName: string]: string | string[] }): void;
public goToType(arg0: any, endMarkerName?: string | string[]) {
public goToType(startMarkerName: Many<string>, endMarkerName: Many<string>): void;
public goToType(startsAndEnds: [Many<string>, Many<string>][] | { [startMarkerName: string]: Many<string> }): void;
public goToType(arg0: any, endMarkerName?: Many<string>) {
this.state.verifyGoToType(arg0, endMarkerName);
}
@@ -4119,7 +4202,7 @@ namespace FourSlashInterface {
this.state.verifyReferencesOf(start, references);
}
public referenceGroups(starts: string | string[] | FourSlash.Range | FourSlash.Range[], parts: ReferenceGroup[]) {
public referenceGroups(starts: Many<string> | Many<FourSlash.Range>, parts: ReferenceGroup[]) {
this.state.verifyReferenceGroups(starts, parts);
}
@@ -4351,7 +4434,7 @@ namespace FourSlashInterface {
this.state.verifyRenameInfoFailed(message);
}
public renameLocations(startRanges: FourSlash.Range | FourSlash.Range[], options: FourSlash.Range[] | { findInStrings?: boolean, findInComments?: boolean, ranges: FourSlash.Range[] }) {
public renameLocations(startRanges: Many<FourSlash.Range>, options: FourSlash.Range[] | { findInStrings?: boolean, findInComments?: boolean, ranges: FourSlash.Range[] }) {
this.state.verifyRenameLocations(startRanges, options);
}
@@ -4664,12 +4747,33 @@ namespace FourSlashInterface {
newContent: string;
}
export type ExpectedCompletionEntry = string | { name: string, insertText?: string, replacementSpan?: FourSlash.Range };
export type ExpectedCompletionEntry = string | {
readonly name: string,
readonly insertText?: string,
readonly replacementSpan?: FourSlash.Range,
readonly hasAction?: boolean, // If not specified, will assert that this is false.
readonly kind?: string, // If not specified, won't assert about this
readonly text: string;
readonly documentation: string;
readonly sourceDisplay?: string;
};
export interface CompletionsAtOptions extends Partial<ts.UserPreferences> {
triggerCharacter?: string;
isNewIdentifierLocation?: boolean;
}
export interface VerifyCompletionsOptions {
readonly at?: Many<string>;
readonly isNewIdentifierLocation?: boolean;
readonly are?: Many<ExpectedCompletionEntry>;
readonly includes?: Many<ExpectedCompletionEntry>;
readonly excludes?: Many<string | { readonly name: string, readonly source: string }>;
readonly preferences: ts.UserPreferences;
readonly triggerCharacter?: string;
}
export type Many<T> = T | ReadonlyArray<T>;
export interface VerifyCompletionListContainsOptions extends ts.UserPreferences {
triggerCharacter?: string;
sourceDisplay: string;
+1 -1
View File
@@ -220,7 +220,7 @@ namespace Utils {
for (const childName in node) {
if (childName === "parent" || childName === "nextContainer" || childName === "modifiers" || childName === "externalModuleIndicator" ||
// for now ignore jsdoc comments
childName === "jsDocComment" || childName === "checkJsDirective") {
childName === "jsDocComment" || childName === "checkJsDirective" || childName === "commonJsModuleIndicator") {
continue;
}
const child = (<any>node)[childName];
+1
View File
@@ -112,6 +112,7 @@
"../services/codefixes/inferFromUsage.ts",
"../services/codefixes/fixInvalidImportSyntax.ts",
"../services/codefixes/fixStrictClassInitialization.ts",
"../services/codefixes/requireInTs.ts",
"../services/codefixes/useDefaultImport.ts",
"../services/refactors/extractSymbol.ts",
"../services/refactors/generateGetAccessorAndSetAccessor.ts",
+3 -3
View File
@@ -60,7 +60,7 @@ namespace ts {
assertParseResult(["--lib", "es5,invalidOption", "0.ts"],
{
errors: [{
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.asynciterable'.",
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.asynciterable'.",
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
file: undefined,
@@ -262,7 +262,7 @@ namespace ts {
assertParseResult(["--lib", "es5,", "es7", "0.ts"],
{
errors: [{
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.asynciterable'.",
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.asynciterable'.",
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
file: undefined,
@@ -281,7 +281,7 @@ namespace ts {
assertParseResult(["--lib", "es5, ", "es7", "0.ts"],
{
errors: [{
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.asynciterable'.",
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.asynciterable'.",
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
file: undefined,
@@ -268,7 +268,7 @@ namespace ts {
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.asynciterable'.",
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.asynciterable'.",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
@@ -299,7 +299,7 @@ namespace ts {
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.asynciterable'.",
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.asynciterable'.",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
@@ -330,7 +330,7 @@ namespace ts {
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.asynciterable'.",
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.asynciterable'.",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
@@ -361,7 +361,7 @@ namespace ts {
file: undefined,
start: 0,
length: 0,
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.asynciterable'.",
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.asynciterable'.",
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
}]
+27 -4
View File
@@ -418,6 +418,28 @@ namespace ts.tscWatch {
checkProgramRootFiles(watch(), [commonFile1.path]);
});
it("works correctly when config file is changed but its content havent", () => {
const configFile: FileOrFolder = {
path: "/a/b/tsconfig.json",
content: `{
"compilerOptions": {},
"files": ["${commonFile1.path}", "${commonFile2.path}"]
}`
};
const files = [libFile, commonFile1, commonFile2, configFile];
const host = createWatchedSystem(files);
const watch = createWatchOfConfigFile(configFile.path, host);
checkProgramActualFiles(watch(), [libFile.path, commonFile1.path, commonFile2.path]);
checkOutputErrorsInitial(host, emptyArray);
host.modifyFile(configFile.path, configFile.content);
host.checkTimeoutQueueLengthAndRun(1); // reload the configured project
checkProgramActualFiles(watch(), [libFile.path, commonFile1.path, commonFile2.path]);
checkOutputErrorsIncremental(host, emptyArray);
});
it("files explicitly excluded in config file", () => {
const configFile: FileOrFolder = {
path: "/a/b/tsconfig.json",
@@ -2235,16 +2257,17 @@ declare module "fs" {
"CreatingProgramWith::\n",
" roots: [\"f.ts\"]\n",
" options: {\"extendedDiagnostics\":true}\n",
"FileWatcher:: Added:: WatchInfo: f.ts 250 \n",
"FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 250 \n"
"FileWatcher:: Added:: WatchInfo: f.ts 250 Source file\n",
"FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 250 Source file\n"
]);
file.content = "//";
host.reloadFS(files);
host.runQueuedTimeoutCallbacks();
checkOutputErrorsIncremental(host, emptyArray, disableConsoleClear, options.extendedDiagnostics && [
"FileWatcher:: Triggered with /f.ts1:: WatchInfo: f.ts 250 \n",
"Elapsed:: 0ms FileWatcher:: Triggered with /f.ts1:: WatchInfo: f.ts 250 \n"
"FileWatcher:: Triggered with /f.ts1:: WatchInfo: f.ts 250 Source file\n",
"Scheduling update\n",
"Elapsed:: 0ms FileWatcher:: Triggered with /f.ts1:: WatchInfo: f.ts 250 Source file\n"
], options.extendedDiagnostics && [
"Synchronizing program\n",
"CreatingProgramWith::\n",
+129 -42
View File
@@ -678,7 +678,10 @@ namespace ts.projectSystem {
projectService.openClientFile(commonFile1.path);
projectService.openClientFile(commonFile2.path);
checkNumberOfInferredProjects(projectService, 2);
projectService.checkNumberOfProjects({ inferredProjects: 2 });
checkProjectActualFiles(projectService.inferredProjects[0], [commonFile1.path, libFile.path]);
checkProjectActualFiles(projectService.inferredProjects[1], [commonFile2.path, libFile.path]);
const configFileLocations = ["/", "/a/", "/a/b/"];
const watchedFiles = flatMap(configFileLocations, location => [location + "tsconfig.json", location + "jsconfig.json"]).concat(libFile.path);
checkWatchedFiles(host, watchedFiles);
@@ -686,18 +689,26 @@ namespace ts.projectSystem {
// Add a tsconfig file
host.reloadFS(filesWithConfig);
host.checkTimeoutQueueLengthAndRun(1);
checkNumberOfInferredProjects(projectService, 1);
checkNumberOfConfiguredProjects(projectService, 1);
projectService.checkNumberOfProjects({ inferredProjects: 2, configuredProjects: 1 });
assert.isTrue(projectService.inferredProjects[0].isOrphan());
checkProjectActualFiles(projectService.inferredProjects[1], [commonFile2.path, libFile.path]);
checkProjectActualFiles(projectService.configuredProjects.get(configFile.path), [libFile.path, commonFile1.path, configFile.path]);
checkWatchedFiles(host, watchedFiles);
// remove the tsconfig file
host.reloadFS(filesWithoutConfig);
checkNumberOfInferredProjects(projectService, 1);
projectService.checkNumberOfProjects({ inferredProjects: 2 });
assert.isTrue(projectService.inferredProjects[0].isOrphan());
checkProjectActualFiles(projectService.inferredProjects[1], [commonFile2.path, libFile.path]);
host.checkTimeoutQueueLengthAndRun(1); // Refresh inferred projects
checkNumberOfInferredProjects(projectService, 2);
checkNumberOfConfiguredProjects(projectService, 0);
projectService.checkNumberOfProjects({ inferredProjects: 2 });
checkProjectActualFiles(projectService.inferredProjects[0], [commonFile1.path, libFile.path]);
checkProjectActualFiles(projectService.inferredProjects[1], [commonFile2.path, libFile.path]);
checkWatchedFiles(host, watchedFiles);
});
@@ -934,6 +945,10 @@ namespace ts.projectSystem {
path: "/a/module1.ts",
content: `export interface T {}`
};
const randomFile: FileOrFolder = {
path: "/a/file1.ts",
content: `export interface T {}`
};
const configFile: FileOrFolder = {
path: "/a/b/tsconfig.json",
content: `{
@@ -943,17 +958,18 @@ namespace ts.projectSystem {
"files": ["${file1.path}"]
}`
};
const files = [file1, nodeModuleFile, classicModuleFile, configFile];
const files = [file1, nodeModuleFile, classicModuleFile, configFile, randomFile];
const host = createServerHost(files);
const projectService = createProjectService(host);
projectService.openClientFile(file1.path);
projectService.openClientFile(nodeModuleFile.path);
projectService.openClientFile(classicModuleFile.path);
checkNumberOfConfiguredProjects(projectService, 1);
checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 1 });
const project = configuredProjectAt(projectService, 0);
const inferredProject0 = projectService.inferredProjects[0];
checkProjectActualFiles(project, [file1.path, nodeModuleFile.path, configFile.path]);
checkNumberOfInferredProjects(projectService, 1);
checkProjectActualFiles(projectService.inferredProjects[0], [classicModuleFile.path]);
configFile.content = `{
"compilerOptions": {
@@ -963,8 +979,22 @@ namespace ts.projectSystem {
}`;
host.reloadFS(files);
host.checkTimeoutQueueLengthAndRun(2);
checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 2 }); // will not remove project 1
checkProjectActualFiles(project, [file1.path, classicModuleFile.path, configFile.path]);
checkNumberOfInferredProjects(projectService, 1);
assert.strictEqual(projectService.inferredProjects[0], inferredProject0);
assert.isTrue(projectService.inferredProjects[0].isOrphan());
const inferredProject1 = projectService.inferredProjects[1];
checkProjectActualFiles(projectService.inferredProjects[1], [nodeModuleFile.path]);
// Open random file and it will reuse first inferred project
projectService.openClientFile(randomFile.path);
checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 2 });
checkProjectActualFiles(project, [file1.path, classicModuleFile.path, configFile.path]);
assert.strictEqual(projectService.inferredProjects[0], inferredProject0);
checkProjectActualFiles(projectService.inferredProjects[0], [randomFile.path]); // Reuses first inferred project
assert.strictEqual(projectService.inferredProjects[1], inferredProject1);
checkProjectActualFiles(projectService.inferredProjects[1], [nodeModuleFile.path]);
});
it("should keep the configured project when the opened file is referenced by the project but not its root", () => {
@@ -1304,20 +1334,21 @@ namespace ts.projectSystem {
assert.isUndefined(projectService.configuredProjects.get(config2.path));
projectService.closeClientFile(file3.path);
checkNumberOfProjects(projectService, { configuredProjects: 1 });
checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 1 });
assert.strictEqual(projectService.configuredProjects.get(config1.path), proj1);
assert.isUndefined(projectService.configuredProjects.get(config2.path));
assert.isTrue(projectService.inferredProjects[0].isOrphan());
projectService.closeClientFile(file1.path);
checkNumberOfProjects(projectService, { configuredProjects: 1 });
checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 1 });
assert.strictEqual(projectService.configuredProjects.get(config1.path), proj1);
assert.isUndefined(projectService.configuredProjects.get(config2.path));
assert.isTrue(projectService.inferredProjects[0].isOrphan());
projectService.openClientFile(file2.path, file2.content);
checkNumberOfProjects(projectService, { configuredProjects: 1 });
assert.isUndefined(projectService.configuredProjects.get(config1.path));
assert.isDefined(projectService.configuredProjects.get(config2.path));
});
describe("ignoreConfigFiles", () => {
@@ -1579,12 +1610,15 @@ namespace ts.projectSystem {
const projectService = createProjectService(host);
projectService.openClientFile(file1.path);
checkNumberOfInferredProjects(projectService, 1);
checkNumberOfProjects(projectService, { inferredProjects: 1 });
const inferredProject0 = projectService.inferredProjects[0];
checkProjectActualFiles(projectService.inferredProjects[0], [file1.path, file2.path]);
projectService.openClientFile(file3.path);
checkNumberOfInferredProjects(projectService, 2);
checkNumberOfProjects(projectService, { inferredProjects: 2 });
assert.strictEqual(projectService.inferredProjects[0], inferredProject0);
checkProjectActualFiles(projectService.inferredProjects[0], [file1.path, file2.path]);
const inferredProject1 = projectService.inferredProjects[1];
checkProjectActualFiles(projectService.inferredProjects[1], [file3.path]);
const modifiedFile2 = {
@@ -1594,8 +1628,11 @@ namespace ts.projectSystem {
host.reloadFS([file1, modifiedFile2, file3]);
host.checkTimeoutQueueLengthAndRun(2);
checkNumberOfInferredProjects(projectService, 1);
checkNumberOfProjects(projectService, { inferredProjects: 2 });
assert.strictEqual(projectService.inferredProjects[0], inferredProject0);
checkProjectActualFiles(projectService.inferredProjects[0], [file1.path, modifiedFile2.path, file3.path]);
assert.strictEqual(projectService.inferredProjects[1], inferredProject1);
assert.isTrue(inferredProject1.isOrphan());
});
it("deleted files affect project structure", () => {
@@ -1767,8 +1804,10 @@ namespace ts.projectSystem {
host.reloadFS([file1, file2, file3, configFile]);
host.checkTimeoutQueueLengthAndRun(1);
checkNumberOfProjects(projectService, { configuredProjects: 1 });
checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 2 });
checkProjectActualFiles(configuredProjectAt(projectService, 0), [file1.path, file2.path, file3.path, configFile.path]);
assert.isTrue(projectService.inferredProjects[0].isOrphan());
assert.isTrue(projectService.inferredProjects[1].isOrphan());
});
it("correctly migrate files between projects", () => {
@@ -1792,19 +1831,46 @@ namespace ts.projectSystem {
projectService.openClientFile(file2.path);
checkNumberOfProjects(projectService, { inferredProjects: 1 });
checkProjectActualFiles(projectService.inferredProjects[0], [file2.path]);
let inferredProjects = projectService.inferredProjects.slice();
projectService.openClientFile(file3.path);
checkNumberOfProjects(projectService, { inferredProjects: 2 });
assert.strictEqual(projectService.inferredProjects[0], inferredProjects[0]);
checkProjectActualFiles(projectService.inferredProjects[0], [file2.path]);
checkProjectActualFiles(projectService.inferredProjects[1], [file3.path]);
inferredProjects = projectService.inferredProjects.slice();
projectService.openClientFile(file1.path);
checkNumberOfProjects(projectService, { inferredProjects: 1 });
assert.notStrictEqual(projectService.inferredProjects[0], inferredProjects[0]);
assert.notStrictEqual(projectService.inferredProjects[0], inferredProjects[1]);
checkProjectRootFiles(projectService.inferredProjects[0], [file1.path]);
checkProjectActualFiles(projectService.inferredProjects[0], [file1.path, file2.path, file3.path]);
inferredProjects = projectService.inferredProjects.slice();
projectService.closeClientFile(file1.path);
checkNumberOfProjects(projectService, { inferredProjects: 3 });
assert.strictEqual(projectService.inferredProjects[0], inferredProjects[0]);
assert.isTrue(projectService.inferredProjects[0].isOrphan());
checkProjectActualFiles(projectService.inferredProjects[1], [file2.path]);
checkProjectActualFiles(projectService.inferredProjects[2], [file3.path]);
inferredProjects = projectService.inferredProjects.slice();
projectService.closeClientFile(file3.path);
checkNumberOfProjects(projectService, { inferredProjects: 3 });
assert.strictEqual(projectService.inferredProjects[0], inferredProjects[0]);
assert.strictEqual(projectService.inferredProjects[1], inferredProjects[1]);
assert.strictEqual(projectService.inferredProjects[2], inferredProjects[2]);
assert.isTrue(projectService.inferredProjects[0].isOrphan());
checkProjectActualFiles(projectService.inferredProjects[1], [file2.path]);
assert.isTrue(projectService.inferredProjects[2].isOrphan());
projectService.openClientFile(file3.path);
checkNumberOfProjects(projectService, { inferredProjects: 2 });
assert.strictEqual(projectService.inferredProjects[0], inferredProjects[2]);
assert.strictEqual(projectService.inferredProjects[1], inferredProjects[1]);
checkProjectActualFiles(projectService.inferredProjects[0], [file3.path]);
checkProjectActualFiles(projectService.inferredProjects[1], [file2.path]);
});
it("can correctly update configured project when set of root files has changed (new file on disk)", () => {
@@ -2286,10 +2352,17 @@ namespace ts.projectSystem {
projectService.openClientFile(modFile.path);
checkNumberOfProjects(projectService, { inferredProjects: 2 });
const inferredProjects = projectService.inferredProjects.slice();
checkProjectActualFiles(inferredProjects[0], [file1.path]);
checkProjectActualFiles(inferredProjects[1], [modFile.path]);
projectService.setCompilerOptionsForInferredProjects({ moduleResolution: ModuleResolutionKind.Classic });
host.checkTimeoutQueueLengthAndRun(3);
checkNumberOfProjects(projectService, { inferredProjects: 1 });
checkNumberOfProjects(projectService, { inferredProjects: 2 });
assert.strictEqual(projectService.inferredProjects[0], inferredProjects[0]);
assert.strictEqual(projectService.inferredProjects[1], inferredProjects[1]);
checkProjectActualFiles(inferredProjects[0], [file1.path, modFile.path]);
assert.isTrue(inferredProjects[1].isOrphan());
});
it("syntax tree cache handles changes in project settings", () => {
@@ -2423,9 +2496,9 @@ namespace ts.projectSystem {
verifyScriptInfos();
checkOpenFiles(projectService, files);
verifyConfiguredProjectStateAfterUpdate(/*hasOpenRef*/ true); // file1, file2, file3
checkNumberOfInferredProjects(projectService, 1);
const inferredProject3 = projectService.inferredProjects[0];
verifyConfiguredProjectStateAfterUpdate(/*hasOpenRef*/ true, 2); // file1, file2, file3
assert.isTrue(projectService.inferredProjects[0].isOrphan());
const inferredProject3 = projectService.inferredProjects[1];
checkProjectActualFiles(inferredProject3, [file4.path]);
assert.strictEqual(inferredProject3, inferredProject2);
@@ -2435,22 +2508,21 @@ namespace ts.projectSystem {
verifyScriptInfos();
checkOpenFiles(projectService, [file3]);
verifyConfiguredProjectStateAfterUpdate(/*hasOpenRef*/ true); // file3
checkNumberOfInferredProjects(projectService, 0);
verifyConfiguredProjectStateAfterUpdate(/*hasOpenRef*/ true, 2); // file3
assert.isTrue(projectService.inferredProjects[0].isOrphan());
assert.isTrue(projectService.inferredProjects[1].isOrphan());
projectService.openClientFile(file4.path);
verifyScriptInfos();
checkOpenFiles(projectService, [file3, file4]);
verifyConfiguredProjectStateAfterUpdate(/*hasOpenRef*/ true); // file3
checkNumberOfInferredProjects(projectService, 1);
verifyConfiguredProjectStateAfterUpdate(/*hasOpenRef*/ true, 1); // file3
const inferredProject4 = projectService.inferredProjects[0];
checkProjectActualFiles(inferredProject4, [file4.path]);
projectService.closeClientFile(file3.path);
verifyScriptInfos();
checkOpenFiles(projectService, [file4]);
verifyConfiguredProjectStateAfterUpdate(/*hasOpenRef*/ false); // No open files
checkNumberOfInferredProjects(projectService, 1);
verifyConfiguredProjectStateAfterUpdate(/*hasOpenRef*/ false, 1); // No open files
const inferredProject5 = projectService.inferredProjects[0];
checkProjectActualFiles(inferredProject4, [file4.path]);
assert.strictEqual(inferredProject5, inferredProject4);
@@ -2465,7 +2537,9 @@ namespace ts.projectSystem {
assert.strictEqual(projectService.getScriptInfoForPath(file4.path as Path), find(infos, info => info.path === file4.path));
assert.isDefined(projectService.getScriptInfoForPath(file5.path as Path));
checkOpenFiles(projectService, [file4, file5]);
checkNumberOfConfiguredProjects(projectService, 0);
checkNumberOfProjects(projectService, { inferredProjects: 2 });
checkProjectActualFiles(projectService.inferredProjects[0], [file4.path]);
checkProjectActualFiles(projectService.inferredProjects[1], [file5.path]);
function verifyScriptInfos() {
infos.forEach(info => assert.strictEqual(projectService.getScriptInfoForPath(info.path), info));
@@ -2477,8 +2551,8 @@ namespace ts.projectSystem {
}
}
function verifyConfiguredProjectStateAfterUpdate(hasOpenRef: boolean) {
checkNumberOfConfiguredProjects(projectService, 1);
function verifyConfiguredProjectStateAfterUpdate(hasOpenRef: boolean, inferredProjects: number) {
checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects });
const configProject2 = projectService.configuredProjects.get(configFile.path);
assert.strictEqual(configProject2, configProject1);
checkProjectActualFiles(configProject2, [file1.path, file2.path, file3.path, configFile.path]);
@@ -2543,11 +2617,13 @@ namespace ts.projectSystem {
checkProjectActualFiles(inferredProject2, [file4.path]);
host.runQueuedTimeoutCallbacks();
checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 1 });
checkNumberOfProjects(projectService, { configuredProjects: 1, inferredProjects: 2 });
assert.strictEqual(projectService.configuredProjects.get(configFile.path), configuredProject);
assert.isTrue(configuredProject.hasOpenRef()); // file2
checkProjectActualFiles(configuredProject, [file1.path, file2.path, file3.path, configFile.path]);
assert.strictEqual(projectService.inferredProjects[0], inferredProject2);
assert.strictEqual(projectService.inferredProjects[0], inferredProject1);
assert.isTrue(inferredProject1.isOrphan());
assert.strictEqual(projectService.inferredProjects[1], inferredProject2);
checkProjectActualFiles(inferredProject2, [file4.path]);
});
@@ -4903,7 +4979,8 @@ namespace ts.projectSystem {
command: server.protocol.CommandTypes.Close,
arguments: { file: f1.path }
});
checkScriptInfoAndProjects(0, f1.content, "contents of closed file");
checkScriptInfoAndProjects(f1.content, "contents of closed file");
checkInferredProjectIsOrphan();
// Can reload contents of the file when its not open and has no project
// reload from temp file
@@ -4911,21 +4988,23 @@ namespace ts.projectSystem {
command: server.protocol.CommandTypes.Reload,
arguments: { file: f1.path, tmpfile: tmp.path }
});
checkScriptInfoAndProjects(0, tmp.content, "contents of temp file");
checkScriptInfoAndProjects(tmp.content, "contents of temp file");
checkInferredProjectIsOrphan();
// reload from own file
session.executeCommandSeq(<server.protocol.ReloadRequest>{
command: server.protocol.CommandTypes.Reload,
arguments: { file: f1.path }
});
checkScriptInfoAndProjects(0, f1.content, "contents of closed file");
checkScriptInfoAndProjects(f1.content, "contents of closed file");
checkInferredProjectIsOrphan();
// Open file again without setting its content
session.executeCommandSeq(<server.protocol.OpenRequest>{
command: server.protocol.CommandTypes.Open,
arguments: { file: f1.path }
});
checkScriptInfoAndProjects(1, f1.content, "contents of file when opened without specifying contents");
checkScriptInfoAndProjects(f1.content, "contents of file when opened without specifying contents");
const snap = info.getSnapshot();
// send close request
@@ -4933,27 +5012,35 @@ namespace ts.projectSystem {
command: server.protocol.CommandTypes.Close,
arguments: { file: f1.path }
});
checkScriptInfoAndProjects(0, f1.content, "contents of closed file");
checkScriptInfoAndProjects(f1.content, "contents of closed file");
assert.strictEqual(info.getSnapshot(), snap);
checkInferredProjectIsOrphan();
// reload from temp file
session.executeCommandSeq(<server.protocol.ReloadRequest>{
command: server.protocol.CommandTypes.Reload,
arguments: { file: f1.path, tmpfile: tmp.path }
});
checkScriptInfoAndProjects(0, tmp.content, "contents of temp file");
checkScriptInfoAndProjects(tmp.content, "contents of temp file");
assert.notStrictEqual(info.getSnapshot(), snap);
checkInferredProjectIsOrphan();
// reload from own file
session.executeCommandSeq(<server.protocol.ReloadRequest>{
command: server.protocol.CommandTypes.Reload,
arguments: { file: f1.path }
});
checkScriptInfoAndProjects(0, f1.content, "contents of closed file");
checkScriptInfoAndProjects(f1.content, "contents of closed file");
assert.notStrictEqual(info.getSnapshot(), snap);
checkInferredProjectIsOrphan();
function checkScriptInfoAndProjects(inferredProjects: number, contentsOfInfo: string, captionForContents: string) {
checkNumberOfProjects(projectService, { inferredProjects });
function checkInferredProjectIsOrphan() {
assert.isTrue(projectService.inferredProjects[0].isOrphan());
assert.equal(info.containingProjects.length, 0);
}
function checkScriptInfoAndProjects(contentsOfInfo: string, captionForContents: string) {
checkNumberOfProjects(projectService, { inferredProjects: 1 });
assert.strictEqual(projectService.getScriptInfo(f1.path), info);
checkScriptInfoContents(contentsOfInfo, captionForContents);
}
+25 -15
View File
@@ -393,21 +393,7 @@ interface Array<T> {}`
if (isString(fileOrDirectory.content)) {
// Update file
if (currentEntry.content !== fileOrDirectory.content) {
if (options && options.invokeFileDeleteCreateAsPartInsteadOfChange) {
this.removeFileOrFolder(currentEntry, returnFalse);
this.ensureFileOrFolder(fileOrDirectory);
}
else {
currentEntry.content = fileOrDirectory.content;
currentEntry.modifiedTime = this.now();
this.fs.get(getDirectoryPath(currentEntry.path)).modifiedTime = this.now();
if (options && options.invokeDirectoryWatcherInsteadOfFileChanged) {
this.invokeDirectoryWatcher(getDirectoryPath(currentEntry.fullPath), currentEntry.fullPath);
}
else {
this.invokeFileWatcher(currentEntry.fullPath, FileWatcherEventKind.Changed);
}
}
this.modifyFile(fileOrDirectory.path, fileOrDirectory.content, options);
}
}
else {
@@ -446,6 +432,30 @@ interface Array<T> {}`
}
}
modifyFile(filePath: string, content: string, options?: Partial<ReloadWatchInvokeOptions>) {
const path = this.toFullPath(filePath);
const currentEntry = this.fs.get(path);
if (!currentEntry || !isFile(currentEntry)) {
throw new Error(`file not present: ${filePath}`);
}
if (options && options.invokeFileDeleteCreateAsPartInsteadOfChange) {
this.removeFileOrFolder(currentEntry, returnFalse);
this.ensureFileOrFolder({ path: filePath, content });
}
else {
currentEntry.content = content;
currentEntry.modifiedTime = this.now();
this.fs.get(getDirectoryPath(currentEntry.path)).modifiedTime = this.now();
if (options && options.invokeDirectoryWatcherInsteadOfFileChanged) {
this.invokeDirectoryWatcher(getDirectoryPath(currentEntry.fullPath), currentEntry.fullPath);
}
else {
this.invokeFileWatcher(currentEntry.fullPath, FileWatcherEventKind.Changed);
}
}
}
renameFolder(folderName: string, newFolderName: string) {
const fullPath = getNormalizedAbsolutePath(folderName, this.currentDirectory);
const path = this.toPath(fullPath);
+9 -7
View File
@@ -1,10 +1,12 @@
type DateTimeFormatPartTypes = "day" | "dayPeriod" | "era" | "hour" | "literal" | "minute" | "month" | "second" | "timeZoneName" | "weekday" | "year";
declare namespace Intl {
type DateTimeFormatPartTypes = "day" | "dayPeriod" | "era" | "hour" | "literal" | "minute" | "month" | "second" | "timeZoneName" | "weekday" | "year";
interface DateTimeFormatPart {
type: DateTimeFormatPartTypes;
value: string;
}
interface DateTimeFormatPart {
type: DateTimeFormatPartTypes;
value: string;
}
interface DateTimeFormat {
formatToParts(date?: Date | number): DateTimeFormatPart[];
interface DateTimeFormat {
formatToParts(date?: Date | number): DateTimeFormatPart[];
}
}
+2 -1
View File
@@ -1,3 +1,4 @@
/// <reference path="lib.es2017.d.ts" />
/// <reference path="lib.es2018.promise.d.ts" />
/// <reference path="lib.es2018.regexp.d.ts" />
/// <reference path="lib.es2018.regexp.d.ts" />
/// <reference path="lib.es2018.intl.d.ts" />
+31
View File
@@ -0,0 +1,31 @@
declare namespace Intl {
interface PluralRulesOptions {
localeMatcher?: 'lookup' | 'best fit';
type?: 'cardinal' | 'ordinal';
}
interface ResolvedPluralRulesOptions {
locale: string;
pluralCategories: string[];
type: 'cardinal' | 'ordinal';
minimumIntegerDigits: number;
minimumFractionDigits: number;
maximumFractionDigits: number;
minimumSignificantDigits: number;
maximumSignificantDigits: number;
}
interface PluralRules {
resolvedOptions(): ResolvedPluralRulesOptions;
select(n: number): string;
}
const PluralRules: {
new (locales?: string | string[], options?: PluralRulesOptions): PluralRules;
(locales?: string | string[], options?: PluralRulesOptions): PluralRules;
supportedLocalesOf(
locales: string | string[],
options?: PluralRulesOptions,
): string[];
};
}
+9
View File
@@ -507,6 +507,15 @@ interface TemplateStringsArray extends ReadonlyArray<string> {
readonly raw: ReadonlyArray<string>;
}
/**
* The type of `import.meta`.
*
* If you need to declare that a given property exists on `import.meta`,
* this type may be augmented via interface merging.
*/
interface ImportMeta {
}
interface Math {
/** The mathematical constant e. This is Euler's number, the base of natural logarithms. */
readonly E: number;
@@ -1251,6 +1251,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_element_access_expression_should_take_an_argument_1011" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An element access expression should take an argument.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[元素访问表达式应采用参数。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_enum_member_cannot_have_a_numeric_name_2452" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An enum member cannot have a numeric name.]]></Val>
@@ -6507,6 +6516,9 @@
<Item ItemId=";Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolve 'keyof' to string valued property names only (no numbers or symbols).]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[只将 "keyof" 解析为字符串值的属性名称(不含数字或符号)。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -8760,6 +8772,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_declared_but_never_used_6196" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is declared but never used.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[“{0}”已声明,但从未使用过。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?]]></Val>
@@ -1260,6 +1260,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_element_access_expression_should_take_an_argument_1011" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An element access expression should take an argument.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Výraz přístupu k elementu by měl přijímat argument.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_enum_member_cannot_have_a_numeric_name_2452" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An enum member cannot have a numeric name.]]></Val>
@@ -6513,6 +6522,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolve 'keyof' to string valued property names only (no numbers or symbols).]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[keyof překládejte jen na názvy vlastností s hodnotami typu string (ne čísla ani symboly).]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolving_from_node_modules_folder_6118" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolving from node_modules folder...]]></Val>
@@ -8763,6 +8781,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_declared_but_never_used_6196" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is declared but never used.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[{0} se nadeklarovalo, ale nepoužilo.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?]]></Val>
@@ -1260,6 +1260,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_element_access_expression_should_take_an_argument_1011" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An element access expression should take an argument.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Una expresión de acceso de elemento debe admitir un argumento.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_enum_member_cannot_have_a_numeric_name_2452" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An enum member cannot have a numeric name.]]></Val>
@@ -6516,6 +6525,9 @@
<Item ItemId=";Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolve 'keyof' to string valued property names only (no numbers or symbols).]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Resolver "keyof" exclusivamente como nombres de propiedad con valores de cadena (sin números ni símbolos).]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -7425,6 +7437,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_option_1343" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary_2527" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[The inferred type of '{0}' references an inaccessible '{1}' type. A type annotation is necessary.]]></Val>
@@ -8769,6 +8787,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_declared_but_never_used_6196" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is declared but never used.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA["{0}" se declara pero nunca se utiliza.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?]]></Val>
@@ -1260,6 +1260,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_element_access_expression_should_take_an_argument_1011" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An element access expression should take an argument.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Une expression d'accès à un élément doit accepter un argument.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_enum_member_cannot_have_a_numeric_name_2452" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An enum member cannot have a numeric name.]]></Val>
@@ -6516,6 +6525,9 @@
<Item ItemId=";Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolve 'keyof' to string valued property names only (no numbers or symbols).]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Résoudre 'keyof' en noms de propriétés de valeur chaîne uniquement (aucun nombre ou symbole).]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -7425,6 +7437,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_option_1343" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary_2527" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[The inferred type of '{0}' references an inaccessible '{1}' type. A type annotation is necessary.]]></Val>
@@ -8769,6 +8787,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_declared_but_never_used_6196" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is declared but never used.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['{0}' est déclaré mais n'est jamais utilisé.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?]]></Val>
@@ -1251,6 +1251,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_element_access_expression_should_take_an_argument_1011" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An element access expression should take an argument.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Un'espressione di accesso a elementi deve accettare un argomento.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_enum_member_cannot_have_a_numeric_name_2452" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An enum member cannot have a numeric name.]]></Val>
@@ -6504,6 +6513,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolve 'keyof' to string valued property names only (no numbers or symbols).]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Risolvere 'keyof' solo in nomi di proprietà con valori stringa (senza numeri o simboli).]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolving_from_node_modules_folder_6118" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolving from node_modules folder...]]></Val>
@@ -8754,6 +8772,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_declared_but_never_used_6196" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is declared but never used.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[La variabile '{0}' è dichiarata, ma non viene mai usata.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?]]></Val>
@@ -1241,6 +1241,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_element_access_expression_should_take_an_argument_1011" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An element access expression should take an argument.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Wyrażenie dostępu do elementu powinno przyjmować argument.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_enum_member_cannot_have_a_numeric_name_2452" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An enum member cannot have a numeric name.]]></Val>
@@ -6494,6 +6503,9 @@
<Item ItemId=";Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolve 'keyof' to string valued property names only (no numbers or symbols).]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Rozwiązuj elementy „keyof” tylko do nazw właściwości mających jako wartość ciągi (nie liczby czy symbole).]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -8747,6 +8759,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_declared_but_never_used_6196" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is declared but never used.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Element „{0}” jest zadeklarowany, ale nie jest nigdy używany.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?]]></Val>
@@ -1241,6 +1241,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_element_access_expression_should_take_an_argument_1011" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An element access expression should take an argument.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Uma expressão de acesso do elemento deveria receber um argumento.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_enum_member_cannot_have_a_numeric_name_2452" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An enum member cannot have a numeric name.]]></Val>
@@ -6494,6 +6503,9 @@
<Item ItemId=";Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolve 'keyof' to string valued property names only (no numbers or symbols).]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Resolva 'keyof' para nomes de propriedades com valores de cadeia de caracteres somente (sem números ou símbolos).]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -7403,6 +7415,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_option_1343" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary_2527" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[The inferred type of '{0}' references an inaccessible '{1}' type. A type annotation is necessary.]]></Val>
@@ -8747,6 +8765,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_declared_but_never_used_6196" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is declared but never used.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['{0}' está declarado, mas nunca foi usado.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?]]></Val>
@@ -1250,6 +1250,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_element_access_expression_should_take_an_argument_1011" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An element access expression should take an argument.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Выражение доступа к элементу должно принимать аргумент.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_enum_member_cannot_have_a_numeric_name_2452" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An enum member cannot have a numeric name.]]></Val>
@@ -6506,6 +6515,9 @@
<Item ItemId=";Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolve 'keyof' to string valued property names only (no numbers or symbols).]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Разрешать "keyof" только в имена свойств со строковым значением (не числа и не символы).]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -8759,6 +8771,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_declared_but_never_used_6196" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is declared but never used.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA["{0}" объявлен, но никогда не использовался.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?]]></Val>
+87 -70
View File
@@ -712,17 +712,11 @@ namespace ts.server {
this.handleDeletedFile(info);
}
else if (!info.isScriptOpen()) {
if (info.containingProjects.length === 0) {
// Orphan script info, remove it as we can always reload it on next open file request
this.stopWatchingScriptInfo(info);
this.deleteScriptInfo(info);
}
else {
// file has been changed which might affect the set of referenced files in projects that include
// this file and set of inferred projects
info.delayReloadNonMixedContentFile();
this.delayUpdateProjectGraphs(info.containingProjects);
}
Debug.assert(info.containingProjects.length !== 0);
// file has been changed which might affect the set of referenced files in projects that include
// this file and set of inferred projects
info.delayReloadNonMixedContentFile();
this.delayUpdateProjectGraphs(info.containingProjects);
}
}
@@ -855,15 +849,23 @@ namespace ts.server {
const project = this.getOrCreateInferredProjectForProjectRootPathIfEnabled(info, projectRootPath) ||
this.getOrCreateSingleInferredProjectIfEnabled() ||
this.createInferredProject(info.isDynamic ? this.currentDirectory : getDirectoryPath(info.path));
this.getOrCreateSingleInferredWithoutProjectRoot(info.isDynamic ? this.currentDirectory : getDirectoryPath(info.path));
project.addRoot(info);
if (info.containingProjects[0] !== project) {
// Ensure this is first project, we could be in this scenario because info could be part of orphan project
info.detachFromProject(project);
info.containingProjects.unshift(project);
}
project.updateGraph();
if (!this.useSingleInferredProject && !project.projectRootPath) {
// Note that we need to create a copy of the array since the list of project can change
for (const inferredProject of this.inferredProjects.slice(0, this.inferredProjects.length - 1)) {
Debug.assert(inferredProject !== project);
for (const inferredProject of this.inferredProjects) {
if (inferredProject === project || inferredProject.isOrphan()) {
continue;
}
// Remove the inferred project if the root of it is now part of newly created inferred project
// e.g through references
// Which means if any root of inferred project is part of more than 1 project can be removed
@@ -874,8 +876,8 @@ namespace ts.server {
// instead of scanning all open files
const roots = inferredProject.getRootScriptInfos();
Debug.assert(roots.length === 1 || !!inferredProject.projectRootPath);
if (roots.length === 1 && roots[0].containingProjects.length > 1) {
this.removeProject(inferredProject);
if (roots.length === 1 && forEach(roots[0].containingProjects, p => p !== roots[0].containingProjects[0] && !p.isOrphan())) {
inferredProject.removeFile(roots[0], /*fileExists*/ true, /*detachFromProject*/ true);
}
}
}
@@ -895,15 +897,13 @@ namespace ts.server {
info.close(fileExists);
this.stopWatchingConfigFilesForClosedScriptInfo(info);
this.openFiles.delete(info.path);
const canonicalFileName = this.toCanonicalFileName(info.fileName);
if (this.openFilesWithNonRootedDiskPath.get(canonicalFileName) === info) {
this.openFilesWithNonRootedDiskPath.delete(canonicalFileName);
}
// collect all projects that should be removed
let projectsToRemove: Project[];
let ensureProjectsForOpenFiles = false;
for (const p of info.containingProjects) {
if (p.projectKind === ProjectKind.Configured) {
if (info.hasMixedContent) {
@@ -913,15 +913,14 @@ namespace ts.server {
// if it would need to be re-created with next file open
}
else if (p.projectKind === ProjectKind.Inferred && p.isRoot(info)) {
// If this was the open root file of inferred project
// If this was the last open root file of inferred project
if ((p as InferredProject).isProjectWithSingleRoot()) {
// - when useSingleInferredProject is not set, we can guarantee that this will be the only root
// - other wise remove the project if it is the only root
(projectsToRemove || (projectsToRemove = [])).push(p);
}
else {
p.removeFile(info, fileExists, /*detachFromProject*/ true);
ensureProjectsForOpenFiles = true;
}
p.removeFile(info, fileExists, /*detachFromProject*/ true);
// Do not remove the project even if this was last root of the inferred project
// so that we can reuse this project, if it would need to be re-created with next file open
}
if (!p.languageServiceEnabled) {
@@ -931,24 +930,24 @@ namespace ts.server {
p.markAsDirty();
}
}
if (projectsToRemove) {
for (const project of projectsToRemove) {
this.removeProject(project);
}
this.openFiles.delete(info.path);
if (ensureProjectsForOpenFiles) {
// collect orphaned files and assign them to inferred project just like we treat open of a file
this.openFiles.forEach((projectRootPath, path) => {
const f = this.getScriptInfoForPath(path as Path);
if (f.isOrphan()) {
this.assignOrphanScriptInfoToInferredProject(f, projectRootPath);
const info = this.getScriptInfoForPath(path as Path);
// collect all orphaned script infos from open files
if (info.isOrphan()) {
this.assignOrphanScriptInfoToInferredProject(info, projectRootPath);
}
});
// Cleanup script infos that arent part of any project (eg. those could be closed script infos not referenced by any project)
// is postponed to next file open so that if file from same project is opened,
// we wont end up creating same script infos
}
// Cleanup script infos that arent part of any project (eg. those could be closed script infos not referenced by any project)
// is postponed to next file open so that if file from same project is opened,
// we wont end up creating same script infos
// If the current info is being just closed - add the watcher file to track changes
// But if file was deleted, handle that part
if (fileExists) {
@@ -959,16 +958,6 @@ namespace ts.server {
}
}
private deleteOrphanScriptInfoNotInAnyProject() {
this.filenameToScriptInfo.forEach(info => {
if (!info.isScriptOpen() && info.isOrphan()) {
// if there are not projects that include this script info - delete it
this.stopWatchingScriptInfo(info);
this.deleteScriptInfo(info);
}
});
}
private deleteScriptInfo(info: ScriptInfo) {
this.filenameToScriptInfo.delete(info.path);
const realpath = info.getRealpathIfDifferent();
@@ -1145,7 +1134,7 @@ namespace ts.server {
* This is called by inferred project whenever script info is added as a root
*/
/* @internal */
startWatchingConfigFilesForInferredProjectRoot(info: ScriptInfo, projectRootPath: NormalizedPath | undefined) {
startWatchingConfigFilesForInferredProjectRoot(info: ScriptInfo) {
Debug.assert(info.isScriptOpen());
this.forEachConfigFileLocation(info, (configFileName, canonicalConfigFilePath) => {
let configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
@@ -1167,7 +1156,7 @@ namespace ts.server {
!this.getConfiguredProjectByCanonicalConfigFilePath(canonicalConfigFilePath)) {
this.createConfigFileWatcherOfConfigFileExistence(configFileName, canonicalConfigFilePath, configFileExistenceInfo);
}
}, projectRootPath);
});
}
/**
@@ -1198,14 +1187,14 @@ namespace ts.server {
* The server must start searching from the directory containing
* the newly opened file.
*/
private forEachConfigFileLocation(info: ScriptInfo,
action: (configFileName: NormalizedPath, canonicalConfigFilePath: string) => boolean | void,
projectRootPath?: NormalizedPath) {
private forEachConfigFileLocation(info: ScriptInfo, action: (configFileName: NormalizedPath, canonicalConfigFilePath: string) => boolean | void) {
if (this.syntaxOnly) {
return undefined;
}
Debug.assert(this.openFiles.has(info.path));
const projectRootPath = this.openFiles.get(info.path);
let searchPath = asNormalizedPath(getDirectoryPath(info.fileName));
while (!projectRootPath || containsPath(projectRootPath, searchPath, this.currentDirectory, !this.host.useCaseSensitiveFileNames)) {
@@ -1240,13 +1229,12 @@ namespace ts.server {
* The server must start searching from the directory containing
* the newly opened file.
*/
private getConfigFileNameForFile(info: ScriptInfo, projectRootPath: NormalizedPath | undefined) {
private getConfigFileNameForFile(info: ScriptInfo) {
Debug.assert(info.isScriptOpen());
this.logger.info(`Search path: ${getDirectoryPath(info.fileName)}`);
const configFileName = this.forEachConfigFileLocation(info,
(configFileName, canonicalConfigFilePath) =>
this.configFileExists(configFileName, canonicalConfigFilePath, info),
projectRootPath
);
if (configFileName) {
this.logger.info(`For info: ${info.fileName} :: Config file name: ${configFileName}`);
@@ -1674,6 +1662,21 @@ namespace ts.server {
return this.createInferredProject(/*currentDirectory*/ undefined, /*isSingleInferredProject*/ true);
}
private getOrCreateSingleInferredWithoutProjectRoot(currentDirectory: string | undefined): InferredProject {
Debug.assert(!this.useSingleInferredProject);
const expectedCurrentDirectory = this.toCanonicalFileName(this.getNormalizedAbsolutePath(currentDirectory || ""));
// Reuse the project with same current directory but no roots
for (const inferredProject of this.inferredProjects) {
if (!inferredProject.projectRootPath &&
inferredProject.isOrphan() &&
inferredProject.canonicalCurrentDirectory === expectedCurrentDirectory) {
return inferredProject;
}
}
return this.createInferredProject(currentDirectory);
}
private createInferredProject(currentDirectory: string | undefined, isSingleInferredProject?: boolean, projectRootPath?: NormalizedPath): InferredProject {
const compilerOptions = projectRootPath && this.compilerOptionsForInferredProjectsPerProjectRoot.get(projectRootPath) || this.compilerOptionsForInferredProjects;
const project = new InferredProject(this, this.documentRegistry, compilerOptions, projectRootPath, currentDirectory);
@@ -1720,6 +1723,7 @@ namespace ts.server {
for (const project of toAddInfo.containingProjects) {
// Add the projects only if they can use symLink targets and not already in the list
if (project.languageServiceEnabled &&
!project.isOrphan() &&
!project.getCompilerOptions().preserveSymlinks &&
!contains(info.containingProjects, project)) {
if (!projects) {
@@ -1909,7 +1913,7 @@ namespace ts.server {
// we first detect if there is already a configured project created for it: if so,
// we re- read the tsconfig file content and update the project only if we havent already done so
// otherwise we create a new one.
const configFileName = this.getConfigFileNameForFile(info, this.openFiles.get(path));
const configFileName = this.getConfigFileNameForFile(info);
if (configFileName) {
const project = this.findConfiguredProjectByProjectName(configFileName);
if (!project) {
@@ -1948,16 +1952,14 @@ namespace ts.server {
// so it will be added to inferred project as a root. (for sake of this example assume single inferred project is false)
// So at this poing a.ts is part of first inferred project and second inferred project (of which c.ts is root)
// And hence it needs to be removed from the first inferred project.
if (info.containingProjects.length > 1 &&
info.containingProjects[0].projectKind === ProjectKind.Inferred &&
info.containingProjects[0].isRoot(info)) {
const inferredProject = info.containingProjects[0] as InferredProject;
if (inferredProject.isProjectWithSingleRoot()) {
this.removeProject(inferredProject);
}
else {
inferredProject.removeFile(info, /*fileExists*/ true, /*detachFromProject*/ true);
}
Debug.assert(info.containingProjects.length > 0);
const firstProject = info.containingProjects[0];
if (!firstProject.isOrphan() &&
firstProject.projectKind === ProjectKind.Inferred &&
firstProject.isRoot(info) &&
forEach(info.containingProjects, p => p !== firstProject && !p.isOrphan())) {
firstProject.removeFile(info, /*fileExists*/ true, /*detachFromProject*/ true);
}
}
@@ -2012,9 +2014,10 @@ namespace ts.server {
let configFileErrors: ReadonlyArray<Diagnostic>;
const info = this.getOrCreateScriptInfoOpenedByClientForNormalizedPath(fileName, projectRootPath ? this.getNormalizedAbsolutePath(projectRootPath) : this.currentDirectory, fileContent, scriptKind, hasMixedContent);
this.openFiles.set(info.path, projectRootPath);
let project: ConfiguredProject | ExternalProject | undefined = this.findExternalProjectContainingOpenScriptInfo(info);
if (!project && !this.syntaxOnly) { // Checking syntaxOnly is an optimization
configFileName = this.getConfigFileNameForFile(info, projectRootPath);
configFileName = this.getConfigFileNameForFile(info);
if (configFileName) {
project = this.findConfiguredProjectByProjectName(configFileName);
if (!project) {
@@ -2050,9 +2053,8 @@ namespace ts.server {
if (info.isOrphan()) {
this.assignOrphanScriptInfoToInferredProject(info, projectRootPath);
}
Debug.assert(!info.isOrphan());
this.openFiles.set(info.path, projectRootPath);
// Remove the configured projects that have zero references from open files.
// This was postponed from closeOpenFile to after opening next file,
@@ -2063,11 +2065,26 @@ namespace ts.server {
}
});
// Remove orphan inferred projects now that we have reused projects
// We need to create a duplicate because we cant guarantee order after removal
for (const inferredProject of this.inferredProjects.slice()) {
if (inferredProject.isOrphan()) {
this.removeProject(inferredProject);
}
}
// Delete the orphan files here because there might be orphan script infos (which are not part of project)
// when some file/s were closed which resulted in project removal.
// It was then postponed to cleanup these script infos so that they can be reused if
// the file from that old project is reopened because of opening file from here.
this.deleteOrphanScriptInfoNotInAnyProject();
this.filenameToScriptInfo.forEach(info => {
if (!info.isScriptOpen() && info.isOrphan()) {
// if there are not projects that include this script info - delete it
this.stopWatchingScriptInfo(info);
this.deleteScriptInfo(info);
}
});
this.printProjects();
return { configFileName, configFileErrors };
+23 -2
View File
@@ -591,6 +591,11 @@ namespace ts.server {
return this.rootFiles && this.rootFiles.length > 0;
}
/*@internal*/
isOrphan() {
return false;
}
getRootFiles() {
return this.rootFiles && this.rootFiles.map(info => info.fileName);
}
@@ -834,6 +839,10 @@ namespace ts.server {
/*@internal*/
updateTypingFiles(typingFiles: SortedReadonlyArray<string>) {
enumerateInsertsAndDeletes(typingFiles, this.typingFiles, getStringComparer(!this.useCaseSensitiveFileNames()),
/*inserted*/ noop,
removed => this.detachScriptInfoFromProject(removed)
);
this.typingFiles = typingFiles;
// Invalidate files with unresolved imports
this.resolutionCache.setFilesWithInvalidatedNonRelativeUnresolvedImports(this.cachedUnresolvedImportsPerFile);
@@ -894,7 +903,7 @@ namespace ts.server {
const oldExternalFiles = this.externalFiles || emptyArray as SortedReadonlyArray<string>;
this.externalFiles = this.getExternalFiles();
enumerateInsertsAndDeletes(this.externalFiles, oldExternalFiles, compareStringsCaseSensitive,
enumerateInsertsAndDeletes(this.externalFiles, oldExternalFiles, getStringComparer(!this.useCaseSensitiveFileNames()),
// Ensure a ScriptInfo is created for new external files. This is performed indirectly
// by the LSHost for files in the program when the program is retrieved above but
// the program doesn't contain external files so this must be done explicitly.
@@ -1169,6 +1178,10 @@ namespace ts.server {
/** this is canonical project root path */
readonly projectRootPath: string | undefined;
/*@internal*/
/** stored only if their is no projectRootPath and this isnt single inferred project */
readonly canonicalCurrentDirectory: string | undefined;
/*@internal*/
constructor(
projectService: ProjectService,
@@ -1187,12 +1200,15 @@ namespace ts.server {
projectService.host,
currentDirectory);
this.projectRootPath = projectRootPath && projectService.toCanonicalFileName(projectRootPath);
if (!projectRootPath && !projectService.useSingleInferredProject) {
this.canonicalCurrentDirectory = projectService.toCanonicalFileName(this.currentDirectory);
}
this.enableGlobalPlugins();
}
addRoot(info: ScriptInfo) {
Debug.assert(info.isScriptOpen());
this.projectService.startWatchingConfigFilesForInferredProjectRoot(info, this.projectService.openFiles.get(info.path));
this.projectService.startWatchingConfigFilesForInferredProjectRoot(info);
if (!this._isJsInferredProject && info.isJavaScript()) {
this.toggleJsInferredProject(/*isJsInferredProject*/ true);
}
@@ -1209,6 +1225,11 @@ namespace ts.server {
}
}
/*@internal*/
isOrphan() {
return !this.hasRoots();
}
isProjectWithSingleRoot() {
// - when useSingleInferredProject is not set and projectRootPath is not set,
// we can guarantee that this will be the only root
+1 -1
View File
@@ -460,7 +460,7 @@ namespace ts.server {
}
isOrphan() {
return this.containingProjects.length === 0;
return !forEach(this.containingProjects, p => !p.isOrphan());
}
/**
+2 -2
View File
@@ -865,7 +865,7 @@ namespace ts.server {
symLinkedProjects = this.projectService.getSymlinkedProjects(scriptInfo);
}
// filter handles case when 'projects' is undefined
projects = filter(projects, p => p.languageServiceEnabled);
projects = filter(projects, p => p.languageServiceEnabled && !p.isOrphan());
if ((!projects || !projects.length) && !symLinkedProjects) {
return Errors.ThrowNoProject();
}
@@ -1336,7 +1336,7 @@ namespace ts.server {
symLinkedProjects ? { projects, symLinkedProjects } : projects,
(project, info) => {
let result: protocol.CompileOnSaveAffectedFileListSingleProject;
if (project.compileOnSaveEnabled && project.languageServiceEnabled && !project.getCompilationSettings().noEmit) {
if (project.compileOnSaveEnabled && project.languageServiceEnabled && !project.isOrphan() && !project.getCompilationSettings().noEmit) {
result = {
projectFileName: project.getProjectName(),
fileNames: project.getCompileOnSaveAffectedFileList(info),
+1
View File
@@ -108,6 +108,7 @@
"../services/codefixes/inferFromUsage.ts",
"../services/codefixes/fixInvalidImportSyntax.ts",
"../services/codefixes/fixStrictClassInitialization.ts",
"../services/codefixes/requireInTs.ts",
"../services/codefixes/useDefaultImport.ts",
"../services/refactors/extractSymbol.ts",
"../services/refactors/generateGetAccessorAndSetAccessor.ts",
+1
View File
@@ -114,6 +114,7 @@
"../services/codefixes/inferFromUsage.ts",
"../services/codefixes/fixInvalidImportSyntax.ts",
"../services/codefixes/fixStrictClassInitialization.ts",
"../services/codefixes/requireInTs.ts",
"../services/codefixes/useDefaultImport.ts",
"../services/refactors/extractSymbol.ts",
"../services/refactors/generateGetAccessorAndSetAccessor.ts",
+11 -5
View File
@@ -1,18 +1,22 @@
/* @internal */
namespace ts.codefix {
const fixId = "fixCannotFindModule";
const errorCodes = [Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type.code];
const errorCodeCannotFindModule = Diagnostics.Cannot_find_module_0.code;
const errorCodes = [
errorCodeCannotFindModule,
Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type.code,
];
registerCodeFix({
errorCodes,
getCodeActions: context => {
const { host, sourceFile, span: { start } } = context;
const packageName = getTypesPackageNameToInstall(host, sourceFile, start);
const packageName = getTypesPackageNameToInstall(host, sourceFile, start, context.errorCode);
return packageName === undefined ? []
: [createCodeFixAction(fixId, /*changes*/ [], [Diagnostics.Install_0, packageName], fixId, Diagnostics.Install_all_missing_types_packages, getCommand(sourceFile.fileName, packageName))];
},
fixIds: [fixId],
getAllCodeActions: context => codeFixAll(context, errorCodes, (_, diag, commands) => {
const pkg = getTypesPackageNameToInstall(context.host, diag.file, diag.start);
const pkg = getTypesPackageNameToInstall(context.host, diag.file, diag.start, diag.code);
if (pkg) {
commands.push(getCommand(diag.file.fileName, pkg));
}
@@ -23,9 +27,11 @@ namespace ts.codefix {
return { type: "install package", file: fileName, packageName };
}
function getTypesPackageNameToInstall(host: LanguageServiceHost, sourceFile: SourceFile, pos: number): string | undefined {
function getTypesPackageNameToInstall(host: LanguageServiceHost, sourceFile: SourceFile, pos: number, diagCode: number): string | undefined {
const moduleName = cast(getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false), isStringLiteral).text;
const { packageName } = getPackageName(moduleName);
return host.isKnownTypesPackageName(packageName) ? getTypesPackageName(packageName) : undefined;
return diagCode === errorCodeCannotFindModule
? (JsTyping.nodeCoreModules.has(packageName) ? "@types/node" : undefined)
: (host.isKnownTypesPackageName(packageName) ? getTypesPackageName(packageName) : undefined);
}
}
+1 -1
View File
@@ -114,7 +114,7 @@ namespace ts.codefix {
}
for (const exported of checker.getExportsOfModule(moduleSymbol)) {
if (exported.escapedName === InternalSymbolName.Default || exported.name === symbolName && skipAlias(exported, checker) === exportedSymbol) {
if ((exported.escapedName === InternalSymbolName.Default || exported.name === symbolName) && skipAlias(exported, checker) === exportedSymbol) {
const isDefaultExport = checker.tryGetMemberInModuleExports(InternalSymbolName.Default, moduleSymbol) === exported;
result.push({ moduleSymbol, importKind: isDefaultExport ? ImportKind.Default : ImportKind.Named });
}
+29
View File
@@ -0,0 +1,29 @@
/* @internal */
namespace ts.codefix {
const fixId = "requireInTs";
const errorCodes = [Diagnostics.require_call_may_be_converted_to_an_import.code];
registerCodeFix({
errorCodes,
getCodeActions(context) {
const changes = textChanges.ChangeTracker.with(context, t => doChange(t, context.sourceFile, context.span.start, context.program));
return [createCodeFixAction(fixId, changes, Diagnostics.Convert_require_to_import, fixId, Diagnostics.Convert_all_require_to_import)];
},
fixIds: [fixId],
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => doChange(changes, diag.file, diag.start, context.program)),
});
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number, program: Program) {
const { statement, name, required } = getInfo(sourceFile, pos);
changes.replaceNode(sourceFile, statement, getAllowSyntheticDefaultImports(program.getCompilerOptions())
? createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createImportClause(name, /*namedBindings*/ undefined), required)
: createImportEqualsDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, name, createExternalModuleReference(required)));
}
interface Info { readonly statement: VariableStatement; readonly name: Identifier; readonly required: StringLiteralLike; }
function getInfo(sourceFile: SourceFile, pos: number): Info {
const { parent } = getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false);
if (!isRequireCall(parent, /*checkArgumentIsStringLiteralLike*/ true)) throw Debug.failBadSyntaxKind(parent);
const decl = cast(parent.parent, isVariableDeclaration);
return { statement: cast(decl.parent.parent, isVariableStatement), name: cast(decl.name, isIdentifier), required: parent.arguments[0] };
}
}
+2 -2
View File
@@ -126,8 +126,8 @@ namespace ts.formatting {
rule("SpaceBetweenAsyncAndOpenParen", SyntaxKind.AsyncKeyword, SyntaxKind.OpenParenToken, [isArrowFunctionContext, isNonJsxSameLineTokenContext], RuleAction.Space),
rule("SpaceBetweenAsyncAndFunctionKeyword", SyntaxKind.AsyncKeyword, SyntaxKind.FunctionKeyword, [isNonJsxSameLineTokenContext], RuleAction.Space),
// template string
rule("NoSpaceBetweenTagAndTemplateString", SyntaxKind.Identifier, [SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead], [isNonJsxSameLineTokenContext], RuleAction.Delete),
// Template string
rule("NoSpaceBetweenTagAndTemplateString", [SyntaxKind.Identifier, SyntaxKind.CloseParenToken], [SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead], [isNonJsxSameLineTokenContext], RuleAction.Delete),
// JSX opening elements
rule("SpaceBeforeJsxAttribute", anyToken, SyntaxKind.Identifier, [isNextTokenParentJsxAttribute, isNonJsxSameLineTokenContext], RuleAction.Space),
+2 -1
View File
@@ -39,7 +39,8 @@ namespace ts.JsTyping {
"crypto", "stream", "util", "assert", "tty", "domain",
"constants", "process", "v8", "timers", "console"];
const nodeCoreModules = arrayToSet(nodeCoreModuleList);
/* @internal */
export const nodeCoreModules = arrayToSet(nodeCoreModuleList);
/**
* A map of loose file names to library names that we are confident require typings
+13
View File
@@ -32,6 +32,19 @@ namespace ts {
}
check(sourceFile);
if (!isJsFile) {
for (const statement of sourceFile.statements) {
if (isVariableStatement(statement) &&
statement.declarationList.flags & NodeFlags.Const &&
statement.declarationList.declarations.length === 1) {
const init = statement.declarationList.declarations[0].initializer;
if (init && isRequireCall(init, /*checkArgumentIsStringLiteralLike*/ true)) {
diags.push(createDiagnosticForNode(init, Diagnostics.require_call_may_be_converted_to_an_import));
}
}
}
}
if (getAllowSyntheticDefaultImports(program.getCompilerOptions())) {
for (const moduleSpecifier of sourceFile.imports) {
const importNode = importFromModuleSpecifier(moduleSpecifier);
+1
View File
@@ -105,6 +105,7 @@
"codefixes/inferFromUsage.ts",
"codefixes/fixInvalidImportSyntax.ts",
"codefixes/fixStrictClassInitialization.ts",
"codefixes/requireInTs.ts",
"codefixes/useDefaultImport.ts",
"refactors/extractSymbol.ts",
"refactors/generateGetAccessorAndSetAccessor.ts",
+5 -4
View File
@@ -414,11 +414,11 @@ declare namespace ts {
JavaScriptFile = 65536,
ThisNodeOrAnySubNodesHasError = 131072,
HasAggregatedChildData = 262144,
JSDoc = 1048576,
JSDoc = 2097152,
BlockScoped = 3,
ReachabilityCheckFlags = 384,
ReachabilityAndEmitFlags = 1408,
ContextFlags = 6387712,
ContextFlags = 12679168,
TypeExcludesFlags = 20480
}
enum ModifierFlags {
@@ -1072,7 +1072,7 @@ declare namespace ts {
}
interface MetaProperty extends PrimaryExpression {
kind: SyntaxKind.MetaProperty;
keywordToken: SyntaxKind.NewKeyword;
keywordToken: SyntaxKind.NewKeyword | SyntaxKind.ImportKeyword;
name: Identifier;
}
interface JsxElement extends PrimaryExpression {
@@ -2111,6 +2111,7 @@ declare namespace ts {
BooleanLike = 136,
EnumLike = 272,
ESSymbolLike = 1536,
VoidLike = 6144,
UnionOrIntersection = 393216,
StructuredType = 458752,
TypeVariable = 1081344,
@@ -8073,7 +8074,6 @@ declare namespace ts.server {
* @param info The file that has been closed or newly configured
*/
private closeOpenFile;
private deleteOrphanScriptInfoNotInAnyProject;
private deleteScriptInfo;
private configFileExists;
private setConfigFileExistenceByNewConfiguredProject;
@@ -8130,6 +8130,7 @@ declare namespace ts.server {
private sendConfigFileDiagEvent;
private getOrCreateInferredProjectForProjectRootPathIfEnabled;
private getOrCreateSingleInferredProjectIfEnabled;
private getOrCreateSingleInferredWithoutProjectRoot;
private createInferredProject;
getScriptInfo(uncheckedFileName: string): ScriptInfo;
private watchClosedScriptInfo;
+4 -3
View File
@@ -414,11 +414,11 @@ declare namespace ts {
JavaScriptFile = 65536,
ThisNodeOrAnySubNodesHasError = 131072,
HasAggregatedChildData = 262144,
JSDoc = 1048576,
JSDoc = 2097152,
BlockScoped = 3,
ReachabilityCheckFlags = 384,
ReachabilityAndEmitFlags = 1408,
ContextFlags = 6387712,
ContextFlags = 12679168,
TypeExcludesFlags = 20480
}
enum ModifierFlags {
@@ -1072,7 +1072,7 @@ declare namespace ts {
}
interface MetaProperty extends PrimaryExpression {
kind: SyntaxKind.MetaProperty;
keywordToken: SyntaxKind.NewKeyword;
keywordToken: SyntaxKind.NewKeyword | SyntaxKind.ImportKeyword;
name: Identifier;
}
interface JsxElement extends PrimaryExpression {
@@ -2111,6 +2111,7 @@ declare namespace ts {
BooleanLike = 136,
EnumLike = 272,
ESSymbolLike = 1536,
VoidLike = 6144,
UnionOrIntersection = 393216,
StructuredType = 458752,
TypeVariable = 1081344,
@@ -0,0 +1,25 @@
tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts(5,22): error TS2449: Class 'A' used before its declaration.
tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts(6,13): error TS2449: Class 'A' used before its declaration.
tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts(7,6): error TS2449: Class 'A' used before its declaration.
tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts(8,6): error TS2449: Class 'A' used before its declaration.
==== tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts (4 errors) ====
class A {
static readonly p1 = Symbol();
static readonly p2 = Symbol();
// All of the below should be out of scope or TDZ - `A` has not finished being constructed as they are executed
static readonly [A.p1] = 0;
~
!!! error TS2449: Class 'A' used before its declaration.
static [A.p2]() { return 0 };
~
!!! error TS2449: Class 'A' used before its declaration.
[A.p1]() { }
~
!!! error TS2449: Class 'A' used before its declaration.
[A.p2] = 0
~
!!! error TS2449: Class 'A' used before its declaration.
}
@@ -0,0 +1,28 @@
//// [classDeclarationShouldBeOutOfScopeInComputedNames.ts]
class A {
static readonly p1 = Symbol();
static readonly p2 = Symbol();
// All of the below should be out of scope or TDZ - `A` has not finished being constructed as they are executed
static readonly [A.p1] = 0;
static [A.p2]() { return 0 };
[A.p1]() { }
[A.p2] = 0
}
//// [classDeclarationShouldBeOutOfScopeInComputedNames.js]
var A = /** @class */ (function () {
function A() {
this[_a] = 0;
}
A[(_b = A.p1, A.p2)] = function () { return 0; };
;
A.prototype[A.p1] = function () { };
_a = A.p2;
A.p1 = Symbol();
A.p2 = Symbol();
// All of the below should be out of scope or TDZ - `A` has not finished being constructed as they are executed
A[_b] = 0;
return A;
var _b, _a;
}());
@@ -0,0 +1,38 @@
=== tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts ===
class A {
>A : Symbol(A, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 0, 0))
static readonly p1 = Symbol();
>p1 : Symbol(A.p1, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 0, 9))
>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --))
static readonly p2 = Symbol();
>p2 : Symbol(A.p2, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 1, 34))
>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --))
// All of the below should be out of scope or TDZ - `A` has not finished being constructed as they are executed
static readonly [A.p1] = 0;
>[A.p1] : Symbol(A[A.p1], Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 2, 34))
>A.p1 : Symbol(A.p1, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 0, 9))
>A : Symbol(A, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 0, 0))
>p1 : Symbol(A.p1, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 0, 9))
static [A.p2]() { return 0 };
>[A.p2] : Symbol(A[A.p2], Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 4, 31))
>A.p2 : Symbol(A.p2, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 1, 34))
>A : Symbol(A, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 0, 0))
>p2 : Symbol(A.p2, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 1, 34))
[A.p1]() { }
>[A.p1] : Symbol(A[A.p1], Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 5, 33))
>A.p1 : Symbol(A.p1, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 0, 9))
>A : Symbol(A, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 0, 0))
>p1 : Symbol(A.p1, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 0, 9))
[A.p2] = 0
>[A.p2] : Symbol(A[A.p2], Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 6, 16))
>A.p2 : Symbol(A.p2, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 1, 34))
>A : Symbol(A, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 0, 0))
>p2 : Symbol(A.p2, Decl(classDeclarationShouldBeOutOfScopeInComputedNames.ts, 1, 34))
}
@@ -0,0 +1,43 @@
=== tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts ===
class A {
>A : A
static readonly p1 = Symbol();
>p1 : unique symbol
>Symbol() : unique symbol
>Symbol : SymbolConstructor
static readonly p2 = Symbol();
>p2 : unique symbol
>Symbol() : unique symbol
>Symbol : SymbolConstructor
// All of the below should be out of scope or TDZ - `A` has not finished being constructed as they are executed
static readonly [A.p1] = 0;
>[A.p1] : 0
>A.p1 : unique symbol
>A : typeof A
>p1 : unique symbol
>0 : 0
static [A.p2]() { return 0 };
>[A.p2] : () => number
>A.p2 : unique symbol
>A : typeof A
>p2 : unique symbol
>0 : 0
[A.p1]() { }
>[A.p1] : () => void
>A.p1 : unique symbol
>A : typeof A
>p1 : unique symbol
[A.p2] = 0
>[A.p2] : number
>A.p2 : unique symbol
>A : typeof A
>p2 : unique symbol
>0 : 0
}
@@ -0,0 +1,22 @@
tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticProperty.ts(3,10): error TS2449: Class 'C' used before its declaration.
tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticProperty.ts(6,10): error TS2449: Class 'C' used before its declaration.
tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticProperty.ts(9,6): error TS2449: Class 'C' used before its declaration.
==== tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticProperty.ts (3 errors) ====
class C {
static staticProp = 10;
get [C.staticProp]() {
~
!!! error TS2449: Class 'C' used before its declaration.
return "hello";
}
set [C.staticProp](x: string) {
~
!!! error TS2449: Class 'C' used before its declaration.
var y = x;
}
[C.staticProp]() { }
~
!!! error TS2449: Class 'C' used before its declaration.
}
@@ -0,0 +1,36 @@
tests/cases/compiler/controlFlowNullTypeAndLiteral.ts(15,12): error TS2345: Argument of type 'null' is not assignable to parameter of type 'number'.
tests/cases/compiler/controlFlowNullTypeAndLiteral.ts(17,12): error TS2345: Argument of type 'null' is not assignable to parameter of type 'number'.
tests/cases/compiler/controlFlowNullTypeAndLiteral.ts(21,15): error TS2322: Type 'null' is not assignable to type 'string'.
==== tests/cases/compiler/controlFlowNullTypeAndLiteral.ts (3 errors) ====
// Repros from #23771
const myNull: null = null;
const objWithValMaybeNull: { val: number | null } = { val: 1 };
const addOne = function (num: number) {
return num + 1;
}
if (objWithValMaybeNull.val !== null)
addOne(objWithValMaybeNull.val);
if (objWithValMaybeNull.val !== myNull)
addOne(objWithValMaybeNull.val);
if (objWithValMaybeNull.val === null)
addOne(objWithValMaybeNull.val); // Error
~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2345: Argument of type 'null' is not assignable to parameter of type 'number'.
if (objWithValMaybeNull.val === myNull)
addOne(objWithValMaybeNull.val); // Error
~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2345: Argument of type 'null' is not assignable to parameter of type 'number'.
function f(x: number | null) {
if(x === myNull) {
const s: string = x; // Error
~
!!! error TS2322: Type 'null' is not assignable to type 'string'.
}
}
@@ -0,0 +1,47 @@
//// [controlFlowNullTypeAndLiteral.ts]
// Repros from #23771
const myNull: null = null;
const objWithValMaybeNull: { val: number | null } = { val: 1 };
const addOne = function (num: number) {
return num + 1;
}
if (objWithValMaybeNull.val !== null)
addOne(objWithValMaybeNull.val);
if (objWithValMaybeNull.val !== myNull)
addOne(objWithValMaybeNull.val);
if (objWithValMaybeNull.val === null)
addOne(objWithValMaybeNull.val); // Error
if (objWithValMaybeNull.val === myNull)
addOne(objWithValMaybeNull.val); // Error
function f(x: number | null) {
if(x === myNull) {
const s: string = x; // Error
}
}
//// [controlFlowNullTypeAndLiteral.js]
"use strict";
// Repros from #23771
var myNull = null;
var objWithValMaybeNull = { val: 1 };
var addOne = function (num) {
return num + 1;
};
if (objWithValMaybeNull.val !== null)
addOne(objWithValMaybeNull.val);
if (objWithValMaybeNull.val !== myNull)
addOne(objWithValMaybeNull.val);
if (objWithValMaybeNull.val === null)
addOne(objWithValMaybeNull.val); // Error
if (objWithValMaybeNull.val === myNull)
addOne(objWithValMaybeNull.val); // Error
function f(x) {
if (x === myNull) {
var s = x; // Error
}
}
@@ -0,0 +1,79 @@
=== tests/cases/compiler/controlFlowNullTypeAndLiteral.ts ===
// Repros from #23771
const myNull: null = null;
>myNull : Symbol(myNull, Decl(controlFlowNullTypeAndLiteral.ts, 2, 5))
const objWithValMaybeNull: { val: number | null } = { val: 1 };
>objWithValMaybeNull : Symbol(objWithValMaybeNull, Decl(controlFlowNullTypeAndLiteral.ts, 3, 5))
>val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
>val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 53))
const addOne = function (num: number) {
>addOne : Symbol(addOne, Decl(controlFlowNullTypeAndLiteral.ts, 4, 5))
>num : Symbol(num, Decl(controlFlowNullTypeAndLiteral.ts, 4, 25))
return num + 1;
>num : Symbol(num, Decl(controlFlowNullTypeAndLiteral.ts, 4, 25))
}
if (objWithValMaybeNull.val !== null)
>objWithValMaybeNull.val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
>objWithValMaybeNull : Symbol(objWithValMaybeNull, Decl(controlFlowNullTypeAndLiteral.ts, 3, 5))
>val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
addOne(objWithValMaybeNull.val);
>addOne : Symbol(addOne, Decl(controlFlowNullTypeAndLiteral.ts, 4, 5))
>objWithValMaybeNull.val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
>objWithValMaybeNull : Symbol(objWithValMaybeNull, Decl(controlFlowNullTypeAndLiteral.ts, 3, 5))
>val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
if (objWithValMaybeNull.val !== myNull)
>objWithValMaybeNull.val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
>objWithValMaybeNull : Symbol(objWithValMaybeNull, Decl(controlFlowNullTypeAndLiteral.ts, 3, 5))
>val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
>myNull : Symbol(myNull, Decl(controlFlowNullTypeAndLiteral.ts, 2, 5))
addOne(objWithValMaybeNull.val);
>addOne : Symbol(addOne, Decl(controlFlowNullTypeAndLiteral.ts, 4, 5))
>objWithValMaybeNull.val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
>objWithValMaybeNull : Symbol(objWithValMaybeNull, Decl(controlFlowNullTypeAndLiteral.ts, 3, 5))
>val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
if (objWithValMaybeNull.val === null)
>objWithValMaybeNull.val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
>objWithValMaybeNull : Symbol(objWithValMaybeNull, Decl(controlFlowNullTypeAndLiteral.ts, 3, 5))
>val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
addOne(objWithValMaybeNull.val); // Error
>addOne : Symbol(addOne, Decl(controlFlowNullTypeAndLiteral.ts, 4, 5))
>objWithValMaybeNull.val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
>objWithValMaybeNull : Symbol(objWithValMaybeNull, Decl(controlFlowNullTypeAndLiteral.ts, 3, 5))
>val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
if (objWithValMaybeNull.val === myNull)
>objWithValMaybeNull.val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
>objWithValMaybeNull : Symbol(objWithValMaybeNull, Decl(controlFlowNullTypeAndLiteral.ts, 3, 5))
>val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
>myNull : Symbol(myNull, Decl(controlFlowNullTypeAndLiteral.ts, 2, 5))
addOne(objWithValMaybeNull.val); // Error
>addOne : Symbol(addOne, Decl(controlFlowNullTypeAndLiteral.ts, 4, 5))
>objWithValMaybeNull.val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
>objWithValMaybeNull : Symbol(objWithValMaybeNull, Decl(controlFlowNullTypeAndLiteral.ts, 3, 5))
>val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
function f(x: number | null) {
>f : Symbol(f, Decl(controlFlowNullTypeAndLiteral.ts, 16, 36))
>x : Symbol(x, Decl(controlFlowNullTypeAndLiteral.ts, 18, 11))
if(x === myNull) {
>x : Symbol(x, Decl(controlFlowNullTypeAndLiteral.ts, 18, 11))
>myNull : Symbol(myNull, Decl(controlFlowNullTypeAndLiteral.ts, 2, 5))
const s: string = x; // Error
>s : Symbol(s, Decl(controlFlowNullTypeAndLiteral.ts, 20, 13))
>x : Symbol(x, Decl(controlFlowNullTypeAndLiteral.ts, 18, 11))
}
}
@@ -0,0 +1,99 @@
=== tests/cases/compiler/controlFlowNullTypeAndLiteral.ts ===
// Repros from #23771
const myNull: null = null;
>myNull : null
>null : null
>null : null
const objWithValMaybeNull: { val: number | null } = { val: 1 };
>objWithValMaybeNull : { val: number | null; }
>val : number | null
>null : null
>{ val: 1 } : { val: number; }
>val : number
>1 : 1
const addOne = function (num: number) {
>addOne : (num: number) => number
>function (num: number) { return num + 1;} : (num: number) => number
>num : number
return num + 1;
>num + 1 : number
>num : number
>1 : 1
}
if (objWithValMaybeNull.val !== null)
>objWithValMaybeNull.val !== null : boolean
>objWithValMaybeNull.val : number | null
>objWithValMaybeNull : { val: number | null; }
>val : number | null
>null : null
addOne(objWithValMaybeNull.val);
>addOne(objWithValMaybeNull.val) : number
>addOne : (num: number) => number
>objWithValMaybeNull.val : number
>objWithValMaybeNull : { val: number | null; }
>val : number
if (objWithValMaybeNull.val !== myNull)
>objWithValMaybeNull.val !== myNull : boolean
>objWithValMaybeNull.val : number | null
>objWithValMaybeNull : { val: number | null; }
>val : number | null
>myNull : null
addOne(objWithValMaybeNull.val);
>addOne(objWithValMaybeNull.val) : number
>addOne : (num: number) => number
>objWithValMaybeNull.val : number
>objWithValMaybeNull : { val: number | null; }
>val : number
if (objWithValMaybeNull.val === null)
>objWithValMaybeNull.val === null : boolean
>objWithValMaybeNull.val : number | null
>objWithValMaybeNull : { val: number | null; }
>val : number | null
>null : null
addOne(objWithValMaybeNull.val); // Error
>addOne(objWithValMaybeNull.val) : number
>addOne : (num: number) => number
>objWithValMaybeNull.val : null
>objWithValMaybeNull : { val: number | null; }
>val : null
if (objWithValMaybeNull.val === myNull)
>objWithValMaybeNull.val === myNull : boolean
>objWithValMaybeNull.val : number | null
>objWithValMaybeNull : { val: number | null; }
>val : number | null
>myNull : null
addOne(objWithValMaybeNull.val); // Error
>addOne(objWithValMaybeNull.val) : number
>addOne : (num: number) => number
>objWithValMaybeNull.val : null
>objWithValMaybeNull : { val: number | null; }
>val : null
function f(x: number | null) {
>f : (x: number | null) => void
>x : number | null
>null : null
if(x === myNull) {
>x === myNull : boolean
>x : number | null
>myNull : null
const s: string = x; // Error
>s : string
>x : null
}
}
@@ -5,5 +5,6 @@ function foo(name) {
var s = require("t/" + name)
>s : Symbol(s, Decl(a.js, 1, 7))
>require : Symbol(require)
>name : Symbol(name, Decl(a.js, 0, 13))
}
@@ -0,0 +1,7 @@
//// [emptyArrayDestructuringExpressionVisitedByTransformer.ts]
var a = [] = [1].map(_ => _);
var b = [1].map(_ => _);
//// [emptyArrayDestructuringExpressionVisitedByTransformer.js]
var a = [1].map(function (_) { return _; });
var b = [1].map(function (_) { return _; });
@@ -0,0 +1,15 @@
=== tests/cases/compiler/emptyArrayDestructuringExpressionVisitedByTransformer.ts ===
var a = [] = [1].map(_ => _);
>a : Symbol(a, Decl(emptyArrayDestructuringExpressionVisitedByTransformer.ts, 0, 3))
>[1].map : Symbol(Array.map, Decl(lib.d.ts, --, --))
>map : Symbol(Array.map, Decl(lib.d.ts, --, --))
>_ : Symbol(_, Decl(emptyArrayDestructuringExpressionVisitedByTransformer.ts, 0, 21))
>_ : Symbol(_, Decl(emptyArrayDestructuringExpressionVisitedByTransformer.ts, 0, 21))
var b = [1].map(_ => _);
>b : Symbol(b, Decl(emptyArrayDestructuringExpressionVisitedByTransformer.ts, 1, 3))
>[1].map : Symbol(Array.map, Decl(lib.d.ts, --, --))
>map : Symbol(Array.map, Decl(lib.d.ts, --, --))
>_ : Symbol(_, Decl(emptyArrayDestructuringExpressionVisitedByTransformer.ts, 1, 16))
>_ : Symbol(_, Decl(emptyArrayDestructuringExpressionVisitedByTransformer.ts, 1, 16))
@@ -0,0 +1,25 @@
=== tests/cases/compiler/emptyArrayDestructuringExpressionVisitedByTransformer.ts ===
var a = [] = [1].map(_ => _);
>a : number[]
>[] = [1].map(_ => _) : number[]
>[] : undefined[]
>[1].map(_ => _) : number[]
>[1].map : <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]
>[1] : number[]
>1 : 1
>map : <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]
>_ => _ : (_: number) => number
>_ : number
>_ : number
var b = [1].map(_ => _);
>b : number[]
>[1].map(_ => _) : number[]
>[1].map : <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]
>[1] : number[]
>1 : 1
>map : <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]
>_ => _ : (_: number) => number
>_ : number
>_ : number
@@ -1,11 +1,9 @@
tests/cases/compiler/errorMessagesIntersectionTypes04.ts(17,5): error TS2322: Type 'A & B' is not assignable to type 'number'.
tests/cases/compiler/errorMessagesIntersectionTypes04.ts(18,5): error TS2322: Type 'A & B' is not assignable to type 'boolean'.
tests/cases/compiler/errorMessagesIntersectionTypes04.ts(19,5): error TS2322: Type 'A & B' is not assignable to type 'string'.
tests/cases/compiler/errorMessagesIntersectionTypes04.ts(21,5): error TS2322: Type '(number & true) | (number & false)' is not assignable to type 'string'.
Type 'number & true' is not assignable to type 'string'.
==== tests/cases/compiler/errorMessagesIntersectionTypes04.ts (4 errors) ====
==== tests/cases/compiler/errorMessagesIntersectionTypes04.ts (3 errors) ====
interface A {
a;
}
@@ -33,7 +31,4 @@ tests/cases/compiler/errorMessagesIntersectionTypes04.ts(21,5): error TS2322: Ty
!!! error TS2322: Type 'A & B' is not assignable to type 'string'.
str = num_and_bool;
~~~
!!! error TS2322: Type '(number & true) | (number & false)' is not assignable to type 'string'.
!!! error TS2322: Type 'number & true' is not assignable to type 'string'.
}
@@ -36,7 +36,7 @@ function f<T, U extends A, V extends U>(): void {
>B : B
let num_and_bool: number & boolean;
>num_and_bool : (number & true) | (number & false)
>num_and_bool : never
num = a_and_b;
>num = a_and_b : A & B
@@ -54,7 +54,7 @@ function f<T, U extends A, V extends U>(): void {
>a_and_b : A & B
str = num_and_bool;
>str = num_and_bool : (number & true) | (number & false)
>str = num_and_bool : never
>str : string
>num_and_bool : (number & true) | (number & false)
>num_and_bool : never
}
@@ -0,0 +1,24 @@
tests/cases/compiler/user.ts(1,8): error TS2395: Individual declarations in merged declaration 'Obj' must be all exported or all local.
tests/cases/compiler/user.ts(1,8): error TS2440: Import declaration conflicts with local declaration of 'Obj'.
tests/cases/compiler/user.ts(3,14): error TS2395: Individual declarations in merged declaration 'Obj' must be all exported or all local.
tests/cases/compiler/user.ts(3,25): error TS2448: Block-scoped variable 'Obj' used before its declaration.
==== tests/cases/compiler/assignment.ts (0 errors) ====
export default {
foo: 12
};
==== tests/cases/compiler/user.ts (4 errors) ====
import Obj from "./assignment";
~~~
!!! error TS2395: Individual declarations in merged declaration 'Obj' must be all exported or all local.
~~~
!!! error TS2440: Import declaration conflicts with local declaration of 'Obj'.
export const Obj = void Obj;
~~~
!!! error TS2395: Individual declarations in merged declaration 'Obj' must be all exported or all local.
~~~
!!! error TS2448: Block-scoped variable 'Obj' used before its declaration.
@@ -0,0 +1,24 @@
//// [tests/cases/compiler/exportAssignmentImportMergeNoCrash.ts] ////
//// [assignment.ts]
export default {
foo: 12
};
//// [user.ts]
import Obj from "./assignment";
export const Obj = void Obj;
//// [assignment.js]
"use strict";
exports.__esModule = true;
exports["default"] = {
foo: 12
};
//// [user.js]
"use strict";
exports.__esModule = true;
var assignment_1 = require("./assignment");
exports.Obj = void exports.Obj;
@@ -0,0 +1,15 @@
=== tests/cases/compiler/assignment.ts ===
export default {
foo: 12
>foo : Symbol(foo, Decl(assignment.ts, 0, 16))
};
=== tests/cases/compiler/user.ts ===
import Obj from "./assignment";
>Obj : Symbol(Obj, Decl(user.ts, 0, 6), Decl(user.ts, 2, 12))
export const Obj = void Obj;
>Obj : Symbol(Obj, Decl(user.ts, 2, 12))
>Obj : Symbol(Obj, Decl(user.ts, 0, 6), Decl(user.ts, 2, 12))
@@ -0,0 +1,19 @@
=== tests/cases/compiler/assignment.ts ===
export default {
>{ foo: 12} : { foo: number; }
foo: 12
>foo : number
>12 : 12
};
=== tests/cases/compiler/user.ts ===
import Obj from "./assignment";
>Obj : { foo: number; }
export const Obj = void Obj;
>Obj : any
>void Obj : undefined
>Obj : any
@@ -1,25 +1,19 @@
tests/cases/conformance/salsa/first.js(1,11): error TS2304: Cannot find name 'require'.
tests/cases/conformance/salsa/first.js(2,9): error TS2339: Property 'formatters' does not exist on type 'typeof import("tests/cases/conformance/salsa/first")'.
tests/cases/conformance/salsa/second.js(1,11): error TS2304: Cannot find name 'require'.
tests/cases/conformance/salsa/second.js(2,9): error TS2339: Property 'formatters' does not exist on type 'typeof import("tests/cases/conformance/salsa/second")'.
==== tests/cases/conformance/salsa/mod.js (0 errors) ====
// Based on a pattern from adonis
exports.formatters = {}
==== tests/cases/conformance/salsa/first.js (2 errors) ====
==== tests/cases/conformance/salsa/first.js (1 errors) ====
exports = require('./mod')
~~~~~~~
!!! error TS2304: Cannot find name 'require'.
exports.formatters.j = function (v) {
~~~~~~~~~~
!!! error TS2339: Property 'formatters' does not exist on type 'typeof import("tests/cases/conformance/salsa/first")'.
return v
}
==== tests/cases/conformance/salsa/second.js (2 errors) ====
==== tests/cases/conformance/salsa/second.js (1 errors) ====
exports = require('./mod')
~~~~~~~
!!! error TS2304: Cannot find name 'require'.
exports.formatters.o = function (v) {
~~~~~~~~~~
!!! error TS2339: Property 'formatters' does not exist on type 'typeof import("tests/cases/conformance/salsa/second")'.
@@ -8,6 +8,7 @@ exports.formatters = {}
=== tests/cases/conformance/salsa/first.js ===
exports = require('./mod')
>exports : Symbol("tests/cases/conformance/salsa/first", Decl(first.js, 0, 0))
>require : Symbol(require)
>'./mod' : Symbol("tests/cases/conformance/salsa/mod", Decl(mod.js, 0, 0))
exports.formatters.j = function (v) {
@@ -20,6 +21,7 @@ exports.formatters.j = function (v) {
=== tests/cases/conformance/salsa/second.js ===
exports = require('./mod')
>exports : Symbol("tests/cases/conformance/salsa/second", Decl(second.js, 0, 0))
>require : Symbol(require)
>'./mod' : Symbol("tests/cases/conformance/salsa/mod", Decl(mod.js, 0, 0))
exports.formatters.o = function (v) {
@@ -0,0 +1,71 @@
error TS2468: Cannot find global value 'Promise'.
tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,44): error TS2339: Property 'blah' does not exist on type 'ImportMeta'.
tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,63): error TS2339: Property 'blue' does not exist on type 'ImportMeta'.
tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(2,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access.
tests/cases/conformance/es2019/importMeta/example.ts(2,2): error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option.
tests/cases/conformance/es2019/importMeta/example.ts(3,71): error TS2339: Property 'url' does not exist on type 'ImportMeta'.
tests/cases/conformance/es2019/importMeta/example.ts(6,28): error TS2339: Property 'scriptElement' does not exist on type 'ImportMeta'.
tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(2,23): error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'?
tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,23): error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'?
tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(2,22): error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'?
tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,22): error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'?
!!! error TS2468: Cannot find global value 'Promise'.
==== tests/cases/conformance/es2019/importMeta/example.ts (3 errors) ====
// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example
(async () => {
~~~~~~~~~~~~~
!!! error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option.
const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString());
~~~
!!! error TS2339: Property 'url' does not exist on type 'ImportMeta'.
const blob = await response.blob();
const size = import.meta.scriptElement.dataset.size || 300;
~~~~~~~~~~~~~
!!! error TS2339: Property 'scriptElement' does not exist on type 'ImportMeta'.
const image = new Image();
image.src = URL.createObjectURL(blob);
image.width = image.height = size;
document.body.appendChild(image);
})();
==== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts (2 errors) ====
export let x = import.meta;
export let y = import.metal;
~~~~~
!!! error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'?
export let z = import.import.import.malkovich;
~~~~~~
!!! error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'?
==== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts (2 errors) ====
let globalA = import.meta;
let globalB = import.metal;
~~~~~
!!! error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'?
let globalC = import.import.import.malkovich;
~~~~~~
!!! error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'?
==== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts (3 errors) ====
export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta;
~~~~
!!! error TS2339: Property 'blah' does not exist on type 'ImportMeta'.
~~~~
!!! error TS2339: Property 'blue' does not exist on type 'ImportMeta'.
import.meta = foo;
~~~~~~~~~~~
!!! error TS2364: The left-hand side of an assignment expression must be a variable or a property access.
// @Filename augmentations.ts
declare global {
interface ImportMeta {
wellKnownProperty: { a: number, b: string, c: boolean };
}
}
const { a, b, c } = import.meta.wellKnownProperty;
+63
View File
@@ -0,0 +1,63 @@
//// [tests/cases/conformance/es2019/importMeta/importMeta.ts] ////
//// [example.ts]
// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example
(async () => {
const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString());
const blob = await response.blob();
const size = import.meta.scriptElement.dataset.size || 300;
const image = new Image();
image.src = URL.createObjectURL(blob);
image.width = image.height = size;
document.body.appendChild(image);
})();
//// [moduleLookingFile01.ts]
export let x = import.meta;
export let y = import.metal;
export let z = import.import.import.malkovich;
//// [scriptLookingFile01.ts]
let globalA = import.meta;
let globalB = import.metal;
let globalC = import.import.import.malkovich;
//// [assignmentTargets.ts]
export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta;
import.meta = foo;
// @Filename augmentations.ts
declare global {
interface ImportMeta {
wellKnownProperty: { a: number, b: string, c: boolean };
}
}
const { a, b, c } = import.meta.wellKnownProperty;
//// [example.js]
// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example
(async () => {
const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString());
const blob = await response.blob();
const size = import.meta.scriptElement.dataset.size || 300;
const image = new Image();
image.src = URL.createObjectURL(blob);
image.width = image.height = size;
document.body.appendChild(image);
})();
//// [moduleLookingFile01.js]
export let x = import.meta;
export let y = import.metal;
export let z = import.import.import.malkovich;
//// [scriptLookingFile01.js]
let globalA = import.meta;
let globalB = import.metal;
let globalC = import.import.import.malkovich;
//// [assignmentTargets.js]
export const foo = import.meta.blah = import.meta.blue = import.meta;
import.meta = foo;
const { a, b, c } = import.meta.wellKnownProperty;
@@ -0,0 +1,101 @@
=== tests/cases/conformance/es2019/importMeta/example.ts ===
// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example
(async () => {
const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString());
>response : Symbol(response, Decl(example.ts, 2, 7))
>fetch : Symbol(fetch, Decl(lib.dom.d.ts, --, --))
>new URL("../hamsters.jpg", import.meta.url).toString : Symbol(URL.toString, Decl(lib.dom.d.ts, --, --))
>URL : Symbol(URL, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
>toString : Symbol(URL.toString, Decl(lib.dom.d.ts, --, --))
const blob = await response.blob();
>blob : Symbol(blob, Decl(example.ts, 3, 7))
>response.blob : Symbol(Body.blob, Decl(lib.dom.d.ts, --, --))
>response : Symbol(response, Decl(example.ts, 2, 7))
>blob : Symbol(Body.blob, Decl(lib.dom.d.ts, --, --))
const size = import.meta.scriptElement.dataset.size || 300;
>size : Symbol(size, Decl(example.ts, 5, 7))
const image = new Image();
>image : Symbol(image, Decl(example.ts, 7, 7))
>Image : Symbol(Image, Decl(lib.dom.d.ts, --, --))
image.src = URL.createObjectURL(blob);
>image.src : Symbol(HTMLImageElement.src, Decl(lib.dom.d.ts, --, --))
>image : Symbol(image, Decl(example.ts, 7, 7))
>src : Symbol(HTMLImageElement.src, Decl(lib.dom.d.ts, --, --))
>URL.createObjectURL : Symbol(createObjectURL, Decl(lib.dom.d.ts, --, --))
>URL : Symbol(URL, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
>createObjectURL : Symbol(createObjectURL, Decl(lib.dom.d.ts, --, --))
>blob : Symbol(blob, Decl(example.ts, 3, 7))
image.width = image.height = size;
>image.width : Symbol(HTMLImageElement.width, Decl(lib.dom.d.ts, --, --))
>image : Symbol(image, Decl(example.ts, 7, 7))
>width : Symbol(HTMLImageElement.width, Decl(lib.dom.d.ts, --, --))
>image.height : Symbol(HTMLImageElement.height, Decl(lib.dom.d.ts, --, --))
>image : Symbol(image, Decl(example.ts, 7, 7))
>height : Symbol(HTMLImageElement.height, Decl(lib.dom.d.ts, --, --))
>size : Symbol(size, Decl(example.ts, 5, 7))
document.body.appendChild(image);
>document.body.appendChild : Symbol(Node.appendChild, Decl(lib.dom.d.ts, --, --))
>document.body : Symbol(Document.body, Decl(lib.dom.d.ts, --, --))
>document : Symbol(document, Decl(lib.dom.d.ts, --, --))
>body : Symbol(Document.body, Decl(lib.dom.d.ts, --, --))
>appendChild : Symbol(Node.appendChild, Decl(lib.dom.d.ts, --, --))
>image : Symbol(image, Decl(example.ts, 7, 7))
})();
=== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts ===
export let x = import.meta;
>x : Symbol(x, Decl(moduleLookingFile01.ts, 0, 10))
export let y = import.metal;
>y : Symbol(y, Decl(moduleLookingFile01.ts, 1, 10))
export let z = import.import.import.malkovich;
>z : Symbol(z, Decl(moduleLookingFile01.ts, 2, 10))
=== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts ===
let globalA = import.meta;
>globalA : Symbol(globalA, Decl(scriptLookingFile01.ts, 0, 3))
let globalB = import.metal;
>globalB : Symbol(globalB, Decl(scriptLookingFile01.ts, 1, 3))
let globalC = import.import.import.malkovich;
>globalC : Symbol(globalC, Decl(scriptLookingFile01.ts, 2, 3))
=== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts ===
export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta;
>foo : Symbol(foo, Decl(assignmentTargets.ts, 0, 12))
>ImportMeta : Symbol(ImportMeta, Decl(lib.es5.d.ts, --, --), Decl(assignmentTargets.ts, 4, 16))
import.meta = foo;
>foo : Symbol(foo, Decl(assignmentTargets.ts, 0, 12))
// @Filename augmentations.ts
declare global {
>global : Symbol(global, Decl(assignmentTargets.ts, 1, 18))
interface ImportMeta {
>ImportMeta : Symbol(ImportMeta, Decl(lib.es5.d.ts, --, --), Decl(assignmentTargets.ts, 4, 16))
wellKnownProperty: { a: number, b: string, c: boolean };
>wellKnownProperty : Symbol(ImportMeta.wellKnownProperty, Decl(assignmentTargets.ts, 5, 24))
>a : Symbol(a, Decl(assignmentTargets.ts, 6, 24))
>b : Symbol(b, Decl(assignmentTargets.ts, 6, 35))
>c : Symbol(c, Decl(assignmentTargets.ts, 6, 46))
}
}
const { a, b, c } = import.meta.wellKnownProperty;
>a : Symbol(a, Decl(assignmentTargets.ts, 10, 7))
>b : Symbol(b, Decl(assignmentTargets.ts, 10, 10))
>c : Symbol(c, Decl(assignmentTargets.ts, 10, 13))
>import.meta.wellKnownProperty : Symbol(ImportMeta.wellKnownProperty, Decl(assignmentTargets.ts, 5, 24))
>wellKnownProperty : Symbol(ImportMeta.wellKnownProperty, Decl(assignmentTargets.ts, 5, 24))
+169
View File
@@ -0,0 +1,169 @@
=== tests/cases/conformance/es2019/importMeta/example.ts ===
// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example
(async () => {
>(async () => { const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; const image = new Image(); image.src = URL.createObjectURL(blob); image.width = image.height = size; document.body.appendChild(image);})() : Promise<void>
>(async () => { const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; const image = new Image(); image.src = URL.createObjectURL(blob); image.width = image.height = size; document.body.appendChild(image);}) : () => Promise<void>
>async () => { const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; const image = new Image(); image.src = URL.createObjectURL(blob); image.width = image.height = size; document.body.appendChild(image);} : () => Promise<void>
const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString());
>response : Response
>await fetch(new URL("../hamsters.jpg", import.meta.url).toString()) : Response
>fetch(new URL("../hamsters.jpg", import.meta.url).toString()) : Promise<Response>
>fetch : (input?: string | Request, init?: RequestInit) => Promise<Response>
>new URL("../hamsters.jpg", import.meta.url).toString() : string
>new URL("../hamsters.jpg", import.meta.url).toString : () => string
>new URL("../hamsters.jpg", import.meta.url) : URL
>URL : { new (url: string, base?: string | URL): URL; prototype: URL; createObjectURL(object: any, options?: ObjectURLOptions): string; revokeObjectURL(url: string): void; }
>"../hamsters.jpg" : "../hamsters.jpg"
>import.meta.url : any
>import.meta : ImportMeta
>meta : any
>url : any
>toString : () => string
const blob = await response.blob();
>blob : Blob
>await response.blob() : Blob
>response.blob() : Promise<Blob>
>response.blob : () => Promise<Blob>
>response : Response
>blob : () => Promise<Blob>
const size = import.meta.scriptElement.dataset.size || 300;
>size : any
>import.meta.scriptElement.dataset.size || 300 : any
>import.meta.scriptElement.dataset.size : any
>import.meta.scriptElement.dataset : any
>import.meta.scriptElement : any
>import.meta : ImportMeta
>meta : any
>scriptElement : any
>dataset : any
>size : any
>300 : 300
const image = new Image();
>image : HTMLImageElement
>new Image() : HTMLImageElement
>Image : new (width?: number, height?: number) => HTMLImageElement
image.src = URL.createObjectURL(blob);
>image.src = URL.createObjectURL(blob) : string
>image.src : string
>image : HTMLImageElement
>src : string
>URL.createObjectURL(blob) : string
>URL.createObjectURL : (object: any, options?: ObjectURLOptions) => string
>URL : { new (url: string, base?: string | URL): URL; prototype: URL; createObjectURL(object: any, options?: ObjectURLOptions): string; revokeObjectURL(url: string): void; }
>createObjectURL : (object: any, options?: ObjectURLOptions) => string
>blob : Blob
image.width = image.height = size;
>image.width = image.height = size : any
>image.width : number
>image : HTMLImageElement
>width : number
>image.height = size : any
>image.height : number
>image : HTMLImageElement
>height : number
>size : any
document.body.appendChild(image);
>document.body.appendChild(image) : HTMLImageElement
>document.body.appendChild : <T extends Node>(newChild: T) => T
>document.body : HTMLElement
>document : Document
>body : HTMLElement
>appendChild : <T extends Node>(newChild: T) => T
>image : HTMLImageElement
})();
=== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts ===
export let x = import.meta;
>x : ImportMeta
>import.meta : ImportMeta
>meta : any
export let y = import.metal;
>y : any
>import.metal : any
>metal : any
export let z = import.import.import.malkovich;
>z : any
>import.import.import.malkovich : any
>import.import.import : any
>import.import : any
>import : any
>import : any
>malkovich : any
=== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts ===
let globalA = import.meta;
>globalA : ImportMeta
>import.meta : ImportMeta
>meta : any
let globalB = import.metal;
>globalB : any
>import.metal : any
>metal : any
let globalC = import.import.import.malkovich;
>globalC : any
>import.import.import.malkovich : any
>import.import.import : any
>import.import : any
>import : any
>import : any
>malkovich : any
=== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts ===
export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta;
>foo : ImportMeta
>ImportMeta : ImportMeta
>import.meta.blah = import.meta.blue = import.meta : ImportMeta
>import.meta.blah : any
>import.meta : ImportMeta
>meta : any
>blah : any
>import.meta.blue = import.meta : ImportMeta
>import.meta.blue : any
>import.meta : ImportMeta
>meta : any
>blue : any
>import.meta : ImportMeta
>meta : any
import.meta = foo;
>import.meta = foo : ImportMeta
>import.meta : ImportMeta
>meta : any
>foo : ImportMeta
// @Filename augmentations.ts
declare global {
>global : any
interface ImportMeta {
>ImportMeta : ImportMeta
wellKnownProperty: { a: number, b: string, c: boolean };
>wellKnownProperty : { a: number; b: string; c: boolean; }
>a : number
>b : string
>c : boolean
}
}
const { a, b, c } = import.meta.wellKnownProperty;
>a : number
>b : string
>c : boolean
>import.meta.wellKnownProperty : { a: number; b: string; c: boolean; }
>import.meta : ImportMeta
>meta : any
>wellKnownProperty : { a: number; b: string; c: boolean; }
@@ -0,0 +1,110 @@
error TS2468: Cannot find global value 'Promise'.
tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,32): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,44): error TS2339: Property 'blah' does not exist on type 'ImportMeta'.
tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,51): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,63): error TS2339: Property 'blue' does not exist on type 'ImportMeta'.
tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,70): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(2,1): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(2,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access.
tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(11,21): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
tests/cases/conformance/es2019/importMeta/example.ts(2,2): error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option.
tests/cases/conformance/es2019/importMeta/example.ts(3,59): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
tests/cases/conformance/es2019/importMeta/example.ts(3,71): error TS2339: Property 'url' does not exist on type 'ImportMeta'.
tests/cases/conformance/es2019/importMeta/example.ts(6,16): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
tests/cases/conformance/es2019/importMeta/example.ts(6,28): error TS2339: Property 'scriptElement' does not exist on type 'ImportMeta'.
tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(1,16): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(2,16): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(2,23): error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'?
tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,16): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,23): error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'?
tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(1,15): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(2,15): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(2,22): error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'?
tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,15): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,22): error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'?
!!! error TS2468: Cannot find global value 'Promise'.
==== tests/cases/conformance/es2019/importMeta/example.ts (5 errors) ====
// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example
(async () => {
~~~~~~~~~~~~~
!!! error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option.
const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString());
~~~~~~~~~~~
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
~~~
!!! error TS2339: Property 'url' does not exist on type 'ImportMeta'.
const blob = await response.blob();
const size = import.meta.scriptElement.dataset.size || 300;
~~~~~~~~~~~
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
~~~~~~~~~~~~~
!!! error TS2339: Property 'scriptElement' does not exist on type 'ImportMeta'.
const image = new Image();
image.src = URL.createObjectURL(blob);
image.width = image.height = size;
document.body.appendChild(image);
})();
==== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts (5 errors) ====
export let x = import.meta;
~~~~~~~~~~~
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
export let y = import.metal;
~~~~~~~~~~~~
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
~~~~~
!!! error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'?
export let z = import.import.import.malkovich;
~~~~~~~~~~~~~
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
~~~~~~
!!! error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'?
==== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts (5 errors) ====
let globalA = import.meta;
~~~~~~~~~~~
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
let globalB = import.metal;
~~~~~~~~~~~~
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
~~~~~
!!! error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'?
let globalC = import.import.import.malkovich;
~~~~~~~~~~~~~
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
~~~~~~
!!! error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'?
==== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts (8 errors) ====
export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta;
~~~~~~~~~~~
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
~~~~
!!! error TS2339: Property 'blah' does not exist on type 'ImportMeta'.
~~~~~~~~~~~
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
~~~~
!!! error TS2339: Property 'blue' does not exist on type 'ImportMeta'.
~~~~~~~~~~~
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
import.meta = foo;
~~~~~~~~~~~
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
~~~~~~~~~~~
!!! error TS2364: The left-hand side of an assignment expression must be a variable or a property access.
// @Filename augmentations.ts
declare global {
interface ImportMeta {
wellKnownProperty: { a: number, b: string, c: boolean };
}
}
const { a, b, c } = import.meta.wellKnownProperty;
~~~~~~~~~~~
!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.
+117
View File
@@ -0,0 +1,117 @@
//// [tests/cases/conformance/es2019/importMeta/importMetaES5.ts] ////
//// [example.ts]
// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example
(async () => {
const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString());
const blob = await response.blob();
const size = import.meta.scriptElement.dataset.size || 300;
const image = new Image();
image.src = URL.createObjectURL(blob);
image.width = image.height = size;
document.body.appendChild(image);
})();
//// [moduleLookingFile01.ts]
export let x = import.meta;
export let y = import.metal;
export let z = import.import.import.malkovich;
//// [scriptLookingFile01.ts]
let globalA = import.meta;
let globalB = import.metal;
let globalC = import.import.import.malkovich;
//// [assignmentTargets.ts]
export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta;
import.meta = foo;
// @Filename augmentations.ts
declare global {
interface ImportMeta {
wellKnownProperty: { a: number, b: string, c: boolean };
}
}
const { a, b, c } = import.meta.wellKnownProperty;
//// [example.js]
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [0, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var _this = this;
Object.defineProperty(exports, "__esModule", { value: true });
// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example
(function () { return __awaiter(_this, void 0, void 0, function () {
var response, blob, size, image;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, fetch(new URL("../hamsters.jpg", import.meta.url).toString())];
case 1:
response = _a.sent();
return [4 /*yield*/, response.blob()];
case 2:
blob = _a.sent();
size = import.meta.scriptElement.dataset.size || 300;
image = new Image();
image.src = URL.createObjectURL(blob);
image.width = image.height = size;
document.body.appendChild(image);
return [2 /*return*/];
}
});
}); })();
//// [moduleLookingFile01.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.x = (import.meta);
exports.y = (import.metal);
exports.z = import.import.import.malkovich;
//// [scriptLookingFile01.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var globalA = import.meta;
var globalB = import.metal;
var globalC = import.import.import.malkovich;
//// [assignmentTargets.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.foo = import.meta.blah = import.meta.blue = import.meta;
import.meta = exports.foo;
var _a = import.meta.wellKnownProperty, a = _a.a, b = _a.b, c = _a.c;
@@ -0,0 +1,101 @@
=== tests/cases/conformance/es2019/importMeta/example.ts ===
// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example
(async () => {
const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString());
>response : Symbol(response, Decl(example.ts, 2, 7))
>fetch : Symbol(fetch, Decl(lib.dom.d.ts, --, --))
>new URL("../hamsters.jpg", import.meta.url).toString : Symbol(URL.toString, Decl(lib.dom.d.ts, --, --))
>URL : Symbol(URL, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
>toString : Symbol(URL.toString, Decl(lib.dom.d.ts, --, --))
const blob = await response.blob();
>blob : Symbol(blob, Decl(example.ts, 3, 7))
>response.blob : Symbol(Body.blob, Decl(lib.dom.d.ts, --, --))
>response : Symbol(response, Decl(example.ts, 2, 7))
>blob : Symbol(Body.blob, Decl(lib.dom.d.ts, --, --))
const size = import.meta.scriptElement.dataset.size || 300;
>size : Symbol(size, Decl(example.ts, 5, 7))
const image = new Image();
>image : Symbol(image, Decl(example.ts, 7, 7))
>Image : Symbol(Image, Decl(lib.dom.d.ts, --, --))
image.src = URL.createObjectURL(blob);
>image.src : Symbol(HTMLImageElement.src, Decl(lib.dom.d.ts, --, --))
>image : Symbol(image, Decl(example.ts, 7, 7))
>src : Symbol(HTMLImageElement.src, Decl(lib.dom.d.ts, --, --))
>URL.createObjectURL : Symbol(createObjectURL, Decl(lib.dom.d.ts, --, --))
>URL : Symbol(URL, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
>createObjectURL : Symbol(createObjectURL, Decl(lib.dom.d.ts, --, --))
>blob : Symbol(blob, Decl(example.ts, 3, 7))
image.width = image.height = size;
>image.width : Symbol(HTMLImageElement.width, Decl(lib.dom.d.ts, --, --))
>image : Symbol(image, Decl(example.ts, 7, 7))
>width : Symbol(HTMLImageElement.width, Decl(lib.dom.d.ts, --, --))
>image.height : Symbol(HTMLImageElement.height, Decl(lib.dom.d.ts, --, --))
>image : Symbol(image, Decl(example.ts, 7, 7))
>height : Symbol(HTMLImageElement.height, Decl(lib.dom.d.ts, --, --))
>size : Symbol(size, Decl(example.ts, 5, 7))
document.body.appendChild(image);
>document.body.appendChild : Symbol(Node.appendChild, Decl(lib.dom.d.ts, --, --))
>document.body : Symbol(Document.body, Decl(lib.dom.d.ts, --, --))
>document : Symbol(document, Decl(lib.dom.d.ts, --, --))
>body : Symbol(Document.body, Decl(lib.dom.d.ts, --, --))
>appendChild : Symbol(Node.appendChild, Decl(lib.dom.d.ts, --, --))
>image : Symbol(image, Decl(example.ts, 7, 7))
})();
=== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts ===
export let x = import.meta;
>x : Symbol(x, Decl(moduleLookingFile01.ts, 0, 10))
export let y = import.metal;
>y : Symbol(y, Decl(moduleLookingFile01.ts, 1, 10))
export let z = import.import.import.malkovich;
>z : Symbol(z, Decl(moduleLookingFile01.ts, 2, 10))
=== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts ===
let globalA = import.meta;
>globalA : Symbol(globalA, Decl(scriptLookingFile01.ts, 0, 3))
let globalB = import.metal;
>globalB : Symbol(globalB, Decl(scriptLookingFile01.ts, 1, 3))
let globalC = import.import.import.malkovich;
>globalC : Symbol(globalC, Decl(scriptLookingFile01.ts, 2, 3))
=== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts ===
export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta;
>foo : Symbol(foo, Decl(assignmentTargets.ts, 0, 12))
>ImportMeta : Symbol(ImportMeta, Decl(lib.es5.d.ts, --, --), Decl(assignmentTargets.ts, 4, 16))
import.meta = foo;
>foo : Symbol(foo, Decl(assignmentTargets.ts, 0, 12))
// @Filename augmentations.ts
declare global {
>global : Symbol(global, Decl(assignmentTargets.ts, 1, 18))
interface ImportMeta {
>ImportMeta : Symbol(ImportMeta, Decl(lib.es5.d.ts, --, --), Decl(assignmentTargets.ts, 4, 16))
wellKnownProperty: { a: number, b: string, c: boolean };
>wellKnownProperty : Symbol(ImportMeta.wellKnownProperty, Decl(assignmentTargets.ts, 5, 24))
>a : Symbol(a, Decl(assignmentTargets.ts, 6, 24))
>b : Symbol(b, Decl(assignmentTargets.ts, 6, 35))
>c : Symbol(c, Decl(assignmentTargets.ts, 6, 46))
}
}
const { a, b, c } = import.meta.wellKnownProperty;
>a : Symbol(a, Decl(assignmentTargets.ts, 10, 7))
>b : Symbol(b, Decl(assignmentTargets.ts, 10, 10))
>c : Symbol(c, Decl(assignmentTargets.ts, 10, 13))
>import.meta.wellKnownProperty : Symbol(ImportMeta.wellKnownProperty, Decl(assignmentTargets.ts, 5, 24))
>wellKnownProperty : Symbol(ImportMeta.wellKnownProperty, Decl(assignmentTargets.ts, 5, 24))
@@ -0,0 +1,169 @@
=== tests/cases/conformance/es2019/importMeta/example.ts ===
// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example
(async () => {
>(async () => { const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; const image = new Image(); image.src = URL.createObjectURL(blob); image.width = image.height = size; document.body.appendChild(image);})() : Promise<void>
>(async () => { const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; const image = new Image(); image.src = URL.createObjectURL(blob); image.width = image.height = size; document.body.appendChild(image);}) : () => Promise<void>
>async () => { const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; const image = new Image(); image.src = URL.createObjectURL(blob); image.width = image.height = size; document.body.appendChild(image);} : () => Promise<void>
const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString());
>response : Response
>await fetch(new URL("../hamsters.jpg", import.meta.url).toString()) : Response
>fetch(new URL("../hamsters.jpg", import.meta.url).toString()) : Promise<Response>
>fetch : (input?: string | Request, init?: RequestInit) => Promise<Response>
>new URL("../hamsters.jpg", import.meta.url).toString() : string
>new URL("../hamsters.jpg", import.meta.url).toString : () => string
>new URL("../hamsters.jpg", import.meta.url) : URL
>URL : { new (url: string, base?: string | URL): URL; prototype: URL; createObjectURL(object: any, options?: ObjectURLOptions): string; revokeObjectURL(url: string): void; }
>"../hamsters.jpg" : "../hamsters.jpg"
>import.meta.url : any
>import.meta : ImportMeta
>meta : any
>url : any
>toString : () => string
const blob = await response.blob();
>blob : Blob
>await response.blob() : Blob
>response.blob() : Promise<Blob>
>response.blob : () => Promise<Blob>
>response : Response
>blob : () => Promise<Blob>
const size = import.meta.scriptElement.dataset.size || 300;
>size : any
>import.meta.scriptElement.dataset.size || 300 : any
>import.meta.scriptElement.dataset.size : any
>import.meta.scriptElement.dataset : any
>import.meta.scriptElement : any
>import.meta : ImportMeta
>meta : any
>scriptElement : any
>dataset : any
>size : any
>300 : 300
const image = new Image();
>image : HTMLImageElement
>new Image() : HTMLImageElement
>Image : new (width?: number, height?: number) => HTMLImageElement
image.src = URL.createObjectURL(blob);
>image.src = URL.createObjectURL(blob) : string
>image.src : string
>image : HTMLImageElement
>src : string
>URL.createObjectURL(blob) : string
>URL.createObjectURL : (object: any, options?: ObjectURLOptions) => string
>URL : { new (url: string, base?: string | URL): URL; prototype: URL; createObjectURL(object: any, options?: ObjectURLOptions): string; revokeObjectURL(url: string): void; }
>createObjectURL : (object: any, options?: ObjectURLOptions) => string
>blob : Blob
image.width = image.height = size;
>image.width = image.height = size : any
>image.width : number
>image : HTMLImageElement
>width : number
>image.height = size : any
>image.height : number
>image : HTMLImageElement
>height : number
>size : any
document.body.appendChild(image);
>document.body.appendChild(image) : HTMLImageElement
>document.body.appendChild : <T extends Node>(newChild: T) => T
>document.body : HTMLElement
>document : Document
>body : HTMLElement
>appendChild : <T extends Node>(newChild: T) => T
>image : HTMLImageElement
})();
=== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts ===
export let x = import.meta;
>x : ImportMeta
>import.meta : ImportMeta
>meta : any
export let y = import.metal;
>y : any
>import.metal : any
>metal : any
export let z = import.import.import.malkovich;
>z : any
>import.import.import.malkovich : any
>import.import.import : any
>import.import : any
>import : any
>import : any
>malkovich : any
=== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts ===
let globalA = import.meta;
>globalA : ImportMeta
>import.meta : ImportMeta
>meta : any
let globalB = import.metal;
>globalB : any
>import.metal : any
>metal : any
let globalC = import.import.import.malkovich;
>globalC : any
>import.import.import.malkovich : any
>import.import.import : any
>import.import : any
>import : any
>import : any
>malkovich : any
=== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts ===
export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta;
>foo : ImportMeta
>ImportMeta : ImportMeta
>import.meta.blah = import.meta.blue = import.meta : ImportMeta
>import.meta.blah : any
>import.meta : ImportMeta
>meta : any
>blah : any
>import.meta.blue = import.meta : ImportMeta
>import.meta.blue : any
>import.meta : ImportMeta
>meta : any
>blue : any
>import.meta : ImportMeta
>meta : any
import.meta = foo;
>import.meta = foo : ImportMeta
>import.meta : ImportMeta
>meta : any
>foo : ImportMeta
// @Filename augmentations.ts
declare global {
>global : any
interface ImportMeta {
>ImportMeta : ImportMeta
wellKnownProperty: { a: number, b: string, c: boolean };
>wellKnownProperty : { a: number; b: string; c: boolean; }
>a : number
>b : string
>c : boolean
}
}
const { a, b, c } = import.meta.wellKnownProperty;
>a : number
>b : string
>c : boolean
>import.meta.wellKnownProperty : { a: number; b: string; c: boolean; }
>import.meta : ImportMeta
>meta : any
>wellKnownProperty : { a: number; b: string; c: boolean; }
@@ -0,0 +1,20 @@
//// [intersectionReduction.ts]
// @strict
declare const sym1: unique symbol;
declare const sym2: unique symbol;
type T1 = string & 'a'; // 'a'
type T2 = 'a' & string & 'b'; // 'a' & 'b'
type T3 = number & 10; // 10
type T4 = 10 & number & 20; // 10 & 20
type T5 = symbol & typeof sym1; // typeof sym1
type T6 = typeof sym1 & symbol & typeof sym2; // typeof sym1 & typeof sym2
type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // 'a' & 10 & typeof sym1
type T10 = string & ('a' | 'b'); // 'a' | 'b'
type T11 = (string | number) & ('a' | 10); // 'a' | 10
//// [intersectionReduction.js]
// @strict
@@ -0,0 +1,40 @@
=== tests/cases/conformance/types/intersection/intersectionReduction.ts ===
// @strict
declare const sym1: unique symbol;
>sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 2, 13))
declare const sym2: unique symbol;
>sym2 : Symbol(sym2, Decl(intersectionReduction.ts, 3, 13))
type T1 = string & 'a'; // 'a'
>T1 : Symbol(T1, Decl(intersectionReduction.ts, 3, 34))
type T2 = 'a' & string & 'b'; // 'a' & 'b'
>T2 : Symbol(T2, Decl(intersectionReduction.ts, 5, 23))
type T3 = number & 10; // 10
>T3 : Symbol(T3, Decl(intersectionReduction.ts, 6, 29))
type T4 = 10 & number & 20; // 10 & 20
>T4 : Symbol(T4, Decl(intersectionReduction.ts, 7, 22))
type T5 = symbol & typeof sym1; // typeof sym1
>T5 : Symbol(T5, Decl(intersectionReduction.ts, 8, 27))
>sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 2, 13))
type T6 = typeof sym1 & symbol & typeof sym2; // typeof sym1 & typeof sym2
>T6 : Symbol(T6, Decl(intersectionReduction.ts, 9, 31))
>sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 2, 13))
>sym2 : Symbol(sym2, Decl(intersectionReduction.ts, 3, 13))
type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // 'a' & 10 & typeof sym1
>T7 : Symbol(T7, Decl(intersectionReduction.ts, 10, 45))
>sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 2, 13))
type T10 = string & ('a' | 'b'); // 'a' | 'b'
>T10 : Symbol(T10, Decl(intersectionReduction.ts, 11, 60))
type T11 = (string | number) & ('a' | 10); // 'a' | 10
>T11 : Symbol(T11, Decl(intersectionReduction.ts, 13, 32))
@@ -0,0 +1,40 @@
=== tests/cases/conformance/types/intersection/intersectionReduction.ts ===
// @strict
declare const sym1: unique symbol;
>sym1 : unique symbol
declare const sym2: unique symbol;
>sym2 : unique symbol
type T1 = string & 'a'; // 'a'
>T1 : "a"
type T2 = 'a' & string & 'b'; // 'a' & 'b'
>T2 : T2
type T3 = number & 10; // 10
>T3 : 10
type T4 = 10 & number & 20; // 10 & 20
>T4 : T4
type T5 = symbol & typeof sym1; // typeof sym1
>T5 : unique symbol
>sym1 : unique symbol
type T6 = typeof sym1 & symbol & typeof sym2; // typeof sym1 & typeof sym2
>T6 : T6
>sym1 : unique symbol
>sym2 : unique symbol
type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // 'a' & 10 & typeof sym1
>T7 : T7
>sym1 : unique symbol
type T10 = string & ('a' | 'b'); // 'a' | 'b'
>T10 : "a" | "b"
type T11 = (string | number) & ('a' | 10); // 'a' | 10
>T11 : "a" | 10
@@ -0,0 +1,83 @@
tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(7,9): error TS2322: Type 'T & U' is not assignable to type 'string | number'.
Type 'string | undefined' is not assignable to type 'string | number'.
Type 'undefined' is not assignable to type 'string | number'.
Type 'T & U' is not assignable to type 'number'.
tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(8,9): error TS2322: Type 'T & U' is not assignable to type 'string | null'.
Type 'string | undefined' is not assignable to type 'string | null'.
Type 'undefined' is not assignable to type 'string | null'.
Type 'T & U' is not assignable to type 'string'.
tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(10,9): error TS2322: Type 'T & U' is not assignable to type 'number | null'.
Type 'string | undefined' is not assignable to type 'number | null'.
Type 'undefined' is not assignable to type 'number | null'.
Type 'T & U' is not assignable to type 'number'.
tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(11,9): error TS2322: Type 'T & U' is not assignable to type 'number | undefined'.
Type 'string | undefined' is not assignable to type 'number | undefined'.
Type 'string' is not assignable to type 'number | undefined'.
Type 'T & U' is not assignable to type 'number'.
tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(12,9): error TS2322: Type 'T & U' is not assignable to type 'null | undefined'.
Type 'string | undefined' is not assignable to type 'null | undefined'.
Type 'string' is not assignable to type 'null | undefined'.
Type 'T & U' is not assignable to type 'null'.
==== tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts (5 errors) ====
function f1<T extends string | number, U extends string | number>(x: T & U) {
// Combined constraint of 'T & U' is 'string | number'
let y: string | number = x;
}
function f2<T extends string | number | undefined, U extends string | null | undefined>(x: T & U) {
let y1: string | number = x; // Error
~~
!!! error TS2322: Type 'T & U' is not assignable to type 'string | number'.
!!! error TS2322: Type 'string | undefined' is not assignable to type 'string | number'.
!!! error TS2322: Type 'undefined' is not assignable to type 'string | number'.
!!! error TS2322: Type 'T & U' is not assignable to type 'number'.
let y2: string | null = x; // Error
~~
!!! error TS2322: Type 'T & U' is not assignable to type 'string | null'.
!!! error TS2322: Type 'string | undefined' is not assignable to type 'string | null'.
!!! error TS2322: Type 'undefined' is not assignable to type 'string | null'.
!!! error TS2322: Type 'T & U' is not assignable to type 'string'.
let y3: string | undefined = x;
let y4: number | null = x; // Error
~~
!!! error TS2322: Type 'T & U' is not assignable to type 'number | null'.
!!! error TS2322: Type 'string | undefined' is not assignable to type 'number | null'.
!!! error TS2322: Type 'undefined' is not assignable to type 'number | null'.
!!! error TS2322: Type 'T & U' is not assignable to type 'number'.
let y5: number | undefined = x; // Error
~~
!!! error TS2322: Type 'T & U' is not assignable to type 'number | undefined'.
!!! error TS2322: Type 'string | undefined' is not assignable to type 'number | undefined'.
!!! error TS2322: Type 'string' is not assignable to type 'number | undefined'.
!!! error TS2322: Type 'T & U' is not assignable to type 'number'.
let y6: null | undefined = x; // Error
~~
!!! error TS2322: Type 'T & U' is not assignable to type 'null | undefined'.
!!! error TS2322: Type 'string | undefined' is not assignable to type 'null | undefined'.
!!! error TS2322: Type 'string' is not assignable to type 'null | undefined'.
!!! error TS2322: Type 'T & U' is not assignable to type 'null'.
}
type T1 = (string | number | undefined) & (string | null | undefined); // string | undefined
function f3<T extends string | number | undefined>(x: T & (number | object | undefined)) {
const y: number | undefined = x;
}
function f4<T extends string | number>(x: T & (number | object)) {
const y: number = x;
}
function f5<T, U extends keyof T>(x: keyof T & U) {
let y: keyof any = x;
}
// Repro from #23648
type Example<T, U> = { [K in keyof T]: K extends keyof U ? UnexpectedError<K> : NoErrorHere<K> }
type UnexpectedError<T extends PropertyKey> = T
type NoErrorHere<T extends PropertyKey> = T
@@ -0,0 +1,60 @@
//// [intersectionWithUnionConstraint.ts]
function f1<T extends string | number, U extends string | number>(x: T & U) {
// Combined constraint of 'T & U' is 'string | number'
let y: string | number = x;
}
function f2<T extends string | number | undefined, U extends string | null | undefined>(x: T & U) {
let y1: string | number = x; // Error
let y2: string | null = x; // Error
let y3: string | undefined = x;
let y4: number | null = x; // Error
let y5: number | undefined = x; // Error
let y6: null | undefined = x; // Error
}
type T1 = (string | number | undefined) & (string | null | undefined); // string | undefined
function f3<T extends string | number | undefined>(x: T & (number | object | undefined)) {
const y: number | undefined = x;
}
function f4<T extends string | number>(x: T & (number | object)) {
const y: number = x;
}
function f5<T, U extends keyof T>(x: keyof T & U) {
let y: keyof any = x;
}
// Repro from #23648
type Example<T, U> = { [K in keyof T]: K extends keyof U ? UnexpectedError<K> : NoErrorHere<K> }
type UnexpectedError<T extends PropertyKey> = T
type NoErrorHere<T extends PropertyKey> = T
//// [intersectionWithUnionConstraint.js]
"use strict";
function f1(x) {
// Combined constraint of 'T & U' is 'string | number'
var y = x;
}
function f2(x) {
var y1 = x; // Error
var y2 = x; // Error
var y3 = x;
var y4 = x; // Error
var y5 = x; // Error
var y6 = x; // Error
}
function f3(x) {
var y = x;
}
function f4(x) {
var y = x;
}
function f5(x) {
var y = x;
}
@@ -0,0 +1,114 @@
=== tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts ===
function f1<T extends string | number, U extends string | number>(x: T & U) {
>f1 : Symbol(f1, Decl(intersectionWithUnionConstraint.ts, 0, 0))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 0, 12))
>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 0, 38))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 0, 66))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 0, 12))
>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 0, 38))
// Combined constraint of 'T & U' is 'string | number'
let y: string | number = x;
>y : Symbol(y, Decl(intersectionWithUnionConstraint.ts, 2, 7))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 0, 66))
}
function f2<T extends string | number | undefined, U extends string | null | undefined>(x: T & U) {
>f2 : Symbol(f2, Decl(intersectionWithUnionConstraint.ts, 3, 1))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 5, 12))
>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 5, 50))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 5, 88))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 5, 12))
>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 5, 50))
let y1: string | number = x; // Error
>y1 : Symbol(y1, Decl(intersectionWithUnionConstraint.ts, 6, 7))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 5, 88))
let y2: string | null = x; // Error
>y2 : Symbol(y2, Decl(intersectionWithUnionConstraint.ts, 7, 7))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 5, 88))
let y3: string | undefined = x;
>y3 : Symbol(y3, Decl(intersectionWithUnionConstraint.ts, 8, 7))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 5, 88))
let y4: number | null = x; // Error
>y4 : Symbol(y4, Decl(intersectionWithUnionConstraint.ts, 9, 7))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 5, 88))
let y5: number | undefined = x; // Error
>y5 : Symbol(y5, Decl(intersectionWithUnionConstraint.ts, 10, 7))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 5, 88))
let y6: null | undefined = x; // Error
>y6 : Symbol(y6, Decl(intersectionWithUnionConstraint.ts, 11, 7))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 5, 88))
}
type T1 = (string | number | undefined) & (string | null | undefined); // string | undefined
>T1 : Symbol(T1, Decl(intersectionWithUnionConstraint.ts, 12, 1))
function f3<T extends string | number | undefined>(x: T & (number | object | undefined)) {
>f3 : Symbol(f3, Decl(intersectionWithUnionConstraint.ts, 14, 70))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 16, 12))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 16, 51))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 16, 12))
const y: number | undefined = x;
>y : Symbol(y, Decl(intersectionWithUnionConstraint.ts, 17, 9))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 16, 51))
}
function f4<T extends string | number>(x: T & (number | object)) {
>f4 : Symbol(f4, Decl(intersectionWithUnionConstraint.ts, 18, 1))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 20, 12))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 20, 39))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 20, 12))
const y: number = x;
>y : Symbol(y, Decl(intersectionWithUnionConstraint.ts, 21, 9))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 20, 39))
}
function f5<T, U extends keyof T>(x: keyof T & U) {
>f5 : Symbol(f5, Decl(intersectionWithUnionConstraint.ts, 22, 1))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 24, 12))
>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 24, 14))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 24, 12))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 24, 34))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 24, 12))
>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 24, 14))
let y: keyof any = x;
>y : Symbol(y, Decl(intersectionWithUnionConstraint.ts, 25, 7))
>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 24, 34))
}
// Repro from #23648
type Example<T, U> = { [K in keyof T]: K extends keyof U ? UnexpectedError<K> : NoErrorHere<K> }
>Example : Symbol(Example, Decl(intersectionWithUnionConstraint.ts, 26, 1))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 30, 13))
>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 30, 15))
>K : Symbol(K, Decl(intersectionWithUnionConstraint.ts, 30, 24))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 30, 13))
>K : Symbol(K, Decl(intersectionWithUnionConstraint.ts, 30, 24))
>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 30, 15))
>UnexpectedError : Symbol(UnexpectedError, Decl(intersectionWithUnionConstraint.ts, 30, 96))
>K : Symbol(K, Decl(intersectionWithUnionConstraint.ts, 30, 24))
>NoErrorHere : Symbol(NoErrorHere, Decl(intersectionWithUnionConstraint.ts, 32, 47))
>K : Symbol(K, Decl(intersectionWithUnionConstraint.ts, 30, 24))
type UnexpectedError<T extends PropertyKey> = T
>UnexpectedError : Symbol(UnexpectedError, Decl(intersectionWithUnionConstraint.ts, 30, 96))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 32, 21))
>PropertyKey : Symbol(PropertyKey, Decl(lib.d.ts, --, --))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 32, 21))
type NoErrorHere<T extends PropertyKey> = T
>NoErrorHere : Symbol(NoErrorHere, Decl(intersectionWithUnionConstraint.ts, 32, 47))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 33, 17))
>PropertyKey : Symbol(PropertyKey, Decl(lib.d.ts, --, --))
>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 33, 17))
@@ -0,0 +1,119 @@
=== tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts ===
function f1<T extends string | number, U extends string | number>(x: T & U) {
>f1 : <T extends string | number, U extends string | number>(x: T & U) => void
>T : T
>U : U
>x : T & U
>T : T
>U : U
// Combined constraint of 'T & U' is 'string | number'
let y: string | number = x;
>y : string | number
>x : T & U
}
function f2<T extends string | number | undefined, U extends string | null | undefined>(x: T & U) {
>f2 : <T extends string | number | undefined, U extends string | null | undefined>(x: T & U) => void
>T : T
>U : U
>null : null
>x : T & U
>T : T
>U : U
let y1: string | number = x; // Error
>y1 : string | number
>x : T & U
let y2: string | null = x; // Error
>y2 : string | null
>null : null
>x : T & U
let y3: string | undefined = x;
>y3 : string | undefined
>x : T & U
let y4: number | null = x; // Error
>y4 : number | null
>null : null
>x : T & U
let y5: number | undefined = x; // Error
>y5 : number | undefined
>x : T & U
let y6: null | undefined = x; // Error
>y6 : null | undefined
>null : null
>x : T & U
}
type T1 = (string | number | undefined) & (string | null | undefined); // string | undefined
>T1 : string | undefined
>null : null
function f3<T extends string | number | undefined>(x: T & (number | object | undefined)) {
>f3 : <T extends string | number | undefined>(x: (T & undefined) | (T & number) | (T & object)) => void
>T : T
>x : (T & undefined) | (T & number) | (T & object)
>T : T
const y: number | undefined = x;
>y : number | undefined
>x : (T & undefined) | (T & number) | (T & object)
}
function f4<T extends string | number>(x: T & (number | object)) {
>f4 : <T extends string | number>(x: (T & number) | (T & object)) => void
>T : T
>x : (T & number) | (T & object)
>T : T
const y: number = x;
>y : number
>x : (T & number) | (T & object)
}
function f5<T, U extends keyof T>(x: keyof T & U) {
>f5 : <T, U extends keyof T>(x: keyof T & U) => void
>T : T
>U : U
>T : T
>x : keyof T & U
>T : T
>U : U
let y: keyof any = x;
>y : string | number | symbol
>x : keyof T & U
}
// Repro from #23648
type Example<T, U> = { [K in keyof T]: K extends keyof U ? UnexpectedError<K> : NoErrorHere<K> }
>Example : Example<T, U>
>T : T
>U : U
>K : K
>T : T
>K : K
>U : U
>UnexpectedError : T
>K : K
>NoErrorHere : T
>K : K
type UnexpectedError<T extends PropertyKey> = T
>UnexpectedError : T
>T : T
>PropertyKey : string | number | symbol
>T : T
type NoErrorHere<T extends PropertyKey> = T
>NoErrorHere : T
>T : T
>PropertyKey : string | number | symbol
>T : T
@@ -1,11 +1,8 @@
tests/cases/compiler/a.js(1,15): error TS2304: Cannot find name 'require'.
tests/cases/compiler/a.js(4,1): error TS2686: 'Puppeteer' refers to a UMD global, but the current file is a module. Consider adding an import instead.
==== tests/cases/compiler/a.js (2 errors) ====
==== tests/cases/compiler/a.js (1 errors) ====
const other = require('./other');
~~~~~~~
!!! error TS2304: Cannot find name 'require'.
/** @type {Puppeteer.Keyboard} */
var ppk;
Puppeteer.connect;
@@ -1,6 +1,7 @@
=== tests/cases/compiler/a.js ===
const other = require('./other');
>other : Symbol(other, Decl(a.js, 0, 5))
>require : Symbol(require)
>'./other' : Symbol("tests/cases/compiler/other", Decl(other.d.ts, 0, 0))
/** @type {Puppeteer.Keyboard} */
@@ -1,11 +1,10 @@
tests/cases/conformance/jsdoc/use.js(3,7): error TS2345: Argument of type '"no"' is not assignable to parameter of type 'number'.
tests/cases/conformance/jsdoc/use.js(4,7): error TS2345: Argument of type '"also no"' is not assignable to parameter of type 'number'.
tests/cases/conformance/jsdoc/use.js(5,7): error TS2345: Argument of type '0' is not assignable to parameter of type 'string'.
tests/cases/conformance/jsdoc/use.js(6,7): error TS2345: Argument of type '1' is not assignable to parameter of type 'string'.
tests/cases/conformance/jsdoc/use.js(2,7): error TS2345: Argument of type '"no"' is not assignable to parameter of type 'number'.
tests/cases/conformance/jsdoc/use.js(3,7): error TS2345: Argument of type '"also no"' is not assignable to parameter of type 'number'.
tests/cases/conformance/jsdoc/use.js(4,7): error TS2345: Argument of type '0' is not assignable to parameter of type 'string'.
tests/cases/conformance/jsdoc/use.js(5,7): error TS2345: Argument of type '1' is not assignable to parameter of type 'string'.
==== tests/cases/conformance/jsdoc/use.js (4 errors) ====
/// <reference path='./types.d.ts'/>
var mod = require('./mod');
mod.f('no')
~~~~
@@ -20,13 +19,7 @@ tests/cases/conformance/jsdoc/use.js(6,7): error TS2345: Argument of type '1' is
~
!!! error TS2345: Argument of type '1' is not assignable to parameter of type 'string'.
==== tests/cases/conformance/jsdoc/types.d.ts (0 errors) ====
declare function require(name: string): any;
declare var exports: any;
declare var module: { exports: any };
==== tests/cases/conformance/jsdoc/mod.js (0 errors) ====
/// <reference path='./types.d.ts'/>
/** @param {number} n */
exports.f = exports.g = function fg(n) {
return n + 1
@@ -1,73 +1,56 @@
=== tests/cases/conformance/jsdoc/use.js ===
/// <reference path='./types.d.ts'/>
var mod = require('./mod');
>mod : Symbol(mod, Decl(use.js, 1, 3))
>require : Symbol(require, Decl(types.d.ts, 0, 0))
>mod : Symbol(mod, Decl(use.js, 0, 3))
>require : Symbol(require)
>'./mod' : Symbol("tests/cases/conformance/jsdoc/mod", Decl(mod.js, 0, 0))
mod.f('no')
>mod.f : Symbol(f, Decl(mod.js, 0, 0))
>mod : Symbol(mod, Decl(use.js, 1, 3))
>mod : Symbol(mod, Decl(use.js, 0, 3))
>f : Symbol(f, Decl(mod.js, 0, 0))
mod.g('also no')
>mod.g : Symbol(g, Decl(mod.js, 3, 11))
>mod : Symbol(mod, Decl(use.js, 1, 3))
>g : Symbol(g, Decl(mod.js, 3, 11))
>mod.g : Symbol(g, Decl(mod.js, 1, 11))
>mod : Symbol(mod, Decl(use.js, 0, 3))
>g : Symbol(g, Decl(mod.js, 1, 11))
mod.h(0)
>mod.h : Symbol(h, Decl(mod.js, 5, 1))
>mod : Symbol(mod, Decl(use.js, 1, 3))
>h : Symbol(h, Decl(mod.js, 5, 1))
>mod.h : Symbol(h, Decl(mod.js, 3, 1))
>mod : Symbol(mod, Decl(use.js, 0, 3))
>h : Symbol(h, Decl(mod.js, 3, 1))
mod.i(1)
>mod.i : Symbol(i, Decl(mod.js, 7, 18))
>mod : Symbol(mod, Decl(use.js, 1, 3))
>i : Symbol(i, Decl(mod.js, 7, 18))
=== tests/cases/conformance/jsdoc/types.d.ts ===
declare function require(name: string): any;
>require : Symbol(require, Decl(types.d.ts, 0, 0))
>name : Symbol(name, Decl(types.d.ts, 0, 25))
declare var exports: any;
>exports : Symbol(exports, Decl(types.d.ts, 1, 11))
declare var module: { exports: any };
>module : Symbol(module, Decl(types.d.ts, 2, 11))
>exports : Symbol(exports, Decl(types.d.ts, 2, 21))
>mod.i : Symbol(i, Decl(mod.js, 5, 18))
>mod : Symbol(mod, Decl(use.js, 0, 3))
>i : Symbol(i, Decl(mod.js, 5, 18))
=== tests/cases/conformance/jsdoc/mod.js ===
/// <reference path='./types.d.ts'/>
/** @param {number} n */
exports.f = exports.g = function fg(n) {
>exports.f : Symbol(f, Decl(mod.js, 0, 0))
>exports : Symbol(f, Decl(mod.js, 0, 0))
>f : Symbol(f, Decl(mod.js, 0, 0))
>exports.g : Symbol(g, Decl(mod.js, 3, 11))
>exports : Symbol(g, Decl(mod.js, 3, 11))
>g : Symbol(g, Decl(mod.js, 3, 11))
>fg : Symbol(fg, Decl(mod.js, 3, 23))
>n : Symbol(n, Decl(mod.js, 3, 36))
>exports.g : Symbol(g, Decl(mod.js, 1, 11))
>exports : Symbol(g, Decl(mod.js, 1, 11))
>g : Symbol(g, Decl(mod.js, 1, 11))
>fg : Symbol(fg, Decl(mod.js, 1, 23))
>n : Symbol(n, Decl(mod.js, 1, 36))
return n + 1
>n : Symbol(n, Decl(mod.js, 3, 36))
>n : Symbol(n, Decl(mod.js, 1, 36))
}
/** @param {string} mom */
module.exports.h = module.exports.i = function hi(mom) {
>module.exports : Symbol(h, Decl(mod.js, 5, 1))
>module : Symbol(module, Decl(types.d.ts, 2, 11))
>exports : Symbol(exports, Decl(types.d.ts, 2, 21))
>h : Symbol(h, Decl(mod.js, 5, 1))
>module.exports : Symbol(i, Decl(mod.js, 7, 18))
>module : Symbol(module, Decl(types.d.ts, 2, 11))
>exports : Symbol(exports, Decl(types.d.ts, 2, 21))
>i : Symbol(i, Decl(mod.js, 7, 18))
>hi : Symbol(hi, Decl(mod.js, 7, 37))
>mom : Symbol(mom, Decl(mod.js, 7, 50))
>module.exports : Symbol(h, Decl(mod.js, 3, 1))
>module : Symbol(module)
>h : Symbol(h, Decl(mod.js, 3, 1))
>module.exports : Symbol(i, Decl(mod.js, 5, 18))
>module : Symbol(module)
>i : Symbol(i, Decl(mod.js, 5, 18))
>hi : Symbol(hi, Decl(mod.js, 5, 37))
>mom : Symbol(mom, Decl(mod.js, 5, 50))
return `hi, ${mom}!`;
>mom : Symbol(mom, Decl(mod.js, 7, 50))
>mom : Symbol(mom, Decl(mod.js, 5, 50))
}
@@ -1,9 +1,8 @@
=== tests/cases/conformance/jsdoc/use.js ===
/// <reference path='./types.d.ts'/>
var mod = require('./mod');
>mod : typeof import("tests/cases/conformance/jsdoc/mod")
>require('./mod') : typeof import("tests/cases/conformance/jsdoc/mod")
>require : (name: string) => any
>require : any
>'./mod' : "./mod"
mod.f('no')
@@ -34,21 +33,7 @@ mod.i(1)
>i : (mom: string) => string
>1 : 1
=== tests/cases/conformance/jsdoc/types.d.ts ===
declare function require(name: string): any;
>require : (name: string) => any
>name : string
declare var exports: any;
>exports : any
declare var module: { exports: any };
>module : { exports: any; }
>exports : any
=== tests/cases/conformance/jsdoc/mod.js ===
/// <reference path='./types.d.ts'/>
/** @param {number} n */
exports.f = exports.g = function fg(n) {
>exports.f = exports.g = function fg(n) { return n + 1} : (n: number) => number
@@ -73,13 +58,13 @@ module.exports.h = module.exports.i = function hi(mom) {
>module.exports.h = module.exports.i = function hi(mom) { return `hi, ${mom}!`;} : (mom: string) => string
>module.exports.h : any
>module.exports : any
>module : { exports: any; }
>module : any
>exports : any
>h : any
>module.exports.i = function hi(mom) { return `hi, ${mom}!`;} : (mom: string) => string
>module.exports.i : any
>module.exports : any
>module : { exports: any; }
>module : any
>exports : any
>i : any
>function hi(mom) { return `hi, ${mom}!`;} : (mom: string) => string
@@ -4,5 +4,5 @@
* }}
*/
export const foo = 5;
>foo : Symbol(foo, Decl(export.js, 4, 12))
>foo : Symbol(foo, Decl(export.js, 4, 12), Decl(export.js, 1, 3))
@@ -319,6 +319,20 @@ function f90<T extends S2, K extends keyof S2>(x1: S2[keyof S2], x2: T[keyof S2]
x4.length;
}
function f91<T, K extends keyof T>(x: T, y: T[keyof T], z: T[K]) {
let a: {};
a = x;
a = y;
a = z;
}
function f92<T, K extends keyof T>(x: T, y: T[keyof T], z: T[K]) {
let a: {} | null | undefined;
a = x;
a = y;
a = z;
}
// Repros from #12011
class Base {
@@ -566,6 +580,15 @@ type Predicates<TaggedRecord> = {
[T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T]
}
// Repros from #23592
type Example<T extends { [K in keyof T]: { prop: any } }> = { [K in keyof T]: T[K]["prop"] };
type Result = Example<{ a: { prop: string }; b: { prop: number } }>;
type Helper2<T> = { [K in keyof T]: Extract<T[K], { prop: any }> };
type Example2<T> = { [K in keyof Helper2<T>]: Helper2<T>[K]["prop"] };
type Result2 = Example2<{ 1: { prop: string }; 2: { prop: number } }>;
// Repro from #23618
type DBBoolTable<K extends string> = { [k in K]: 0 | 1 }
@@ -583,6 +606,27 @@ type DynamicDBRecord<Flag extends string> = ({ dynamicField: number } | { dynami
function getFlagsFromDynamicRecord<Flag extends string>(record: DynamicDBRecord<Flag>, flags: Flag[]) {
return record[flags[0]];
}
// Repro from #21368
interface I {
foo: string;
}
declare function take<T>(p: T): void;
function fn<T extends I, K extends keyof T>(o: T, k: K) {
take<{} | null | undefined>(o[k]);
take<any>(o[k]);
}
// Repro from #23133
class Unbounded<T> {
foo(x: T[keyof T]) {
let y: {} | undefined | null = x;
}
}
//// [keyofAndIndexedAccess.js]
@@ -821,6 +865,18 @@ function f90(x1, x2, x3, x4) {
x3.length;
x4.length;
}
function f91(x, y, z) {
var a;
a = x;
a = y;
a = z;
}
function f92(x, y, z) {
var a;
a = x;
a = y;
a = z;
}
// Repros from #12011
var Base = /** @class */ (function () {
function Base() {
@@ -977,6 +1033,19 @@ function getFlagsFromSimpleRecord(record, flags) {
function getFlagsFromDynamicRecord(record, flags) {
return record[flags[0]];
}
function fn(o, k) {
take(o[k]);
take(o[k]);
}
// Repro from #23133
var Unbounded = /** @class */ (function () {
function Unbounded() {
}
Unbounded.prototype.foo = function (x) {
var y = x;
};
return Unbounded;
}());
//// [keyofAndIndexedAccess.d.ts]
@@ -1117,6 +1186,8 @@ declare type S2 = {
b: string;
};
declare function f90<T extends S2, K extends keyof S2>(x1: S2[keyof S2], x2: T[keyof S2], x3: S2[K], x4: T[K]): void;
declare function f91<T, K extends keyof T>(x: T, y: T[keyof T], z: T[K]): void;
declare function f92<T, K extends keyof T>(x: T, y: T[keyof T], z: T[K]): void;
declare class Base {
get<K extends keyof this>(prop: K): this[K];
set<K extends keyof this>(prop: K, value: this[K]): void;
@@ -1241,6 +1312,37 @@ declare function f3<T, K extends Extract<keyof T, string>>(t: T, k: K, tk: T[K])
declare type Predicates<TaggedRecord> = {
[T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T];
};
declare type Example<T extends {
[K in keyof T]: {
prop: any;
};
}> = {
[K in keyof T]: T[K]["prop"];
};
declare type Result = Example<{
a: {
prop: string;
};
b: {
prop: number;
};
}>;
declare type Helper2<T> = {
[K in keyof T]: Extract<T[K], {
prop: any;
}>;
};
declare type Example2<T> = {
[K in keyof Helper2<T>]: Helper2<T>[K]["prop"];
};
declare type Result2 = Example2<{
1: {
prop: string;
};
2: {
prop: number;
};
}>;
declare type DBBoolTable<K extends string> = {
[k in K]: 0 | 1;
};
@@ -1258,3 +1360,11 @@ declare type DynamicDBRecord<Flag extends string> = ({
dynamicField: string;
}) & DBBoolTable<Flag>;
declare function getFlagsFromDynamicRecord<Flag extends string>(record: DynamicDBRecord<Flag>, flags: Flag[]): DynamicDBRecord<Flag>[Flag];
interface I {
foo: string;
}
declare function take<T>(p: T): void;
declare function fn<T extends I, K extends keyof T>(o: T, k: K): void;
declare class Unbounded<T> {
foo(x: T[keyof T]): void;
}
Loaded 100 of 244 files, more files were not shown because too many files have changed in this diff. Show more