Handle parentless nodes in isParameterPropertyDeclaration

Fixes #33295.

This follows a similar pattern as in #20314 by requiring an explicit
`parent` parameter. Where possible, it uses the appopriate variable at
the call sites.

In several locations there is no context available though (e.g.
inspecting `valueDeclarations`) and we access `.parent` as the code
previously did. From a cursory inspection this seems correct, these
callpaths originate in phases where there must be a `parent` (i.e. in
checker, binder, etc).

Change-Id: I28e4726777b57237bec776e4001e9e69ac591b11
This commit is contained in:
Martin Probst
2019-09-09 14:08:00 +02:00
committed by Daniel Rosenwasser
parent 2f8832cccc
commit 6bb7e5c086
13 changed files with 64 additions and 18 deletions

View File

@@ -1145,7 +1145,7 @@ namespace ts.FindAllReferences.Core {
}
export function eachSymbolReferenceInFile<T>(definition: Identifier, checker: TypeChecker, sourceFile: SourceFile, cb: (token: Identifier) => T): T | undefined {
const symbol = isParameterPropertyDeclaration(definition.parent)
const symbol = isParameterPropertyDeclaration(definition.parent, definition.parent.parent)
? first(checker.getSymbolsOfParameterPropertyDeclaration(definition.parent, definition.text))
: checker.getSymbolAtLocation(definition);
if (!symbol) return undefined;
@@ -1886,7 +1886,7 @@ namespace ts.FindAllReferences.Core {
const res = fromRoot(symbol);
if (res) return res;
if (symbol.valueDeclaration && isParameterPropertyDeclaration(symbol.valueDeclaration)) {
if (symbol.valueDeclaration && isParameterPropertyDeclaration(symbol.valueDeclaration, symbol.valueDeclaration.parent)) {
// For a parameter property, now try on the other symbol (property if this was a parameter, parameter if this was a property).
const paramProps = checker.getSymbolsOfParameterPropertyDeclaration(cast(symbol.valueDeclaration, isParameter), symbol.name);
Debug.assert(paramProps.length === 2 && !!(paramProps[0].flags & SymbolFlags.FunctionScopedVariable) && !!(paramProps[1].flags & SymbolFlags.Property)); // is [parameter, property]

View File

@@ -197,7 +197,7 @@ namespace ts.NavigationBar {
// Parameter properties are children of the class, not the constructor.
for (const param of ctr.parameters) {
if (isParameterPropertyDeclaration(param)) {
if (isParameterPropertyDeclaration(param, ctr)) {
addLeafNode(param);
}
}

View File

@@ -92,7 +92,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
}
function isAcceptedDeclaration(node: Node): node is AcceptedDeclaration {
return isParameterPropertyDeclaration(node) || isPropertyDeclaration(node) || isPropertyAssignment(node);
return isParameterPropertyDeclaration(node, node.parent) || isPropertyDeclaration(node) || isPropertyAssignment(node);
}
function createPropertyName (name: string, originalName: AcceptedNameType) {
@@ -214,7 +214,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
}
function insertAccessor(changeTracker: textChanges.ChangeTracker, file: SourceFile, accessor: AccessorDeclaration, declaration: AcceptedDeclaration, container: ContainerDeclaration) {
isParameterPropertyDeclaration(declaration) ? changeTracker.insertNodeAtClassStart(file, <ClassLikeDeclaration>container, accessor) :
isParameterPropertyDeclaration(declaration, declaration.parent) ? changeTracker.insertNodeAtClassStart(file, <ClassLikeDeclaration>container, accessor) :
isPropertyAssignment(declaration) ? changeTracker.insertNodeAfterComma(file, declaration, accessor) :
changeTracker.insertNodeAfter(file, declaration, accessor);
}