Version

Custom Diagnostics and Annotations

Topic Overview

Purpose

This topic explains how to attach and obtain additional data to and from the syntax tree.

Required background

The following topics are prerequisites to understanding this topic:

Topic Purpose

This topic provides an overview of the Syntax Parsing Engine.

This topic provides an overview of the Syntax Parsing Engine’s Grammar.

This topic explains when the syntax tree is created and how to access it.

In this topic

This topic contains the following sections:

Introduction

Overview

In addition to obtaining information from a syntax tree, you may want to store information on it as well. The SyntaxTree and all objects within it are immutable, so the only way to store additional information is to make a copy of the tree with the additional data included. This can be done for either diagnostic information (such as semantic errors or warnings) or annotations, which can be any kind of data. The methods which allow you to attach this data to the tree are defined on SyntaxTree.

Note
Note

When attaching annotations or diagnostic information a new tree is created containing the same snapshot as the original tree. Both trees represent the same textual content and have an identical node structure and can logically be considered "sibling trees". Since they have the same node structure, you can specify a node from any sibling tree when you want to attach information to a tree.

Adding Annotations

Annotations summary

To attach annotations use the AddAnnotation method of the SyntaxTree and provide the SyntaxAnnotation you want to attach. The SyntaxAnnotation class can be derived so you can attach any data to a node. As a result the AddAnnotation method will return a copy of the Syntax Tree with the new annotation attached to the specified node.

To obtain annotation information on a specific node use the HasAnnotations property to determine whether that specific node has annotations, GetAnnotations overloaded methods for getting the annotations attached to that specific node, and GetAnnotatedNodes overloaded methods for enumerating the nodes with annotations in that node’s sub-tree. Both methods mentioned here have overloads taking a Type so you get annotations or nodes with annotations whose SyntaxAnnotation instances are of the specified Type or derived.

The following is an example of how to attach annotations:

In C#:

var document = new TextDocument();
document.Language = CSharpLanguage.Instance;
// ... Parse a document
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
Note

Notice how node2 is obtained from originalTree but passed to annotatedTree. This is legal because originalTree, annotatedTree, and annotatedTreeAgain are sibling trees.

Adding Diagnostics

Diagnostics summary

To attach diagnostic information use the AddDiagnostic method of the SyntaxTree which takes the Diagnostic and the tree node to which you want to attach the diagnostic. As a result the AddDiagnostic method will return a copy of the Syntax Tree with the new diagnostic attached to the specified node.

To obtain diagnostic information use the ContainsDiagnostics property and the GetDiagnostics methods on the SyntaxNode class. These methods do not distinguish between Syntax Parsing Engine’s diagnostics and custom diagnostics, so those members automatically return all diagnostics information from the node and its descendants.

Related Content

Topics

The following topics provide additional information related to this topic.

Topic Purpose

This topic explains how to access the ignored content produced during syntax analysis.

This topic explains the syntax tree pruning types performed by the Syntax Parsing Engine.