.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.1.1-0.20210319172145-bda8f5cee399 / internal / lsp / protocol / typescript / util.ts
1
2 // for us typescript ignorati, having an import makes this file a module
3 import * as fs from 'fs';
4 import * as process from 'process';
5 import * as ts from 'typescript';
6
7 // This file contains various utilities having to do with producing strings
8 // and managing output
9
10 // ------ create files
11 let dir = process.env['HOME'];
12 const srcDir = '/vscode-languageserver-node';
13 export const fnames = [
14   `${dir}${srcDir}/protocol/src/common/protocol.ts`,
15   `${dir}/${srcDir}/protocol/src/browser/main.ts`, `${dir}${srcDir}/types/src/main.ts`,
16   `${dir}${srcDir}/jsonrpc/src/node/main.ts`
17 ];
18 export const gitHash = 'dae62de921d25964e8732411ca09e532dde992f5';
19 let outFname = 'tsprotocol.go';
20 let fda: number, fdb: number, fde: number;  // file descriptors
21
22 export function createOutputFiles() {
23   fda = fs.openSync('/tmp/ts-a', 'w');  // dump of AST
24   fdb = fs.openSync('/tmp/ts-b', 'w');  // unused, for debugging
25   fde = fs.openSync(outFname, 'w');     // generated Go
26 }
27 export function pra(s: string) {
28   return (fs.writeSync(fda, s));
29 }
30 export function prb(s: string) {
31   return (fs.writeSync(fdb, s));
32 }
33 export function prgo(s: string) {
34   return (fs.writeSync(fde, s));
35 }
36
37 // Get the hash value of the git commit
38 export function git(): string {
39   let a = fs.readFileSync(`${dir}${srcDir}/.git/HEAD`).toString();
40   // ref: refs/heads/foo, or a hash like
41   // cc12d1a1c7df935012cdef5d085cdba04a7c8ebe
42   if (a.charAt(a.length - 1) == '\n') {
43     a = a.substring(0, a.length - 1);
44   }
45   if (a.length == 40) {
46     return a;  // a hash
47   }
48   if (a.substring(0, 5) == 'ref: ') {
49     const fname = `${dir}${srcDir}/.git/` + a.substring(5);
50     let b = fs.readFileSync(fname).toString();
51     if (b.length == 41) {
52       return b.substring(0, 40);
53     }
54   }
55   throw new Error('failed to find the git commit hash');
56 }
57
58 // Produce a header for Go output files
59 export function computeHeader(pkgDoc: boolean): string {
60   let lastMod = 0;
61   let lastDate: Date;
62   for (const f of fnames) {
63     const st = fs.statSync(f);
64     if (st.mtimeMs > lastMod) {
65       lastMod = st.mtimeMs;
66       lastDate = st.mtime;
67     }
68   }
69   const cp = `// Copyright 2019 The Go Authors. All rights reserved.
70   // Use of this source code is governed by a BSD-style
71   // license that can be found in the LICENSE file.
72
73   `;
74   const a =
75     '// Package protocol contains data types and code for LSP jsonrpcs\n' +
76     '// generated automatically from vscode-languageserver-node\n' +
77     `// commit: ${gitHash}\n` +
78     `// last fetched ${lastDate}\n`;
79   const b = 'package protocol\n';
80   const c = '\n// Code generated (see typescript/README.md) DO NOT EDIT.\n\n';
81   if (pkgDoc) {
82     return cp + a + b + c;
83   }
84   else {
85     return cp + b + a + c;
86   }
87 }
88
89 // Turn a typescript name into an exportable Go name, and appease lint
90 export function goName(s: string): string {
91   let ans = s;
92   if (s.charAt(0) == '_') {
93     ans = 'Inner' + s.substring(1);
94   }
95   else { ans = s.substring(0, 1).toUpperCase() + s.substring(1); }
96   ans = ans.replace(/Uri$/, 'URI');
97   ans = ans.replace(/Id$/, 'ID');
98   return ans;
99 }
100
101 // Generate JSON tag for a struct field
102 export function JSON(n: ts.PropertySignature): string {
103   const json = `\`json:"${n.name.getText()}${
104     n.questionToken != undefined ? ',omitempty' : ''}"\``;
105   return json;
106 }
107
108 // Generate modifying prefixes and suffixes to ensure
109 // consts are unique. (Go consts are package-level, but Typescript's are
110 // not.) Use suffixes to minimize changes to gopls.
111 export function constName(nm: string, type: string): string {
112   let pref = new Map<string, string>([
113     ['DiagnosticSeverity', 'Severity'], ['WatchKind', 'Watch'],
114     ['SignatureHelpTriggerKind', 'Sig'], ['CompletionItemTag', 'Compl'],
115     ['Integer', 'INT_'], ['Uinteger', 'UINT_']
116   ]);  // typeName->prefix
117   let suff = new Map<string, string>([
118     ['CompletionItemKind', 'Completion'], ['InsertTextFormat', 'TextFormat'],
119     ['SymbolTag', 'Symbol'], ['FileOperationPatternKind', 'Op'],
120   ]);
121   let ans = nm;
122   if (pref.get(type)) ans = pref.get(type) + ans;
123   if (suff.has(type)) ans = ans + suff.get(type);
124   return ans;
125 }
126
127 // Find the comments associated with an AST node
128 export function getComments(node: ts.Node): string {
129   const sf = node.getSourceFile();
130   const start = node.getStart(sf, false);
131   const starta = node.getStart(sf, true);
132   const x = sf.text.substring(starta, start);
133   return x;
134 }
135
136
137 // --------- printing the AST, for debugging
138
139 export function printAST(program: ts.Program) {
140   // dump the ast, for debugging
141   const f = function (n: ts.Node) {
142     describe(n, pra);
143   };
144   for (const sourceFile of program.getSourceFiles()) {
145     if (!sourceFile.isDeclarationFile) {
146       // walk the tree to do stuff
147       ts.forEachChild(sourceFile, f);
148     }
149   }
150   pra('\n');
151   for (const key of Object.keys(seenThings).sort()) {
152     pra(`${key}: ${seenThings[key]} \n`);
153   }
154 }
155
156 // Used in printing the AST
157 let seenThings = new Map<string, number>();
158 function seenAdd(x: string) {
159   seenThings[x] = (seenThings[x] === undefined ? 1 : seenThings[x] + 1);
160 }
161
162 // eslint-disable-next-line no-unused-vars
163 function describe(node: ts.Node, pr: (s: string) => any) {
164   if (node === undefined) {
165     return;
166   }
167   let indent = '';
168
169   function f(n: ts.Node) {
170     seenAdd(kinds(n));
171     if (ts.isIdentifier(n)) {
172       pr(`${indent} ${loc(n)} ${strKind(n)} ${n.text} \n`);
173     }
174     else if (ts.isPropertySignature(n) || ts.isEnumMember(n)) {
175       pra(`${indent} ${loc(n)} ${strKind(n)} \n`);
176     }
177     else if (ts.isTypeLiteralNode(n)) {
178       let m = n.members;
179       pr(`${indent} ${loc(n)} ${strKind(n)} ${m.length} \n`);
180     }
181     else if (ts.isStringLiteral(n)) {
182       pr(`${indent} ${loc(n)} ${strKind(n)} ${n.text} \n`);
183     }
184     else { pr(`${indent} ${loc(n)} ${strKind(n)} \n`); }
185     indent += ' .';
186     ts.forEachChild(n, f);
187     indent = indent.slice(0, indent.length - 2);
188   }
189   f(node);
190 }
191
192
193 // For debugging, say where an AST node is in a file
194 export function loc(node: ts.Node): string {
195   const sf = node.getSourceFile();
196   const start = node.getStart();
197   const x = sf.getLineAndCharacterOfPosition(start);
198   const full = node.getFullStart();
199   const y = sf.getLineAndCharacterOfPosition(full);
200   let fn = sf.fileName;
201   const n = fn.search(/-node./);
202   fn = fn.substring(n + 6);
203   return `${fn} ${x.line + 1}: ${x.character + 1} (${y.line + 1}: ${
204     y.character + 1})`;
205 }
206 // --- various string stuff
207
208 // return a string of the kinds of the immediate descendants
209 // as part of printing the AST tree
210 function kinds(n: ts.Node): string {
211   let res = 'Seen ' + strKind(n);
212   function f(n: ts.Node): void { res += ' ' + strKind(n); }
213   ts.forEachChild(n, f);
214   return res;
215 }
216
217 // What kind of AST node is it? This would just be typescript's
218 // SyntaxKind[n.kind] except that the default names for some nodes
219 // are misleading
220 export function strKind(n: ts.Node): string {
221   if (n == null || n == undefined) {
222     return 'null';
223   }
224    return kindToStr(n.kind);
225 }
226
227 export function kindToStr(k: ts.SyntaxKind): string {
228   if (k === undefined) return 'unDefined';
229   const x = ts.SyntaxKind[k];
230   // some of these have two names
231   switch (x) {
232     default:
233       return x;
234     case 'FirstAssignment':
235       return 'EqualsToken';
236     case 'FirstBinaryOperator':
237       return 'LessThanToken';
238     case 'FirstCompoundAssignment':
239       return 'PlusEqualsToken';
240     case 'FirstContextualKeyword':
241       return 'AbstractKeyword';
242     case 'FirstLiteralToken':
243       return 'NumericLiteral';
244     case 'FirstNode':
245       return 'QualifiedName';
246     case 'FirstTemplateToken':
247       return 'NoSubstitutionTemplateLiteral';
248     case 'LastTemplateToken':
249       return 'TemplateTail';
250     case 'FirstTypeNode':
251       return 'TypePredicate';
252   }
253 }