Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

prh-languageserver

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

prh-languageserver - npm Package Compare versions

Comparing version 0.2.0 to 0.3.0

213

lib/index.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("fs");
const path = require("path");
const prh_1 = require("prh");

@@ -13,2 +12,4 @@ const vscode_uri_1 = require("vscode-uri");

this.documents = documents;
this.state = "valid" /* valid */;
this.engineCache = {};
this.validationCache = {};

@@ -26,3 +27,2 @@ this.connection.onInitialize(arg => this.onInitialized(arg));

onInitialized(params) {
this.workspaceRoot = params.rootUri || params.rootPath;
return {

@@ -57,83 +57,36 @@ capabilities: {

this.enable = !!settings.prh.enable;
this.configPath = settings.prh.configFile || "prh.yml";
this.loadConfig();
this.configPaths = settings.prh.configFiles || [];
this.checkConfig();
this.documents.all().forEach(document => this.validateAndSendDiagnostics(document));
}
loadConfig() {
this.connection.console.log(`loadConfig: ${this.configPath}`);
this.validationCache = {};
if (!fs.existsSync(this.configPath)) {
this.connection.console.log(`Config file not exists: ${this.configPath}`);
this.engine = null;
this.documents.all().forEach(document => {
this.connection.sendDiagnostics({ uri: document.uri, diagnostics: [] });
});
return;
}
this.engine = prh_1.fromYAMLFilePath(this.configPath);
this.documents.all().forEach(document => this.sendValidationDiagnostics(document));
}
onDidChangeContent(change) {
this.sendValidationDiagnostics(change.document);
this.validateAndSendDiagnostics(change.document);
}
onDidChangeWatchedFiles(change) {
if (this.workspaceRoot == null) {
return;
}
let configUri = vscode_uri_1.default.parse(this.workspaceRoot);
configUri = configUri.with({
path: path.resolve(configUri.path, this.configPath),
this.connection.console.log(`onDidChangeWatchedFiles: ${JSON.stringify(change, null, 2)}`);
// 設定ファイルのいずれかが変更されたらキャッシュを捨てる
// TODO: 既知の問題として、imports先のymlファイルの更新を検出できない 自力でやるしかない…?
const configChanged = change.changes.some(change => {
const uri = vscode_uri_1.default.parse(change.uri);
return Object.keys(this.engineCache).some(concatenatedRulePaths => {
// 若干雑な条件だけど間違っててもさほど痛くないのでOK
// rulePathはpwdからの相対パス表現なので注意
const rulePaths = concatenatedRulePaths.split("|");
return rulePaths.some(rulePath => {
if (uri.path.endsWith(rulePath)) {
this.connection.console.log(`matched: ${uri.path} - ${rulePath}`);
return true;
}
return false;
});
});
});
const configChanged = change.changes.filter(change => change.uri === configUri.toString());
if (configChanged) {
this.loadConfig();
this.checkConfig();
this.documents.all().forEach(document => this.validateAndSendDiagnostics(document));
}
}
documentValidate(textDocument) {
if (!this.engine || !this.enable) {
return null;
}
if (this.validationCache[textDocument.uri] && this.validationCache[textDocument.uri].version === textDocument.version) {
return this.validationCache[textDocument.uri].changeSet;
}
this.validationCache[textDocument.uri] = null;
const changeSet = this.engine.makeChangeSet(textDocument.uri, textDocument.getText());
if (!changeSet) {
return null;
}
this.validationCache[textDocument.uri] = {
version: textDocument.version,
changeSet,
};
return changeSet;
}
sendValidationDiagnostics(textDocument) {
const changeSet = this.documentValidate(textDocument);
if (!changeSet) {
return;
}
const diagnostics = changeSet.diffs.map(diff => {
const start = textDocument.positionAt(diff.index);
const end = textDocument.positionAt(diff.tailIndex);
let message;
if (diff.rule && diff.rule.raw && diff.rule.raw.prh) {
message = `→${diff.expected || "??"} ${diff.rule.raw.prh}`;
}
else {
message = `→${diff.expected || "??"}`;
}
return {
severity: vscode_languageserver_1.DiagnosticSeverity.Warning,
range: {
start,
end,
},
message,
source: "prh",
};
});
this.connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
}
onCodeAction(params) {
const textDocument = this.documents.get(params.textDocument.uri);
const changeSet = this.documentValidate(textDocument);
const changeSet = this.makeChangeSet(textDocument);
if (!changeSet) {

@@ -154,7 +107,7 @@ return [];

range: params.range,
newText: diff.expected || diff.matches[0],
newText: diff.newText || "??",
},
};
return {
title: `→ ${diff.expected}`,
title: `→ ${diff.newText || "??"}`,
command: "replace",

@@ -177,2 +130,107 @@ arguments: [commandParams],

}
invalidateCache() {
this.engineCache = {};
this.validationCache = {};
}
checkConfig() {
this.configPaths = this.configPaths || [];
this.connection.console.log(`loadConfig: ${this.configPaths.join(", ") || "implicit"}`);
this.invalidateCache();
for (let configPath of this.configPaths) {
if (!fs.existsSync(configPath)) {
this.connection.console.log(`rule file not exists: ${configPath}`);
if (this.state !== "invalid" /* invalid */) {
this.connection.window.showWarningMessage(`prh: 指定された設定ファイルが見つかりません ${configPath}`);
}
this.state = "invalid" /* invalid */;
this.documents.all().forEach(document => this.clearDiagnostics(document));
return;
}
}
this.state = "valid" /* valid */;
}
makeChangeSet(textDocument) {
if (!this.enable || this.state === "invalid" /* invalid */) {
return null;
}
if (this.validationCache[textDocument.uri] && this.validationCache[textDocument.uri].version === textDocument.version) {
return this.validationCache[textDocument.uri].changeSet;
}
delete this.validationCache[textDocument.uri];
let configPaths;
if (this.configPaths && this.configPaths[0]) {
configPaths = this.configPaths;
}
else {
const contentUri = vscode_uri_1.default.parse(textDocument.uri);
if (contentUri.scheme !== "file") {
return null;
}
let foundPath = prh_1.getRuleFilePath(contentUri.path);
if (!foundPath) {
this.connection.console.log(`rule file not found for ${textDocument.uri}`);
return null;
}
this.connection.console.log(`rule file found: ${foundPath}`);
configPaths = [foundPath];
}
let engine = this.engineCache[configPaths.join("|")];
if (!engine) {
try {
engine = prh_1.fromYAMLFilePaths(...configPaths);
}
catch (e) {
this.connection.console.error(e);
if (e instanceof Error) {
this.connection.window.showErrorMessage(`prh: \`${e.message}\` from ${configPaths.join(" ,")}`);
return null;
}
}
this.engineCache[configPaths.join("|")] = engine;
}
const changeSet = engine.makeChangeSet(textDocument.uri, textDocument.getText());
if (!changeSet) {
return null;
}
this.validationCache[textDocument.uri] = {
version: textDocument.version,
changeSet,
};
return changeSet;
}
makeDiagnostic(textDocument) {
const changeSet = this.makeChangeSet(textDocument);
if (!changeSet) {
return null;
}
return changeSet.diffs.map(diff => {
const start = textDocument.positionAt(diff.index);
const end = textDocument.positionAt(diff.tailIndex);
let message;
this.connection.console.log(JSON.stringify(diff));
diff.apply(textDocument.getText());
if (diff.rule && diff.rule.raw && diff.rule.raw.prh) {
message = `→${diff.newText || "??"} ${diff.rule.raw.prh}`;
}
else {
message = `→${diff.newText || "??"}`;
}
return {
severity: vscode_languageserver_1.DiagnosticSeverity.Warning,
range: {
start,
end,
},
message,
source: "prh",
};
});
}
validateAndSendDiagnostics(textDocument) {
const diagnostics = this.makeDiagnostic(textDocument);
this.connection.sendDiagnostics({ uri: textDocument.uri, diagnostics: diagnostics || [] });
}
clearDiagnostics(textDocument) {
this.connection.sendDiagnostics({ uri: textDocument.uri, diagnostics: [] });
}
executeReplace(args) {

@@ -183,2 +241,3 @@ if (!args.arguments || !args.arguments[0]) {

const commandParams = args.arguments[0];
this.connection.console.log(JSON.stringify(commandParams));
const textDocument = this.documents.get(commandParams.uri);

@@ -206,3 +265,3 @@ if (commandParams.version !== textDocument.version) {

const textDocument = this.documents.get(args.arguments[0]);
const changeSet = this.documentValidate(textDocument);
const changeSet = this.makeChangeSet(textDocument);
if (!changeSet) {

@@ -229,3 +288,3 @@ return;

range: { start, end },
newText: diff.expected || diff.matches[0],
newText: diff.newText || "??",
};

@@ -232,0 +291,0 @@ }

@@ -5,3 +5,4 @@ {

"description": "Language Server of prh",
"version": "0.2.0",
"version": "0.3.0",
"license": "MIT",
"publisher": "vvakame",

@@ -19,3 +20,3 @@ "engines": {

"dependencies": {
"prh": "^4.0.0",
"prh": "^5.3.0",
"vscode-languageserver": "3.2.2",

@@ -22,0 +23,0 @@ "vscode-uri": "1.0.1"

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc