prh-languageserver
Advanced tools
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No License Found
License(Experimental) License information could not be found.
Found 1 instance in 1 package
24385
0
316
+ Addeddiff@4.0.2(transitive)
+ Addedprh@5.4.4(transitive)
- Removeddiff@3.5.0(transitive)
- Removedprh@4.0.0(transitive)
Updatedprh@^5.3.0