@@ -13,6 +13,7 @@ import {
13
13
TokenKind ,
14
14
IPosition ,
15
15
OutlineTree ,
16
+ IRange ,
16
17
} from '../types' ;
17
18
18
19
import {
@@ -38,6 +39,7 @@ import {
38
39
FieldDefinitionNode ,
39
40
EnumValueDefinitionNode ,
40
41
InputObjectTypeDefinitionNode ,
42
+ Source as GraphQLSource ,
41
43
} from 'graphql' ;
42
44
import type { ASTReducer } from 'graphql/language/visitor' ;
43
45
@@ -105,16 +107,16 @@ type OutlineTreeConverterType = {
105
107
) => OutlineTreeResult ;
106
108
} ;
107
109
108
- export function getOutline ( documentText : string ) : Outline | null {
110
+ export function getOutline ( document : string | GraphQLSource ) : Outline | null {
109
111
let ast ;
110
112
try {
111
- ast = parse ( documentText ) ;
113
+ ast = parse ( document ) ;
112
114
} catch {
113
115
return null ;
114
116
}
115
117
116
118
type VisitorFns = Record < Kind , ( node : ASTNode ) => OutlineTreeResult > ;
117
- const visitorFns = outlineTreeConverter ( documentText ) as VisitorFns ;
119
+ const visitorFns = outlineTreeConverter ( document ) as VisitorFns ;
118
120
const outlineTrees = visit ( ast , {
119
121
leave ( node : ASTNode ) {
120
122
if ( node . kind in visitorFns ) {
@@ -127,13 +129,19 @@ export function getOutline(documentText: string): Outline | null {
127
129
return { outlineTrees } ;
128
130
}
129
131
130
- function outlineTreeConverter ( docText : string ) : OutlineTreeConverterType {
132
+ function outlineTreeConverter (
133
+ document : string | GraphQLSource ,
134
+ ) : OutlineTreeConverterType {
135
+ const docText = typeof document === 'string' ? document : document . body ;
136
+ const { locationOffset } : Partial < GraphQLSource > =
137
+ typeof document === 'string' ? { } : document ;
131
138
type MetaNode = Exclude <
132
139
OutlineableNode ,
133
140
DocumentNode | SelectionSetNode | NameNode | InlineFragmentNode
134
141
> ;
135
142
const meta = ( node : ExclusiveUnion < MetaNode > ) : OutlineTreeResultMeta => {
136
143
const range = locToRange ( docText , node . loc ! ) ;
144
+ applyOffsetToRange ( range , locationOffset ) ;
137
145
return {
138
146
representativeName : node . name ,
139
147
startPosition : range . start ,
@@ -250,3 +258,24 @@ function concatMap<V>(arr: Readonly<V[]>, fn: Function): Readonly<V[]> {
250
258
}
251
259
return res ;
252
260
}
261
+
262
+ function applyOffsetToRange (
263
+ range : IRange ,
264
+ locationOffset ?: GraphQLSource [ 'locationOffset' ] ,
265
+ ) {
266
+ if ( ! locationOffset ) {
267
+ return ;
268
+ }
269
+ applyOffsetToPosition ( range . start , locationOffset ) ;
270
+ applyOffsetToPosition ( range . end , locationOffset ) ;
271
+ }
272
+
273
+ function applyOffsetToPosition (
274
+ position : IPosition ,
275
+ locationOffset : GraphQLSource [ 'locationOffset' ] ,
276
+ ) {
277
+ if ( position . line === 1 ) {
278
+ position . character += locationOffset . column - 1 ;
279
+ }
280
+ position . line += locationOffset . line - 1 ;
281
+ }
0 commit comments