目次
基本原理
実践的な実装
最初にクライアントでサーバーを作成します
全体プロセス
クライアントから渡された Vue コード テキストを処理する場合、vue/compiler-dom を通じて ast 形式のデータ構造の 3 つの部分 (テンプレート、JS、CSS) に解析する必要があります。現在のフロントエンド コードでは TypeScript が使用されており、JS 部分は AST に解析されないため、babel/parser を使用して TypeScript コードを解析し、最終的な JS AST データ構造を生成する必要があります。
コードの構文ツリーを取得した後、各コード ノードをチェックして、それが準拠しているかどうかを判断する必要があります。コード レビューの要件があるため、各ノードを処理するには構文ツリーをたどる必要があります。
3. 发现不合规代码,生成诊断
4. 提供快速修复
总结
ホームページ 開発ツール VSCode VSCode プラグイン開発の実践: コード診断プラグインの実装

VSCode プラグイン開発の実践: コード診断プラグインの実装

Feb 16, 2022 pm 08:01 PM
vscode プラグイン開発

この記事では、VSCode プラグイン開発の実践、コード診断プラグインの開発、基本原則の分析、およびそれを段階的に実装する方法について説明します。みんな!

VSCode プラグイン開発の実践: コード診断プラグインの実装

最近、コード レビュー ガイドを社内で公開しました。しかし、コード レビュー プロセスには多くの時間がかかります。人々はコードをあまり注意深くレビューしません。プラグインを使って作業を楽にしたい 開発者は開発段階で書き込みミスを感知することができ、その効果は以下の通りです

Kapture 2022-02-10 at 15.36.49.gif

以下にその方法を紹介します。そのような機能を最初から実装します。

基本原理

Visual Studio Codeのプログラミング言語の機能拡張は、Language Serverで実装されています。これはわかりやすいですね。結局のところ、言語機能のチェックはパフォーマンスを消費し、別のプロセスを起動する必要があります。言語サービス。これは Language Server 言語サーバーです。 [推奨学習: 「vscode 入門チュートリアル 」]

Language Server は、多くのプログラミング言語の編集エクスペリエンスを提供する特別な Visual Studio Code 拡張機能です。言語サーバーを使用すると、オートコンプリート、エラー チェック (診断)、定義へのジャンプ、および VS Code でサポートされるその他の多くの言語機能を実装できます。

サーバーによって提供される構文チェック機能があるため、クライアントは言語サーバーに接続してからサーバーと対話する必要があります。たとえば、ユーザーは言語サーバー上でコードを編集するときに言語チェックを実行します。クライアント。具体的な操作は次のとおりです:

VSCode プラグイン開発の実践: コード診断プラグインの実装

Vue ファイルを開くと、プラグインが有効になり、言語サーバーが起動します。ドキュメントが変更されると、言語サーバーはコードを再診断し、診断結果をクライアントに送信します。

コード診断の効果は、波線が表示され、マウスを上に移動するとプロンプト メッセージが表示されることです。クイック フィックスがある場合は、ポップの下にクイック フィックス ボタンが表示されます。プロンプト ウィンドウを起動

実践的な実装

#コード診断の基本原則を理解した後、実装を開始しました。上記の基本原則から、次のことが必要であることがわかります。 2 つの主要な機能を実装します。

  • # クライアントと言語サーバー間の対話

  • # 言語サーバーの診断とクイック修復機能
クライアントと言語サーバー間の対話

公式ドキュメント

に例が示されています。これは、プレーン テキスト ファイル用の単純な言語サーバーであり、これに基づいて変更できます。この例。

最初にクライアントでサーバーを作成します

// client/src/extension.ts
export function activate(context: ExtensionContext) {
    ...
    const clientOptions: LanguageClientOptions = {
        documentSelector: [{ scheme: 'file', language: 'vue' }], // 打开 vue 文件时才激活
        ...
    };
    client = new LanguageClient(...);
    client.start();
}
ログイン後にコピー

次に、server/src/server.ts にクライアント側の対話ロジックを記述します。ドキュメントが変更されたときは、コードを確認してください:

// server/src/server.ts
import {
    createConnection
    TextDocuments,
    ProposedFeatures,
    ...
} from 'vscode-languageserver/node';
const connection = createConnection(ProposedFeatures.all);
const documents: TextDocuments<TextDocument> = new TextDocuments(TextDocument);
documents.onDidChangeContent(change => {
    // 文档发生变化时,校验文档
    validateTextDocument(change.document);
});

