mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into fix2-getConstraintOfIndexedAccess
Also fix test failure from last commit.
This commit is contained in:
+1
-3
@@ -49,6 +49,7 @@
|
||||
"@types/run-sequence": "latest",
|
||||
"@types/through2": "latest",
|
||||
"browserify": "latest",
|
||||
"browser-resolve": "^1.11.2",
|
||||
"chai": "latest",
|
||||
"convert-source-map": "latest",
|
||||
"del": "latest",
|
||||
@@ -93,8 +94,5 @@
|
||||
"fs": false,
|
||||
"os": false,
|
||||
"path": false
|
||||
},
|
||||
"dependencies": {
|
||||
"browser-resolve": "^1.11.2"
|
||||
}
|
||||
}
|
||||
|
||||
+91
-52
@@ -497,6 +497,8 @@ namespace ts {
|
||||
const builtinGlobals = createSymbolTable();
|
||||
builtinGlobals.set(undefinedSymbol.escapedName, undefinedSymbol);
|
||||
|
||||
const isNotOverloadAndNotAccessor = and(isNotOverload, isNotAccessor);
|
||||
|
||||
initializeTypeChecker();
|
||||
|
||||
return checker;
|
||||
@@ -638,7 +640,7 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
|
||||
function mergeModuleAugmentation(moduleName: LiteralExpression): void {
|
||||
function mergeModuleAugmentation(moduleName: StringLiteral | Identifier): void {
|
||||
const moduleAugmentation = <ModuleDeclaration>moduleName.parent;
|
||||
if (moduleAugmentation.symbol.declarations[0] !== moduleAugmentation) {
|
||||
// this is a combined symbol for multiple augmentations within the same file.
|
||||
@@ -670,7 +672,8 @@ namespace ts {
|
||||
mergeSymbol(mainModule, moduleAugmentation.symbol);
|
||||
}
|
||||
else {
|
||||
error(moduleName, Diagnostics.Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity, moduleName.text);
|
||||
// moduleName will be a StringLiteral since this is not `declare global`.
|
||||
error(moduleName, Diagnostics.Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity, (moduleName as StringLiteral).text);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3112,6 +3115,12 @@ namespace ts {
|
||||
return "(Anonymous function)";
|
||||
}
|
||||
}
|
||||
if ((symbol as TransientSymbol).syntheticLiteralTypeOrigin) {
|
||||
const stringValue = (symbol as TransientSymbol).syntheticLiteralTypeOrigin.value;
|
||||
if (!isIdentifierText(stringValue, compilerOptions.target)) {
|
||||
return `"${escapeString(stringValue, CharacterCodes.doubleQuote)}"`;
|
||||
}
|
||||
}
|
||||
return unescapeLeadingUnderscores(symbol.escapedName);
|
||||
}
|
||||
|
||||
@@ -5722,7 +5731,14 @@ namespace ts {
|
||||
}
|
||||
setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, undefined);
|
||||
|
||||
function addMemberForKeyType(t: Type, propertySymbol?: Symbol) {
|
||||
function addMemberForKeyType(t: Type, propertySymbolOrIndex?: Symbol | number) {
|
||||
let propertySymbol: Symbol;
|
||||
// forEachType delegates to forEach, which calls with a numeric second argument
|
||||
// the type system currently doesn't catch this incompatibility, so we annotate
|
||||
// the function ourselves to indicate the runtime behavior and deal with it here
|
||||
if (typeof propertySymbolOrIndex === "object") {
|
||||
propertySymbol = propertySymbolOrIndex;
|
||||
}
|
||||
// Create a mapper from T to the current iteration type constituent. Then, if the
|
||||
// mapped type is itself an instantiated type, combine the iteration mapper with the
|
||||
// instantiation mapper.
|
||||
@@ -5742,6 +5758,7 @@ namespace ts {
|
||||
prop.syntheticOrigin = propertySymbol;
|
||||
prop.declarations = propertySymbol.declarations;
|
||||
}
|
||||
prop.syntheticLiteralTypeOrigin = t as StringLiteralType;
|
||||
members.set(propName, prop);
|
||||
}
|
||||
else if (t.flags & TypeFlags.String) {
|
||||
@@ -5914,7 +5931,7 @@ namespace ts {
|
||||
const keepTypeParameterForMappedType = baseObjectType && getObjectFlags(baseObjectType) & ObjectFlags.Mapped &&
|
||||
type.indexType.flags & TypeFlags.TypeParameter;
|
||||
const baseIndexType = !keepTypeParameterForMappedType && getBaseConstraintOfType(type.indexType);
|
||||
if (baseIndexType === stringType && (!baseObjectType || !getIndexInfoOfType(baseObjectType, IndexKind.String))) {
|
||||
if (baseIndexType === stringType && !getIndexInfoOfType(baseObjectType || type.objectType, IndexKind.String)) {
|
||||
// getIndexedAccessType returns `any` for X[string] where X doesn't have an index signature.
|
||||
// to avoid this, return `undefined`.
|
||||
return undefined;
|
||||
@@ -7601,22 +7618,6 @@ namespace ts {
|
||||
return anyType;
|
||||
}
|
||||
|
||||
function getIndexedAccessForMappedType(type: MappedType, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode) {
|
||||
if (accessNode) {
|
||||
// Check if the index type is assignable to 'keyof T' for the object type.
|
||||
if (!isTypeAssignableTo(indexType, getIndexType(type))) {
|
||||
error(accessNode, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(type));
|
||||
return unknownType;
|
||||
}
|
||||
if (accessNode.kind === SyntaxKind.ElementAccessExpression && isAssignmentTarget(accessNode) && type.declaration.readonlyToken) {
|
||||
error(accessNode, Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(type));
|
||||
}
|
||||
}
|
||||
const mapper = createTypeMapper([getTypeParameterFromMappedType(type)], [indexType]);
|
||||
const templateMapper = type.mapper ? combineTypeMappers(type.mapper, mapper) : mapper;
|
||||
return instantiateType(getTemplateTypeFromMappedType(type), templateMapper);
|
||||
}
|
||||
|
||||
function isGenericObjectType(type: Type): boolean {
|
||||
return type.flags & TypeFlags.TypeVariable ? true :
|
||||
getObjectFlags(type) & ObjectFlags.Mapped ? isGenericIndexType(getConstraintTypeFromMappedType(<MappedType>type)) :
|
||||
@@ -7642,12 +7643,14 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Given an indexed access type T[K], if T is an intersection containing one or more generic types and one or
|
||||
// more object types with only a string index signature, e.g. '(U & V & { [x: string]: D })[K]', return a
|
||||
// transformed type of the form '(U & V)[K] | D'. This allows us to properly reason about higher order indexed
|
||||
// access types with default property values as expressed by D.
|
||||
// Transform an indexed access to a simpler form, if possible. Return the simpler form, or return
|
||||
// undefined if no transformation is possible.
|
||||
function getTransformedIndexedAccessType(type: IndexedAccessType): Type {
|
||||
const objectType = type.objectType;
|
||||
// Given an indexed access type T[K], if T is an intersection containing one or more generic types and one or
|
||||
// more object types with only a string index signature, e.g. '(U & V & { [x: string]: D })[K]', return a
|
||||
// transformed type of the form '(U & V)[K] | D'. This allows us to properly reason about higher order indexed
|
||||
// access types with default property values as expressed by D.
|
||||
if (objectType.flags & TypeFlags.Intersection && isGenericObjectType(objectType) && some((<IntersectionType>objectType).types, isStringIndexOnlyType)) {
|
||||
const regularTypes: Type[] = [];
|
||||
const stringIndexTypes: Type[] = [];
|
||||
@@ -7664,20 +7667,23 @@ namespace ts {
|
||||
getIntersectionType(stringIndexTypes)
|
||||
]);
|
||||
}
|
||||
// If the object type is a mapped type { [P in K]: E }, where K is generic, instantiate E using a mapper
|
||||
// that substitutes the index type for P. For example, for an index access { [P in K]: Box<T[P]> }[X], we
|
||||
// construct the type Box<T[X]>.
|
||||
if (isGenericMappedType(objectType)) {
|
||||
const mapper = createTypeMapper([getTypeParameterFromMappedType(<MappedType>objectType)], [type.indexType]);
|
||||
const objectTypeMapper = (<MappedType>objectType).mapper;
|
||||
const templateMapper = objectTypeMapper ? combineTypeMappers(objectTypeMapper, mapper) : mapper;
|
||||
return instantiateType(getTemplateTypeFromMappedType(<MappedType>objectType), templateMapper);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode): Type {
|
||||
// If the object type is a mapped type { [P in K]: E }, where K is generic, we instantiate E using a mapper
|
||||
// that substitutes the index type for P. For example, for an index access { [P in K]: Box<T[P]> }[X], we
|
||||
// construct the type Box<T[X]>.
|
||||
if (isGenericMappedType(objectType)) {
|
||||
return getIndexedAccessForMappedType(<MappedType>objectType, indexType, accessNode);
|
||||
}
|
||||
// Otherwise, if the index type is generic, or if the object type is generic and doesn't originate in an
|
||||
// expression, we are performing a higher-order index access where we cannot meaningfully access the properties
|
||||
// of the object type. Note that for a generic T and a non-generic K, we eagerly resolve T[K] if it originates
|
||||
// in an expression. This is to preserve backwards compatibility. For example, an element access 'this["foo"]'
|
||||
// If the index type is generic, or if the object type is generic and doesn't originate in an expression,
|
||||
// we are performing a higher-order index access where we cannot meaningfully access the properties of the
|
||||
// object type. Note that for a generic T and a non-generic K, we eagerly resolve T[K] if it originates in
|
||||
// an expression. This is to preserve backwards compatibility. For example, an element access 'this["foo"]'
|
||||
// has always been resolved eagerly using the constraint type of 'this' at the given location.
|
||||
if (isGenericIndexType(indexType) || !(accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression) && isGenericObjectType(objectType)) {
|
||||
if (objectType.flags & TypeFlags.Any) {
|
||||
@@ -9299,7 +9305,7 @@ namespace ts {
|
||||
else if (target.flags & TypeFlags.IndexedAccess) {
|
||||
// A type S is related to a type T[K] if S is related to A[K], where K is string-like and
|
||||
// A is the apparent type of T.
|
||||
const constraint = getConstraintOfType(<IndexedAccessType>target);
|
||||
const constraint = getConstraintOfIndexedAccess(<IndexedAccessType>target);
|
||||
if (constraint) {
|
||||
if (result = isRelatedTo(source, constraint, reportErrors)) {
|
||||
errorInfo = saveErrorInfo;
|
||||
@@ -9339,7 +9345,7 @@ namespace ts {
|
||||
else if (source.flags & TypeFlags.IndexedAccess) {
|
||||
// A type S[K] is related to a type T if A[K] is related to T, where K is string-like and
|
||||
// A is the apparent type of S.
|
||||
const constraint = getConstraintOfType(<IndexedAccessType>source);
|
||||
const constraint = getConstraintOfIndexedAccess(<IndexedAccessType>source);
|
||||
if (constraint) {
|
||||
if (result = isRelatedTo(constraint, target, reportErrors)) {
|
||||
errorInfo = saveErrorInfo;
|
||||
@@ -15225,7 +15231,7 @@ namespace ts {
|
||||
// example, given a 'function wrap<T, U>(cb: (x: T) => U): (x: T) => U' and a call expression
|
||||
// 'let f: (x: string) => number = wrap(s => s.length)', we infer from the declared type of 'f' to the
|
||||
// return type of 'wrap'.
|
||||
if (isExpression(node)) {
|
||||
if (node.kind !== SyntaxKind.Decorator) {
|
||||
const contextualType = getContextualType(node);
|
||||
if (contextualType) {
|
||||
// We clone the contextual mapper to avoid disturbing a resolution in progress for an
|
||||
@@ -16377,8 +16383,8 @@ namespace ts {
|
||||
* Indicates whether a declaration can be treated as a constructor in a JavaScript
|
||||
* file.
|
||||
*/
|
||||
function isJavaScriptConstructor(node: Declaration): boolean {
|
||||
if (isInJavaScriptFile(node)) {
|
||||
function isJavaScriptConstructor(node: Declaration | undefined): boolean {
|
||||
if (node && isInJavaScriptFile(node)) {
|
||||
// If the node has a @class tag, treat it like a constructor.
|
||||
if (getJSDocClassTag(node)) return true;
|
||||
|
||||
@@ -16393,6 +16399,21 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function getJavaScriptClassType(symbol: Symbol): Type | undefined {
|
||||
if (isDeclarationOfFunctionOrClassExpression(symbol)) {
|
||||
symbol = getSymbolOfNode((<VariableDeclaration>symbol.valueDeclaration).initializer);
|
||||
}
|
||||
if (isJavaScriptConstructor(symbol.valueDeclaration)) {
|
||||
return getInferredClassType(symbol);
|
||||
}
|
||||
if (symbol.flags & SymbolFlags.Variable) {
|
||||
const valueType = getTypeOfSymbol(symbol);
|
||||
if (valueType.symbol && !isInferredClassType(valueType) && isJavaScriptConstructor(valueType.symbol.valueDeclaration)) {
|
||||
return getInferredClassType(valueType.symbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getInferredClassType(symbol: Symbol) {
|
||||
const links = getSymbolLinks(symbol);
|
||||
if (!links.inferredClassType) {
|
||||
@@ -16436,16 +16457,14 @@ namespace ts {
|
||||
// in a JS file
|
||||
// Note:JS inferred classes might come from a variable declaration instead of a function declaration.
|
||||
// In this case, using getResolvedSymbol directly is required to avoid losing the members from the declaration.
|
||||
let funcSymbol = node.expression.kind === SyntaxKind.Identifier ?
|
||||
const funcSymbol = node.expression.kind === SyntaxKind.Identifier ?
|
||||
getResolvedSymbol(node.expression as Identifier) :
|
||||
checkExpression(node.expression).symbol;
|
||||
if (funcSymbol && isDeclarationOfFunctionOrClassExpression(funcSymbol)) {
|
||||
funcSymbol = getSymbolOfNode((<VariableDeclaration>funcSymbol.valueDeclaration).initializer);
|
||||
const type = funcSymbol && getJavaScriptClassType(funcSymbol);
|
||||
if (type) {
|
||||
return type;
|
||||
}
|
||||
if (funcSymbol && funcSymbol.flags & SymbolFlags.Function && (funcSymbol.members || getJSDocClassTag(funcSymbol.valueDeclaration))) {
|
||||
return getInferredClassType(funcSymbol);
|
||||
}
|
||||
else if (noImplicitAny) {
|
||||
if (noImplicitAny) {
|
||||
error(node, Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type);
|
||||
}
|
||||
return anyType;
|
||||
@@ -18815,6 +18834,10 @@ namespace ts {
|
||||
const objectType = (<IndexedAccessType>type).objectType;
|
||||
const indexType = (<IndexedAccessType>type).indexType;
|
||||
if (isTypeAssignableTo(indexType, getIndexType(objectType))) {
|
||||
if (accessNode.kind === SyntaxKind.ElementAccessExpression && isAssignmentTarget(accessNode) &&
|
||||
getObjectFlags(objectType) & ObjectFlags.Mapped && (<MappedType>objectType).declaration.readonlyToken) {
|
||||
error(accessNode, Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType));
|
||||
}
|
||||
return type;
|
||||
}
|
||||
// Check if we're indexing with a numeric type and if either object or index types
|
||||
@@ -19156,6 +19179,8 @@ namespace ts {
|
||||
: DeclarationSpaces.ExportNamespace;
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
// A NamespaceImport declares an Alias, which is allowed to merge with other values within the module
|
||||
case SyntaxKind.NamespaceImport:
|
||||
return DeclarationSpaces.ExportType | DeclarationSpaces.ExportValue;
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
let result = DeclarationSpaces.None;
|
||||
@@ -22262,7 +22287,7 @@ namespace ts {
|
||||
if (flags & (SymbolFlags.Namespace | SymbolFlags.Interface | SymbolFlags.Enum)) {
|
||||
return;
|
||||
}
|
||||
const exportedDeclarationsCount = countWhere(declarations, isNotOverload);
|
||||
const exportedDeclarationsCount = countWhere(declarations, isNotOverloadAndNotAccessor);
|
||||
if (flags & SymbolFlags.TypeAlias && exportedDeclarationsCount <= 2) {
|
||||
// it is legal to merge type alias with other values
|
||||
// so count should be either 1 (just type alias) or 2 (type alias + merged value)
|
||||
@@ -22278,11 +22303,16 @@ namespace ts {
|
||||
});
|
||||
links.exportsChecked = true;
|
||||
}
|
||||
}
|
||||
|
||||
function isNotOverload(declaration: Declaration): boolean {
|
||||
return (declaration.kind !== SyntaxKind.FunctionDeclaration && declaration.kind !== SyntaxKind.MethodDeclaration) ||
|
||||
!!(declaration as FunctionDeclaration).body;
|
||||
}
|
||||
function isNotAccessor(declaration: Declaration): boolean {
|
||||
// Accessors check for their own matching duplicates, and in contexts where they are valid, there are already duplicate identifier checks
|
||||
return !isAccessor(declaration);
|
||||
}
|
||||
|
||||
function isNotOverload(declaration: Declaration): boolean {
|
||||
return (declaration.kind !== SyntaxKind.FunctionDeclaration && declaration.kind !== SyntaxKind.MethodDeclaration) ||
|
||||
!!(declaration as FunctionDeclaration).body;
|
||||
}
|
||||
|
||||
function checkSourceElement(node: Node): void {
|
||||
@@ -23479,6 +23509,15 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getTypeReferenceSerializationKind(typeName: EntityName, location?: Node): TypeReferenceSerializationKind {
|
||||
// ensure both `typeName` and `location` are parse tree nodes.
|
||||
typeName = getParseTreeNode(typeName, isEntityName);
|
||||
if (!typeName) return TypeReferenceSerializationKind.Unknown;
|
||||
|
||||
if (location) {
|
||||
location = getParseTreeNode(location);
|
||||
if (!location) return TypeReferenceSerializationKind.Unknown;
|
||||
}
|
||||
|
||||
// Resolve the symbol as a value to ensure the type can be reached at runtime during emit.
|
||||
const valueSymbol = resolveEntityName(typeName, SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location);
|
||||
|
||||
@@ -23767,7 +23806,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Initialize global symbol table
|
||||
let augmentations: ReadonlyArray<StringLiteral>[];
|
||||
let augmentations: ReadonlyArray<StringLiteral | Identifier>[];
|
||||
for (const file of host.getSourceFiles()) {
|
||||
if (!isExternalOrCommonJsModule(file)) {
|
||||
mergeSymbolTable(globals, file.locals);
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace ts {
|
||||
let declarationListContainerEnd = -1;
|
||||
let currentSourceFile: SourceFile;
|
||||
let currentText: string;
|
||||
let currentLineMap: number[];
|
||||
let currentLineMap: ReadonlyArray<number>;
|
||||
let detachedCommentsInfo: { nodePos: number, detachedCommentEndPos: number}[];
|
||||
let hasWrittenComment = false;
|
||||
let disabled: boolean = printerOptions.removeComments;
|
||||
|
||||
@@ -715,7 +715,7 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function sum<T extends Record<K, number>, K extends string>(array: T[], prop: K): number {
|
||||
export function sum<T extends Record<K, number>, K extends string>(array: ReadonlyArray<T>, prop: K): number {
|
||||
let result = 0;
|
||||
for (const v of array) {
|
||||
// TODO: Remove the following type assertion once the fix for #17069 is merged
|
||||
@@ -2626,4 +2626,8 @@ namespace ts {
|
||||
export function isCheckJsEnabledForFile(sourceFile: SourceFile, compilerOptions: CompilerOptions) {
|
||||
return sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : compilerOptions.checkJs;
|
||||
}
|
||||
|
||||
export function and<T>(f: (arg: T) => boolean, g: (arg: T) => boolean) {
|
||||
return (arg: T) => f(arg) && g(arg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace ts {
|
||||
let enclosingDeclaration: Node;
|
||||
let resultHasExternalModuleIndicator: boolean;
|
||||
let currentText: string;
|
||||
let currentLineMap: number[];
|
||||
let currentLineMap: ReadonlyArray<number>;
|
||||
let currentIdentifiers: Map<string>;
|
||||
let isCurrentFileExternalModule: boolean;
|
||||
let reportedDeclarationError = false;
|
||||
|
||||
@@ -3696,7 +3696,7 @@
|
||||
"code": 95003
|
||||
},
|
||||
|
||||
"Extract function into '{0}'": {
|
||||
"Extract function into {0}": {
|
||||
"category": "Message",
|
||||
"code": 95004
|
||||
}
|
||||
|
||||
+44
-3
@@ -2339,13 +2339,13 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createBundle(sourceFiles: SourceFile[]) {
|
||||
export function createBundle(sourceFiles: ReadonlyArray<SourceFile>) {
|
||||
const node = <Bundle>createNode(SyntaxKind.Bundle);
|
||||
node.sourceFiles = sourceFiles;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateBundle(node: Bundle, sourceFiles: SourceFile[]) {
|
||||
export function updateBundle(node: Bundle, sourceFiles: ReadonlyArray<SourceFile>) {
|
||||
if (node.sourceFiles !== sourceFiles) {
|
||||
return createBundle(sourceFiles);
|
||||
}
|
||||
@@ -2372,6 +2372,24 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
export function createImmediatelyInvokedArrowFunction(statements: Statement[]): CallExpression;
|
||||
export function createImmediatelyInvokedArrowFunction(statements: Statement[], param: ParameterDeclaration, paramValue: Expression): CallExpression;
|
||||
export function createImmediatelyInvokedArrowFunction(statements: Statement[], param?: ParameterDeclaration, paramValue?: Expression) {
|
||||
return createCall(
|
||||
createArrowFunction(
|
||||
/*modifiers*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
/*parameters*/ param ? [param] : [],
|
||||
/*type*/ undefined,
|
||||
/*equalsGreaterThanToken*/ undefined,
|
||||
createBlock(statements, /*multiLine*/ true)
|
||||
),
|
||||
/*typeArguments*/ undefined,
|
||||
/*argumentsArray*/ paramValue ? [paramValue] : []
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
export function createComma(left: Expression, right: Expression) {
|
||||
return <Expression>createBinary(left, SyntaxKind.CommaToken, right);
|
||||
}
|
||||
@@ -4036,8 +4054,31 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a node is a parenthesized expression that can be ignored when recreating outer expressions.
|
||||
*
|
||||
* A parenthesized expression can be ignored when all of the following are true:
|
||||
*
|
||||
* - It's `pos` and `end` are not -1
|
||||
* - It does not have a custom source map range
|
||||
* - It does not have a custom comment range
|
||||
* - It does not have synthetic leading or trailing comments
|
||||
*
|
||||
* If an outermost parenthesized expression is ignored, but the containing expression requires a parentheses around
|
||||
* the expression to maintain precedence, a new parenthesized expression should be created automatically when
|
||||
* the containing expression is created/updated.
|
||||
*/
|
||||
function isIgnorableParen(node: Expression) {
|
||||
return node.kind === SyntaxKind.ParenthesizedExpression
|
||||
&& nodeIsSynthesized(node)
|
||||
&& nodeIsSynthesized(getSourceMapRange(node))
|
||||
&& nodeIsSynthesized(getCommentRange(node))
|
||||
&& !some(getSyntheticLeadingComments(node))
|
||||
&& !some(getSyntheticTrailingComments(node));
|
||||
}
|
||||
|
||||
export function recreateOuterExpressions(outerExpression: Expression | undefined, innerExpression: Expression, kinds = OuterExpressionKinds.All): Expression {
|
||||
if (outerExpression && isOuterExpression(outerExpression, kinds)) {
|
||||
if (outerExpression && isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) {
|
||||
return updateOuterExpression(
|
||||
outerExpression,
|
||||
recreateOuterExpressions(outerExpression.expression, innerExpression)
|
||||
|
||||
+43
-31
@@ -205,13 +205,15 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[] {
|
||||
let diagnostics = program.getOptionsDiagnostics(cancellationToken).concat(
|
||||
program.getSyntacticDiagnostics(sourceFile, cancellationToken),
|
||||
program.getGlobalDiagnostics(cancellationToken),
|
||||
program.getSemanticDiagnostics(sourceFile, cancellationToken));
|
||||
const diagnostics = [
|
||||
...program.getOptionsDiagnostics(cancellationToken),
|
||||
...program.getSyntacticDiagnostics(sourceFile, cancellationToken),
|
||||
...program.getGlobalDiagnostics(cancellationToken),
|
||||
...program.getSemanticDiagnostics(sourceFile, cancellationToken)
|
||||
];
|
||||
|
||||
if (program.getCompilerOptions().declaration) {
|
||||
diagnostics = diagnostics.concat(program.getDeclarationDiagnostics(sourceFile, cancellationToken));
|
||||
addRange(diagnostics, program.getDeclarationDiagnostics(sourceFile, cancellationToken));
|
||||
}
|
||||
|
||||
return sortAndDeduplicateDiagnostics(diagnostics);
|
||||
@@ -223,7 +225,7 @@ namespace ts {
|
||||
getNewLine(): string;
|
||||
}
|
||||
|
||||
export function formatDiagnostics(diagnostics: Diagnostic[], host: FormatDiagnosticsHost): string {
|
||||
export function formatDiagnostics(diagnostics: ReadonlyArray<Diagnostic>, host: FormatDiagnosticsHost): string {
|
||||
let output = "";
|
||||
|
||||
for (const diagnostic of diagnostics) {
|
||||
@@ -399,7 +401,7 @@ namespace ts {
|
||||
* @param oldProgram - Reuses an old program structure.
|
||||
* @returns A 'Program' object.
|
||||
*/
|
||||
export function createProgram(rootNames: string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program): Program {
|
||||
export function createProgram(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: Program): Program {
|
||||
let program: Program;
|
||||
let files: SourceFile[] = [];
|
||||
let commonSourceDirectory: string;
|
||||
@@ -888,7 +890,7 @@ namespace ts {
|
||||
for (const { oldFile: oldSourceFile, newFile: newSourceFile } of modifiedSourceFiles) {
|
||||
const newSourceFilePath = getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory);
|
||||
if (resolveModuleNamesWorker) {
|
||||
const moduleNames = map(concatenate(newSourceFile.imports, newSourceFile.moduleAugmentations), getTextOfLiteral);
|
||||
const moduleNames = getModuleNames(newSourceFile);
|
||||
const oldProgramState = { program: oldProgram, file: oldSourceFile, modifiedFilePaths };
|
||||
const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFilePath, newSourceFile, oldProgramState);
|
||||
// ensure that module resolution results are still correct
|
||||
@@ -996,7 +998,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function emitWorker(program: Program, sourceFile: SourceFile, writeFileCallback: WriteFileCallback, cancellationToken: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult {
|
||||
let declarationDiagnostics: Diagnostic[] = [];
|
||||
let declarationDiagnostics: ReadonlyArray<Diagnostic> = [];
|
||||
|
||||
if (options.noEmit) {
|
||||
return { diagnostics: declarationDiagnostics, sourceMaps: undefined, emittedFiles: undefined, emitSkipped: true };
|
||||
@@ -1006,10 +1008,12 @@ namespace ts {
|
||||
// immediately bail out. Note that we pass 'undefined' for 'sourceFile' so that we
|
||||
// get any preEmit diagnostics, not just the ones
|
||||
if (options.noEmitOnError) {
|
||||
const diagnostics = program.getOptionsDiagnostics(cancellationToken).concat(
|
||||
program.getSyntacticDiagnostics(sourceFile, cancellationToken),
|
||||
program.getGlobalDiagnostics(cancellationToken),
|
||||
program.getSemanticDiagnostics(sourceFile, cancellationToken));
|
||||
const diagnostics = [
|
||||
...program.getOptionsDiagnostics(cancellationToken),
|
||||
...program.getSyntacticDiagnostics(sourceFile, cancellationToken),
|
||||
...program.getGlobalDiagnostics(cancellationToken),
|
||||
...program.getSemanticDiagnostics(sourceFile, cancellationToken)
|
||||
];
|
||||
|
||||
if (diagnostics.length === 0 && program.getCompilerOptions().declaration) {
|
||||
declarationDiagnostics = program.getDeclarationDiagnostics(/*sourceFile*/ undefined, cancellationToken);
|
||||
@@ -1060,8 +1064,8 @@ namespace ts {
|
||||
|
||||
function getDiagnosticsHelper(
|
||||
sourceFile: SourceFile,
|
||||
getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationToken) => Diagnostic[],
|
||||
cancellationToken: CancellationToken): Diagnostic[] {
|
||||
getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationToken) => ReadonlyArray<Diagnostic>,
|
||||
cancellationToken: CancellationToken): ReadonlyArray<Diagnostic> {
|
||||
if (sourceFile) {
|
||||
return getDiagnostics(sourceFile, cancellationToken);
|
||||
}
|
||||
@@ -1073,15 +1077,15 @@ namespace ts {
|
||||
}));
|
||||
}
|
||||
|
||||
function getSyntacticDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
function getSyntacticDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): ReadonlyArray<Diagnostic> {
|
||||
return getDiagnosticsHelper(sourceFile, getSyntacticDiagnosticsForFile, cancellationToken);
|
||||
}
|
||||
|
||||
function getSemanticDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
function getSemanticDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): ReadonlyArray<Diagnostic> {
|
||||
return getDiagnosticsHelper(sourceFile, getSemanticDiagnosticsForFile, cancellationToken);
|
||||
}
|
||||
|
||||
function getDeclarationDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
function getDeclarationDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): ReadonlyArray<Diagnostic> {
|
||||
const options = program.getCompilerOptions();
|
||||
// collect diagnostics from the program only once if either no source file was specified or out/outFile is set (bundled emit)
|
||||
if (!sourceFile || options.out || options.outFile) {
|
||||
@@ -1092,7 +1096,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getSyntacticDiagnosticsForFile(sourceFile: SourceFile): Diagnostic[] {
|
||||
function getSyntacticDiagnosticsForFile(sourceFile: SourceFile): ReadonlyArray<Diagnostic> {
|
||||
// For JavaScript files, we report semantic errors for using TypeScript-only
|
||||
// constructs from within a JavaScript file as syntactic errors.
|
||||
if (isSourceFileJavaScript(sourceFile)) {
|
||||
@@ -1430,12 +1434,10 @@ namespace ts {
|
||||
return a.fileName === b.fileName;
|
||||
}
|
||||
|
||||
function moduleNameIsEqualTo(a: LiteralExpression, b: LiteralExpression): boolean {
|
||||
return a.text === b.text;
|
||||
}
|
||||
|
||||
function getTextOfLiteral(literal: LiteralExpression): string {
|
||||
return literal.text;
|
||||
function moduleNameIsEqualTo(a: StringLiteral | Identifier, b: StringLiteral | Identifier): boolean {
|
||||
return a.kind === SyntaxKind.StringLiteral
|
||||
? b.kind === SyntaxKind.StringLiteral && a.text === b.text
|
||||
: b.kind === SyntaxKind.Identifier && a.escapedText === b.escapedText;
|
||||
}
|
||||
|
||||
function collectExternalModuleReferences(file: SourceFile): void {
|
||||
@@ -1448,7 +1450,7 @@ namespace ts {
|
||||
|
||||
// file.imports may not be undefined if there exists dynamic import
|
||||
let imports: StringLiteral[];
|
||||
let moduleAugmentations: StringLiteral[];
|
||||
let moduleAugmentations: Array<StringLiteral | Identifier>;
|
||||
let ambientModules: string[];
|
||||
|
||||
// If we are importing helpers, we need to add a synthetic reference to resolve the
|
||||
@@ -1477,7 +1479,7 @@ namespace ts {
|
||||
|
||||
return;
|
||||
|
||||
function collectModuleReferences(node: Node, inAmbientModule: boolean): void {
|
||||
function collectModuleReferences(node: Statement, inAmbientModule: boolean): void {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
@@ -1499,8 +1501,8 @@ namespace ts {
|
||||
break;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
if (isAmbientModule(<ModuleDeclaration>node) && (inAmbientModule || hasModifier(node, ModifierFlags.Ambient) || file.isDeclarationFile)) {
|
||||
const moduleName = <StringLiteral>(<ModuleDeclaration>node).name; // TODO: GH#17347
|
||||
const nameText = ts.getTextOfIdentifierOrLiteral(moduleName);
|
||||
const moduleName = (<ModuleDeclaration>node).name;
|
||||
const nameText = getTextOfIdentifierOrLiteral(moduleName);
|
||||
// Ambient module declarations can be interpreted as augmentations for some existing external modules.
|
||||
// This will happen in two cases:
|
||||
// - if current file is external module then module augmentation is a ambient module declaration defined in the top level scope
|
||||
@@ -1817,8 +1819,7 @@ namespace ts {
|
||||
collectExternalModuleReferences(file);
|
||||
if (file.imports.length || file.moduleAugmentations.length) {
|
||||
// Because global augmentation doesn't have string literal name, we can check for global augmentation as such.
|
||||
const nonGlobalAugmentation = filter(file.moduleAugmentations, (moduleAugmentation) => moduleAugmentation.kind === SyntaxKind.StringLiteral);
|
||||
const moduleNames = map(concatenate(file.imports, nonGlobalAugmentation), getTextOfLiteral);
|
||||
const moduleNames = getModuleNames(file);
|
||||
const oldProgramState = { program: oldProgram, file, modifiedFilePaths };
|
||||
const resolutions = resolveModuleNamesReusingOldState(moduleNames, getNormalizedAbsolutePath(file.fileName, currentDirectory), file, oldProgramState);
|
||||
Debug.assert(resolutions.length === moduleNames.length);
|
||||
@@ -2229,4 +2230,15 @@ namespace ts {
|
||||
Debug.assert(names.every(name => name !== undefined), "A name is undefined.", () => JSON.stringify(names));
|
||||
return names;
|
||||
}
|
||||
|
||||
function getModuleNames({ imports, moduleAugmentations }: SourceFile): string[] {
|
||||
const res = imports.map(i => i.text);
|
||||
for (const aug of moduleAugmentations) {
|
||||
if (aug.kind === SyntaxKind.StringLiteral) {
|
||||
res.push(aug.text);
|
||||
}
|
||||
// Do nothing if it's an Identifier; we don't need to do module resolution for `declare global`.
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,7 +343,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function getLineStarts(sourceFile: SourceFileLike): number[] {
|
||||
export function getLineStarts(sourceFile: SourceFileLike): ReadonlyArray<number> {
|
||||
return sourceFile.lineMap || (sourceFile.lineMap = computeLineStarts(sourceFile.text));
|
||||
}
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace ts {
|
||||
* @param transforms An array of `TransformerFactory` callbacks.
|
||||
* @param allowDtsFiles A value indicating whether to allow the transformation of .d.ts files.
|
||||
*/
|
||||
export function transformNodes<T extends Node>(resolver: EmitResolver, host: EmitHost, options: CompilerOptions, nodes: T[], transformers: TransformerFactory<T>[], allowDtsFiles: boolean): TransformationResult<T> {
|
||||
export function transformNodes<T extends Node>(resolver: EmitResolver, host: EmitHost, options: CompilerOptions, nodes: ReadonlyArray<T>, transformers: ReadonlyArray<TransformerFactory<T>>, allowDtsFiles: boolean): TransformationResult<T> {
|
||||
const enabledSyntaxKindFeatures = new Array<SyntaxKindFeatureFlags>(SyntaxKind.Count);
|
||||
let lexicalEnvironmentVariableDeclarations: VariableDeclaration[];
|
||||
let lexicalEnvironmentFunctionDeclarations: FunctionDeclaration[];
|
||||
|
||||
@@ -409,7 +409,7 @@ namespace ts {
|
||||
*/
|
||||
function createDestructuringPropertyAccess(flattenContext: FlattenContext, value: Expression, propertyName: PropertyName): LeftHandSideExpression {
|
||||
if (isComputedPropertyName(propertyName)) {
|
||||
const argumentExpression = ensureIdentifier(flattenContext, propertyName.expression, /*reuseIdentifierExpressions*/ false, /*location*/ propertyName);
|
||||
const argumentExpression = ensureIdentifier(flattenContext, visitNode(propertyName.expression, flattenContext.visitor), /*reuseIdentifierExpressions*/ false, /*location*/ propertyName);
|
||||
return createElementAccess(value, argumentExpression);
|
||||
}
|
||||
else if (isStringOrNumericLiteral(propertyName)) {
|
||||
|
||||
@@ -339,64 +339,12 @@ namespace ts {
|
||||
&& !(<ReturnStatement>node).expression;
|
||||
}
|
||||
|
||||
function isClassLikeVariableStatement(node: Node) {
|
||||
if (!isVariableStatement(node)) return false;
|
||||
const variable = singleOrUndefined((<VariableStatement>node).declarationList.declarations);
|
||||
return variable
|
||||
&& variable.initializer
|
||||
&& isIdentifier(variable.name)
|
||||
&& (isClassLike(variable.initializer)
|
||||
|| (isAssignmentExpression(variable.initializer)
|
||||
&& isIdentifier(variable.initializer.left)
|
||||
&& isClassLike(variable.initializer.right)));
|
||||
}
|
||||
|
||||
function isTypeScriptClassWrapper(node: Node) {
|
||||
const call = tryCast(node, isCallExpression);
|
||||
if (!call || isParseTreeNode(call) ||
|
||||
some(call.typeArguments) ||
|
||||
some(call.arguments)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const func = tryCast(skipOuterExpressions(call.expression), isFunctionExpression);
|
||||
if (!func || isParseTreeNode(func) ||
|
||||
some(func.typeParameters) ||
|
||||
some(func.parameters) ||
|
||||
func.type ||
|
||||
!func.body) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const statements = func.body.statements;
|
||||
if (statements.length < 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const firstStatement = statements[0];
|
||||
if (isParseTreeNode(firstStatement) ||
|
||||
!isClassLike(firstStatement) &&
|
||||
!isClassLikeVariableStatement(firstStatement)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const lastStatement = elementAt(statements, -1);
|
||||
const returnStatement = tryCast(isVariableStatement(lastStatement) ? elementAt(statements, -2) : lastStatement, isReturnStatement);
|
||||
if (!returnStatement ||
|
||||
!returnStatement.expression ||
|
||||
!isIdentifier(skipOuterExpressions(returnStatement.expression))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function shouldVisitNode(node: Node): boolean {
|
||||
return (node.transformFlags & TransformFlags.ContainsES2015) !== 0
|
||||
|| convertedLoopState !== undefined
|
||||
|| (hierarchyFacts & HierarchyFacts.ConstructorWithCapturedSuper && (isStatement(node) || (node.kind === SyntaxKind.Block)))
|
||||
|| (isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatementBody(node))
|
||||
|| isTypeScriptClassWrapper(node);
|
||||
|| (getEmitFlags(node) & EmitFlags.TypeScriptClassWrapper) !== 0;
|
||||
}
|
||||
|
||||
function visitor(node: Node): VisitResult<Node> {
|
||||
@@ -3308,13 +3256,14 @@ namespace ts {
|
||||
* @param node a CallExpression.
|
||||
*/
|
||||
function visitCallExpression(node: CallExpression) {
|
||||
if (isTypeScriptClassWrapper(node)) {
|
||||
if (getEmitFlags(node) & EmitFlags.TypeScriptClassWrapper) {
|
||||
return visitTypeScriptClassWrapper(node);
|
||||
}
|
||||
|
||||
if (node.transformFlags & TransformFlags.ES2015) {
|
||||
return visitCallExpressionWithPotentialCapturedThisAssignment(node, /*assignToCapturedThis*/ true);
|
||||
}
|
||||
|
||||
return updateCall(
|
||||
node,
|
||||
visitNode(node.expression, callExpressionVisitor, isExpression),
|
||||
@@ -3357,7 +3306,7 @@ namespace ts {
|
||||
|
||||
// We skip any outer expressions in a number of places to get to the innermost
|
||||
// expression, but we will restore them later to preserve comments and source maps.
|
||||
const body = cast(skipOuterExpressions(node.expression), isFunctionExpression).body;
|
||||
const body = cast(cast(skipOuterExpressions(node.expression), isArrowFunction).body, isBlock);
|
||||
|
||||
// The class statements are the statements generated by visiting the first statement of the
|
||||
// body (1), while all other statements are added to remainingStatements (2)
|
||||
|
||||
@@ -430,26 +430,29 @@ namespace ts {
|
||||
*/
|
||||
function addExportEqualsIfNeeded(statements: Statement[], emitAsReturn: boolean) {
|
||||
if (currentModuleInfo.exportEquals) {
|
||||
if (emitAsReturn) {
|
||||
const statement = createReturn(currentModuleInfo.exportEquals.expression);
|
||||
setTextRange(statement, currentModuleInfo.exportEquals);
|
||||
setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoComments);
|
||||
statements.push(statement);
|
||||
}
|
||||
else {
|
||||
const statement = createStatement(
|
||||
createAssignment(
|
||||
createPropertyAccess(
|
||||
createIdentifier("module"),
|
||||
"exports"
|
||||
),
|
||||
currentModuleInfo.exportEquals.expression
|
||||
)
|
||||
);
|
||||
const expressionResult = visitNode(currentModuleInfo.exportEquals.expression, importCallExpressionVisitor);
|
||||
if (expressionResult) {
|
||||
if (emitAsReturn) {
|
||||
const statement = createReturn(expressionResult);
|
||||
setTextRange(statement, currentModuleInfo.exportEquals);
|
||||
setEmitFlags(statement, EmitFlags.NoTokenSourceMaps | EmitFlags.NoComments);
|
||||
statements.push(statement);
|
||||
}
|
||||
else {
|
||||
const statement = createStatement(
|
||||
createAssignment(
|
||||
createPropertyAccess(
|
||||
createIdentifier("module"),
|
||||
"exports"
|
||||
),
|
||||
expressionResult
|
||||
)
|
||||
);
|
||||
|
||||
setTextRange(statement, currentModuleInfo.exportEquals);
|
||||
setEmitFlags(statement, EmitFlags.NoComments);
|
||||
statements.push(statement);
|
||||
setTextRange(statement, currentModuleInfo.exportEquals);
|
||||
setEmitFlags(statement, EmitFlags.NoComments);
|
||||
statements.push(statement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -497,7 +500,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function importCallExpressionVisitor(node: Node): VisitResult<Node> {
|
||||
function importCallExpressionVisitor(node: Expression): VisitResult<Expression> {
|
||||
// This visitor does not need to descend into the tree if there is no dynamic import,
|
||||
// as export/import statements are only transformed at the top level of a file.
|
||||
if (!(node.transformFlags & TransformFlags.ContainsDynamicImport)) {
|
||||
@@ -1204,7 +1207,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (hasModifier(decl, ModifierFlags.Export)) {
|
||||
const exportName = hasModifier(decl, ModifierFlags.Default) ? createIdentifier("default") : decl.name;
|
||||
const exportName = hasModifier(decl, ModifierFlags.Default) ? createIdentifier("default") : getDeclarationName(decl);
|
||||
statements = appendExportStatement(statements, exportName, getLocalName(decl), /*location*/ decl);
|
||||
}
|
||||
|
||||
|
||||
@@ -613,13 +613,16 @@ namespace ts {
|
||||
|
||||
addRange(statements, context.endLexicalEnvironment());
|
||||
|
||||
const iife = createImmediatelyInvokedArrowFunction(statements);
|
||||
setEmitFlags(iife, EmitFlags.TypeScriptClassWrapper);
|
||||
|
||||
const varStatement = createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList([
|
||||
createVariableDeclaration(
|
||||
getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ false),
|
||||
/*type*/ undefined,
|
||||
createImmediatelyInvokedFunctionExpression(statements)
|
||||
iife
|
||||
)
|
||||
])
|
||||
);
|
||||
@@ -1944,7 +1947,7 @@ namespace ts {
|
||||
const name = getMutableClone(<Identifier>node);
|
||||
name.flags &= ~NodeFlags.Synthesized;
|
||||
name.original = undefined;
|
||||
name.parent = currentScope;
|
||||
name.parent = getParseTreeNode(currentScope); // ensure the parent is set to a parse tree node.
|
||||
if (useFallback) {
|
||||
return createLogicalAnd(
|
||||
createStrictInequality(
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace ts {
|
||||
else {
|
||||
// export class x { }
|
||||
const name = (<ClassDeclaration>node).name;
|
||||
if (!uniqueExports.get(unescapeLeadingUnderscores(name.escapedText))) {
|
||||
if (name && !uniqueExports.get(unescapeLeadingUnderscores(name.escapedText))) {
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
|
||||
uniqueExports.set(unescapeLeadingUnderscores(name.escapedText), true);
|
||||
exportedNames = append(exportedNames, name);
|
||||
|
||||
+3
-3
@@ -469,7 +469,7 @@ namespace ts {
|
||||
let diagnostics: Diagnostic[];
|
||||
|
||||
// First get and report any syntactic errors.
|
||||
diagnostics = program.getSyntacticDiagnostics();
|
||||
diagnostics = program.getSyntacticDiagnostics().slice();
|
||||
|
||||
// If we didn't have any syntactic errors, then also try getting the global and
|
||||
// semantic errors.
|
||||
@@ -477,13 +477,13 @@ namespace ts {
|
||||
diagnostics = program.getOptionsDiagnostics().concat(program.getGlobalDiagnostics());
|
||||
|
||||
if (diagnostics.length === 0) {
|
||||
diagnostics = program.getSemanticDiagnostics();
|
||||
diagnostics = program.getSemanticDiagnostics().slice();
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, emit and report any errors we ran into.
|
||||
const emitOutput = program.emit();
|
||||
diagnostics = diagnostics.concat(emitOutput.diagnostics);
|
||||
addRange(diagnostics, emitOutput.diagnostics);
|
||||
|
||||
reportDiagnostics(sortAndDeduplicateDiagnostics(diagnostics), compilerHost);
|
||||
|
||||
|
||||
+27
-23
@@ -2254,7 +2254,7 @@ namespace ts {
|
||||
*/
|
||||
export interface SourceFileLike {
|
||||
readonly text: string;
|
||||
lineMap: number[];
|
||||
lineMap: ReadonlyArray<number>;
|
||||
}
|
||||
|
||||
|
||||
@@ -2286,16 +2286,16 @@ namespace ts {
|
||||
*/
|
||||
/* @internal */ redirectInfo?: RedirectInfo | undefined;
|
||||
|
||||
amdDependencies: AmdDependency[];
|
||||
amdDependencies: ReadonlyArray<AmdDependency>;
|
||||
moduleName: string;
|
||||
referencedFiles: FileReference[];
|
||||
typeReferenceDirectives: FileReference[];
|
||||
referencedFiles: ReadonlyArray<FileReference>;
|
||||
typeReferenceDirectives: ReadonlyArray<FileReference>;
|
||||
languageVariant: LanguageVariant;
|
||||
isDeclarationFile: boolean;
|
||||
|
||||
// this map is used by transpiler to supply alternative names for dependencies (i.e. in case of bundling)
|
||||
/* @internal */
|
||||
renamedDependencies?: Map<string>;
|
||||
renamedDependencies?: ReadonlyMap<string>;
|
||||
|
||||
/**
|
||||
* lib.d.ts should have a reference comment like
|
||||
@@ -2331,19 +2331,20 @@ namespace ts {
|
||||
/* @internal */ jsDocDiagnostics?: Diagnostic[];
|
||||
|
||||
// Stores additional file-level diagnostics reported by the program
|
||||
/* @internal */ additionalSyntacticDiagnostics?: Diagnostic[];
|
||||
/* @internal */ additionalSyntacticDiagnostics?: ReadonlyArray<Diagnostic>;
|
||||
|
||||
// Stores a line map for the file.
|
||||
// This field should never be used directly to obtain line map, use getLineMap function instead.
|
||||
/* @internal */ lineMap: number[];
|
||||
/* @internal */ classifiableNames?: UnderscoreEscapedMap<true>;
|
||||
/* @internal */ lineMap: ReadonlyArray<number>;
|
||||
/* @internal */ classifiableNames?: ReadonlyUnderscoreEscapedMap<true>;
|
||||
// Stores a mapping 'external module reference text' -> 'resolved file name' | undefined
|
||||
// It is used to resolve module names in the checker.
|
||||
// Content of this field should never be used directly - use getResolvedModuleFileName/setResolvedModuleFileName functions instead
|
||||
/* @internal */ resolvedModules: Map<ResolvedModuleFull>;
|
||||
/* @internal */ resolvedTypeReferenceDirectiveNames: Map<ResolvedTypeReferenceDirective>;
|
||||
/* @internal */ imports: ReadonlyArray<StringLiteral>;
|
||||
/* @internal */ moduleAugmentations: ReadonlyArray<StringLiteral>;
|
||||
// Identifier only if `declare global`
|
||||
/* @internal */ moduleAugmentations: ReadonlyArray<StringLiteral | Identifier>;
|
||||
/* @internal */ patternAmbientModules?: PatternAmbientModule[];
|
||||
/* @internal */ ambientModuleNames: ReadonlyArray<string>;
|
||||
/* @internal */ checkJsDirective: CheckJsDirective | undefined;
|
||||
@@ -2351,7 +2352,7 @@ namespace ts {
|
||||
|
||||
export interface Bundle extends Node {
|
||||
kind: SyntaxKind.Bundle;
|
||||
sourceFiles: SourceFile[];
|
||||
sourceFiles: ReadonlyArray<SourceFile>;
|
||||
}
|
||||
|
||||
export interface JsonSourceFile extends SourceFile {
|
||||
@@ -2398,19 +2399,19 @@ namespace ts {
|
||||
/**
|
||||
* Get a list of root file names that were passed to a 'createProgram'
|
||||
*/
|
||||
getRootFileNames(): string[];
|
||||
getRootFileNames(): ReadonlyArray<string>;
|
||||
|
||||
/**
|
||||
* Get a list of files in the program
|
||||
*/
|
||||
getSourceFiles(): SourceFile[];
|
||||
getSourceFiles(): ReadonlyArray<SourceFile>;
|
||||
|
||||
/**
|
||||
* Get a list of file names that were passed to 'createProgram' or referenced in a
|
||||
* program source file but could not be located.
|
||||
*/
|
||||
/* @internal */
|
||||
getMissingFilePaths(): Path[];
|
||||
getMissingFilePaths(): ReadonlyArray<Path>;
|
||||
|
||||
/**
|
||||
* Emits the JavaScript and declaration files. If targetSourceFile is not specified, then
|
||||
@@ -2424,11 +2425,11 @@ namespace ts {
|
||||
*/
|
||||
emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult;
|
||||
|
||||
getOptionsDiagnostics(cancellationToken?: CancellationToken): Diagnostic[];
|
||||
getGlobalDiagnostics(cancellationToken?: CancellationToken): Diagnostic[];
|
||||
getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[];
|
||||
getSemanticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[];
|
||||
getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[];
|
||||
getOptionsDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
getGlobalDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
getSemanticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
|
||||
/**
|
||||
* Gets a type checker that can be used to semantically analyze source files in the program.
|
||||
@@ -2522,7 +2523,7 @@ namespace ts {
|
||||
export interface EmitResult {
|
||||
emitSkipped: boolean;
|
||||
/** Contains declaration emit diagnostics */
|
||||
diagnostics: Diagnostic[];
|
||||
diagnostics: ReadonlyArray<Diagnostic>;
|
||||
emittedFiles: string[]; // Array of files the compiler wrote to disk
|
||||
/* @internal */ sourceMaps: SourceMapData[]; // Array of sourceMapData if compiler emitted sourcemaps
|
||||
}
|
||||
@@ -2531,9 +2532,9 @@ namespace ts {
|
||||
export interface TypeCheckerHost {
|
||||
getCompilerOptions(): CompilerOptions;
|
||||
|
||||
getSourceFiles(): SourceFile[];
|
||||
getSourceFiles(): ReadonlyArray<SourceFile>;
|
||||
getSourceFile(fileName: string): SourceFile;
|
||||
getResolvedTypeReferenceDirectives(): Map<ResolvedTypeReferenceDirective>;
|
||||
getResolvedTypeReferenceDirectives(): ReadonlyMap<ResolvedTypeReferenceDirective>;
|
||||
}
|
||||
|
||||
export interface TypeChecker {
|
||||
@@ -2972,6 +2973,7 @@ namespace ts {
|
||||
leftSpread?: Symbol; // Left source for synthetic spread property
|
||||
rightSpread?: Symbol; // Right source for synthetic spread property
|
||||
syntheticOrigin?: Symbol; // For a property on a mapped or spread type, points back to the original property
|
||||
syntheticLiteralTypeOrigin?: StringLiteralType; // For a property on a mapped type, indicates the type whose text to use as the declaration name, instead of the symbol name
|
||||
isDiscriminantProperty?: boolean; // True if discriminant synthetic property
|
||||
resolvedExports?: SymbolTable; // Resolved exports of module
|
||||
exportsChecked?: boolean; // True if exports of external module have been checked
|
||||
@@ -3315,6 +3317,7 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export interface MappedType extends ObjectType {
|
||||
// { [typeParameter in constraintType]: templateType }
|
||||
declaration: MappedTypeNode;
|
||||
typeParameter?: TypeParameter;
|
||||
constraintType?: Type;
|
||||
@@ -4137,7 +4140,7 @@ namespace ts {
|
||||
export interface SourceMapSource {
|
||||
fileName: string;
|
||||
text: string;
|
||||
/* @internal */ lineMap: number[];
|
||||
/* @internal */ lineMap: ReadonlyArray<number>;
|
||||
skipTrivia?: (pos: number) => number;
|
||||
}
|
||||
|
||||
@@ -4184,6 +4187,7 @@ namespace ts {
|
||||
HasEndOfDeclarationMarker = 1 << 22, // Declaration has an associated NotEmittedStatement to mark the end of the declaration
|
||||
Iterator = 1 << 23, // The expression to a `yield*` should be treated as an Iterator when down-leveling, not an Iterable.
|
||||
NoAsciiEscaping = 1 << 24, // When synthesizing nodes that lack an original node or textSourceNode, we want to write the text on the node with ASCII escaping substitutions.
|
||||
/*@internal*/ TypeScriptClassWrapper = 1 << 25, // The node is an IIFE class wrapper created by the ts transform.
|
||||
}
|
||||
|
||||
export interface EmitHelper {
|
||||
@@ -4244,7 +4248,7 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export interface EmitHost extends ScriptReferenceHost {
|
||||
getSourceFiles(): SourceFile[];
|
||||
getSourceFiles(): ReadonlyArray<SourceFile>;
|
||||
|
||||
/* @internal */
|
||||
isSourceFileFromExternalLibrary(file: SourceFile): boolean;
|
||||
|
||||
+78
-55
@@ -2068,9 +2068,9 @@ namespace ts {
|
||||
|| kind === SyntaxKind.SourceFile;
|
||||
}
|
||||
|
||||
export function nodeIsSynthesized(node: TextRange): boolean {
|
||||
return positionIsSynthesized(node.pos)
|
||||
|| positionIsSynthesized(node.end);
|
||||
export function nodeIsSynthesized(range: TextRange): boolean {
|
||||
return positionIsSynthesized(range.pos)
|
||||
|| positionIsSynthesized(range.end);
|
||||
}
|
||||
|
||||
export function getOriginalSourceFile(sourceFile: SourceFile) {
|
||||
@@ -2380,6 +2380,7 @@ namespace ts {
|
||||
"\u2029": "\\u2029", // paragraphSeparator
|
||||
"\u0085": "\\u0085" // nextLine
|
||||
});
|
||||
const escapedNullRegExp = /\\0[0-9]/g;
|
||||
|
||||
/**
|
||||
* Based heavily on the abstract 'Quote'/'QuoteJSONString' operation from ECMA-262 (24.3.2.2),
|
||||
@@ -2391,7 +2392,11 @@ namespace ts {
|
||||
quoteChar === CharacterCodes.backtick ? backtickQuoteEscapedCharsRegExp :
|
||||
quoteChar === CharacterCodes.singleQuote ? singleQuoteEscapedCharsRegExp :
|
||||
doubleQuoteEscapedCharsRegExp;
|
||||
return s.replace(escapedCharsRegExp, getReplacement);
|
||||
return s.replace(escapedCharsRegExp, getReplacement).replace(escapedNullRegExp, nullReplacement);
|
||||
}
|
||||
|
||||
function nullReplacement(c: string) {
|
||||
return "\\x00" + c.charAt(c.length - 1);
|
||||
}
|
||||
|
||||
function getReplacement(c: string) {
|
||||
@@ -2572,7 +2577,7 @@ namespace ts {
|
||||
* @param host An EmitHost.
|
||||
* @param targetSourceFile An optional target source file to emit.
|
||||
*/
|
||||
export function getSourceFilesToEmit(host: EmitHost, targetSourceFile?: SourceFile): SourceFile[] {
|
||||
export function getSourceFilesToEmit(host: EmitHost, targetSourceFile?: SourceFile): ReadonlyArray<SourceFile> {
|
||||
const options = host.getCompilerOptions();
|
||||
const isSourceFileFromExternalLibrary = (file: SourceFile) => host.isSourceFileFromExternalLibrary(file);
|
||||
if (options.outFile || options.out) {
|
||||
@@ -4946,49 +4951,43 @@ namespace ts {
|
||||
|| kind === SyntaxKind.NoSubstitutionTemplateLiteral;
|
||||
}
|
||||
|
||||
function isLeftHandSideExpressionKind(kind: SyntaxKind): boolean {
|
||||
return kind === SyntaxKind.PropertyAccessExpression
|
||||
|| kind === SyntaxKind.ElementAccessExpression
|
||||
|| kind === SyntaxKind.NewExpression
|
||||
|| kind === SyntaxKind.CallExpression
|
||||
|| kind === SyntaxKind.JsxElement
|
||||
|| kind === SyntaxKind.JsxSelfClosingElement
|
||||
|| kind === SyntaxKind.TaggedTemplateExpression
|
||||
|| kind === SyntaxKind.ArrayLiteralExpression
|
||||
|| kind === SyntaxKind.ParenthesizedExpression
|
||||
|| kind === SyntaxKind.ObjectLiteralExpression
|
||||
|| kind === SyntaxKind.ClassExpression
|
||||
|| kind === SyntaxKind.FunctionExpression
|
||||
|| kind === SyntaxKind.Identifier
|
||||
|| kind === SyntaxKind.RegularExpressionLiteral
|
||||
|| kind === SyntaxKind.NumericLiteral
|
||||
|| kind === SyntaxKind.StringLiteral
|
||||
|| kind === SyntaxKind.NoSubstitutionTemplateLiteral
|
||||
|| kind === SyntaxKind.TemplateExpression
|
||||
|| kind === SyntaxKind.FalseKeyword
|
||||
|| kind === SyntaxKind.NullKeyword
|
||||
|| kind === SyntaxKind.ThisKeyword
|
||||
|| kind === SyntaxKind.TrueKeyword
|
||||
|| kind === SyntaxKind.SuperKeyword
|
||||
|| kind === SyntaxKind.ImportKeyword
|
||||
|| kind === SyntaxKind.NonNullExpression
|
||||
|| kind === SyntaxKind.MetaProperty;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isLeftHandSideExpression(node: Node): node is LeftHandSideExpression {
|
||||
return isLeftHandSideExpressionKind(skipPartiallyEmittedExpressions(node).kind);
|
||||
}
|
||||
|
||||
function isUnaryExpressionKind(kind: SyntaxKind): boolean {
|
||||
return kind === SyntaxKind.PrefixUnaryExpression
|
||||
|| kind === SyntaxKind.PostfixUnaryExpression
|
||||
|| kind === SyntaxKind.DeleteExpression
|
||||
|| kind === SyntaxKind.TypeOfExpression
|
||||
|| kind === SyntaxKind.VoidExpression
|
||||
|| kind === SyntaxKind.AwaitExpression
|
||||
|| kind === SyntaxKind.TypeAssertionExpression
|
||||
|| isLeftHandSideExpressionKind(kind);
|
||||
function isLeftHandSideExpressionKind(kind: SyntaxKind): boolean {
|
||||
switch (kind) {
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.JsxElement:
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
case SyntaxKind.ClassExpression:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.Identifier:
|
||||
case SyntaxKind.RegularExpressionLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
case SyntaxKind.TemplateExpression:
|
||||
case SyntaxKind.FalseKeyword:
|
||||
case SyntaxKind.NullKeyword:
|
||||
case SyntaxKind.ThisKeyword:
|
||||
case SyntaxKind.TrueKeyword:
|
||||
case SyntaxKind.SuperKeyword:
|
||||
case SyntaxKind.NonNullExpression:
|
||||
case SyntaxKind.MetaProperty:
|
||||
case SyntaxKind.ImportKeyword: // technically this is only an Expression if it's in a CallExpression
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -4996,6 +4995,21 @@ namespace ts {
|
||||
return isUnaryExpressionKind(skipPartiallyEmittedExpressions(node).kind);
|
||||
}
|
||||
|
||||
function isUnaryExpressionKind(kind: SyntaxKind): boolean {
|
||||
switch (kind) {
|
||||
case SyntaxKind.PrefixUnaryExpression:
|
||||
case SyntaxKind.PostfixUnaryExpression:
|
||||
case SyntaxKind.DeleteExpression:
|
||||
case SyntaxKind.TypeOfExpression:
|
||||
case SyntaxKind.VoidExpression:
|
||||
case SyntaxKind.AwaitExpression:
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
return true;
|
||||
default:
|
||||
return isLeftHandSideExpressionKind(kind);
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isUnaryExpressionWithWrite(expr: Node): expr is PrefixUnaryExpression | PostfixUnaryExpression {
|
||||
switch (expr.kind) {
|
||||
@@ -5009,23 +5023,32 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function isExpressionKind(kind: SyntaxKind) {
|
||||
return kind === SyntaxKind.ConditionalExpression
|
||||
|| kind === SyntaxKind.YieldExpression
|
||||
|| kind === SyntaxKind.ArrowFunction
|
||||
|| kind === SyntaxKind.BinaryExpression
|
||||
|| kind === SyntaxKind.SpreadElement
|
||||
|| kind === SyntaxKind.AsExpression
|
||||
|| kind === SyntaxKind.OmittedExpression
|
||||
|| kind === SyntaxKind.CommaListExpression
|
||||
|| isUnaryExpressionKind(kind);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
/**
|
||||
* Determines whether a node is an expression based only on its kind.
|
||||
* Use `isPartOfExpression` if not in transforms.
|
||||
*/
|
||||
export function isExpression(node: Node): node is Expression {
|
||||
return isExpressionKind(skipPartiallyEmittedExpressions(node).kind);
|
||||
}
|
||||
|
||||
function isExpressionKind(kind: SyntaxKind): boolean {
|
||||
switch (kind) {
|
||||
case SyntaxKind.ConditionalExpression:
|
||||
case SyntaxKind.YieldExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.BinaryExpression:
|
||||
case SyntaxKind.SpreadElement:
|
||||
case SyntaxKind.AsExpression:
|
||||
case SyntaxKind.OmittedExpression:
|
||||
case SyntaxKind.CommaListExpression:
|
||||
case SyntaxKind.PartiallyEmittedExpression:
|
||||
return true;
|
||||
default:
|
||||
return isUnaryExpressionKind(kind);
|
||||
}
|
||||
}
|
||||
|
||||
export function isAssertionExpression(node: Node): node is AssertionExpression {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.TypeAssertionExpression
|
||||
|
||||
+37
-17
@@ -490,7 +490,8 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
private getDiagnostics(fileName: string): ts.Diagnostic[] {
|
||||
return this.languageService.getSyntacticDiagnostics(fileName).concat(this.languageService.getSemanticDiagnostics(fileName));
|
||||
return ts.concatenate(this.languageService.getSyntacticDiagnostics(fileName),
|
||||
this.languageService.getSemanticDiagnostics(fileName));
|
||||
}
|
||||
|
||||
private getAllDiagnostics(): ts.Diagnostic[] {
|
||||
@@ -1148,7 +1149,7 @@ namespace FourSlash {
|
||||
this.testDiagnostics(expected, diagnostics);
|
||||
}
|
||||
|
||||
private testDiagnostics(expected: string, diagnostics: ts.Diagnostic[]) {
|
||||
private testDiagnostics(expected: string, diagnostics: ReadonlyArray<ts.Diagnostic>) {
|
||||
const realized = ts.realizeDiagnostics(diagnostics, "\r\n");
|
||||
const actual = stringify(realized);
|
||||
assert.equal(actual, expected);
|
||||
@@ -1585,7 +1586,7 @@ namespace FourSlash {
|
||||
public printErrorList() {
|
||||
const syntacticErrors = this.languageService.getSyntacticDiagnostics(this.activeFile.fileName);
|
||||
const semanticErrors = this.languageService.getSemanticDiagnostics(this.activeFile.fileName);
|
||||
const errorList = syntacticErrors.concat(semanticErrors);
|
||||
const errorList = ts.concatenate(syntacticErrors, semanticErrors);
|
||||
Harness.IO.log(`Error list (${errorList.length} errors)`);
|
||||
|
||||
if (errorList.length) {
|
||||
@@ -2760,20 +2761,25 @@ namespace FourSlash {
|
||||
});
|
||||
}
|
||||
|
||||
public verifyRefactorAvailable(negative: boolean, name?: string, subName?: string) {
|
||||
public verifyRefactorAvailable(negative: boolean, name: string, actionName?: string) {
|
||||
const selection = this.getSelection();
|
||||
|
||||
let refactors = this.languageService.getApplicableRefactors(this.activeFile.fileName, selection) || [];
|
||||
if (name) {
|
||||
refactors = refactors.filter(r => r.name === name && (subName === undefined || r.actions.some(a => a.name === subName)));
|
||||
}
|
||||
refactors = refactors.filter(r => r.name === name && (actionName === undefined || r.actions.some(a => a.name === actionName)));
|
||||
const isAvailable = refactors.length > 0;
|
||||
|
||||
if (negative && isAvailable) {
|
||||
this.raiseError(`verifyApplicableRefactorAvailableForRange failed - expected no refactor but found some: ${refactors.map(r => r.name).join(", ")}`);
|
||||
if (negative) {
|
||||
if (isAvailable) {
|
||||
this.raiseError(`verifyApplicableRefactorAvailableForRange failed - expected no refactor but found: ${refactors.map(r => r.name).join(", ")}`);
|
||||
}
|
||||
}
|
||||
else if (!negative && !isAvailable) {
|
||||
this.raiseError(`verifyApplicableRefactorAvailableForRange failed - expected a refactor but found none.`);
|
||||
else {
|
||||
if (!isAvailable) {
|
||||
this.raiseError(`verifyApplicableRefactorAvailableForRange failed - expected a refactor but found none.`);
|
||||
}
|
||||
if (refactors.length > 1) {
|
||||
this.raiseError(`${refactors.length} available refactors both have name ${name} and action ${actionName}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2793,14 +2799,22 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
public applyRefactor(refactorName: string, actionName: string) {
|
||||
public applyRefactor({ refactorName, actionName, actionDescription }: FourSlashInterface.ApplyRefactorOptions) {
|
||||
const range = this.getSelection();
|
||||
const refactors = this.languageService.getApplicableRefactors(this.activeFile.fileName, range);
|
||||
const refactor = ts.find(refactors, r => r.name === refactorName);
|
||||
const refactor = refactors.find(r => r.name === refactorName);
|
||||
if (!refactor) {
|
||||
this.raiseError(`The expected refactor: ${refactorName} is not available at the marker location.`);
|
||||
}
|
||||
|
||||
const action = refactor.actions.find(a => a.name === actionName);
|
||||
if (!action) {
|
||||
this.raiseError(`The expected action: ${action} is not included in: ${refactor.actions.map(a => a.name)}`);
|
||||
}
|
||||
if (action.description !== actionDescription) {
|
||||
this.raiseError(`Expected action description to be ${JSON.stringify(actionDescription)}, got: ${JSON.stringify(action.description)}`);
|
||||
}
|
||||
|
||||
const editInfo = this.languageService.getEditsForRefactor(this.activeFile.fileName, this.formatCodeSettings, range, refactorName, actionName);
|
||||
for (const edit of editInfo.edits) {
|
||||
this.applyEdits(edit.fileName, edit.textChanges, /*isFormattingEdit*/ false);
|
||||
@@ -3681,8 +3695,8 @@ namespace FourSlashInterface {
|
||||
this.state.verifyApplicableRefactorAvailableForRange(this.negative);
|
||||
}
|
||||
|
||||
public refactorAvailable(name?: string, subName?: string) {
|
||||
this.state.verifyRefactorAvailable(this.negative, name, subName);
|
||||
public refactorAvailable(name: string, actionName?: string) {
|
||||
this.state.verifyRefactorAvailable(this.negative, name, actionName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4080,8 +4094,8 @@ namespace FourSlashInterface {
|
||||
this.state.enableFormatting = false;
|
||||
}
|
||||
|
||||
public applyRefactor(refactorName: string, actionName: string) {
|
||||
this.state.applyRefactor(refactorName, actionName);
|
||||
public applyRefactor(options: ApplyRefactorOptions) {
|
||||
this.state.applyRefactor(options);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4294,4 +4308,10 @@ namespace FourSlashInterface {
|
||||
return { classificationType, text, textSpan };
|
||||
}
|
||||
}
|
||||
|
||||
export interface ApplyRefactorOptions {
|
||||
refactorName: string;
|
||||
actionName: string;
|
||||
actionDescription: string;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ namespace Utils {
|
||||
return a !== undefined && typeof a.pos === "number";
|
||||
}
|
||||
|
||||
export function convertDiagnostics(diagnostics: ts.Diagnostic[]) {
|
||||
export function convertDiagnostics(diagnostics: ReadonlyArray<ts.Diagnostic>) {
|
||||
return diagnostics.map(convertDiagnostic);
|
||||
}
|
||||
|
||||
@@ -337,7 +337,7 @@ namespace Utils {
|
||||
}
|
||||
}
|
||||
|
||||
export function assertDiagnosticsEquals(array1: ts.Diagnostic[], array2: ts.Diagnostic[]) {
|
||||
export function assertDiagnosticsEquals(array1: ReadonlyArray<ts.Diagnostic>, array2: ReadonlyArray<ts.Diagnostic>) {
|
||||
if (array1 === array2) {
|
||||
return;
|
||||
}
|
||||
@@ -1284,12 +1284,12 @@ namespace Harness {
|
||||
return normalized;
|
||||
}
|
||||
|
||||
export function minimalDiagnosticsToString(diagnostics: ts.Diagnostic[]) {
|
||||
export function minimalDiagnosticsToString(diagnostics: ReadonlyArray<ts.Diagnostic>) {
|
||||
return ts.formatDiagnostics(diagnostics, { getCanonicalFileName, getCurrentDirectory: () => "", getNewLine: () => Harness.IO.newLine() });
|
||||
}
|
||||
|
||||
export function getErrorBaseline(inputFiles: TestFile[], diagnostics: ts.Diagnostic[]) {
|
||||
diagnostics.sort(ts.compareDiagnostics);
|
||||
export function getErrorBaseline(inputFiles: ReadonlyArray<TestFile>, diagnostics: ReadonlyArray<ts.Diagnostic>) {
|
||||
diagnostics = diagnostics.slice().sort(ts.compareDiagnostics);
|
||||
let outputLines = "";
|
||||
// Count up all errors that were found in files other than lib.d.ts so we don't miss any
|
||||
let totalErrorsReportedInNonLibraryFiles = 0;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
interface ProjectRunnerTestCase {
|
||||
scenario: string;
|
||||
projectRoot: string; // project where it lives - this also is the current directory when compiling
|
||||
inputFiles: string[]; // list of input files to be given to program
|
||||
inputFiles: ReadonlyArray<string>; // list of input files to be given to program
|
||||
resolveMapRoot?: boolean; // should we resolve this map root and give compiler the absolute disk path as map root?
|
||||
resolveSourceRoot?: boolean; // should we resolve this source root and give compiler the absolute disk path as map root?
|
||||
baselineCheck?: boolean; // Verify the baselines of output files, if this is false, we will write to output to the disk but there is no verification of baselines
|
||||
@@ -15,8 +15,8 @@ interface ProjectRunnerTestCase {
|
||||
|
||||
interface ProjectRunnerTestCaseResolutionInfo extends ProjectRunnerTestCase {
|
||||
// Apart from actual test case the results of the resolution
|
||||
resolvedInputFiles: string[]; // List of files that were asked to read by compiler
|
||||
emittedFiles: string[]; // List of files that were emitted by the compiler
|
||||
resolvedInputFiles: ReadonlyArray<string>; // List of files that were asked to read by compiler
|
||||
emittedFiles: ReadonlyArray<string>; // List of files that were emitted by the compiler
|
||||
}
|
||||
|
||||
interface BatchCompileProjectTestCaseEmittedFile extends Harness.Compiler.GeneratedFile {
|
||||
@@ -24,12 +24,12 @@ interface BatchCompileProjectTestCaseEmittedFile extends Harness.Compiler.Genera
|
||||
}
|
||||
|
||||
interface CompileProjectFilesResult {
|
||||
configFileSourceFiles: ts.SourceFile[];
|
||||
configFileSourceFiles: ReadonlyArray<ts.SourceFile>;
|
||||
moduleKind: ts.ModuleKind;
|
||||
program?: ts.Program;
|
||||
compilerOptions?: ts.CompilerOptions;
|
||||
errors: ts.Diagnostic[];
|
||||
sourceMapData?: ts.SourceMapData[];
|
||||
errors: ReadonlyArray<ts.Diagnostic>;
|
||||
sourceMapData?: ReadonlyArray<ts.SourceMapData>;
|
||||
}
|
||||
|
||||
interface BatchCompileProjectTestCaseResult extends CompileProjectFilesResult {
|
||||
@@ -125,17 +125,17 @@ class ProjectRunner extends RunnerBase {
|
||||
return Harness.IO.resolvePath(testCase.projectRoot);
|
||||
}
|
||||
|
||||
function compileProjectFiles(moduleKind: ts.ModuleKind, configFileSourceFiles: ts.SourceFile[],
|
||||
getInputFiles: () => string[],
|
||||
function compileProjectFiles(moduleKind: ts.ModuleKind, configFileSourceFiles: ReadonlyArray<ts.SourceFile>,
|
||||
getInputFiles: () => ReadonlyArray<string>,
|
||||
getSourceFileTextImpl: (fileName: string) => string,
|
||||
writeFile: (fileName: string, data: string, writeByteOrderMark: boolean) => void,
|
||||
compilerOptions: ts.CompilerOptions): CompileProjectFilesResult {
|
||||
|
||||
const program = ts.createProgram(getInputFiles(), compilerOptions, createCompilerHost());
|
||||
let errors = ts.getPreEmitDiagnostics(program);
|
||||
const errors = ts.getPreEmitDiagnostics(program);
|
||||
|
||||
const emitResult = program.emit();
|
||||
errors = ts.concatenate(errors, emitResult.diagnostics);
|
||||
ts.addRange(errors, emitResult.diagnostics);
|
||||
const sourceMapData = emitResult.sourceMaps;
|
||||
|
||||
// Clean up source map data that will be used in baselining
|
||||
@@ -235,7 +235,7 @@ class ProjectRunner extends RunnerBase {
|
||||
compilerOptions,
|
||||
sourceMapData: projectCompilerResult.sourceMapData,
|
||||
outputFiles,
|
||||
errors: errors ? errors.concat(projectCompilerResult.errors) : projectCompilerResult.errors,
|
||||
errors: errors ? ts.concatenate(errors, projectCompilerResult.errors) : projectCompilerResult.errors,
|
||||
};
|
||||
|
||||
function createCompilerOptions() {
|
||||
@@ -422,16 +422,21 @@ class ProjectRunner extends RunnerBase {
|
||||
}
|
||||
|
||||
function getErrorsBaseline(compilerResult: CompileProjectFilesResult) {
|
||||
const inputFiles = ts.map(compilerResult.configFileSourceFiles.concat(
|
||||
compilerResult.program ?
|
||||
ts.filter(compilerResult.program.getSourceFiles(), sourceFile => !Harness.isDefaultLibraryFile(sourceFile.fileName)) :
|
||||
[]),
|
||||
(sourceFile): Harness.Compiler.TestFile => ({
|
||||
unitName: ts.isRootedDiskPath(sourceFile.fileName) ?
|
||||
RunnerBase.removeFullPaths(sourceFile.fileName) :
|
||||
sourceFile.fileName,
|
||||
content: sourceFile.text
|
||||
}));
|
||||
const inputSourceFiles = compilerResult.configFileSourceFiles.slice();
|
||||
if (compilerResult.program) {
|
||||
for (const sourceFile of compilerResult.program.getSourceFiles()) {
|
||||
if (!Harness.isDefaultLibraryFile(sourceFile.fileName)) {
|
||||
inputSourceFiles.push(sourceFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const inputFiles = inputSourceFiles.map<Harness.Compiler.TestFile>(sourceFile => ({
|
||||
unitName: ts.isRootedDiskPath(sourceFile.fileName) ?
|
||||
RunnerBase.removeFullPaths(sourceFile.fileName) :
|
||||
sourceFile.fileName,
|
||||
content: sourceFile.text
|
||||
}));
|
||||
|
||||
return Harness.Compiler.getErrorBaseline(inputFiles, compilerResult.errors);
|
||||
}
|
||||
|
||||
@@ -125,6 +125,7 @@
|
||||
"./unittests/printer.ts",
|
||||
"./unittests/transform.ts",
|
||||
"./unittests/customTransforms.ts",
|
||||
"./unittests/extractMethods.ts",
|
||||
"./unittests/textChanges.ts",
|
||||
"./unittests/telemetry.ts",
|
||||
"./unittests/programMissingFiles.ts"
|
||||
|
||||
@@ -3,12 +3,11 @@
|
||||
|
||||
namespace ts {
|
||||
describe("customTransforms", () => {
|
||||
function emitsCorrectly(name: string, sources: { file: string, text: string }[], customTransformers: CustomTransformers) {
|
||||
function emitsCorrectly(name: string, sources: { file: string, text: string }[], customTransformers: CustomTransformers, options: CompilerOptions = {}) {
|
||||
it(name, () => {
|
||||
const roots = sources.map(source => createSourceFile(source.file, source.text, ScriptTarget.ES2015));
|
||||
const fileMap = arrayToMap(roots, file => file.fileName);
|
||||
const outputs = createMap<string>();
|
||||
const options: CompilerOptions = {};
|
||||
const host: CompilerHost = {
|
||||
getSourceFile: (fileName) => fileMap.get(fileName),
|
||||
getDefaultLibFileName: () => "lib.d.ts",
|
||||
@@ -82,5 +81,25 @@ namespace ts {
|
||||
emitsCorrectly("before", sources, { before: [before] });
|
||||
emitsCorrectly("after", sources, { after: [after] });
|
||||
emitsCorrectly("both", sources, { before: [before], after: [after] });
|
||||
|
||||
emitsCorrectly("before+decorators", [{
|
||||
file: "source.ts",
|
||||
text: `
|
||||
declare const dec: any;
|
||||
class B {}
|
||||
@dec export class C { constructor(b: B) { } }
|
||||
'change'
|
||||
`
|
||||
}], {before: [
|
||||
context => node => visitNode(node, function visitor(node: Node): Node {
|
||||
if (isStringLiteral(node) && node.text === "change") return createLiteral("changed");
|
||||
return visitEachChild(node, visitor, context);
|
||||
})
|
||||
]}, {
|
||||
target: ScriptTarget.ES5,
|
||||
module: ModuleKind.ES2015,
|
||||
emitDecoratorMetadata: true,
|
||||
experimentalDecorators: true
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -425,7 +425,7 @@ export = C;
|
||||
readFile: notImplemented
|
||||
};
|
||||
const program = createProgram(rootFiles, options, host);
|
||||
const diagnostics = sortAndDeduplicateDiagnostics(program.getSemanticDiagnostics().concat(program.getOptionsDiagnostics()));
|
||||
const diagnostics = sortAndDeduplicateDiagnostics([...program.getSemanticDiagnostics(), ...program.getOptionsDiagnostics()]);
|
||||
assert.equal(diagnostics.length, diagnosticCodes.length, `Incorrect number of expected diagnostics, expected ${diagnosticCodes.length}, got '${Harness.Compiler.minimalDiagnosticsToString(diagnostics)}'`);
|
||||
for (let i = 0; i < diagnosticCodes.length; i++) {
|
||||
assert.equal(diagnostics[i].code, diagnosticCodes[i], `Expected diagnostic code ${diagnosticCodes[i]}, got '${diagnostics[i].code}': '${diagnostics[i].messageText}'`);
|
||||
|
||||
@@ -48,18 +48,18 @@ namespace ts {
|
||||
const program = createProgram(["./nonexistent.ts"], options, testCompilerHost);
|
||||
const missing = program.getMissingFilePaths();
|
||||
assert.isDefined(missing);
|
||||
assert.deepEqual(missing, ["d:/pretend/nonexistent.ts"]); // Absolute path
|
||||
assert.deepEqual(missing, ["d:/pretend/nonexistent.ts" as Path]); // Absolute path
|
||||
});
|
||||
|
||||
it("handles multiple missing root files", () => {
|
||||
const program = createProgram(["./nonexistent0.ts", "./nonexistent1.ts"], options, testCompilerHost);
|
||||
const missing = program.getMissingFilePaths().sort();
|
||||
const missing = program.getMissingFilePaths().slice().sort();
|
||||
assert.deepEqual(missing, ["d:/pretend/nonexistent0.ts", "d:/pretend/nonexistent1.ts"]);
|
||||
});
|
||||
|
||||
it("handles a mix of present and missing root files", () => {
|
||||
const program = createProgram(["./nonexistent0.ts", emptyFileRelativePath, "./nonexistent1.ts"], options, testCompilerHost);
|
||||
const missing = program.getMissingFilePaths().sort();
|
||||
const missing = program.getMissingFilePaths().slice().sort();
|
||||
assert.deepEqual(missing, ["d:/pretend/nonexistent0.ts", "d:/pretend/nonexistent1.ts"]);
|
||||
});
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace ts {
|
||||
const program = createProgram(["./nonexistent.ts", "./nonexistent.ts"], options, testCompilerHost);
|
||||
const missing = program.getMissingFilePaths();
|
||||
assert.isDefined(missing);
|
||||
assert.deepEqual(missing, ["d:/pretend/nonexistent.ts"]);
|
||||
assert.deepEqual(missing, ["d:/pretend/nonexistent.ts" as Path]);
|
||||
});
|
||||
|
||||
it("normalizes file paths", () => {
|
||||
@@ -81,7 +81,7 @@ namespace ts {
|
||||
|
||||
it("handles missing triple slash references", () => {
|
||||
const program = createProgram([referenceFileRelativePath], options, testCompilerHost);
|
||||
const missing = program.getMissingFilePaths().sort();
|
||||
const missing = program.getMissingFilePaths().slice().sort();
|
||||
assert.isDefined(missing);
|
||||
assert.deepEqual(missing, [
|
||||
// From absolute reference
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
interface ProgramWithSourceTexts extends Program {
|
||||
sourceTexts?: NamedSourceText[];
|
||||
sourceTexts?: ReadonlyArray<NamedSourceText>;
|
||||
host: TestCompilerHost;
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ namespace ts {
|
||||
return file;
|
||||
}
|
||||
|
||||
function createTestCompilerHost(texts: NamedSourceText[], target: ScriptTarget, oldProgram?: ProgramWithSourceTexts): TestCompilerHost {
|
||||
function createTestCompilerHost(texts: ReadonlyArray<NamedSourceText>, target: ScriptTarget, oldProgram?: ProgramWithSourceTexts): TestCompilerHost {
|
||||
const files = arrayToMap(texts, t => t.name, t => {
|
||||
if (oldProgram) {
|
||||
let oldFile = <SourceFileWithText>oldProgram.getSourceFile(t.name);
|
||||
@@ -162,7 +162,7 @@ namespace ts {
|
||||
return program;
|
||||
}
|
||||
|
||||
function updateProgram(oldProgram: ProgramWithSourceTexts, rootNames: string[], options: CompilerOptions, updater: (files: NamedSourceText[]) => void, newTexts?: NamedSourceText[]) {
|
||||
function updateProgram(oldProgram: ProgramWithSourceTexts, rootNames: ReadonlyArray<string>, options: CompilerOptions, updater: (files: NamedSourceText[]) => void, newTexts?: NamedSourceText[]) {
|
||||
if (!newTexts) {
|
||||
newTexts = (<ProgramWithSourceTexts>oldProgram).sourceTexts.slice(0);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
namespace ts.server {
|
||||
|
||||
export function shouldEmitFile(scriptInfo: ScriptInfo) {
|
||||
return !scriptInfo.hasMixedContent;
|
||||
return !scriptInfo.hasMixedContent && !scriptInfo.isDynamic;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -188,7 +188,7 @@ namespace ts.server {
|
||||
*/
|
||||
getFilesAffectedBy(scriptInfo: ScriptInfo): string[] {
|
||||
const info = this.getOrCreateFileInfo(scriptInfo.path);
|
||||
const singleFileResult = scriptInfo.hasMixedContent ? [] : [scriptInfo.fileName];
|
||||
const singleFileResult = scriptInfo.hasMixedContent || scriptInfo.isDynamic ? [] : [scriptInfo.fileName];
|
||||
if (info.updateShapeSignature()) {
|
||||
const options = this.project.getCompilerOptions();
|
||||
// If `--out` or `--outFile` is specified, any new emit will result in re-emitting the entire project,
|
||||
@@ -303,7 +303,7 @@ namespace ts.server {
|
||||
getFilesAffectedBy(scriptInfo: ScriptInfo): string[] {
|
||||
this.ensureProjectDependencyGraphUpToDate();
|
||||
|
||||
const singleFileResult = scriptInfo.hasMixedContent ? [] : [scriptInfo.fileName];
|
||||
const singleFileResult = scriptInfo.hasMixedContent || scriptInfo.isDynamic ? [] : [scriptInfo.fileName];
|
||||
const fileInfo = this.getFileInfo(scriptInfo.path);
|
||||
if (!fileInfo || !fileInfo.updateShapeSignature()) {
|
||||
return singleFileResult;
|
||||
|
||||
@@ -239,18 +239,21 @@ namespace ts.server {
|
||||
getFileName(f: T): string;
|
||||
getScriptKind(f: T): ScriptKind;
|
||||
hasMixedContent(f: T, extraFileExtensions: JsFileExtensionInfo[]): boolean;
|
||||
isDynamicFile(f: T): boolean;
|
||||
}
|
||||
|
||||
const fileNamePropertyReader: FilePropertyReader<string> = {
|
||||
getFileName: x => x,
|
||||
getScriptKind: _ => undefined,
|
||||
hasMixedContent: (fileName, extraFileExtensions) => some(extraFileExtensions, ext => ext.isMixedContent && fileExtensionIs(fileName, ext.extension)),
|
||||
isDynamicFile: x => x[0] === "^",
|
||||
};
|
||||
|
||||
const externalFilePropertyReader: FilePropertyReader<protocol.ExternalFile> = {
|
||||
getFileName: x => x.fileName,
|
||||
getScriptKind: x => tryConvertScriptKindName(x.scriptKind),
|
||||
hasMixedContent: x => x.hasMixedContent
|
||||
hasMixedContent: x => x.hasMixedContent,
|
||||
isDynamicFile: x => x.fileName[0] === "^",
|
||||
};
|
||||
|
||||
function findProjectByName<T extends Project>(projectName: string, projects: T[]): T {
|
||||
@@ -1210,15 +1213,16 @@ namespace ts.server {
|
||||
private addFilesToProjectAndUpdateGraph<T>(project: ConfiguredProject | ExternalProject, files: T[], propertyReader: FilePropertyReader<T>, clientFileName: string, typeAcquisition: TypeAcquisition, configFileErrors: ReadonlyArray<Diagnostic>): void {
|
||||
let errors: Diagnostic[];
|
||||
for (const f of files) {
|
||||
const rootFilename = propertyReader.getFileName(f);
|
||||
const rootFileName = propertyReader.getFileName(f);
|
||||
const scriptKind = propertyReader.getScriptKind(f);
|
||||
const hasMixedContent = propertyReader.hasMixedContent(f, this.hostConfiguration.extraFileExtensions);
|
||||
if (this.host.fileExists(rootFilename)) {
|
||||
const info = this.getOrCreateScriptInfoForNormalizedPath(toNormalizedPath(rootFilename), /*openedByClient*/ clientFileName === rootFilename, /*fileContent*/ undefined, scriptKind, hasMixedContent);
|
||||
const isDynamicFile = propertyReader.isDynamicFile(f);
|
||||
if (isDynamicFile || this.host.fileExists(rootFileName)) {
|
||||
const info = this.getOrCreateScriptInfoForNormalizedPath(toNormalizedPath(rootFileName), /*openedByClient*/ clientFileName === rootFileName, /*fileContent*/ undefined, scriptKind, hasMixedContent, isDynamicFile);
|
||||
project.addRoot(info);
|
||||
}
|
||||
else {
|
||||
(errors || (errors = [])).push(createFileNotFoundDiagnostic(rootFilename));
|
||||
(errors || (errors = [])).push(createFileNotFoundDiagnostic(rootFileName));
|
||||
}
|
||||
}
|
||||
project.setProjectErrors(concatenate(configFileErrors, errors));
|
||||
@@ -1248,7 +1252,8 @@ namespace ts.server {
|
||||
let rootFilesChanged = false;
|
||||
for (const f of newUncheckedFiles) {
|
||||
const newRootFile = propertyReader.getFileName(f);
|
||||
if (!this.host.fileExists(newRootFile)) {
|
||||
const isDynamic = propertyReader.isDynamicFile(f);
|
||||
if (!isDynamic && !this.host.fileExists(newRootFile)) {
|
||||
(projectErrors || (projectErrors = [])).push(createFileNotFoundDiagnostic(newRootFile));
|
||||
continue;
|
||||
}
|
||||
@@ -1259,7 +1264,7 @@ namespace ts.server {
|
||||
if (!scriptInfo) {
|
||||
const scriptKind = propertyReader.getScriptKind(f);
|
||||
const hasMixedContent = propertyReader.hasMixedContent(f, this.hostConfiguration.extraFileExtensions);
|
||||
scriptInfo = this.getOrCreateScriptInfoForNormalizedPath(normalizedPath, /*openedByClient*/ false, /*fileContent*/ undefined, scriptKind, hasMixedContent);
|
||||
scriptInfo = this.getOrCreateScriptInfoForNormalizedPath(normalizedPath, /*openedByClient*/ false, /*fileContent*/ undefined, scriptKind, hasMixedContent, isDynamic);
|
||||
}
|
||||
}
|
||||
newRootScriptInfos.push(scriptInfo);
|
||||
@@ -1443,17 +1448,17 @@ namespace ts.server {
|
||||
|
||||
watchClosedScriptInfo(info: ScriptInfo) {
|
||||
// do not watch files with mixed content - server doesn't know how to interpret it
|
||||
if (!info.hasMixedContent) {
|
||||
if (!info.hasMixedContent && !info.isDynamic) {
|
||||
const { fileName } = info;
|
||||
info.setWatcher(this.host.watchFile(fileName, _ => this.onSourceFileChanged(fileName)));
|
||||
}
|
||||
}
|
||||
|
||||
getOrCreateScriptInfoForNormalizedPath(fileName: NormalizedPath, openedByClient: boolean, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean) {
|
||||
getOrCreateScriptInfoForNormalizedPath(fileName: NormalizedPath, openedByClient: boolean, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, isDynamic?: boolean) {
|
||||
let info = this.getScriptInfoForNormalizedPath(fileName);
|
||||
if (!info) {
|
||||
if (openedByClient || this.host.fileExists(fileName)) {
|
||||
info = new ScriptInfo(this.host, fileName, scriptKind, hasMixedContent);
|
||||
if (openedByClient || isDynamic || this.host.fileExists(fileName)) {
|
||||
info = new ScriptInfo(this.host, fileName, scriptKind, hasMixedContent, isDynamic);
|
||||
|
||||
this.filenameToScriptInfo.set(info.path, info);
|
||||
|
||||
@@ -1463,6 +1468,7 @@ namespace ts.server {
|
||||
fileContent = this.host.readFile(fileName) || "";
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
this.watchClosedScriptInfo(info);
|
||||
}
|
||||
|
||||
@@ -156,11 +156,12 @@ namespace ts.server {
|
||||
private readonly host: ServerHost,
|
||||
readonly fileName: NormalizedPath,
|
||||
readonly scriptKind: ScriptKind,
|
||||
public hasMixedContent = false) {
|
||||
public hasMixedContent = false,
|
||||
public isDynamic = false) {
|
||||
|
||||
this.path = toPath(fileName, host.getCurrentDirectory(), createGetCanonicalFileName(host.useCaseSensitiveFileNames));
|
||||
this.textStorage = new TextStorage(host, fileName);
|
||||
if (hasMixedContent) {
|
||||
if (hasMixedContent || isDynamic) {
|
||||
this.textStorage.reload("");
|
||||
}
|
||||
this.scriptKind = scriptKind
|
||||
@@ -180,7 +181,7 @@ namespace ts.server {
|
||||
|
||||
public close() {
|
||||
this.isOpen = false;
|
||||
this.textStorage.useText(this.hasMixedContent ? "" : undefined);
|
||||
this.textStorage.useText(this.hasMixedContent || this.isDynamic ? "" : undefined);
|
||||
this.markContainingProjectsAsDirty();
|
||||
}
|
||||
|
||||
@@ -307,7 +308,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
reloadFromFile(tempFileName?: NormalizedPath) {
|
||||
if (this.hasMixedContent) {
|
||||
if (this.hasMixedContent || this.isDynamic) {
|
||||
this.reload("");
|
||||
}
|
||||
else {
|
||||
@@ -354,4 +355,4 @@ namespace ts.server {
|
||||
return this.scriptKind === ScriptKind.JS || this.scriptKind === ScriptKind.JSX;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,7 +425,7 @@ namespace ts.server {
|
||||
|
||||
private semanticCheck(file: NormalizedPath, project: Project) {
|
||||
try {
|
||||
let diags: Diagnostic[] = [];
|
||||
let diags: ReadonlyArray<Diagnostic> = emptyArray;
|
||||
if (!isDeclarationFileInJSOnlyNonConfiguredProject(project, file)) {
|
||||
diags = project.getLanguageService().getSemanticDiagnostics(file);
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace ts.server {
|
||||
};
|
||||
}
|
||||
|
||||
export function mergeMapLikes(target: MapLike<any>, source: MapLike <any>): void {
|
||||
export function mergeMapLikes(target: MapLike<any>, source: MapLike<any>): void {
|
||||
for (const key in source) {
|
||||
if (hasProperty(source, key)) {
|
||||
target[key] = source[key];
|
||||
@@ -299,4 +299,4 @@ namespace ts.server {
|
||||
deleted(oldItems[oldIndex++]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace ts.FindAllReferences {
|
||||
readonly implementations?: boolean;
|
||||
}
|
||||
|
||||
export function findReferencedSymbols(program: Program, cancellationToken: CancellationToken, sourceFiles: SourceFile[], sourceFile: SourceFile, position: number): ReferencedSymbol[] | undefined {
|
||||
export function findReferencedSymbols(program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray<SourceFile>, sourceFile: SourceFile, position: number): ReferencedSymbol[] | undefined {
|
||||
const referencedSymbols = findAllReferencedSymbols(program, cancellationToken, sourceFiles, sourceFile, position);
|
||||
|
||||
if (!referencedSymbols || !referencedSymbols.length) {
|
||||
@@ -60,7 +60,7 @@ namespace ts.FindAllReferences {
|
||||
return out;
|
||||
}
|
||||
|
||||
export function getImplementationsAtPosition(program: Program, cancellationToken: CancellationToken, sourceFiles: SourceFile[], sourceFile: SourceFile, position: number): ImplementationLocation[] {
|
||||
export function getImplementationsAtPosition(program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray<SourceFile>, sourceFile: SourceFile, position: number): ImplementationLocation[] {
|
||||
// A node in a JSDoc comment can't have an implementation anyway.
|
||||
const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ false);
|
||||
const referenceEntries = getImplementationReferenceEntries(program, cancellationToken, sourceFiles, node);
|
||||
@@ -68,7 +68,7 @@ namespace ts.FindAllReferences {
|
||||
return map(referenceEntries, entry => toImplementationLocation(entry, checker));
|
||||
}
|
||||
|
||||
function getImplementationReferenceEntries(program: Program, cancellationToken: CancellationToken, sourceFiles: SourceFile[], node: Node): Entry[] | undefined {
|
||||
function getImplementationReferenceEntries(program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray<SourceFile>, node: Node): Entry[] | undefined {
|
||||
if (node.kind === SyntaxKind.SourceFile) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -93,16 +93,16 @@ namespace ts.FindAllReferences {
|
||||
}
|
||||
}
|
||||
|
||||
export function findReferencedEntries(program: Program, cancellationToken: CancellationToken, sourceFiles: SourceFile[], sourceFile: SourceFile, position: number, options?: Options): ReferenceEntry[] | undefined {
|
||||
export function findReferencedEntries(program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray<SourceFile>, sourceFile: SourceFile, position: number, options?: Options): ReferenceEntry[] | undefined {
|
||||
const x = flattenEntries(findAllReferencedSymbols(program, cancellationToken, sourceFiles, sourceFile, position, options));
|
||||
return map(x, toReferenceEntry);
|
||||
}
|
||||
|
||||
export function getReferenceEntriesForNode(node: Node, program: Program, sourceFiles: SourceFile[], cancellationToken: CancellationToken, options: Options = {}): Entry[] | undefined {
|
||||
export function getReferenceEntriesForNode(node: Node, program: Program, sourceFiles: ReadonlyArray<SourceFile>, cancellationToken: CancellationToken, options: Options = {}): Entry[] | undefined {
|
||||
return flattenEntries(Core.getReferencedSymbolsForNode(node, program, sourceFiles, cancellationToken, options));
|
||||
}
|
||||
|
||||
function findAllReferencedSymbols(program: Program, cancellationToken: CancellationToken, sourceFiles: SourceFile[], sourceFile: SourceFile, position: number, options?: Options): SymbolAndEntries[] | undefined {
|
||||
function findAllReferencedSymbols(program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray<SourceFile>, sourceFile: SourceFile, position: number, options?: Options): SymbolAndEntries[] | undefined {
|
||||
const node = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true);
|
||||
return Core.getReferencedSymbolsForNode(node, program, sourceFiles, cancellationToken, options);
|
||||
}
|
||||
@@ -264,7 +264,7 @@ namespace ts.FindAllReferences {
|
||||
/* @internal */
|
||||
namespace ts.FindAllReferences.Core {
|
||||
/** Core find-all-references algorithm. Handles special cases before delegating to `getReferencedSymbolsForSymbol`. */
|
||||
export function getReferencedSymbolsForNode(node: Node, program: Program, sourceFiles: SourceFile[], cancellationToken: CancellationToken, options: Options = {}): SymbolAndEntries[] | undefined {
|
||||
export function getReferencedSymbolsForNode(node: Node, program: Program, sourceFiles: ReadonlyArray<SourceFile>, cancellationToken: CancellationToken, options: Options = {}): SymbolAndEntries[] | undefined {
|
||||
if (node.kind === ts.SyntaxKind.SourceFile) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -313,7 +313,7 @@ namespace ts.FindAllReferences.Core {
|
||||
}
|
||||
}
|
||||
|
||||
function getReferencedSymbolsForModule(program: Program, symbol: Symbol, sourceFiles: SourceFile[]): SymbolAndEntries[] {
|
||||
function getReferencedSymbolsForModule(program: Program, symbol: Symbol, sourceFiles: ReadonlyArray<SourceFile>): SymbolAndEntries[] {
|
||||
Debug.assert(!!symbol.valueDeclaration);
|
||||
|
||||
const references = findModuleReferences(program, sourceFiles, symbol).map<Entry>(reference => {
|
||||
@@ -349,7 +349,7 @@ namespace ts.FindAllReferences.Core {
|
||||
}
|
||||
|
||||
/** getReferencedSymbols for special node kinds. */
|
||||
function getReferencedSymbolsSpecial(node: Node, sourceFiles: SourceFile[], cancellationToken: CancellationToken): SymbolAndEntries[] | undefined {
|
||||
function getReferencedSymbolsSpecial(node: Node, sourceFiles: ReadonlyArray<SourceFile>, cancellationToken: CancellationToken): SymbolAndEntries[] | undefined {
|
||||
if (isTypeKeyword(node.kind)) {
|
||||
return getAllReferencesForKeyword(sourceFiles, node.kind, cancellationToken);
|
||||
}
|
||||
@@ -380,7 +380,7 @@ namespace ts.FindAllReferences.Core {
|
||||
}
|
||||
|
||||
/** Core find-all-references algorithm for a normal symbol. */
|
||||
function getReferencedSymbolsForSymbol(symbol: Symbol, node: Node, sourceFiles: SourceFile[], checker: TypeChecker, cancellationToken: CancellationToken, options: Options): SymbolAndEntries[] {
|
||||
function getReferencedSymbolsForSymbol(symbol: Symbol, node: Node, sourceFiles: ReadonlyArray<SourceFile>, checker: TypeChecker, cancellationToken: CancellationToken, options: Options): SymbolAndEntries[] {
|
||||
symbol = skipPastExportOrImportSpecifier(symbol, node, checker);
|
||||
|
||||
// Compute the meaning from the location and the symbol it references
|
||||
@@ -474,7 +474,7 @@ namespace ts.FindAllReferences.Core {
|
||||
readonly markSeenReExportRHS = nodeSeenTracker();
|
||||
|
||||
constructor(
|
||||
readonly sourceFiles: SourceFile[],
|
||||
readonly sourceFiles: ReadonlyArray<SourceFile>,
|
||||
/** True if we're searching for constructor references. */
|
||||
readonly isForConstructor: boolean,
|
||||
readonly checker: TypeChecker,
|
||||
@@ -759,7 +759,7 @@ namespace ts.FindAllReferences.Core {
|
||||
}
|
||||
}
|
||||
|
||||
function getAllReferencesForKeyword(sourceFiles: SourceFile[], keywordKind: ts.SyntaxKind, cancellationToken: CancellationToken): SymbolAndEntries[] {
|
||||
function getAllReferencesForKeyword(sourceFiles: ReadonlyArray<SourceFile>, keywordKind: ts.SyntaxKind, cancellationToken: CancellationToken): SymbolAndEntries[] {
|
||||
const references: NodeEntry[] = [];
|
||||
for (const sourceFile of sourceFiles) {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
@@ -1259,7 +1259,7 @@ namespace ts.FindAllReferences.Core {
|
||||
return [{ definition: { type: "symbol", symbol: searchSpaceNode.symbol, node: superKeyword }, references }];
|
||||
}
|
||||
|
||||
function getReferencesForThisKeyword(thisOrSuperKeyword: Node, sourceFiles: SourceFile[], cancellationToken: CancellationToken): SymbolAndEntries[] {
|
||||
function getReferencesForThisKeyword(thisOrSuperKeyword: Node, sourceFiles: ReadonlyArray<SourceFile>, cancellationToken: CancellationToken): SymbolAndEntries[] {
|
||||
let searchSpaceNode = getThisContainer(thisOrSuperKeyword, /* includeArrowFunctions */ false);
|
||||
|
||||
// Whether 'this' occurs in a static context within a class.
|
||||
@@ -1355,7 +1355,7 @@ namespace ts.FindAllReferences.Core {
|
||||
}
|
||||
}
|
||||
|
||||
function getReferencesForStringLiteral(node: StringLiteral, sourceFiles: SourceFile[], cancellationToken: CancellationToken): SymbolAndEntries[] {
|
||||
function getReferencesForStringLiteral(node: StringLiteral, sourceFiles: ReadonlyArray<SourceFile>, cancellationToken: CancellationToken): SymbolAndEntries[] {
|
||||
const references: NodeEntry[] = [];
|
||||
|
||||
for (const sourceFile of sourceFiles) {
|
||||
|
||||
@@ -279,7 +279,7 @@ namespace ts.GoToDefinition {
|
||||
return createDefinitionInfo(decl, symbolKind, symbolName, containerName);
|
||||
}
|
||||
|
||||
function findReferenceInPosition(refs: FileReference[], pos: number): FileReference {
|
||||
function findReferenceInPosition(refs: ReadonlyArray<FileReference>, pos: number): FileReference {
|
||||
for (const ref of refs) {
|
||||
if (ref.pos <= pos && pos <= ref.end) {
|
||||
return ref;
|
||||
|
||||
@@ -7,12 +7,12 @@ namespace ts.FindAllReferences {
|
||||
/** For rename imports/exports `{ foo as bar }`, `foo` is not a local, so it may be added as a reference immediately without further searching. */
|
||||
singleReferences: Identifier[];
|
||||
/** List of source files that may (or may not) use the symbol via a namespace. (For UMD modules this is every file.) */
|
||||
indirectUsers: SourceFile[];
|
||||
indirectUsers: ReadonlyArray<SourceFile>;
|
||||
}
|
||||
export type ImportTracker = (exportSymbol: Symbol, exportInfo: ExportInfo, isForRename: boolean) => ImportsResult;
|
||||
|
||||
/** Creates the imports map and returns an ImportTracker that uses it. Call this lazily to avoid calling `getDirectImportsMap` unnecessarily. */
|
||||
export function createImportTracker(sourceFiles: SourceFile[], checker: TypeChecker, cancellationToken: CancellationToken): ImportTracker {
|
||||
export function createImportTracker(sourceFiles: ReadonlyArray<SourceFile>, checker: TypeChecker, cancellationToken: CancellationToken): ImportTracker {
|
||||
const allDirectImports = getDirectImportsMap(sourceFiles, checker, cancellationToken);
|
||||
return (exportSymbol, exportInfo, isForRename) => {
|
||||
const { directImports, indirectUsers } = getImportersForExport(sourceFiles, allDirectImports, exportInfo, checker, cancellationToken);
|
||||
@@ -38,12 +38,12 @@ namespace ts.FindAllReferences {
|
||||
|
||||
/** Returns import statements that directly reference the exporting module, and a list of files that may access the module through a namespace. */
|
||||
function getImportersForExport(
|
||||
sourceFiles: SourceFile[],
|
||||
sourceFiles: ReadonlyArray<SourceFile>,
|
||||
allDirectImports: Map<ImporterOrCallExpression[]>,
|
||||
{ exportingModuleSymbol, exportKind }: ExportInfo,
|
||||
checker: TypeChecker,
|
||||
cancellationToken: CancellationToken
|
||||
): { directImports: Importer[], indirectUsers: SourceFile[] } {
|
||||
): { directImports: Importer[], indirectUsers: ReadonlyArray<SourceFile> } {
|
||||
const markSeenDirectImport = nodeSeenTracker<ImporterOrCallExpression>();
|
||||
const markSeenIndirectUser = nodeSeenTracker<SourceFileLike>();
|
||||
const directImports: Importer[] = [];
|
||||
@@ -54,7 +54,7 @@ namespace ts.FindAllReferences {
|
||||
|
||||
return { directImports, indirectUsers: getIndirectUsers() };
|
||||
|
||||
function getIndirectUsers(): SourceFile[] {
|
||||
function getIndirectUsers(): ReadonlyArray<SourceFile> {
|
||||
if (isAvailableThroughGlobal) {
|
||||
// It has `export as namespace`, so anything could potentially use it.
|
||||
return sourceFiles;
|
||||
@@ -313,7 +313,7 @@ namespace ts.FindAllReferences {
|
||||
| { kind: "import", literal: StringLiteral }
|
||||
/** <reference path> or <reference types> */
|
||||
| { kind: "reference", referencingFile: SourceFile, ref: FileReference };
|
||||
export function findModuleReferences(program: Program, sourceFiles: SourceFile[], searchModuleSymbol: Symbol): ModuleReference[] {
|
||||
export function findModuleReferences(program: Program, sourceFiles: ReadonlyArray<SourceFile>, searchModuleSymbol: Symbol): ModuleReference[] {
|
||||
const refs: ModuleReference[] = [];
|
||||
const checker = program.getTypeChecker();
|
||||
for (const referencingFile of sourceFiles) {
|
||||
@@ -343,7 +343,7 @@ namespace ts.FindAllReferences {
|
||||
}
|
||||
|
||||
/** Returns a map from a module symbol Id to all import statements that directly reference the module. */
|
||||
function getDirectImportsMap(sourceFiles: SourceFile[], checker: TypeChecker, cancellationToken: CancellationToken): Map<ImporterOrCallExpression[]> {
|
||||
function getDirectImportsMap(sourceFiles: ReadonlyArray<SourceFile>, checker: TypeChecker, cancellationToken: CancellationToken): Map<ImporterOrCallExpression[]> {
|
||||
const map = createMap<ImporterOrCallExpression[]>();
|
||||
|
||||
for (const sourceFile of sourceFiles) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
namespace ts.NavigateTo {
|
||||
type RawNavigateToItem = { name: string; fileName: string; matchKind: PatternMatchKind; isCaseSensitive: boolean; declaration: Declaration };
|
||||
|
||||
export function getNavigateToItems(sourceFiles: SourceFile[], checker: TypeChecker, cancellationToken: CancellationToken, searchValue: string, maxResultCount: number, excludeDtsFiles: boolean): NavigateToItem[] {
|
||||
export function getNavigateToItems(sourceFiles: ReadonlyArray<SourceFile>, checker: TypeChecker, cancellationToken: CancellationToken, searchValue: string, maxResultCount: number, excludeDtsFiles: boolean): NavigateToItem[] {
|
||||
const patternMatcher = createPatternMatcher(searchValue);
|
||||
let rawItems: RawNavigateToItem[] = [];
|
||||
|
||||
|
||||
@@ -231,18 +231,7 @@ namespace ts.refactor.extractMethod {
|
||||
if (errors) {
|
||||
return { errors };
|
||||
}
|
||||
|
||||
// If our selection is the expression in an ExpressionStatement, expand
|
||||
// the selection to include the enclosing Statement (this stops us
|
||||
// from trying to care about the return value of the extracted function
|
||||
// and eliminates double semicolon insertion in certain scenarios)
|
||||
const range = isStatement(start)
|
||||
? [start]
|
||||
: start.parent && start.parent.kind === SyntaxKind.ExpressionStatement
|
||||
? [start.parent as Statement]
|
||||
: start as Expression;
|
||||
|
||||
return { targetRange: { range, facts: rangeFacts, declarations } };
|
||||
return { targetRange: { range: getStatementOrExpressionRange(start), facts: rangeFacts, declarations } };
|
||||
}
|
||||
|
||||
function createErrorResult(sourceFile: SourceFile, start: number, length: number, message: DiagnosticMessage): RangeToExtract {
|
||||
@@ -289,7 +278,7 @@ namespace ts.refactor.extractMethod {
|
||||
Continue = 1 << 1,
|
||||
Return = 1 << 2
|
||||
}
|
||||
if (!isStatement(nodeToCheck) && !(isExpression(nodeToCheck) && isExtractableExpression(nodeToCheck))) {
|
||||
if (!isStatement(nodeToCheck) && !(isPartOfExpression(nodeToCheck) && isExtractableExpression(nodeToCheck))) {
|
||||
return [createDiagnosticForNode(nodeToCheck, Messages.StatementOrExpressionExpected)];
|
||||
}
|
||||
|
||||
@@ -459,6 +448,20 @@ namespace ts.refactor.extractMethod {
|
||||
}
|
||||
}
|
||||
|
||||
function getStatementOrExpressionRange(node: Node): Statement[] | Expression {
|
||||
if (isStatement(node)) {
|
||||
return [node];
|
||||
}
|
||||
else if (isPartOfExpression(node)) {
|
||||
// If our selection is the expression in an ExpressionStatement, expand
|
||||
// the selection to include the enclosing Statement (this stops us
|
||||
// from trying to care about the return value of the extracted function
|
||||
// and eliminates double semicolon insertion in certain scenarios)
|
||||
return isExpressionStatement(node.parent) ? [node.parent] : node as Expression;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function isValidExtractionTarget(node: Node): node is Scope {
|
||||
// Note that we don't use isFunctionLike because we don't want to put the extracted closure *inside* a method
|
||||
return (node.kind === SyntaxKind.FunctionDeclaration) || isSourceFile(node) || isModuleBlock(node) || isClassLike(node);
|
||||
@@ -560,32 +563,32 @@ namespace ts.refactor.extractMethod {
|
||||
return "constructor";
|
||||
case SyntaxKind.FunctionExpression:
|
||||
return scope.name
|
||||
? `function expression ${scope.name.getText()}`
|
||||
? `function expression ${scope.name.text}`
|
||||
: "anonymous function expression";
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
return `function ${scope.name.getText()}`;
|
||||
return `function '${scope.name.text}'`;
|
||||
case SyntaxKind.ArrowFunction:
|
||||
return "arrow function";
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
return `method ${scope.name.getText()}`;
|
||||
return `method '${scope.name.getText()}`;
|
||||
case SyntaxKind.GetAccessor:
|
||||
return `get ${scope.name.getText()}`;
|
||||
return `'get ${scope.name.getText()}'`;
|
||||
case SyntaxKind.SetAccessor:
|
||||
return `set ${scope.name.getText()}`;
|
||||
return `'set ${scope.name.getText()}'`;
|
||||
}
|
||||
}
|
||||
else if (isModuleBlock(scope)) {
|
||||
return `namespace ${scope.parent.name.getText()}`;
|
||||
return `namespace '${scope.parent.name.getText()}'`;
|
||||
}
|
||||
else if (isClassLike(scope)) {
|
||||
return scope.kind === SyntaxKind.ClassDeclaration
|
||||
? `class ${scope.name.text}`
|
||||
? `class '${scope.name.text}'`
|
||||
: scope.name.text
|
||||
? `class expression ${scope.name.text}`
|
||||
? `class expression '${scope.name.text}'`
|
||||
: "anonymous class expression";
|
||||
}
|
||||
else if (isSourceFile(scope)) {
|
||||
return `file '${scope.fileName}'`;
|
||||
return scope.externalModuleIndicator ? "module scope" : "global scope";
|
||||
}
|
||||
else {
|
||||
return "unknown";
|
||||
|
||||
@@ -495,7 +495,7 @@ namespace ts {
|
||||
public path: Path;
|
||||
public text: string;
|
||||
public scriptSnapshot: IScriptSnapshot;
|
||||
public lineMap: number[];
|
||||
public lineMap: ReadonlyArray<number>;
|
||||
|
||||
public statements: NodeArray<Statement>;
|
||||
public endOfFileToken: Token<SyntaxKind.EndOfFileToken>;
|
||||
@@ -545,7 +545,7 @@ namespace ts {
|
||||
return ts.getLineAndCharacterOfPosition(this, position);
|
||||
}
|
||||
|
||||
public getLineStarts(): number[] {
|
||||
public getLineStarts(): ReadonlyArray<number> {
|
||||
return getLineStarts(this);
|
||||
}
|
||||
|
||||
@@ -1336,10 +1336,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
/// Diagnostics
|
||||
function getSyntacticDiagnostics(fileName: string) {
|
||||
function getSyntacticDiagnostics(fileName: string): Diagnostic[] {
|
||||
synchronizeHostData();
|
||||
|
||||
return program.getSyntacticDiagnostics(getValidSourceFile(fileName), cancellationToken);
|
||||
return program.getSyntacticDiagnostics(getValidSourceFile(fileName), cancellationToken).slice();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1356,18 +1356,17 @@ namespace ts {
|
||||
|
||||
const semanticDiagnostics = program.getSemanticDiagnostics(targetSourceFile, cancellationToken);
|
||||
if (!program.getCompilerOptions().declaration) {
|
||||
return semanticDiagnostics;
|
||||
return semanticDiagnostics.slice();
|
||||
}
|
||||
|
||||
// If '-d' is enabled, check for emitter error. One example of emitter error is export class implements non-export interface
|
||||
const declarationDiagnostics = program.getDeclarationDiagnostics(targetSourceFile, cancellationToken);
|
||||
return concatenate(semanticDiagnostics, declarationDiagnostics);
|
||||
return [...semanticDiagnostics, ...declarationDiagnostics];
|
||||
}
|
||||
|
||||
function getCompilerOptionsDiagnostics() {
|
||||
synchronizeHostData();
|
||||
return program.getOptionsDiagnostics(cancellationToken).concat(
|
||||
program.getGlobalDiagnostics(cancellationToken));
|
||||
return [...program.getOptionsDiagnostics(cancellationToken), ...program.getGlobalDiagnostics(cancellationToken)];
|
||||
}
|
||||
|
||||
function getCompletionsAtPosition(fileName: string, position: number): CompletionInfo {
|
||||
|
||||
@@ -568,7 +568,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function realizeDiagnostics(diagnostics: Diagnostic[], newLine: string): { message: string; start: number; length: number; category: string; code: number; }[] {
|
||||
export function realizeDiagnostics(diagnostics: ReadonlyArray<Diagnostic>, newLine: string): { message: string; start: number; length: number; category: string; code: number; }[] {
|
||||
return diagnostics.map(d => realizeDiagnostic(d, newLine));
|
||||
}
|
||||
|
||||
@@ -641,7 +641,7 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
|
||||
private realizeDiagnostics(diagnostics: Diagnostic[]): { message: string; start: number; length: number; category: string; }[] {
|
||||
private realizeDiagnostics(diagnostics: ReadonlyArray<Diagnostic>): { message: string; start: number; length: number; category: string; }[] {
|
||||
const newLine = getNewLineOrDefaultFromHost(this.host);
|
||||
return ts.realizeDiagnostics(diagnostics, newLine);
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace ts {
|
||||
|
||||
getLineAndCharacterOfPosition(pos: number): LineAndCharacter;
|
||||
getLineEndOfPosition(pos: number): number;
|
||||
getLineStarts(): number[];
|
||||
getLineStarts(): ReadonlyArray<number>;
|
||||
getPositionOfLineAndCharacter(line: number, character: number): number;
|
||||
update(newText: string, textChangeRange: TextChangeRange): SourceFile;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
//// [asyncArrowInClassES5.ts]
|
||||
// https://github.com/Microsoft/TypeScript/issues/16924
|
||||
// Should capture `this`
|
||||
|
||||
class Test {
|
||||
static member = async (x: string) => { };
|
||||
}
|
||||
|
||||
|
||||
//// [asyncArrowInClassES5.js]
|
||||
// https://github.com/Microsoft/TypeScript/issues/16924
|
||||
// Should capture `this`
|
||||
var _this = this;
|
||||
var Test = /** @class */ (function () {
|
||||
function Test() {
|
||||
}
|
||||
Test.member = function (x) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
|
||||
return [2 /*return*/];
|
||||
}); }); };
|
||||
return Test;
|
||||
}());
|
||||
@@ -0,0 +1,12 @@
|
||||
=== tests/cases/compiler/asyncArrowInClassES5.ts ===
|
||||
// https://github.com/Microsoft/TypeScript/issues/16924
|
||||
// Should capture `this`
|
||||
|
||||
class Test {
|
||||
>Test : Symbol(Test, Decl(asyncArrowInClassES5.ts, 0, 0))
|
||||
|
||||
static member = async (x: string) => { };
|
||||
>member : Symbol(Test.member, Decl(asyncArrowInClassES5.ts, 3, 12))
|
||||
>x : Symbol(x, Decl(asyncArrowInClassES5.ts, 4, 27))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
=== tests/cases/compiler/asyncArrowInClassES5.ts ===
|
||||
// https://github.com/Microsoft/TypeScript/issues/16924
|
||||
// Should capture `this`
|
||||
|
||||
class Test {
|
||||
>Test : Test
|
||||
|
||||
static member = async (x: string) => { };
|
||||
>member : (x: string) => Promise<void>
|
||||
>async (x: string) => { } : (x: string) => Promise<void>
|
||||
>x : string
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
//// [computerPropertiesInES5ShouldBeTransformed.ts]
|
||||
const b = ({ [`key`]: renamed }) => renamed;
|
||||
|
||||
//// [computerPropertiesInES5ShouldBeTransformed.js]
|
||||
var b = function (_a) {
|
||||
var _b = "key", renamed = _a[_b];
|
||||
return renamed;
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
=== tests/cases/compiler/computerPropertiesInES5ShouldBeTransformed.ts ===
|
||||
const b = ({ [`key`]: renamed }) => renamed;
|
||||
>b : Symbol(b, Decl(computerPropertiesInES5ShouldBeTransformed.ts, 0, 5))
|
||||
>renamed : Symbol(renamed, Decl(computerPropertiesInES5ShouldBeTransformed.ts, 0, 12))
|
||||
>renamed : Symbol(renamed, Decl(computerPropertiesInES5ShouldBeTransformed.ts, 0, 12))
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
=== tests/cases/compiler/computerPropertiesInES5ShouldBeTransformed.ts ===
|
||||
const b = ({ [`key`]: renamed }) => renamed;
|
||||
>b : ({ [`key`]: renamed }: {}) => any
|
||||
>({ [`key`]: renamed }) => renamed : ({ [`key`]: renamed }: {}) => any
|
||||
>`key` : "key"
|
||||
>renamed : any
|
||||
>renamed : any
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
=== tests/cases/conformance/salsa/node.d.ts ===
|
||||
declare function require(id: string): any;
|
||||
>require : Symbol(require, Decl(node.d.ts, 0, 0))
|
||||
>id : Symbol(id, Decl(node.d.ts, 0, 25))
|
||||
|
||||
declare var module: any, exports: any;
|
||||
>module : Symbol(module, Decl(node.d.ts, 1, 11))
|
||||
>exports : Symbol(exports, Decl(node.d.ts, 1, 24))
|
||||
|
||||
=== tests/cases/conformance/salsa/index.js ===
|
||||
const A = require("./other");
|
||||
>A : Symbol(A, Decl(index.js, 0, 5))
|
||||
>require : Symbol(require, Decl(node.d.ts, 0, 0))
|
||||
>"./other" : Symbol("tests/cases/conformance/salsa/other", Decl(other.js, 0, 0))
|
||||
|
||||
const a = new A().id;
|
||||
>a : Symbol(a, Decl(index.js, 1, 5))
|
||||
>new A().id : Symbol(A.id, Decl(other.js, 0, 14))
|
||||
>A : Symbol(A, Decl(index.js, 0, 5))
|
||||
>id : Symbol(A.id, Decl(other.js, 0, 14))
|
||||
|
||||
const B = function() { this.id = 1; }
|
||||
>B : Symbol(B, Decl(index.js, 3, 5))
|
||||
>id : Symbol(B.id, Decl(index.js, 3, 22))
|
||||
|
||||
const b = new B().id;
|
||||
>b : Symbol(b, Decl(index.js, 4, 5))
|
||||
>new B().id : Symbol(B.id, Decl(index.js, 3, 22))
|
||||
>B : Symbol(B, Decl(index.js, 3, 5))
|
||||
>id : Symbol(B.id, Decl(index.js, 3, 22))
|
||||
|
||||
=== tests/cases/conformance/salsa/other.js ===
|
||||
function A() { this.id = 1; }
|
||||
>A : Symbol(A, Decl(other.js, 0, 0))
|
||||
>id : Symbol(A.id, Decl(other.js, 0, 14))
|
||||
|
||||
module.exports = A;
|
||||
>module : Symbol(export=, Decl(other.js, 0, 29))
|
||||
>exports : Symbol(export=, Decl(other.js, 0, 29))
|
||||
>A : Symbol(A, Decl(other.js, 0, 0))
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
=== tests/cases/conformance/salsa/node.d.ts ===
|
||||
declare function require(id: string): any;
|
||||
>require : (id: string) => any
|
||||
>id : string
|
||||
|
||||
declare var module: any, exports: any;
|
||||
>module : any
|
||||
>exports : any
|
||||
|
||||
=== tests/cases/conformance/salsa/index.js ===
|
||||
const A = require("./other");
|
||||
>A : () => void
|
||||
>require("./other") : () => void
|
||||
>require : (id: string) => any
|
||||
>"./other" : "./other"
|
||||
|
||||
const a = new A().id;
|
||||
>a : number
|
||||
>new A().id : number
|
||||
>new A() : { id: number; }
|
||||
>A : () => void
|
||||
>id : number
|
||||
|
||||
const B = function() { this.id = 1; }
|
||||
>B : () => void
|
||||
>function() { this.id = 1; } : () => void
|
||||
>this.id = 1 : 1
|
||||
>this.id : any
|
||||
>this : any
|
||||
>id : any
|
||||
>1 : 1
|
||||
|
||||
const b = new B().id;
|
||||
>b : number
|
||||
>new B().id : number
|
||||
>new B() : { id: number; }
|
||||
>B : () => void
|
||||
>id : number
|
||||
|
||||
=== tests/cases/conformance/salsa/other.js ===
|
||||
function A() { this.id = 1; }
|
||||
>A : () => void
|
||||
>this.id = 1 : 1
|
||||
>this.id : any
|
||||
>this : any
|
||||
>id : any
|
||||
>1 : 1
|
||||
|
||||
module.exports = A;
|
||||
>module.exports = A : () => void
|
||||
>module.exports : any
|
||||
>module : any
|
||||
>exports : any
|
||||
>A : () => void
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// [source.js]
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
var B = /** @class */ (function () {
|
||||
function B() {
|
||||
}
|
||||
return B;
|
||||
}());
|
||||
var C = /** @class */ (function () {
|
||||
function C(b) {
|
||||
}
|
||||
C = __decorate([
|
||||
dec,
|
||||
__metadata("design:paramtypes", [B])
|
||||
], C);
|
||||
return C;
|
||||
}());
|
||||
export { C };
|
||||
"changed";
|
||||
@@ -0,0 +1,17 @@
|
||||
//// [declarationQuotedMembers.ts]
|
||||
export declare const mapped: { [K in 'a-b-c']: number }
|
||||
export const example = mapped;
|
||||
|
||||
//// [declarationQuotedMembers.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.example = exports.mapped;
|
||||
|
||||
|
||||
//// [declarationQuotedMembers.d.ts]
|
||||
export declare const mapped: {
|
||||
[K in 'a-b-c']: number;
|
||||
};
|
||||
export declare const example: {
|
||||
"a-b-c": number;
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
=== tests/cases/compiler/declarationQuotedMembers.ts ===
|
||||
export declare const mapped: { [K in 'a-b-c']: number }
|
||||
>mapped : Symbol(mapped, Decl(declarationQuotedMembers.ts, 0, 20))
|
||||
>K : Symbol(K, Decl(declarationQuotedMembers.ts, 0, 32))
|
||||
|
||||
export const example = mapped;
|
||||
>example : Symbol(example, Decl(declarationQuotedMembers.ts, 1, 12))
|
||||
>mapped : Symbol(mapped, Decl(declarationQuotedMembers.ts, 0, 20))
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
=== tests/cases/compiler/declarationQuotedMembers.ts ===
|
||||
export declare const mapped: { [K in 'a-b-c']: number }
|
||||
>mapped : { a-b-c: number; }
|
||||
>K : K
|
||||
|
||||
export const example = mapped;
|
||||
>example : { a-b-c: number; }
|
||||
>mapped : { a-b-c: number; }
|
||||
|
||||
@@ -17,6 +17,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
||||
};
|
||||
var M;
|
||||
(function (M) {
|
||||
var _this = this;
|
||||
var C = /** @class */ (function () {
|
||||
function C() {
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
||||
};
|
||||
var M;
|
||||
(function (M) {
|
||||
var _this = this;
|
||||
var S = /** @class */ (function () {
|
||||
function S() {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
tests/cases/compiler/exportClassWithoutName.ts(1,1): error TS1211: A class declaration without the 'default' modifier must have a name.
|
||||
|
||||
|
||||
==== tests/cases/compiler/exportClassWithoutName.ts (1 errors) ====
|
||||
export class {
|
||||
~~~~~~
|
||||
!!! error TS1211: A class declaration without the 'default' modifier must have a name.
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
//// [exportClassWithoutName.ts]
|
||||
export class {
|
||||
}
|
||||
|
||||
//// [exportClassWithoutName.js]
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
class default_1 {
|
||||
}
|
||||
exports.default_1 = default_1;
|
||||
@@ -0,0 +1,19 @@
|
||||
//// [exportEqualsClassNoRedeclarationError.ts]
|
||||
class SomeClass {
|
||||
static get someProp(): number {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static set someProp(value: number) {}
|
||||
}
|
||||
export = SomeClass;
|
||||
|
||||
//// [exportEqualsClassNoRedeclarationError.js]
|
||||
"use strict";
|
||||
class SomeClass {
|
||||
static get someProp() {
|
||||
return 0;
|
||||
}
|
||||
static set someProp(value) { }
|
||||
}
|
||||
module.exports = SomeClass;
|
||||
@@ -0,0 +1,17 @@
|
||||
=== tests/cases/compiler/exportEqualsClassNoRedeclarationError.ts ===
|
||||
class SomeClass {
|
||||
>SomeClass : Symbol(SomeClass, Decl(exportEqualsClassNoRedeclarationError.ts, 0, 0))
|
||||
|
||||
static get someProp(): number {
|
||||
>someProp : Symbol(SomeClass.someProp, Decl(exportEqualsClassNoRedeclarationError.ts, 0, 17), Decl(exportEqualsClassNoRedeclarationError.ts, 3, 5))
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static set someProp(value: number) {}
|
||||
>someProp : Symbol(SomeClass.someProp, Decl(exportEqualsClassNoRedeclarationError.ts, 0, 17), Decl(exportEqualsClassNoRedeclarationError.ts, 3, 5))
|
||||
>value : Symbol(value, Decl(exportEqualsClassNoRedeclarationError.ts, 5, 24))
|
||||
}
|
||||
export = SomeClass;
|
||||
>SomeClass : Symbol(SomeClass, Decl(exportEqualsClassNoRedeclarationError.ts, 0, 0))
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
=== tests/cases/compiler/exportEqualsClassNoRedeclarationError.ts ===
|
||||
class SomeClass {
|
||||
>SomeClass : SomeClass
|
||||
|
||||
static get someProp(): number {
|
||||
>someProp : number
|
||||
|
||||
return 0;
|
||||
>0 : 0
|
||||
}
|
||||
|
||||
static set someProp(value: number) {}
|
||||
>someProp : number
|
||||
>value : number
|
||||
}
|
||||
export = SomeClass;
|
||||
>SomeClass : SomeClass
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
tests/cases/compiler/exportEqualsClassRedeclarationError.ts(2,16): error TS2300: Duplicate identifier 'someProp'.
|
||||
tests/cases/compiler/exportEqualsClassRedeclarationError.ts(6,16): error TS2300: Duplicate identifier 'someProp'.
|
||||
tests/cases/compiler/exportEqualsClassRedeclarationError.ts(7,16): error TS2300: Duplicate identifier 'someProp'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/exportEqualsClassRedeclarationError.ts (3 errors) ====
|
||||
class SomeClass {
|
||||
static get someProp(): number {
|
||||
~~~~~~~~
|
||||
!!! error TS2300: Duplicate identifier 'someProp'.
|
||||
return 0;
|
||||
}
|
||||
|
||||
static set someProp(value: number) {}
|
||||
~~~~~~~~
|
||||
!!! error TS2300: Duplicate identifier 'someProp'.
|
||||
static set someProp(value: number) {}
|
||||
~~~~~~~~
|
||||
!!! error TS2300: Duplicate identifier 'someProp'.
|
||||
}
|
||||
export = SomeClass;
|
||||
@@ -0,0 +1,21 @@
|
||||
//// [exportEqualsClassRedeclarationError.ts]
|
||||
class SomeClass {
|
||||
static get someProp(): number {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static set someProp(value: number) {}
|
||||
static set someProp(value: number) {}
|
||||
}
|
||||
export = SomeClass;
|
||||
|
||||
//// [exportEqualsClassRedeclarationError.js]
|
||||
"use strict";
|
||||
class SomeClass {
|
||||
static get someProp() {
|
||||
return 0;
|
||||
}
|
||||
static set someProp(value) { }
|
||||
static set someProp(value) { }
|
||||
}
|
||||
module.exports = SomeClass;
|
||||
@@ -14,7 +14,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::function a==
|
||||
==SCOPE::function 'a'==
|
||||
namespace A {
|
||||
let x = 1;
|
||||
function foo() {
|
||||
@@ -34,7 +34,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::namespace B==
|
||||
==SCOPE::namespace 'B'==
|
||||
namespace A {
|
||||
let x = 1;
|
||||
function foo() {
|
||||
@@ -55,7 +55,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::namespace A==
|
||||
==SCOPE::namespace 'A'==
|
||||
namespace A {
|
||||
let x = 1;
|
||||
function foo() {
|
||||
@@ -76,7 +76,7 @@ namespace A {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
==SCOPE::file '/a.ts'==
|
||||
==SCOPE::global scope==
|
||||
namespace A {
|
||||
let x = 1;
|
||||
function foo() {
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::class C==
|
||||
==SCOPE::class 'C'==
|
||||
namespace A {
|
||||
export interface I { x: number };
|
||||
class C {
|
||||
@@ -24,7 +24,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::namespace A==
|
||||
==SCOPE::namespace 'A'==
|
||||
namespace A {
|
||||
export interface I { x: number };
|
||||
class C {
|
||||
@@ -39,7 +39,7 @@ namespace A {
|
||||
return a1.x + 10;
|
||||
}
|
||||
}
|
||||
==SCOPE::file '/a.ts'==
|
||||
==SCOPE::global scope==
|
||||
namespace A {
|
||||
export interface I { x: number };
|
||||
class C {
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::class C==
|
||||
==SCOPE::class 'C'==
|
||||
namespace A {
|
||||
let y = 1;
|
||||
class C {
|
||||
@@ -30,7 +30,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::namespace A==
|
||||
==SCOPE::namespace 'A'==
|
||||
namespace A {
|
||||
let y = 1;
|
||||
class C {
|
||||
@@ -49,7 +49,7 @@ namespace A {
|
||||
return { __return: a1.x + 10, z };
|
||||
}
|
||||
}
|
||||
==SCOPE::file '/a.ts'==
|
||||
==SCOPE::global scope==
|
||||
namespace A {
|
||||
let y = 1;
|
||||
class C {
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::class C==
|
||||
==SCOPE::class 'C'==
|
||||
namespace A {
|
||||
let y = 1;
|
||||
class C {
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::function a==
|
||||
==SCOPE::function 'a'==
|
||||
namespace A {
|
||||
let x = 1;
|
||||
function foo() {
|
||||
@@ -30,7 +30,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::namespace B==
|
||||
==SCOPE::namespace 'B'==
|
||||
namespace A {
|
||||
let x = 1;
|
||||
function foo() {
|
||||
@@ -48,7 +48,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::namespace A==
|
||||
==SCOPE::namespace 'A'==
|
||||
namespace A {
|
||||
let x = 1;
|
||||
function foo() {
|
||||
@@ -66,7 +66,7 @@ namespace A {
|
||||
return foo();
|
||||
}
|
||||
}
|
||||
==SCOPE::file '/a.ts'==
|
||||
==SCOPE::global scope==
|
||||
namespace A {
|
||||
let x = 1;
|
||||
function foo() {
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::function a==
|
||||
==SCOPE::function 'a'==
|
||||
namespace A {
|
||||
function foo() {
|
||||
}
|
||||
@@ -28,7 +28,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::namespace B==
|
||||
==SCOPE::namespace 'B'==
|
||||
namespace A {
|
||||
function foo() {
|
||||
}
|
||||
@@ -45,7 +45,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::namespace A==
|
||||
==SCOPE::namespace 'A'==
|
||||
namespace A {
|
||||
function foo() {
|
||||
}
|
||||
@@ -62,7 +62,7 @@ namespace A {
|
||||
return foo();
|
||||
}
|
||||
}
|
||||
==SCOPE::file '/a.ts'==
|
||||
==SCOPE::global scope==
|
||||
namespace A {
|
||||
function foo() {
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::function a==
|
||||
==SCOPE::function 'a'==
|
||||
namespace A {
|
||||
function foo() {
|
||||
}
|
||||
@@ -32,7 +32,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::namespace B==
|
||||
==SCOPE::namespace 'B'==
|
||||
namespace A {
|
||||
function foo() {
|
||||
}
|
||||
@@ -51,7 +51,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::namespace A==
|
||||
==SCOPE::namespace 'A'==
|
||||
namespace A {
|
||||
function foo() {
|
||||
}
|
||||
@@ -70,7 +70,7 @@ namespace A {
|
||||
return foo();
|
||||
}
|
||||
}
|
||||
==SCOPE::file '/a.ts'==
|
||||
==SCOPE::global scope==
|
||||
namespace A {
|
||||
function foo() {
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::function a==
|
||||
==SCOPE::function 'a'==
|
||||
namespace A {
|
||||
let x = 1;
|
||||
export function foo() {
|
||||
@@ -34,7 +34,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::namespace B==
|
||||
==SCOPE::namespace 'B'==
|
||||
namespace A {
|
||||
let x = 1;
|
||||
export function foo() {
|
||||
@@ -55,7 +55,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::namespace A==
|
||||
==SCOPE::namespace 'A'==
|
||||
namespace A {
|
||||
let x = 1;
|
||||
export function foo() {
|
||||
@@ -76,7 +76,7 @@ namespace A {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
==SCOPE::file '/a.ts'==
|
||||
==SCOPE::global scope==
|
||||
namespace A {
|
||||
let x = 1;
|
||||
export function foo() {
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::function a==
|
||||
==SCOPE::function 'a'==
|
||||
namespace A {
|
||||
let x = 1;
|
||||
export function foo() {
|
||||
@@ -34,7 +34,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::namespace B==
|
||||
==SCOPE::namespace 'B'==
|
||||
namespace A {
|
||||
let x = 1;
|
||||
export function foo() {
|
||||
@@ -56,7 +56,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::namespace A==
|
||||
==SCOPE::namespace 'A'==
|
||||
namespace A {
|
||||
let x = 1;
|
||||
export function foo() {
|
||||
@@ -78,7 +78,7 @@ namespace A {
|
||||
return { __return: foo(), a };
|
||||
}
|
||||
}
|
||||
==SCOPE::file '/a.ts'==
|
||||
==SCOPE::global scope==
|
||||
namespace A {
|
||||
let x = 1;
|
||||
export function foo() {
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::function a==
|
||||
==SCOPE::function 'a'==
|
||||
namespace A {
|
||||
let x = 1;
|
||||
export namespace C {
|
||||
@@ -38,7 +38,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::namespace B==
|
||||
==SCOPE::namespace 'B'==
|
||||
namespace A {
|
||||
let x = 1;
|
||||
export namespace C {
|
||||
@@ -62,7 +62,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::namespace A==
|
||||
==SCOPE::namespace 'A'==
|
||||
namespace A {
|
||||
let x = 1;
|
||||
export namespace C {
|
||||
@@ -86,7 +86,7 @@ namespace A {
|
||||
return { __return: C.foo(), a };
|
||||
}
|
||||
}
|
||||
==SCOPE::file '/a.ts'==
|
||||
==SCOPE::global scope==
|
||||
namespace A {
|
||||
let x = 1;
|
||||
export namespace C {
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::function a==
|
||||
==SCOPE::function 'a'==
|
||||
namespace A {
|
||||
let x = 1;
|
||||
namespace B {
|
||||
@@ -22,7 +22,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::namespace B==
|
||||
==SCOPE::namespace 'B'==
|
||||
namespace A {
|
||||
let x = 1;
|
||||
namespace B {
|
||||
@@ -36,7 +36,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::namespace A==
|
||||
==SCOPE::namespace 'A'==
|
||||
namespace A {
|
||||
let x = 1;
|
||||
namespace B {
|
||||
@@ -50,7 +50,7 @@ namespace A {
|
||||
return 1 + a1 + x;
|
||||
}
|
||||
}
|
||||
==SCOPE::file '/a.ts'==
|
||||
==SCOPE::global scope==
|
||||
namespace A {
|
||||
let x = 1;
|
||||
namespace B {
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::function a==
|
||||
==SCOPE::function 'a'==
|
||||
namespace A {
|
||||
export interface I { x: number };
|
||||
namespace B {
|
||||
@@ -22,7 +22,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::namespace B==
|
||||
==SCOPE::namespace 'B'==
|
||||
namespace A {
|
||||
export interface I { x: number };
|
||||
namespace B {
|
||||
@@ -36,7 +36,7 @@ namespace A {
|
||||
}
|
||||
}
|
||||
}
|
||||
==SCOPE::namespace A==
|
||||
==SCOPE::namespace 'A'==
|
||||
namespace A {
|
||||
export interface I { x: number };
|
||||
namespace B {
|
||||
@@ -50,7 +50,7 @@ namespace A {
|
||||
return a1.x + 10;
|
||||
}
|
||||
}
|
||||
==SCOPE::file '/a.ts'==
|
||||
==SCOPE::global scope==
|
||||
namespace A {
|
||||
export interface I { x: number };
|
||||
namespace B {
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
//// [tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsAMD.ts] ////
|
||||
|
||||
//// [something.ts]
|
||||
export = 42;
|
||||
|
||||
//// [index.ts]
|
||||
export = async function() {
|
||||
const something = await import("./something");
|
||||
};
|
||||
|
||||
//// [something.js]
|
||||
define(["require", "exports"], function (require, exports) {
|
||||
"use strict";
|
||||
return 42;
|
||||
});
|
||||
//// [index.js]
|
||||
define(["require", "exports"], function (require, exports) {
|
||||
"use strict";
|
||||
return async function () {
|
||||
const something = await new Promise(function (resolve_1, reject_1) { require(["./something"], resolve_1, reject_1); });
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
=== tests/cases/conformance/dynamicImport/something.ts ===
|
||||
export = 42;
|
||||
No type information for this code.
|
||||
No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts ===
|
||||
export = async function() {
|
||||
const something = await import("./something");
|
||||
>something : Symbol(something, Decl(index.ts, 1, 9))
|
||||
>"./something" : Symbol("tests/cases/conformance/dynamicImport/something", Decl(something.ts, 0, 0))
|
||||
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
=== tests/cases/conformance/dynamicImport/something.ts ===
|
||||
export = 42;
|
||||
No type information for this code.
|
||||
No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts ===
|
||||
export = async function() {
|
||||
>async function() { const something = await import("./something");} : () => Promise<void>
|
||||
|
||||
const something = await import("./something");
|
||||
>something : 42
|
||||
>await import("./something") : 42
|
||||
>import("./something") : Promise<42>
|
||||
>"./something" : "./something"
|
||||
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
//// [tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsCJS.ts] ////
|
||||
|
||||
//// [something.ts]
|
||||
export = 42;
|
||||
|
||||
//// [index.ts]
|
||||
export = async function() {
|
||||
const something = await import("./something");
|
||||
};
|
||||
|
||||
//// [something.js]
|
||||
"use strict";
|
||||
module.exports = 42;
|
||||
//// [index.js]
|
||||
"use strict";
|
||||
module.exports = async function () {
|
||||
const something = await Promise.resolve().then(function () { return require("./something"); });
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
=== tests/cases/conformance/dynamicImport/something.ts ===
|
||||
export = 42;
|
||||
No type information for this code.
|
||||
No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts ===
|
||||
export = async function() {
|
||||
const something = await import("./something");
|
||||
>something : Symbol(something, Decl(index.ts, 1, 9))
|
||||
>"./something" : Symbol("tests/cases/conformance/dynamicImport/something", Decl(something.ts, 0, 0))
|
||||
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
=== tests/cases/conformance/dynamicImport/something.ts ===
|
||||
export = 42;
|
||||
No type information for this code.
|
||||
No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts ===
|
||||
export = async function() {
|
||||
>async function() { const something = await import("./something");} : () => Promise<void>
|
||||
|
||||
const something = await import("./something");
|
||||
>something : 42
|
||||
>await import("./something") : 42
|
||||
>import("./something") : Promise<42>
|
||||
>"./something" : "./something"
|
||||
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
//// [tests/cases/conformance/dynamicImport/importCallExpressionInExportEqualsUMD.ts] ////
|
||||
|
||||
//// [something.ts]
|
||||
export = 42;
|
||||
|
||||
//// [index.ts]
|
||||
export = async function() {
|
||||
const something = await import("./something");
|
||||
};
|
||||
|
||||
//// [something.js]
|
||||
(function (factory) {
|
||||
if (typeof module === "object" && typeof module.exports === "object") {
|
||||
var v = factory(require, exports);
|
||||
if (v !== undefined) module.exports = v;
|
||||
}
|
||||
else if (typeof define === "function" && define.amd) {
|
||||
define(["require", "exports"], factory);
|
||||
}
|
||||
})(function (require, exports) {
|
||||
"use strict";
|
||||
return 42;
|
||||
});
|
||||
//// [index.js]
|
||||
(function (factory) {
|
||||
if (typeof module === "object" && typeof module.exports === "object") {
|
||||
var v = factory(require, exports);
|
||||
if (v !== undefined) module.exports = v;
|
||||
}
|
||||
else if (typeof define === "function" && define.amd) {
|
||||
define(["require", "exports"], factory);
|
||||
}
|
||||
})(function (require, exports) {
|
||||
"use strict";
|
||||
var __syncRequire = typeof module === "object" && typeof module.exports === "object";
|
||||
return async function () {
|
||||
const something = await (__syncRequire ? Promise.resolve().then(function () { return require("./something"); }) : new Promise(function (resolve_1, reject_1) { require(["./something"], resolve_1, reject_1); }));
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
=== tests/cases/conformance/dynamicImport/something.ts ===
|
||||
export = 42;
|
||||
No type information for this code.
|
||||
No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts ===
|
||||
export = async function() {
|
||||
const something = await import("./something");
|
||||
>something : Symbol(something, Decl(index.ts, 1, 9))
|
||||
>"./something" : Symbol("tests/cases/conformance/dynamicImport/something", Decl(something.ts, 0, 0))
|
||||
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
=== tests/cases/conformance/dynamicImport/something.ts ===
|
||||
export = 42;
|
||||
No type information for this code.
|
||||
No type information for this code.=== tests/cases/conformance/dynamicImport/index.ts ===
|
||||
export = async function() {
|
||||
>async function() { const something = await import("./something");} : () => Promise<void>
|
||||
|
||||
const something = await import("./something");
|
||||
>something : 42
|
||||
>await import("./something") : 42
|
||||
>import("./something") : Promise<42>
|
||||
>"./something" : "./something"
|
||||
|
||||
};
|
||||
@@ -124,6 +124,7 @@ var stringOrNumberOrUndefined = C.inStaticNestedArrowFunction;
|
||||
|
||||
|
||||
//// [output.js]
|
||||
var _this = this;
|
||||
var C = /** @class */ (function () {
|
||||
function C() {
|
||||
var _this = this;
|
||||
|
||||
@@ -69,7 +69,7 @@ function boxify<T>(obj: T): Boxified<T> {
|
||||
|
||||
result[k] = box(obj[k]);
|
||||
>result[k] = box(obj[k]) : Box<T[keyof T]>
|
||||
>result[k] : Box<T[keyof T]>
|
||||
>result[k] : Boxified<T>[keyof T]
|
||||
>result : Boxified<T>
|
||||
>k : keyof T
|
||||
>box(obj[k]) : Box<T[keyof T]>
|
||||
@@ -107,7 +107,7 @@ function unboxify<T>(obj: Boxified<T>): T {
|
||||
>k : keyof T
|
||||
>unbox(obj[k]) : T[keyof T]
|
||||
>unbox : <T>(x: Box<T>) => T
|
||||
>obj[k] : Box<T[keyof T]>
|
||||
>obj[k] : Boxified<T>[keyof T]
|
||||
>obj : Boxified<T>
|
||||
>k : keyof T
|
||||
}
|
||||
@@ -131,7 +131,7 @@ function assignBoxified<T>(obj: Boxified<T>, values: T) {
|
||||
obj[k].value = values[k];
|
||||
>obj[k].value = values[k] : T[keyof T]
|
||||
>obj[k].value : T[keyof T]
|
||||
>obj[k] : Box<T[keyof T]>
|
||||
>obj[k] : Boxified<T>[keyof T]
|
||||
>obj : Boxified<T>
|
||||
>k : keyof T
|
||||
>value : T[keyof T]
|
||||
|
||||
@@ -27,8 +27,8 @@ function f1<K extends string, T>(obj: { [P in K]: T }, k: K) {
|
||||
>obj : { [P in K]: T; }
|
||||
|
||||
let x1 = obj[k1];
|
||||
>x1 : T
|
||||
>obj[k1] : T
|
||||
>x1 : { [P in K]: T; }[K]
|
||||
>obj[k1] : { [P in K]: T; }[K]
|
||||
>obj : { [P in K]: T; }
|
||||
>k1 : K
|
||||
}
|
||||
@@ -37,8 +37,8 @@ function f1<K extends string, T>(obj: { [P in K]: T }, k: K) {
|
||||
>obj : { [P in K]: T; }
|
||||
|
||||
let x2 = obj[k2];
|
||||
>x2 : T
|
||||
>obj[k2] : T
|
||||
>x2 : { [P in K]: T; }[K]
|
||||
>obj[k2] : { [P in K]: T; }[K]
|
||||
>obj : { [P in K]: T; }
|
||||
>k2 : K
|
||||
}
|
||||
@@ -70,8 +70,8 @@ function f2<T>(obj: { [P in keyof T]: T[P] }, k: keyof T) {
|
||||
>obj : { [P in keyof T]: T[P]; }
|
||||
|
||||
let x1 = obj[k1];
|
||||
>x1 : T[keyof T]
|
||||
>obj[k1] : T[keyof T]
|
||||
>x1 : { [P in keyof T]: T[P]; }[keyof T]
|
||||
>obj[k1] : { [P in keyof T]: T[P]; }[keyof T]
|
||||
>obj : { [P in keyof T]: T[P]; }
|
||||
>k1 : keyof T
|
||||
}
|
||||
@@ -80,8 +80,8 @@ function f2<T>(obj: { [P in keyof T]: T[P] }, k: keyof T) {
|
||||
>obj : { [P in keyof T]: T[P]; }
|
||||
|
||||
let x2 = obj[k2];
|
||||
>x2 : T[keyof T]
|
||||
>obj[k2] : T[keyof T]
|
||||
>x2 : { [P in keyof T]: T[P]; }[keyof T]
|
||||
>obj[k2] : { [P in keyof T]: T[P]; }[keyof T]
|
||||
>obj : { [P in keyof T]: T[P]; }
|
||||
>k2 : keyof T
|
||||
}
|
||||
@@ -115,8 +115,8 @@ function f3<T, K extends keyof T>(obj: { [P in K]: T[P] }, k: K) {
|
||||
>obj : { [P in K]: T[P]; }
|
||||
|
||||
let x1 = obj[k1];
|
||||
>x1 : T[K]
|
||||
>obj[k1] : T[K]
|
||||
>x1 : { [P in K]: T[P]; }[K]
|
||||
>obj[k1] : { [P in K]: T[P]; }[K]
|
||||
>obj : { [P in K]: T[P]; }
|
||||
>k1 : K
|
||||
}
|
||||
@@ -125,8 +125,8 @@ function f3<T, K extends keyof T>(obj: { [P in K]: T[P] }, k: K) {
|
||||
>obj : { [P in K]: T[P]; }
|
||||
|
||||
let x2 = obj[k2];
|
||||
>x2 : T[K]
|
||||
>obj[k2] : T[K]
|
||||
>x2 : { [P in K]: T[P]; }[K]
|
||||
>obj[k2] : { [P in K]: T[P]; }[K]
|
||||
>obj : { [P in K]: T[P]; }
|
||||
>k2 : K
|
||||
}
|
||||
|
||||
@@ -2194,7 +2194,7 @@ class Form<T> {
|
||||
|
||||
this.childFormFactories[prop](value)
|
||||
>this.childFormFactories[prop](value) : Form<T[K]>
|
||||
>this.childFormFactories[prop] : (v: T[K]) => Form<T[K]>
|
||||
>this.childFormFactories[prop] : { [K in keyof T]: (v: T[K]) => Form<T[K]>; }[K]
|
||||
>this.childFormFactories : { [K in keyof T]: (v: T[K]) => Form<T[K]>; }
|
||||
>this : this
|
||||
>childFormFactories : { [K in keyof T]: (v: T[K]) => Form<T[K]>; }
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
tests/cases/compiler/mappedTypeIndexedAccess.ts(18,5): error TS2322: Type '{ key: "foo"; value: number; }' is not assignable to type '{ key: "foo"; value: string; } | { key: "bar"; value: number; }'.
|
||||
Type '{ key: "foo"; value: number; }' is not assignable to type '{ key: "foo"; value: string; }'.
|
||||
Types of property 'value' are incompatible.
|
||||
Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/compiler/mappedTypeIndexedAccess.ts(24,5): error TS2322: Type '{ key: "foo"; value: number; }' is not assignable to type '{ key: "foo"; value: string; } | { key: "bar"; value: number; }'.
|
||||
Type '{ key: "foo"; value: number; }' is not assignable to type '{ key: "foo"; value: string; }'.
|
||||
Types of property 'value' are incompatible.
|
||||
Type 'number' is not assignable to type 'string'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/mappedTypeIndexedAccess.ts (2 errors) ====
|
||||
// Repro from #15756
|
||||
|
||||
type Pairs<T> = {
|
||||
[TKey in keyof T]: {
|
||||
key: TKey;
|
||||
value: T[TKey];
|
||||
};
|
||||
};
|
||||
|
||||
type Pair<T> = Pairs<T>[keyof T];
|
||||
|
||||
type FooBar = {
|
||||
foo: string;
|
||||
bar: number;
|
||||
};
|
||||
|
||||
// Error expected here
|
||||
let pair1: Pair<FooBar> = {
|
||||
~~~~~
|
||||
!!! error TS2322: Type '{ key: "foo"; value: number; }' is not assignable to type '{ key: "foo"; value: string; } | { key: "bar"; value: number; }'.
|
||||
!!! error TS2322: Type '{ key: "foo"; value: number; }' is not assignable to type '{ key: "foo"; value: string; }'.
|
||||
!!! error TS2322: Types of property 'value' are incompatible.
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
key: "foo",
|
||||
value: 3
|
||||
};
|
||||
|
||||
// Error expected here
|
||||
let pair2: Pairs<FooBar>[keyof FooBar] = {
|
||||
~~~~~
|
||||
!!! error TS2322: Type '{ key: "foo"; value: number; }' is not assignable to type '{ key: "foo"; value: string; } | { key: "bar"; value: number; }'.
|
||||
!!! error TS2322: Type '{ key: "foo"; value: number; }' is not assignable to type '{ key: "foo"; value: string; }'.
|
||||
!!! error TS2322: Types of property 'value' are incompatible.
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
key: "foo",
|
||||
value: 3
|
||||
};
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
//// [mappedTypeIndexedAccess.ts]
|
||||
// Repro from #15756
|
||||
|
||||
type Pairs<T> = {
|
||||
[TKey in keyof T]: {
|
||||
key: TKey;
|
||||
value: T[TKey];
|
||||
};
|
||||
};
|
||||
|
||||
type Pair<T> = Pairs<T>[keyof T];
|
||||
|
||||
type FooBar = {
|
||||
foo: string;
|
||||
bar: number;
|
||||
};
|
||||
|
||||
// Error expected here
|
||||
let pair1: Pair<FooBar> = {
|
||||
key: "foo",
|
||||
value: 3
|
||||
};
|
||||
|
||||
// Error expected here
|
||||
let pair2: Pairs<FooBar>[keyof FooBar] = {
|
||||
key: "foo",
|
||||
value: 3
|
||||
};
|
||||
|
||||
|
||||
//// [mappedTypeIndexedAccess.js]
|
||||
"use strict";
|
||||
// Repro from #15756
|
||||
// Error expected here
|
||||
var pair1 = {
|
||||
key: "foo",
|
||||
value: 3
|
||||
};
|
||||
// Error expected here
|
||||
var pair2 = {
|
||||
key: "foo",
|
||||
value: 3
|
||||
};
|
||||
@@ -1,76 +1,38 @@
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(11,5): error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'.
|
||||
Type 'T[string]' is not assignable to type 'U[keyof T]'.
|
||||
Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
Type 'T[keyof T]' is not assignable to type 'U[string]'.
|
||||
Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
Type 'T' is not assignable to type 'U'.
|
||||
Type 'T' is not assignable to type 'U'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(16,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K]'.
|
||||
Type 'T[string]' is not assignable to type 'U[K]'.
|
||||
Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
Type 'T[K]' is not assignable to type 'U[string]'.
|
||||
Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
Type 'T' is not assignable to type 'U'.
|
||||
Type 'T' is not assignable to type 'U'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(20,5): error TS2536: Type 'keyof U' cannot be used to index type 'T'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(21,5): error TS2322: Type 'T[keyof U]' is not assignable to type 'U[keyof U]'.
|
||||
Type 'T[string]' is not assignable to type 'U[keyof U]'.
|
||||
Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
Type 'T[keyof U]' is not assignable to type 'U[string]'.
|
||||
Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
Type 'T' is not assignable to type 'U'.
|
||||
Type 'T' is not assignable to type 'U'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(21,12): error TS2536: Type 'keyof U' cannot be used to index type 'T'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(25,5): error TS2536: Type 'K' cannot be used to index type 'T'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(26,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K]'.
|
||||
Type 'T[string]' is not assignable to type 'U[K]'.
|
||||
Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
Type 'T[K]' is not assignable to type 'U[string]'.
|
||||
Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
Type 'T' is not assignable to type 'U'.
|
||||
Type 'T' is not assignable to type 'U'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(26,12): error TS2536: Type 'K' cannot be used to index type 'T'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(30,5): error TS2322: Type 'T[keyof T] | undefined' is not assignable to type 'T[keyof T]'.
|
||||
Type 'undefined' is not assignable to type 'T[keyof T]'.
|
||||
Type 'undefined' is not assignable to type 'T[string]'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(35,5): error TS2322: Type 'T[K] | undefined' is not assignable to type 'T[K]'.
|
||||
Type 'undefined' is not assignable to type 'T[K]'.
|
||||
Type 'undefined' is not assignable to type 'T[string]'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(40,5): error TS2322: Type 'U[keyof T] | undefined' is not assignable to type 'T[keyof T]'.
|
||||
Type 'undefined' is not assignable to type 'T[keyof T]'.
|
||||
Type 'undefined' is not assignable to type 'T[string]'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(41,5): error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T] | undefined'.
|
||||
Type 'T[string]' is not assignable to type 'U[keyof T] | undefined'.
|
||||
Type 'T[string]' is not assignable to type 'U[keyof T]'.
|
||||
Type 'T[keyof T]' is not assignable to type 'U[keyof T]'.
|
||||
Type 'T[string]' is not assignable to type 'U[keyof T]'.
|
||||
Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
Type 'T[keyof T]' is not assignable to type 'U[string]'.
|
||||
Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
Type 'T' is not assignable to type 'U'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(45,5): error TS2322: Type 'U[K] | undefined' is not assignable to type 'T[K]'.
|
||||
Type 'undefined' is not assignable to type 'T[K]'.
|
||||
Type 'undefined' is not assignable to type 'T[string]'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(46,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K] | undefined'.
|
||||
Type 'T[string]' is not assignable to type 'U[K] | undefined'.
|
||||
Type 'T[string]' is not assignable to type 'U[K]'.
|
||||
Type 'T[K]' is not assignable to type 'U[K]'.
|
||||
Type 'T[string]' is not assignable to type 'U[K]'.
|
||||
Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
Type 'T[K]' is not assignable to type 'U[string]'.
|
||||
Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
Type 'T' is not assignable to type 'U'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(30,5): error TS2322: Type 'Partial<T>[keyof T]' is not assignable to type 'T[keyof T]'.
|
||||
Type 'T[keyof T] | undefined' is not assignable to type 'T[keyof T]'.
|
||||
Type 'undefined' is not assignable to type 'T[keyof T]'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(35,5): error TS2322: Type 'Partial<T>[K]' is not assignable to type 'T[K]'.
|
||||
Type 'T[K] | undefined' is not assignable to type 'T[K]'.
|
||||
Type 'undefined' is not assignable to type 'T[K]'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(40,5): error TS2322: Type 'Partial<U>[keyof T]' is not assignable to type 'T[keyof T]'.
|
||||
Type 'U[keyof T] | undefined' is not assignable to type 'T[keyof T]'.
|
||||
Type 'undefined' is not assignable to type 'T[keyof T]'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(45,5): error TS2322: Type 'Partial<U>[K]' is not assignable to type 'T[K]'.
|
||||
Type 'U[K] | undefined' is not assignable to type 'T[K]'.
|
||||
Type 'undefined' is not assignable to type 'T[K]'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(51,5): error TS2542: Index signature in type 'Readonly<T>' only permits reading.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(56,5): error TS2542: Index signature in type 'Readonly<T>' only permits reading.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(61,5): error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'.
|
||||
Type 'T[string]' is not assignable to type 'U[keyof T]'.
|
||||
Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
Type 'T[keyof T]' is not assignable to type 'U[string]'.
|
||||
Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
Type 'T' is not assignable to type 'U'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(61,5): error TS2322: Type 'T[keyof T]' is not assignable to type 'Readonly<U>[keyof T]'.
|
||||
Type 'T' is not assignable to type 'Readonly<U>'.
|
||||
Type 'T[keyof T]' is not assignable to type 'U[keyof T]'.
|
||||
Type 'T' is not assignable to type 'U'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(61,5): error TS2542: Index signature in type 'Readonly<U>' only permits reading.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(66,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K]'.
|
||||
Type 'T[string]' is not assignable to type 'U[K]'.
|
||||
Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
Type 'T[K]' is not assignable to type 'U[string]'.
|
||||
Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
Type 'T' is not assignable to type 'U'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(66,5): error TS2322: Type 'T[K]' is not assignable to type 'Readonly<U>[K]'.
|
||||
Type 'T' is not assignable to type 'Readonly<U>'.
|
||||
Type 'T[K]' is not assignable to type 'U[K]'.
|
||||
Type 'T' is not assignable to type 'U'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(66,5): error TS2542: Index signature in type 'Readonly<U>' only permits reading.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(72,5): error TS2322: Type 'Partial<T>' is not assignable to type 'T'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(78,5): error TS2322: Type 'Partial<Thing>' is not assignable to type 'Partial<T>'.
|
||||
@@ -78,11 +40,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(88,5): error TS2
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(127,5): error TS2322: Type 'Partial<U>' is not assignable to type 'Identity<U>'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(143,5): error TS2322: Type '{ [P in keyof T]: T[P]; }' is not assignable to type '{ [P in keyof T]: U[P]; }'.
|
||||
Type 'T[P]' is not assignable to type 'U[P]'.
|
||||
Type 'T[string]' is not assignable to type 'U[P]'.
|
||||
Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
Type 'T[P]' is not assignable to type 'U[string]'.
|
||||
Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
Type 'T' is not assignable to type 'U'.
|
||||
Type 'T' is not assignable to type 'U'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(148,5): error TS2322: Type '{ [P in keyof T]: T[P]; }' is not assignable to type '{ [P in keyof U]: U[P]; }'.
|
||||
Type 'keyof U' is not assignable to type 'keyof T'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(153,5): error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in keyof T]: T[P]; }'.
|
||||
@@ -93,14 +51,10 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(163,5): error TS
|
||||
Type 'keyof T' is not assignable to type 'K'.
|
||||
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in K]: U[P]; }'.
|
||||
Type 'T[P]' is not assignable to type 'U[P]'.
|
||||
Type 'T[string]' is not assignable to type 'U[P]'.
|
||||
Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
Type 'T[P]' is not assignable to type 'U[string]'.
|
||||
Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
Type 'T' is not assignable to type 'U'.
|
||||
Type 'T' is not assignable to type 'U'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/mapped/mappedTypeRelationships.ts (30 errors) ====
|
||||
==== tests/cases/conformance/types/mapped/mappedTypeRelationships.ts (28 errors) ====
|
||||
function f1<T>(x: T, k: keyof T) {
|
||||
return x[k];
|
||||
}
|
||||
@@ -114,11 +68,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS
|
||||
y[k] = x[k]; // Error
|
||||
~~~~
|
||||
!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'U'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'U'.
|
||||
}
|
||||
|
||||
function f4<T, U extends T, K extends keyof T>(x: T, y: U, k: K) {
|
||||
@@ -126,11 +76,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS
|
||||
y[k] = x[k]; // Error
|
||||
~~~~
|
||||
!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T[K]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'U'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'U'.
|
||||
}
|
||||
|
||||
function f5<T, U extends T>(x: T, y: U, k: keyof U) {
|
||||
@@ -140,11 +86,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS
|
||||
y[k] = x[k]; // Error
|
||||
~~~~
|
||||
!!! error TS2322: Type 'T[keyof U]' is not assignable to type 'U[keyof U]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof U]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T[keyof U]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'U'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'U'.
|
||||
~~~~
|
||||
!!! error TS2536: Type 'keyof U' cannot be used to index type 'T'.
|
||||
}
|
||||
@@ -156,11 +98,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS
|
||||
y[k] = x[k]; // Error
|
||||
~~~~
|
||||
!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T[K]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'U'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'U'.
|
||||
~~~~
|
||||
!!! error TS2536: Type 'K' cannot be used to index type 'T'.
|
||||
}
|
||||
@@ -168,57 +106,37 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS
|
||||
function f10<T>(x: T, y: Partial<T>, k: keyof T) {
|
||||
x[k] = y[k]; // Error
|
||||
~~~~
|
||||
!!! error TS2322: Type 'T[keyof T] | undefined' is not assignable to type 'T[keyof T]'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'T[keyof T]'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'T[string]'.
|
||||
!!! error TS2322: Type 'Partial<T>[keyof T]' is not assignable to type 'T[keyof T]'.
|
||||
!!! error TS2322: Type 'T[keyof T] | undefined' is not assignable to type 'T[keyof T]'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'T[keyof T]'.
|
||||
y[k] = x[k];
|
||||
}
|
||||
|
||||
function f11<T, K extends keyof T>(x: T, y: Partial<T>, k: K) {
|
||||
x[k] = y[k]; // Error
|
||||
~~~~
|
||||
!!! error TS2322: Type 'T[K] | undefined' is not assignable to type 'T[K]'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'T[K]'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'T[string]'.
|
||||
!!! error TS2322: Type 'Partial<T>[K]' is not assignable to type 'T[K]'.
|
||||
!!! error TS2322: Type 'T[K] | undefined' is not assignable to type 'T[K]'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'T[K]'.
|
||||
y[k] = x[k];
|
||||
}
|
||||
|
||||
function f12<T, U extends T>(x: T, y: Partial<U>, k: keyof T) {
|
||||
x[k] = y[k]; // Error
|
||||
~~~~
|
||||
!!! error TS2322: Type 'U[keyof T] | undefined' is not assignable to type 'T[keyof T]'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'T[keyof T]'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'T[string]'.
|
||||
!!! error TS2322: Type 'Partial<U>[keyof T]' is not assignable to type 'T[keyof T]'.
|
||||
!!! error TS2322: Type 'U[keyof T] | undefined' is not assignable to type 'T[keyof T]'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'T[keyof T]'.
|
||||
y[k] = x[k]; // Error
|
||||
~~~~
|
||||
!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T] | undefined'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T] | undefined'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T]'.
|
||||
!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'U'.
|
||||
}
|
||||
|
||||
function f13<T, U extends T, K extends keyof T>(x: T, y: Partial<U>, k: K) {
|
||||
x[k] = y[k]; // Error
|
||||
~~~~
|
||||
!!! error TS2322: Type 'U[K] | undefined' is not assignable to type 'T[K]'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'T[K]'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'T[string]'.
|
||||
!!! error TS2322: Type 'Partial<U>[K]' is not assignable to type 'T[K]'.
|
||||
!!! error TS2322: Type 'U[K] | undefined' is not assignable to type 'T[K]'.
|
||||
!!! error TS2322: Type 'undefined' is not assignable to type 'T[K]'.
|
||||
y[k] = x[k]; // Error
|
||||
~~~~
|
||||
!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K] | undefined'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K] | undefined'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'.
|
||||
!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T[K]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'U'.
|
||||
}
|
||||
|
||||
function f20<T>(x: T, y: Readonly<T>, k: keyof T) {
|
||||
@@ -239,12 +157,10 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS
|
||||
x[k] = y[k];
|
||||
y[k] = x[k]; // Error
|
||||
~~~~
|
||||
!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'U'.
|
||||
!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'Readonly<U>[keyof T]'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'Readonly<U>'.
|
||||
!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'U'.
|
||||
~~~~
|
||||
!!! error TS2542: Index signature in type 'Readonly<U>' only permits reading.
|
||||
}
|
||||
@@ -253,12 +169,10 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS
|
||||
x[k] = y[k];
|
||||
y[k] = x[k]; // Error
|
||||
~~~~
|
||||
!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T[K]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'U'.
|
||||
!!! error TS2322: Type 'T[K]' is not assignable to type 'Readonly<U>[K]'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'Readonly<U>'.
|
||||
!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'U'.
|
||||
~~~~
|
||||
!!! error TS2542: Index signature in type 'Readonly<U>' only permits reading.
|
||||
}
|
||||
@@ -349,11 +263,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS
|
||||
~
|
||||
!!! error TS2322: Type '{ [P in keyof T]: T[P]; }' is not assignable to type '{ [P in keyof T]: U[P]; }'.
|
||||
!!! error TS2322: Type 'T[P]' is not assignable to type 'U[P]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[P]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T[P]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'U'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'U'.
|
||||
}
|
||||
|
||||
function f72<T, U extends T>(x: { [P in keyof T]: T[P] }, y: { [P in keyof U]: U[P] }) {
|
||||
@@ -394,10 +304,6 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS
|
||||
~
|
||||
!!! error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in K]: U[P]; }'.
|
||||
!!! error TS2322: Type 'T[P]' is not assignable to type 'U[P]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[P]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T[P]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'U'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'U'.
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ function boxify<T>(obj: T): Boxified<T> {
|
||||
|
||||
result[k] = { value: obj[k] };
|
||||
>result[k] = { value: obj[k] } : { value: T[keyof T]; }
|
||||
>result[k] : Box<T[keyof T]>
|
||||
>result[k] : Boxified<T>[keyof T]
|
||||
>result : Boxified<T>
|
||||
>k : keyof T
|
||||
>{ value: obj[k] } : { value: T[keyof T]; }
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
tests/cases/compiler/index.ts(4,1): error TS2693: 'B' only refers to a type, but is being used as a value here.
|
||||
tests/cases/compiler/index.ts(9,10): error TS2304: Cannot find name 'OriginalB'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/b.ts (0 errors) ====
|
||||
export const zzz = 123;
|
||||
|
||||
==== tests/cases/compiler/a.ts (0 errors) ====
|
||||
import * as B from "./b";
|
||||
|
||||
interface B {
|
||||
x: string;
|
||||
}
|
||||
|
||||
const x: B = { x: "" };
|
||||
B.zzz;
|
||||
|
||||
export { B };
|
||||
|
||||
==== tests/cases/compiler/index.ts (2 errors) ====
|
||||
import { B } from "./a";
|
||||
|
||||
const x: B = { x: "" };
|
||||
B.zzz;
|
||||
~
|
||||
!!! error TS2693: 'B' only refers to a type, but is being used as a value here.
|
||||
|
||||
import * as OriginalB from "./b";
|
||||
OriginalB.zzz;
|
||||
|
||||
const y: OriginalB = x;
|
||||
~~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'OriginalB'.
|
||||
@@ -0,0 +1,46 @@
|
||||
//// [tests/cases/compiler/noCrashOnImportShadowing.ts] ////
|
||||
|
||||
//// [b.ts]
|
||||
export const zzz = 123;
|
||||
|
||||
//// [a.ts]
|
||||
import * as B from "./b";
|
||||
|
||||
interface B {
|
||||
x: string;
|
||||
}
|
||||
|
||||
const x: B = { x: "" };
|
||||
B.zzz;
|
||||
|
||||
export { B };
|
||||
|
||||
//// [index.ts]
|
||||
import { B } from "./a";
|
||||
|
||||
const x: B = { x: "" };
|
||||
B.zzz;
|
||||
|
||||
import * as OriginalB from "./b";
|
||||
OriginalB.zzz;
|
||||
|
||||
const y: OriginalB = x;
|
||||
|
||||
//// [b.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.zzz = 123;
|
||||
//// [a.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var B = require("./b");
|
||||
var x = { x: "" };
|
||||
B.zzz;
|
||||
//// [index.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var x = { x: "" };
|
||||
B.zzz;
|
||||
var OriginalB = require("./b");
|
||||
OriginalB.zzz;
|
||||
var y = x;
|
||||
@@ -0,0 +1,15 @@
|
||||
//// [shouldNotPrintNullEscapesIntoOctalLiterals.ts]
|
||||
"use strict";
|
||||
`\x001`;
|
||||
`\u00001`;
|
||||
`\u{00000000}1`;
|
||||
`\u{000000}1`;
|
||||
`\u{0}1`;
|
||||
|
||||
//// [shouldNotPrintNullEscapesIntoOctalLiterals.js]
|
||||
"use strict";
|
||||
"\x001";
|
||||
"\x001";
|
||||
"\x001";
|
||||
"\x001";
|
||||
"\x001";
|
||||
@@ -0,0 +1,8 @@
|
||||
=== tests/cases/compiler/shouldNotPrintNullEscapesIntoOctalLiterals.ts ===
|
||||
"use strict";
|
||||
No type information for this code.`\x001`;
|
||||
No type information for this code.`\u00001`;
|
||||
No type information for this code.`\u{00000000}1`;
|
||||
No type information for this code.`\u{000000}1`;
|
||||
No type information for this code.`\u{0}1`;
|
||||
No type information for this code.
|
||||
@@ -0,0 +1,19 @@
|
||||
=== tests/cases/compiler/shouldNotPrintNullEscapesIntoOctalLiterals.ts ===
|
||||
"use strict";
|
||||
>"use strict" : "use strict"
|
||||
|
||||
`\x001`;
|
||||
>`\x001` : "\x001"
|
||||
|
||||
`\u00001`;
|
||||
>`\u00001` : "\x001"
|
||||
|
||||
`\u{00000000}1`;
|
||||
>`\u{00000000}1` : "\x001"
|
||||
|
||||
`\u{000000}1`;
|
||||
>`\u{000000}1` : "\x001"
|
||||
|
||||
`\u{0}1`;
|
||||
>`\u{0}1` : "\x001"
|
||||
|
||||
@@ -35,6 +35,7 @@ var __extends = (this && this.__extends) || (function () {
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
var _this = this;
|
||||
var P = /** @class */ (function () {
|
||||
function P() {
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ class Vector {
|
||||
}
|
||||
|
||||
//// [thisInArrowFunctionInStaticInitializer1.js]
|
||||
var _this = this;
|
||||
function log(a) { }
|
||||
var Vector = /** @class */ (function () {
|
||||
function Vector() {
|
||||
|
||||
@@ -10,6 +10,7 @@ class P {
|
||||
}
|
||||
|
||||
//// [thisInConstructorParameter2.js]
|
||||
var _this = this;
|
||||
var P = /** @class */ (function () {
|
||||
function P(z, zz) {
|
||||
if (z === void 0) { z = this; }
|
||||
|
||||
@@ -59,6 +59,7 @@ var __extends = (this && this.__extends) || (function () {
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
var _this = this;
|
||||
//'this' in static member initializer
|
||||
var ErrClass1 = /** @class */ (function () {
|
||||
function ErrClass1() {
|
||||
|
||||
@@ -60,6 +60,7 @@ var __extends = (this && this.__extends) || (function () {
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
var _this = this;
|
||||
//'this' in static member initializer
|
||||
var ErrClass1 = /** @class */ (function () {
|
||||
function ErrClass1() {
|
||||
|
||||
@@ -21,6 +21,7 @@ class Foo {
|
||||
}
|
||||
|
||||
//// [thisInOuterClassBody.js]
|
||||
var _this = this;
|
||||
var Foo = /** @class */ (function () {
|
||||
function Foo() {
|
||||
this.x = this;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user