@profile-psl/psl-parser 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -0
- package/LICENSE +9 -0
- package/README.md +34 -0
- package/config.d.ts +29 -0
- package/config.js +51 -0
- package/index.d.ts +6 -0
- package/index.js +7 -0
- package/package.json +35 -0
- package/parser.d.ts +155 -0
- package/parser.js +707 -0
- package/statementParser.d.ts +93 -0
- package/statementParser.js +739 -0
- package/tokenizer.d.ts +139 -0
- package/tokenizer.js +535 -0
- package/utilities.d.ts +43 -0
- package/utilities.js +427 -0
package/utilities.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { FinderPaths } from "./config";
|
|
2
|
+
import { Member, Method, ParsedDocument } from "./parser";
|
|
3
|
+
import { Position, Token } from "./tokenizer";
|
|
4
|
+
export interface FinderResult {
|
|
5
|
+
fsPath: string;
|
|
6
|
+
member?: Member;
|
|
7
|
+
}
|
|
8
|
+
export declare const dummyPosition: Position;
|
|
9
|
+
export declare class ParsedDocFinder {
|
|
10
|
+
parsedDocument: ParsedDocument;
|
|
11
|
+
paths: FinderPaths;
|
|
12
|
+
procName: string;
|
|
13
|
+
private hierarchy;
|
|
14
|
+
constructor(parsedDocument: ParsedDocument, paths: FinderPaths, getWorkspaceDocumentText?: (fsPath: string) => Promise<string>);
|
|
15
|
+
resolveResult(callTokens: Token[]): Promise<FinderResult>;
|
|
16
|
+
newFinder(routineName: string): Promise<ParsedDocFinder>;
|
|
17
|
+
/**
|
|
18
|
+
* Search the parsed document and parents for a particular member
|
|
19
|
+
*/
|
|
20
|
+
searchParser(queriedToken: Token): Promise<FinderResult>;
|
|
21
|
+
searchInDocument(queriedId: string): Promise<FinderResult>;
|
|
22
|
+
findAllInDocument(results?: FinderResult[]): Promise<FinderResult[]>;
|
|
23
|
+
resolveFileDefinitionDirectory(tableName: string): Promise<string>;
|
|
24
|
+
private searchForParent;
|
|
25
|
+
private searchInMethod;
|
|
26
|
+
private findActiveMethod;
|
|
27
|
+
private getWorkspaceDocumentText;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Get the tokens on the line of position, as well as the specific index of the token at position
|
|
31
|
+
*/
|
|
32
|
+
export declare function searchTokens(tokens: Token[], position: Position): {
|
|
33
|
+
tokensOnLine: Token[];
|
|
34
|
+
index: number;
|
|
35
|
+
};
|
|
36
|
+
export declare function getCallTokens(tokensOnLine: Token[], index: number): Token[];
|
|
37
|
+
export declare function resolve(tokens: Token[]): number;
|
|
38
|
+
export declare function findCallable(tokensOnLine: Token[], index: number): {
|
|
39
|
+
callTokens: Token[];
|
|
40
|
+
parameterIndex: number;
|
|
41
|
+
};
|
|
42
|
+
export declare function getLineAfter(method: Method): number;
|
|
43
|
+
export declare function getCommentsOnLine(parsedDocument: ParsedDocument, lineNumber: number): Token[];
|
package/utilities.js
ADDED
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as fsx from "fs-extra";
|
|
3
|
+
import * as jsonc from "jsonc-parser";
|
|
4
|
+
import * as path from "path";
|
|
5
|
+
import { MemberClass, parseText } from "./parser";
|
|
6
|
+
import { Position, Token } from "./tokenizer";
|
|
7
|
+
export const dummyPosition = new Position(0, 0);
|
|
8
|
+
export class ParsedDocFinder {
|
|
9
|
+
parsedDocument;
|
|
10
|
+
paths;
|
|
11
|
+
procName;
|
|
12
|
+
hierarchy = [];
|
|
13
|
+
constructor(parsedDocument, paths, getWorkspaceDocumentText) {
|
|
14
|
+
this.parsedDocument = parsedDocument;
|
|
15
|
+
this.paths = paths;
|
|
16
|
+
if (getWorkspaceDocumentText)
|
|
17
|
+
this.getWorkspaceDocumentText = getWorkspaceDocumentText;
|
|
18
|
+
this.procName = path.basename(this.paths.activeRoutine).split(".")[0];
|
|
19
|
+
}
|
|
20
|
+
async resolveResult(callTokens) {
|
|
21
|
+
// TODO: (Mischa Reitsma) Reset the finder a few times. Most of them can be a local const finder = this.newFinder(), but not all. Not going to change it now
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
23
|
+
let finder = this;
|
|
24
|
+
if (callTokens.length === 1) {
|
|
25
|
+
const result = await finder.searchParser(callTokens[0]);
|
|
26
|
+
// check for core class or tables
|
|
27
|
+
if (!result) {
|
|
28
|
+
const pslClsNames = await getPslClsNames(this.paths.corePsl);
|
|
29
|
+
if (pslClsNames.indexOf(callTokens[0].value) >= 0) {
|
|
30
|
+
const finder = await this.newFinder(callTokens[0].value);
|
|
31
|
+
return {
|
|
32
|
+
fsPath: finder.paths.activeRoutine,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const tableName = callTokens[0].value.replace("Record", "");
|
|
36
|
+
const fileDefinitionDirectory = await this.resolveFileDefinitionDirectory(tableName);
|
|
37
|
+
if (fileDefinitionDirectory) {
|
|
38
|
+
return {
|
|
39
|
+
fsPath: path.join(fileDefinitionDirectory, tableName.toUpperCase() + ".TBL"),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
else if (callTokens[0] === this.parsedDocument.extending) {
|
|
43
|
+
finder = await finder.newFinder(callTokens[0].value);
|
|
44
|
+
return {
|
|
45
|
+
fsPath: finder.paths.activeRoutine,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
else if (callTokens[0].value === "this" ||
|
|
49
|
+
callTokens[0].value === this.procName) {
|
|
50
|
+
return {
|
|
51
|
+
fsPath: this.paths.activeRoutine,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// handle static types
|
|
56
|
+
else if (result.member.types[0] === callTokens[0]) {
|
|
57
|
+
finder = await finder.newFinder(result.member.id.value);
|
|
58
|
+
return {
|
|
59
|
+
fsPath: finder.paths.activeRoutine,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
let result;
|
|
66
|
+
for (let index = 0; index < callTokens.length; index++) {
|
|
67
|
+
const token = callTokens[index];
|
|
68
|
+
if (index === 0) {
|
|
69
|
+
// handle core class
|
|
70
|
+
const pslClsNames = await getPslClsNames(this.paths.corePsl);
|
|
71
|
+
if (pslClsNames.indexOf(token.value) >= 0) {
|
|
72
|
+
finder = await finder.newFinder(token.value);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
// skip over "this"
|
|
76
|
+
else if (token.value === "this" ||
|
|
77
|
+
token.value === this.procName) {
|
|
78
|
+
result = {
|
|
79
|
+
fsPath: this.paths.activeRoutine,
|
|
80
|
+
};
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
result = await finder.searchParser(token);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (!result || (result.fsPath === this.paths.activeRoutine
|
|
88
|
+
&& !result.member)) {
|
|
89
|
+
result = await finder.searchInDocument(token.value);
|
|
90
|
+
}
|
|
91
|
+
if (!result)
|
|
92
|
+
return null;
|
|
93
|
+
if (!callTokens[index + 1])
|
|
94
|
+
return result;
|
|
95
|
+
let type = result.member.types[0].value;
|
|
96
|
+
if (type === "void")
|
|
97
|
+
type = "Primitive"; // TODO whack hack
|
|
98
|
+
finder = await finder.newFinder(type);
|
|
99
|
+
result = undefined;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
async newFinder(routineName) {
|
|
105
|
+
if (routineName.startsWith("Record") && routineName !== "Record") {
|
|
106
|
+
const tableName = routineName.replace("Record", "");
|
|
107
|
+
const tableDirectory = await this.resolveFileDefinitionDirectory(tableName.toLowerCase());
|
|
108
|
+
if (!tableDirectory)
|
|
109
|
+
return null;
|
|
110
|
+
const columns = (await fsx.readdir(tableDirectory))
|
|
111
|
+
.filter(file => file.endsWith(".COL"))
|
|
112
|
+
.map(col => {
|
|
113
|
+
const colName = col
|
|
114
|
+
.replace(`${tableName}-`, "")
|
|
115
|
+
.replace(".COL", "")
|
|
116
|
+
.toLowerCase();
|
|
117
|
+
const ret = {
|
|
118
|
+
id: new Token(1 /* Type.Alphanumeric */, colName, dummyPosition),
|
|
119
|
+
memberClass: MemberClass.column,
|
|
120
|
+
modifiers: [],
|
|
121
|
+
types: [new Token(1 /* Type.Alphanumeric */, "String", dummyPosition)],
|
|
122
|
+
};
|
|
123
|
+
return ret;
|
|
124
|
+
});
|
|
125
|
+
const text = await this.getWorkspaceDocumentText(path.join(tableDirectory, `${tableName.toUpperCase()}.TBL`));
|
|
126
|
+
const parsed = jsonc.parse(text);
|
|
127
|
+
const parentFileId = parsed.PARFID;
|
|
128
|
+
const extendingValue = parentFileId ? `Record${parentFileId}` : "Record";
|
|
129
|
+
const parsedDocument = {
|
|
130
|
+
comments: [],
|
|
131
|
+
declarations: [],
|
|
132
|
+
extending: new Token(1 /* Type.Alphanumeric */, extendingValue, dummyPosition),
|
|
133
|
+
methods: [],
|
|
134
|
+
properties: columns,
|
|
135
|
+
pslPackage: "",
|
|
136
|
+
tokens: [],
|
|
137
|
+
};
|
|
138
|
+
const newPaths = Object.create(this.paths);
|
|
139
|
+
newPaths.activeRoutine = "";
|
|
140
|
+
newPaths.activeTable = tableDirectory;
|
|
141
|
+
return new ParsedDocFinder(parsedDocument, newPaths, this.getWorkspaceDocumentText);
|
|
142
|
+
}
|
|
143
|
+
const pathsWithoutExtensions = this.paths.projectPsl
|
|
144
|
+
.map(pslPath => path.join(pslPath, routineName));
|
|
145
|
+
for (const pathWithoutExtension of pathsWithoutExtensions) {
|
|
146
|
+
for (const extension of [".PROC", ".psl", ".PSL"]) {
|
|
147
|
+
const possiblePath = pathWithoutExtension + extension;
|
|
148
|
+
const routineText = await this.getWorkspaceDocumentText(possiblePath);
|
|
149
|
+
if (!routineText)
|
|
150
|
+
continue;
|
|
151
|
+
const newPaths = Object.create(this.paths);
|
|
152
|
+
newPaths.activeRoutine = possiblePath;
|
|
153
|
+
return new ParsedDocFinder(parseText(routineText), newPaths, this.getWorkspaceDocumentText);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Search the parsed document and parents for a particular member
|
|
160
|
+
*/
|
|
161
|
+
async searchParser(queriedToken) {
|
|
162
|
+
const activeMethod = this.findActiveMethod(queriedToken);
|
|
163
|
+
if (activeMethod) {
|
|
164
|
+
const variable = this.searchInMethod(activeMethod, queriedToken);
|
|
165
|
+
if (variable)
|
|
166
|
+
return { member: variable, fsPath: this.paths.activeRoutine };
|
|
167
|
+
}
|
|
168
|
+
return this.searchInDocument(queriedToken.value);
|
|
169
|
+
}
|
|
170
|
+
async searchInDocument(queriedId) {
|
|
171
|
+
let foundProperty;
|
|
172
|
+
if (this.paths.activeTable) {
|
|
173
|
+
foundProperty = this.parsedDocument.properties
|
|
174
|
+
.find(p => p.id.value.toLowerCase() === queriedId.toLowerCase());
|
|
175
|
+
if (foundProperty) {
|
|
176
|
+
const tableName = path.basename(this.paths.activeTable)
|
|
177
|
+
.toUpperCase();
|
|
178
|
+
return {
|
|
179
|
+
fsPath: path.join(this.paths.activeTable, `${tableName}-` +
|
|
180
|
+
foundProperty.id.value.toUpperCase() +
|
|
181
|
+
".COL"),
|
|
182
|
+
member: foundProperty,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
foundProperty = this.parsedDocument.properties.find(p => p.id.value === queriedId);
|
|
187
|
+
if (foundProperty)
|
|
188
|
+
return { member: foundProperty, fsPath: this.paths.activeRoutine };
|
|
189
|
+
const foundMethod = this.parsedDocument.methods.find(p => p.id.value === queriedId);
|
|
190
|
+
if (foundMethod)
|
|
191
|
+
return { member: foundMethod, fsPath: this.paths.activeRoutine };
|
|
192
|
+
if (this.parsedDocument.extending) {
|
|
193
|
+
const parentRoutineName = this.parsedDocument.extending.value;
|
|
194
|
+
if (this.hierarchy.indexOf(parentRoutineName) > -1)
|
|
195
|
+
return null;
|
|
196
|
+
const parentFinder = await this.searchForParent(parentRoutineName);
|
|
197
|
+
if (!parentFinder)
|
|
198
|
+
return null;
|
|
199
|
+
return parentFinder.searchInDocument(queriedId);
|
|
200
|
+
}
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
async findAllInDocument(results) {
|
|
204
|
+
if (!results)
|
|
205
|
+
results = [];
|
|
206
|
+
const addToResults = (result) => {
|
|
207
|
+
if (!results.find(r => r.member.id.value === result.member.id.value)) {
|
|
208
|
+
results.push(result);
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
if (this.paths.activeTable) {
|
|
212
|
+
this.parsedDocument.properties.forEach(property => {
|
|
213
|
+
const tableName = path.basename(this.paths.activeTable)
|
|
214
|
+
.toUpperCase();
|
|
215
|
+
addToResults({
|
|
216
|
+
member: property,
|
|
217
|
+
fsPath: path.join(this.paths.activeTable, `${tableName}-` +
|
|
218
|
+
property.id.value.toUpperCase() +
|
|
219
|
+
".COL")
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
this.parsedDocument.properties.forEach(property => {
|
|
224
|
+
addToResults({ member: property, fsPath: this.paths.activeRoutine });
|
|
225
|
+
});
|
|
226
|
+
this.parsedDocument.methods.forEach(method => {
|
|
227
|
+
addToResults({ member: method, fsPath: this.paths.activeRoutine });
|
|
228
|
+
});
|
|
229
|
+
if (this.parsedDocument.extending) {
|
|
230
|
+
const parentRoutineName = this.parsedDocument.extending.value;
|
|
231
|
+
if (this.hierarchy.indexOf(parentRoutineName) > -1)
|
|
232
|
+
return results;
|
|
233
|
+
const parentFinder = await this.searchForParent(parentRoutineName);
|
|
234
|
+
if (!parentFinder)
|
|
235
|
+
return results;
|
|
236
|
+
return parentFinder.findAllInDocument(results);
|
|
237
|
+
}
|
|
238
|
+
return results;
|
|
239
|
+
}
|
|
240
|
+
async resolveFileDefinitionDirectory(tableName) {
|
|
241
|
+
for (const tableSource of this.paths.tables) {
|
|
242
|
+
const directory = path.join(tableSource, tableName.toLowerCase());
|
|
243
|
+
if (await fsx.pathExists(directory)) {
|
|
244
|
+
return directory;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return "";
|
|
248
|
+
}
|
|
249
|
+
async searchForParent(parentRoutineName) {
|
|
250
|
+
const parentFinder = await this.newFinder(parentRoutineName);
|
|
251
|
+
if (!parentFinder)
|
|
252
|
+
return null;
|
|
253
|
+
parentFinder.hierarchy = this.hierarchy.concat(this.paths.activeRoutine);
|
|
254
|
+
return parentFinder;
|
|
255
|
+
}
|
|
256
|
+
searchInMethod(activeMethod, queriedToken) {
|
|
257
|
+
for (const variable of activeMethod.declarations.reverse()) {
|
|
258
|
+
if (queriedToken.position.line < variable.id.position.line)
|
|
259
|
+
continue;
|
|
260
|
+
if (queriedToken.value === variable.id.value)
|
|
261
|
+
return variable;
|
|
262
|
+
}
|
|
263
|
+
for (const parameter of activeMethod.parameters) {
|
|
264
|
+
if (queriedToken.value === parameter.id.value)
|
|
265
|
+
return parameter;
|
|
266
|
+
}
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
findActiveMethod(queriedToken) {
|
|
270
|
+
const methods = this.parsedDocument.methods
|
|
271
|
+
.filter(method => queriedToken.position.line >= method.id.position.line);
|
|
272
|
+
return methods ? methods.at(-1) : null;
|
|
273
|
+
}
|
|
274
|
+
async getWorkspaceDocumentText(fsPath) {
|
|
275
|
+
return new Promise((resolve) => {
|
|
276
|
+
fs.readFile(fsPath, (err, data) => {
|
|
277
|
+
if (err)
|
|
278
|
+
resolve("");
|
|
279
|
+
resolve(data.toString());
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
async function getPslClsNames(dir) {
|
|
285
|
+
try {
|
|
286
|
+
const names = await fsx.readdir(dir);
|
|
287
|
+
return names.map(name => name.split(".")[0]);
|
|
288
|
+
}
|
|
289
|
+
catch {
|
|
290
|
+
return [];
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Get the tokens on the line of position, as well as the specific index of the token at position
|
|
295
|
+
*/
|
|
296
|
+
export function searchTokens(tokens, position) {
|
|
297
|
+
const tokensOnLine = tokens.filter(t => t.position.line === position.line);
|
|
298
|
+
if (tokensOnLine.length === 0)
|
|
299
|
+
return undefined;
|
|
300
|
+
const index = tokensOnLine.findIndex(t => {
|
|
301
|
+
if (t.isNewLine() || t.isSpace() || t.isTab())
|
|
302
|
+
return null;
|
|
303
|
+
const start = t.position;
|
|
304
|
+
const end = {
|
|
305
|
+
line: t.position.line,
|
|
306
|
+
character: t.position.character + t.value.length
|
|
307
|
+
};
|
|
308
|
+
return isBetween(start, position, end);
|
|
309
|
+
});
|
|
310
|
+
return { tokensOnLine, index };
|
|
311
|
+
}
|
|
312
|
+
function isBetween(lb, t, ub) {
|
|
313
|
+
return lb.line <= t.line &&
|
|
314
|
+
lb.character <= t.character &&
|
|
315
|
+
ub.line >= t.line &&
|
|
316
|
+
ub.character >= t.character;
|
|
317
|
+
}
|
|
318
|
+
export function getCallTokens(tokensOnLine, index) {
|
|
319
|
+
const ret = [];
|
|
320
|
+
let current = getChildNode(tokensOnLine, index);
|
|
321
|
+
if (!current)
|
|
322
|
+
return ret;
|
|
323
|
+
while (current.parent && current.token) {
|
|
324
|
+
ret.unshift(current.token);
|
|
325
|
+
current = current.parent;
|
|
326
|
+
}
|
|
327
|
+
if (current.token)
|
|
328
|
+
ret.unshift(current.token);
|
|
329
|
+
return ret;
|
|
330
|
+
}
|
|
331
|
+
function getChildNode(tokensOnLine, index) {
|
|
332
|
+
const currentToken = tokensOnLine[index];
|
|
333
|
+
if (!currentToken)
|
|
334
|
+
return { token: undefined };
|
|
335
|
+
const previousToken = tokensOnLine[index - 1];
|
|
336
|
+
const nextToken = tokensOnLine[index + 1];
|
|
337
|
+
let routine = false;
|
|
338
|
+
if (previousToken) {
|
|
339
|
+
let newIndex = -1;
|
|
340
|
+
if (currentToken.isPeriod()) {
|
|
341
|
+
newIndex = resolve(tokensOnLine.slice(0, index));
|
|
342
|
+
}
|
|
343
|
+
else if (previousToken.isCaret()) {
|
|
344
|
+
routine = true;
|
|
345
|
+
}
|
|
346
|
+
else if (currentToken.isAlphanumeric() && previousToken.isPeriod()) {
|
|
347
|
+
newIndex = resolve(tokensOnLine.slice(0, index - 1));
|
|
348
|
+
}
|
|
349
|
+
if (newIndex >= 0) {
|
|
350
|
+
const parent = getChildNode(tokensOnLine, newIndex);
|
|
351
|
+
return { parent, token: currentToken };
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
if (nextToken && nextToken.isCaret()) {
|
|
355
|
+
const routineToken = tokensOnLine[index + 2];
|
|
356
|
+
if (!routineToken)
|
|
357
|
+
return undefined;
|
|
358
|
+
return { parent: { token: routineToken, routine: true }, token: currentToken };
|
|
359
|
+
}
|
|
360
|
+
if (currentToken.isAlphanumeric()) {
|
|
361
|
+
return { token: currentToken, routine };
|
|
362
|
+
}
|
|
363
|
+
return undefined;
|
|
364
|
+
}
|
|
365
|
+
export function resolve(tokens) {
|
|
366
|
+
const length = tokens.length;
|
|
367
|
+
let parenCount = 0;
|
|
368
|
+
if (length === 0)
|
|
369
|
+
return -1;
|
|
370
|
+
if (tokens[length - 1].isAlphanumeric())
|
|
371
|
+
return length - 1;
|
|
372
|
+
for (let index = tokens.length - 1; index >= 0; index--) {
|
|
373
|
+
const token = tokens[index];
|
|
374
|
+
if (token.isCloseParen())
|
|
375
|
+
parenCount++;
|
|
376
|
+
else if (token.isOpenParen())
|
|
377
|
+
parenCount--;
|
|
378
|
+
if (parenCount === 0) {
|
|
379
|
+
if (index > 0 && tokens[index - 1].isAlphanumeric())
|
|
380
|
+
return index - 1;
|
|
381
|
+
else
|
|
382
|
+
return -1;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
return -1;
|
|
386
|
+
}
|
|
387
|
+
export function findCallable(tokensOnLine, index) {
|
|
388
|
+
const callables = [];
|
|
389
|
+
for (let tokenBufferIndex = 0; tokenBufferIndex <= index; tokenBufferIndex++) {
|
|
390
|
+
const token = tokensOnLine[tokenBufferIndex];
|
|
391
|
+
if (!tokenBufferIndex && !token.isTab() && !token.isSpace())
|
|
392
|
+
return null;
|
|
393
|
+
if (token.isOpenParen()) {
|
|
394
|
+
callables.push({
|
|
395
|
+
tokenBufferIndex: tokenBufferIndex - 1,
|
|
396
|
+
parameterIndex: 0
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
else if (token.isCloseParen()) {
|
|
400
|
+
if (callables.length)
|
|
401
|
+
callables.pop();
|
|
402
|
+
else
|
|
403
|
+
return null;
|
|
404
|
+
}
|
|
405
|
+
else if (token.isComma() && callables.length) {
|
|
406
|
+
callables[callables.length - 1].parameterIndex += 1;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
if (!callables.length)
|
|
410
|
+
return null;
|
|
411
|
+
const activeCallable = callables.at(-1);
|
|
412
|
+
return {
|
|
413
|
+
callTokens: getCallTokens(tokensOnLine, activeCallable.tokenBufferIndex),
|
|
414
|
+
parameterIndex: activeCallable.parameterIndex,
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
export function getLineAfter(method) {
|
|
418
|
+
return method.closeParen ?
|
|
419
|
+
method.closeParen.position.line + 1 :
|
|
420
|
+
method.id.position.line + 1;
|
|
421
|
+
}
|
|
422
|
+
export function getCommentsOnLine(parsedDocument, lineNumber) {
|
|
423
|
+
return parsedDocument.comments.filter(t => {
|
|
424
|
+
return t.position.line === lineNumber;
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbGl0aWVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3V0aWxpdGllcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxNQUFNLElBQUksQ0FBQztBQUN6QixPQUFPLEtBQUssR0FBRyxNQUFNLFVBQVUsQ0FBQztBQUNoQyxPQUFPLEtBQUssS0FBSyxNQUFNLGNBQWMsQ0FBQztBQUN0QyxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUU3QixPQUFPLEVBQVUsV0FBVyxFQUEwQixTQUFTLEVBQVksTUFBTSxVQUFVLENBQUM7QUFDNUYsT0FBTyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQVEsTUFBTSxhQUFhLENBQUM7QUFPcEQsTUFBTSxDQUFDLE1BQU0sYUFBYSxHQUFHLElBQUksUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUVoRCxNQUFNLE9BQU8sZUFBZTtJQUUzQixjQUFjLENBQWlCO0lBQy9CLEtBQUssQ0FBYztJQUNuQixRQUFRLENBQVM7SUFFVCxTQUFTLEdBQWEsRUFBRSxDQUFDO0lBRWpDLFlBQ0MsY0FBOEIsRUFDOUIsS0FBa0IsRUFDbEIsd0JBQThEO1FBRTlELElBQUksQ0FBQyxjQUFjLEdBQUcsY0FBYyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ25CLElBQUksd0JBQXdCO1lBQzNCLElBQUksQ0FBQyx3QkFBd0IsR0FBRyx3QkFBd0IsQ0FBQztRQUMxRCxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDdkUsQ0FBQztJQUVELEtBQUssQ0FBQyxhQUFhLENBQUMsVUFBbUI7UUFDdEMsNEpBQTRKO1FBQzVKLDREQUE0RDtRQUM1RCxJQUFJLE1BQU0sR0FB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
|