Merge pull request #15 from youknowone/spellchecker

Setup spell checker
This commit is contained in:
Jeong, YunWon 2023-05-10 18:11:40 +09:00 committed by GitHub
commit d495cd9129
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 501 additions and 178 deletions

304
.cspell.json Normal file
View file

@ -0,0 +1,304 @@
// See: https://github.com/streetsidesoftware/cspell/tree/master/packages/cspell
{
"version": "0.2",
// language - current active spelling language
"language": "en",
// dictionaries - list of the names of the dictionaries to use
"dictionaries": [
"en_US",
"softwareTerms",
"c",
"cpp",
"python",
"python-custom",
"rust",
"unix",
"posix",
"winapi"
],
// dictionaryDefinitions - this list defines any custom dictionaries to use
"dictionaryDefinitions": [],
"ignorePaths": [
"**/__pycache__/**",
"Lib/**"
],
// words - list of words to be always considered correct
"words": [
// Rust
"ahash",
"bidi",
"biguint",
"bindgen",
"bitflags",
"bstr",
"byteorder",
"chrono",
"consts",
"cstring",
"flate2",
"fract",
"hasher",
"hexf",
"idents",
"indexmap",
"insta",
"keccak",
"lalrpop",
"libc",
"libz",
"longlong",
"Manually",
"nbaz",
"maplit",
"memchr",
"memrchr",
"memmap",
"metas",
"modpow",
"nanos",
"peekable",
"powc",
"powf",
"prepended",
"punct",
"replacen",
"rsplitn",
"rustc",
"rustfmt",
"seekfrom",
"splitn",
"subsec",
"timsort",
"trai",
"ulonglong",
"unic",
"unistd",
"unsync",
"winapi",
"winsock",
// Python
"abstractmethods",
"aiter",
"anext",
"arrayiterator",
"arraytype",
"asend",
"athrow",
"basicsize",
"cformat",
"classcell",
"closesocket",
"codepoint",
"codepoints",
"cpython",
"decompressor",
"defaultaction",
"descr",
"dictcomp",
"dictitems",
"dictkeys",
"dictview",
"docstring",
"docstrings",
"dunder",
"eventmask",
"fdel",
"fget",
"fileencoding",
"fillchar",
"finallyhandler",
"frombytes",
"fromhex",
"fromunicode",
"fset",
"fspath",
"fstring",
"fstrings",
"genexpr",
"getattro",
"getformat",
"getnewargs",
"getweakrefcount",
"getweakrefs",
"hostnames",
"idiv",
"impls",
"infj",
"instancecheck",
"instanceof",
"isabstractmethod",
"itemiterator",
"itemsize",
"iternext",
"keyiterator",
"kwarg",
"kwargs",
"linearization",
"linearize",
"listcomp",
"mappingproxy",
"maxsplit",
"memoryview",
"memoryviewiterator",
"metaclass",
"metaclasses",
"metatype",
"mro",
"mros",
"nanj",
"ndigits",
"ndim",
"nonbytes",
"origname",
"posixsubprocess",
"pyexpat",
"PYTHONDEBUG",
"PYTHONHOME",
"PYTHONINSPECT",
"PYTHONOPTIMIZE",
"PYTHONPATH",
"PYTHONPATH",
"PYTHONVERBOSE",
"PYTHONWARNINGS",
"qualname",
"radd",
"rdiv",
"rdivmod",
"reconstructor",
"reversevalueiterator",
"rfloordiv",
"rlshift",
"rmod",
"rpow",
"rrshift",
"rsub",
"rtruediv",
"scproxy",
"setattro",
"setcomp",
"stacklevel",
"subclasscheck",
"subclasshook",
"unionable",
"unraisablehook",
"valueiterator",
"vararg",
"varargs",
"varnames",
"warningregistry",
"warnopts",
"weakproxy",
"xopts",
// RustPython
"baseclass",
"Bytecode",
"cfgs",
"codegen",
"dedentations",
"dedents",
"deduped",
"downcasted",
"dumpable",
"GetSet",
"internable",
"makeunicodedata",
"miri",
"nonterminal",
"notrace",
"pyarg",
"pyarg",
"pyargs",
"PyAttr",
"pyc",
"PyClass",
"PyClassMethod",
"PyException",
"PyFunction",
"pygetset",
"pyimpl",
"pymember",
"PyMethod",
"PyModule",
"pyname",
"pyobj",
"PyObject",
"pypayload",
"PyProperty",
"pyref",
"PyResult",
"pyslot",
"PyStaticMethod",
"pystr",
"pystruct",
"pystructseq",
"pytrace",
"reducelib",
"richcompare",
"RustPython",
"struc",
"tracebacks",
"typealiases",
"Unconstructible",
"unhashable",
"uninit",
"unraisable",
"wasi",
"zelf",
// cpython
"argtypes",
"asdl",
"asname",
"augassign",
"badsyntax",
"basetype",
"boolop",
"bxor",
"cellarg",
"cellvar",
"cellvars",
"cmpop",
"dictoffset",
"elts",
"excepthandler",
"finalbody",
"freevar",
"freevars",
"fromlist",
"heaptype",
"IMMUTABLETYPE",
"kwonlyarg",
"kwonlyargs",
"linearise",
"maxdepth",
"mult",
"nkwargs",
"orelse",
"patma",
"posonlyarg",
"posonlyargs",
"prec",
"significand",
"stackdepth",
"unaryop",
"unparse",
"unparser",
"VARKEYWORDS",
"varkwarg",
"wbits",
"withitem",
"withitems",
"withs"
],
// flagWords - list of words to be always considered incorrect
"flagWords": [
],
"ignoreRegExpList": [
],
// languageSettings - allow for per programming language configuration settings.
"languageSettings": [
{
"languageId": "python",
"locale": "en"
}
]
}

View file

@ -62,3 +62,13 @@ jobs:
run: python -m pip install ruff run: python -m pip install ruff
- name: run python lint - name: run python lint
run: ruff --ignore=E501 ast --show-source run: ruff --ignore=E501 ast --show-source
- name: spell checker
uses: streetsidesoftware/cspell-action@v2
with:
files: |
'ast/**/*.rs'
'core/**/*.rs'
'literal/**/*.rs'
'parser/**/*.rs'
'ast/asdl_rs.py'

View file

