Skip to content

Commit 654e86c

Browse files
committed
feat: implement first-pass tree-sitter parsing when validating ccini filepaths
1 parent 094b095 commit 654e86c

File tree

3 files changed

+72
-40
lines changed

3 files changed

+72
-40
lines changed

packages/server/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "server",
2+
"name": "language-server",
33
"version": "1.0.0",
44
"private": true,
55
"license": "GPL-3.0-only",
@@ -13,6 +13,8 @@
1313
"dependencies": {
1414
"vscode-uri": "^3.0.2",
1515
"vscode-languageserver": "^7.0.0",
16-
"vscode-languageserver-textdocument": "^1.0.1"
16+
"vscode-languageserver-textdocument": "^1.0.1",
17+
"path": "^0.12.7",
18+
"@keqingmoe/tree-sitter": "^0.26.2"
1719
}
1820
}

packages/server/src/validations/validateFilePath.ts

Lines changed: 50 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { extname, normalize } from 'path';
2-
import { Diagnostic, DiagnosticSeverity } from 'vscode-languageserver';
1+
import { extname } from 'path';
2+
import { Diagnostic } from 'vscode-languageserver';
33
import { TextDocument } from 'vscode-languageserver-textdocument';
44
import { configService } from '../services/configuration.service';
55
import { fileSystemService } from '../services/fs.service';
66
import { imageFileExtensions } from 'shared';
7-
import Parser, { Language } from 'tree-sitter';
8-
import ccini from 'tree-sitter-ccini';
7+
import Parser, { Language, Query } from '@keqingmoe/tree-sitter';
8+
import language from 'tree-sitter-ccini';
99

1010
export function validateFilePaths(textDocument: TextDocument): Diagnostic[] {
1111
// In this simple example we get the settings for every validate run.
@@ -15,44 +15,59 @@ export function validateFilePaths(textDocument: TextDocument): Diagnostic[] {
1515
const text = textDocument.getText();
1616

1717
const parser = new Parser();
18-
parser.setLanguage(ccini as Language);
18+
parser.setLanguage(language as Language);
19+
20+
const queryString = `\
21+
(assignment
22+
key: (property) @key
23+
value: (modulePath
24+
extension: (fileExtension) @extension
25+
) @modulePathValue
26+
) @assignment`;
27+
28+
const filepathQuery = new Query(language as Language, queryString);
1929

2030
const tree = parser.parse(text);
2131

22-
let m: RegExpExecArray | null;
32+
const captures = filepathQuery.captures(tree.rootNode);
2333

24-
let problems = 0;
34+
const problems = 0;
2535
const diagnostics: Diagnostic[] = [];
2636

27-
while (
28-
(m = pattern.exec(text)) &&
29-
problems < configService.globalSettings.maxNumberOfProblems
30-
) {
31-
if (!checkIfPathExists(normalizedPath)) {
32-
problems++;
33-
const diagnostic: Diagnostic = {
34-
severity: DiagnosticSeverity.Error,
35-
range: {
36-
start: textDocument.positionAt(m.index + m[1].length),
37-
end: textDocument.positionAt(m.index + m[0].length),
38-
},
39-
message: `Cannot find the file ${m[2]}`,
40-
source: 'CC Language Features',
41-
};
42-
if (configService.hasDiagnosticRelatedInformationCapability) {
43-
diagnostic.relatedInformation = [
44-
{
45-
location: {
46-
uri: textDocument.uri,
47-
range: Object.assign({}, diagnostic.range),
48-
},
49-
message:
50-
'This may be due to a bad file extension/path, or incorrect capitalization.',
51-
},
52-
];
53-
}
54-
diagnostics.push(diagnostic);
37+
for (const capture of captures) {
38+
if (problems >= configService.globalSettings.maxNumberOfProblems) {
39+
break;
5540
}
41+
42+
console.log(capture.name);
43+
console.log(capture.node.text);
44+
const normalizedPath = capture.name;
45+
46+
// if (!checkIfPathExists(normalizedPath)) {
47+
// problems++;
48+
// const diagnostic: Diagnostic = {
49+
// severity: DiagnosticSeverity.Error,
50+
// range: {
51+
// start: textDocument.positionAt(captures.index + captures[1].length),
52+
// end: textDocument.positionAt(captures.index + captures[0].length),
53+
// },
54+
// message: `Cannot find the file ${captures[2]}`,
55+
// source: 'CC Language Features',
56+
// };
57+
// if (configService.hasDiagnosticRelatedInformationCapability) {
58+
// diagnostic.relatedInformation = [
59+
// {
60+
// location: {
61+
// uri: textDocument.uri,
62+
// range: Object.assign({}, diagnostic.range),
63+
// },
64+
// message:
65+
// 'This may be due to a bad file extension/path, or incorrect capitalization.',
66+
// },
67+
// ];
68+
// }
69+
// diagnostics.push(diagnostic);
70+
// }
5671
}
5772

5873
// Send the computed diagnostics to VSCode.

packages/server/webpack.config.js

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1+
//@ts-check
2+
13
const { composePlugins, withNx, withWeb } = require('@nrwl/webpack');
24

35
const path = require('path');
4-
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
6+
const { TsconfigPathsPlugin } = require('tsconfig-paths-webpack-plugin');
57

68
// Nx plugins for webpack.
79
module.exports = composePlugins(withNx(), withWeb(), (config) => {
810
// Update the webpack config as needed here.
911
// e.g. `config.plugins.push(new MyPlugin())`
12+
1013
config.mode = 'none'; // this leaves the source code as close as possible to the original (when packaging we set this to 'production')
1114
config.target = 'node'; // extensions run in a node context
1215
config.node = {
@@ -17,10 +20,11 @@ module.exports = composePlugins(withNx(), withWeb(), (config) => {
1720
plugins: [
1821
new TsconfigPathsPlugin({
1922
configFile: path.join(__dirname, 'tsconfig.app.json'),
23+
logLevel: 'INFO',
2024
}),
2125
],
2226
mainFields: ['module', 'main'],
23-
extensions: ['.ts', '.js'], // support ts-files and js-files
27+
extensions: ['.ts', '.js', '.node'], // support ts-files and js-files
2428
};
2529

2630
config.module = {
@@ -41,12 +45,21 @@ module.exports = composePlugins(withNx(), withWeb(), (config) => {
4145
},
4246
],
4347
},
48+
{
49+
test: /\.node$/,
50+
loader: 'node-loader',
51+
},
4452
],
4553
};
4654
config.externals = {
4755
vscode: 'commonjs vscode', // ignored because it doesn't exist
56+
'tree-sitter': 'commonjs tree-sitter',
57+
'@keqingmoe/tree-sitter': 'commonjs @keqingmoe/tree-sitter',
58+
'tree-sitter-ccini': 'commonjs ../../tree-sitter-ccini',
4859
};
4960

61+
config.output = config.output || {};
62+
5063
config.output.libraryTarget = 'commonjs2';
5164
// config.output.filename = 'extension.js';
5265

@@ -66,7 +79,9 @@ module.exports = composePlugins(withNx(), withWeb(), (config) => {
6679
extension: './src/extension.ts',
6780
};
6881

69-
config.output.devtoolModuleFilenameTemplate = function (info) {
82+
config.output.devtoolModuleFilenameTemplate = function (
83+
/** @type {{ absoluteResourcePath: string; }} */ info
84+
) {
7085
const rel = path.relative(process.cwd(), info.absoluteResourcePath);
7186
return `webpack:///./${rel}`;
7287
};

0 commit comments

Comments
 (0)