Merge pull request #16031 from Microsoft/isWriteAccess
findAllReferences: Make "isWriteAccess" handle special declaration kinds
This commit is contained in:
commit
23b2545586
|
@ -12750,7 +12750,7 @@ namespace ts {
|
|||
function getContextualTypeForBinaryOperand(node: Expression): Type {
|
||||
const binaryExpression = <BinaryExpression>node.parent;
|
||||
const operator = binaryExpression.operatorToken.kind;
|
||||
if (operator >= SyntaxKind.FirstAssignment && operator <= SyntaxKind.LastAssignment) {
|
||||
if (isAssignmentOperator(operator)) {
|
||||
// Don't do this for special property assignments to avoid circularity
|
||||
if (getSpecialPropertyAssignmentKind(binaryExpression) !== SpecialPropertyAssignmentKind.None) {
|
||||
return undefined;
|
||||
|
@ -17305,7 +17305,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function checkAssignmentOperator(valueType: Type): void {
|
||||
if (produceDiagnostics && operator >= SyntaxKind.FirstAssignment && operator <= SyntaxKind.LastAssignment) {
|
||||
if (produceDiagnostics && isAssignmentOperator(operator)) {
|
||||
// TypeScript 1.0 spec (April 2014): 4.17
|
||||
// An assignment of the form
|
||||
// VarExpr = ValueExpr
|
||||
|
|
|
@ -1785,6 +1785,23 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
// See GH#16030
|
||||
export function isAnyDeclarationName(name: Node): boolean {
|
||||
switch (name.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
if (isDeclaration(name.parent)) {
|
||||
return name.parent.name === name;
|
||||
}
|
||||
const binExp = name.parent.parent;
|
||||
return isBinaryExpression(binExp) && getSpecialPropertyAssignmentKind(binExp) !== SpecialPropertyAssignmentKind.None && getNameOfDeclaration(binExp) === name;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function isLiteralComputedPropertyDeclarationName(node: Node) {
|
||||
return (node.kind === SyntaxKind.StringLiteral || node.kind === SyntaxKind.NumericLiteral) &&
|
||||
node.parent.kind === SyntaxKind.ComputedPropertyName &&
|
||||
|
|
|
@ -176,7 +176,7 @@ namespace ts.FindAllReferences {
|
|||
fileName: node.getSourceFile().fileName,
|
||||
textSpan: getTextSpan(node),
|
||||
isWriteAccess: isWriteAccess(node),
|
||||
isDefinition: isDeclarationName(node) || isLiteralComputedPropertyDeclarationName(node),
|
||||
isDefinition: isAnyDeclarationName(node) || isLiteralComputedPropertyDeclarationName(node),
|
||||
isInString
|
||||
};
|
||||
}
|
||||
|
@ -242,22 +242,20 @@ namespace ts.FindAllReferences {
|
|||
|
||||
/** A node is considered a writeAccess iff it is a name of a declaration or a target of an assignment */
|
||||
function isWriteAccess(node: Node): boolean {
|
||||
if (node.kind === SyntaxKind.Identifier && isDeclarationName(node)) {
|
||||
if (isAnyDeclarationName(node)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const parent = node.parent;
|
||||
if (parent) {
|
||||
if (parent.kind === SyntaxKind.PostfixUnaryExpression || parent.kind === SyntaxKind.PrefixUnaryExpression) {
|
||||
const { parent } = node;
|
||||
switch (parent && parent.kind) {
|
||||
case SyntaxKind.PostfixUnaryExpression:
|
||||
case SyntaxKind.PrefixUnaryExpression:
|
||||
return true;
|
||||
}
|
||||
else if (parent.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>parent).left === node) {
|
||||
const operator = (<BinaryExpression>parent).operatorToken.kind;
|
||||
return SyntaxKind.FirstAssignment <= operator && operator <= SyntaxKind.LastAssignment;
|
||||
}
|
||||
case SyntaxKind.BinaryExpression:
|
||||
return (<BinaryExpression>parent).left === node && isAssignmentOperator((<BinaryExpression>parent).operatorToken.kind);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
// @Filename: /b.ts
|
||||
/////// <reference types="[|foo|]" />
|
||||
////import { x } from "[|foo|]";
|
||||
////declare module "[|{| "isDefinition": true |}foo|]" {}
|
||||
////declare module "[|{| "isWriteAccess": true, "isDefinition": true |}foo|]" {}
|
||||
|
||||
verify.noErrors();
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
////let o = { [|{| "isDefinition": true |}1|]: 12 };
|
||||
////let o = { [|{| "isWriteAccess": true, "isDefinition": true |}1|]: 12 };
|
||||
////let y = o[[|1|]];
|
||||
|
||||
const ranges = test.ranges();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
////let o = { "[|{| "isDefinition": true |}x|]": 12 };
|
||||
////let o = { "[|{| "isWriteAccess": true, "isDefinition": true |}x|]": 12 };
|
||||
////let y = o.[|x|];
|
||||
|
||||
const ranges = test.ranges();
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
////function blah2() { container["[|searchProp|]"] };
|
||||
|
||||
// @Filename: redeclaration.ts
|
||||
////container = { "[|{| "isDefinition": true |}searchProp|]" : 18 };
|
||||
////container = { "[|{| "isWriteAccess": true, "isDefinition": true |}searchProp|]" : 18 };
|
||||
|
||||
const ranges = test.ranges();
|
||||
const [r0, r1, r2, r3] = ranges;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// Ensure BloomFilter building logic is correct, by having one reference per file
|
||||
|
||||
// @Filename: declaration.ts
|
||||
////var container = { [|{| "isDefinition": true |}42|]: 1 };
|
||||
////var container = { [|{| "isWriteAccess": true, "isDefinition": true |}42|]: 1 };
|
||||
|
||||
// @Filename: expression.ts
|
||||
////function blah() { return (container[[|42|]]) === 2; };
|
||||
|
@ -12,7 +12,7 @@
|
|||
////function blah2() { container["[|42|]"] };
|
||||
|
||||
// @Filename: redeclaration.ts
|
||||
////container = { "[|{| "isDefinition": true |}42|]" : 18 };
|
||||
////container = { "[|{| "isWriteAccess": true, "isDefinition": true |}42|]" : 18 };
|
||||
|
||||
const ranges = test.ranges();
|
||||
const [r0, r1, r2, r3] = ranges;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
|
||||
// @Filename: declaration.ts
|
||||
////enum Test { "[|{| "isDefinition": true |}42|]" = 1 };
|
||||
////enum Test { "[|{| "isWriteAccess": true, "isDefinition": true |}42|]" = 1 };
|
||||
|
||||
// @Filename: expression.ts
|
||||
////(Test[[|42|]]);
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////declare module "[|{| "isDefinition": true |}foo|]" {
|
||||
////declare module "[|{| "isWriteAccess": true, "isDefinition": true |}foo|]" {
|
||||
//// var [|{| "isWriteAccess": true, "isDefinition": true |}f|]: number;
|
||||
////}
|
||||
////
|
||||
////declare module "[|{| "isDefinition": true |}bar|]" {
|
||||
////declare module "[|{| "isWriteAccess": true, "isDefinition": true |}bar|]" {
|
||||
//// export import [|{| "isWriteAccess": true, "isDefinition": true |}foo|] = require("[|foo|]");
|
||||
//// var f2: typeof [|foo|].[|f|];
|
||||
////}
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
////enum E {
|
||||
//// [|{| "isWriteAccess": true, "isDefinition": true |}value1|] = 1,
|
||||
//// "[|{| "isDefinition": true |}value2|]" = [|value1|],
|
||||
//// [|{| "isDefinition": true |}111|] = 11
|
||||
//// "[|{| "isWriteAccess": true, "isDefinition": true |}value2|]" = [|value1|],
|
||||
//// [|{| "isWriteAccess": true, "isDefinition": true |}111|] = 11
|
||||
////}
|
||||
////
|
||||
////E.[|value1|];
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// Global interface reference.
|
||||
|
||||
// @Filename: referencesForGlobals_1.ts
|
||||
////declare module "[|{| "isDefinition": true |}foo|]" {
|
||||
////declare module "[|{| "isWriteAccess": true, "isDefinition": true |}foo|]" {
|
||||
//// var f: number;
|
||||
////}
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////class Foo {
|
||||
//// public [|{| "isDefinition": true |}12|]: any;
|
||||
//// public [|{| "isWriteAccess": true, "isDefinition": true |}12|]: any;
|
||||
////}
|
||||
////
|
||||
////var x: Foo;
|
||||
////x[[|12|]];
|
||||
////x = { "[|{| "isDefinition": true |}12|]": 0 };
|
||||
////x = { [|{| "isDefinition": true |}12|]: 0 };
|
||||
////x = { "[|{| "isWriteAccess": true, "isDefinition": true |}12|]": 0 };
|
||||
////x = { [|{| "isWriteAccess": true, "isDefinition": true |}12|]: 0 };
|
||||
|
||||
//verify.singleReferenceGroup("(property) Foo[12]: any");
|
||||
const ranges = test.ranges();
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////class Foo {
|
||||
//// public "[|{| "isDefinition": true |}ss|]": any;
|
||||
//// public "[|{| "isWriteAccess": true, "isDefinition": true |}ss|]": any;
|
||||
////}
|
||||
////
|
||||
////var x: Foo;
|
||||
////x.[|ss|];
|
||||
////x["[|ss|]"];
|
||||
////x = { "[|{| "isDefinition": true |}ss|]": 0 };
|
||||
////x = { "[|{| "isWriteAccess": true, "isDefinition": true |}ss|]": 0 };
|
||||
////x = { [|{| "isWriteAccess": true, "isDefinition": true |}ss|]: 0 };
|
||||
|
||||
const ranges = test.ranges();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////class Foo {
|
||||
//// "[|{| "isDefinition": true |}blah|]"() { return 0; }
|
||||
//// "[|{| "isWriteAccess": true, "isDefinition": true |}blah|]"() { return 0; }
|
||||
////}
|
||||
////
|
||||
////var x: Foo;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////class Foo2 {
|
||||
//// get "[|{| "isDefinition": true |}42|]"() { return 0; }
|
||||
//// set [|{| "isDefinition": true |}42|](n) { }
|
||||
//// get "[|{| "isWriteAccess": true, "isDefinition": true |}42|]"() { return 0; }
|
||||
//// set [|{| "isWriteAccess": true, "isDefinition": true |}42|](n) { }
|
||||
////}
|
||||
////
|
||||
////var y: Foo2;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////var x = { "[|{| "isDefinition": true |}someProperty|]": 0 }
|
||||
////var x = { "[|{| "isWriteAccess": true, "isDefinition": true |}someProperty|]": 0 }
|
||||
////x["[|someProperty|]"] = 3;
|
||||
////x.[|someProperty|] = 5;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
// @allowJs: true
|
||||
// @Filename: a.js
|
||||
////exports.[|area|] = function (r) { return r * r; }
|
||||
////exports.[|{| "isWriteAccess": true, "isDefinition": true |}area|] = function (r) { return r * r; }
|
||||
|
||||
// @Filename: b.js
|
||||
////var mod = require('./a');
|
||||
|
|
Loading…
Reference in a new issue