mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-29 16:29:19 -05:00
Merge branch 'master' into fixMappedTypeCombinedMappers
# Conflicts: # src/compiler/checker.ts
This commit is contained in:
@@ -4606,7 +4606,7 @@ namespace ts {
|
||||
// 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.
|
||||
const iterationMapper = createUnaryTypeMapper(typeParameter, t);
|
||||
const iterationMapper = createTypeMapper([typeParameter], [t]);
|
||||
const templateMapper = type.mapper ? combineTypeMappers(type.mapper, iterationMapper) : iterationMapper;
|
||||
const propType = instantiateType(templateType, templateMapper);
|
||||
// If the current iteration type constituent is a string literal type, create a property.
|
||||
@@ -4666,7 +4666,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getErasedTemplateTypeFromMappedType(type: MappedType) {
|
||||
return instantiateType(getTemplateTypeFromMappedType(type), createUnaryTypeMapper(getTypeParameterFromMappedType(type), anyType));
|
||||
return instantiateType(getTemplateTypeFromMappedType(type), createTypeEraser([getTypeParameterFromMappedType(type)]));
|
||||
}
|
||||
|
||||
function isGenericMappedType(type: Type) {
|
||||
@@ -5058,9 +5058,10 @@ namespace ts {
|
||||
if (!links.resolvedSignature) {
|
||||
const parameters: Symbol[] = [];
|
||||
let hasLiteralTypes = false;
|
||||
let minArgumentCount = -1;
|
||||
let minArgumentCount = 0;
|
||||
let thisParameter: Symbol = undefined;
|
||||
let hasThisParameter: boolean;
|
||||
const iife = getImmediatelyInvokedFunctionExpression(declaration);
|
||||
const isJSConstructSignature = isJSDocConstructSignature(declaration);
|
||||
|
||||
// If this is a JSDoc construct signature, then skip the first parameter in the
|
||||
@@ -5087,14 +5088,12 @@ namespace ts {
|
||||
hasLiteralTypes = true;
|
||||
}
|
||||
|
||||
if (param.initializer || param.questionToken || param.dotDotDotToken || isJSDocOptionalParameter(param)) {
|
||||
if (minArgumentCount < 0) {
|
||||
minArgumentCount = i - (hasThisParameter ? 1 : 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// If we see any required parameters, it means the prior ones were not in fact optional.
|
||||
minArgumentCount = -1;
|
||||
// Record a new minimum argument count if this is not an optional parameter
|
||||
const isOptionalParameter = param.initializer || param.questionToken || param.dotDotDotToken ||
|
||||
iife && parameters.length > iife.arguments.length && !param.type ||
|
||||
isJSDocOptionalParameter(param);
|
||||
if (!isOptionalParameter) {
|
||||
minArgumentCount = parameters.length;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5109,13 +5108,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
if (minArgumentCount < 0) {
|
||||
minArgumentCount = declaration.parameters.length - (hasThisParameter ? 1 : 0);
|
||||
}
|
||||
if (isJSConstructSignature) {
|
||||
minArgumentCount--;
|
||||
}
|
||||
|
||||
const classType = declaration.kind === SyntaxKind.Constructor ?
|
||||
getDeclaredTypeOfClassOrInterface(getMergedSymbol((<ClassDeclaration>declaration.parent).symbol))
|
||||
: undefined;
|
||||
@@ -6135,7 +6127,7 @@ namespace ts {
|
||||
error(accessExpression, Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(type));
|
||||
return unknownType;
|
||||
}
|
||||
const mapper = createUnaryTypeMapper(getTypeParameterFromMappedType(type), indexType);
|
||||
const mapper = createTypeMapper([getTypeParameterFromMappedType(type)], [indexType]);
|
||||
const templateMapper = type.mapper ? combineTypeMappers(type.mapper, mapper) : mapper;
|
||||
return instantiateType(getTemplateTypeFromMappedType(type), templateMapper);
|
||||
}
|
||||
@@ -6241,7 +6233,7 @@ namespace ts {
|
||||
* this function should be called in a left folding style, with left = previous result of getSpreadType
|
||||
* and right = the new element to be spread.
|
||||
*/
|
||||
function getSpreadType(left: Type, right: Type, isFromObjectLiteral: boolean): Type {
|
||||
function getSpreadType(left: Type, right: Type): Type {
|
||||
if (left.flags & TypeFlags.Any || right.flags & TypeFlags.Any) {
|
||||
return anyType;
|
||||
}
|
||||
@@ -6254,10 +6246,10 @@ namespace ts {
|
||||
return left;
|
||||
}
|
||||
if (left.flags & TypeFlags.Union) {
|
||||
return mapType(left, t => getSpreadType(t, right, isFromObjectLiteral));
|
||||
return mapType(left, t => getSpreadType(t, right));
|
||||
}
|
||||
if (right.flags & TypeFlags.Union) {
|
||||
return mapType(right, t => getSpreadType(left, t, isFromObjectLiteral));
|
||||
return mapType(right, t => getSpreadType(left, t));
|
||||
}
|
||||
|
||||
const members = createMap<Symbol>();
|
||||
@@ -6276,18 +6268,18 @@ namespace ts {
|
||||
|
||||
for (const rightProp of getPropertiesOfType(right)) {
|
||||
// we approximate own properties as non-methods plus methods that are inside the object literal
|
||||
const isOwnProperty = !(rightProp.flags & SymbolFlags.Method) || isFromObjectLiteral;
|
||||
const isSetterWithoutGetter = rightProp.flags & SymbolFlags.SetAccessor && !(rightProp.flags & SymbolFlags.GetAccessor);
|
||||
if (getDeclarationModifierFlagsFromSymbol(rightProp) & (ModifierFlags.Private | ModifierFlags.Protected)) {
|
||||
skippedPrivateMembers[rightProp.name] = true;
|
||||
}
|
||||
else if (isOwnProperty && !isSetterWithoutGetter) {
|
||||
else if (!isClassMethod(rightProp) && !isSetterWithoutGetter) {
|
||||
members[rightProp.name] = rightProp;
|
||||
}
|
||||
}
|
||||
for (const leftProp of getPropertiesOfType(left)) {
|
||||
if (leftProp.flags & SymbolFlags.SetAccessor && !(leftProp.flags & SymbolFlags.GetAccessor)
|
||||
|| leftProp.name in skippedPrivateMembers) {
|
||||
|| leftProp.name in skippedPrivateMembers
|
||||
|| isClassMethod(leftProp)) {
|
||||
continue;
|
||||
}
|
||||
if (leftProp.name in members) {
|
||||
@@ -6312,6 +6304,10 @@ namespace ts {
|
||||
return createAnonymousType(undefined, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
|
||||
}
|
||||
|
||||
function isClassMethod(prop: Symbol) {
|
||||
return prop.flags & SymbolFlags.Method && find(prop.declarations, decl => isClassLike(decl.parent));
|
||||
}
|
||||
|
||||
function createLiteralType(flags: TypeFlags, text: string) {
|
||||
const type = <LiteralType>createType(flags);
|
||||
type.text = text;
|
||||
@@ -6502,16 +6498,16 @@ namespace ts {
|
||||
return <T>instantiations[type.id] || (instantiations[type.id] = instantiator(type, mapper));
|
||||
}
|
||||
|
||||
function createUnaryTypeMapper(source: Type, target: Type): TypeMapper {
|
||||
return t => t === source ? target : t;
|
||||
function makeUnaryTypeMapper(source: Type, target: Type) {
|
||||
return (t: Type) => t === source ? target : t;
|
||||
}
|
||||
|
||||
function createBinaryTypeMapper(source1: Type, target1: Type, source2: Type, target2: Type): TypeMapper {
|
||||
return t => t === source1 ? target1 : t === source2 ? target2 : t;
|
||||
function makeBinaryTypeMapper(source1: Type, target1: Type, source2: Type, target2: Type) {
|
||||
return (t: Type) => t === source1 ? target1 : t === source2 ? target2 : t;
|
||||
}
|
||||
|
||||
function createArrayTypeMapper(sources: Type[], targets: Type[]): TypeMapper {
|
||||
return t => {
|
||||
function makeArrayTypeMapper(sources: Type[], targets: Type[]) {
|
||||
return (t: Type) => {
|
||||
for (let i = 0; i < sources.length; i++) {
|
||||
if (t === sources[i]) {
|
||||
return targets ? targets[i] : anyType;
|
||||
@@ -6522,11 +6518,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
function createTypeMapper(sources: Type[], targets: Type[]): TypeMapper {
|
||||
const count = sources.length;
|
||||
const mapper: TypeMapper =
|
||||
count == 1 ? createUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) :
|
||||
count == 2 ? createBinaryTypeMapper(sources[0], targets ? targets[0] : anyType, sources[1], targets ? targets[1] : anyType) :
|
||||
createArrayTypeMapper(sources, targets);
|
||||
const mapper: TypeMapper = sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) :
|
||||
sources.length === 2 ? makeBinaryTypeMapper(sources[0], targets ? targets[0] : anyType, sources[1], targets ? targets[1] : anyType) :
|
||||
makeArrayTypeMapper(sources, targets);
|
||||
mapper.mappedTypes = sources;
|
||||
return mapper;
|
||||
}
|
||||
@@ -6560,7 +6554,7 @@ namespace ts {
|
||||
|
||||
function combineTypeMappers(mapper1: TypeMapper, mapper2: TypeMapper): TypeMapper {
|
||||
const mapper: TypeMapper = t => instantiateType(mapper1(t), mapper2);
|
||||
mapper.mappedTypes = mapper1.mappedTypes;
|
||||
mapper.mappedTypes = concatenate(mapper1.mappedTypes, mapper2.mappedTypes);
|
||||
return mapper;
|
||||
}
|
||||
|
||||
@@ -10936,23 +10930,23 @@ namespace ts {
|
||||
const func = parameter.parent;
|
||||
if (isContextSensitiveFunctionOrObjectLiteralMethod(func)) {
|
||||
const iife = getImmediatelyInvokedFunctionExpression(func);
|
||||
if (iife) {
|
||||
if (iife && iife.arguments) {
|
||||
const indexOfParameter = indexOf(func.parameters, parameter);
|
||||
if (iife.arguments && indexOfParameter < iife.arguments.length) {
|
||||
if (parameter.dotDotDotToken) {
|
||||
const restTypes: Type[] = [];
|
||||
for (let i = indexOfParameter; i < iife.arguments.length; i++) {
|
||||
restTypes.push(getWidenedLiteralType(checkExpression(iife.arguments[i])));
|
||||
}
|
||||
return createArrayType(getUnionType(restTypes));
|
||||
if (parameter.dotDotDotToken) {
|
||||
const restTypes: Type[] = [];
|
||||
for (let i = indexOfParameter; i < iife.arguments.length; i++) {
|
||||
restTypes.push(getWidenedLiteralType(checkExpression(iife.arguments[i])));
|
||||
}
|
||||
const links = getNodeLinks(iife);
|
||||
const cached = links.resolvedSignature;
|
||||
links.resolvedSignature = anySignature;
|
||||
const type = getWidenedLiteralType(checkExpression(iife.arguments[indexOfParameter]));
|
||||
links.resolvedSignature = cached;
|
||||
return type;
|
||||
return restTypes.length ? createArrayType(getUnionType(restTypes)) : undefined;
|
||||
}
|
||||
const links = getNodeLinks(iife);
|
||||
const cached = links.resolvedSignature;
|
||||
links.resolvedSignature = anySignature;
|
||||
const type = indexOfParameter < iife.arguments.length ?
|
||||
getWidenedLiteralType(checkExpression(iife.arguments[indexOfParameter])) :
|
||||
parameter.initializer ? undefined : undefinedWideningType;
|
||||
links.resolvedSignature = cached;
|
||||
return type;
|
||||
}
|
||||
const contextualSignature = getContextualSignature(func);
|
||||
if (contextualSignature) {
|
||||
@@ -11661,7 +11655,7 @@ namespace ts {
|
||||
checkExternalEmitHelpers(memberDecl, ExternalEmitHelpers.Assign);
|
||||
}
|
||||
if (propertiesArray.length > 0) {
|
||||
spread = getSpreadType(spread, createObjectLiteralType(), /*isFromObjectLiteral*/ true);
|
||||
spread = getSpreadType(spread, createObjectLiteralType());
|
||||
propertiesArray = [];
|
||||
propertiesTable = createMap<Symbol>();
|
||||
hasComputedStringProperty = false;
|
||||
@@ -11673,7 +11667,7 @@ namespace ts {
|
||||
error(memberDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types);
|
||||
return unknownType;
|
||||
}
|
||||
spread = getSpreadType(spread, type, /*isFromObjectLiteral*/ false);
|
||||
spread = getSpreadType(spread, type);
|
||||
offset = i + 1;
|
||||
continue;
|
||||
}
|
||||
@@ -11718,7 +11712,7 @@ namespace ts {
|
||||
|
||||
if (spread !== emptyObjectType) {
|
||||
if (propertiesArray.length > 0) {
|
||||
spread = getSpreadType(spread, createObjectLiteralType(), /*isFromObjectLiteral*/ true);
|
||||
spread = getSpreadType(spread, createObjectLiteralType());
|
||||
}
|
||||
if (spread.flags & TypeFlags.Object) {
|
||||
// only set the symbol and flags if this is a (fresh) object type
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** Array that is only intended to be pushed to, never read. */
|
||||
interface Push<T> {
|
||||
export interface Push<T> {
|
||||
push(value: T): void;
|
||||
}
|
||||
|
||||
@@ -357,7 +357,7 @@ namespace ts {
|
||||
* Then it computes the set of parent folders for 'directory' that should have the same module resolution result
|
||||
* and for every parent folder in set it adds entry: parent -> module resolution. .
|
||||
* Lets say we first directory name: /a/b/c/d/e and resolution result is: /a/b/bar.ts.
|
||||
* Set of parent folders that should have the same result will be:
|
||||
* Set of parent folders that should have the same result will be:
|
||||
* [
|
||||
* /a/b/c/d, /a/b/c, /a/b
|
||||
* ]
|
||||
@@ -391,7 +391,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getCommonPrefix(directory: Path, resolution: string) {
|
||||
if (resolution === undefined) {
|
||||
return undefined;
|
||||
@@ -421,7 +421,7 @@ namespace ts {
|
||||
trace(host, Diagnostics.Resolving_module_0_from_1, moduleName, containingFile);
|
||||
}
|
||||
const containingDirectory = getDirectoryPath(containingFile);
|
||||
let perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory);
|
||||
const perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory);
|
||||
let result = perFolderCache && perFolderCache[moduleName];
|
||||
|
||||
if (result) {
|
||||
@@ -1022,7 +1022,7 @@ namespace ts {
|
||||
|
||||
/**
|
||||
* Represents result of search. Normally when searching among several alternatives we treat value `undefined` as indicator
|
||||
* that search fails and we should try another option.
|
||||
* that search fails and we should try another option.
|
||||
* However this does not allow us to represent final result that should be used instead of further searching (i.e. a final result that was found in cache).
|
||||
* SearchResult is used to deal with this issue, its values represents following outcomes:
|
||||
* - undefined - not found, continue searching
|
||||
@@ -1030,7 +1030,7 @@ namespace ts {
|
||||
* - { value: <some-value> } - found - stop searching
|
||||
*/
|
||||
type SearchResult<T> = { value: T | undefined } | undefined;
|
||||
|
||||
|
||||
/**
|
||||
* Wraps value to SearchResult.
|
||||
* @returns undefined if value is undefined or { value } otherwise
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/// <reference path='../compiler/utilities.ts' />
|
||||
|
||||
/* @internal */
|
||||
namespace ts.Completions {
|
||||
export function getCompletionsAtPosition(host: LanguageServiceHost, typeChecker: TypeChecker, log: (message: string) => void, compilerOptions: CompilerOptions, sourceFile: SourceFile, position: number): CompletionInfo {
|
||||
export function getCompletionsAtPosition(host: LanguageServiceHost, typeChecker: TypeChecker, log: (message: string) => void, compilerOptions: CompilerOptions, sourceFile: SourceFile, position: number): CompletionInfo | undefined {
|
||||
if (isInReferenceComment(sourceFile, position)) {
|
||||
return getTripleSlashReferenceCompletion(sourceFile, position);
|
||||
}
|
||||
@@ -134,7 +132,7 @@ namespace ts.Completions {
|
||||
return uniqueNames;
|
||||
}
|
||||
|
||||
function getStringLiteralCompletionEntries(sourceFile: SourceFile, position: number) {
|
||||
function getStringLiteralCompletionEntries(sourceFile: SourceFile, position: number): CompletionInfo | undefined {
|
||||
const node = findPrecedingToken(position, sourceFile);
|
||||
if (!node || node.kind !== SyntaxKind.StringLiteral) {
|
||||
return undefined;
|
||||
@@ -174,7 +172,7 @@ namespace ts.Completions {
|
||||
return getStringLiteralCompletionEntriesFromModuleNames(<StringLiteral>node);
|
||||
}
|
||||
else {
|
||||
const argumentInfo = SignatureHelp.getContainingArgumentInfo(node, position, sourceFile);
|
||||
const argumentInfo = SignatureHelp.getImmediatelyContainingArgumentInfo(node, position, sourceFile);
|
||||
if (argumentInfo) {
|
||||
// Get string literal completions from specialized signatures of the target
|
||||
// i.e. declare function f(a: 'A');
|
||||
@@ -188,7 +186,7 @@ namespace ts.Completions {
|
||||
}
|
||||
}
|
||||
|
||||
function getStringLiteralCompletionEntriesFromPropertyAssignment(element: ObjectLiteralElement) {
|
||||
function getStringLiteralCompletionEntriesFromPropertyAssignment(element: ObjectLiteralElement): CompletionInfo | undefined {
|
||||
const type = typeChecker.getContextualType((<ObjectLiteralExpression>element.parent));
|
||||
const entries: CompletionEntry[] = [];
|
||||
if (type) {
|
||||
@@ -199,7 +197,7 @@ namespace ts.Completions {
|
||||
}
|
||||
}
|
||||
|
||||
function getStringLiteralCompletionEntriesFromCallExpression(argumentInfo: SignatureHelp.ArgumentListInfo) {
|
||||
function getStringLiteralCompletionEntriesFromCallExpression(argumentInfo: SignatureHelp.ArgumentListInfo): CompletionInfo | undefined {
|
||||
const candidates: Signature[] = [];
|
||||
const entries: CompletionEntry[] = [];
|
||||
|
||||
@@ -219,7 +217,7 @@ namespace ts.Completions {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getStringLiteralCompletionEntriesFromElementAccess(node: ElementAccessExpression) {
|
||||
function getStringLiteralCompletionEntriesFromElementAccess(node: ElementAccessExpression): CompletionInfo | undefined {
|
||||
const type = typeChecker.getTypeAtLocation(node.expression);
|
||||
const entries: CompletionEntry[] = [];
|
||||
if (type) {
|
||||
@@ -231,7 +229,7 @@ namespace ts.Completions {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getStringLiteralCompletionEntriesFromContextualType(node: StringLiteral) {
|
||||
function getStringLiteralCompletionEntriesFromContextualType(node: StringLiteral): CompletionInfo | undefined {
|
||||
const type = typeChecker.getContextualType(node);
|
||||
if (type) {
|
||||
const entries: CompletionEntry[] = [];
|
||||
@@ -243,7 +241,7 @@ namespace ts.Completions {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function addStringLiteralCompletionsFromType(type: Type, result: CompletionEntry[]): void {
|
||||
function addStringLiteralCompletionsFromType(type: Type, result: Push<CompletionEntry>): void {
|
||||
if (type && type.flags & TypeFlags.TypeParameter) {
|
||||
type = typeChecker.getApparentType(type);
|
||||
}
|
||||
@@ -251,18 +249,18 @@ namespace ts.Completions {
|
||||
return;
|
||||
}
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
forEach((<UnionType>type).types, t => addStringLiteralCompletionsFromType(t, result));
|
||||
}
|
||||
else {
|
||||
if (type.flags & TypeFlags.StringLiteral) {
|
||||
result.push({
|
||||
name: (<LiteralType>type).text,
|
||||
kindModifiers: ScriptElementKindModifier.none,
|
||||
kind: ScriptElementKind.variableElement,
|
||||
sortText: "0"
|
||||
});
|
||||
for (const t of (<UnionType>type).types) {
|
||||
addStringLiteralCompletionsFromType(t, result);
|
||||
}
|
||||
}
|
||||
else if (type.flags & TypeFlags.StringLiteral) {
|
||||
result.push({
|
||||
name: (<LiteralType>type).text,
|
||||
kindModifiers: ScriptElementKindModifier.none,
|
||||
kind: ScriptElementKind.variableElement,
|
||||
sortText: "0"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getStringLiteralCompletionEntriesFromModuleNames(node: StringLiteral): CompletionInfo {
|
||||
|
||||
@@ -260,7 +260,7 @@ namespace ts.SignatureHelp {
|
||||
* Returns relevant information for the argument list and the current argument if we are
|
||||
* in the argument of an invocation; returns undefined otherwise.
|
||||
*/
|
||||
function getImmediatelyContainingArgumentInfo(node: Node, position: number, sourceFile: SourceFile): ArgumentListInfo {
|
||||
export function getImmediatelyContainingArgumentInfo(node: Node, position: number, sourceFile: SourceFile): ArgumentListInfo {
|
||||
if (node.parent.kind === SyntaxKind.CallExpression || node.parent.kind === SyntaxKind.NewExpression) {
|
||||
const callExpression = <CallExpression>node.parent;
|
||||
// There are 3 cases to handle:
|
||||
|
||||
Reference in New Issue
Block a user