バージョン

カスタム診断および注釈 (Syntax Parsing Engine)

トピックの概要

目的

このトピックは、構文ツリーにデータを追加、取得する方法について説明します。

前提条件

本トピックの理解を深めるために、以下のトピックを参照することをお勧めします。

トピック 目的

このトピックは、Syntax Parsing Engine の概要を示します。

このトピックは、Syntax Parsing Engine の文章校正の概要を示します。

このトピックは、構文ツリーが作成される場合とアクセス方法について説明します。

このトピックの内容

このトピックは、以下のセクションで構成されます。

概要

概要

構文ツリーから情報を取得するには、ツリー上にも情報を保存します。ツリー内の SyntaxTree およびすべてのオブジェクトは不変であり、そのため追加情報を保存する唯一の方法は、含まれる追加データのあるツリーのコピーを作成することです。これは、診断情報 (セマンティック エラーまたは警告など) または注釈のために実施します。どの種類のデータでもかまいません。このデータをツリーにアタッチできるメソッドは、SyntaxTree 上で定義されます。

注:

Note

注釈または診断情報をアタッチすると新しいツリーが作成され、元のツリーと同じスナップショットが含まれます。どちらのツリーも同じテキスト コンテンツを表し、同一ノード構造を有し、論理的に「兄弟ツリー」とみなされます。ノード構造が同じであるため、情報をツリーにアタッチする場合にいずれかの兄弟ツリーからノードを指定できます。

注釈の追加

注釈のサマリー

注釈をアタッチするには、SyntaxTreeAddAnnotation メソッドを使用して、アタッチする SyntaxAnnotation を提供します。SyntaxAnnotation クラスは、いずれかのデータをノードにアタッチできるように導出できます。結果として、AddAnnotation メソッドは、指定されたノードにアタッチされた新しい注釈で構文ツリーのコピーを返します。

特定のノードに関する注釈情報を得るには、 HasAnnotations プロパティを使用して特定のノードに注釈があるかどうか、特定のノードにアタッチされた注釈を取得するための GetAnnotations オーバーロード メソッド、およびそのノードのサブツリー内に注釈のあるノードを列挙するための GetAnnotatedNodes オーバーロード メソッドがあるかどうかを判断します。ここで説明したメソッドはどちらも Type をとるオーバーロードを有するため、その SyntaxAnnotation インスタンスが特定のタイプであるまたは導出された注釈を持つノードまたは注釈を取得します。

以下は、構文ツリーに注釈のアタッチ方法例です。

Visual Basic の場合:

Dim document = New TextDocument()
document.Language = CSharpLanguage.Instance
' ...ドキュメントを解析します。
Dim originalTree = document.SyntaxTree
Dim node1 = originalTree.RootNode.GetChild(0)
Dim node2 = originalTree.RootNode.GetChild(1)
Dim annotatedTree = originalTree.AddAnnotation(node1, New SyntaxAnnotation())
Dim annotatedTreeAgain = annotatedTree.AddAnnotation(node2, New SyntaxAnnotation())

C# の場合:

var document = new TextDocument();
document.Language = CSharpLanguage.Instance;
// ...ドキュメントを解析します。
var originalTree = document.SyntaxTree;
var node1 = originalTree.RootNode.GetChild(0);
var node2 = originalTree.RootNode.GetChild(1);
var annotatedTree = originalTree.AddAnnotation(node1, new SyntaxAnnotation());
var annotatedTreeAgain = annotatedTree.AddAnnotation(node2, new SyntaxAnnotation());

注:

Note

node2 をどのように originalTree から取得するものの annotatedTree に渡すかにご注意ください。これは、originalTreeannotatedTree および annotatedTreeAgain が兄弟ツリーであるためルール違反ではありません。

診断の追加

診断のサマリー

診断情報をアタッチするには、 Diagnostic と診断をアタッチするツリー ノードを取得する SyntaxTreeAddDiagnostic メソッドを使用します。結果として、AddDiagnostic メソッドは、指定されたノードにアタッチされた新しい注釈で構文ツリーのコピーを返します。