async function validateTextDocument(textDocument: TextDocument): Promise<void> {
    ...
    // 拿到诊断结果
    const diagnostics = getDiagnostics(textDocument, settings);
    // 发给客户端
    connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
}
// 提供快速修复的操作
connection.onCodeAction(provideCodeActions);

async function provideCodeActions(params: CodeActionParams): Promise<CodeAction[]> {
    ...
    return quickfix(textDocument, params);
}
ログイン後にコピー

クライアントとサーバー間の上記の対話が完了すると、2 つのメソッド

getDiagnostics(textDocument, settings)

および quickfix に気づくことができます。 ( textDocument、params)。これら 2 つの方法は、それぞれ診断データを提供し、ドキュメントの迅速な修復操作を提供します。

コード診断

全体プロセス

VSCode プラグイン開発の実践: コード診断プラグインの実装

1. コードドキュメントを AST 構文に変換します。ツリー

クライアントから渡された Vue コード テキストを処理する場合、vue/compiler-dom を通じて ast 形式のデータ構造の 3 つの部分 (テンプレート、JS、CSS) に解析する必要があります。現在のフロントエンド コードでは TypeScript が使用されており、JS 部分は AST に解析されないため、babel/parser を使用して TypeScript コードを解析し、最終的な JS AST データ構造を生成する必要があります。

