11import { SignatureHelp } from 'vscode' ;
2+ import * as vscode from "vscode" ;
3+ import * as proxy from "../../providers/jediProxy" ;
4+
5+ const DOCSTRING_PARAM_PATTERNS = [
6+ "\\s*:type\\s*PARAMNAME:\\s*([^\\n, ]+)" , // Sphinx
7+ "\\s*:param\\s*(\\w?)\\s*PARAMNAME:[^\\n]+" , // Sphinx param with type
8+ "\\s*@type\\s*PARAMNAME:\\s*([^\\n, ]+)" // Epydoc
9+ ] ;
10+
11+ /**
12+ * Extrct the documentation for parameters from a given docstring
13+ *
14+ * @param {string } paramName Name of the parameter
15+ * @param {string } docString The docstring for the function
16+ * @returns {string } Docstring for the parameter
17+ */
18+ function extractParamDocString ( paramName : string , docString : string ) : string {
19+ let paramDocString = "" ;
20+ // In docstring the '*' is escaped with a backslash
21+ paramName = paramName . replace ( new RegExp ( "\\*" , "g" ) , "\\\\\\*" ) ;
22+
23+ DOCSTRING_PARAM_PATTERNS . forEach ( pattern => {
24+ if ( paramDocString . length > 0 ) {
25+ return ;
26+ }
27+ pattern = pattern . replace ( "PARAMNAME" , paramName ) ;
28+ let regExp = new RegExp ( pattern ) ;
29+ let matches = regExp . exec ( docString ) ;
30+ if ( matches && matches . length > 0 ) {
31+ paramDocString = matches [ 0 ] ;
32+ if ( paramDocString . indexOf ( ":" ) >= 0 ) {
33+ paramDocString = paramDocString . substring ( paramDocString . indexOf ( ":" ) + 1 ) ;
34+ }
35+ if ( paramDocString . indexOf ( ":" ) >= 0 ) {
36+ paramDocString = paramDocString . substring ( paramDocString . indexOf ( ":" ) + 1 ) ;
37+ }
38+ }
39+ } ) ;
40+
41+ return paramDocString . trim ( ) ;
42+ }
243export class SignatureHelpParser {
3- public static parse ( data : Object ) : SignatureHelp {
4- return null ;
44+ public static parse ( data : proxy . IArgumentsResult ) : SignatureHelp {
45+ if ( ! data || ! Array . isArray ( data . definitions ) || data . definitions . length === 0 ) {
46+ return new SignatureHelp ( ) ;
47+ }
48+ let signature = new SignatureHelp ( ) ;
49+ signature . activeSignature = 0 ;
50+
51+ data . definitions . forEach ( def => {
52+ signature . activeParameter = def . paramindex ;
53+ // Don't display the documentation, as vs code doesn't format the docmentation
54+ // i.e. line feeds are not respected, long content is stripped
55+ let sig = < vscode . SignatureInformation > {
56+ // documentation: def.docstring,
57+ label : def . description ,
58+ parameters : [ ]
59+ } ;
60+ sig . parameters = def . params . map ( arg => {
61+ if ( arg . docstring . length === 0 ) {
62+ arg . docstring = extractParamDocString ( arg . name , def . docstring ) ;
63+ }
64+ return < vscode . ParameterInformation > {
65+ documentation : arg . docstring . length > 0 ? arg . docstring : arg . description ,
66+ label : arg . description . length > 0 ? arg . description : arg . name
67+ } ;
68+ } ) ;
69+ signature . signatures . push ( sig ) ;
70+ } ) ;
71+ return signature ;
572 }
673}
0 commit comments