Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add generated language-definition.json #1206

Merged
merged 1 commit into from
Dec 31, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions Cargo.lock

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
@@ -1,9 +1,8 @@
use std::fmt::Debug;
use std::path::{Path, PathBuf};
use std::path::PathBuf;
use std::rc::Rc;

use indexmap::{IndexMap, IndexSet};
use infra_utils::paths::PathExtensions;
use proc_macro2::Ident;
use semver::Version;
use syn::parse::ParseStream;
Expand Down Expand Up @@ -100,7 +99,7 @@ impl ParseInputTokens for PathBuf {
fn parse_value(input: ParseStream<'_>, errors: &mut ErrorsCollection) -> Result<Self> {
let value = String::parse_value(input, errors)?;

Ok(Path::repo_path(value))
Ok(PathBuf::from(value))
}
}

Expand Down
14 changes: 14 additions & 0 deletions crates/codegen/language/definition/src/model/built_ins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,37 @@ pub enum BuiltIn {
#[derive_spanned_type(Clone, Debug, ParseInputTokens, WriteOutputTokens)]
pub struct BuiltInFunction {
pub name: String,

#[serde(skip_serializing_if = "Vec::is_empty")]
pub parameters: Vec<String>,

#[serde(skip_serializing_if = "Option::is_none")]
pub return_type: Option<String>,

#[serde(skip_serializing_if = "Option::is_none")]
pub enabled: Option<VersionSpecifier>,
}

#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[derive_spanned_type(Clone, Debug, ParseInputTokens, WriteOutputTokens)]
pub struct BuiltInType {
pub name: String,

#[serde(skip_serializing_if = "Vec::is_empty")]
pub fields: Vec<BuiltInField>,

#[serde(skip_serializing_if = "Vec::is_empty")]
pub functions: Vec<BuiltInFunction>,

#[serde(skip_serializing_if = "Option::is_none")]
pub enabled: Option<VersionSpecifier>,
}

#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[derive_spanned_type(Clone, Debug, ParseInputTokens, WriteOutputTokens)]
pub struct BuiltInField {
pub definition: String,

#[serde(skip_serializing_if = "Option::is_none")]
pub enabled: Option<VersionSpecifier>,
}
3 changes: 2 additions & 1 deletion crates/codegen/language/definition/src/model/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,8 @@ impl Section {
#[derive_spanned_type(Clone, Debug, ParseInputTokens, WriteOutputTokens)]
pub struct Topic {
pub title: String,
pub notes_file: Option<String>,

#[serde(skip_serializing_if = "Option::is_none")]
pub lexical_context: Option<Identifier>,

pub items: Vec<Item>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::model::{Identifier, VersionSpecifier};
pub struct EnumItem {
pub name: Identifier,

#[serde(skip_serializing_if = "Option::is_none")]
pub enabled: Option<VersionSpecifier>,

pub variants: Vec<EnumVariant>,
Expand All @@ -18,5 +19,6 @@ pub struct EnumItem {
pub struct EnumVariant {
pub reference: Identifier,

#[serde(skip_serializing_if = "Option::is_none")]
pub enabled: Option<VersionSpecifier>,
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use crate::model::{Identifier, VersionSpecifier};
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[derive_spanned_type(Clone, Debug, ParseInputTokens, WriteOutputTokens)]
pub struct FieldsErrorRecovery {
#[serde(skip_serializing_if = "Option::is_none")]
pub terminator: Option<Identifier>,

#[serde(skip_serializing_if = "Option::is_none")]
pub delimiters: Option<FieldDelimiters>,
}

Expand All @@ -15,12 +18,14 @@ pub struct FieldsErrorRecovery {
pub struct FieldDelimiters {
pub open: Identifier,
pub close: Identifier,

/// How many tokens have to be matched to trigger the error recovery.
/// For ambiguous syntaxes this needs to be set to at least N, where N
/// is the token lookahead required to disambiguate the syntax.
///
/// By default, we assume no lookahead (0) is required to recover from
/// unrecognized body between delimiters, so it's always triggered.
#[serde(skip_serializing_if = "Option::is_none")]
pub terminals_matched_acceptance_threshold: Option<u8>,
}

Expand All @@ -33,6 +38,7 @@ pub enum Field {
Optional {
reference: Identifier,

#[serde(skip_serializing_if = "Option::is_none")]
enabled: Option<VersionSpecifier>,
},
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::model::{Field, FieldsErrorRecovery, Identifier, VersionSpecifier};
pub struct PrecedenceItem {
pub name: Identifier,

#[serde(skip_serializing_if = "Option::is_none")]
pub enabled: Option<VersionSpecifier>,

pub precedence_expressions: Vec<Rc<PrecedenceExpression>>,
Expand All @@ -30,9 +31,12 @@ pub struct PrecedenceExpression {
pub struct PrecedenceOperator {
pub model: OperatorModel,

#[serde(skip_serializing_if = "Option::is_none")]
pub enabled: Option<VersionSpecifier>,

#[serde(skip_serializing_if = "Option::is_none")]
pub error_recovery: Option<FieldsErrorRecovery>,

pub fields: IndexMap<Identifier, Field>,
}

Expand All @@ -50,5 +54,6 @@ pub enum OperatorModel {
pub struct PrimaryExpression {
pub reference: Identifier,

#[serde(skip_serializing_if = "Option::is_none")]
pub enabled: Option<VersionSpecifier>,
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ pub struct RepeatedItem {
pub name: Identifier,
pub reference: Identifier,

#[serde(skip_serializing_if = "Option::is_none")]
pub enabled: Option<VersionSpecifier>,

#[serde(skip_serializing_if = "Option::is_none")]
pub allow_empty: Option<bool>,
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ pub struct SeparatedItem {
pub reference: Identifier,
pub separator: Identifier,

#[serde(skip_serializing_if = "Option::is_none")]
pub enabled: Option<VersionSpecifier>,

#[serde(skip_serializing_if = "Option::is_none")]
pub allow_empty: Option<bool>,
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ use crate::model::{Field, FieldsErrorRecovery, Identifier, VersionSpecifier};
pub struct StructItem {
pub name: Identifier,

#[serde(skip_serializing_if = "Option::is_none")]
pub enabled: Option<VersionSpecifier>,

#[serde(skip_serializing_if = "Option::is_none")]
pub error_recovery: Option<FieldsErrorRecovery>,

pub fields: IndexMap<Identifier, Field>,
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::model::{Identifier, Scanner, VersionSpecifier};
pub struct FragmentItem {
pub name: Identifier,

#[serde(skip_serializing_if = "Option::is_none")]
pub enabled: Option<VersionSpecifier>,

pub scanner: Scanner,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@ pub struct KeywordItem {
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[derive_spanned_type(Clone, Debug, ParseInputTokens, WriteOutputTokens)]
pub struct KeywordDefinition {
#[serde(skip_serializing_if = "Option::is_none")]
pub enabled: Option<VersionSpecifier>,

/// When the keyword is reserved, i.e. can't be used in other position (e.g. as a name)
#[serde(skip_serializing_if = "Option::is_none")]
pub reserved: Option<VersionSpecifier>,
// Underlying keyword scanner (i.e. identifier scanner)

/// Underlying keyword scanner (i.e. identifier scanner)
pub value: KeywordValue,
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub struct TokenItem {
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[derive_spanned_type(Clone, Debug, ParseInputTokens, WriteOutputTokens)]
pub struct TokenDefinition {
#[serde(skip_serializing_if = "Option::is_none")]
pub enabled: Option<VersionSpecifier>,

pub scanner: Scanner,
Expand Down
8 changes: 2 additions & 6 deletions crates/codegen/language/tests/src/pass/tiny_language.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
use std::path::Path;

use codegen_language_definition::model::{
Field, Item, Language, Scanner, Section, StructItem, TokenDefinition, TokenItem, Topic,
TriviaParser,
};
use infra_utils::paths::PathExtensions;
use semver::Version;

codegen_language_macros::compile!(Language(
Expand Down Expand Up @@ -49,8 +46,8 @@ fn definition() {
tiny::TinyDefinition::create(),
Language {
name: "Tiny".into(),
documentation_dir: Path::repo_path("tiny/docs"),
binding_rules_file: Path::repo_path("tiny/bindings/rules.msgb"),
documentation_dir: "tiny/docs".into(),
binding_rules_file: "tiny/bindings/rules.msgb".into(),
file_extension: Some(".tiny".into()),
root_item: "Foo".into(),
leading_trivia: TriviaParser::Sequence { parsers: [].into() },
Expand All @@ -65,7 +62,6 @@ fn definition() {
title: "Section One".into(),
topics: vec![Topic {
title: "Topic One".into(),
notes_file: None,
lexical_context: None,
items: [
Item::Struct {
Expand Down
6 changes: 4 additions & 2 deletions crates/codegen/runtime/generator/src/bindings/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::BTreeSet;
use std::path::Path;

use anyhow::Result;
use codegen_language_definition::model;
Expand All @@ -17,9 +18,10 @@ pub struct BindingsModel {
impl BindingsModel {
pub fn from_language(language: &model::Language) -> Result<Self> {
// We use `CodegenFileSystem` here to ensure the rules are rebuilt if the rules file changes
let binding_rules_dir = language.binding_rules_file.unwrap_parent();
let binding_rules_file = Path::repo_path(&language.binding_rules_file);
let binding_rules_dir = binding_rules_file.unwrap_parent();
let mut fs = CodegenFileSystem::new(binding_rules_dir)?;
let binding_rules_source = fs.read_file(&language.binding_rules_file)?;
let binding_rules_source = fs.read_file(&binding_rules_file)?;
let built_ins_versions = language.collect_built_ins_versions();
let file_extension = language.file_extension.clone().unwrap_or_default();

Expand Down
1 change: 1 addition & 0 deletions crates/codegen/spec/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Inflector = { workspace = true }
infra_utils = { workspace = true }
itertools = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }

[lints]
workspace = true
2 changes: 1 addition & 1 deletion crates/codegen/spec/src/generators/topic_page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub fn generate_topic_page(
}
}

let documentation_dir = model.language.documentation_dir.strip_repo_root()?;
let documentation_dir = &model.language.documentation_dir;

writeln!(buffer)?;
writeln!(
Expand Down
9 changes: 8 additions & 1 deletion crates/codegen/spec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use std::rc::Rc;
use anyhow::Result;
use codegen_language_definition::model::Language;
use infra_utils::codegen::CodegenFileSystem;
use infra_utils::paths::PathExtensions;

use crate::generators::grammar_ebnf::generate_grammar_ebnf;
use crate::generators::navigation::{SpecDir, SpecPage};
Expand All @@ -26,7 +27,13 @@ pub struct Spec;

impl Spec {
pub fn generate(language: Rc<Language>, output_dir: &Path) -> Result<()> {
let mut fs = CodegenFileSystem::new(&language.documentation_dir)?;
let documentation_dir = Path::repo_path(&language.documentation_dir);
let mut fs = CodegenFileSystem::new(documentation_dir)?;

fs.write_file(
output_dir.join("language-definition.json"),
serde_json::to_string(&language)?,
)?;

let model = SpecModel::build(language);
let public_dir = Self::generate_public_dir(&model)?;
Expand Down
Loading