1+ import * as vscode from 'vscode' ;
2+ import * as path from 'path' ;
3+ import { DocumentSymbol , SymbolKind } from "vscode-languageclient" ;
4+ import { IMethodExtractor , SymbolInfo } from "../extractors" ;
5+ import { Logger } from '../../logger' ;
6+
7+ export class GoMethodExtractor implements IMethodExtractor {
8+ public async extractMethods ( document : vscode . TextDocument , docSymbols : DocumentSymbol [ ] ) : Promise < SymbolInfo [ ] > {
9+ const methodSymbols = docSymbols . filter ( s => s . kind + 1 === SymbolKind . Method || s . kind + 1 === SymbolKind . Function ) ;
10+ if ( ! methodSymbols . length )
11+ return [ ] ;
12+
13+ const modFiles = await vscode . workspace . findFiles ( '**/go.mod' ) ;
14+ const modFile = modFiles . find ( f => document . uri . path . startsWith ( path . dirname ( f . path ) ) )
15+ if ( ! modFile ) {
16+ Logger . warn ( `Could not resolve mod file for '${ document . uri . path } '` )
17+ return [ ] ;
18+ }
19+
20+ const modFolder = path . dirname ( modFile . path ) ;
21+ const docFolder = path . dirname ( document . uri . path ) ;
22+ let packageName = '' ;
23+ if ( modFolder === docFolder ) {
24+ const match = document . getText ( ) . match ( / ^ p a c k a g e ( .+ ) $ / m) ;
25+ if ( ! match ) {
26+ Logger . warn ( `Could not found packakge name in '${ document . uri . path } '` )
27+ return [ ] ;
28+ }
29+ packageName = match [ 1 ] ;
30+ }
31+ if ( ! packageName || packageName !== 'main' ) {
32+ const modDocument = await vscode . workspace . openTextDocument ( modFile ) ;
33+ const match = modDocument . getText ( ) . match ( / ^ m o d u l e ( .+ ) $ / m) ;
34+ if ( ! match ) {
35+ Logger . warn ( `Could not found module name in '${ modFile . path } '` )
36+ return [ ] ;
37+ }
38+ packageName = match [ 1 ]
39+
40+ if ( modFolder !== docFolder )
41+ packageName += '/' + path . relative ( modFolder , docFolder ) ;
42+ }
43+
44+ const methods : SymbolInfo [ ] = methodSymbols . map ( s => {
45+ return {
46+ id : packageName + '$_$' + s . name ,
47+ name : s . name ,
48+ displayName : packageName . split ( '/' ) . lastOrDefault ( ) + '.' + s . name ,
49+ documentUri : document . uri ,
50+ codeLocation : packageName ,
51+ range : new vscode . Range (
52+ new vscode . Position ( s . range . start . line , s . range . start . character ) ,
53+ new vscode . Position ( s . range . end . line , s . range . end . character )
54+ )
55+ }
56+ } ) ;
57+
58+ return methods ;
59+ }
60+
61+ }
0 commit comments