mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into vfs
This commit is contained in:
commit
d62a11ffc0
244 files changed
+7414
-2974
No files matched your search
@@ -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
@@ -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
@@ -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,4 +1,5 @@
|
||||
[](https://travis-ci.org/Microsoft/TypeScript)
|
||||
[](https://typescript.visualstudio.com/TypeScript/_build/index?context=allDefinitions&path=%5C&definitionId=4&_a=completed)
|
||||
[](https://www.npmjs.com/package/typescript)
|
||||
[](https://www.npmjs.com/package/typescript)
|
||||
|
||||
|
||||
+1
-1
@@ -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
@@ -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
|
||||
@@ -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}")
|
||||
}
|
||||
Generated
+978
-978
File diff suppressed because it is too large.
Load diff
+28
-5
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace ts {
|
||||
value = node.right;
|
||||
}
|
||||
else {
|
||||
return value;
|
||||
return visitNode(value, visitor, isExpression);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-3
@@ -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
@@ -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
@@ -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"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
}]
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Vendored
+9
-7
@@ -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[];
|
||||
}
|
||||
}
|
||||
Vendored
+2
-1
@@ -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" />
|
||||
Vendored
+31
@@ -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[];
|
||||
};
|
||||
}
|
||||
Vendored
+9
@@ -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>
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -460,7 +460,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
isOrphan() {
|
||||
return this.containingProjects.length === 0;
|
||||
return !forEach(this.containingProjects, p => !p.isOrphan());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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 });
|
||||
}
|
||||
|
||||
@@ -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] };
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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,
|
||||
|
||||
+25
@@ -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 _; });
|
||||
+15
@@ -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;
|
||||
@@ -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))
|
||||
|
||||
@@ -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.
|
||||
@@ -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
Reference in new issue
Block a user