This repository has been archived by the owner on Jun 4, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 17
/
parseImportNodes.ts
61 lines (52 loc) · 2.21 KB
/
parseImportNodes.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import { DestructedImport, TypescriptImport } from './TypescriptImport';
import * as vscode from 'vscode';
const name = `((?!\\d)(?:(?!\\s)[$\\w\\u0080-\\uFFFF]|\\\\u[\\da-fA-F]{4}|\\\\u\\{[\\da-fA-F]+\\})+)`;
const ws = `[\\s\\n\\r]`;
const namespaceToken = `\\*\\s+as\\s+(${name})`;
const defaultImportToken = name;
const destructingImportToken = `(${name})(\\s+as\\s+(${name}))?`;
const destructingImport = `{(${ws}*${destructingImportToken}(,${ws}*${destructingImportToken})*${ws}*)}`;
const defaultAndDestructingImport = `${defaultImportToken}${ws}*,${ws}*${destructingImport}`;
const combinedImportTypes = `(${namespaceToken}|${defaultImportToken}|${destructingImport}|${defaultAndDestructingImport})`;
const importRegexString = `^import\\s+(${combinedImportTypes}\\s+from\\s+)?['"]([@\\w\\\\/\.-]+)['"];?\\r?\\n?`;
// Group 5 || Group 18 - default import
// Group 3 - namespace import
// Group 6 || Group 19 - destructing import group; requires further tokenizing
// Group 31 - file path or package
const importRegex = new RegExp(importRegexString, 'gm');
// Group 1 - importName
// Group 4 - alias
const destructingImportTokenRegex = new RegExp(destructingImportToken);
export default function parseImportNodes(document: vscode.TextDocument) {
let source = document.getText();
importRegex.lastIndex = 0;
let imports: TypescriptImport[] = [];
let match;
while (match = importRegex.exec(source)) {
imports.push({
path: match[31],
default: match[5] || match[18],
namedImports: parseDestructiveImports(match[6] || match[19]),
namespace: match[3],
range: new vscode.Range(
document.positionAt(match.index),
document.positionAt(importRegex.lastIndex)
),
});
}
return imports;
}
function parseDestructiveImports(destructiveImports: string): DestructedImport[] {
if (!destructiveImports) {
return null;
}
return destructiveImports
.split(',')
.map(destructiveImport => {
let match = destructingImportTokenRegex.exec(destructiveImport);
return {
importName: match[1],
alias: match[4],
};
});
}