11import type { DependencyInfo , Extractor } from '#types/extractor'
22import type { Node } from 'jsonc-parser'
33import type { TextDocument } from 'vscode'
4+ import { isInRange } from '#utils/ast'
45import { createCachedParse } from '#utils/data'
56import { findNodeAtLocation , findNodeAtOffset , parseTree } from 'jsonc-parser'
67import { Range } from 'vscode'
78
8- const DEP_SECTIONS = [
9+ const DEPENDENCY_SECTIONS = [
910 'dependencies' ,
1011 'devDependencies' ,
1112 'peerDependencies' ,
@@ -17,58 +18,68 @@ export class JsonExtractor implements Extractor<Node> {
1718
1819 getNodeRange ( doc : TextDocument , node : Node ) {
1920 const start = doc . positionAt ( node . offset + 1 )
20- const end = doc . positionAt (
21- node . offset + node . length - 1 ,
22- )
21+ const end = doc . positionAt ( node . offset + node . length - 1 )
2322
2423 return new Range ( start , end )
2524 }
2625
27- inDependencySection ( root : Node , node : Node ) {
28- return DEP_SECTIONS . some ( ( section ) => {
26+ isInDependencySection ( root : Node , node : Node ) {
27+ return DEPENDENCY_SECTIONS . some ( ( section ) => {
2928 const dep = findNodeAtLocation ( root , [ section ] )
3029 if ( ! dep || ! dep . parent )
3130 return false
3231
3332 const { offset, length } = dep . parent . children ! [ 1 ]
3433
35- return node . offset > offset && node . offset < offset + length
34+ return isInRange ( node . offset , [ offset , offset + length ] )
3635 } )
3736 }
3837
38+ private parseDependencyNode ( node : Node ) : DependencyInfo < Node > | undefined {
39+ if ( ! node . children ?. length )
40+ return
41+
42+ const [ nameNode , versionNode ] = node . children
43+
44+ if (
45+ typeof nameNode ?. value !== 'string'
46+ || typeof versionNode . value !== 'string'
47+ ) {
48+ return
49+ }
50+
51+ return {
52+ nameNode,
53+ versionNode,
54+ name : nameNode . value ,
55+ version : versionNode . value ,
56+ }
57+ }
58+
3959 getDependenciesInfo ( root : Node ) {
40- const info : DependencyInfo < Node > [ ] = [ ]
60+ const result : DependencyInfo < Node > [ ] = [ ]
4161
42- DEP_SECTIONS . forEach ( ( section ) => {
62+ DEPENDENCY_SECTIONS . forEach ( ( section ) => {
4363 const node = findNodeAtLocation ( root , [ section ] )
4464 if ( ! node || ! node . children )
4565 return
4666
4767 for ( const dep of node . children ) {
48- const keyNode = dep . children ?. [ 0 ]
49- if ( ! keyNode || typeof keyNode . value !== 'string' )
50- continue
51-
52- info . push ( {
53- node : keyNode ,
54- name : keyNode . value ,
55- version : '' ,
56- } )
68+ const info = this . parseDependencyNode ( dep )
69+
70+ if ( info )
71+ result . push ( info )
5772 }
5873 } )
5974
60- return info
75+ return result
6176 }
6277
6378 getDependencyInfoByOffset ( root : Node , offset : number ) {
6479 const node = findNodeAtOffset ( root , offset )
65- if ( ! node || node . type !== 'string' || ! this . inDependencySection ( root , node ) )
80+ if ( ! node || node . type !== 'string' || ! this . isInDependencySection ( root , node ) )
6681 return
6782
68- return {
69- node,
70- name : node . parent ! . children ! [ 0 ] . value as string ,
71- version : node . value as string ,
72- }
83+ return this . parseDependencyNode ( node . parent ! )
7384 }
7485}
0 commit comments