feat(core): mix模式下使用diff去修改代码防止触发整个文件代码高亮的重新构建
This commit is contained in:
141
common/modules/mixly-modules/workers/common/tree-sitter/index.js
Normal file
141
common/modules/mixly-modules/workers/common/tree-sitter/index.js
Normal file
@@ -0,0 +1,141 @@
|
||||
importScripts('./tree-sitter.js');
|
||||
importScripts('../../../../web-modules/workerpool.min.js');
|
||||
|
||||
|
||||
const terms = [
|
||||
'type',
|
||||
'scope',
|
||||
'function',
|
||||
'variable',
|
||||
'number',
|
||||
'string',
|
||||
'comment',
|
||||
'constant',
|
||||
'directive',
|
||||
'control',
|
||||
'operator',
|
||||
'modifier',
|
||||
'punctuation'
|
||||
];
|
||||
|
||||
let parser;
|
||||
let tree = null;
|
||||
let language = null;
|
||||
|
||||
|
||||
class Language {
|
||||
constructor(grammarJson) {
|
||||
this.simpleTerms = {};
|
||||
this.complexTerms = [];
|
||||
this.complexScopes = {};
|
||||
for (const t in grammarJson.simpleTerms)
|
||||
this.simpleTerms[t] = grammarJson.simpleTerms[t];
|
||||
for (const t in grammarJson.complexTerms)
|
||||
this.complexTerms[t] = grammarJson.complexTerms[t];
|
||||
for (const t in grammarJson.complexScopes)
|
||||
this.complexScopes[t] = grammarJson.complexScopes[t];
|
||||
this.complexDepth = 0;
|
||||
this.complexOrder = false;
|
||||
for (const s in this.complexScopes) {
|
||||
const depth = s.split('>').length;
|
||||
if (depth > this.complexDepth)
|
||||
this.complexDepth = depth;
|
||||
if (s.indexOf('[') >= 0)
|
||||
this.complexOrder = true;
|
||||
}
|
||||
this.complexDepth--;
|
||||
}
|
||||
}
|
||||
|
||||
async function init(languageWasmPath, grammarJson) {
|
||||
await TreeSitter.init();
|
||||
|
||||
parser = new TreeSitter();
|
||||
const lang = await TreeSitter.Language.load(languageWasmPath);
|
||||
console.log(lang.version)
|
||||
parser.setLanguage(lang);
|
||||
language = new Language(grammarJson);
|
||||
|
||||
tree = null;
|
||||
}
|
||||
|
||||
function buildDecorations(tree) {
|
||||
const result = [];
|
||||
const stack = [];
|
||||
let node = tree.rootNode.firstChild;
|
||||
while (stack.length > 0 || node) {
|
||||
if (node) {
|
||||
stack.push(node);
|
||||
node = node.firstChild;
|
||||
}
|
||||
else {
|
||||
node = stack.pop();
|
||||
let type = node.type;
|
||||
if (!node.isNamed())
|
||||
type = '"' + type + '"';
|
||||
let term = null;
|
||||
if (!language.complexTerms.includes(type)) {
|
||||
term = language.simpleTerms[type];
|
||||
}
|
||||
else {
|
||||
let desc = type;
|
||||
let scopes = [desc];
|
||||
let parent = node.parent;
|
||||
for (let i = 0; i < language.complexDepth && parent; i++) {
|
||||
let parentType = parent.type;
|
||||
if (!parent.isNamed())
|
||||
parentType = '"' + parentType + '"';
|
||||
desc = parentType + ' > ' + desc;
|
||||
scopes.push(desc);
|
||||
parent = parent.parent;
|
||||
}
|
||||
if (language.complexOrder) {
|
||||
let index = 0;
|
||||
let sibling = node.previousSibling;
|
||||
while (sibling) {
|
||||
if (sibling.type === node.type)
|
||||
index++;
|
||||
sibling = sibling.previousSibling;
|
||||
}
|
||||
let rindex = -1;
|
||||
sibling = node.nextSibling;
|
||||
while (sibling) {
|
||||
if (sibling.type === node.type)
|
||||
rindex--;
|
||||
sibling = sibling.nextSibling;
|
||||
}
|
||||
const orderScopes = [];
|
||||
for (let i = 0; i < scopes.length; i++)
|
||||
orderScopes.push(scopes[i], scopes[i] + '[' + index + ']', scopes[i] + '[' + rindex + ']');
|
||||
scopes = orderScopes;
|
||||
}
|
||||
for (const d of scopes)
|
||||
if (d in language.complexScopes)
|
||||
term = language.complexScopes[d];
|
||||
}
|
||||
if (terms.includes(term)) {
|
||||
if (!result[term]) {
|
||||
result[term] = [];
|
||||
}
|
||||
result[term].push({
|
||||
startLineNumber: node.startPosition.row + 1,
|
||||
startColumn: node.startPosition.column + 1,
|
||||
endLineNumber: node.endPosition.row + 1,
|
||||
endColumn: node.endPosition.column + 1
|
||||
});
|
||||
}
|
||||
node = node.nextSibling;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function update(text) {
|
||||
const tree = parser.parse(text);
|
||||
return buildDecorations(tree);
|
||||
}
|
||||
|
||||
workerpool.worker({
|
||||
init,
|
||||
update
|
||||
});
|
||||
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Reference in New Issue
Block a user