Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 105 additions & 11 deletions src/dotnet/APIView/APIView/Model/StructuredTokenModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,44 +5,138 @@

namespace APIView.TreeToken
{
/// <summary>
/// Represents the type of a structured token.
/// All tokens should be content except for spacing tokens and url.
/// </summary>
public enum StructuredTokenKind
{
/// <summary>
/// Specifies that the token is content.
/// This is the default value for a token.
/// </summary>
Content = 0,
/// <summary>
/// Space token indicating switch to new line.
/// </summary>
LineBreak = 1,
NonBreakingSpace = 2,
/// <summary>
/// Regular single space.
/// </summary>
NoneBreakingSpace = 2,
/// <summary>
/// 4 NonBreakingSpaces.
/// </summary>
TabSpace = 3,
/// <summary>
/// Use this between method parameters. Depending on user setting this would result in a single space or new line.
/// </summary>
ParameterSeparator = 4,
/// <summary>
/// A url token should have `LinkText` property i.e `token.Properties["LinkText"]` and the url/link should be the token value.
/// </summary>
Url = 5
}

/// <summary>
/// Used to represent a APIView token its properties and tags for APIView parsers.
/// Represents an APIView token its properties and tags for APIView parsers.
/// </summary>

public class StructuredToken
{
public HashSet<string> Tags
{
get { return TagsObj.Count > 0 ? TagsObj : null; }
set { TagsObj = value ?? new HashSet<string>(); }
}
/// <summary>
/// Token Id.
/// Previously known as DefinitionId.
/// </summary>
public string Id { get; set; }

/// <summary>
/// Represents the type of a structured token.
/// </summary>
public StructuredTokenKind Kind { get; set; } = StructuredTokenKind.Content;

/// <summary>
/// The token value which will be displayed. Spacing tokens don't need to have value as it will be
/// replaced at deserialization based on the Token Kind.
/// </summary>
public string Value { get; set; } = string.Empty;

/// <summary>
/// Properties of the token.
/// <list type="bullet">
/// <item>
/// <description>GroupId: `doc` to group consecutive comment tokens as documentation.</description>
/// </item>
/// <item>
/// <description>NavigateToId: When the token is clicked, will navigate to the location that matches the provided token id.</description>
/// </item>
/// </list>
/// </summary>
public Dictionary<string, string> Properties
{
get { return PropertiesObj.Count > 0 ? PropertiesObj : null; }
set { PropertiesObj = value ?? new Dictionary<string, string>(); }
}

/// <summary>
/// List of default CSS configuration for any language.
/// Languages can override these or add new classes by reaching out to the APIView team.
/// <list type="bullet">
/// <item>
/// <description>comment</description>
/// </item>
/// <item>
/// <description>keyword</description>
/// </item>
/// <item>
/// <description>literal</description>
/// </item>
/// <item>
/// <description>mname: member name</description>
/// </item>
/// <item>
/// <description>punc</description>
/// </item>
/// <item>
/// <description>sliteral: string literal</description>
/// </item>
/// <item>
/// <description>text</description>
/// </item>
/// <item>
/// <description>tname: type name</description>
/// </item>
/// </list>
/// </summary>
public HashSet<string> RenderClasses
{
get { return RenderClassesObj.Count > 0 ? RenderClassesObj : null; }
set { RenderClassesObj = value ?? new HashSet<string>(); }
}
public string Value { get; set; } = string.Empty;
public string Id { get; set; }
public StructuredTokenKind Kind { get; set; } = StructuredTokenKind.Content;

/// <summary>
/// Behavioral boolean properties
/// <list type="bullet">
/// <item>
/// <description>Deprecated: Mark a node as deprecated</description>
/// </item>
/// <item>
/// <description>SkipDiff: Indicate that a node should not be used in computation of diff.</description>
/// </item>
/// </list>
/// </summary>
public HashSet<string> Tags
{
get { return TagsObj.Count > 0 ? TagsObj : null; }
set { TagsObj = value ?? new HashSet<string>(); }
}

[JsonIgnore]
public HashSet<string> TagsObj { get; set; } = new HashSet<string>();

[JsonIgnore]
public Dictionary<string, string> PropertiesObj { get; set; } = new Dictionary<string, string>();

[JsonIgnore]
public HashSet<string> RenderClassesObj { get; set; } = new HashSet<string>();

Expand Down Expand Up @@ -75,7 +169,7 @@ public static StructuredToken CreateEmptyToken(string id = null)
public static StructuredToken CreateSpaceToken()
{
var token = new StructuredToken();
token.Kind = StructuredTokenKind.NonBreakingSpace;
token.Kind = StructuredTokenKind.NoneBreakingSpace;
return token;
}

Expand Down
107 changes: 89 additions & 18 deletions src/dotnet/APIView/APIView/Model/TokenTreeModel.cs
Original file line number Diff line number Diff line change
@@ -1,47 +1,118 @@
using System.Collections.Generic;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace APIView.TreeToken
{
{
public class APITreeNode
{
public HashSet<string> Tags
/// <summary>
/// Id of the node, which should be unique at the node level. i.e. unique among its siblings.
/// This was previously represented by the DefinitionId for the main Token of the node.
/// </summary>
public string Id { get; set; }

/// <summary>
/// The type of node it is. Using any of the following `assembly`, `class`, `delegate`, `enum`, `interface`,
/// `method` , `namespace`, `package`, `struct`, `type` will get you the corresponding default icons
/// for the page navigation.
/// </summary>
public string Kind { get; set; }

/// <summary>
/// The name of the tree node which will be used as label for the API Navigation.
/// Generally use the name of the module (class, method).
/// </summary>
public string Name { get; set; }

/// <summary>
/// Tokens which are rendered after all child nodes.
/// Depending on the language this would include the closing curly brace and/or empty lines.
/// You can simulate an empty line by adding an empty token (Content token with no value) and a LineBreak token.
/// </summary>
public List<StructuredToken> BottomTokens
{
get { return TagsObj.Count > 0 ? TagsObj : null; }
set { TagsObj = value ?? new HashSet<string>(); }
get { return BottomTokensObj.Count > 0 ? BottomTokensObj : null; }
set { BottomTokensObj = value ?? new List<StructuredToken>(); }
}
/// <summary>
/// The nodes immediate children.
/// For a namespace this would be classes, for a class this would be the class constructors and methods.
/// Children are rendered after TopTokens but before BottomTokens, and are automatically indented.
/// </summary>
public List<APITreeNode> Children
{
get { return ChildrenObj.Count > 0 ? ChildrenObj : null; }
set { ChildrenObj = value ?? new List<APITreeNode>(); }
}
/// <summary>
/// Properties of a node.
/// <list type="bullet">
/// <item>
/// <description>SubKind: Similar to kind, use this to make the node more specific.
/// e.g. `Kind = 'Type'`, and `SubKind = 'class'`. We also use this to make the navigation icon it will override kind.</description>
/// </item>
/// <item>
/// <description>IconName: Use this only if you are looking to add a custom icon different from language wide defaults. New additions will need to be supported APIView side.</description>
/// </item>
/// </list>
/// </summary>
public Dictionary<string, string> Properties
{
get { return PropertiesObj.Count > 0 ? PropertiesObj : null; }
set { PropertiesObj = value ?? new Dictionary<string, string>(); }
}

/// <summary>
/// Behavioral boolean properties.
/// <list type="bullet">
/// <item>
/// <description>Deprecated: Mark a node as deprecated</description>
/// </item>
/// <item>
/// <description>Hidden: Mark a node as Hidden</description>
/// </item>
/// <item>
/// <description>HideFromNavigation: Indicate that a node should be hidden from the page navigation.</description>
/// </item>
/// <item>
/// <description>SkipDiff: Indicate that a node should not be used in computation of diff.</description>
/// </item>
/// <item>
/// <description>CrossLangDefId: The cross language definitionId for the node.</description>
/// </item>
/// </list>
/// </summary>
public HashSet<string> Tags
{
get { return TagsObj.Count > 0 ? TagsObj : null; }
set { TagsObj = value ?? new HashSet<string>(); }
}

/// <summary>
/// The main data of the node. This is all the tokens that actually define the node.
/// When rendering, TopTokens are rendered first, followed by any Children, and then finally BottomTokens
/// </summary>
public List<StructuredToken> TopTokens
{
get { return TopTokensObj.Count > 0 ? TopTokensObj : null; }
set { TopTokensObj = value ?? new List<StructuredToken>(); }
}
public List<StructuredToken> BottomTokens
{
get { return BottomTokensObj.Count > 0 ? BottomTokensObj : null; }
set { BottomTokensObj = value ?? new List<StructuredToken>(); }
}
public List<APITreeNode> Children
{
get { return ChildrenObj.Count > 0 ? ChildrenObj : null; }
set { ChildrenObj = value ?? new List<APITreeNode>(); }
}

public string Name { get; set; }
public string Id { get; set; }
public string Kind { get; set; }

[JsonIgnore]
public HashSet<string> TagsObj { get; set; } = new HashSet<string>();

[JsonIgnore]
public Dictionary<string, string> PropertiesObj { get; set; } = new Dictionary<string, string>();

[JsonIgnore]
public List<StructuredToken> TopTokensObj { get; set; } = new List<StructuredToken>();

[JsonIgnore]
public List<StructuredToken> BottomTokensObj { get; set; } = new List<StructuredToken>();

[JsonIgnore]
public List<APITreeNode> ChildrenObj { get; set; } = new List<APITreeNode>();

Expand Down
Loading