Skip to content

Commit

Permalink
complete public API documentation (#1212)
Browse files Browse the repository at this point in the history
Adds `typedoc` linter, and fixes all violations in the public API.

See the config in `crates/solidity/outputs/npm/package/typedoc.mjs` for
more info.
  • Loading branch information
OmarTawfik authored Jan 9, 2025
1 parent 2fda675 commit 111e24a
Show file tree
Hide file tree
Showing 69 changed files with 10,697 additions and 2,198 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,25 @@
)]
#[strum(serialize_all = "snake_case")]
#[derive(Clone, Copy)]
/// Represents the different types of relationships between nodes in the syntax tree.
pub enum EdgeLabel {
// Built-in:
{# Built-in: #}

{% for label in model.kinds.predefined_labels -%}
/// Represents a child node with the label `{{ label | snake_case }}`.
{{ label | pascal_case }},
{%- endfor %}

// Generated:
{# Generated: #}

{% if rendering_in_stubs -%}
Stub1,
Stub2,
Stub3,
{%- else -%}
{% for variant in model.kinds.labels -%}
{{ variant | pascal_case }},
{% for label in model.kinds.labels -%}
/// Represents a child node with the label `{{ label | snake_case }}`.
{{ label | pascal_case }},
{%- endfor -%}
{%- endif -%}
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@ pub enum NonterminalKind {
Stub3,
{%- else -%}
{%- for variant in model.kinds.nonterminal_kinds -%}
/// Represents a node with kind `{{ variant.id | pascal_case }}`, having the following structure:
///
/// ```ebnf
{{ variant.documentation | indent(prefix = "/// ", first = true, blank = true) }}
{%- for line in variant.documentation | split(pat="\n") %}
/// {{ line }}
{%- endfor %}
/// ```
{{ variant.id }},
{{ variant.id | pascal_case }},
{%- endfor -%}
{%- endif -%}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,27 @@
#[allow(clippy::doc_markdown)]
#[allow(clippy::doc_link_with_quotes)]
pub enum TerminalKind {
// Built-in:
{# Built-in: #}

UNRECOGNIZED,
MISSING,

// Generated:
{# Generated: #}

{% if rendering_in_stubs -%}
Stub1,
Stub2,
Stub3,
{%- else -%}
{%- for variant in model.kinds.terminal_kinds -%}
/// Represents a node with kind `{{ variant.id | pascal_case }}`, having the following structure:
///
/// ```ebnf
{{ variant.documentation | indent(prefix = "/// ", first = true, blank = true) }}
{%- for line in variant.documentation | split(pat="\n") %}
/// {{ line }}
{%- endfor %}
/// ```
{{ variant.id }},
{{ variant.id | pascal_case }},
{%- endfor -%}
{%- endif -%}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
interface ast {
use cst.{node, nonterminal-node};

/// @internal
resource selectors {
sequence: static func(node: borrow<nonterminal-node>) -> result<list<option<node>>, string>;
choice: static func(node: borrow<nonterminal-node>) -> result<node, string>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ interface compilation {
///
/// This is an internal API, and exposed via a public `CompilationBuilder` wrapper class written in TypeScript.
/// This allows storing/invoking user supplied callbacks in TypeScript, rather than Rust, which has its limitations.
///
/// @internal
resource internal-compilation-builder {
/// Creates a new compilation builder for the specified language version.
create: static func(language-version: string) -> result<internal-compilation-builder, string>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ interface cst {
stub3,
{%- else %}
{%- for variant in model.kinds.nonterminal_kinds %}
/// This kind represents a `{{ variant.id }}` node, with the following structure:
/// Represents a node with kind `{{ variant.id | pascal_case }}`, having the following structure:
///
/// ```ebnf
{%- for line in variant.documentation | split(pat="\n") %}
Expand Down Expand Up @@ -42,7 +42,7 @@ interface cst {
stub3,
{%- else %}
{%- for variant in model.kinds.terminal_kinds %}
/// This kind represents a `{{ variant.id }}` node, with the following structure:
/// Represents a node with kind `{{ variant.id | pascal_case }}`, having the following structure:
///
/// ```ebnf
{%- for line in variant.documentation | split(pat="\n") %}
Expand All @@ -65,6 +65,7 @@ interface cst {
/// Represents the different types of relationships between nodes in the syntax tree.
enum edge-label {
{%- for label in model.kinds.predefined_labels %}
/// Represents a child node with the label `{{ label | snake_case }}`.
{{ label | wit_case }},
{%- endfor %}

Expand All @@ -76,8 +77,9 @@ interface cst {
/// Generated stub.
stub3,
{%- else %}
{%- for variant in model.kinds.labels %}
{{ variant | wit_case }},
{%- for label in model.kinds.labels %}
/// Represents a child node with the label `{{ label | snake_case }}`.
{{ label | wit_case }},
{%- endfor %}
{%- endif %}
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 44 additions & 7 deletions crates/codegen/runtime/generator/src/ast/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use codegen_ebnf::{EbnfModel, PlainWriter};
use codegen_language_definition::model::{self, PredefinedLabel};
use indexmap::{IndexMap, IndexSet};
use serde::Serialize;
Expand All @@ -6,6 +7,8 @@ use serde::Serialize;
pub struct AstModel {
#[serde(skip)]
terminals: IndexSet<model::Identifier>,
#[serde(skip)]
ebnf: Option<EbnfModel>,

pub sequences: Vec<Sequence>,
pub choices: Vec<Choice>,
Expand All @@ -16,6 +19,7 @@ pub struct AstModel {
#[derive(Serialize)]
pub struct Sequence {
pub parent_type: model::Identifier,
pub ebnf: String,

pub fields: Vec<Field>,
}
Expand All @@ -33,6 +37,7 @@ pub struct Field {
#[derive(Serialize)]
pub struct Choice {
pub parent_type: model::Identifier,
pub ebnf: String,

pub nonterminal_types: Vec<model::Identifier>,
pub includes_terminals: bool,
Expand All @@ -41,6 +46,7 @@ pub struct Choice {
#[derive(Serialize)]
pub struct Repeated {
pub parent_type: model::Identifier,
pub ebnf: String,

/// AST Type of the field, [`None`] if the field is a terminal.
pub item_type: Option<model::Identifier>,
Expand All @@ -49,14 +55,23 @@ pub struct Repeated {
#[derive(Serialize)]
pub struct Separated {
pub parent_type: model::Identifier,
pub ebnf: String,

/// AST Type of the field, [`None`] if the field is a terminal.
pub item_type: Option<model::Identifier>,
}

impl AstModel {
pub fn from_language(language: &model::Language) -> Self {
let mut model = Self::default();
let mut model = Self {
terminals: IndexSet::new(),
ebnf: Some(EbnfModel::build(language)),

sequences: Vec::new(),
choices: Vec::new(),
repeated: Vec::new(),
separated: Vec::new(),
};

// First pass: collect all terminals:
model.collect_terminals(language);
Expand Down Expand Up @@ -129,16 +144,19 @@ impl AstModel {

fn add_struct_item(&mut self, item: &model::StructItem) {
let parent_type = item.name.clone();
let ebnf = self.get_ebnf(&parent_type);
let fields = self.convert_fields(&item.fields).collect();

self.sequences.push(Sequence {
parent_type,
ebnf,
fields,
});
}

fn add_enum_item(&mut self, item: &model::EnumItem) {
let parent_type = item.name.clone();
let ebnf = self.get_ebnf(&parent_type);

let (terminal_types, nonterminal_types) = item
.variants
Expand All @@ -148,16 +166,19 @@ impl AstModel {

self.choices.push(Choice {
parent_type,
ebnf,
nonterminal_types,
includes_terminals: !terminal_types.is_empty(),
});
}

fn add_repeated_item(&mut self, item: &model::RepeatedItem) {
let parent_type = item.name.clone();
let ebnf = self.get_ebnf(&parent_type);

self.repeated.push(Repeated {
parent_type,
ebnf,
item_type: if self.terminals.contains(&item.reference) {
None
} else {
Expand All @@ -168,9 +189,11 @@ impl AstModel {

fn add_separated_item(&mut self, item: &model::SeparatedItem) {
let parent_type = item.name.clone();
let ebnf = self.get_ebnf(&parent_type);

self.separated.push(Separated {
parent_type,
ebnf,
item_type: if self.terminals.contains(&item.reference) {
None
} else {
Expand All @@ -181,6 +204,7 @@ impl AstModel {

fn add_precedence_item(&mut self, item: &model::PrecedenceItem) {
let parent_type = item.name.clone();
let ebnf = self.get_ebnf(&parent_type);

let precedence_expressions = item
.precedence_expressions
Expand All @@ -198,6 +222,7 @@ impl AstModel {

self.choices.push(Choice {
parent_type,
ebnf,
nonterminal_types,
includes_terminals: !terminal_types.is_empty(),
});
Expand All @@ -208,19 +233,20 @@ impl AstModel {
base_name: &model::Identifier,
expression: &model::PrecedenceExpression,
) {
let operand = |label: PredefinedLabel| Field {
label: label.as_ref().into(),
r#type: Some(base_name.clone()),
is_optional: false,
};

let parent_type = expression.name.clone();
let ebnf = self.get_ebnf(&parent_type);

// All operators should have the same structure (validated at compile-time),
// So let's pick up the first one to generate the types:
let operator = &expression.operators[0];
let mut fields = vec![];

let operand = |label: PredefinedLabel| Field {
label: label.as_ref().into(),
r#type: Some(base_name.clone()),
is_optional: false,
};

match operator.model {
model::OperatorModel::Prefix => {
fields.extend(self.convert_fields(&operator.fields));
Expand All @@ -240,6 +266,7 @@ impl AstModel {

self.sequences.push(Sequence {
parent_type,
ebnf,
fields,
});
}
Expand Down Expand Up @@ -268,4 +295,14 @@ impl AstModel {
}
})
}

fn get_ebnf(&self, base_name: &model::Identifier) -> String {
let Some(ebnf) = &self.ebnf else {
return String::new();
};

let mut writer = PlainWriter::default();
ebnf.serialize(base_name, &mut writer).unwrap();
writer.flush()
}
}
Loading

0 comments on commit 111e24a

Please sign in to comment.