diff --git a/src/diagnostic/index.ts b/src/diagnostic/index.ts index d36bd2e7..1508838b 100644 --- a/src/diagnostic/index.ts +++ b/src/diagnostic/index.ts @@ -1,10 +1,10 @@ -import { Diagnostic, DiagnosticSeverity, Range } from "vscode"; +import { Diagnostic, DiagnosticSeverity, Range, Uri } from "vscode"; export const notFound = ( descriptor: string, match: string, range: Range, - code: DiagnosticCode, + code: DiagnosticCode | DiagnosticCodeObject, ): Diagnostic => ({ message: `${descriptor} [${match}] not found.`, severity: DiagnosticSeverity.Warning, @@ -13,6 +13,11 @@ export const notFound = ( code, }); +export type DiagnosticCodeObject = { + value: DiagnosticCode; + target: Uri; +}; + export type DiagnosticCode = | "appBinding" | "asset" diff --git a/src/features/config.ts b/src/features/config.ts index fcd45141..615963db 100644 --- a/src/features/config.ts +++ b/src/features/config.ts @@ -1,6 +1,6 @@ -import { notFound } from "@src/diagnostic"; +import { DiagnosticCodeObject, notFound } from "@src/diagnostic"; import AutocompleteResult from "@src/parser/AutocompleteResult"; -import { getConfigs } from "@src/repositories/configs"; +import { getConfigPathByName, getConfigs } from "@src/repositories/configs"; import { config } from "@src/support/config"; import { findHoverMatchesInDoc } from "@src/support/doc"; import { detectedRange, detectInDoc } from "@src/support/parser"; @@ -75,7 +75,7 @@ export const linkProvider: LinkProvider = (doc: vscode.TextDocument) => { return null; } - const configItem = getConfigs().items.find( + const configItem = getConfigs().items.configs.find( (config) => config.name === param.value, ); @@ -107,7 +107,7 @@ export const hoverProvider: HoverProvider = ( return null; } - const configItem = getConfigs().items.find( + const configItem = getConfigs().items.configs.find( (config) => config.name === match, ); @@ -159,7 +159,7 @@ export const diagnosticProvider = ( return null; } - const config = getConfigs().items.find( + const config = getConfigs().items.configs.find( (c) => c.name === param.value, ); @@ -167,11 +167,18 @@ export const diagnosticProvider = ( return null; } + const pathToFile = getConfigPathByName(param.value); + + const code = pathToFile ? { + value: "config", + target: vscode.Uri.file(projectPath(pathToFile)), + } as DiagnosticCodeObject : "config"; + return notFound( "Config", param.value, detectedRange(param), - "config", + code, ); }, ); @@ -197,7 +204,7 @@ export const completionProvider: CompletionProvider = { return []; } - return getConfigs().items.map((config) => { + return getConfigs().items.configs.map((config) => { let completeItem = new vscode.CompletionItem( config.name, vscode.CompletionItemKind.Value, diff --git a/src/features/storage.ts b/src/features/storage.ts index 4d20de27..34dee6bd 100644 --- a/src/features/storage.ts +++ b/src/features/storage.ts @@ -22,7 +22,7 @@ export const linkProvider: LinkProvider = (doc: vscode.TextDocument) => { toFind, getPaths, ({ param, item }) => { - const configItem = getConfigs().items.find( + const configItem = getConfigs().items.configs.find( (c) => c.name === `filesystems.disks.${param.value}`, ); @@ -48,7 +48,7 @@ export const diagnosticProvider = ( toFind, getConfigs, ({ param, item, index }) => { - const config = getConfigs().items.find( + const config = getConfigs().items.configs.find( (c) => c.name === `filesystems.disks.${param.value}`, ); @@ -83,7 +83,7 @@ export const completionProvider: CompletionProvider = { } return getConfigs() - .items.filter((config) => { + .items.configs.filter((config) => { return ( config.name.startsWith("filesystems.disks.") && config.name.split(".").length === 3 diff --git a/src/features/translation.ts b/src/features/translation.ts index 72f6441b..48b6635d 100644 --- a/src/features/translation.ts +++ b/src/features/translation.ts @@ -1,7 +1,8 @@ -import { notFound } from "@src/diagnostic"; +import { DiagnosticCodeObject, notFound } from "@src/diagnostic"; import AutocompleteResult from "@src/parser/AutocompleteResult"; import { getTranslationItemByName, + getTranslationPathByName, getTranslations, TranslationItem, } from "@src/repositories/translations"; @@ -9,7 +10,7 @@ import { config } from "@src/support/config"; import { findHoverMatchesInDoc } from "@src/support/doc"; import { detectedRange, detectInDoc } from "@src/support/parser"; import { wordMatchRegex } from "@src/support/patterns"; -import { relativePath } from "@src/support/project"; +import { projectPath, relativePath } from "@src/support/project"; import { contract, createIndexMapping, facade } from "@src/support/util"; import { AutocompleteParsingResult } from "@src/types"; import * as vscode from "vscode"; @@ -179,22 +180,32 @@ export const diagnosticProvider = ( doc, toFind, getTranslations, - ({ param, index }) => { + ({ param, index, item }) => { if (index !== 0) { return null; } - const item = getTranslationItemByName(param.value); + const translation = getTranslationItemByName(param.value); - if (item) { + if (translation) { return null; } + const pathToFile = getTranslationPathByName( + param.value, + getLang(item as AutocompleteParsingResult.MethodCall) + ); + + const code = pathToFile ? { + value: "translation", + target: vscode.Uri.file(projectPath(pathToFile)), + } as DiagnosticCodeObject : "translation"; + return notFound( "Translation", param.value, detectedRange(param), - "translation", + code, ); }, ); diff --git a/src/repositories/configs.ts b/src/repositories/configs.ts index cea56b83..86137ce9 100644 --- a/src/repositories/configs.ts +++ b/src/repositories/configs.ts @@ -2,20 +2,42 @@ import { repository } from "."; import { Config } from ".."; import { runInLaravel, template } from "../support/php"; -export const getConfigs = repository({ +interface ConfigGroupResult { + configs: Config[]; + paths: string[]; +} + +export const getConfigPathByName = (match: string): string | undefined => { + const filePath = match.replace(/\.[^.]+$/, '').replaceAll('.', '/'); + + return getConfigs().items.paths.find((path) => { + return !path.startsWith('vendor/') && path.endsWith(`${filePath}.php`); + }); +}; + +export const getConfigs = repository({ load: () => { return runInLaravel(template("configs"), "Configs").then( - (result) => - result.map((item) => { - return { - name: item.name, - value: item.value, - file: item.file, - line: item.line, - }; - }), + (result) => { + console.log('result', result); + + return { + configs: result.map((item) => { + return { + name: item.name, + value: item.value, + file: item.file, + line: item.line, + }; + }), + paths: [...new Set(result.filter(item => typeof item.file === 'string').map(item => item.file))] + } as ConfigGroupResult; + } ); }, pattern: ["config/{,*,**/*}.php", ".env"], - itemsDefault: [], + itemsDefault: { + configs: [], + paths: [], + }, }); diff --git a/src/repositories/translations.ts b/src/repositories/translations.ts index ae98df46..c609745d 100644 --- a/src/repositories/translations.ts +++ b/src/repositories/translations.ts @@ -18,6 +18,7 @@ interface TranslationGroupResult { [key: string]: TranslationItem; }; languages: string[]; + paths: string[]; } interface TranslationGroupPhpResult { @@ -66,6 +67,7 @@ const load = () => { default: res.default, translations: result, languages: res.languages, + paths: res.paths, }; }); }; @@ -74,6 +76,16 @@ export const getTranslationItemByName = (match: string): TranslationItem | undef return getTranslations().items.translations[match.replaceAll('\\', '')]; }; +export const getTranslationPathByName = (match: string, lang: string | undefined): string | undefined => { + lang = lang ?? getTranslations().items.default; + + const fileName = match.replace(/^.*::/, '').replace(/\.[^.]+$/, ''); + + return getTranslations().items.paths.find((path) => { + return !path.startsWith('vendor/') && path.endsWith(`${lang}/${fileName}.php`); + }); +}; + export const getTranslations = repository({ load, pattern: () => @@ -88,5 +100,6 @@ export const getTranslations = repository({ default: "", translations: {}, languages: [], + paths: [], }, });