|
1 | 1 | interface TypeWriterResult { |
2 | 2 | line: number; |
3 | | - column: number; |
4 | 3 | syntaxKind: number; |
5 | 4 | sourceText: string; |
6 | 5 | type: string; |
@@ -29,90 +28,43 @@ class TypeWriterWalker { |
29 | 28 | } |
30 | 29 |
|
31 | 30 | private visitNode(node: ts.Node): void { |
32 | | - switch (node.kind) { |
33 | | - // Should always log expressions that are not tokens |
34 | | - // Also, always log the "this" keyword |
35 | | - // TODO: Ideally we should log all expressions, but to compare to the |
36 | | - // old typeWriter baselines, suppress tokens |
37 | | - case ts.SyntaxKind.ThisKeyword: |
38 | | - case ts.SyntaxKind.SuperKeyword: |
39 | | - case ts.SyntaxKind.ArrayLiteralExpression: |
40 | | - case ts.SyntaxKind.ObjectLiteralExpression: |
41 | | - case ts.SyntaxKind.ElementAccessExpression: |
42 | | - case ts.SyntaxKind.CallExpression: |
43 | | - case ts.SyntaxKind.NewExpression: |
44 | | - case ts.SyntaxKind.TypeAssertionExpression: |
45 | | - case ts.SyntaxKind.ParenthesizedExpression: |
46 | | - case ts.SyntaxKind.FunctionExpression: |
47 | | - case ts.SyntaxKind.ArrowFunction: |
48 | | - case ts.SyntaxKind.TypeOfExpression: |
49 | | - case ts.SyntaxKind.VoidExpression: |
50 | | - case ts.SyntaxKind.DeleteExpression: |
51 | | - case ts.SyntaxKind.PrefixUnaryExpression: |
52 | | - case ts.SyntaxKind.PostfixUnaryExpression: |
53 | | - case ts.SyntaxKind.BinaryExpression: |
54 | | - case ts.SyntaxKind.ConditionalExpression: |
55 | | - case ts.SyntaxKind.SpreadElementExpression: |
56 | | - this.log(node, this.getTypeOfNode(node)); |
57 | | - break; |
58 | | - |
59 | | - case ts.SyntaxKind.PropertyAccessExpression: |
60 | | - for (var current = node; current.kind === ts.SyntaxKind.PropertyAccessExpression; current = current.parent) { |
61 | | - } |
62 | | - if (current.kind !== ts.SyntaxKind.HeritageClauseElement) { |
63 | | - this.log(node, this.getTypeOfNode(node)); |
64 | | - } |
65 | | - break; |
66 | | - |
67 | | - // Should not change expression status (maybe expressions) |
68 | | - // TODO: Again, ideally should log number and string literals too, |
69 | | - // but to be consistent with the old typeWriter, just log identifiers |
70 | | - case ts.SyntaxKind.Identifier: |
71 | | - var identifier = <ts.Identifier>node; |
72 | | - if (!this.isLabel(identifier)) { |
73 | | - var type = this.getTypeOfNode(identifier); |
74 | | - this.log(node, type); |
75 | | - } |
76 | | - break; |
| 31 | + if (ts.isExpression(node) || node.kind === ts.SyntaxKind.Identifier) { |
| 32 | + this.logTypeAndSymbol(node); |
77 | 33 | } |
78 | 34 |
|
79 | 35 | ts.forEachChild(node, child => this.visitNode(child)); |
80 | 36 | } |
81 | 37 |
|
82 | | - private isLabel(identifier: ts.Identifier): boolean { |
83 | | - var parent = identifier.parent; |
84 | | - switch (parent.kind) { |
85 | | - case ts.SyntaxKind.ContinueStatement: |
86 | | - case ts.SyntaxKind.BreakStatement: |
87 | | - return (<ts.BreakOrContinueStatement>parent).label === identifier; |
88 | | - case ts.SyntaxKind.LabeledStatement: |
89 | | - return (<ts.LabeledStatement>parent).label === identifier; |
90 | | - } |
91 | | - return false; |
92 | | - } |
93 | | - |
94 | | - private log(node: ts.Node, type: ts.Type): void { |
| 38 | + private logTypeAndSymbol(node: ts.Node): void { |
95 | 39 | var actualPos = ts.skipTrivia(this.currentSourceFile.text, node.pos); |
96 | 40 | var lineAndCharacter = this.currentSourceFile.getLineAndCharacterOfPosition(actualPos); |
97 | 41 | var sourceText = ts.getTextOfNodeFromSourceText(this.currentSourceFile.text, node); |
98 | | - |
99 | | - // If we got an unknown type, we temporarily want to fall back to just pretending the name |
100 | | - // (source text) of the node is the type. This is to align with the old typeWriter to make |
101 | | - // baseline comparisons easier. In the long term, we will want to just call typeToString |
| 42 | + |
| 43 | + var type = this.checker.getTypeAtLocation(node); |
| 44 | + ts.Debug.assert(type !== undefined, "type doesn't exist"); |
| 45 | + var symbol = this.checker.getSymbolAtLocation(node); |
| 46 | + |
| 47 | + var typeString = this.checker.typeToString(type, node.parent, ts.TypeFormatFlags.NoTruncation); |
| 48 | + if (symbol) { |
| 49 | + var symbolString = "Symbol(" + this.checker.symbolToString(symbol, node.parent); |
| 50 | + if (symbol.declarations) { |
| 51 | + for (let declaration of symbol.declarations) { |
| 52 | + symbolString += ", "; |
| 53 | + let declSourceFile = declaration.getSourceFile(); |
| 54 | + let declLineAndCharacter = declSourceFile.getLineAndCharacterOfPosition(declaration.pos); |
| 55 | + symbolString += `Decl(${ ts.getBaseFileName(declSourceFile.fileName) }, ${ declLineAndCharacter.line }, ${ declLineAndCharacter.character })` |
| 56 | + } |
| 57 | + } |
| 58 | + symbolString += ")"; |
| 59 | + |
| 60 | + typeString += ", " + symbolString; |
| 61 | + } |
| 62 | + |
102 | 63 | this.results.push({ |
103 | 64 | line: lineAndCharacter.line, |
104 | | - // todo(cyrusn): Not sure why column is one-based for type-writer. But I'm preserving |
105 | | - // that behavior to prevent having a lot of baselines to fix up. |
106 | | - column: lineAndCharacter.character + 1, |
107 | 65 | syntaxKind: node.kind, |
108 | 66 | sourceText: sourceText, |
109 | | - type: this.checker.typeToString(type, node.parent, ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.WriteOwnNameForAnyLike) |
| 67 | + type: typeString |
110 | 68 | }); |
111 | 69 | } |
112 | | - |
113 | | - private getTypeOfNode(node: ts.Node): ts.Type { |
114 | | - var type = this.checker.getTypeAtLocation(node); |
115 | | - ts.Debug.assert(type !== undefined, "type doesn't exist"); |
116 | | - return type; |
117 | | - } |
118 | 70 | } |
0 commit comments