Skip to content
This repository has been archived by the owner on Jul 27, 2023. It is now read-only.

Commit

Permalink
Remove Range type parameter from AST nodes (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaReiser authored and zanieb committed Jul 17, 2023
1 parent b8cbc29 commit a95112d
Show file tree
Hide file tree
Showing 14 changed files with 1,026 additions and 1,339 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
- name: run tests with num-bigint
run: cargo test --all --no-default-features --features num-bigint
- name: run tests with malachite-bigint and all features
run: cargo test --all --features malachite-bigint,all-nodes-with-ranges,full-lexer,serde
run: cargo test --all --features malachite-bigint,full-lexer,serde

lint:
name: Check Rust code with rustfmt and clippy
Expand All @@ -55,7 +55,7 @@ jobs:
- name: run clippy
run: cargo clippy --all --no-default-features --features num-bigint
- name: run clippy
run: cargo clippy --all --features malachite-bigint,all-nodes-with-ranges,full-lexer,serde -- -Dwarnings
run: cargo clippy --all --features malachite-bigint,full-lexer,serde -- -Dwarnings

- uses: actions/setup-python@v4
with:
Expand Down
1 change: 0 additions & 1 deletion ast/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ license = "MIT"

[features]
default = ["malachite-bigint"]
all-nodes-with-ranges = []

[dependencies]
rustpython-parser-core = { workspace = true }
Expand Down
62 changes: 21 additions & 41 deletions ast/asdl_rs.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,13 +286,6 @@ def customized_type_info(self, type_name):
def has_user_data(self, typ):
return self.type_info[typ].has_user_data

def apply_generics(self, typ, *generics):
needs_generics = not self.type_info[typ].is_simple
if needs_generics:
return [f"<{g}>" for g in generics]
else:
return ["" for g in generics]


class EmitVisitor(asdl.VisitorBase, TypeInfoMixin):
"""Visit that emits lines"""
Expand Down Expand Up @@ -393,37 +386,33 @@ def emit_attrs(self, depth):
self.emit("#[derive(Clone, Debug, PartialEq)]", depth)

def emit_range(self, has_attributes, depth):
if has_attributes:
self.emit("pub range: R,", depth + 1)
else:
self.emit("pub range: OptionalRange<R>,", depth + 1)
self.emit("pub range: TextRange,", depth + 1)

def visitModule(self, mod):
self.emit_attrs(0)
self.emit(
"""
#[derive(is_macro::Is)]
pub enum Ast<R=TextRange> {
pub enum Ast {
""",
0,
)
for dfn in mod.dfns:
info = self.customized_type_info(dfn.name)
dfn = info.custom
rust_name = info.full_type_name
generics = "" if self.type_info[dfn.name].is_simple else "<R>"
if dfn.name == "mod":
# This is exceptional rule to other enums.
# Unlike other enums, this is justified because `Mod` is only used as
# the top node of parsing result and never a child node of other nodes.
# Because it will be very rarely used in very particular applications,
# "ast_" prefix to everywhere seems less useful.
self.emit('#[is(name = "module")]', 1)
self.emit(f"{rust_name}({rust_name}{generics}),", 1)
self.emit(f"{rust_name}({rust_name}),", 1)
self.emit(
"""
}
impl<R> Node for Ast<R> {
impl Node for Ast {
const NAME: &'static str = "AST";
const FIELD_NAMES: &'static [&'static str] = &[];
}
Expand All @@ -433,11 +422,10 @@ def visitModule(self, mod):
for dfn in mod.dfns:
info = self.customized_type_info(dfn.name)
rust_name = info.full_type_name
generics = "" if self.type_info[dfn.name].is_simple else "<R>"
self.emit(
f"""
impl<R> From<{rust_name}{generics}> for Ast<R> {{
fn from(node: {rust_name}{generics}) -> Self {{
impl From<{rust_name}> for Ast {{
fn from(node: {rust_name}) -> Self {{
Ast::{rust_name}(node)
}}
}}
Expand All @@ -462,10 +450,9 @@ def visitSum(self, sum, type, depth):
else:
self.sum_with_constructors(sum, type, depth)

(generics_applied,) = self.apply_generics(type.name, "R")
self.emit(
f"""
impl{generics_applied} Node for {rust_type_name(type.name)}{generics_applied} {{
impl Node for {rust_type_name(type.name)} {{
const NAME: &'static str = "{type.name}";
const FIELD_NAMES: &'static [&'static str] = &[];
}}
Expand Down Expand Up @@ -512,7 +499,7 @@ def simple_sum(self, sum, type, depth):
{rust_name}::{cons.name}
}}
}}
impl<R> From<{rust_name}{cons.name}> for Ast<R> {{
impl From<{rust_name}{cons.name}> for Ast {{
fn from(_: {rust_name}{cons.name}) -> Self {{
{rust_name}::{cons.name}.into()
}}
Expand All @@ -537,15 +524,15 @@ def sum_with_constructors(self, sum, type, depth):

self.emit_attrs(depth)
self.emit("#[derive(is_macro::Is)]", depth)
self.emit(f"pub enum {rust_name}<R = TextRange> {{", depth)
self.emit(f"pub enum {rust_name} {{", depth)
needs_escape = any(rust_field_name(t.name) in RUST_KEYWORDS for t in sum.types)
for t in sum.types:
if needs_escape:
self.emit(
f'#[is(name = "{rust_field_name(t.name)}_{rust_name.lower()}")]',
depth + 1,
)
self.emit(f"{t.name}({rust_name}{t.name}<R>),", depth + 1)
self.emit(f"{t.name}({rust_name}{t.name}),", depth + 1)
self.emit("}", depth)
self.emit("", depth)

Expand All @@ -559,7 +546,7 @@ def sum_subtype_struct(self, sum_type_info, t, rust_name, depth):
)
self.emit_attrs(depth)
payload_name = f"{rust_name}{t.name}"
self.emit(f"pub struct {payload_name}<R = TextRange> {{", depth)
self.emit(f"pub struct {payload_name} {{", depth)
self.emit_range(sum_type_info.has_attributes, depth)
for f in t.fields:
self.visit(f, sum_type_info, "pub ", depth + 1, t.name)
Expand All @@ -572,17 +559,17 @@ def sum_subtype_struct(self, sum_type_info, t, rust_name, depth):
field_names = [f'"{f.name}"' for f in t.fields]
self.emit(
f"""
impl<R> Node for {payload_name}<R> {{
impl Node for {payload_name} {{
const NAME: &'static str = "{t.name}";
const FIELD_NAMES: &'static [&'static str] = &[{', '.join(field_names)}];
}}
impl<R> From<{payload_name}<R>> for {rust_name}<R> {{
fn from(payload: {payload_name}<R>) -> Self {{
impl From<{payload_name}> for {rust_name} {{
fn from(payload: {payload_name}) -> Self {{
{rust_name}::{t.name}(payload)
}}
}}
impl<R> From<{payload_name}<R>> for Ast<R> {{
fn from(payload: {payload_name}<R>) -> Self {{
impl From<{payload_name}> for Ast {{
fn from(payload: {payload_name}) -> Self {{
{rust_name}::from(payload).into()
}}
}}
Expand All @@ -609,7 +596,7 @@ def visitField(self, field, parent, vis, depth, constructor=None):
field_type = None
typ = rust_type_name(field.type)
if field_type and not field_type.is_simple:
typ = f"{typ}<R>"
typ = f"{typ}"
# don't box if we're doing Vec<T>, but do box if we're doing Vec<Option<Box<T>>>
if (
field_type
Expand Down Expand Up @@ -642,7 +629,7 @@ def visitProduct(self, product, type, depth):
type_info = self.type_info[type.name]
product_name = type_info.full_type_name
self.emit_attrs(depth)
self.emit(f"pub struct {product_name}<R = TextRange> {{", depth)
self.emit(f"pub struct {product_name} {{", depth)
self.emit_range(product.attributes, depth + 1)
for f in product.fields:
self.visit(f, type_info, "pub ", depth + 1)
Expand All @@ -652,7 +639,7 @@ def visitProduct(self, product, type, depth):
field_names = [f'"{f.name}"' for f in product.fields]
self.emit(
f"""
impl<R> Node for {product_name}<R> {{
impl Node for {product_name} {{
const NAME: &'static str = "{type.name}";
const FIELD_NAMES: &'static [&'static str] = &[
{', '.join(field_names)}
Expand Down Expand Up @@ -692,8 +679,6 @@ def visitSum(self, sum, name, depth):
self.emit_type_alias(variant_info)
self.emit_ranged_impl(variant_info)

if not info.no_cfg(self.type_info):
self.emit('#[cfg(feature = "all-nodes-with-ranges")]', 0)

self.emit(
f"""
Expand All @@ -716,21 +701,16 @@ def visitProduct(self, product, name, depth):

def emit_type_alias(self, info):
return # disable
generics = "" if info.is_simple else "::<TextRange>"

self.emit(
f"pub type {info.full_type_name} = crate::generic::{info.full_type_name}{generics};",
f"pub type {info.full_type_name} = crate::generic::{info.full_type_name};",
0,
)
self.emit("", 0)

def emit_ranged_impl(self, info):
if not info.no_cfg(self.type_info):
self.emit('#[cfg(feature = "all-nodes-with-ranges")]', 0)

self.file.write(
f"""
impl Ranged for crate::generic::{info.full_type_name}::<TextRange> {{
impl Ranged for crate::generic::{info.full_type_name} {{
fn range(&self) -> TextRange {{
self.range
}}
Expand Down
Loading

0 comments on commit a95112d

Please sign in to comment.