Get quickInfo from a contextual type if possible (#18119)

This commit is contained in:
Andy 2017-09-07 07:22:39 -07:00 committed by GitHub
parent 8c714c3651
commit 0434fe797a
6 changed files with 56 additions and 28 deletions

View File

@ -744,6 +744,7 @@ namespace ts {
;
export interface PropertyAssignment extends ObjectLiteralElement {
parent: ObjectLiteralExpression;
kind: SyntaxKind.PropertyAssignment;
name: PropertyName;
questionToken?: QuestionToken;
@ -751,6 +752,7 @@ namespace ts {
}
export interface ShorthandPropertyAssignment extends ObjectLiteralElement {
parent: ObjectLiteralExpression;
kind: SyntaxKind.ShorthandPropertyAssignment;
name: Identifier;
questionToken?: QuestionToken;
@ -761,6 +763,7 @@ namespace ts {
}
export interface SpreadAssignment extends ObjectLiteralElement {
parent: ObjectLiteralExpression;
kind: SyntaxKind.SpreadAssignment;
expression: Expression;
}

View File

@ -1398,7 +1398,7 @@ namespace ts {
}
const typeChecker = program.getTypeChecker();
const symbol = typeChecker.getSymbolAtLocation(node);
const symbol = getSymbolAtLocationForQuickInfo(node, typeChecker);
if (!symbol || typeChecker.isUnknownSymbol(symbol)) {
// Try getting just type at this position and show
@ -1437,6 +1437,21 @@ namespace ts {
};
}
function getSymbolAtLocationForQuickInfo(node: Node, checker: TypeChecker): Symbol | undefined {
if ((isIdentifier(node) || isStringLiteral(node))
&& isPropertyAssignment(node.parent)
&& node.parent.name === node) {
const type = checker.getContextualType(node.parent.parent);
if (type) {
const property = checker.getPropertyOfType(type, getTextOfIdentifierOrLiteral(node));
if (property) {
return property;
}
}
}
return checker.getSymbolAtLocation(node);
}
/// Goto definition
function getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] {
synchronizeHostData();

View File

@ -32,7 +32,7 @@
////var /*13*/c3t5: (n: number) => IFoo = function(/*14*/n) { return <IFoo>({}) };
////var /*15*/c3t6: (n: number, s: string) => IFoo = function(/*16*/n, /*17*/s) { return <IFoo>({}) };
////var /*18*/c3t7: {
//// (n: number): number;
//// (n: number): number;
//// (s1: string): number;
////};
////var /*20*/c3t8: (n: number, s: string) => number = function(/*21*/n) { return n; };
@ -79,7 +79,7 @@
//// t5: (n: number) => IFoo;
//// t6: (n: number, s: string) => IFoo;
//// t7: {
//// (n: number, s: string): number;
//// (n: number, s: string): number;
//// //(s1: string, s2: string): number;
//// };
//// t8: (n: number, s: string) => number;
@ -98,7 +98,7 @@
//// t5: (n: number) => IFoo;
//// t6: (n: number, s: string) => IFoo;
//// t7: {
//// (n: number, s: string): number;
//// (n: number, s: string): number;
//// //(s1: string, s2: string): number;
//// };
//// t8: (n: number, s: string) => number;
@ -152,7 +152,7 @@
////var /*80*/c12t5 = <(n: number) => IFoo> function(/*81*/n) { return <IFoo>({}) };
////var /*82*/c12t6 = <(n: number, s: string) => IFoo> function(/*83*/n, /*84*/s) { return <IFoo>({}) };
////var /*85*/c12t7 = <{
//// (n: number, s: string): number;
//// (n: number, s: string): number;
//// //(s1: string, s2: string): number;
////}> function(n:number) { return n };
////var /*86*/c12t8 = <(n: number, s: string) => number> function (/*87*/n) { return n; };
@ -221,13 +221,13 @@ verify.quickInfos({
25: "(parameter) n: number",
26: "(parameter) s: string",
27: "var c3t12: IBar",
28: "(property) foo: IFoo",
28: "(property) IBar.foo: IFoo",
29: "var c3t13: IFoo",
30: "(property) f: (i: number, s: string) => string",
30: "(method) IFoo.f(i: number, s: string): string",
31: "(parameter) i: number",
32: "(parameter) s: string",
33: "var c3t14: IFoo",
34: "(property) a: undefined[]",
34: "(property) IFoo.a: number[]",
35: "(property) C4T5.foo: (i: number, s: string) => string",
36: "(parameter) i: number",
37: "(parameter) s: string",
@ -257,13 +257,13 @@ verify.quickInfos({
61: "(parameter) n: number",
62: "(parameter) s: string",
63: "(property) t12: IBar",
64: "(property) foo: IFoo",
64: "(property) IBar.foo: IFoo",
65: "(property) t13: IFoo",
66: "(property) f: (i: number, s: string) => string",
66: "(method) IFoo.f(i: number, s: string): string",
67: "(parameter) i: number",
68: "(parameter) s: string",
69: "(property) t14: IFoo",
70: "(property) a: undefined[]",
70: "(property) IFoo.a: number[]",
71: "(parameter) n: number",
72: "var c10t5: () => (n: number) => IFoo",
73: "(parameter) n: number",
@ -287,13 +287,13 @@ verify.quickInfos({
91: "(parameter) n: number",
92: "(parameter) s: string",
93: "var c12t12: IBar",
94: "(property) foo: IFoo",
94: "(property) IBar.foo: IFoo",
95: "var c12t13: IFoo",
96: "(property) f: (i: number, s: string) => string",
96: "(method) IFoo.f(i: number, s: string): string",
97: "(parameter) i: number",
98: "(parameter) s: string",
99: "var c12t14: IFoo",
100: "(property) a: undefined[]",
100: "(property) IFoo.a: number[]",
101: "function EF1(a: number, b: number): number",
102: "(parameter) a: any",
103: "(parameter) b: any",
@ -302,7 +302,7 @@ verify.quickInfos({
112: "(method) Point.add(dx: number, dy: number): Point",
113: "(parameter) dx: number",
114: "(parameter) dy: number",
115: "(property) add: (dx: number, dy: number) => Point",
115: "(method) Point.add(dx: number, dy: number): Point",
116: "(parameter) dx: number",
117: "(parameter) dy: number"
});

View File

@ -0,0 +1,10 @@
/// <reference path='fourslash.ts' />
// @Filename: quickInfoExportAssignmentOfGenericInterface_0.ts
////interface I {
//// /** Documentation */
//// x: number;
////}
////const i: I = { /**/x: 0 };
verify.quickInfoAt("", "(property) I.x: number", "Documentation ");

View File

@ -1,16 +1,16 @@
/// <reference path="fourslash.ts" />
////module Test {
//// class Mocked {
//// myProp: string;
//// }
//// class Tester {
//// willThrowError() {
//// Mocked = Mocked || function () { // => Error: Invalid left-hand side of assignment expression.
//// return { /**/myProp: "test" };
//// };
//// }
//// }
//// class Mocked {
//// myProp: string;
//// }
//// class Tester {
//// willThrowError() {
//// Mocked = Mocked || function () { // => Error: Invalid left-hand side of assignment expression.
//// return { /**/myProp: "test" };
//// };
//// }
//// }
////}
verify.quickInfoAt("", "(property) myProp: string");
verify.quickInfoAt("", "(property) myProp: string");

View File

@ -5,6 +5,6 @@
//// f() {}
////});
// The symbol indicates that this is a funciton, but the type is `any`.
// The symbol indicates that this is a function, but the type is `any`.
// Regression test that we don't crash (by trying to get signatures from `any`).
verify.quickInfoAt("", "(method) f");
verify.quickInfoAt("", "(method) f(): void");