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 support to resolve bindings to built-in functions, types and variables #1101

Merged
merged 39 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
dd6e148
First cut at implementing support for bindings built-in identifiers
ggiraldez Sep 13, 2024
8a7ef47
Move builtins content to the language definition and load during cons…
ggiraldez Sep 13, 2024
9a12700
Move built-ins rendering specific code to the input language
ggiraldez Sep 17, 2024
bf9de78
Make generated built-ins source dependant on the language version
ggiraldez Sep 17, 2024
ba6c84d
Separate built-ins parsing test
ggiraldez Sep 17, 2024
81b9c95
Allow filtering of fields in built-in type per version
ggiraldez Sep 18, 2024
fcc371e
Check built-ins in language definitions for version enablement consis…
ggiraldez Sep 18, 2024
ebd47c4
Make built-in types, functions and variables visible
ggiraldez Sep 18, 2024
486aebb
Simplify built-in parameter and field definitions
ggiraldez Sep 19, 2024
5939f3b
Output a `built-in` marker when found in ambiguous definitions
ggiraldez Sep 20, 2024
bef4458
Rename builtin -> built-in (and similar identifiers)
ggiraldez Sep 20, 2024
c6275db
Refactor: split apart `render_bindings` for readability
ggiraldez Sep 20, 2024
3757c60
Externalize built-ins file path from the graph building rules file
ggiraldez Sep 20, 2024
d6fe128
Use a Vec<String> for built-in parameters definition
ggiraldez Sep 20, 2024
23ecf01
Merge remote-tracking branch 'upstream/main' into builtin-bindings
ggiraldez Oct 2, 2024
ea9cc13
Remove `built_ins()` method in `SpannedLanguage`
ggiraldez Oct 3, 2024
eed92dd
Merge branch 'main' into builtin-bindings
ggiraldez Oct 3, 2024
fbec218
Rework built-ins definitions
ggiraldez Oct 3, 2024
7e05529
Use writeln! to generate the built-ins contents
ggiraldez Oct 3, 2024
904199a
Revamp built-ins generation code
ggiraldez Oct 4, 2024
5c8a842
Track built-ins source files with the CodegenFileSystem
ggiraldez Oct 4, 2024
aaaab29
Add marker reminders to keep built-ins contract name in sync
ggiraldez Oct 4, 2024
3ad2a37
Change the output for ambiguous definitions on bindings snapshots
ggiraldez Oct 4, 2024
6dd6cb9
Use `assert` in bindings snapshots, which is available in all versions
ggiraldez Oct 4, 2024
35412c3
Change status/failure marker semantics for bindings output snapshots
ggiraldez Oct 4, 2024
c38535a
Fix formatting
ggiraldez Oct 4, 2024
96c0c2b
Adding built-ins to bindings is no longer done by default
ggiraldez Oct 4, 2024
0eafae0
Revert unnecessary change
ggiraldez Oct 7, 2024
f08836a
Simplify built-ins import/export in the stack graph
ggiraldez Oct 7, 2024
79f06b5
Support more generic system files to be added to the Bindings API
ggiraldez Oct 7, 2024
d782d33
Updated public_api.txt file
ggiraldez Oct 7, 2024
bd76019
Small refactor to hide some internal functionality
ggiraldez Oct 8, 2024
fb7baf4
Merge branch 'main' into builtin-bindings
ggiraldez Oct 9, 2024
988b205
Rename perf bindings test to init_bindings
ggiraldez Oct 11, 2024
13d6987
Rename FileKind to FileDescriptor
ggiraldez Oct 11, 2024
40ace53
Move language definition built-ins struct into their own module
ggiraldez Oct 11, 2024
fc623fb
Remove `FileDescriptor::Unknown` and revert `PathResolver` to work on…
ggiraldez Oct 11, 2024
974350a
Write generated built-ins source files using CodegenFileSystem
ggiraldez Oct 21, 2024
74748ed
Merge remote-tracking branch 'upstream/main' into builtin-bindings
ggiraldez Oct 21, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ use crate::model::SpannedItemDiscriminants::{
self, Enum, Fragment, Keyword, Precedence, Repeated, Separated, Struct, Token, Trivia,
};
use crate::model::{
Identifier, SpannedEnumItem, SpannedEnumVariant, SpannedField, SpannedFragmentItem,
SpannedItem, SpannedKeywordDefinition, SpannedKeywordItem, SpannedPrecedenceExpression,
Identifier, SpannedBuiltIn, SpannedBuiltInField, SpannedBuiltInFunction, SpannedBuiltInType,
SpannedEnumItem, SpannedEnumVariant, SpannedField, SpannedFragmentItem, SpannedItem,
SpannedKeywordDefinition, SpannedKeywordItem, SpannedPrecedenceExpression,
SpannedPrecedenceItem, SpannedPrecedenceOperator, SpannedPrimaryExpression,
SpannedRepeatedItem, SpannedScanner, SpannedSeparatedItem, SpannedStructItem,
SpannedTokenDefinition, SpannedTokenItem, SpannedTriviaItem, SpannedTriviaParser,
Expand All @@ -39,6 +40,10 @@ pub(crate) fn analyze_references(analysis: &mut Analysis) {
for item in language.items() {
check_item(analysis, item, &enablement);
}

for built_in in &language.built_ins {
check_built_in(analysis, built_in, &enablement);
}
}

fn check_item(analysis: &mut Analysis, item: &SpannedItem, enablement: &VersionSet) {
Expand Down Expand Up @@ -396,6 +401,70 @@ fn check_reference(
}
}

fn check_built_in(analysis: &mut Analysis, built_in: &SpannedBuiltIn, enablement: &VersionSet) {
match built_in {
SpannedBuiltIn::BuiltInFunction { item } => {
check_built_in_function(analysis, item, enablement);
}
SpannedBuiltIn::BuiltInType { item } => {
check_built_in_type(analysis, item, enablement);
}
SpannedBuiltIn::BuiltInVariable { item } => {
check_built_in_field(analysis, item, enablement);
}
}
}

fn check_built_in_function(
analysis: &mut Analysis,
built_in: &SpannedBuiltInFunction,
enablement: &VersionSet,
) {
let SpannedBuiltInFunction {
name: _,
return_type: _,
parameters: _,
enabled,
} = built_in;

let _ = update_enablement(analysis, enablement, enabled);
}

fn check_built_in_type(
analysis: &mut Analysis,
built_in: &SpannedBuiltInType,
enablement: &VersionSet,
) {
let SpannedBuiltInType {
name: _,
fields,
functions,
enabled,
} = built_in;

let enablement = update_enablement(analysis, enablement, enabled);

for field in fields {
check_built_in_field(analysis, field, &enablement);
}
for function in functions {
check_built_in_function(analysis, function, &enablement);
}
}

fn check_built_in_field(
analysis: &mut Analysis,
built_in: &SpannedBuiltInField,
enablement: &VersionSet,
) {
let SpannedBuiltInField {
definition: _,
enabled,
} = built_in;

let _ = update_enablement(analysis, enablement, enabled);
}

fn update_enablement(
analysis: &mut Analysis,
existing_enablement: &VersionSet,
Expand Down
40 changes: 40 additions & 0 deletions crates/codegen/language/definition/src/model/built_ins.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use std::rc::Rc;

use codegen_language_internal_macros::{derive_spanned_type, ParseInputTokens, WriteOutputTokens};
use serde::{Deserialize, Serialize};
use strum_macros::EnumDiscriminants;

use crate::model::VersionSpecifier;

#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[derive_spanned_type(Clone, Debug, EnumDiscriminants, ParseInputTokens, WriteOutputTokens)]
pub enum BuiltIn {
BuiltInFunction { item: Rc<BuiltInFunction> },
BuiltInType { item: Rc<BuiltInType> },
BuiltInVariable { item: Rc<BuiltInField> },
}

#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[derive_spanned_type(Clone, Debug, ParseInputTokens, WriteOutputTokens)]
pub struct BuiltInFunction {
pub name: String,
pub parameters: Vec<String>,
pub return_type: Option<String>,
pub enabled: Option<VersionSpecifier>,
}

#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[derive_spanned_type(Clone, Debug, ParseInputTokens, WriteOutputTokens)]
pub struct BuiltInType {
pub name: String,
pub fields: Vec<BuiltInField>,
pub functions: Vec<BuiltInFunction>,
pub enabled: Option<VersionSpecifier>,
}

#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[derive_spanned_type(Clone, Debug, ParseInputTokens, WriteOutputTokens)]
pub struct BuiltInField {
pub definition: String,
pub enabled: Option<VersionSpecifier>,
}
45 changes: 44 additions & 1 deletion crates/codegen/language/definition/src/model/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use indexmap::IndexSet;
use semver::Version;
use serde::{Deserialize, Serialize};

use crate::model::{Field, Identifier, Item, TriviaParser, VersionSpecifier};
use crate::model::{BuiltIn, Field, Identifier, Item, TriviaParser, VersionSpecifier};

#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[derive_spanned_type(Clone, Debug, ParseInputTokens, WriteOutputTokens)]
Expand All @@ -15,6 +15,7 @@ pub struct Language {

pub documentation_dir: PathBuf,
pub binding_rules_file: PathBuf,
pub file_extension: Option<String>,

pub root_item: Identifier,

Expand All @@ -24,6 +25,7 @@ pub struct Language {
pub versions: IndexSet<Version>,

pub sections: Vec<Section>,
pub built_ins: Vec<BuiltIn>,
}

impl Language {
Expand Down Expand Up @@ -104,6 +106,47 @@ impl Language {

res
}

/// Collects all versions that change the language built-ins.
///
/// Includes the first supported version. Returns an empty set if there are
/// no built-ins defined.
pub fn collect_built_ins_versions(&self) -> BTreeSet<Version> {
if self.built_ins.is_empty() {
return BTreeSet::new();
}

let first = self.versions.first().unwrap().clone();
let mut res = BTreeSet::from_iter([first]);

let mut add_spec = |spec: &Option<VersionSpecifier>| {
if let Some(spec) = spec {
res.extend(spec.versions().cloned());
}
};

for item in &self.built_ins {
match item {
BuiltIn::BuiltInFunction { item } => {
add_spec(&item.enabled);
}
BuiltIn::BuiltInType { item } => {
add_spec(&item.enabled);
for field in &item.fields {
add_spec(&field.enabled);
}
for function in &item.functions {
add_spec(&function.enabled);
}
}
BuiltIn::BuiltInVariable { item } => {
add_spec(&item.enabled);
}
}
}

res
}
}

#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
Expand Down
2 changes: 2 additions & 0 deletions crates/codegen/language/definition/src/model/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
mod built_ins;
mod item;
mod manifest;
mod nonterminals;
mod terminals;
mod utils;

pub use built_ins::*;
pub use item::*;
pub use manifest::*;
pub use nonterminals::*;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,12 @@ fn get_spanned_type(input: Type) -> Type {
match type_name.as_str() {
// These are model Types that have a derived 'SpannedXXX' type.
// Let's use that instead:
"EnumItem"
"BuiltIn"
| "BuiltInField"
| "BuiltInFunction"
| "BuiltInParameter"
| "BuiltInType"
| "EnumItem"
| "EnumVariant"
| "Field"
| "FieldDelimiters"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ codegen_language_macros::compile!(Language(
)
]
)]
)]
)],
built_ins = []
));

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ codegen_language_macros::compile!(Language(
Struct(name = Bar2, fields = (field = Required(Bar1)))
]
)]
)]
)],
built_ins = []
));

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ codegen_language_macros::compile!(Language(
)
]
)]
)]
)],
built_ins = []
));

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ codegen_language_macros::compile!(Language(
)
]
)]
)]
)],
built_ins = []
));

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ codegen_language_macros::compile!(Language(
)
]
)]
)]
)],
built_ins = []
));

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ codegen_language_macros::compile!(Language(
definitions = [TokenDefinition(scanner = Atom("bar"))]
)]
)]
)]
)],
built_ins = []
));

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ codegen_language_macros::compile!(Language(
definitions = [TokenDefinition(scanner = Atom(""))]
)]
)]
)]
)],
built_ins = []
));

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ codegen_language_macros::compile!(Language(
sections = [Section(
// title = "Section One"
topics = []
)]
)],
built_ins = []
));

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ codegen_language_macros::compile!(Language(
)],
unrecognized_field = true
)]
)]
)],
built_ins = []
));

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ codegen_language_macros::compile!(Language(
),
Topic(title = "Topic Two", items = [Unrecognized(true)])
]
)]
)],
built_ins = []
));

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ codegen_language_macros::compile!(Language(
Struct(name = Baz2, fields = (field = Required(Baz1)))
]
)]
)]
)],
built_ins = []
));

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ codegen_language_macros::compile!(Language(
)
]
)]
)]
)],
built_ins = []
));

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ codegen_language_macros::compile!(Language(
)
]
)]
)]
)],
built_ins = []
));

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ codegen_language_macros::compile!(Language(
)
]
)]
)]
)],
built_ins = []
));

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ codegen_language_macros::compile!(Language(
Fragment(name = Baz, scanner = Atom("baz"))
]
)]
)]
)],
built_ins = []
));

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ codegen_language_macros::compile!(Language(
)
]
)]
)]
)],
built_ins = []
));

fn main() {}
Loading
Loading