const VueParser = require(&#39;@vue/compiler-dom&#39;);
// 该函数返回诊断结果客户端
function getDiagnostics(textDocument: TextDocument, settings: any): Diagnostic[] {
	const text = textDocument.getText();
	const res = VueParser.parse(text);
	const [template, script] = res.children;
	return [
		...analyzeTemplate(template), // 解析 template 得到诊断结果
		...analyzeScript(script, textDocument), // 解析 js 得到诊断结果
	];
}
// 分析 js 语法
function analyzeScript(script: any, textDocument: TextDocument) {
  const scriptAst = parser.parse(script.children[0]?.content, {
    sourceType: &#39;module&#39;,
    plugins: [
      &#39;typescript&#39;, // typescript
      [&#39;decorators&#39;, { decoratorsBeforeExport: true }], // 装饰器
      &#39;classProperties&#39;, // ES6 class 写法
      &#39;classPrivateProperties&#39;,
    ],
  });
ログイン後にコピー

取得した AST 構文ツリー構造は次のとおりです。

テンプレート AST

VSCode プラグイン開発の実践: コード診断プラグインの実装JS AST

VSCode プラグイン開発の実践: コード診断プラグインの実装##2. 構文ツリーをたどってコードを確認する

コードの構文ツリーを取得した後、各コード ノードをチェックして、それが準拠しているかどうかを判断する必要があります。コード レビューの要件があるため、各ノードを処理するには構文ツリーをたどる必要があります。

深さ優先検索を使用してテンプレートの AST を走査します:

function deepLoopData(
  data: AstTemplateInterface[],
  handler: Function,
  diagnostics: Diagnostic[],
) {
  function dfs(data: AstTemplateInterface[]) {
    for (let i = 0; i < data.length; i++) {
      handler(data[i], diagnostics); // 在这一步对代码进行处理
      if (data[i]?.children?.length) {
        dfs(data[i].children);
      } else {
        continue;
      }
    }
  }
  dfs(data);
}

function analyzeTemplate(template: any) {
  const diagnostics: Diagnostic[] = [];
  deepLoopData(template.children, templateHandler, diagnostics);
  return diagnostics;
}
function templateHandler(currData: AstTemplateInterface, diagnostics: Diagnostic[]){
   // ...对代码节点检查
}
ログイン後にコピー

JS AST 走査の場合、babel/traverse 走査を使用できます:

 traverse(scriptAst, {
    enter(path: any) {
      ...
    }
 }
ログイン後にコピー

3. 发现不合规代码,生成诊断

根据 ast 语法节点去判断语法是否合规,如果不符合要求,需要在代码处生成诊断,一个基础的诊断对象(diagnostics)包括下面几个属性:

  • range: 诊断有问题的范围,也就是画波浪线的地方

  • severity: 严重性,分别有四个等级,不同等级标记的颜色不同,分别是:

    • Error: 1
    • Warning: 2
    • Information:3
    • Hint:4
  • message: 诊断的提示信息

  • source: 来源,比如说来源是 Eslint

  • data:携带数据,可以将修复好的数据放在这里,用于后面的快速修复功能

比如实现一个提示函数过长的诊断:

function isLongFunction(node: Record<string, any>) {
  return (
    // 如果结束位置的行 - 开始位置的行 > 80 的话,我们认为这个函数写得太长了
    node.type === &#39;ClassMethod&#39; && node.loc.end.line - node.loc.start.line > 80
  );
}
ログイン後にコピー

在遍历 AST 时如果遇到某个节点是出现函数过长的时候,就往诊断数据中添加此诊断

traverse(scriptAst, {
    enter(path: any) {
        const { node } = path;
        if (isLongFunction(node)) {
            const diagnostic: Diagnostic ={
                severity: DiagnosticSeverity.Warning,
                range: getPositionRange(node, scriptStart),
                message: &#39;尽可能保持一个函数的单一职责原则,单个函数不宜超过 80 行&#39;,
                source: &#39;Code Review 指南&#39;,
            }
            diagnostics.push(diagnostic);
        }
        ...   
    }
});
ログイン後にコピー

文档中所有的诊断结果会保存在 diagnostics 数组中,最后通过交互返回给客户端。

4. 提供快速修复

上面那个函数过长的诊断没办法快速修复,如果能快速修复的话,可以将修正后的结果放在 diagnostics.data 。换个例子写一个快速修复, 比如 Vue template 属性排序不正确,我们需要把代码自动修复

// attributeOrderValidator 得到判断结果 和 修复后的代码
const {isGoodSort, newText} = attributeOrderValidator(props, currData.loc.source);
    if (!isGoodSort) {
      const range = {
        start: {
          line: props[0].loc.start.line - 1,
          character: props[0].loc.start.column - 1,
        },
        end: {
          line: props[props.length - 1].loc.end.line - 1,
          character: props[props.length - 1].loc.end.column - 1,
        },
      }
      let diagnostic: Diagnostic = genDiagnostics(
        &#39;vue template 上的属性顺序&#39;,
        range
      );
      if (newText) { // 如果有修复后的代码
        // 将快速修复数据保存在 diagnostic.data
        diagnostic.data = {
          title: &#39;按照 Code Review 指南的顺序修复&#39;,
          newText,
        }
      }
      diagnostics.push(diagnostic);
    }
ログイン後にコピー

quickfix(textDocument, params)

export function quickfix(
  textDocument: TextDocument,
  params: CodeActionParams
): CodeAction[] {
  const diagnostics = params.context.diagnostics;
  if (isNullOrUndefined(diagnostics) || diagnostics.length === 0) {
    return [];
  }
  const codeActions: CodeAction[] = [];
  diagnostics.forEach((diag) => {
    if (diag.severity === DiagnosticSeverity.Warning) {
      if (diag.data) { // 如果有快速修复数据
        // 添加快速修复
        codeActions.push({
          title: (diag.data as any)?.title,
          kind: CodeActionKind.QuickFix, // 快速修复
          diagnostics: [diag], // 属于哪个诊断的操作
          edit: {
            changes: {
                [params.textDocument.uri]: [
                  {
                    range: diag.range,
                    newText: (diag.data as any)?.newText, // 修复后的内容
                  },
                ],
              },
           },
        });
    } 
  }
});
ログイン後にコピー

有快速修复的诊断会保存在 codeActions 中,并且返回给客户端, 重新回看交互的代码,在 documents.onDidChangeContent 事件中,通过 connection.sendDiagnostics({ uri: textDocument.uri, diagnostics }) 把诊断发送给客户端。quickfix 结果通过 connection.onCodeAction 发给客户端。

import {
    createConnection
    TextDocuments,
    ProposedFeatures,
    ...
} from &#39;vscode-languageserver/node&#39;;
const connection = createConnection(ProposedFeatures.all);
const documents: TextDocuments<TextDocument> = new TextDocuments(TextDocument);
documents.onDidChangeContent(change => {
    ...
    // 拿到诊断结果
    const diagnostics = getDiagnostics(textDocument, settings);
    // 发给客户端
    connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
});

// 提供快速修复的操作
connection.onCodeAction(provideCodeActions);

async function provideCodeActions(params: CodeActionParams): Promise<CodeAction[]> {
    ...
    return quickfix(textDocument, params);
}
ログイン後にコピー

总结

实现一个代码诊断的插件功能,需要两个步骤,首先建立语言服务器,并且建立客户端与语言服务器的交互。接着需要 服务器根据客户端的代码进行校验,把诊断结果放入 Diagnostics,快速修复结果放在 CodeActions,通过与客户端的通信,把两个结果返回给客户端,客户端即可出现黄色波浪线的问题提示。

更多关于VSCode的相关知识,请访问:vscode教程!!

以上がVSCode プラグイン開発の実践: コード診断プラグインの実装の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

VSCODEに必要なコンピューター構成 VSCODEに必要なコンピューター構成 Apr 15, 2025 pm 09:48 PM

VSコードシステムの要件:オペレーティングシステム:オペレーティングシステム:Windows 10以降、MACOS 10.12以上、Linux Distributionプロセッサ:最小1.6 GHz、推奨2.0 GHz以上のメモリ:最小512 MB、推奨4 GB以上のストレージスペース:最低250 MB以上:その他の要件を推奨:安定ネットワーク接続、XORG/WAYLAND(Linux)

vscodeのヘッダーファイルを定義する方法 vscodeのヘッダーファイルを定義する方法 Apr 15, 2025 pm 09:09 PM

ビジュアルスタジオコードを使用してヘッダーファイルを定義する方法は?ヘッダーファイルを作成し、.hまたは.hpp接尾辞名(クラス、関数、変数など)を使用してヘッダーファイルにシンボルを宣言し、#includeディレクティブを使用してプログラムをコンパイルして、ソースファイルにヘッダーファイルを含めます。ヘッダーファイルが含まれ、宣言された記号が利用可能になります。

vscode端子使用チュートリアル vscode端子使用チュートリアル Apr 15, 2025 pm 10:09 PM

VSCODEビルトインターミナルは、エディター内でコマンドとスクリプトを実行して開発プロセスを簡素化できるようにする開発ツールです。 VSCODE端子の使用方法:ショートカットキー(CTRL/CMD)で端子を開きます。コマンドを入力するか、スクリプトを実行します。 Hotkeys(Ctrl Lなどの端子をクリアするなど)を使用します。作業ディレクトリ(CDコマンドなど)を変更します。高度な機能には、デバッグモード、自動コードスニペット完了、およびインタラクティブコマンド履歴が含まれます。

vscodeでコードを書く場所 vscodeでコードを書く場所 Apr 15, 2025 pm 09:54 PM

Visual Studioコード(VSCODE)でコードを作成するのはシンプルで使いやすいです。 VSCODEをインストールし、プロジェクトの作成、言語の選択、ファイルの作成、コードの書き込み、保存して実行します。 VSCODEの利点には、クロスプラットフォーム、フリーおよびオープンソース、強力な機能、リッチエクステンション、軽量で高速が含まれます。

vscode中国の注釈が疑問符になるという問題を解決する方法 vscode中国の注釈が疑問符になるという問題を解決する方法 Apr 15, 2025 pm 11:36 PM

Visual Studioコードで中国のコメントが疑問符になるという問題を解決する方法:ファイルのエンコーディングを確認し、「BOMなしでUTF-8」であることを確認します。フォントを「歌のスタイル」や「Microsoft Yahei」などの漢字をサポートするフォントに変更します。フォントを再インストールします。 Unicodeサポートを有効にします。 VSCODEをアップグレードし、コンピューターを再起動し、ソースファイルを再作成します。

VSCODE端子の共通コマンド VSCODE端子の共通コマンド Apr 15, 2025 pm 10:06 PM

VSコード端子の一般的なコマンドには、端子画面のクリア(クリア)、現在のディレクトリファイル(LS)のリスト、現在のワーキングディレクトリ(CD)、現在のワーキングディレクトリパス(PWD)の印刷、新しいディレクトリ(MKDIR)の作成、空のディレクトリ(RMDIR)の削除、新しいファイルの作成(RM)の削除(RM)、COPのコピー(RM)、 (MV)ファイルコンテンツの表示(CAT)ファイルコンテンツを表示してスクロール(より少ない)ファイルコンテンツを表示するだけです(その他)ファイルの最初の数行(ヘッド)を表示する

VSCODE端子コマンドは使用できません VSCODE端子コマンドは使用できません Apr 15, 2025 pm 10:03 PM

VSコード端末コマンドの原因とソリューションは使用できません:必要なツールはインストールされていません(Windows:WSL; MACOS:XCODE LINEツール)パス構成が間違っています(パス環境変数に実行可能ファイルを追加)許可問題(管理者としてのコードの実行)ファイアウォールまたはプロキシ制限制限(チェック設定、無制限) (再インストールまたは更新)端子構成は互換性がありません(異なる端子タイプまたはコマンドを試してください)特定の環境変数が欠落しています(必要な環境変数を設定します)

VSCODE前の次のショートカットキー VSCODE前の次のショートカットキー Apr 15, 2025 pm 10:51 PM

VSコードワンステップ/次のステップショートカットキー使用法:ワンステップ(後方):Windows/Linux:Ctrl←; macOS:CMD←次のステップ(フォワード):Windows/Linux:Ctrl→; macOS:CMD→

See all articles