Skip to main content

oak_go/kind/
mod.rs

1use oak_core::{ElementType, TokenType, UniversalElementRole, UniversalTokenRole};
2use serde::{Deserialize, Serialize};
3
4/// Go 语法节点类型
5#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
6pub enum GoSyntaxKind {
7    // 非终端节点
8    SourceFile,
9    PackageClause,
10    ImportDeclaration,
11    ImportSpec,
12    FunctionDeclaration,
13    ParameterList,
14    ParameterDecl,
15    Block,
16    VariableDeclaration,
17    VariableSpec,
18    ConstDeclaration,
19    ConstSpec,
20    TypeDeclaration,
21    TypeSpec,
22    StructType,
23    FieldDeclList,
24    FieldDecl,
25    InterfaceType,
26    MethodSpecList,
27    MethodSpec,
28    ExpressionList,
29    AssignmentStatement,
30    ShortVarDecl,
31    ReturnStatement,
32    IfStatement,
33    ForStatement,
34    SwitchStatement,
35    ExprCaseClause,
36    TypeSwitchStatement,
37    TypeCaseClause,
38    SelectStatement,
39    CommClause,
40    GoStatement,
41    DeferStatement,
42    CallExpression,
43    IndexExpression,
44    SelectorExpression,
45    SliceExpression,
46    TypeAssertion,
47    UnaryExpression,
48    BinaryExpression,
49    LiteralValue,
50    ElementList,
51    KeyedElement,
52
53    // 字面
54    IntLiteral,
55    FloatLiteral,
56    StringLiteral,
57    RuneLiteral,
58    BoolLiteral,
59
60    // 标识
61    Identifier,
62
63    // 关键
64    Break,
65    Case,
66    Chan,
67    Const,
68    Continue,
69    Default,
70    Defer,
71    Else,
72    Fallthrough,
73    For,
74    Func,
75    Go,
76    Goto,
77    If,
78    Import,
79    Interface,
80    Map,
81    Package,
82    Range,
83    Return,
84    Select,
85    Struct,
86    Switch,
87    Type,
88    Var,
89
90    // 内置类型
91    Bool,
92    Byte,
93    Complex64,
94    Complex128,
95    ErrorType,
96    Float32,
97    Float64,
98    Int,
99    Int8,
100    Int16,
101    Int32,
102    Int64,
103    Rune,
104    String,
105    Uint,
106    Uint8,
107    Uint16,
108    Uint32,
109    Uint64,
110    Uintptr,
111
112    // 特殊字面
113    NilLiteral,
114    NumberLiteral,
115    CharLiteral,
116
117    // 操作
118    Plus,           // +
119    Minus,          // -
120    Star,           // *
121    Slash,          // /
122    Percent,        // %
123    Ampersand,      // &
124    Pipe,           // |
125    Caret,          // ^
126    LeftShift,      // <<
127    RightShift,     // >>
128    AmpersandCaret, // &^
129
130    PlusAssign,           // +=
131    MinusAssign,          // -=
132    StarAssign,           // *=
133    SlashAssign,          // /=
134    PercentAssign,        // %=
135    AmpersandAssign,      // &=
136    PipeAssign,           // |=
137    CaretAssign,          // ^=
138    XorAssign,            // ^= (别名)
139    LeftShiftAssign,      // <<=
140    RightShiftAssign,     // >>=
141    AmpersandCaretAssign, // &^=
142    AndAssign,            // &=
143    OrAssign,             // |=
144    AndNotAssign,         // &^=
145    AndNot,               // &^
146
147    LogicalAnd, // &&
148    LogicalOr,  // ||
149    And,        // && (别名)
150    Or,         // || (别名)
151    Arrow,      // <-
152    LeftArrow,  // <- (别名)
153    Increment,  // ++
154    Decrement,  // --
155
156    Equal,      // ==
157    Less,       // <
158    Greater,    // >
159    Assign,     // =
160    LogicalNot, // !
161    Not,        // ! (别名)
162
163    NotEqual,     // !=
164    LessEqual,    // <=
165    GreaterEqual, // >=
166    ColonAssign,  // :=
167    Define,       // := (别名)
168    Ellipsis,     // ...
169
170    // 分隔
171    LeftParen,    // (
172    RightParen,   // )
173    LeftBracket,  // [
174    RightBracket, // ]
175    LeftBrace,    // {
176    RightBrace,   // }
177    Comma,        // ,
178    Period,       // .
179    Dot,          // . (别名)
180    Semicolon,    // ;
181    Colon,        // :
182
183    // 空白和注
184    Whitespace,
185    Comment,
186
187    // 特殊
188    Eof,
189    Error,
190}
191
192impl GoSyntaxKind {
193    pub fn is_ignored(&self) -> bool {
194        matches!(self, Self::Whitespace | Self::Comment)
195    }
196
197    pub fn is_keyword(&self) -> bool {
198        matches!(
199            self,
200            Self::Break
201                | Self::Case
202                | Self::Chan
203                | Self::Const
204                | Self::Continue
205                | Self::Default
206                | Self::Defer
207                | Self::Else
208                | Self::Fallthrough
209                | Self::For
210                | Self::Func
211                | Self::Go
212                | Self::Goto
213                | Self::If
214                | Self::Import
215                | Self::Interface
216                | Self::Map
217                | Self::Package
218                | Self::Range
219                | Self::Return
220                | Self::Select
221                | Self::Struct
222                | Self::Switch
223                | Self::Type
224                | Self::Var
225        )
226    }
227}
228
229impl TokenType for GoSyntaxKind {
230    const END_OF_STREAM: Self = Self::Eof;
231    type Role = UniversalTokenRole;
232
233    fn role(&self) -> Self::Role {
234        match self {
235            Self::Whitespace => UniversalTokenRole::Whitespace,
236            Self::Comment => UniversalTokenRole::Comment,
237            Self::Identifier => UniversalTokenRole::Name,
238            Self::IntLiteral | Self::FloatLiteral | Self::StringLiteral | Self::RuneLiteral | Self::BoolLiteral | Self::NilLiteral | Self::NumberLiteral | Self::CharLiteral => UniversalTokenRole::Literal,
239            _ if self.is_keyword() => UniversalTokenRole::Keyword,
240            Self::Plus
241            | Self::Minus
242            | Self::Star
243            | Self::Slash
244            | Self::Percent
245            | Self::Ampersand
246            | Self::Pipe
247            | Self::Caret
248            | Self::LeftShift
249            | Self::RightShift
250            | Self::AmpersandCaret
251            | Self::PlusAssign
252            | Self::MinusAssign
253            | Self::StarAssign
254            | Self::SlashAssign
255            | Self::PercentAssign
256            | Self::AmpersandAssign
257            | Self::PipeAssign
258            | Self::CaretAssign
259            | Self::XorAssign
260            | Self::LeftShiftAssign
261            | Self::RightShiftAssign
262            | Self::AmpersandCaretAssign
263            | Self::AndAssign
264            | Self::OrAssign
265            | Self::AndNotAssign
266            | Self::AndNot
267            | Self::LogicalAnd
268            | Self::LogicalOr
269            | Self::And
270            | Self::Or
271            | Self::Arrow
272            | Self::LeftArrow
273            | Self::Increment
274            | Self::Decrement
275            | Self::Equal
276            | Self::Less
277            | Self::Greater
278            | Self::Assign
279            | Self::LogicalNot
280            | Self::Not
281            | Self::NotEqual
282            | Self::LessEqual
283            | Self::GreaterEqual
284            | Self::ColonAssign
285            | Self::Define => UniversalTokenRole::Operator,
286            Self::LeftParen | Self::RightParen | Self::LeftBracket | Self::RightBracket | Self::LeftBrace | Self::RightBrace | Self::Comma | Self::Period | Self::Dot | Self::Semicolon | Self::Colon | Self::Ellipsis => UniversalTokenRole::Punctuation,
287            Self::Eof => UniversalTokenRole::Eof,
288            _ => UniversalTokenRole::None,
289        }
290    }
291
292    fn is_comment(&self) -> bool {
293        matches!(self, Self::Comment)
294    }
295
296    fn is_whitespace(&self) -> bool {
297        matches!(self, Self::Whitespace)
298    }
299}
300
301use core::fmt;
302
303impl fmt::Debug for GoSyntaxKind {
304    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
305        let name = match self {
306            Self::SourceFile => "SourceFile",
307            Self::PackageClause => "PackageClause",
308            Self::ImportDeclaration => "ImportDeclaration",
309            Self::ImportSpec => "ImportSpec",
310            Self::FunctionDeclaration => "FunctionDeclaration",
311            Self::ParameterList => "ParameterList",
312            Self::ParameterDecl => "ParameterDecl",
313            Self::Block => "Block",
314            Self::VariableDeclaration => "VariableDeclaration",
315            Self::VariableSpec => "VariableSpec",
316            Self::ConstDeclaration => "ConstDeclaration",
317            Self::ConstSpec => "ConstSpec",
318            Self::TypeDeclaration => "TypeDeclaration",
319            Self::TypeSpec => "TypeSpec",
320            Self::StructType => "StructType",
321            Self::FieldDeclList => "FieldDeclList",
322            Self::FieldDecl => "FieldDecl",
323            Self::InterfaceType => "InterfaceType",
324            Self::MethodSpecList => "MethodSpecList",
325            Self::MethodSpec => "MethodSpec",
326            Self::ExpressionList => "ExpressionList",
327            Self::AssignmentStatement => "AssignmentStatement",
328            Self::ShortVarDecl => "ShortVarDecl",
329            Self::ReturnStatement => "ReturnStatement",
330            Self::IfStatement => "IfStatement",
331            Self::ForStatement => "ForStatement",
332            Self::SwitchStatement => "SwitchStatement",
333            Self::ExprCaseClause => "ExprCaseClause",
334            Self::TypeSwitchStatement => "TypeSwitchStatement",
335            Self::TypeCaseClause => "TypeCaseClause",
336            Self::SelectStatement => "SelectStatement",
337            Self::CommClause => "CommClause",
338            Self::GoStatement => "GoStatement",
339            Self::DeferStatement => "DeferStatement",
340            Self::CallExpression => "CallExpression",
341            Self::IndexExpression => "IndexExpression",
342            Self::SelectorExpression => "SelectorExpression",
343            Self::SliceExpression => "SliceExpression",
344            Self::TypeAssertion => "TypeAssertion",
345            Self::UnaryExpression => "UnaryExpression",
346            Self::BinaryExpression => "BinaryExpression",
347            Self::LiteralValue => "LiteralValue",
348            Self::ElementList => "ElementList",
349            Self::KeyedElement => "KeyedElement",
350            Self::IntLiteral => "IntLiteral",
351            Self::FloatLiteral => "FloatLiteral",
352            Self::StringLiteral => "StringLiteral",
353            Self::RuneLiteral => "RuneLiteral",
354            Self::BoolLiteral => "BoolLiteral",
355            Self::NilLiteral => "NilLiteral",
356            Self::Identifier => "Identifier",
357            Self::Package => "Package",
358            Self::Import => "Import",
359            Self::Func => "Func",
360            Self::Var => "Var",
361            Self::Const => "Const",
362            Self::Type => "Type",
363            Self::Struct => "Struct",
364            Self::Interface => "Interface",
365            Self::Map => "Map",
366            Self::Chan => "Chan",
367            Self::If => "If",
368            Self::Else => "Else",
369            Self::For => "For",
370            Self::Range => "Range",
371            Self::Switch => "Switch",
372            Self::Case => "Case",
373            Self::Default => "Default",
374            Self::Break => "Break",
375            Self::Continue => "Continue",
376            Self::Return => "Return",
377            Self::Go => "Go",
378            Self::Defer => "Defer",
379            Self::Select => "Select",
380            Self::Fallthrough => "Fallthrough",
381            Self::Goto => "Goto",
382            Self::LeftParen => "LeftParen",
383            Self::RightParen => "RightParen",
384            Self::LeftBrace => "LeftBrace",
385            Self::RightBrace => "RightBrace",
386            Self::LeftBracket => "LeftBracket",
387            Self::RightBracket => "RightBracket",
388            Self::Plus => "Plus",
389            Self::Minus => "Minus",
390            Self::Star => "Star",
391            Self::Slash => "Slash",
392            Self::Percent => "Percent",
393            Self::Ampersand => "Ampersand",
394            Self::Pipe => "Pipe",
395            Self::Caret => "Caret",
396            Self::LeftShift => "LeftShift",
397            Self::RightShift => "RightShift",
398            Self::AndNot => "AndNot",
399            Self::PlusAssign => "PlusAssign",
400            Self::MinusAssign => "MinusAssign",
401            Self::StarAssign => "StarAssign",
402            Self::SlashAssign => "SlashAssign",
403            Self::PercentAssign => "PercentAssign",
404            Self::AmpersandAssign => "AmpersandAssign",
405            Self::PipeAssign => "PipeAssign",
406            Self::CaretAssign => "CaretAssign",
407            Self::LeftShiftAssign => "LeftShiftAssign",
408            Self::RightShiftAssign => "RightShiftAssign",
409            Self::XorAssign => "XorAssign",
410            Self::AndAssign => "AndAssign",
411            Self::OrAssign => "OrAssign",
412            Self::AndNotAssign => "AndNotAssign",
413            Self::LogicalAnd => "LogicalAnd",
414            Self::LogicalOr => "LogicalOr",
415            Self::And => "And",
416            Self::Or => "Or",
417            Self::Arrow => "Arrow",
418            Self::LeftArrow => "LeftArrow",
419            Self::Increment => "Increment",
420            Self::Decrement => "Decrement",
421            Self::Equal => "Equal",
422            Self::Less => "Less",
423            Self::Greater => "Greater",
424            Self::Assign => "Assign",
425            Self::LogicalNot => "LogicalNot",
426            Self::Not => "Not",
427            Self::NotEqual => "NotEqual",
428            Self::LessEqual => "LessEqual",
429            Self::GreaterEqual => "GreaterEqual",
430            Self::ColonAssign => "ColonAssign",
431            Self::Define => "Define",
432            Self::Comma => "Comma",
433            Self::Period => "Period",
434            Self::Dot => "Dot",
435            Self::Semicolon => "Semicolon",
436            Self::Colon => "Colon",
437            Self::Ellipsis => "Ellipsis",
438            Self::AmpersandCaret => "AmpersandCaret",
439            Self::AmpersandCaretAssign => "AmpersandCaretAssign",
440            Self::Bool => "Bool",
441            Self::Byte => "Byte",
442            Self::Complex64 => "Complex64",
443            Self::Complex128 => "Complex128",
444            Self::ErrorType => "ErrorType",
445            Self::Float32 => "Float32",
446            Self::Float64 => "Float64",
447            Self::Int => "Int",
448            Self::Int8 => "Int8",
449            Self::Int16 => "Int16",
450            Self::Int32 => "Int32",
451            Self::Int64 => "Int64",
452            Self::Rune => "Rune",
453            Self::String => "String",
454            Self::Uint => "Uint",
455            Self::Uint8 => "Uint8",
456            Self::Uint16 => "Uint16",
457            Self::Uint32 => "Uint32",
458            Self::Uint64 => "Uint64",
459            Self::Uintptr => "Uintptr",
460            Self::NumberLiteral => "NumberLiteral",
461            Self::CharLiteral => "CharLiteral",
462            Self::Whitespace => "Whitespace",
463            Self::Comment => "Comment",
464            Self::Eof => "Eof",
465            Self::Error => "Error",
466        };
467        write!(f, "{}", name)
468    }
469}
470
471impl ElementType for GoSyntaxKind {
472    type Role = UniversalElementRole;
473
474    fn role(&self) -> Self::Role {
475        match self {
476            Self::SourceFile => UniversalElementRole::Root,
477            Self::FunctionDeclaration | Self::VariableDeclaration | Self::ConstDeclaration | Self::TypeDeclaration => UniversalElementRole::Definition,
478            Self::IfStatement | Self::ForStatement | Self::SwitchStatement | Self::ReturnStatement => UniversalElementRole::Statement,
479            Self::CallExpression | Self::BinaryExpression | Self::UnaryExpression => UniversalElementRole::Expression,
480            Self::Error => UniversalElementRole::Error,
481            _ => UniversalElementRole::None,
482        }
483    }
484
485    fn is_error(&self) -> bool {
486        matches!(self, Self::Error)
487    }
488
489    fn is_root(&self) -> bool {
490        matches!(self, Self::SourceFile)
491    }
492}