@ -1,3 +1,5 @@
# spell-checker:words dfn dfns
#! /usr/bin/env python #! /usr/bin/env python
"""Generate Rust code from an ASDL description.""" """Generate Rust code from an ASDL description."""
@ -12,7 +14,7 @@ from typing import Optional, Dict
import asdl import asdl
TABSIZE = 4 TABSIZE = 4
AUTOGEN_MESSAGE = "// File automatically generated by {}.\n\n" AUTO_GEN_MESSAGE = "// File automatically generated by {}.\n\n"
builtin_type_mapping = { builtin_type_mapping = {
"identifier": "Ident", "identifier": "Ident",
@ -23,7 +25,7 @@ builtin_type_mapping = {
assert builtin_type_mapping.keys() == asdl.builtin_types assert builtin_type_mapping.keys() == asdl.builtin_types
def get_rust_type(name): def rust_type_name(name):
"""Return a string for the C name of the type. """Return a string for the C name of the type.
This function special cases the default types provided by asdl. This function special cases the default types provided by asdl.
@ -66,7 +68,7 @@ def asdl_of(name, obj):
class TypeInfo: class TypeInfo:
name: str name: str
enum_name: Optional[str] enum_name: Optional[str]
has_userdata: Optional[bool] has_user_data: Optional[bool]
has_attributes: bool has_attributes: bool
empty_field: bool empty_field: bool
children: set children: set
@ -77,7 +79,7 @@ class TypeInfo:
def __init__(self, name): def __init__(self, name):
self.name = name self.name = name
self.enum_name = None self.enum_name = None
self.has_userdata = None self.has_user_data = None
self.has_attributes = False self.has_attributes = False
self.empty_field = False self.empty_field = False
self.children = set() self.children = set()
@ -90,7 +92,7 @@ class TypeInfo:
@property @property
def rust_name(self): def rust_name(self):
return get_rust_type(self.name) return rust_type_name(self.name)
@property @property
def sum_name(self): def sum_name(self):
@ -101,11 +103,11 @@ class TypeInfo:
@property @property
def rust_sum_name(self): def rust_sum_name(self):
rust_name = get_rust_type(self.name) rust_name = rust_type_name(self.name)
if self.enum_name is None: if self.enum_name is None:
return rust_name return rust_name
else: else:
name = get_rust_type(self.enum_name) + rust_name name = rust_type_name(self.enum_name) + rust_name
return name return name
@property @property
@ -121,30 +123,30 @@ class TypeInfo:
else: else:
return "" return ""
def determine_userdata(self, typeinfo, stack): def determine_user_data(self, type_info, stack):
if self.name in stack: if self.name in stack:
return None return None
stack.add(self.name) stack.add(self.name)
for child, child_seq in self.children: for child, child_seq in self.children:
if child in asdl.builtin_types: if child in asdl.builtin_types:
continue continue
childinfo = typeinfo[child] child_info = type_info[child]
child_has_userdata = childinfo.determine_userdata(typeinfo, stack) child_has_user_data = child_info.determine_user_data(type_info, stack)
if self.has_userdata is None and child_has_userdata is True: if self.has_user_data is None and child_has_user_data is True:
self.has_userdata = True self.has_user_data = True
stack.remove(self.name) stack.remove(self.name)
return self.has_userdata return self.has_user_data
class TypeInfoMixin: class TypeInfoMixin:
typeinfo: Dict[str, TypeInfo] type_info: Dict[str, TypeInfo]
def has_userdata(self, typ): def has_user_data(self, typ):
return self.typeinfo[typ].has_userdata return self.type_info[typ].has_user_data
def get_generics(self, typ, *generics): def apply_generics(self, typ, *generics):
if self.has_userdata(typ): if self.has_user_data(typ):
return [f"<{g}>" for g in generics] return [f"<{g}>" for g in generics]
else: else:
return ["" for g in generics] return ["" for g in generics]
@ -153,9 +155,9 @@ class TypeInfoMixin:
class EmitVisitor(asdl.VisitorBase, TypeInfoMixin): class EmitVisitor(asdl.VisitorBase, TypeInfoMixin):
"""Visit that emits lines""" """Visit that emits lines"""
def __init__(self, file, typeinfo): def __init__(self, file, type_info):
self.file = file self.file = file
self.typeinfo = typeinfo self.type_info = type_info
self.identifiers = set() self.identifiers = set()
super(EmitVisitor, self).__init__() super(EmitVisitor, self).__init__()
@ -172,48 +174,48 @@ class EmitVisitor(asdl.VisitorBase, TypeInfoMixin):
self.file.write(line + "\n") self.file.write(line + "\n")
class FindUserdataTypesVisitor(asdl.VisitorBase): class FindUserDataTypesVisitor(asdl.VisitorBase):
def __init__(self, typeinfo): def __init__(self, type_info):
self.typeinfo = typeinfo self.type_info = type_info
super().__init__() super().__init__()
def visitModule(self, mod): def visitModule(self, mod):
for dfn in mod.dfns: for dfn in mod.dfns:
self.visit(dfn) self.visit(dfn)
stack = set() stack = set()
for info in self.typeinfo.values(): for info in self.type_info.values():
info.determine_userdata(self.typeinfo, stack) info.determine_user_data(self.type_info, stack)
def visitType(self, type): def visitType(self, type):
self.typeinfo[type.name] = TypeInfo(type.name) self.type_info[type.name] = TypeInfo(type.name)
self.visit(type.value, type.name) self.visit(type.value, type.name)
def visitSum(self, sum, name): def visitSum(self, sum, name):
info = self.typeinfo[name] info = self.type_info[name]
if is_simple(sum): if is_simple(sum):
info.has_userdata = False info.has_user_data = False
else: else:
for t in sum.types: for t in sum.types:
t_info = TypeInfo(t.name) t_info = TypeInfo(t.name)
t_info.enum_name = name t_info.enum_name = name
t_info.empty_field = not t.fields t_info.empty_field = not t.fields
self.typeinfo[t.name] = t_info self.type_info[t.name] = t_info
self.add_children(t.name, t.fields) self.add_children(t.name, t.fields)
if len(sum.types) > 1: if len(sum.types) > 1:
info.boxed = True info.boxed = True
if sum.attributes: if sum.attributes:
# attributes means located, which has the `custom: U` field # attributes means located, which has the `custom: U` field
info.has_userdata = True info.has_user_data = True
info.has_attributes = True info.has_attributes = True
for variant in sum.types: for variant in sum.types:
self.add_children(name, variant.fields) self.add_children(name, variant.fields)
def visitProduct(self, product, name): def visitProduct(self, product, name):
info = self.typeinfo[name] info = self.type_info[name]
if product.attributes: if product.attributes:
# attributes means located, which has the `custom: U` field # attributes means located, which has the `custom: U` field
info.has_userdata = True info.has_user_data = True
info.has_attributes = True info.has_attributes = True
info.has_expr = product_has_expr(product) info.has_expr = product_has_expr(product)
if len(product.fields) > 2: if len(product.fields) > 2:
@ -222,7 +224,9 @@ class FindUserdataTypesVisitor(asdl.VisitorBase):
self.add_children(name, product.fields) self.add_children(name, product.fields)
def add_children(self, name, fields): def add_children(self, name, fields):
self.typeinfo[name].children.update((field.type, field.seq) for field in fields) self.type_info[name].children.update(
(field.type, field.seq) for field in fields
)
def rust_field(field_name): def rust_field(field_name):
@ -237,7 +241,7 @@ def product_has_expr(product):
class StructVisitor(EmitVisitor): class StructVisitor(EmitVisitor):
"""Visitor to generate typedefs for AST.""" """Visitor to generate type-defs for AST."""
def __init__(self, *args, **kw): def __init__(self, *args, **kw):
super().__init__(*args, **kw) super().__init__(*args, **kw)
@ -260,59 +264,59 @@ class StructVisitor(EmitVisitor):
self.emit("#[derive(Clone, Debug, PartialEq)]", depth) self.emit("#[derive(Clone, Debug, PartialEq)]", depth)
def simple_sum(self, sum, name, depth): def simple_sum(self, sum, name, depth):
rustname = get_rust_type(name) rust_name = rust_type_name(name)
self.emit_attrs(depth) self.emit_attrs(depth)
self.emit(f"pub enum {rustname} {{", depth) self.emit(f"pub enum {rust_name} {{", depth)
for variant in sum.types: for variant in sum.types:
self.emit(f"{variant.name},", depth + 1) self.emit(f"{variant.name},", depth + 1)
self.emit("}", depth) self.emit("}", depth)
self.emit("", depth) self.emit("", depth)
def sum_with_constructors(self, sum, name, depth): def sum_with_constructors(self, sum, name, depth):
typeinfo = self.typeinfo[name] type_info = self.type_info[name]
suffix = typeinfo.rust_suffix suffix = type_info.rust_suffix
rustname = get_rust_type(name) rust_name = rust_type_name(name)
# all the attributes right now are for location, so if it has attrs we # all the attributes right now are for location, so if it has attrs we
# can just wrap it in Attributed<> # can just wrap it in Attributed<>
for t in sum.types: for t in sum.types:
if not t.fields: if not t.fields:
continue continue
self.sum_subtype_struct(typeinfo, t, rustname, depth) self.sum_subtype_struct(type_info, t, rust_name, depth)
generics, generics_applied = self.get_generics(name, "U = ()", "U") generics, generics_applied = self.apply_generics(name, "U = ()", "U")
self.emit_attrs(depth) self.emit_attrs(depth)
self.emit(f"pub enum {rustname}{suffix}{generics} {{", depth) self.emit(f"pub enum {rust_name}{suffix}{generics} {{", depth)
for t in sum.types: for t in sum.types:
if t.fields: if t.fields:
(t_generics_applied,) = self.get_generics(t.name, "U") (t_generics_applied,) = self.apply_generics(t.name, "U")
self.emit( self.emit(
f"{t.name}({rustname}{t.name}{t_generics_applied}),", depth + 1 f"{t.name}({rust_name}{t.name}{t_generics_applied}),", depth + 1
) )
else: else:
self.emit(f"{t.name},", depth + 1) self.emit(f"{t.name},", depth + 1)
self.emit("}", depth) self.emit("}", depth)
if typeinfo.has_attributes: if type_info.has_attributes:
self.emit( self.emit(
f"pub type {rustname}<U = ()> = Attributed<{rustname}{suffix}{generics_applied}, U>;", f"pub type {rust_name}<U = ()> = Attributed<{rust_name}{suffix}{generics_applied}, U>;",
depth, depth,
) )
self.emit("", depth) self.emit("", depth)
def sum_subtype_struct(self, sum_typeinfo, t, rustname, depth): def sum_subtype_struct(self, sum_type_info, t, rust_name, depth):
self.emit_attrs(depth) self.emit_attrs(depth)
generics, generics_applied = self.get_generics(t.name, "U = ()", "U") generics, generics_applied = self.apply_generics(t.name, "U = ()", "U")
payload_name = f"{rustname}{t.name}" payload_name = f"{rust_name}{t.name}"
self.emit(f"pub struct {payload_name}{generics} {{", depth) self.emit(f"pub struct {payload_name}{generics} {{", depth)
for f in t.fields: for f in t.fields:
self.visit(f, sum_typeinfo, "pub ", depth + 1, t.name) self.visit(f, sum_type_info, "pub ", depth + 1, t.name)
self.emit("}", depth) self.emit("}", depth)
self.emit( self.emit(
textwrap.dedent( textwrap.dedent(
f""" f"""
impl{generics_applied} From<{payload_name}{generics_applied}> for {rustname}{sum_typeinfo.rust_suffix}{generics_applied} {{ impl{generics_applied} From<{payload_name}{generics_applied}> for {rust_name}{sum_type_info.rust_suffix}{generics_applied} {{
fn from(payload: {payload_name}{generics_applied}) -> Self {{ fn from(payload: {payload_name}{generics_applied}) -> Self {{
{rustname}{sum_typeinfo.rust_suffix}::{t.name}(payload) {rust_name}{sum_type_info.rust_suffix}::{t.name}(payload)
}} }}
}} }}
""" """
@ -330,14 +334,14 @@ class StructVisitor(EmitVisitor):
self.emit(f"{cons.name},", depth) self.emit(f"{cons.name},", depth)
def visitField(self, field, parent, vis, depth, constructor=None): def visitField(self, field, parent, vis, depth, constructor=None):
typ = get_rust_type(field.type) typ = rust_type_name(field.type)
fieldtype = self.typeinfo.get(field.type) field_type = self.type_info.get(field.type)
if fieldtype and fieldtype.has_userdata: if field_type and field_type.has_user_data:
typ = f"{typ}<U>" typ = f"{typ}<U>"
# don't box if we're doing Vec<T>, but do box if we're doing Vec<Option<Box<T>>> # don't box if we're doing Vec<T>, but do box if we're doing Vec<Option<Box<T>>>
if ( if (
fieldtype field_type
and fieldtype.boxed and field_type.boxed
and (not (parent.product or field.seq) or field.opt) and (not (parent.product or field.seq) or field.opt)
): ):
typ = f"Box<{typ}>" typ = f"Box<{typ}>"
@ -355,27 +359,27 @@ class StructVisitor(EmitVisitor):
self.emit(f"{vis}{name}: {typ},", depth) self.emit(f"{vis}{name}: {typ},", depth)
def visitProduct(self, product, name, depth): def visitProduct(self, product, name, depth):
typeinfo = self.typeinfo[name] type_info = self.type_info[name]
generics, generics_applied = self.get_generics(name, "U = ()", "U") generics, generics_applied = self.apply_generics(name, "U = ()", "U")
dataname = rustname = get_rust_type(name) data_name = rust_name = rust_type_name(name)
if product.attributes: if product.attributes:
dataname = rustname + "Data" data_name = rust_name + "Data"
self.emit_attrs(depth) self.emit_attrs(depth)
has_expr = product_has_expr(product) has_expr = product_has_expr(product)
if has_expr: if has_expr:
datadef = f"{dataname}{generics}" data_def = f"{data_name}{generics}"
else: else:
datadef = dataname data_def = data_name
self.emit(f"pub struct {datadef} {{", depth) self.emit(f"pub struct {data_def} {{", depth)
for f in product.fields: for f in product.fields:
self.visit(f, typeinfo, "pub ", depth + 1) self.visit(f, type_info, "pub ", depth + 1)
self.emit("}", depth) self.emit("}", depth)
if product.attributes: if product.attributes:
# attributes should just be location info # attributes should just be location info
if not has_expr: if not has_expr:
generics_applied = "" generics_applied = ""
self.emit( self.emit(
f"pub type {rustname}<U = ()> = Attributed<{dataname}{generics_applied}, U>;", f"pub type {rust_name}<U = ()> = Attributed<{data_name}{generics_applied}, U>;",
depth, depth,
) )
self.emit("", depth) self.emit("", depth)
@ -411,10 +415,10 @@ class FoldTraitDefVisitor(EmitVisitor):
def visitType(self, type, depth): def visitType(self, type, depth):
name = type.name name = type.name
apply_u, apply_target_u = self.get_generics(name, "U", "Self::TargetU") apply_u, apply_target_u = self.apply_generics(name, "U", "Self::TargetU")
enumname = get_rust_type(name) enum_name = rust_type_name(name)
self.emit( self.emit(
f"fn fold_{name}(&mut self, node: {enumname}{apply_u}) -> Result<{enumname}{apply_target_u}, Self::Error> {{", f"fn fold_{name}(&mut self, node: {enum_name}{apply_u}) -> Result<{enum_name}{apply_target_u}, Self::Error> {{",
depth, depth,
) )
self.emit(f"fold_{name}(self, node)", depth + 1) self.emit(f"fold_{name}(self, node)", depth + 1)
@ -439,14 +443,14 @@ class FoldImplVisitor(EmitVisitor):
self.visit(type.value, type.name, depth) self.visit(type.value, type.name, depth)
def visitSum(self, sum, name, depth): def visitSum(self, sum, name, depth):
typeinfo = self.typeinfo[name] type_info = self.type_info[name]
apply_t, apply_u, apply_target_u = self.get_generics( apply_t, apply_u, apply_target_u = self.apply_generics(
name, "T", "U", "F::TargetU" name, "T", "U", "F::TargetU"
) )
enumname = get_rust_type(name) enum_name = rust_type_name(name)
self.emit(f"impl<T, U> Foldable<T, U> for {enumname}{apply_t} {{", depth) self.emit(f"impl<T, U> Foldable<T, U> for {enum_name}{apply_t} {{", depth)
self.emit(f"type Mapped = {enumname}{apply_u};", depth + 1) self.emit(f"type Mapped = {enum_name}{apply_u};", depth + 1)
self.emit( self.emit(
"fn fold<F: Fold<T, TargetU = U> + ?Sized>(self, folder: &mut F) -> Result<Self::Mapped, F::Error> {", "fn fold<F: Fold<T, TargetU = U> + ?Sized>(self, folder: &mut F) -> Result<Self::Mapped, F::Error> {",
depth + 1, depth + 1,
@ -456,16 +460,16 @@ class FoldImplVisitor(EmitVisitor):
self.emit("}", depth) self.emit("}", depth)
self.emit( self.emit(
f"pub fn fold_{name}<U, F: Fold<U> + ?Sized>(#[allow(unused)] folder: &mut F, node: {enumname}{apply_u}) -> Result<{enumname}{apply_target_u}, F::Error> {{", f"pub fn fold_{name}<U, F: Fold<U> + ?Sized>(#[allow(unused)] folder: &mut F, node: {enum_name}{apply_u}) -> Result<{enum_name}{apply_target_u}, F::Error> {{",
depth, depth,
) )
if typeinfo.has_attributes: if type_info.has_attributes:
self.emit("fold_attributed(folder, node, |folder, node| {", depth) self.emit("fold_attributed(folder, node, |folder, node| {", depth)
self.emit("match node {", depth + 1) self.emit("match node {", depth + 1)
for cons in sum.types: for cons in sum.types:
fields_pattern = self.make_pattern( fields_pattern = self.make_pattern(
enumname, typeinfo.rust_suffix, cons.name, cons.fields enum_name, type_info.rust_suffix, cons.name, cons.fields
) )
self.emit( self.emit(
f"{fields_pattern[0]} {{ {fields_pattern[1]} }} {fields_pattern[2]} => {{", f"{fields_pattern[0]} {{ {fields_pattern[1]} }} {fields_pattern[2]} => {{",
@ -476,19 +480,19 @@ class FoldImplVisitor(EmitVisitor):
) )
self.emit("}", depth + 2) self.emit("}", depth + 2)
self.emit("}", depth + 1) self.emit("}", depth + 1)
if typeinfo.has_attributes: if type_info.has_attributes:
self.emit("})", depth) self.emit("})", depth)
self.emit("}", depth) self.emit("}", depth)
def visitProduct(self, product, name, depth): def visitProduct(self, product, name, depth):
apply_t, apply_u, apply_target_u = self.get_generics( apply_t, apply_u, apply_target_u = self.apply_generics(
name, "T", "U", "F::TargetU" name, "T", "U", "F::TargetU"
) )
structname = get_rust_type(name) struct_name = rust_type_name(name)
has_attributes = bool(product.attributes) has_attributes = bool(product.attributes)
self.emit(f"impl<T, U> Foldable<T, U> for {structname}{apply_t} {{", depth) self.emit(f"impl<T, U> Foldable<T, U> for {struct_name}{apply_t} {{", depth)
self.emit(f"type Mapped = {structname}{apply_u};", depth + 1) self.emit(f"type Mapped = {struct_name}{apply_u};", depth + 1)
self.emit( self.emit(
"fn fold<F: Fold<T, TargetU = U> + ?Sized>(self, folder: &mut F) -> Result<Self::Mapped, F::Error> {", "fn fold<F: Fold<T, TargetU = U> + ?Sized>(self, folder: &mut F) -> Result<Self::Mapped, F::Error> {",
depth + 1, depth + 1,
@ -498,27 +502,27 @@ class FoldImplVisitor(EmitVisitor):
self.emit("}", depth) self.emit("}", depth)
self.emit( self.emit(
f"pub fn fold_{name}<U, F: Fold<U> + ?Sized>(#[allow(unused)] folder: &mut F, node: {structname}{apply_u}) -> Result<{structname}{apply_target_u}, F::Error> {{", f"pub fn fold_{name}<U, F: Fold<U> + ?Sized>(#[allow(unused)] folder: &mut F, node: {struct_name}{apply_u}) -> Result<{struct_name}{apply_target_u}, F::Error> {{",
depth, depth,
) )
if has_attributes: if has_attributes:
self.emit("fold_attributed(folder, node, |folder, node| {", depth) self.emit("fold_attributed(folder, node, |folder, node| {", depth)
rustname = structname + "Data" rust_name = struct_name + "Data"
else: else:
rustname = structname rust_name = struct_name
fields_pattern = self.make_pattern(rustname, structname, None, product.fields) fields_pattern = self.make_pattern(rust_name, struct_name, None, product.fields)
self.emit(f"let {rustname} {{ {fields_pattern[1]} }} = node;", depth + 1) self.emit(f"let {rust_name} {{ {fields_pattern[1]} }} = node;", depth + 1)
self.gen_construction(rustname, product.fields, "", depth + 1) self.gen_construction(rust_name, product.fields, "", depth + 1)
if has_attributes: if has_attributes:
self.emit("})", depth) self.emit("})", depth)
self.emit("}", depth) self.emit("}", depth)
def make_pattern(self, rustname, suffix, fieldname, fields): def make_pattern(self, rust_name, suffix, fieldname, fields):
if fields: if fields:
header = f"{rustname}{suffix}::{fieldname}({rustname}{fieldname}" header = f"{rust_name}{suffix}::{fieldname}({rust_name}{fieldname}"
footer = ")" footer = ")"
else: else:
header = f"{rustname}{suffix}::{fieldname}" header = f"{rust_name}{suffix}::{fieldname}"
footer = "" footer = ""
body = ",".join(rust_field(f.name) for f in fields) body = ",".join(rust_field(f.name) for f in fields)
@ -536,24 +540,24 @@ class FoldModuleVisitor(EmitVisitor):
def visitModule(self, mod): def visitModule(self, mod):
depth = 0 depth = 0
self.emit("use crate::fold_helpers::Foldable;", depth) self.emit("use crate::fold_helpers::Foldable;", depth)
FoldTraitDefVisitor(self.file, self.typeinfo).visit(mod, depth) FoldTraitDefVisitor(self.file, self.type_info).visit(mod, depth)
FoldImplVisitor(self.file, self.typeinfo).visit(mod, depth) FoldImplVisitor(self.file, self.type_info).visit(mod, depth)
class VisitorTraitDefVisitor(StructVisitor): class VisitorTraitDefVisitor(StructVisitor):
def full_name(self, name): def full_name(self, name):
typeinfo = self.typeinfo[name] type_info = self.type_info[name]
if typeinfo.enum_name: if type_info.enum_name:
return f"{typeinfo.enum_name}_{name}" return f"{type_info.enum_name}_{name}"
else: else:
return name return name
def node_type_name(self, name): def node_type_name(self, name):
typeinfo = self.typeinfo[name] type_info = self.type_info[name]
if typeinfo.enum_name: if type_info.enum_name:
return f"{get_rust_type(typeinfo.enum_name)}{get_rust_type(name)}" return f"{rust_type_name(type_info.enum_name)}{rust_type_name(name)}"
else: else:
return get_rust_type(name) return rust_type_name(name)
def visitModule(self, mod, depth): def visitModule(self, mod, depth):
self.emit("pub trait Visitor<U=()> {", depth) self.emit("pub trait Visitor<U=()> {", depth)
@ -566,27 +570,27 @@ class VisitorTraitDefVisitor(StructVisitor):
self.visit(type.value, type.name, depth) self.visit(type.value, type.name, depth)
def emit_visitor(self, nodename, depth, has_node=True): def emit_visitor(self, nodename, depth, has_node=True):
typeinfo = self.typeinfo[nodename] type_info = self.type_info[nodename]
if has_node: if has_node:
node_type = typeinfo.rust_sum_name node_type = type_info.rust_sum_name
node_value = "node" node_value = "node"
else: else:
node_type = "()" node_type = "()"
node_value = "()" node_value = "()"
self.emit( self.emit(
f"fn visit_{typeinfo.sum_name}(&mut self, node: {node_type}) {{", depth f"fn visit_{type_info.sum_name}(&mut self, node: {node_type}) {{", depth
) )
self.emit(f"self.generic_visit_{typeinfo.sum_name}({node_value})", depth + 1) self.emit(f"self.generic_visit_{type_info.sum_name}({node_value})", depth + 1)
self.emit("}", depth) self.emit("}", depth)
def emit_generic_visitor_signature(self, nodename, depth, has_node=True): def emit_generic_visitor_signature(self, nodename, depth, has_node=True):
typeinfo = self.typeinfo[nodename] type_info = self.type_info[nodename]
if has_node: if has_node:
node_type = typeinfo.rust_sum_name node_type = type_info.rust_sum_name
else: else:
node_type = "()" node_type = "()"
self.emit( self.emit(
f"fn generic_visit_{typeinfo.sum_name}(&mut self, node: {node_type}) {{", f"fn generic_visit_{type_info.sum_name}(&mut self, node: {node_type}) {{",
depth, depth,
) )
@ -598,8 +602,8 @@ class VisitorTraitDefVisitor(StructVisitor):
self.emit_visitor(name, depth) self.emit_visitor(name, depth)
self.emit_empty_generic_visitor(name, depth) self.emit_empty_generic_visitor(name, depth)
def visit_match_for_type(self, nodename, rustname, type_, depth): def visit_match_for_type(self, nodename, rust_name, type_, depth):
self.emit(f"{rustname}::{type_.name}", depth) self.emit(f"{rust_name}::{type_.name}", depth)
if type_.fields: if type_.fields:
self.emit("(data)", depth) self.emit("(data)", depth)
data = "data" data = "data"
@ -607,13 +611,13 @@ class VisitorTraitDefVisitor(StructVisitor):
data = "()" data = "()"
self.emit(f"=> self.visit_{nodename}_{type_.name}({data}),", depth) self.emit(f"=> self.visit_{nodename}_{type_.name}({data}),", depth)
def visit_sumtype(self, name, type_, depth): def visit_sum_type(self, name, type_, depth):
self.emit_visitor(type_.name, depth, has_node=type_.fields) self.emit_visitor(type_.name, depth, has_node=type_.fields)
self.emit_generic_visitor_signature(type_.name, depth, has_node=type_.fields) self.emit_generic_visitor_signature(type_.name, depth, has_node=type_.fields)
for f in type_.fields: for f in type_.fields:
fieldname = rust_field(f.name) fieldname = rust_field(f.name)
fieldtype = self.typeinfo.get(f.type) field_type = self.type_info.get(f.type)
if not (fieldtype and fieldtype.has_userdata): if not (field_type and field_type.has_user_data):
continue continue
if f.opt: if f.opt:
@ -628,10 +632,10 @@ class VisitorTraitDefVisitor(StructVisitor):
self.emit(f"let value = node.{fieldname};", depth + 2) self.emit(f"let value = node.{fieldname};", depth + 2)
variable = "value" variable = "value"
if fieldtype.boxed and (not f.seq or f.opt): if field_type.boxed and (not f.seq or f.opt):
variable = "*" + variable variable = "*" + variable
typeinfo = self.typeinfo[fieldtype.name] type_info = self.type_info[field_type.name]
self.emit(f"self.visit_{typeinfo.sum_name}({variable});", depth + 2) self.emit(f"self.visit_{type_info.sum_name}({variable});", depth + 2)
self.emit("}", depth + 1) self.emit("}", depth + 1)
@ -641,22 +645,22 @@ class VisitorTraitDefVisitor(StructVisitor):
if not sum.attributes: if not sum.attributes:
return return
rustname = enumname = get_rust_type(name) rust_name = enum_name = rust_type_name(name)
if sum.attributes: if sum.attributes:
rustname = enumname + "Kind" rust_name = enum_name + "Kind"
self.emit_visitor(name, depth) self.emit_visitor(name, depth)
self.emit_generic_visitor_signature(name, depth) self.emit_generic_visitor_signature(name, depth)
depth += 1 depth += 1
self.emit("match node.node {", depth) self.emit("match node.node {", depth)
for t in sum.types: for t in sum.types:
self.visit_match_for_type(name, rustname, t, depth + 1) self.visit_match_for_type(name, rust_name, t, depth + 1)
self.emit("}", depth) self.emit("}", depth)
depth -= 1 depth -= 1
self.emit("}", depth) self.emit("}", depth)
# Now for the visitors for the types # Now for the visitors for the types
for t in sum.types: for t in sum.types:
self.visit_sumtype(name, t, depth) self.visit_sum_type(name, t, depth)
def visitProduct(self, product, name, depth): def visitProduct(self, product, name, depth):
self.emit_visitor(name, depth) self.emit_visitor(name, depth)
@ -667,10 +671,10 @@ class VisitorModuleVisitor(EmitVisitor):
def visitModule(self, mod): def visitModule(self, mod):
depth = 0 depth = 0
self.emit("#[allow(unused_variables, non_snake_case)]", depth) self.emit("#[allow(unused_variables, non_snake_case)]", depth)
VisitorTraitDefVisitor(self.file, self.typeinfo).visit(mod, depth) VisitorTraitDefVisitor(self.file, self.type_info).visit(mod, depth)
class ClassDefVisitor(EmitVisitor): class class_defVisitor(EmitVisitor):
def visitModule(self, mod): def visitModule(self, mod):
for dfn in mod.dfns: for dfn in mod.dfns:
self.visit(dfn) self.visit(dfn)
@ -679,32 +683,32 @@ class ClassDefVisitor(EmitVisitor):
self.visit(type.value, type.name, depth) self.visit(type.value, type.name, depth)
def visitSum(self, sum, name, depth): def visitSum(self, sum, name, depth):
structname = "NodeKind" + get_rust_type(name) struct_name = "NodeKind" + rust_type_name(name)
self.emit( self.emit(
f'#[pyclass(module = "_ast", name = {json.dumps(name)}, base = "AstNode")]', f'#[pyclass(module = "_ast", name = {json.dumps(name)}, base = "AstNode")]',
depth, depth,
) )
self.emit(f"struct {structname};", depth) self.emit(f"struct {struct_name};", depth)
self.emit("#[pyclass(flags(HAS_DICT, BASETYPE))]", depth) self.emit("#[pyclass(flags(HAS_DICT, BASETYPE))]", depth)
self.emit(f"impl {structname} {{}}", depth) self.emit(f"impl {struct_name} {{}}", depth)
for cons in sum.types: for cons in sum.types:
self.visit(cons, sum.attributes, structname, depth) self.visit(cons, sum.attributes, struct_name, depth)
def visitConstructor(self, cons, attrs, base, depth): def visitConstructor(self, cons, attrs, base, depth):
self.gen_classdef(cons.name, cons.fields, attrs, depth, base) self.gen_class_def(cons.name, cons.fields, attrs, depth, base)
def visitProduct(self, product, name, depth): def visitProduct(self, product, name, depth):
self.gen_classdef(name, product.fields, product.attributes, depth) self.gen_class_def(name, product.fields, product.attributes, depth)
def gen_classdef(self, name, fields, attrs, depth, base="AstNode"): def gen_class_def(self, name, fields, attrs, depth, base="AstNode"):
structname = "Node" + get_rust_type(name) struct_name = "Node" + rust_type_name(name)
self.emit( self.emit(
f'#[pyclass(module = "_ast", name = {json.dumps(name)}, base = {json.dumps(base)})]', f'#[pyclass(module = "_ast", name = {json.dumps(name)}, base = {json.dumps(base)})]',
depth, depth,
) )
self.emit(f"struct {structname};", depth) self.emit(f"struct {struct_name};", depth)
self.emit("#[pyclass(flags(HAS_DICT, BASETYPE))]", depth) self.emit("#[pyclass(flags(HAS_DICT, BASETYPE))]", depth)
self.emit(f"impl {structname} {{", depth) self.emit(f"impl {struct_name} {{", depth)
self.emit("#[extend_class]", depth + 1) self.emit("#[extend_class]", depth + 1)
self.emit( self.emit(
"fn extend_class_with_fields(ctx: &Context, class: &'static Py<PyType>) {", "fn extend_class_with_fields(ctx: &Context, class: &'static Py<PyType>) {",
@ -745,7 +749,7 @@ class ExtendModuleVisitor(EmitVisitor):
self.visit(type.value, type.name, depth) self.visit(type.value, type.name, depth)
def visitSum(self, sum, name, depth): def visitSum(self, sum, name, depth):
rust_name = get_rust_type(name) rust_name = rust_type_name(name)
self.emit( self.emit(
f"{json.dumps(name)} => NodeKind{rust_name}::make_class(&vm.ctx),", depth f"{json.dumps(name)} => NodeKind{rust_name}::make_class(&vm.ctx),", depth
) )
@ -759,7 +763,7 @@ class ExtendModuleVisitor(EmitVisitor):
self.gen_extension(name, depth) self.gen_extension(name, depth)
def gen_extension(self, name, depth): def gen_extension(self, name, depth):
rust_name = get_rust_type(name) rust_name = rust_type_name(name)
self.emit(f"{json.dumps(name)} => Node{rust_name}::make_class(&vm.ctx),", depth) self.emit(f"{json.dumps(name)} => Node{rust_name}::make_class(&vm.ctx),", depth)
@ -772,56 +776,57 @@ class TraitImplVisitor(EmitVisitor):
self.visit(type.value, type.name, depth) self.visit(type.value, type.name, depth)
def visitSum(self, sum, name, depth): def visitSum(self, sum, name, depth):
rustname = enumname = get_rust_type(name) rust_name = enum_name = rust_type_name(name)
if sum.attributes: if sum.attributes:
rustname = enumname + "Kind" rust_name = enum_name + "Kind"
self.emit(f"impl NamedNode for ast::located::{rustname} {{", depth) self.emit(f"impl NamedNode for ast::located::{rust_name} {{", depth)
self.emit(f"const NAME: &'static str = {json.dumps(name)};", depth + 1) self.emit(f"const NAME: &'static str = {json.dumps(name)};", depth + 1)
self.emit("}", depth) self.emit("}", depth)
self.emit(f"impl Node for ast::located::{rustname} {{", depth) self.emit(f"impl Node for ast::located::{rust_name} {{", depth)
self.emit( self.emit(
"fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef {", depth + 1 "fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef {", depth + 1
) )
self.emit("match self {", depth + 2) self.emit("match self {", depth + 2)
for variant in sum.types: for variant in sum.types:
self.constructor_to_object(variant, enumname, rustname, depth + 3) self.constructor_to_object(variant, enum_name, rust_name, depth + 3)
self.emit("}", depth + 2) self.emit("}", depth + 2)
self.emit("}", depth + 1) self.emit("}", depth + 1)
self.emit( self.emit(
"fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult<Self> {", "fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult<Self> {",
depth + 1, depth + 1,
) )
self.gen_sum_fromobj(sum, name, enumname, rustname, depth + 2) self.gen_sum_from_object(sum, name, enum_name, rust_name, depth + 2)
self.emit("}", depth + 1) self.emit("}", depth + 1)
self.emit("}", depth) self.emit("}", depth)
def constructor_to_object(self, cons, enumname, rustname, depth): def constructor_to_object(self, cons, enum_name, rust_name, depth):
self.emit(f"ast::located::{rustname}::{cons.name}", depth) self.emit(f"ast::located::{rust_name}::{cons.name}", depth)
if cons.fields: if cons.fields:
fields_pattern = self.make_pattern(cons.fields) fields_pattern = self.make_pattern(cons.fields)
self.emit( self.emit(
f"( ast::located::{enumname}{cons.name} {{ {fields_pattern} }} )", depth f"( ast::located::{enum_name}{cons.name} {{ {fields_pattern} }} )",
depth,
) )
self.emit(" => {", depth) self.emit(" => {", depth)
self.make_node(cons.name, cons.fields, depth + 1) self.make_node(cons.name, cons.fields, depth + 1)
self.emit("}", depth) self.emit("}", depth)
def visitProduct(self, product, name, depth): def visitProduct(self, product, name, depth):
structname = get_rust_type(name) struct_name = rust_type_name(name)
if product.attributes: if product.attributes:
structname += "Data" struct_name += "Data"
self.emit(f"impl NamedNode for ast::located::{structname} {{", depth) self.emit(f"impl NamedNode for ast::located::{struct_name} {{", depth)
self.emit(f"const NAME: &'static str = {json.dumps(name)};", depth + 1) self.emit(f"const NAME: &'static str = {json.dumps(name)};", depth + 1)
self.emit("}", depth) self.emit("}", depth)
self.emit(f"impl Node for ast::located::{structname} {{", depth) self.emit(f"impl Node for ast::located::{struct_name} {{", depth)
self.emit( self.emit(
"fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef {", depth + 1 "fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef {", depth + 1
) )
fields_pattern = self.make_pattern(product.fields) fields_pattern = self.make_pattern(product.fields)
self.emit( self.emit(
f"let ast::located::{structname} {{ {fields_pattern} }} = self;", depth + 2 f"let ast::located::{struct_name} {{ {fields_pattern} }} = self;", depth + 2
) )
self.make_node(name, product.fields, depth + 2) self.make_node(name, product.fields, depth + 2)
self.emit("}", depth + 1) self.emit("}", depth + 1)
@ -829,12 +834,12 @@ class TraitImplVisitor(EmitVisitor):
"fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult<Self> {", "fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult<Self> {",
depth + 1, depth + 1,
) )
self.gen_product_fromobj(product, name, structname, depth + 2) self.gen_product_from_object(product, name, struct_name, depth + 2)
self.emit("}", depth + 1) self.emit("}", depth + 1)
self.emit("}", depth) self.emit("}", depth)
def make_node(self, variant, fields, depth): def make_node(self, variant, fields, depth):
rust_variant = get_rust_type(variant) rust_variant = rust_type_name(variant)
self.emit( self.emit(
f"let _node = AstNode.into_ref_with_type(_vm, Node{rust_variant}::static_type().to_owned()).unwrap();", f"let _node = AstNode.into_ref_with_type(_vm, Node{rust_variant}::static_type().to_owned()).unwrap();",
depth, depth,
@ -851,9 +856,9 @@ class TraitImplVisitor(EmitVisitor):
def make_pattern(self, fields): def make_pattern(self, fields):
return ",".join(rust_field(f.name) for f in fields) return ",".join(rust_field(f.name) for f in fields)
def gen_sum_fromobj(self, sum, sumname, enumname, rustname, depth): def gen_sum_from_object(self, sum, sum_name, enum_name, rust_name, depth):
# if sum.attributes: # if sum.attributes:
# self.extract_location(sumname, depth) # self.extract_location(sum_name, depth)
self.emit("let _cls = _object.class();", depth) self.emit("let _cls = _object.class();", depth)
self.emit("Ok(", depth) self.emit("Ok(", depth)
@ -861,26 +866,26 @@ class TraitImplVisitor(EmitVisitor):
self.emit(f"if _cls.is(Node{cons.name}::static_type()) {{", depth) self.emit(f"if _cls.is(Node{cons.name}::static_type()) {{", depth)
if cons.fields: if cons.fields:
self.emit( self.emit(
f"ast::located::{rustname}::{cons.name} (ast::located::{enumname}{cons.name} {{", f"ast::located::{rust_name}::{cons.name} (ast::located::{enum_name}{cons.name} {{",
depth + 1, depth + 1,
) )
self.gen_construction_fields(cons, sumname, depth + 1) self.gen_construction_fields(cons, sum_name, depth + 1)
self.emit("})", depth + 1) self.emit("})", depth + 1)
else: else:
self.emit(f"ast::located::{rustname}::{cons.name}", depth + 1) self.emit(f"ast::located::{rust_name}::{cons.name}", depth + 1)
self.emit("} else", depth) self.emit("} else", depth)
self.emit("{", depth) self.emit("{", depth)
msg = f'format!("expected some sort of {sumname}, but got {{}}",_object.repr(_vm)?)' msg = f'format!("expected some sort of {sum_name}, but got {{}}",_object.repr(_vm)?)'
self.emit(f"return Err(_vm.new_type_error({msg}));", depth + 1) self.emit(f"return Err(_vm.new_type_error({msg}));", depth + 1)
self.emit("})", depth) self.emit("})", depth)
def gen_product_fromobj(self, product, prodname, structname, depth): def gen_product_from_object(self, product, product_name, struct_name, depth):
# if product.attributes: # if product.attributes:
# self.extract_location(prodname, depth) # self.extract_location(product_name, depth)
self.emit("Ok(", depth) self.emit("Ok(", depth)
self.gen_construction(structname, product, prodname, depth + 1) self.gen_construction(struct_name, product, product_name, depth + 1)
self.emit(")", depth) self.emit(")", depth)
def gen_construction_fields(self, cons, name, depth): def gen_construction_fields(self, cons, name, depth):
@ -926,19 +931,19 @@ class ChainOfVisitors:
v.emit("", 0) v.emit("", 0)
def write_ast_def(mod, typeinfo, f): def write_ast_def(mod, type_info, f):
StructVisitor(f, typeinfo).visit(mod) StructVisitor(f, type_info).visit(mod)
def write_fold_def(mod, typeinfo, f): def write_fold_def(mod, type_info, f):
FoldModuleVisitor(f, typeinfo).visit(mod) FoldModuleVisitor(f, type_info).visit(mod)
def write_visitor_def(mod, typeinfo, f): def write_visitor_def(mod, type_info, f):
VisitorModuleVisitor(f, typeinfo).visit(mod) VisitorModuleVisitor(f, type_info).visit(mod)
def write_located_def(mod, typeinfo, f): def write_located_def(mod, type_info, f):
f.write( f.write(
textwrap.dedent( textwrap.dedent(
""" """
@ -948,10 +953,10 @@ def write_located_def(mod, typeinfo, f):
""" """
) )
) )
for info in typeinfo.values(): for info in type_info.values():
if info.empty_field: if info.empty_field:
continue continue
if info.has_userdata: if info.has_user_data:
generics = "::<SourceRange>" generics = "::<SourceRange>"
else: else:
generics = "" generics = ""
@ -966,7 +971,7 @@ def write_located_def(mod, typeinfo, f):
) )
def write_ast_mod(mod, typeinfo, f): def write_ast_mod(mod, type_info, f):
f.write( f.write(
textwrap.dedent( textwrap.dedent(
""" """
@ -979,9 +984,9 @@ def write_ast_mod(mod, typeinfo, f):
) )
c = ChainOfVisitors( c = ChainOfVisitors(
ClassDefVisitor(f, typeinfo), class_defVisitor(f, type_info),
TraitImplVisitor(f, typeinfo), TraitImplVisitor(f, type_info),
ExtendModuleVisitor(f, typeinfo), ExtendModuleVisitor(f, type_info),
) )
c.visit(mod) c.visit(mod)
@ -992,7 +997,7 @@ def main(
module_filename, module_filename,
dump_module=False, dump_module=False,
): ):
auto_gen_msg = AUTOGEN_MESSAGE.format("/".join(Path(__file__).parts[-2:])) auto_gen_msg = AUTO_GEN_MESSAGE.format("/".join(Path(__file__).parts[-2:]))
mod = asdl.parse(input_filename) mod = asdl.parse(input_filename)
if dump_module: if dump_module:
print("Parsed Module:") print("Parsed Module:")
@ -1000,8 +1005,8 @@ def main(
if not asdl.check(mod): if not asdl.check(mod):
sys.exit(1) sys.exit(1)
typeinfo = {} type_info = {}
FindUserdataTypesVisitor(typeinfo).visit(mod) FindUserDataTypesVisitor(type_info).visit(mod)
for filename, write in [ for filename, write in [
("generic", write_ast_def), ("generic", write_ast_def),
@ -1011,11 +1016,11 @@ def main(
]: ]:
with (ast_dir / f"{filename}.rs").open("w") as f: with (ast_dir / f"{filename}.rs").open("w") as f:
f.write(auto_gen_msg) f.write(auto_gen_msg)
write(mod, typeinfo, f) write(mod, type_info, f)
with module_filename.open("w") as module_file: with module_filename.open("w") as module_file:
module_file.write(auto_gen_msg) module_file.write(auto_gen_msg)
write_ast_mod(mod, typeinfo, module_file) write_ast_mod(mod, type_info, module_file)
print(f"{ast_dir}, {module_filename} regenerated.") print(f"{ast_dir}, {module_filename} regenerated.")

View file

@ -32,6 +32,7 @@ pub mod fold {
#[cfg(feature = "visitor")] #[cfg(feature = "visitor")]
mod visitor { mod visitor {
use super::generic::*; use super::generic::*;
include!("gen/visitor.rs"); include!("gen/visitor.rs");
} }

View file

@ -65,7 +65,7 @@ pub(crate) const fn choose_quote(
Quote::Double => (double_count, single_count), Quote::Double => (double_count, single_count),
}; };
// always use primary unless we have primary but no seconday // always use primary unless we have primary but no secondary
let use_secondary = primary_count > 0 && secondary_count == 0; let use_secondary = primary_count > 0 && secondary_count == 0;
if use_secondary { if use_secondary {
(preferred_quote.swap(), secondary_count) (preferred_quote.swap(), secondary_count)
@ -242,7 +242,7 @@ impl<'a> Escape for UnicodeEscape<'a> {
} }
#[cfg(test)] #[cfg(test)]
mod unicode_escapse_tests { mod unicode_escape_tests {
use super::*; use super::*;
#[test] #[test]

3
scripts/cspell.sh Normal file
View file

@ -0,0 +1,3 @@
#!/bin/bash
cspell "ast/**/*.rs" "literal/**/*.rs" "core/**/*.rs" "parser/**/*.rs"
cspell ast/asdl_rs.py