@@ -110,26 +110,25 @@ export interface Node extends TextRange {
110110}
111111
112112export function createNode ( kind : SyntaxKind , tsOriginal ?: ts . Node , parent ?: Node ) : Node {
113- let line : number | undefined ;
114- let column : number | undefined ;
115- // TODO figure out why tsOriginal.getSourceFile()
116- // can return udnefined in the first place instead of catching it here
117- if ( tsOriginal && tsOriginal . getSourceFile ( ) ) {
118- const lineAndCharacter = ts . getLineAndCharacterOfPosition ( tsOriginal . getSourceFile ( ) , tsOriginal . pos ) ;
119- line = lineAndCharacter . line ;
120- column = lineAndCharacter . character ;
113+ const sourcePosition = getSourcePosition ( tsOriginal ) ;
114+ if ( sourcePosition ) {
115+ return { kind, parent, line : sourcePosition . line , column : sourcePosition . column } ;
116+ } else {
117+ return { kind, parent} ;
121118 }
122- return { kind, parent, line, column} ;
123119}
124120
125121export function cloneNode < T extends Node > ( node : T ) : T {
126122 return Object . assign ( { } , node ) ;
127123}
128124
129125export function setNodeOriginal < T extends Node > ( node : T , tsOriginal : ts . Node ) : T {
130- const lineAndCharacter = ts . getLineAndCharacterOfPosition ( tsOriginal . getSourceFile ( ) , tsOriginal . pos ) ;
131- node . line = lineAndCharacter . line ;
132- node . column = lineAndCharacter . character ;
126+ const sourcePosition = getSourcePosition ( tsOriginal ) ;
127+ if ( sourcePosition ) {
128+ node . line = sourcePosition . line ;
129+ node . line = sourcePosition . line ;
130+ }
131+
133132 return node ;
134133}
135134
@@ -140,20 +139,32 @@ export function setParent(node: Node | Node[] | undefined, parent: Node): void
140139 if ( Array . isArray ( node ) ) {
141140 node . forEach ( n => {
142141 n . parent = parent ;
143- if ( ! n . line || ! n . column ) {
144- n . line = parent . line ;
145- n . column = parent . column ;
146- }
147142 } ) ;
148143 } else {
149144 node . parent = parent ;
150- if ( ! node . line || ! node . column ) {
151- node . line = parent . line ;
152- node . column = parent . column ;
153- }
154145 }
155146}
156147
148+ function getSourcePosition ( sourceNode : ts . Node ) : TextRange | undefined {
149+ if ( sourceNode !== undefined && sourceNode . getSourceFile ( ) !== undefined && sourceNode . pos >= 0 ) {
150+
151+ const { line, character } = ts . getLineAndCharacterOfPosition (
152+ sourceNode . getSourceFile ( ) ,
153+ sourceNode . pos + sourceNode . getLeadingTriviaWidth ( )
154+ ) ;
155+
156+ return { line, column : character } ;
157+ }
158+ }
159+
160+ export function getOriginalPos ( node : Node ) : TextRange {
161+ while ( node . line === undefined && node . parent !== undefined ) {
162+ node = node . parent ;
163+ }
164+
165+ return { line : node . line , column : node . column } ;
166+ }
167+
157168export interface Block extends Node {
158169 kind : SyntaxKind . Block ;
159170 statements ?: Statement [ ] ;
@@ -816,8 +827,8 @@ export function createIdentifier(
816827 return expression ;
817828}
818829
819- export function cloneIdentifier ( identifier : Identifier ) : Identifier {
820- return createIdentifier ( identifier . text , undefined , identifier . symbolId ) ;
830+ export function cloneIdentifier ( identifier : Identifier , tsOriginal ?: ts . Node ) : Identifier {
831+ return createIdentifier ( identifier . text , tsOriginal , identifier . symbolId ) ;
821832}
822833
823834export function createAnnonymousIdentifier ( tsOriginal ?: ts . Node , parent ?: Node ) : Identifier {
0 commit comments