診断情報を取得するには、 ContainsDiagnostics プロパティと GetDiagnostics メソッドを SyntaxNode クラス上で使用します。これらのメソッドは、Syntax Parsing Engine の診断とカスタム診断を区別しないため、これらのメンバーはすべての診断情報を自動的にノードとその子孫から返します。

以下は、構文ツリーに診断のアタッチ方法例です。

Visual Basic の場合:

Dim document = New TextDocument()
document.Language = CSharpLanguage.Instance
' ...ドキュメントを解析します。
Dim syntaxNode = document.SyntaxTree.RootNode.GetChild(0)
Dim newTree = document.SyntaxTree.AddDiagnostic( _
    syntaxNode, _
    New Diagnostic( _
            New TextSpan(syntaxNode.LeadingIgnoredContentLength, syntaxNode.GetText().Trim().Length), _
                         "Something wrong happened!", _
                         DiagnosticSeverity.Warning))

C# の場合:

var document = new TextDocument();
document.Language = CSharpLanguage.Instance;
// ...ドキュメントを解析します。
var syntaxNode = document.SyntaxTree.RootNode.GetChild(0);
var newTree = document.SyntaxTree.AddDiagnostic(
    syntaxNode,
    new Diagnostic(
        new TextSpan(syntaxNode.LeadingIgnoredContentLength, syntaxNode.GetText().Trim().Length),
                     "Something wrong happened!",
                     DiagnosticSeverity.Warning));

構文ツリーの取得と変更

概要

解析操作が完了した後、 TextDocument に戻される前に、新しく作成された構文ツリーを取得するには、 LanguageBase クラスに定義される SyntaxTreeCreated イベントにハンドラーをアタッチします。 SyntaxTreeCreatedEventArgs クラスは取得/設定可能な SyntaxTree プロパティを公開します。このプロパティを AddAnnotation または AddDiagnostic メソッドから返された新しい SyntaxTree に設定できます。この方法で、カスタム診断および注釈を xamSyntaxEditor で表示できます。

以下は、 SyntaxTreeCreated イベントにイベント ハンドラーをアタッチする方法の例です。

Visual Basic の場合:

Me.xamSyntaxEditor1.Document.Language.SyntaxTreeCreated += Language_SyntaxTreeCreated
Private Sub Language_SyntaxTreeCreated(sender As Object, e As SyntaxTreeCreatedEventArgs)
    Dim syntaxNode = e.SyntaxTree.RootNode.GetChild(0)
    ' 診断を追加
    Dim newTree = e.SyntaxTree.AddDiagnostic(syntaxNode, New Diagnostic(New TextSpan(syntaxNode.LeadingIgnoredContentLength, syntaxNode.GetText().Trim().Length), "Something wrong happened!", DiagnosticSeverity.Warning))
    ' 注釈を追加
    Dim anotherNewTree = newTree.AddAnnotation(newTree.RootNode.GetChild(0), New SyntaxAnnotation())
    e.SyntaxTree = anotherNewTree
End Sub

C# の場合:

this.xamSyntaxEditor1.Document.Language.SyntaxTreeCreated += Language_SyntaxTreeCreated;
void Language_SyntaxTreeCreated(object sender, SyntaxTreeCreatedEventArgs e)
{
    var syntaxNode = e.SyntaxTree.RootNode.GetChild(0);
    // 診断を追加
    var newTree = e.SyntaxTree.AddDiagnostic(
        syntaxNode,
        new Diagnostic(
            new TextSpan(syntaxNode.LeadingIgnoredContentLength, syntaxNode.GetText().Trim().Length),
            "Something wrong happened!",
            DiagnosticSeverity.Warning));
    // 注釈を追加
    var anotherNewTree = newTree.AddAnnotation(
        newTree.RootNode.GetChild(0), new SyntaxAnnotation());
    e.SyntaxTree = anotherNewTree;
}

関連コンテンツ

トピック

このトピックの追加情報については、以下のトピックも合わせてご参照ください。

トピック 目的

このトピックは、構文解析中に起こる無視されたコンテンツへのアクセス方法について説明します。

このトピックでは、Syntax Parsing Engine が行う構文ツリーのプルーニングについて説明します。