Add undefined to Symbol.valueDeclaration (#43033)
* About halfway through the checker I'm going to merge with master to avoid clashing with the declaration fix. * Add undefined to Symbol.valueDeclaration Also add undefined to a number of utility functions that have always accepted it, but never added it to their type. * Fix lint from code review Co-authored-by: Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com> * remove obsoleted fix from inferFromUsage Co-authored-by: Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com>
This commit is contained in:
parent
3d1c6e8f2f
commit
c497b487a7
|
@ -3187,7 +3187,7 @@ namespace ts {
|
|||
undefined;
|
||||
init = init && getRightMostAssignedExpression(init);
|
||||
if (init) {
|
||||
const isPrototypeAssignment = isPrototypeAccess(isVariableDeclaration(node) ? node.name : isBinaryExpression(node) ? node.left : node);
|
||||
const isPrototypeAssignment = isPrototypeAccess(isVariableDeclaration(node!) ? node.name : isBinaryExpression(node!) ? node.left : node!);
|
||||
return !!getExpandoInitializer(isBinaryExpression(init) && (init.operatorToken.kind === SyntaxKind.BarBarToken || init.operatorToken.kind === SyntaxKind.QuestionQuestionToken) ? init.right : init, isPrototypeAssignment);
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -1640,7 +1640,11 @@ namespace ts {
|
|||
function useOuterVariableScopeInParameter(result: Symbol, location: Node, lastLocation: Node) {
|
||||
const target = getEmitScriptTarget(compilerOptions);
|
||||
const functionLocation = <FunctionLikeDeclaration>location;
|
||||
if (isParameter(lastLocation) && functionLocation.body && result.valueDeclaration.pos >= functionLocation.body.pos && result.valueDeclaration.end <= functionLocation.body.end) {
|
||||
if (isParameter(lastLocation)
|
||||
&& functionLocation.body
|
||||
&& result.valueDeclaration
|
||||
&& result.valueDeclaration.pos >= functionLocation.body.pos
|
||||
&& result.valueDeclaration.end <= functionLocation.body.end) {
|
||||
// check for several cases where we introduce temporaries that require moving the name/initializer of the parameter to the body
|
||||
// - static field in a class expression
|
||||
// - optional chaining pre-es2020
|
||||
|
@ -2613,11 +2617,13 @@ namespace ts {
|
|||
const exportAssignment = exportEqualsSymbol!.valueDeclaration;
|
||||
const err = error(node.name, Diagnostics.Module_0_can_only_be_default_imported_using_the_1_flag, symbolToString(moduleSymbol), compilerOptionName);
|
||||
|
||||
addRelatedInfo(err, createDiagnosticForNode(
|
||||
exportAssignment,
|
||||
Diagnostics.This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag,
|
||||
compilerOptionName
|
||||
));
|
||||
if (exportAssignment) {
|
||||
addRelatedInfo(err, createDiagnosticForNode(
|
||||
exportAssignment,
|
||||
Diagnostics.This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag,
|
||||
compilerOptionName
|
||||
));
|
||||
}
|
||||
}
|
||||
else {
|
||||
reportNonDefaultExport(moduleSymbol, node);
|
||||
|
@ -2796,7 +2802,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function reportNonExportedMember(node: ImportDeclaration | ExportDeclaration | VariableDeclaration, name: Identifier, declarationName: string, moduleSymbol: Symbol, moduleName: string): void {
|
||||
const localSymbol = moduleSymbol.valueDeclaration.locals?.get(name.escapedText);
|
||||
const localSymbol = moduleSymbol.valueDeclaration?.locals?.get(name.escapedText);
|
||||
const exports = moduleSymbol.exports;
|
||||
if (localSymbol) {
|
||||
const exportedEqualsSymbol = exports?.get(InternalSymbolName.ExportEquals);
|
||||
|
@ -4415,7 +4421,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function symbolValueDeclarationIsContextSensitive(symbol: Symbol): boolean {
|
||||
return symbol && symbol.valueDeclaration && isExpression(symbol.valueDeclaration) && !isContextSensitive(symbol.valueDeclaration);
|
||||
return symbol && !!symbol.valueDeclaration && isExpression(symbol.valueDeclaration) && !isContextSensitive(symbol.valueDeclaration);
|
||||
}
|
||||
|
||||
function toNodeBuilderFlags(flags = TypeFormatFlags.None): NodeBuilderFlags {
|
||||
|
@ -4764,7 +4770,9 @@ namespace ts {
|
|||
return symbolToTypeNode(symbol, context, isInstanceType);
|
||||
}
|
||||
// Always use 'typeof T' for type of class, enum, and module objects
|
||||
else if (symbol.flags & SymbolFlags.Class && !getBaseTypeVariableOfClass(symbol) && !(symbol.valueDeclaration.kind === SyntaxKind.ClassExpression && context.flags & NodeBuilderFlags.WriteClassExpressionAsTypeLiteral) ||
|
||||
else if (symbol.flags & SymbolFlags.Class
|
||||
&& !getBaseTypeVariableOfClass(symbol)
|
||||
&& !(symbol.valueDeclaration && symbol.valueDeclaration.kind === SyntaxKind.ClassExpression && context.flags & NodeBuilderFlags.WriteClassExpressionAsTypeLiteral) ||
|
||||
symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule) ||
|
||||
shouldWriteTypeOfFunctionSymbol()) {
|
||||
return symbolToTypeNode(symbol, context, isInstanceType);
|
||||
|
@ -6528,7 +6536,7 @@ namespace ts {
|
|||
}
|
||||
const propertyAccessRequire = symbol.declarations?.find(isPropertyAccessExpression);
|
||||
if (propertyAccessRequire && isBinaryExpression(propertyAccessRequire.parent) && isIdentifier(propertyAccessRequire.parent.right)
|
||||
&& type.symbol && isSourceFile(type.symbol.valueDeclaration)) {
|
||||
&& type.symbol?.valueDeclaration && isSourceFile(type.symbol.valueDeclaration)) {
|
||||
const alias = localName === propertyAccessRequire.parent.right.escapedText ? undefined : propertyAccessRequire.parent.right;
|
||||
addResult(
|
||||
factory.createExportDeclaration(
|
||||
|
@ -6588,7 +6596,10 @@ namespace ts {
|
|||
serializeEnum(symbol, symbolName, modifierFlags);
|
||||
}
|
||||
if (symbol.flags & SymbolFlags.Class) {
|
||||
if (symbol.flags & SymbolFlags.Property && isBinaryExpression(symbol.valueDeclaration.parent) && isClassExpression(symbol.valueDeclaration.parent.right)) {
|
||||
if (symbol.flags & SymbolFlags.Property
|
||||
&& symbol.valueDeclaration
|
||||
&& isBinaryExpression(symbol.valueDeclaration.parent)
|
||||
&& isClassExpression(symbol.valueDeclaration.parent.right)) {
|
||||
// Looks like a `module.exports.Sub = class {}` - if we serialize `symbol` as a class, the result will have no members,
|
||||
// since the classiness is actually from the target of the effective alias the symbol is. yes. A BlockScopedVariable|Class|Property
|
||||
// _really_ acts like an Alias, and none of a BlockScopedVariable, Class, or Property. This is the travesty of JS binding today.
|
||||
|
@ -6940,14 +6951,14 @@ namespace ts {
|
|||
// a union/intersection base type, but inherited properties
|
||||
// don't matter here.
|
||||
const valueDecl = s.valueDeclaration;
|
||||
return valueDecl && !(isNamedDeclaration(valueDecl) && isPrivateIdentifier(valueDecl.name));
|
||||
return !!valueDecl && !(isNamedDeclaration(valueDecl) && isPrivateIdentifier(valueDecl.name));
|
||||
});
|
||||
const hasPrivateIdentifier = some(symbolProps, s => {
|
||||
// `valueDeclaration` could be undefined if inherited from
|
||||
// a union/intersection base type, but inherited properties
|
||||
// don't matter here.
|
||||
const valueDecl = s.valueDeclaration;
|
||||
return valueDecl && isNamedDeclaration(valueDecl) && isPrivateIdentifier(valueDecl.name);
|
||||
return !!valueDecl && isNamedDeclaration(valueDecl) && isPrivateIdentifier(valueDecl.name);
|
||||
});
|
||||
// Boil down all private properties into a single one.
|
||||
const privateProperties = hasPrivateIdentifier ?
|
||||
|
@ -8394,7 +8405,10 @@ namespace ts {
|
|||
}
|
||||
|
||||
function getFlowTypeOfProperty(reference: Node, prop: Symbol | undefined) {
|
||||
const initialType = prop && (!isAutoTypedProperty(prop) || getEffectiveModifierFlags(prop.valueDeclaration) & ModifierFlags.Ambient) && getTypeOfPropertyInBaseClass(prop) || undefinedType;
|
||||
const initialType = prop?.valueDeclaration
|
||||
&& (!isAutoTypedProperty(prop) || getEffectiveModifierFlags(prop.valueDeclaration) & ModifierFlags.Ambient)
|
||||
&& getTypeOfPropertyInBaseClass(prop)
|
||||
|| undefinedType;
|
||||
return getFlowTypeOfReference(reference, autoType, initialType);
|
||||
}
|
||||
|
||||
|
@ -8406,7 +8420,7 @@ namespace ts {
|
|||
if (tag && tag.typeExpression) {
|
||||
return getTypeFromTypeNode(tag.typeExpression);
|
||||
}
|
||||
const containerObjectType = getJSContainerObjectType(symbol.valueDeclaration, symbol, container);
|
||||
const containerObjectType = symbol.valueDeclaration && getJSContainerObjectType(symbol.valueDeclaration, symbol, container);
|
||||
return containerObjectType || getWidenedLiteralType(checkExpressionCached(container));
|
||||
}
|
||||
let type;
|
||||
|
@ -8467,7 +8481,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
const widened = getWidenedType(addOptionality(type, definedInMethod && !definedInConstructor));
|
||||
if (filterType(widened, t => !!(t.flags & ~TypeFlags.Nullable)) === neverType) {
|
||||
if (symbol.valueDeclaration && filterType(widened, t => !!(t.flags & ~TypeFlags.Nullable)) === neverType) {
|
||||
reportImplicitAny(symbol.valueDeclaration, anyType);
|
||||
return anyType;
|
||||
}
|
||||
|
@ -8506,7 +8520,7 @@ namespace ts {
|
|||
errorNextVariableOrPropertyDeclarationMustHaveSameType(/*firstDeclaration*/ undefined, declaredType, declaration, type);
|
||||
}
|
||||
}
|
||||
if (symbol.parent) {
|
||||
if (symbol.parent?.valueDeclaration) {
|
||||
const typeNode = getEffectiveTypeAnnotationNode(symbol.parent.valueDeclaration);
|
||||
if (typeNode) {
|
||||
return getTypeOfPropertyOfType(getTypeFromTypeNode(typeNode), symbol.escapedName);
|
||||
|
@ -8571,7 +8585,7 @@ namespace ts {
|
|||
// but we may have a JS file with `module.exports = { a: true }` along with a TypeScript module augmentation
|
||||
// declaring an `export const a: number`. In that case, we issue a duplicate identifier error, because
|
||||
// it's unclear what that's supposed to mean, so it's probably a mistake.
|
||||
if (getSourceFileOfNode(s.valueDeclaration) !== getSourceFileOfNode(exportedMember.valueDeclaration)) {
|
||||
if (s.valueDeclaration && exportedMember.valueDeclaration && getSourceFileOfNode(s.valueDeclaration) !== getSourceFileOfNode(exportedMember.valueDeclaration)) {
|
||||
const unescapedName = unescapeLeadingUnderscores(s.escapedName);
|
||||
const exportedMemberName = tryCast(exportedMember.valueDeclaration, isNamedDeclaration)?.name || exportedMember.valueDeclaration;
|
||||
addRelatedInfo(
|
||||
|
@ -8816,7 +8830,7 @@ namespace ts {
|
|||
if (symbol === requireSymbol) {
|
||||
return anyType;
|
||||
}
|
||||
if (symbol.flags & SymbolFlags.ModuleExports) {
|
||||
if (symbol.flags & SymbolFlags.ModuleExports && symbol.valueDeclaration) {
|
||||
const fileSymbol = getSymbolOfNode(getSourceFileOfNode(symbol.valueDeclaration));
|
||||
const result = createSymbol(fileSymbol.flags, "exports" as __String);
|
||||
result.declarations = fileSymbol.declarations ? fileSymbol.declarations.slice() : [];
|
||||
|
@ -8830,6 +8844,7 @@ namespace ts {
|
|||
return createAnonymousType(symbol, members, emptyArray, emptyArray, undefined, undefined);
|
||||
}
|
||||
// Handle catch clause variables
|
||||
Debug.assertIsDefined(symbol.valueDeclaration);
|
||||
const declaration = symbol.valueDeclaration;
|
||||
if (isCatchClauseVariableDeclarationOrBindingElement(declaration)) {
|
||||
const decl = declaration as VariableDeclaration;
|
||||
|
@ -9224,7 +9239,7 @@ namespace ts {
|
|||
if (assignmentKind === AssignmentDeclarationKind.Prototype || assignmentKind === AssignmentDeclarationKind.PrototypeProperty) {
|
||||
const symbol = getSymbolOfNode(node.left);
|
||||
if (symbol && symbol.parent && !findAncestor(symbol.parent.valueDeclaration, d => node === d)) {
|
||||
node = symbol.parent.valueDeclaration;
|
||||
node = symbol.parent.valueDeclaration!;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9268,7 +9283,7 @@ namespace ts {
|
|||
case SyntaxKind.JSDocParameterTag:
|
||||
const paramSymbol = getParameterSymbolFromJSDoc(node as JSDocParameterTag);
|
||||
if (paramSymbol) {
|
||||
node = paramSymbol.valueDeclaration;
|
||||
node = paramSymbol.valueDeclaration!;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.JSDocComment: {
|
||||
|
@ -9622,7 +9637,7 @@ namespace ts {
|
|||
const originalLinks = links;
|
||||
if (!links.declaredType) {
|
||||
const kind = symbol.flags & SymbolFlags.Class ? ObjectFlags.Class : ObjectFlags.Interface;
|
||||
const merged = mergeJSSymbols(symbol, getAssignedClassSymbol(symbol.valueDeclaration));
|
||||
const merged = mergeJSSymbols(symbol, symbol.valueDeclaration && getAssignedClassSymbol(symbol.valueDeclaration));
|
||||
if (merged) {
|
||||
// note:we overwrite links because we just cloned the symbol
|
||||
symbol = links = merged;
|
||||
|
@ -23460,6 +23475,9 @@ namespace ts {
|
|||
|
||||
// Check if a parameter is assigned anywhere within its declaring function.
|
||||
function isParameterAssigned(symbol: Symbol) {
|
||||
if (!symbol.valueDeclaration) {
|
||||
return false;
|
||||
}
|
||||
const func = <FunctionLikeDeclaration>getRootDeclaration(symbol.valueDeclaration).parent;
|
||||
const links = getNodeLinks(func);
|
||||
if (!(links.flags & NodeCheckFlags.AssignmentsMarked)) {
|
||||
|
@ -23599,8 +23617,8 @@ namespace ts {
|
|||
addDeprecatedSuggestion(node, sourceSymbol.declarations, node.escapedText as string);
|
||||
}
|
||||
|
||||
let declaration: Declaration | undefined = localOrExportSymbol.valueDeclaration;
|
||||
if (localOrExportSymbol.flags & SymbolFlags.Class) {
|
||||
let declaration = localOrExportSymbol.valueDeclaration;
|
||||
if (declaration && localOrExportSymbol.flags & SymbolFlags.Class) {
|
||||
// Due to the emit for class decorators, any reference to the class from inside of the class body
|
||||
// must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
|
||||
// behavior of class names in ES6.
|
||||
|
@ -23739,6 +23757,7 @@ namespace ts {
|
|||
function checkNestedBlockScopedBinding(node: Identifier, symbol: Symbol): void {
|
||||
if (languageVersion >= ScriptTarget.ES2015 ||
|
||||
(symbol.flags & (SymbolFlags.BlockScopedVariable | SymbolFlags.Class)) === 0 ||
|
||||
!symbol.valueDeclaration ||
|
||||
isSourceFile(symbol.valueDeclaration) ||
|
||||
symbol.valueDeclaration.parent.kind === SyntaxKind.CatchClause) {
|
||||
return;
|
||||
|
@ -26378,7 +26397,7 @@ namespace ts {
|
|||
return true;
|
||||
}
|
||||
if (isInJSFile(symbol.valueDeclaration)) {
|
||||
const parent = symbol.valueDeclaration.parent;
|
||||
const parent = symbol.valueDeclaration!.parent;
|
||||
return parent && isBinaryExpression(parent) &&
|
||||
getAssignmentDeclarationKind(parent) === AssignmentDeclarationKind.PrototypeProperty;
|
||||
}
|
||||
|
@ -26618,14 +26637,13 @@ namespace ts {
|
|||
}
|
||||
const diagName = diagnosticName(right);
|
||||
if (propertyOnType) {
|
||||
const typeValueDecl = propertyOnType.valueDeclaration;
|
||||
const typeClass = getContainingClass(typeValueDecl);
|
||||
Debug.assert(!!typeClass);
|
||||
const typeValueDecl = Debug.checkDefined(propertyOnType.valueDeclaration);
|
||||
const typeClass = Debug.checkDefined(getContainingClass(typeValueDecl));
|
||||
// We found a private identifier property with the same description.
|
||||
// Either:
|
||||
// - There is a lexically scoped private identifier AND it shadows the one we found on the type.
|
||||
// - It is an attempt to access the private identifier outside of the class.
|
||||
if (lexicallyScopedIdentifier) {
|
||||
if (lexicallyScopedIdentifier?.valueDeclaration) {
|
||||
const lexicalValueDecl = lexicallyScopedIdentifier.valueDeclaration;
|
||||
const lexicalClass = getContainingClass(lexicalValueDecl);
|
||||
Debug.assert(!!lexicalClass);
|
||||
|
@ -26934,7 +26952,7 @@ namespace ts {
|
|||
|
||||
function typeHasStaticProperty(propName: __String, containingType: Type): boolean {
|
||||
const prop = containingType.symbol && getPropertyOfType(getTypeOfSymbol(containingType.symbol), propName);
|
||||
return prop !== undefined && prop.valueDeclaration && hasSyntacticModifier(prop.valueDeclaration, ModifierFlags.Static);
|
||||
return prop !== undefined && !!prop.valueDeclaration && hasSyntacticModifier(prop.valueDeclaration, ModifierFlags.Static);
|
||||
}
|
||||
|
||||
function getSuggestedLibForNonExistentName(name: __String | Identifier) {
|
||||
|
@ -27082,7 +27100,7 @@ namespace ts {
|
|||
return;
|
||||
}
|
||||
const hasPrivateModifier = hasEffectiveModifier(valueDeclaration, ModifierFlags.Private);
|
||||
const hasPrivateIdentifier = isNamedDeclaration(prop.valueDeclaration) && isPrivateIdentifier(prop.valueDeclaration.name);
|
||||
const hasPrivateIdentifier = prop.valueDeclaration && isNamedDeclaration(prop.valueDeclaration) && isPrivateIdentifier(prop.valueDeclaration.name);
|
||||
if (!hasPrivateModifier && !hasPrivateIdentifier) {
|
||||
return;
|
||||
}
|
||||
|
@ -34739,7 +34757,7 @@ namespace ts {
|
|||
if (node.initializer) {
|
||||
checkTypeAssignableToAndOptionallyElaborate(checkExpressionCached(node.initializer), declarationType, node, node.initializer, /*headMessage*/ undefined);
|
||||
}
|
||||
if (!areDeclarationFlagsIdentical(node, symbol.valueDeclaration)) {
|
||||
if (symbol.valueDeclaration && !areDeclarationFlagsIdentical(node, symbol.valueDeclaration)) {
|
||||
error(node.name, Diagnostics.All_declarations_of_0_must_have_identical_modifiers, declarationNameToString(node.name));
|
||||
}
|
||||
}
|
||||
|
@ -36040,7 +36058,7 @@ namespace ts {
|
|||
if (blockLocals) {
|
||||
forEachKey(catchClause.locals!, caughtName => {
|
||||
const blockLocal = blockLocals.get(caughtName);
|
||||
if (blockLocal && (blockLocal.flags & SymbolFlags.BlockScopedVariable) !== 0) {
|
||||
if (blockLocal?.valueDeclaration && (blockLocal.flags & SymbolFlags.BlockScopedVariable) !== 0) {
|
||||
grammarErrorOnNode(blockLocal.valueDeclaration, Diagnostics.Cannot_redeclare_identifier_0_in_catch_clause, caughtName);
|
||||
}
|
||||
});
|
||||
|
@ -36071,7 +36089,7 @@ namespace ts {
|
|||
});
|
||||
|
||||
const classDeclaration = type.symbol.valueDeclaration;
|
||||
if (getObjectFlags(type) & ObjectFlags.Class && isClassLike(classDeclaration)) {
|
||||
if (getObjectFlags(type) & ObjectFlags.Class && classDeclaration && isClassLike(classDeclaration)) {
|
||||
for (const member of classDeclaration.members) {
|
||||
// Only process instance properties with computed names here.
|
||||
// Static properties cannot be in conflict with indexers,
|
||||
|
@ -36941,7 +36959,7 @@ namespace ts {
|
|||
if (memberSymbol) {
|
||||
const declaration = memberSymbol.valueDeclaration;
|
||||
if (declaration !== member) {
|
||||
if (isBlockScopedNameDeclaredBeforeUse(declaration, member)) {
|
||||
if (declaration && isBlockScopedNameDeclaredBeforeUse(declaration, member)) {
|
||||
return getEnumMemberValue(declaration as EnumMember);
|
||||
}
|
||||
error(expr, Diagnostics.A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums);
|
||||
|
@ -37600,7 +37618,7 @@ namespace ts {
|
|||
const exportEqualsSymbol = moduleSymbol.exports!.get("export=" as __String);
|
||||
if (exportEqualsSymbol && hasExportedMembers(moduleSymbol)) {
|
||||
const declaration = getDeclarationOfAliasSymbol(exportEqualsSymbol) || exportEqualsSymbol.valueDeclaration;
|
||||
if (!isTopLevelInExternalModuleAugmentation(declaration) && !isInJSFile(declaration)) {
|
||||
if (declaration && !isTopLevelInExternalModuleAugmentation(declaration) && !isInJSFile(declaration)) {
|
||||
error(declaration, Diagnostics.An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements);
|
||||
}
|
||||
}
|
||||
|
@ -38574,7 +38592,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function getShorthandAssignmentValueSymbol(location: Node): Symbol | undefined {
|
||||
function getShorthandAssignmentValueSymbol(location: Node | undefined): Symbol | undefined {
|
||||
if (location && location.kind === SyntaxKind.ShorthandPropertyAssignment) {
|
||||
return resolveEntityName((<ShorthandPropertyAssignment>location).name, SymbolFlags.Value | SymbolFlags.Alias);
|
||||
}
|
||||
|
@ -38862,7 +38880,7 @@ namespace ts {
|
|||
}
|
||||
const parentSymbol = getParentOfSymbol(symbol);
|
||||
if (parentSymbol) {
|
||||
if (parentSymbol.flags & SymbolFlags.ValueModule && parentSymbol.valueDeclaration.kind === SyntaxKind.SourceFile) {
|
||||
if (parentSymbol.flags & SymbolFlags.ValueModule && parentSymbol.valueDeclaration?.kind === SyntaxKind.SourceFile) {
|
||||
const symbolFile = <SourceFile>parentSymbol.valueDeclaration;
|
||||
const referenceFile = getSourceFileOfNode(node);
|
||||
// If `node` accesses an export and that export isn't in the same file, then symbol is a namespace export, so return undefined.
|
||||
|
@ -38895,12 +38913,13 @@ namespace ts {
|
|||
}
|
||||
|
||||
function isSymbolOfDestructuredElementOfCatchBinding(symbol: Symbol) {
|
||||
return isBindingElement(symbol.valueDeclaration)
|
||||
return symbol.valueDeclaration
|
||||
&& isBindingElement(symbol.valueDeclaration)
|
||||
&& walkUpBindingElementsAndPatterns(symbol.valueDeclaration).parent.kind === SyntaxKind.CatchClause;
|
||||
}
|
||||
|
||||
function isSymbolOfDeclarationWithCollidingName(symbol: Symbol): boolean {
|
||||
if (symbol.flags & SymbolFlags.BlockScoped && !isSourceFile(symbol.valueDeclaration)) {
|
||||
if (symbol.flags & SymbolFlags.BlockScoped && symbol.valueDeclaration && !isSourceFile(symbol.valueDeclaration)) {
|
||||
const links = getSymbolLinks(symbol);
|
||||
if (links.isDeclarationWithCollidingName === undefined) {
|
||||
const container = getEnclosingBlockScopeContainer(symbol.valueDeclaration);
|
||||
|
|
|
@ -5507,7 +5507,7 @@ namespace ts {
|
|||
: reduceLeft(expressions, factory.createComma)!;
|
||||
}
|
||||
|
||||
function getName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags: EmitFlags = 0) {
|
||||
function getName(node: Declaration | undefined, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags: EmitFlags = 0) {
|
||||
const nodeName = getNameOfDeclaration(node);
|
||||
if (nodeName && isIdentifier(nodeName) && !isGeneratedIdentifier(nodeName)) {
|
||||
// TODO(rbuckton): Does this need to be parented?
|
||||
|
@ -5571,7 +5571,7 @@ namespace ts {
|
|||
* @param allowComments A value indicating whether comments may be emitted for the name.
|
||||
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
|
||||
*/
|
||||
function getDeclarationName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean) {
|
||||
function getDeclarationName(node: Declaration | undefined, allowComments?: boolean, allowSourceMaps?: boolean) {
|
||||
return getName(node, allowComments, allowSourceMaps);
|
||||
}
|
||||
|
||||
|
|
|
@ -103,6 +103,9 @@ namespace ts.moduleSpecifiers {
|
|||
|
||||
const info = getInfo(importingSourceFile.path, host);
|
||||
const moduleSourceFile = getSourceFileOfNode(moduleSymbol.valueDeclaration || getNonAugmentationDeclaration(moduleSymbol));
|
||||
if (!moduleSourceFile) {
|
||||
return [];
|
||||
}
|
||||
const modulePaths = getAllModulePaths(importingSourceFile.path, moduleSourceFile.originalFileName, host);
|
||||
const preferences = getPreferences(userPreferences, compilerOptions, importingSourceFile);
|
||||
|
||||
|
|
|
@ -1202,7 +1202,7 @@ namespace ts {
|
|||
fakespace.symbol = props[0].parent!;
|
||||
const exportMappings: [Identifier, string][] = [];
|
||||
let declarations: (VariableStatement | ExportDeclaration)[] = mapDefined(props, p => {
|
||||
if (!isPropertyAccessExpression(p.valueDeclaration)) {
|
||||
if (!p.valueDeclaration || !isPropertyAccessExpression(p.valueDeclaration)) {
|
||||
return undefined; // TODO GH#33569: Handle element access expressions that created late bound names (rather than silently omitting them)
|
||||
}
|
||||
getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(p.valueDeclaration);
|
||||
|
|
|
@ -4046,7 +4046,7 @@ namespace ts {
|
|||
* The function returns the value (local variable) symbol of an identifier in the short-hand property assignment.
|
||||
* This is necessary as an identifier in short-hand property assignment can contains two meaning: property name and property value.
|
||||
*/
|
||||
getShorthandAssignmentValueSymbol(location: Node): Symbol | undefined;
|
||||
getShorthandAssignmentValueSymbol(location: Node | undefined): Symbol | undefined;
|
||||
|
||||
getExportSpecifierLocalTargetSymbol(location: ExportSpecifier | Identifier): Symbol | undefined;
|
||||
/**
|
||||
|
@ -4715,7 +4715,7 @@ namespace ts {
|
|||
flags: SymbolFlags; // Symbol flags
|
||||
escapedName: __String; // Name of symbol
|
||||
declarations?: Declaration[]; // Declarations associated with this symbol
|
||||
valueDeclaration: Declaration; // First value declaration of the symbol
|
||||
valueDeclaration?: Declaration; // First value declaration of the symbol
|
||||
members?: SymbolTable; // Class, interface or object literal instance members
|
||||
exports?: SymbolTable; // Module exports
|
||||
globalExports?: SymbolTable; // Conditional global UMD exports
|
||||
|
@ -7394,7 +7394,7 @@ namespace ts {
|
|||
* @param allowComments A value indicating whether comments may be emitted for the name.
|
||||
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
|
||||
*/
|
||||
/* @internal */ getDeclarationName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean): Identifier;
|
||||
/* @internal */ getDeclarationName(node: Declaration | undefined, allowComments?: boolean, allowSourceMaps?: boolean): Identifier;
|
||||
/**
|
||||
* Gets a namespace-qualified name for use in expressions.
|
||||
*
|
||||
|
|
|
@ -734,9 +734,9 @@ namespace ts {
|
|||
return isShorthandAmbientModule(moduleSymbol.valueDeclaration);
|
||||
}
|
||||
|
||||
function isShorthandAmbientModule(node: Node): boolean {
|
||||
function isShorthandAmbientModule(node: Node | undefined): boolean {
|
||||
// The only kind of module that can be missing a body is a shorthand ambient module.
|
||||
return node && node.kind === SyntaxKind.ModuleDeclaration && (!(<ModuleDeclaration>node).body);
|
||||
return !!node && node.kind === SyntaxKind.ModuleDeclaration && (!(<ModuleDeclaration>node).body);
|
||||
}
|
||||
|
||||
export function isBlockScopedContainerTopLevel(node: Node): boolean {
|
||||
|
|
|
@ -614,7 +614,7 @@ namespace ts {
|
|||
return (declaration as NamedDeclaration).name;
|
||||
}
|
||||
|
||||
export function getNameOfDeclaration(declaration: Declaration | Expression): DeclarationName | undefined {
|
||||
export function getNameOfDeclaration(declaration: Declaration | Expression | undefined): DeclarationName | undefined {
|
||||
if (declaration === undefined) return undefined;
|
||||
return getNonAssignedNameOfDeclaration(declaration) ||
|
||||
(isFunctionExpression(declaration) || isClassExpression(declaration) ? getAssignedName(declaration) : undefined);
|
||||
|
@ -1208,8 +1208,8 @@ namespace ts {
|
|||
|
||||
// Functions
|
||||
|
||||
export function isFunctionLike(node: Node): node is SignatureDeclaration {
|
||||
return node && isFunctionLikeKind(node.kind);
|
||||
export function isFunctionLike(node: Node | undefined): node is SignatureDeclaration {
|
||||
return !!node && isFunctionLikeKind(node.kind);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace ts.codefix {
|
|||
const token = getTokenAtPosition(sourceFile, pos);
|
||||
const checker = program.getTypeChecker();
|
||||
const symbol = checker.getSymbolAtLocation(token);
|
||||
if (symbol) {
|
||||
if (symbol?.valueDeclaration) {
|
||||
return symbol.valueDeclaration.parent.parent as VariableStatement;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace ts.codefix {
|
|||
|
||||
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, position: number, checker: TypeChecker, preferences: UserPreferences, compilerOptions: CompilerOptions): void {
|
||||
const ctorSymbol = checker.getSymbolAtLocation(getTokenAtPosition(sourceFile, position))!;
|
||||
if (!ctorSymbol || !(ctorSymbol.flags & (SymbolFlags.Function | SymbolFlags.Variable))) {
|
||||
if (!ctorSymbol || !ctorSymbol.valueDeclaration || !(ctorSymbol.flags & (SymbolFlags.Function | SymbolFlags.Variable))) {
|
||||
// Bad input
|
||||
return undefined;
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ namespace ts.codefix {
|
|||
// all instance members are stored in the "member" array of symbol
|
||||
if (symbol.members) {
|
||||
symbol.members.forEach((member, key) => {
|
||||
if (key === "constructor") {
|
||||
if (key === "constructor" && member.valueDeclaration) {
|
||||
// fn.prototype.constructor = fn
|
||||
changes.delete(sourceFile, member.valueDeclaration.parent);
|
||||
return;
|
||||
|
|
|
@ -168,7 +168,10 @@ namespace ts.codefix {
|
|||
// so we push an entry for 'response'.
|
||||
if (lastCallSignature && !isParameter(node.parent) && !isFunctionLikeDeclaration(node.parent) && !synthNamesMap.has(symbolIdString)) {
|
||||
const firstParameter = firstOrUndefined(lastCallSignature.parameters);
|
||||
const ident = firstParameter && isParameter(firstParameter.valueDeclaration) && tryCast(firstParameter.valueDeclaration.name, isIdentifier) || factory.createUniqueName("result", GeneratedIdentifierFlags.Optimistic);
|
||||
const ident = firstParameter?.valueDeclaration
|
||||
&& isParameter(firstParameter.valueDeclaration)
|
||||
&& tryCast(firstParameter.valueDeclaration.name, isIdentifier)
|
||||
|| factory.createUniqueName("result", GeneratedIdentifierFlags.Optimistic);
|
||||
const synthName = getNewNameIfConflict(ident, collidingSymbolMap);
|
||||
synthNamesMap.set(symbolIdString, synthName);
|
||||
collidingSymbolMap.add(ident.text, symbol);
|
||||
|
|
|
@ -87,7 +87,7 @@ namespace ts.codefix {
|
|||
const suggestion = symbolName(suggestedSymbol);
|
||||
if (!isIdentifierText(suggestion, target) && isPropertyAccessExpression(node.parent)) {
|
||||
const valDecl = suggestedSymbol.valueDeclaration;
|
||||
if (isNamedDeclaration(valDecl) && isPrivateIdentifier(valDecl.name)) {
|
||||
if (valDecl && isNamedDeclaration(valDecl) && isPrivateIdentifier(valDecl.name)) {
|
||||
changes.replaceNode(sourceFile, node, factory.createIdentifier(suggestion));
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -1025,7 +1025,7 @@ namespace ts.codefix {
|
|||
}
|
||||
|
||||
function allowsImportingAmbientModule(moduleSymbol: Symbol): boolean {
|
||||
if (!packageJsons.length) {
|
||||
if (!packageJsons.length || !moduleSymbol.valueDeclaration) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -950,7 +950,7 @@ namespace ts.codefix {
|
|||
const props = createMultiMap<Type>();
|
||||
for (const anon of anons) {
|
||||
for (const p of checker.getPropertiesOfType(anon)) {
|
||||
props.add(p.name, checker.getTypeOfSymbolAtLocation(p, p.valueDeclaration));
|
||||
props.add(p.name, p.valueDeclaration ? checker.getTypeOfSymbolAtLocation(p, p.valueDeclaration) : checker.getAnyType());
|
||||
}
|
||||
calls.push(...checker.getSignaturesOfType(anon, SignatureKind.Call));
|
||||
constructs.push(...checker.getSignaturesOfType(anon, SignatureKind.Construct));
|
||||
|
@ -1104,12 +1104,13 @@ namespace ts.codefix {
|
|||
if (!usageParam) {
|
||||
break;
|
||||
}
|
||||
let genericParamType = checker.getTypeOfSymbolAtLocation(genericParam, genericParam.valueDeclaration);
|
||||
let genericParamType = genericParam.valueDeclaration ? checker.getTypeOfSymbolAtLocation(genericParam, genericParam.valueDeclaration) : checker.getAnyType();
|
||||
const elementType = isRest && checker.getElementTypeOfArrayType(genericParamType);
|
||||
if (elementType) {
|
||||
genericParamType = elementType;
|
||||
}
|
||||
const targetType = (usageParam as SymbolLinks).type || checker.getTypeOfSymbolAtLocation(usageParam, usageParam.valueDeclaration);
|
||||
const targetType = (usageParam as SymbolLinks).type
|
||||
|| (usageParam.valueDeclaration ? checker.getTypeOfSymbolAtLocation(usageParam, usageParam.valueDeclaration) : checker.getAnyType());
|
||||
types.push(...inferTypeParameters(genericParamType, targetType, typeParameter));
|
||||
}
|
||||
const genericReturn = checker.getReturnTypeOfSignature(genericSig);
|
||||
|
|
|
@ -360,7 +360,7 @@ namespace ts.FindAllReferences {
|
|||
const checker = program.getTypeChecker();
|
||||
for (const referencingFile of sourceFiles) {
|
||||
const searchSourceFile = searchModuleSymbol.valueDeclaration;
|
||||
if (searchSourceFile.kind === SyntaxKind.SourceFile) {
|
||||
if (searchSourceFile?.kind === SyntaxKind.SourceFile) {
|
||||
for (const ref of referencingFile.referencedFiles) {
|
||||
if (program.getSourceFileFromReference(referencingFile, ref) === searchSourceFile) {
|
||||
refs.push({ kind: "reference", referencingFile, ref });
|
||||
|
@ -582,7 +582,7 @@ namespace ts.FindAllReferences {
|
|||
return Debug.checkDefined(checker.getImmediateAliasedSymbol(importedSymbol));
|
||||
}
|
||||
|
||||
const decl = importedSymbol.valueDeclaration;
|
||||
const decl = Debug.checkDefined(importedSymbol.valueDeclaration);
|
||||
if (isExportAssignment(decl)) { // `export = class {}`
|
||||
return Debug.checkDefined(decl.expression.symbol);
|
||||
}
|
||||
|
|
|
@ -168,7 +168,7 @@ namespace ts.refactor {
|
|||
else if (isTypeQueryNode(node)) {
|
||||
if (isIdentifier(node.exprName)) {
|
||||
const symbol = checker.resolveName(node.exprName.text, node.exprName, SymbolFlags.Value, /* excludeGlobals */ false);
|
||||
if (symbol && rangeContainsSkipTrivia(statement, symbol.valueDeclaration, file) && !rangeContainsSkipTrivia(selection, symbol.valueDeclaration, file)) {
|
||||
if (symbol?.valueDeclaration && rangeContainsSkipTrivia(statement, symbol.valueDeclaration, file) && !rangeContainsSkipTrivia(selection, symbol.valueDeclaration, file)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2187,7 +2187,7 @@ declare namespace ts {
|
|||
* The function returns the value (local variable) symbol of an identifier in the short-hand property assignment.
|
||||
* This is necessary as an identifier in short-hand property assignment can contains two meaning: property name and property value.
|
||||
*/
|
||||
getShorthandAssignmentValueSymbol(location: Node): Symbol | undefined;
|
||||
getShorthandAssignmentValueSymbol(location: Node | undefined): Symbol | undefined;
|
||||
getExportSpecifierLocalTargetSymbol(location: ExportSpecifier | Identifier): Symbol | undefined;
|
||||
/**
|
||||
* If a symbol is a local symbol with an associated exported symbol, returns the exported symbol.
|
||||
|
@ -2409,7 +2409,7 @@ declare namespace ts {
|
|||
flags: SymbolFlags;
|
||||
escapedName: __String;
|
||||
declarations?: Declaration[];
|
||||
valueDeclaration: Declaration;
|
||||
valueDeclaration?: Declaration;
|
||||
members?: SymbolTable;
|
||||
exports?: SymbolTable;
|
||||
globalExports?: SymbolTable;
|
||||
|
@ -4107,7 +4107,7 @@ declare namespace ts {
|
|||
function idText(identifierOrPrivateName: Identifier | PrivateIdentifier): string;
|
||||
function symbolName(symbol: Symbol): string;
|
||||
function getNameOfJSDocTypedef(declaration: JSDocTypedefTag): Identifier | PrivateIdentifier | undefined;
|
||||
function getNameOfDeclaration(declaration: Declaration | Expression): DeclarationName | undefined;
|
||||
function getNameOfDeclaration(declaration: Declaration | Expression | undefined): DeclarationName | undefined;
|
||||
/**
|
||||
* Gets the JSDoc parameter tags for the node if present.
|
||||
*
|
||||
|
@ -4233,7 +4233,7 @@ declare namespace ts {
|
|||
function isEntityName(node: Node): node is EntityName;
|
||||
function isPropertyName(node: Node): node is PropertyName;
|
||||
function isBindingName(node: Node): node is BindingName;
|
||||
function isFunctionLike(node: Node): node is SignatureDeclaration;
|
||||
function isFunctionLike(node: Node | undefined): node is SignatureDeclaration;
|
||||
function isClassElement(node: Node): node is ClassElement;
|
||||
function isClassLike(node: Node): node is ClassLikeDeclaration;
|
||||
function isAccessor(node: Node): node is AccessorDeclaration;
|
||||
|
|
|
@ -2187,7 +2187,7 @@ declare namespace ts {
|
|||
* The function returns the value (local variable) symbol of an identifier in the short-hand property assignment.
|
||||
* This is necessary as an identifier in short-hand property assignment can contains two meaning: property name and property value.
|
||||
*/
|
||||
getShorthandAssignmentValueSymbol(location: Node): Symbol | undefined;
|
||||
getShorthandAssignmentValueSymbol(location: Node | undefined): Symbol | undefined;
|
||||
getExportSpecifierLocalTargetSymbol(location: ExportSpecifier | Identifier): Symbol | undefined;
|
||||
/**
|
||||
* If a symbol is a local symbol with an associated exported symbol, returns the exported symbol.
|
||||
|
@ -2409,7 +2409,7 @@ declare namespace ts {
|
|||
flags: SymbolFlags;
|
||||
escapedName: __String;
|
||||
declarations?: Declaration[];
|
||||
valueDeclaration: Declaration;
|
||||
valueDeclaration?: Declaration;
|
||||
members?: SymbolTable;
|
||||
exports?: SymbolTable;
|
||||
globalExports?: SymbolTable;
|
||||
|
@ -4107,7 +4107,7 @@ declare namespace ts {
|
|||
function idText(identifierOrPrivateName: Identifier | PrivateIdentifier): string;
|
||||
function symbolName(symbol: Symbol): string;
|
||||
function getNameOfJSDocTypedef(declaration: JSDocTypedefTag): Identifier | PrivateIdentifier | undefined;
|
||||
function getNameOfDeclaration(declaration: Declaration | Expression): DeclarationName | undefined;
|
||||
function getNameOfDeclaration(declaration: Declaration | Expression | undefined): DeclarationName | undefined;
|
||||
/**
|
||||
* Gets the JSDoc parameter tags for the node if present.
|
||||
*
|
||||
|
@ -4233,7 +4233,7 @@ declare namespace ts {
|
|||
function isEntityName(node: Node): node is EntityName;
|
||||
function isPropertyName(node: Node): node is PropertyName;
|
||||
function isBindingName(node: Node): node is BindingName;
|
||||
function isFunctionLike(node: Node): node is SignatureDeclaration;
|
||||
function isFunctionLike(node: Node | undefined): node is SignatureDeclaration;
|
||||
function isClassElement(node: Node): node is ClassElement;
|
||||
function isClassLike(node: Node): node is ClassLikeDeclaration;
|
||||
function isAccessor(node: Node): node is AccessorDeclaration;
|
||||
|
|
Loading…
Reference in a new issue