Skip to main content

lisette_syntax/program/
definition.rs

1use rustc_hash::FxHashMap as HashMap;
2
3use ecow::EcoString;
4
5use crate::ast::{
6    Annotation, EnumVariant, Generic, Span, StructFieldDefinition, StructKind, ValueEnumVariant,
7};
8use crate::types::Type;
9
10#[derive(Debug, Clone)]
11pub enum Definition {
12    TypeAlias {
13        visibility: Visibility,
14        name: EcoString,
15        name_span: Span,
16        generics: Vec<Generic>,
17        annotation: Annotation,
18        ty: Type,
19        methods: MethodSignatures,
20        doc: Option<String>,
21    },
22    Enum {
23        visibility: Visibility,
24        ty: Type,
25        name: EcoString,
26        name_span: Span,
27        generics: Vec<Generic>,
28        variants: Vec<EnumVariant>,
29        methods: MethodSignatures,
30        doc: Option<String>,
31    },
32    ValueEnum {
33        visibility: Visibility,
34        ty: Type,
35        name: EcoString,
36        name_span: Span,
37        variants: Vec<ValueEnumVariant>,
38        underlying_ty: Option<Type>,
39        methods: MethodSignatures,
40        doc: Option<String>,
41    },
42    Struct {
43        visibility: Visibility,
44        ty: Type,
45        name: EcoString,
46        name_span: Span,
47        generics: Vec<Generic>,
48        fields: Vec<StructFieldDefinition>,
49        kind: StructKind,
50        methods: MethodSignatures,
51        constructor: Option<Type>,
52        doc: Option<String>,
53    },
54    Interface {
55        visibility: Visibility,
56        ty: Type,
57        name_span: Span,
58        definition: Interface,
59        doc: Option<String>,
60    },
61    Value {
62        visibility: Visibility,
63        ty: Type,
64        name_span: Option<Span>,
65        allowed_lints: Vec<String>,
66        go_hints: Vec<String>,
67        go_name: Option<String>,
68        doc: Option<String>,
69    },
70}
71
72impl Definition {
73    pub fn ty(&self) -> &Type {
74        match self {
75            Definition::TypeAlias { ty, .. } => ty,
76            Definition::Enum { ty, .. } => ty,
77            Definition::ValueEnum { ty, .. } => ty,
78            Definition::Struct { ty, .. } => ty,
79            Definition::Interface { ty, .. } => ty,
80            Definition::Value { ty, .. } => ty,
81        }
82    }
83
84    pub fn visibility(&self) -> &Visibility {
85        match self {
86            Definition::TypeAlias { visibility, .. } => visibility,
87            Definition::Enum { visibility, .. } => visibility,
88            Definition::ValueEnum { visibility, .. } => visibility,
89            Definition::Struct { visibility, .. } => visibility,
90            Definition::Interface { visibility, .. } => visibility,
91            Definition::Value { visibility, .. } => visibility,
92        }
93    }
94
95    /// A newtype is a single-field, non-generic tuple struct. Relevant
96    /// because Go compiles newtypes to named scalar types, so `.0` is a cast
97    /// rather than a field access — it cannot be assigned to, and taking
98    /// its address is invalid.
99    pub fn is_newtype(&self) -> bool {
100        matches!(
101            self,
102            Definition::Struct {
103                kind: StructKind::Tuple,
104                fields,
105                generics,
106                ..
107            } if fields.len() == 1 && generics.is_empty()
108        )
109    }
110
111    pub fn allowed_lints(&self) -> &[String] {
112        match self {
113            Definition::Value { allowed_lints, .. } => allowed_lints,
114            _ => &[],
115        }
116    }
117
118    pub fn go_hints(&self) -> &[String] {
119        match self {
120            Definition::Value { go_hints, .. } => go_hints,
121            _ => &[],
122        }
123    }
124
125    pub fn go_name(&self) -> Option<&str> {
126        match self {
127            Definition::Value { go_name, .. } => go_name.as_deref(),
128            _ => None,
129        }
130    }
131
132    pub fn methods_mut(&mut self) -> Option<&mut MethodSignatures> {
133        match self {
134            Definition::Struct { methods, .. } => Some(methods),
135            Definition::TypeAlias { methods, .. } => Some(methods),
136            Definition::Enum { methods, .. } => Some(methods),
137            Definition::ValueEnum { methods, .. } => Some(methods),
138            _ => None,
139        }
140    }
141
142    pub fn is_type_definition(&self) -> bool {
143        matches!(
144            self,
145            Definition::Struct { .. }
146                | Definition::Enum { .. }
147                | Definition::ValueEnum { .. }
148                | Definition::TypeAlias { .. }
149        )
150    }
151
152    pub fn name_span(&self) -> Option<Span> {
153        match self {
154            Definition::TypeAlias { name_span, .. } => Some(*name_span),
155            Definition::Enum { name_span, .. } => Some(*name_span),
156            Definition::ValueEnum { name_span, .. } => Some(*name_span),
157            Definition::Struct { name_span, .. } => Some(*name_span),
158            Definition::Interface { name_span, .. } => Some(*name_span),
159            Definition::Value { name_span, .. } => *name_span,
160        }
161    }
162
163    pub fn doc(&self) -> Option<&String> {
164        match self {
165            Definition::TypeAlias { doc, .. }
166            | Definition::Enum { doc, .. }
167            | Definition::ValueEnum { doc, .. }
168            | Definition::Struct { doc, .. }
169            | Definition::Interface { doc, .. }
170            | Definition::Value { doc, .. } => doc.as_ref(),
171        }
172    }
173}
174
175pub type MethodSignatures = HashMap<EcoString, Type>;
176
177#[derive(Debug, Clone, PartialEq)]
178pub enum Visibility {
179    Public,
180    Private,
181    Local,
182}
183
184impl Visibility {
185    pub fn is_public(&self) -> bool {
186        matches!(self, Visibility::Public)
187    }
188}
189
190#[derive(Debug, Clone, PartialEq)]
191pub struct Interface {
192    pub name: EcoString,
193    pub generics: Vec<Generic>,
194    pub parents: Vec<Type>,
195    pub methods: HashMap<EcoString, Type>,
196}