mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-09 02:30:15 -06:00
Monomorphic Symbol access (#51880)
This commit is contained in:
parent
b9aa8a4096
commit
2993ea8eaa
@ -960,6 +960,7 @@ import {
|
||||
tracing,
|
||||
TracingNode,
|
||||
TransientSymbol,
|
||||
TransientSymbolLinks,
|
||||
tryAddToSet,
|
||||
tryCast,
|
||||
tryExtractTSExtension,
|
||||
@ -1307,8 +1308,9 @@ const intrinsicTypeKinds: ReadonlyMap<string, IntrinsicTypeKind> = new Map(getEn
|
||||
Uncapitalize: IntrinsicTypeKind.Uncapitalize
|
||||
}));
|
||||
|
||||
function SymbolLinks(this: SymbolLinks) {
|
||||
}
|
||||
const SymbolLinks = class implements SymbolLinks {
|
||||
declare _symbolLinksBrand: any;
|
||||
};
|
||||
|
||||
function NodeLinks(this: NodeLinks) {
|
||||
this.flags = NodeCheckFlags.None;
|
||||
@ -2319,8 +2321,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
|
||||
function createSymbol(flags: SymbolFlags, name: __String, checkFlags?: CheckFlags) {
|
||||
symbolCount++;
|
||||
const symbol = (new Symbol(flags | SymbolFlags.Transient, name) as TransientSymbol);
|
||||
symbol.checkFlags = checkFlags || CheckFlags.None;
|
||||
const symbol = new Symbol(flags | SymbolFlags.Transient, name) as TransientSymbol;
|
||||
symbol.links = new SymbolLinks() as TransientSymbolLinks;
|
||||
symbol.links.checkFlags = checkFlags || CheckFlags.None;
|
||||
return symbol;
|
||||
}
|
||||
|
||||
@ -2353,7 +2356,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
mergedSymbols[source.mergeId] = target;
|
||||
}
|
||||
|
||||
function cloneSymbol(symbol: Symbol): Symbol {
|
||||
function cloneSymbol(symbol: Symbol): TransientSymbol {
|
||||
const result = createSymbol(symbol.flags, symbol.escapedName);
|
||||
result.declarations = symbol.declarations ? symbol.declarations.slice() : [];
|
||||
result.parent = symbol.parent;
|
||||
@ -2570,9 +2573,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
|
||||
function getSymbolLinks(symbol: Symbol): SymbolLinks {
|
||||
if (symbol.flags & SymbolFlags.Transient) return symbol as TransientSymbol;
|
||||
if (symbol.flags & SymbolFlags.Transient) return (symbol as TransientSymbol).links;
|
||||
const id = getSymbolId(symbol);
|
||||
return symbolLinks[id] || (symbolLinks[id] = new (SymbolLinks as any)());
|
||||
return symbolLinks[id] ??= new SymbolLinks();
|
||||
}
|
||||
|
||||
function getNodeLinks(node: Node): NodeLinks {
|
||||
@ -5042,14 +5045,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const result = createSymbol(symbol.flags, symbol.escapedName);
|
||||
result.declarations = symbol.declarations ? symbol.declarations.slice() : [];
|
||||
result.parent = symbol.parent;
|
||||
result.target = symbol;
|
||||
result.originatingImport = referenceParent;
|
||||
result.links.target = symbol;
|
||||
result.links.originatingImport = referenceParent;
|
||||
if (symbol.valueDeclaration) result.valueDeclaration = symbol.valueDeclaration;
|
||||
if (symbol.constEnumOnlyModule) result.constEnumOnlyModule = true;
|
||||
if (symbol.members) result.members = new Map(symbol.members);
|
||||
if (symbol.exports) result.exports = new Map(symbol.exports);
|
||||
const resolvedModuleType = resolveStructuredTypeMembers(moduleType as StructuredType); // Should already be resolved from the signature checks above
|
||||
result.type = createAnonymousType(result, resolvedModuleType.members, emptyArray, emptyArray, resolvedModuleType.indexInfos);
|
||||
result.links.type = createAnonymousType(result, resolvedModuleType.members, emptyArray, emptyArray, resolvedModuleType.indexInfos);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -6912,7 +6915,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
contains(context.reverseMappedStack, propertySymbol as ReverseMappedSymbol)
|
||||
|| (
|
||||
context.reverseMappedStack?.[0]
|
||||
&& !(getObjectFlags(last(context.reverseMappedStack).propertyType) & ObjectFlags.Anonymous)
|
||||
&& !(getObjectFlags(last(context.reverseMappedStack).links.propertyType) & ObjectFlags.Anonymous)
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -7385,7 +7388,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const params = getTypeParametersOfClassOrInterface(
|
||||
parentSymbol.flags & SymbolFlags.Alias ? resolveAlias(parentSymbol) : parentSymbol
|
||||
);
|
||||
typeParameterNodes = mapToTypeNodes(map(params, t => getMappedType(t, (nextSymbol as TransientSymbol).mapper!)), context);
|
||||
// NOTE: cast to TransientSymbol should be safe because only TransientSymbol can have CheckFlags.Instantiated
|
||||
typeParameterNodes = mapToTypeNodes(map(params, t => getMappedType(t, (nextSymbol as TransientSymbol).links.mapper!)), context);
|
||||
}
|
||||
else {
|
||||
typeParameterNodes = typeParametersToTypeParameterDeclarations(symbol, context);
|
||||
@ -10551,7 +10555,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
createDiagnosticForNode(s.valueDeclaration, Diagnostics._0_was_also_declared_here, unescapedName));
|
||||
}
|
||||
const union = createSymbol(s.flags | exportedMember.flags, name);
|
||||
union.type = getUnionType([getTypeOfSymbol(s), getTypeOfSymbol(exportedMember)]);
|
||||
union.links.type = getUnionType([getTypeOfSymbol(s), getTypeOfSymbol(exportedMember)]);
|
||||
union.valueDeclaration = exportedMember.valueDeclaration;
|
||||
union.declarations = concatenate(exportedMember.declarations, s.declarations);
|
||||
members.set(name, union);
|
||||
@ -10664,8 +10668,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const text = getPropertyNameFromType(exprType);
|
||||
const flags = SymbolFlags.Property | (e.initializer ? SymbolFlags.Optional : 0);
|
||||
const symbol = createSymbol(flags, text);
|
||||
symbol.type = getTypeFromBindingElement(e, includePatternInType, reportErrors);
|
||||
symbol.bindingElement = e;
|
||||
symbol.links.type = getTypeFromBindingElement(e, includePatternInType, reportErrors);
|
||||
symbol.links.bindingElement = e;
|
||||
members.set(symbol.escapedName, symbol);
|
||||
});
|
||||
const result = createAnonymousType(undefined, members, emptyArray, emptyArray, stringIndexInfo ? [stringIndexInfo] : emptyArray);
|
||||
@ -10817,7 +10821,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const result = createSymbol(fileSymbol.flags, "exports" as __String);
|
||||
result.declarations = fileSymbol.declarations ? fileSymbol.declarations.slice() : [];
|
||||
result.parent = symbol;
|
||||
result.target = fileSymbol;
|
||||
result.links.target = fileSymbol;
|
||||
if (fileSymbol.valueDeclaration) result.valueDeclaration = fileSymbol.valueDeclaration;
|
||||
if (fileSymbol.members) result.members = new Map(fileSymbol.members);
|
||||
if (fileSymbol.exports) result.exports = new Map(fileSymbol.exports);
|
||||
@ -11048,7 +11052,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const merged = mergeJSSymbols(symbol, expando);
|
||||
if (merged) {
|
||||
// note:we overwrite links because we just cloned the symbol
|
||||
symbol = links = merged;
|
||||
symbol = merged;
|
||||
links = merged.links;
|
||||
}
|
||||
}
|
||||
originalLinks.type = links.type = getTypeOfFuncClassEnumModuleWorker(symbol);
|
||||
@ -11175,7 +11180,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return checkFlags & CheckFlags.SyntheticProperty ?
|
||||
checkFlags & CheckFlags.DeferredType ?
|
||||
getWriteTypeOfSymbolWithDeferredType(symbol) || getTypeOfSymbolWithDeferredType(symbol) :
|
||||
(symbol as TransientSymbol).writeType || (symbol as TransientSymbol).type! :
|
||||
// NOTE: cast to TransientSymbol should be safe because only TransientSymbols can have CheckFlags.SyntheticProperty
|
||||
(symbol as TransientSymbol).links.writeType || (symbol as TransientSymbol).links.type! :
|
||||
getTypeOfSymbol(symbol);
|
||||
}
|
||||
if (symbol.flags & SymbolFlags.Accessor) {
|
||||
@ -11670,7 +11676,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const merged = mergeJSSymbols(symbol, symbol.valueDeclaration && getAssignedClassSymbol(symbol.valueDeclaration));
|
||||
if (merged) {
|
||||
// note:we overwrite links because we just cloned the symbol
|
||||
symbol = links = merged;
|
||||
symbol = merged;
|
||||
links = merged.links;
|
||||
}
|
||||
|
||||
const type = originalLinks.declaredType = links.declaredType = createObjectType(kind, symbol) as InterfaceType;
|
||||
@ -12087,7 +12094,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
error(declName || decl, Diagnostics.Duplicate_property_0, name);
|
||||
lateSymbol = createSymbol(SymbolFlags.None, memberName, CheckFlags.Late);
|
||||
}
|
||||
lateSymbol.nameType = type;
|
||||
lateSymbol.links.nameType = type;
|
||||
addDeclarationToLateBoundSymbol(lateSymbol, decl, symbolFlags);
|
||||
if (lateSymbol.parent) {
|
||||
Debug.assert(lateSymbol.parent === parent, "Existing symbol parent should match new one");
|
||||
@ -12341,7 +12348,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const checkFlags = flags & ElementFlags.Variable ? CheckFlags.RestParameter :
|
||||
flags & ElementFlags.Optional ? CheckFlags.OptionalParameter : 0;
|
||||
const symbol = createSymbol(SymbolFlags.FunctionScopedVariable, name, checkFlags);
|
||||
symbol.type = flags & ElementFlags.Rest ? createArrayType(t) : t;
|
||||
symbol.links.type = flags & ElementFlags.Rest ? createArrayType(t) : t;
|
||||
return symbol;
|
||||
});
|
||||
return concatenate(sig.parameters.slice(0, restIndex), restParams);
|
||||
@ -12533,14 +12540,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
SymbolFlags.FunctionScopedVariable | (isOptional && !isRestParam ? SymbolFlags.Optional : 0),
|
||||
paramName || `arg${i}` as __String
|
||||
);
|
||||
paramSymbol.type = isRestParam ? createArrayType(unionParamType) : unionParamType;
|
||||
paramSymbol.links.type = isRestParam ? createArrayType(unionParamType) : unionParamType;
|
||||
params[i] = paramSymbol;
|
||||
}
|
||||
if (needsExtraRestElement) {
|
||||
const restParamSymbol = createSymbol(SymbolFlags.FunctionScopedVariable, "args" as __String);
|
||||
restParamSymbol.type = createArrayType(getTypeAtPosition(shorter, longestCount));
|
||||
restParamSymbol.links.type = createArrayType(getTypeAtPosition(shorter, longestCount));
|
||||
if (shorter === right) {
|
||||
restParamSymbol.type = instantiateType(restParamSymbol.type, mapper);
|
||||
restParamSymbol.links.type = instantiateType(restParamSymbol.links.type, mapper);
|
||||
}
|
||||
params[longestCount] = restParamSymbol;
|
||||
}
|
||||
@ -12797,8 +12804,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const checkFlags = CheckFlags.ReverseMapped | (readonlyMask && isReadonlySymbol(prop) ? CheckFlags.Readonly : 0);
|
||||
const inferredProp = createSymbol(SymbolFlags.Property | prop.flags & optionalMask, prop.escapedName, checkFlags) as ReverseMappedSymbol;
|
||||
inferredProp.declarations = prop.declarations;
|
||||
inferredProp.nameType = getSymbolLinks(prop).nameType;
|
||||
inferredProp.propertyType = getTypeOfSymbol(prop);
|
||||
inferredProp.links.nameType = getSymbolLinks(prop).nameType;
|
||||
inferredProp.links.propertyType = getTypeOfSymbol(prop);
|
||||
if (type.constraintType.type.flags & TypeFlags.IndexedAccess
|
||||
&& (type.constraintType.type as IndexedAccessType).objectType.flags & TypeFlags.TypeParameter
|
||||
&& (type.constraintType.type as IndexedAccessType).indexType.flags & TypeFlags.TypeParameter) {
|
||||
@ -12807,12 +12814,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
// type identities produced, we simplify such indexed access occurences
|
||||
const newTypeParam = (type.constraintType.type as IndexedAccessType).objectType;
|
||||
const newMappedType = replaceIndexedAccess(type.mappedType, type.constraintType.type as ReplaceableIndexedAccessType, newTypeParam);
|
||||
inferredProp.mappedType = newMappedType as MappedType;
|
||||
inferredProp.constraintType = getIndexType(newTypeParam) as IndexType;
|
||||
inferredProp.links.mappedType = newMappedType as MappedType;
|
||||
inferredProp.links.constraintType = getIndexType(newTypeParam) as IndexType;
|
||||
}
|
||||
else {
|
||||
inferredProp.mappedType = type.mappedType;
|
||||
inferredProp.constraintType = type.constraintType;
|
||||
inferredProp.links.mappedType = type.mappedType;
|
||||
inferredProp.links.constraintType = type.constraintType;
|
||||
}
|
||||
members.set(prop.escapedName, inferredProp);
|
||||
}
|
||||
@ -12911,8 +12918,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
// property symbol's name type be the union of those enum member types.
|
||||
const existingProp = members.get(propName) as MappedSymbol | undefined;
|
||||
if (existingProp) {
|
||||
existingProp.nameType = getUnionType([existingProp.nameType!, propNameType]);
|
||||
existingProp.keyType = getUnionType([existingProp.keyType, keyType]);
|
||||
existingProp.links.nameType = getUnionType([existingProp.links.nameType!, propNameType]);
|
||||
existingProp.links.keyType = getUnionType([existingProp.links.keyType, keyType]);
|
||||
}
|
||||
else {
|
||||
const modifiersProp = isTypeUsableAsPropertyName(keyType) ? getPropertyOfType(modifiersType, getPropertyNameFromType(keyType)) : undefined;
|
||||
@ -12924,11 +12931,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const lateFlag: CheckFlags = modifiersProp ? getIsLateCheckFlag(modifiersProp) : 0;
|
||||
const prop = createSymbol(SymbolFlags.Property | (isOptional ? SymbolFlags.Optional : 0), propName,
|
||||
lateFlag | CheckFlags.Mapped | (isReadonly ? CheckFlags.Readonly : 0) | (stripOptional ? CheckFlags.StripOptional : 0)) as MappedSymbol;
|
||||
prop.mappedType = type;
|
||||
prop.nameType = propNameType;
|
||||
prop.keyType = keyType;
|
||||
prop.links.mappedType = type;
|
||||
prop.links.nameType = propNameType;
|
||||
prop.links.keyType = keyType;
|
||||
if (modifiersProp) {
|
||||
prop.syntheticOrigin = modifiersProp;
|
||||
prop.links.syntheticOrigin = modifiersProp;
|
||||
// If the mapped type has an `as XXX` clause, the property name likely won't match the declaration name and
|
||||
// multiple properties may map to the same name. Thus, we attach no declarations to the symbol.
|
||||
prop.declarations = nameType ? undefined : modifiersProp.declarations;
|
||||
@ -12948,28 +12955,28 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
|
||||
function getTypeOfMappedSymbol(symbol: MappedSymbol) {
|
||||
if (!symbol.type) {
|
||||
const mappedType = symbol.mappedType;
|
||||
if (!symbol.links.type) {
|
||||
const mappedType = symbol.links.mappedType;
|
||||
if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) {
|
||||
mappedType.containsError = true;
|
||||
return errorType;
|
||||
}
|
||||
const templateType = getTemplateTypeFromMappedType(mappedType.target as MappedType || mappedType);
|
||||
const mapper = appendTypeMapping(mappedType.mapper, getTypeParameterFromMappedType(mappedType), symbol.keyType);
|
||||
const mapper = appendTypeMapping(mappedType.mapper, getTypeParameterFromMappedType(mappedType), symbol.links.keyType);
|
||||
const propType = instantiateType(templateType, mapper);
|
||||
// When creating an optional property in strictNullChecks mode, if 'undefined' isn't assignable to the
|
||||
// type, we include 'undefined' in the type. Similarly, when creating a non-optional property in strictNullChecks
|
||||
// mode, if the underlying property is optional we remove 'undefined' from the type.
|
||||
let type = strictNullChecks && symbol.flags & SymbolFlags.Optional && !maybeTypeOfKind(propType, TypeFlags.Undefined | TypeFlags.Void) ? getOptionalType(propType, /*isProperty*/ true) :
|
||||
symbol.checkFlags & CheckFlags.StripOptional ? removeMissingOrUndefinedType(propType) :
|
||||
symbol.links.checkFlags & CheckFlags.StripOptional ? removeMissingOrUndefinedType(propType) :
|
||||
propType;
|
||||
if (!popTypeResolution()) {
|
||||
error(currentNode, Diagnostics.Type_of_property_0_circularly_references_itself_in_mapped_type_1, symbolToString(symbol), typeToString(mappedType));
|
||||
type = errorType;
|
||||
}
|
||||
symbol.type = type;
|
||||
symbol.links.type = type;
|
||||
}
|
||||
return symbol.type;
|
||||
return symbol.links.type;
|
||||
}
|
||||
|
||||
function getTypeParameterFromMappedType(type: MappedType) {
|
||||
@ -13648,10 +13655,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
// No symbol from a union/intersection should have a `.parent` set (since unions/intersections don't act as symbol parents)
|
||||
// Unless that parent is "reconstituted" from the "first value declaration" on the symbol (which is likely different than its instantiated parent!)
|
||||
// They also have a `.containingType` set, which affects some services endpoints behavior, like `getRootSymbol`
|
||||
const clone = createSymbolWithType(singleProp, (singleProp as TransientSymbol).type);
|
||||
const links = tryCast(singleProp, isTransientSymbol)?.links;
|
||||
const clone = createSymbolWithType(singleProp, links?.type);
|
||||
clone.parent = singleProp.valueDeclaration?.symbol?.parent;
|
||||
clone.containingType = containingType;
|
||||
clone.mapper = (singleProp as TransientSymbol).mapper;
|
||||
clone.links.containingType = containingType;
|
||||
clone.links.mapper = links?.mapper;
|
||||
return clone;
|
||||
}
|
||||
else {
|
||||
@ -13696,7 +13704,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
addRange(propTypes, indexTypes);
|
||||
const result = createSymbol(SymbolFlags.Property | (optionalFlag ?? 0), name, syntheticFlag | checkFlags);
|
||||
result.containingType = containingType;
|
||||
result.links.containingType = containingType;
|
||||
if (!hasNonUniformValueDeclaration && firstValueDeclaration) {
|
||||
result.valueDeclaration = firstValueDeclaration;
|
||||
|
||||
@ -13707,18 +13715,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
|
||||
result.declarations = declarations;
|
||||
result.nameType = nameType;
|
||||
result.links.nameType = nameType;
|
||||
if (propTypes.length > 2) {
|
||||
// When `propTypes` has the potential to explode in size when normalized, defer normalization until absolutely needed
|
||||
result.checkFlags |= CheckFlags.DeferredType;
|
||||
result.deferralParent = containingType;
|
||||
result.deferralConstituents = propTypes;
|
||||
result.deferralWriteConstituents = writeTypes;
|
||||
result.links.checkFlags |= CheckFlags.DeferredType;
|
||||
result.links.deferralParent = containingType;
|
||||
result.links.deferralConstituents = propTypes;
|
||||
result.links.deferralWriteConstituents = writeTypes;
|
||||
}
|
||||
else {
|
||||
result.type = isUnion ? getUnionType(propTypes) : getIntersectionType(propTypes);
|
||||
result.links.type = isUnion ? getUnionType(propTypes) : getIntersectionType(propTypes);
|
||||
if (writeTypes) {
|
||||
result.writeType = isUnion ? getUnionType(writeTypes) : getIntersectionType(writeTypes);
|
||||
result.links.writeType = isUnion ? getUnionType(writeTypes) : getIntersectionType(writeTypes);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@ -14180,16 +14188,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const syntheticArgsSymbol = createSymbol(SymbolFlags.Variable, "args" as __String, CheckFlags.RestParameter);
|
||||
if (lastParamVariadicType) {
|
||||
// Parameter has effective annotation, lock in type
|
||||
syntheticArgsSymbol.type = createArrayType(getTypeFromTypeNode(lastParamVariadicType.type));
|
||||
syntheticArgsSymbol.links.type = createArrayType(getTypeFromTypeNode(lastParamVariadicType.type));
|
||||
}
|
||||
else {
|
||||
// Parameter has no annotation
|
||||
// By using a `DeferredType` symbol, we allow the type of this rest arg to be overriden by contextual type assignment so long as its type hasn't been
|
||||
// cached by `getTypeOfSymbol` yet.
|
||||
syntheticArgsSymbol.checkFlags |= CheckFlags.DeferredType;
|
||||
syntheticArgsSymbol.deferralParent = neverType;
|
||||
syntheticArgsSymbol.deferralConstituents = [anyArrayType];
|
||||
syntheticArgsSymbol.deferralWriteConstituents = [anyArrayType];
|
||||
syntheticArgsSymbol.links.checkFlags |= CheckFlags.DeferredType;
|
||||
syntheticArgsSymbol.links.deferralParent = neverType;
|
||||
syntheticArgsSymbol.links.deferralConstituents = [anyArrayType];
|
||||
syntheticArgsSymbol.links.deferralWriteConstituents = [anyArrayType];
|
||||
}
|
||||
if (lastParamVariadicType) {
|
||||
// Replace the last parameter with a rest parameter.
|
||||
@ -14960,7 +14968,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
if (!result) {
|
||||
unresolvedSymbols.set(path, result = createSymbol(SymbolFlags.TypeAlias, text, CheckFlags.Unresolved));
|
||||
result.parent = parentSymbol;
|
||||
result.declaredType = unresolvedType;
|
||||
result.links.declaredType = unresolvedType;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -15302,7 +15310,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
|
||||
const metaPropertySymbol = createSymbol(SymbolFlags.Property, "meta" as __String, CheckFlags.Readonly);
|
||||
metaPropertySymbol.parent = symbol;
|
||||
metaPropertySymbol.type = importMetaType;
|
||||
metaPropertySymbol.links.type = importMetaType;
|
||||
|
||||
const members = createSymbolTable([metaPropertySymbol]);
|
||||
symbol.members = members;
|
||||
@ -15600,8 +15608,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
if (!(combinedFlags & ElementFlags.Variable)) {
|
||||
const property = createSymbol(SymbolFlags.Property | (flags & ElementFlags.Optional ? SymbolFlags.Optional : 0),
|
||||
"" + i as __String, readonly ? CheckFlags.Readonly : 0);
|
||||
property.tupleLabelDeclaration = namedMemberDeclarations?.[i];
|
||||
property.type = typeParameter;
|
||||
property.links.tupleLabelDeclaration = namedMemberDeclarations?.[i];
|
||||
property.links.type = typeParameter;
|
||||
properties.push(property);
|
||||
}
|
||||
}
|
||||
@ -15609,12 +15617,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const fixedLength = properties.length;
|
||||
const lengthSymbol = createSymbol(SymbolFlags.Property, "length" as __String, readonly ? CheckFlags.Readonly : 0);
|
||||
if (combinedFlags & ElementFlags.Variable) {
|
||||
lengthSymbol.type = numberType;
|
||||
lengthSymbol.links.type = numberType;
|
||||
}
|
||||
else {
|
||||
const literalTypes = [];
|
||||
for (let i = minLength; i <= arity; i++) literalTypes.push(getNumberLiteralType(i));
|
||||
lengthSymbol.type = getUnionType(literalTypes);
|
||||
lengthSymbol.links.type = getUnionType(literalTypes);
|
||||
}
|
||||
properties.push(lengthSymbol);
|
||||
const type = createObjectType(ObjectFlags.Tuple | ObjectFlags.Reference) as TupleType & InterfaceTypeWithDeclaredMembers;
|
||||
@ -17686,10 +17694,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const isSetonlyAccessor = prop.flags & SymbolFlags.SetAccessor && !(prop.flags & SymbolFlags.GetAccessor);
|
||||
const flags = SymbolFlags.Property | SymbolFlags.Optional;
|
||||
const result = createSymbol(flags, prop.escapedName, getIsLateCheckFlag(prop) | (readonly ? CheckFlags.Readonly : 0));
|
||||
result.type = isSetonlyAccessor ? undefinedType : addOptionality(getTypeOfSymbol(prop), /*isProperty*/ true);
|
||||
result.links.type = isSetonlyAccessor ? undefinedType : addOptionality(getTypeOfSymbol(prop), /*isProperty*/ true);
|
||||
result.declarations = prop.declarations;
|
||||
result.nameType = getSymbolLinks(prop).nameType;
|
||||
result.syntheticOrigin = prop;
|
||||
result.links.nameType = getSymbolLinks(prop).nameType;
|
||||
result.links.syntheticOrigin = prop;
|
||||
members.set(prop.escapedName, result);
|
||||
}
|
||||
}
|
||||
@ -17774,11 +17782,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const declarations = concatenate(leftProp.declarations, rightProp.declarations);
|
||||
const flags = SymbolFlags.Property | (leftProp.flags & SymbolFlags.Optional);
|
||||
const result = createSymbol(flags, leftProp.escapedName);
|
||||
result.type = getUnionType([getTypeOfSymbol(leftProp), removeMissingOrUndefinedType(rightType)], UnionReduction.Subtype);
|
||||
result.leftSpread = leftProp;
|
||||
result.rightSpread = rightProp;
|
||||
result.links.type = getUnionType([getTypeOfSymbol(leftProp), removeMissingOrUndefinedType(rightType)], UnionReduction.Subtype);
|
||||
result.links.leftSpread = leftProp;
|
||||
result.links.rightSpread = rightProp;
|
||||
result.declarations = declarations;
|
||||
result.nameType = getSymbolLinks(leftProp).nameType;
|
||||
result.links.nameType = getSymbolLinks(leftProp).nameType;
|
||||
members.set(leftProp.escapedName, result);
|
||||
}
|
||||
}
|
||||
@ -17806,10 +17814,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
const flags = SymbolFlags.Property | (prop.flags & SymbolFlags.Optional);
|
||||
const result = createSymbol(flags, prop.escapedName, getIsLateCheckFlag(prop) | (readonly ? CheckFlags.Readonly : 0));
|
||||
result.type = isSetonlyAccessor ? undefinedType : getTypeOfSymbol(prop);
|
||||
result.links.type = isSetonlyAccessor ? undefinedType : getTypeOfSymbol(prop);
|
||||
result.declarations = prop.declarations;
|
||||
result.nameType = getSymbolLinks(prop).nameType;
|
||||
result.syntheticOrigin = prop;
|
||||
result.links.nameType = getSymbolLinks(prop).nameType;
|
||||
result.links.syntheticOrigin = prop;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -18256,13 +18264,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const result = createSymbol(symbol.flags, symbol.escapedName, CheckFlags.Instantiated | getCheckFlags(symbol) & (CheckFlags.Readonly | CheckFlags.Late | CheckFlags.OptionalParameter | CheckFlags.RestParameter));
|
||||
result.declarations = symbol.declarations;
|
||||
result.parent = symbol.parent;
|
||||
result.target = symbol;
|
||||
result.mapper = mapper;
|
||||
result.links.target = symbol;
|
||||
result.links.mapper = mapper;
|
||||
if (symbol.valueDeclaration) {
|
||||
result.valueDeclaration = symbol.valueDeclaration;
|
||||
}
|
||||
if (links.nameType) {
|
||||
result.nameType = links.nameType;
|
||||
result.links.nameType = links.nameType;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -22268,7 +22276,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
// value that isn't undefined.
|
||||
function forEachProperty<T>(prop: Symbol, callback: (p: Symbol) => T): T | undefined {
|
||||
if (getCheckFlags(prop) & CheckFlags.Synthetic) {
|
||||
for (const t of (prop as TransientSymbol).containingType!.types) {
|
||||
// NOTE: cast to TransientSymbol should be safe because only TransientSymbols can have CheckFlags.Synthetic
|
||||
for (const t of (prop as TransientSymbol).links.containingType!.types) {
|
||||
const p = getPropertyOfType(t, prop.escapedName);
|
||||
const result = p && forEachProperty(p, callback);
|
||||
if (result) {
|
||||
@ -22900,14 +22909,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const symbol = createSymbol(source.flags, source.escapedName, getCheckFlags(source) & CheckFlags.Readonly);
|
||||
symbol.declarations = source.declarations;
|
||||
symbol.parent = source.parent;
|
||||
symbol.type = type;
|
||||
symbol.target = source;
|
||||
symbol.links.type = type;
|
||||
symbol.links.target = source;
|
||||
if (source.valueDeclaration) {
|
||||
symbol.valueDeclaration = source.valueDeclaration;
|
||||
}
|
||||
const nameType = getSymbolLinks(source).nameType;
|
||||
if (nameType) {
|
||||
symbol.nameType = nameType;
|
||||
symbol.links.nameType = nameType;
|
||||
}
|
||||
return symbol;
|
||||
}
|
||||
@ -23383,7 +23392,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
const name = escapeLeadingUnderscores((t as StringLiteralType).value);
|
||||
const literalProp = createSymbol(SymbolFlags.Property, name);
|
||||
literalProp.type = anyType;
|
||||
literalProp.links.type = anyType;
|
||||
if (t.symbol) {
|
||||
literalProp.declarations = t.symbol.declarations;
|
||||
literalProp.valueDeclaration = t.symbol.valueDeclaration;
|
||||
@ -23455,7 +23464,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
function getTypeOfReverseMappedSymbol(symbol: ReverseMappedSymbol) {
|
||||
const links = getSymbolLinks(symbol);
|
||||
if (!links.type) {
|
||||
links.type = inferReverseMappedType(symbol.propertyType, symbol.mappedType, symbol.constraintType);
|
||||
links.type = inferReverseMappedType(symbol.links.propertyType, symbol.links.mappedType, symbol.links.constraintType);
|
||||
}
|
||||
return links.type;
|
||||
}
|
||||
@ -24773,12 +24782,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
if (type && type.flags & TypeFlags.Union) {
|
||||
const prop = getUnionOrIntersectionProperty(type as UnionType, name);
|
||||
if (prop && getCheckFlags(prop) & CheckFlags.SyntheticProperty) {
|
||||
if ((prop as TransientSymbol).isDiscriminantProperty === undefined) {
|
||||
(prop as TransientSymbol).isDiscriminantProperty =
|
||||
((prop as TransientSymbol).checkFlags & CheckFlags.Discriminant) === CheckFlags.Discriminant &&
|
||||
// NOTE: cast to TransientSymbol should be safe because only TransientSymbols can have CheckFlags.SyntheticProperty
|
||||
if ((prop as TransientSymbol).links.isDiscriminantProperty === undefined) {
|
||||
(prop as TransientSymbol).links.isDiscriminantProperty =
|
||||
((prop as TransientSymbol).links.checkFlags & CheckFlags.Discriminant) === CheckFlags.Discriminant &&
|
||||
!isGenericType(getTypeOfSymbol(prop));
|
||||
}
|
||||
return !!(prop as TransientSymbol).isDiscriminantProperty;
|
||||
return !!(prop as TransientSymbol).links.isDiscriminantProperty;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@ -25487,7 +25497,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
if (symbol.flags & (SymbolFlags.Variable | SymbolFlags.Property)) {
|
||||
if (getCheckFlags(symbol) & CheckFlags.Mapped) {
|
||||
const origin = (symbol as MappedSymbol).syntheticOrigin;
|
||||
const origin = (symbol as MappedSymbol).links.syntheticOrigin;
|
||||
if (origin && getExplicitTypeOfSymbol(origin)) {
|
||||
return getTypeOfSymbol(symbol);
|
||||
}
|
||||
@ -28401,7 +28411,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
|
||||
function isCircularMappedProperty(symbol: Symbol) {
|
||||
return !!(getCheckFlags(symbol) & CheckFlags.Mapped && !(symbol as MappedSymbol).type && findResolutionCycleStartIndex(symbol, TypeSystemPropertyName.Type) >= 0);
|
||||
return !!(getCheckFlags(symbol) & CheckFlags.Mapped && !(symbol as MappedSymbol).links.type && findResolutionCycleStartIndex(symbol, TypeSystemPropertyName.Type) >= 0);
|
||||
}
|
||||
|
||||
function getTypeOfPropertyOfContextualType(type: Type, name: __String, nameType?: Type) {
|
||||
@ -28943,14 +28953,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
SymbolFlags.FunctionScopedVariable | (isOptional && !isRestParam ? SymbolFlags.Optional : 0),
|
||||
paramName || `arg${i}` as __String
|
||||
);
|
||||
paramSymbol.type = isRestParam ? createArrayType(unionParamType) : unionParamType;
|
||||
paramSymbol.links.type = isRestParam ? createArrayType(unionParamType) : unionParamType;
|
||||
params[i] = paramSymbol;
|
||||
}
|
||||
if (needsExtraRestElement) {
|
||||
const restParamSymbol = createSymbol(SymbolFlags.FunctionScopedVariable, "args" as __String);
|
||||
restParamSymbol.type = createArrayType(getTypeAtPosition(shorter, longestCount));
|
||||
restParamSymbol.links.type = createArrayType(getTypeAtPosition(shorter, longestCount));
|
||||
if (shorter === right) {
|
||||
restParamSymbol.type = instantiateType(restParamSymbol.type, mapper);
|
||||
restParamSymbol.links.type = instantiateType(restParamSymbol.links.type, mapper);
|
||||
}
|
||||
params[longestCount] = restParamSymbol;
|
||||
}
|
||||
@ -29316,7 +29326,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
createSymbol(SymbolFlags.Property | member.flags, getPropertyNameFromType(nameType), checkFlags | CheckFlags.Late) :
|
||||
createSymbol(SymbolFlags.Property | member.flags, member.escapedName, checkFlags);
|
||||
if (nameType) {
|
||||
prop.nameType = nameType;
|
||||
prop.links.nameType = nameType;
|
||||
}
|
||||
|
||||
if (inDestructuringPattern) {
|
||||
@ -29349,8 +29359,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
prop.valueDeclaration = member.valueDeclaration;
|
||||
}
|
||||
|
||||
prop.type = type;
|
||||
prop.target = member;
|
||||
prop.links.type = type;
|
||||
prop.links.target = member;
|
||||
member = prop;
|
||||
allPropertiesTable?.set(prop.escapedName, prop);
|
||||
|
||||
@ -29446,7 +29456,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
for (const prop of getPropertiesOfType(contextualType)) {
|
||||
if (!propertiesTable.get(prop.escapedName) && !getPropertyOfType(spread, prop.escapedName)) {
|
||||
if (!(prop.flags & SymbolFlags.Optional)) {
|
||||
error(prop.valueDeclaration || (prop as TransientSymbol).bindingElement,
|
||||
error(prop.valueDeclaration || tryCast(prop, isTransientSymbol)?.links.bindingElement,
|
||||
Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value);
|
||||
}
|
||||
propertiesTable.set(prop.escapedName, prop);
|
||||
@ -29597,8 +29607,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
if (member.valueDeclaration) {
|
||||
attributeSymbol.valueDeclaration = member.valueDeclaration;
|
||||
}
|
||||
attributeSymbol.type = exprType;
|
||||
attributeSymbol.target = member;
|
||||
attributeSymbol.links.type = exprType;
|
||||
attributeSymbol.links.target = member;
|
||||
attributesTable.set(attributeSymbol.escapedName, attributeSymbol);
|
||||
allAttributesTable?.set(attributeSymbol.escapedName, attributeSymbol);
|
||||
if (attributeDecl.name.escapedText === jsxChildrenPropertyName) {
|
||||
@ -29658,7 +29668,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const childrenContextualType = contextualType && getTypeOfPropertyOfContextualType(contextualType, jsxChildrenPropertyName);
|
||||
// If there are children in the body of JSX element, create dummy attribute "children" with the union of children types so that it will pass the attribute checking process
|
||||
const childrenPropSymbol = createSymbol(SymbolFlags.Property, jsxChildrenPropertyName);
|
||||
childrenPropSymbol.type = childrenTypes.length === 1 ? childrenTypes[0] :
|
||||
childrenPropSymbol.links.type = childrenTypes.length === 1 ? childrenTypes[0] :
|
||||
childrenContextualType && someType(childrenContextualType, isTupleLikeType) ? createTupleType(childrenTypes) :
|
||||
createArrayType(getUnionType(childrenTypes));
|
||||
// Fake up a property declaration for the children
|
||||
@ -33094,7 +33104,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
returnNode ? factory.createTypeReferenceNode(returnNode, /*typeArguments*/ undefined) : factory.createKeywordTypeNode(SyntaxKind.AnyKeyword)
|
||||
);
|
||||
const parameterSymbol = createSymbol(SymbolFlags.FunctionScopedVariable, "props" as __String);
|
||||
parameterSymbol.type = result;
|
||||
parameterSymbol.links.type = result;
|
||||
return createSignature(
|
||||
declaration,
|
||||
/*typeParameters*/ undefined,
|
||||
@ -33226,7 +33236,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
if (source) {
|
||||
const links = getSymbolLinks(source);
|
||||
if (!links.inferredClassSymbol || !links.inferredClassSymbol.has(getSymbolId(target))) {
|
||||
const inferred = isTransientSymbol(target) ? target : cloneSymbol(target) as TransientSymbol;
|
||||
const inferred = isTransientSymbol(target) ? target : cloneSymbol(target);
|
||||
inferred.exports = inferred.exports || createSymbolTable();
|
||||
inferred.members = inferred.members || createSymbolTable();
|
||||
inferred.flags |= source.flags & SymbolFlags.Class;
|
||||
@ -33479,8 +33489,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const memberTable = createSymbolTable();
|
||||
const newSymbol = createSymbol(SymbolFlags.Alias, InternalSymbolName.Default);
|
||||
newSymbol.parent = originalSymbol;
|
||||
newSymbol.nameType = getStringLiteralType("default");
|
||||
newSymbol.aliasTarget = resolveSymbol(symbol);
|
||||
newSymbol.links.nameType = getStringLiteralType("default");
|
||||
newSymbol.links.aliasTarget = resolveSymbol(symbol);
|
||||
memberTable.set(InternalSymbolName.Default, newSymbol);
|
||||
return createAnonymousType(anonymousSymbol, memberTable, emptyArray, emptyArray, emptyArray);
|
||||
}
|
||||
@ -33507,7 +33517,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
if (hasSyntheticDefault) {
|
||||
const anonymousSymbol = createSymbol(SymbolFlags.TypeLiteral, InternalSymbolName.Type);
|
||||
const defaultContainingObject = createDefaultPropertyWrapperForModule(symbol, originalSymbol, anonymousSymbol);
|
||||
anonymousSymbol.type = defaultContainingObject;
|
||||
anonymousSymbol.links.type = defaultContainingObject;
|
||||
synthType.syntheticType = isValidSpreadType(type) ? getSpreadType(type, defaultContainingObject, anonymousSymbol, /*objectFlags*/ 0, /*readonly*/ false) : defaultContainingObject;
|
||||
}
|
||||
else {
|
||||
@ -34141,7 +34151,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
|
||||
const targetPropertySymbol = createSymbol(SymbolFlags.Property, "target" as __String, CheckFlags.Readonly);
|
||||
targetPropertySymbol.parent = symbol;
|
||||
targetPropertySymbol.type = targetType;
|
||||
targetPropertySymbol.links.type = targetType;
|
||||
|
||||
const members = createSymbolTable([targetPropertySymbol]);
|
||||
symbol.members = members;
|
||||
@ -41688,7 +41698,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
function getTargetSymbol(s: Symbol) {
|
||||
// if symbol is instantiated its flags are not copied from the 'target'
|
||||
// so we'll need to get back original 'target' symbol to work with correct set of flags
|
||||
return getCheckFlags(s) & CheckFlags.Instantiated ? (s as TransientSymbol).target! : s;
|
||||
// NOTE: cast to TransientSymbol should be safe because only TransientSymbols have CheckFlags.Instantiated
|
||||
return getCheckFlags(s) & CheckFlags.Instantiated ? (s as TransientSymbol).links.target! : s;
|
||||
}
|
||||
|
||||
function getClassOrInterfaceDeclarationsOfSymbol(symbol: Symbol) {
|
||||
@ -44337,7 +44348,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return mapDefined(getSymbolLinks(symbol).containingType!.types, type => getPropertyOfType(type, symbol.escapedName));
|
||||
}
|
||||
else if (symbol.flags & SymbolFlags.Transient) {
|
||||
const { leftSpread, rightSpread, syntheticOrigin } = symbol as TransientSymbol;
|
||||
const { links: { leftSpread, rightSpread, syntheticOrigin } } = symbol as TransientSymbol;
|
||||
return leftSpread ? [leftSpread, rightSpread!]
|
||||
: syntheticOrigin ? [syntheticOrigin]
|
||||
: singleElementArray(tryGetTarget(symbol));
|
||||
|
||||
@ -5744,19 +5744,20 @@ export interface Symbol {
|
||||
members?: SymbolTable; // Class, interface or object literal instance members
|
||||
exports?: SymbolTable; // Module exports
|
||||
globalExports?: SymbolTable; // Conditional global UMD exports
|
||||
/** @internal */ id?: SymbolId; // Unique id (used to look up SymbolLinks)
|
||||
/** @internal */ mergeId?: number; // Merge id (used to look up merged symbol)
|
||||
/** @internal */ parent?: Symbol; // Parent symbol
|
||||
/** @internal */ exportSymbol?: Symbol; // Exported symbol associated with this symbol
|
||||
/** @internal */ constEnumOnlyModule?: boolean; // True if module contains only const enums or other modules with only const enums
|
||||
/** @internal */ id: SymbolId; // Unique id (used to look up SymbolLinks)
|
||||
/** @internal */ mergeId: number; // Merge id (used to look up merged symbol)
|
||||
/** @internal */ parent?: Symbol; // Parent symbol
|
||||
/** @internal */ exportSymbol?: Symbol; // Exported symbol associated with this symbol
|
||||
/** @internal */ constEnumOnlyModule: boolean | undefined; // True if module contains only const enums or other modules with only const enums
|
||||
/** @internal */ isReferenced?: SymbolFlags; // True if the symbol is referenced elsewhere. Keeps track of the meaning of a reference in case a symbol is both a type parameter and parameter.
|
||||
/** @internal */ isReplaceableByMethod?: boolean; // Can this Javascript class property be replaced by a method symbol?
|
||||
/** @internal */ isAssigned?: boolean; // True if the symbol is a parameter with assignments
|
||||
/** @internal */ isAssigned?: boolean; // True if the symbol is a parameter with assignments
|
||||
/** @internal */ assignmentDeclarationMembers?: Map<number, Declaration>; // detected late-bound assignment declarations associated with the symbol
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface SymbolLinks {
|
||||
_symbolLinksBrand: any;
|
||||
immediateTarget?: Symbol; // Immediate target of an alias. May be another alias. Do not access directly, use `checker.getImmediateAliasedSymbol` instead.
|
||||
aliasTarget?: Symbol, // Resolved (non-alias) target of an alias
|
||||
target?: Symbol; // Original version of an instantiated symbol
|
||||
@ -5767,7 +5768,7 @@ export interface SymbolLinks {
|
||||
declaredType?: Type; // Type of class, interface, enum, type alias, or type parameter
|
||||
typeParameters?: TypeParameter[]; // Type parameters of type alias (undefined if non-generic)
|
||||
outerTypeParameters?: TypeParameter[]; // Outer type parameters of anonymous object type
|
||||
instantiations?: Map<string, Type>; // Instantiations of generic type alias (undefined if non-generic)
|
||||
instantiations?: Map<string, Type>; // Instantiations of generic type alias (undefined if non-generic)
|
||||
aliasSymbol?: Symbol; // Alias associated with generic type alias instantiation
|
||||
aliasTypeArguments?: readonly Type[] // Alias type arguments (if any)
|
||||
inferredClassSymbol?: Map<SymbolId, TransientSymbol>; // Symbol of an inferred ES5 constructor function
|
||||
@ -5840,23 +5841,38 @@ export const enum CheckFlags {
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface TransientSymbol extends Symbol, SymbolLinks {
|
||||
export interface TransientSymbolLinks extends SymbolLinks {
|
||||
checkFlags: CheckFlags;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface MappedSymbol extends TransientSymbol {
|
||||
export interface TransientSymbol extends Symbol {
|
||||
links: TransientSymbolLinks;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface MappedSymbolLinks extends TransientSymbolLinks {
|
||||
mappedType: MappedType;
|
||||
keyType: Type;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface ReverseMappedSymbol extends TransientSymbol {
|
||||
export interface MappedSymbol extends TransientSymbol {
|
||||
links: MappedSymbolLinks;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface ReverseMappedSymbolLinks extends TransientSymbolLinks {
|
||||
propertyType: Type;
|
||||
mappedType: MappedType;
|
||||
constraintType: IndexType;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface ReverseMappedSymbol extends TransientSymbol {
|
||||
links: ReverseMappedSymbolLinks;
|
||||
}
|
||||
|
||||
export const enum InternalSymbolName {
|
||||
Call = "__call", // Call signatures
|
||||
Constructor = "__constructor", // Constructor implementations
|
||||
|
||||
@ -6825,7 +6825,7 @@ export function closeFileWatcher(watcher: FileWatcher) {
|
||||
|
||||
/** @internal */
|
||||
export function getCheckFlags(symbol: Symbol): CheckFlags {
|
||||
return symbol.flags & SymbolFlags.Transient ? (symbol as TransientSymbol).checkFlags : 0;
|
||||
return symbol.flags & SymbolFlags.Transient ? (symbol as TransientSymbol).links.checkFlags : 0;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
@ -6837,7 +6837,8 @@ export function getDeclarationModifierFlagsFromSymbol(s: Symbol, isWrite = false
|
||||
return s.parent && s.parent.flags & SymbolFlags.Class ? flags : flags & ~ModifierFlags.AccessibilityModifier;
|
||||
}
|
||||
if (getCheckFlags(s) & CheckFlags.Synthetic) {
|
||||
const checkFlags = (s as TransientSymbol).checkFlags;
|
||||
// NOTE: potentially unchecked cast to TransientSymbol
|
||||
const checkFlags = (s as TransientSymbol).links.checkFlags;
|
||||
const accessModifier = checkFlags & CheckFlags.ContainsPrivate ? ModifierFlags.Private :
|
||||
checkFlags & CheckFlags.ContainsPublic ? ModifierFlags.Public :
|
||||
ModifierFlags.Protected;
|
||||
@ -7266,9 +7267,16 @@ function Symbol(this: Symbol, flags: SymbolFlags, name: __String) {
|
||||
this.escapedName = name;
|
||||
this.declarations = undefined;
|
||||
this.valueDeclaration = undefined;
|
||||
this.id = undefined;
|
||||
this.mergeId = undefined;
|
||||
this.id = 0;
|
||||
this.mergeId = 0;
|
||||
this.parent = undefined;
|
||||
this.members = undefined;
|
||||
this.exports = undefined;
|
||||
this.exportSymbol = undefined;
|
||||
this.constEnumOnlyModule = undefined;
|
||||
this.isReferenced = undefined;
|
||||
this.isAssigned = undefined;
|
||||
(this as any).links = undefined; // used by TransientSymbol
|
||||
}
|
||||
|
||||
function Type(this: Type, checker: TypeChecker, flags: TypeFlags) {
|
||||
|
||||
@ -15,6 +15,7 @@ import {
|
||||
isExpression,
|
||||
isImportCall,
|
||||
isNamedDeclaration,
|
||||
isTransientSymbol,
|
||||
makeImport,
|
||||
ModuleKind,
|
||||
NamespaceImport,
|
||||
@ -23,7 +24,6 @@ import {
|
||||
SourceFile,
|
||||
SyntaxKind,
|
||||
textChanges,
|
||||
TransientSymbol,
|
||||
} from "../_namespaces/ts";
|
||||
import {
|
||||
createCodeFixActionWithoutFixAll,
|
||||
@ -107,11 +107,11 @@ function getActionsForInvalidImportLocation(context: CodeFixContext): CodeFixAct
|
||||
|
||||
function getImportCodeFixesForExpression(context: CodeFixContext, expr: Node): CodeFixAction[] | undefined {
|
||||
const type = context.program.getTypeChecker().getTypeAtLocation(expr);
|
||||
if (!(type.symbol && (type.symbol as TransientSymbol).originatingImport)) {
|
||||
if (!(type.symbol && isTransientSymbol(type.symbol) && type.symbol.links.originatingImport)) {
|
||||
return [];
|
||||
}
|
||||
const fixes: CodeFixAction[] = [];
|
||||
const relatedImport = (type.symbol as TransientSymbol).originatingImport!; // TODO: GH#18217
|
||||
const relatedImport = type.symbol.links.originatingImport;
|
||||
if (!isImportCall(relatedImport)) {
|
||||
addRange(fixes, getCodeFixesForImportDeclaration(context, relatedImport));
|
||||
}
|
||||
|
||||
@ -53,6 +53,7 @@ import {
|
||||
isRestParameter,
|
||||
isRightSideOfQualifiedNameOrPropertyAccess,
|
||||
isSetAccessorDeclaration,
|
||||
isTransientSymbol,
|
||||
isVariableDeclaration,
|
||||
isVariableStatement,
|
||||
LanguageServiceHost,
|
||||
@ -88,7 +89,6 @@ import {
|
||||
SourceFile,
|
||||
Symbol,
|
||||
SymbolFlags,
|
||||
SymbolLinks,
|
||||
SyntaxKind,
|
||||
textChanges,
|
||||
Token,
|
||||
@ -1045,7 +1045,7 @@ function inferTypeFromReferences(program: Program, references: readonly Identifi
|
||||
const members = mapEntries(props, (name, types) => {
|
||||
const isOptional = types.length < anons.length ? SymbolFlags.Optional : 0;
|
||||
const s = checker.createSymbol(SymbolFlags.Property | isOptional, name as __String);
|
||||
s.type = checker.getUnionType(types);
|
||||
s.links.type = checker.getUnionType(types);
|
||||
return [name, s];
|
||||
});
|
||||
const indexInfos = [];
|
||||
@ -1080,7 +1080,7 @@ function inferTypeFromReferences(program: Program, references: readonly Identifi
|
||||
|
||||
const candidateTypes = (usage.candidateTypes || []).map(t => checker.getBaseTypeOfLiteralType(t));
|
||||
const callsType = usage.calls?.length ? inferStructuralType(usage) : undefined;
|
||||
if (callsType && candidateTypes) {
|
||||
if (callsType && candidateTypes) { // TODO: should this be `some(candidateTypes)`?
|
||||
types.push(checker.getUnionType([callsType, ...candidateTypes], UnionReduction.Subtype));
|
||||
}
|
||||
else {
|
||||
@ -1101,7 +1101,7 @@ function inferTypeFromReferences(program: Program, references: readonly Identifi
|
||||
if (usage.properties) {
|
||||
usage.properties.forEach((u, name) => {
|
||||
const symbol = checker.createSymbol(SymbolFlags.Property, name);
|
||||
symbol.type = combineFromUsage(u);
|
||||
symbol.links.type = combineFromUsage(u);
|
||||
members.set(name, symbol);
|
||||
});
|
||||
}
|
||||
@ -1202,7 +1202,7 @@ function inferTypeFromReferences(program: Program, references: readonly Identifi
|
||||
if (elementType) {
|
||||
genericParamType = elementType;
|
||||
}
|
||||
const targetType = (usageParam as SymbolLinks).type
|
||||
const targetType = tryCast(usageParam, isTransientSymbol)?.links.type
|
||||
|| (usageParam.valueDeclaration ? checker.getTypeOfSymbolAtLocation(usageParam, usageParam.valueDeclaration) : checker.getAnyType());
|
||||
types.push(...inferTypeParameters(genericParamType, targetType, typeParameter));
|
||||
}
|
||||
@ -1221,7 +1221,7 @@ function inferTypeFromReferences(program: Program, references: readonly Identifi
|
||||
const length = Math.max(...calls.map(c => c.argumentTypes.length));
|
||||
for (let i = 0; i < length; i++) {
|
||||
const symbol = checker.createSymbol(SymbolFlags.FunctionScopedVariable, escapeLeadingUnderscores(`arg${i}`));
|
||||
symbol.type = combineTypes(calls.map(call => call.argumentTypes[i] || checker.getUndefinedType()));
|
||||
symbol.links.type = combineTypes(calls.map(call => call.argumentTypes[i] || checker.getUndefinedType()));
|
||||
if (calls.some(call => call.argumentTypes[i] === undefined)) {
|
||||
symbol.flags |= SymbolFlags.Optional;
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ registerCodeFix({
|
||||
|
||||
function createObjectTypeFromLabeledExpression(checker: TypeChecker, label: Identifier, expression: Expression) {
|
||||
const member = checker.createSymbol(SymbolFlags.Property, label.escapedText);
|
||||
member.type = checker.getTypeAtLocation(expression);
|
||||
member.links.type = checker.getTypeAtLocation(expression);
|
||||
const members = createSymbolTable([member]);
|
||||
return checker.createAnonymousType(/*symbol*/ undefined, members, [], [], []);
|
||||
}
|
||||
|
||||
@ -2124,7 +2124,7 @@ function collectReadsAndWrites(
|
||||
const decl = find(visibleDeclarationsInExtractedRange, d => d.symbol === sym);
|
||||
if (decl) {
|
||||
if (isVariableDeclaration(decl)) {
|
||||
const idString = decl.symbol.id!.toString();
|
||||
const idString = decl.symbol.id.toString();
|
||||
if (!exposedVariableSymbolSet.has(idString)) {
|
||||
exposedVariableDeclarations.push(decl);
|
||||
exposedVariableSymbolSet.set(idString, true);
|
||||
|
||||
@ -183,8 +183,9 @@ import {
|
||||
isTagName,
|
||||
isTextWhiteSpaceLike,
|
||||
isThisTypeParameter,
|
||||
JSDoc,
|
||||
isTransientSymbol,
|
||||
JsDoc,
|
||||
JSDoc,
|
||||
JSDocContainer,
|
||||
JSDocTagInfo,
|
||||
JsonSourceFile,
|
||||
@ -304,7 +305,6 @@ import {
|
||||
toPath,
|
||||
tracing,
|
||||
TransformFlags,
|
||||
TransientSymbol,
|
||||
Type,
|
||||
TypeChecker,
|
||||
TypeFlags,
|
||||
@ -615,6 +615,9 @@ class SymbolObject implements Symbol {
|
||||
escapedName: __String;
|
||||
declarations!: Declaration[];
|
||||
valueDeclaration!: Declaration;
|
||||
id = 0;
|
||||
mergeId = 0;
|
||||
constEnumOnlyModule: boolean | undefined;
|
||||
|
||||
// Undefined is used to indicate the value has not been computed. If, after computing, the
|
||||
// symbol has no doc comment, then the empty array will be returned.
|
||||
@ -656,8 +659,8 @@ class SymbolObject implements Symbol {
|
||||
if (!this.documentationComment) {
|
||||
this.documentationComment = emptyArray; // Set temporarily to avoid an infinite loop finding inherited docs
|
||||
|
||||
if (!this.declarations && (this as Symbol as TransientSymbol).target && ((this as Symbol as TransientSymbol).target as TransientSymbol).tupleLabelDeclaration) {
|
||||
const labelDecl = ((this as Symbol as TransientSymbol).target as TransientSymbol).tupleLabelDeclaration!;
|
||||
if (!this.declarations && isTransientSymbol(this) && this.links.target && isTransientSymbol(this.links.target) && this.links.target.links.tupleLabelDeclaration) {
|
||||
const labelDecl = this.links.target.links.tupleLabelDeclaration;
|
||||
this.documentationComment = getDocumentationComment([labelDecl], checker);
|
||||
}
|
||||
else {
|
||||
|
||||
@ -49,6 +49,7 @@ import {
|
||||
isTemplateLiteralToken,
|
||||
isTemplateSpan,
|
||||
isTemplateTail,
|
||||
isTransientSymbol,
|
||||
last,
|
||||
lastOrUndefined,
|
||||
ListFormat,
|
||||
@ -77,7 +78,6 @@ import {
|
||||
TaggedTemplateExpression,
|
||||
TemplateExpression,
|
||||
TextSpan,
|
||||
TransientSymbol,
|
||||
tryCast,
|
||||
Type,
|
||||
TypeChecker,
|
||||
@ -724,7 +724,7 @@ function itemInfoForParameters(candidateSignature: Signature, checker: TypeCheck
|
||||
const isVariadic: (parameterList: readonly Symbol[]) => boolean =
|
||||
!checker.hasEffectiveRestParameter(candidateSignature) ? _ => false
|
||||
: lists.length === 1 ? _ => true
|
||||
: pList => !!(pList.length && (pList[pList.length - 1] as TransientSymbol).checkFlags & CheckFlags.RestParameter);
|
||||
: pList => !!(pList.length && tryCast(pList[pList.length - 1], isTransientSymbol)?.links.checkFlags! & CheckFlags.RestParameter);
|
||||
return lists.map(parameterList => ({
|
||||
isVariadic: isVariadic(parameterList),
|
||||
parameters: parameterList.map(p => createSignatureHelpParameterForParameter(p, checker, enclosingDeclaration, sourceFile, printer)),
|
||||
@ -739,7 +739,7 @@ function createSignatureHelpParameterForParameter(parameter: Symbol, checker: Ty
|
||||
printer.writeNode(EmitHint.Unspecified, param, sourceFile, writer);
|
||||
});
|
||||
const isOptional = checker.isOptionalParameter(parameter.valueDeclaration as ParameterDeclaration);
|
||||
const isRest = !!((parameter as TransientSymbol).checkFlags & CheckFlags.RestParameter);
|
||||
const isRest = isTransientSymbol(parameter) && !!(parameter.links.checkFlags & CheckFlags.RestParameter);
|
||||
return { name: parameter.name, documentation: parameter.getDocumentationComment(checker), displayParts, isOptional, isRest };
|
||||
}
|
||||
|
||||
|
||||
@ -58,6 +58,7 @@ import {
|
||||
isObjectBindingPattern,
|
||||
isTaggedTemplateExpression,
|
||||
isThisInTypeQuery,
|
||||
isTransientSymbol,
|
||||
isTypeAliasDeclaration,
|
||||
isVarConst,
|
||||
JSDocTagInfo,
|
||||
@ -176,7 +177,7 @@ function getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeCheck
|
||||
if (flags & SymbolFlags.Signature) return ScriptElementKind.indexSignatureElement;
|
||||
|
||||
if (flags & SymbolFlags.Property) {
|
||||
if (flags & SymbolFlags.Transient && (symbol as TransientSymbol).checkFlags & CheckFlags.Synthetic) {
|
||||
if (flags & SymbolFlags.Transient && (symbol as TransientSymbol).links.checkFlags & CheckFlags.Synthetic) {
|
||||
// If union property is result of union of non method (property/accessors/variables), it is labeled as property
|
||||
const unionPropertyKind = forEach(typeChecker.getRootSymbols(symbol), rootSymbol => {
|
||||
const rootSymbolFlags = rootSymbol.getFlags();
|
||||
@ -645,8 +646,8 @@ export function getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker: Typ
|
||||
else {
|
||||
addRange(displayParts, typeToDisplayParts(typeChecker, type, enclosingDeclaration));
|
||||
}
|
||||
if ((symbol as TransientSymbol).target && ((symbol as TransientSymbol).target as TransientSymbol).tupleLabelDeclaration) {
|
||||
const labelDecl = ((symbol as TransientSymbol).target as TransientSymbol).tupleLabelDeclaration!;
|
||||
if (isTransientSymbol(symbol) && symbol.links.target && isTransientSymbol(symbol.links.target) && symbol.links.target.links.tupleLabelDeclaration) {
|
||||
const labelDecl = symbol.links.target.links.tupleLabelDeclaration;
|
||||
Debug.assertNode(labelDecl.name, isIdentifier);
|
||||
displayParts.push(spacePart());
|
||||
displayParts.push(punctuationPart(SyntaxKind.OpenParenToken));
|
||||
|
||||
@ -225,6 +225,7 @@ import {
|
||||
isTaggedTemplateExpression,
|
||||
isTemplateLiteralKind,
|
||||
isToken,
|
||||
isTransientSymbol,
|
||||
isTypeAliasDeclaration,
|
||||
isTypeElement,
|
||||
isTypeNode,
|
||||
@ -336,7 +337,6 @@ import {
|
||||
textSpanEnd,
|
||||
Token,
|
||||
tokenToString,
|
||||
TransientSymbol,
|
||||
tryCast,
|
||||
Type,
|
||||
TypeChecker,
|
||||
@ -2999,9 +2999,9 @@ export function getScriptKind(fileName: string, host: LanguageServiceHost): Scri
|
||||
/** @internal */
|
||||
export function getSymbolTarget(symbol: Symbol, checker: TypeChecker): Symbol {
|
||||
let next: Symbol = symbol;
|
||||
while (isAliasSymbol(next) || (isTransientSymbol(next) && next.target)) {
|
||||
if (isTransientSymbol(next) && next.target) {
|
||||
next = next.target;
|
||||
while (isAliasSymbol(next) || (isTransientSymbol(next) && next.links.target)) {
|
||||
if (isTransientSymbol(next) && next.links.target) {
|
||||
next = next.links.target;
|
||||
}
|
||||
else {
|
||||
next = skipAlias(next, checker);
|
||||
@ -3010,10 +3010,6 @@ export function getSymbolTarget(symbol: Symbol, checker: TypeChecker): Symbol {
|
||||
return next;
|
||||
}
|
||||
|
||||
function isTransientSymbol(symbol: Symbol): symbol is TransientSymbol {
|
||||
return (symbol.flags & SymbolFlags.Transient) !== 0;
|
||||
}
|
||||
|
||||
function isAliasSymbol(symbol: Symbol): boolean {
|
||||
return (symbol.flags & SymbolFlags.Alias) !== 0;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user