Skip to content

Commit

Permalink
refactor: Use collect_breaking_versions from v2 directly in PG
Browse files Browse the repository at this point in the history
  • Loading branch information
Xanewok committed Jun 4, 2024
1 parent 12e0c18 commit 3acf212
Show file tree
Hide file tree
Showing 6 changed files with 18 additions and 49 deletions.
20 changes: 4 additions & 16 deletions crates/codegen/language/definition/src/model/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,27 +36,15 @@ impl Language {
}

/// Collects all versions that change the language grammar in a breaking way.
///
/// Includes the first supported version.
pub fn collect_breaking_versions(&self) -> BTreeSet<Version> {
let first = self.versions.first().unwrap().clone();
let mut res = BTreeSet::from_iter([first]);

let mut add_spec = |spec: &Option<VersionSpecifier>| {
let Some(spec) = spec else {
return;
};

match spec.clone() {
VersionSpecifier::Never => (),
VersionSpecifier::From { from } => {
res.insert(from);
}
VersionSpecifier::Till { till } => {
res.insert(till);
}
VersionSpecifier::Range { from, till } => {
res.insert(from);
res.insert(till);
}
if let Some(spec) = spec {
res.extend(spec.versions().cloned());
}
};

Expand Down
7 changes: 5 additions & 2 deletions crates/codegen/runtime/cargo/src/runtime/language.rs.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ use crate::parser_support::{
#[cfg_attr(feature = "slang_napi_interfaces", napi(namespace = "language"))]
pub struct Language {
{%- if not rendering_in_stubs -%}
{%- for version in model.parser.referenced_versions -%}
{%- for version in model.breaking_versions -%}
{% if loop.first %} {# The first supported version may not be referenced by the items #}
#[allow(dead_code)]
{% endif %}
pub(crate) version_is_at_least_{{ version | replace(from=".", to="_") }}: bool,
{%- endfor -%}
{%- endif -%}
Expand Down Expand Up @@ -68,7 +71,7 @@ impl Language {
if Self::SUPPORTED_VERSIONS.binary_search(&version).is_ok() {
Ok(Self {
{%- if not rendering_in_stubs -%}
{%- for version in model.parser.referenced_versions %}
{%- for version in model.breaking_versions %}
version_is_at_least_{{ version | replace(from=".", to="_") }}: Version::new({{ version | split(pat=".") | join(sep=", ") }}) <= version,
{%- endfor -%}
{%- endif -%}
Expand Down
2 changes: 2 additions & 0 deletions crates/codegen/runtime/generator/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::parser::ParserModel;
pub struct RuntimeModel {
/// Defines the `Language::SUPPORTED_VERSIONS` field.
all_versions: BTreeSet<Version>,
breaking_versions: BTreeSet<Version>,
parser: ParserModel,
ast: AstModel,
kinds: KindsModel,
Expand All @@ -22,6 +23,7 @@ impl RuntimeModel {
pub fn from_language(language: &Rc<Language>) -> Self {
Self {
all_versions: language.versions.iter().cloned().collect(),
breaking_versions: language.collect_breaking_versions(),
ast: AstModel::create(language),
parser: ParserModel::from_language(language),
kinds: KindsModel::create(language),
Expand Down
34 changes: 3 additions & 31 deletions crates/codegen/runtime/generator/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
use std::collections::{BTreeMap, BTreeSet};
use std::rc::Rc;

use codegen_language_definition::model::{Identifier, Language, VersionSpecifier};
use semver::Version;
use codegen_language_definition::model::{Identifier, Language};
use serde::Serialize;

mod codegen;
Expand All @@ -16,8 +15,8 @@ use codegen::{
};
use grammar::{
Grammar, GrammarVisitor, KeywordScannerAtomic, KeywordScannerDefinitionRef,
ParserDefinitionNode, ParserDefinitionRef, PrecedenceParserDefinitionRef,
ScannerDefinitionNode, ScannerDefinitionRef, TriviaParserDefinitionRef,
ParserDefinitionNode, ParserDefinitionRef, PrecedenceParserDefinitionRef, ScannerDefinitionRef,
TriviaParserDefinitionRef,
};

/// Newtype for the already generated Rust code, not to be confused with regular strings.
Expand All @@ -26,9 +25,6 @@ struct RustCode(String);

#[derive(Default, Serialize)]
pub struct ParserModel {
/// Constructs inner `Language` the state to evaluate the version-dependent branches.
referenced_versions: BTreeSet<Version>,

/// Defines the top-level scanner functions in `Language`.
scanner_functions: BTreeMap<Identifier, RustCode>, // (name of scanner, code)
// Defines the `Lexer::next_terminal` method.
Expand Down Expand Up @@ -61,9 +57,6 @@ struct ScannerContextModel {

#[derive(Default)]
struct ParserAccumulatorState {
/// Constructs inner `Language` the state to evaluate the version-dependent branches.
referenced_versions: BTreeSet<Version>,

// Defines the `Lexer::next_terminal` method.
scanner_contexts: BTreeMap<Identifier, ScannerContextAccumulatorState>,

Expand Down Expand Up @@ -192,7 +185,6 @@ impl ParserAccumulatorState {
.collect();

ParserModel {
referenced_versions: self.referenced_versions,
parser_functions: self.parser_functions,
trivia_parser_functions: self.trivia_parser_functions,
// These are derived from the accumulated state
Expand All @@ -209,15 +201,6 @@ impl GrammarVisitor for ParserAccumulatorState {
.insert(scanner.name().clone(), Rc::clone(scanner));
}

fn keyword_scanner_definition_enter(&mut self, scanner: &KeywordScannerDefinitionRef) {
for def in scanner.definitions() {
let specifiers = def.enabled.iter().chain(def.reserved.iter());

self.referenced_versions
.extend(specifiers.flat_map(VersionSpecifier::versions).cloned());
}
}

fn trivia_parser_definition_enter(&mut self, parser: &TriviaParserDefinitionRef) {
self.set_current_context(parser.context().clone());

Expand Down Expand Up @@ -254,19 +237,8 @@ impl GrammarVisitor for ParserAccumulatorState {
);
}

fn scanner_definition_node_enter(&mut self, node: &ScannerDefinitionNode) {
if let ScannerDefinitionNode::Versioned(_, version_specifier) = node {
self.referenced_versions
.extend(version_specifier.versions().cloned());
}
}

fn parser_definition_node_enter(&mut self, node: &ParserDefinitionNode) {
match node {
ParserDefinitionNode::Versioned(_, version_specifier) => {
self.referenced_versions
.extend(version_specifier.versions().cloned());
}
ParserDefinitionNode::ScannerDefinition(scanner) => {
self.top_level_scanner_names.insert(scanner.name().clone());

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.

0 comments on commit 3acf212

Please sign in to comment.