From 914c6db4a2c8b15ff42021493b7505814f93b0d7 Mon Sep 17 00:00:00 2001 From: MineGame159 Date: Thu, 4 Jan 2024 17:11:23 +0100 Subject: [PATCH] CORE: Add Clone() method to ast.Node --- core/ast/ast.go | 8 +- core/ast/declarations.go | 106 +++++++++++++++++ core/ast/expressions.go | 249 +++++++++++++++++++++++++++++++++++++++ core/ast/other.go | 111 +++++++++++++++++ core/ast/statements.go | 128 ++++++++++++++++++++ core/ast/types.go | 52 ++++++++ gen/main.go | 54 +++++++++ 7 files changed, 706 insertions(+), 2 deletions(-) diff --git a/core/ast/ast.go b/core/ast/ast.go index 4b2e8c1..f137f8c 100644 --- a/core/ast/ast.go +++ b/core/ast/ast.go @@ -15,6 +15,8 @@ type Node interface { AcceptChildren(visitor Visitor) + Clone() Node + String() string } @@ -45,9 +47,11 @@ func (g *get) VisitNode(node Node) { } // Check if node contains target position - if node.Cst() == nil || node.Cst().Range.Contains(g.pos) { + contains := node.Cst().Range.Contains(g.pos) + + if node.Cst() == nil || contains { // Check if node is a leaf node - if !node.Token().IsError() { + if !node.Token().IsEmpty() && contains { g.node = node return } diff --git a/core/ast/declarations.go b/core/ast/declarations.go index 8e9c65d..9008368 100644 --- a/core/ast/declarations.go +++ b/core/ast/declarations.go @@ -92,6 +92,29 @@ func (s *Struct) AcceptChildren(visitor Visitor) { } } +func (s *Struct) Clone() Node { + s2 := &Struct{ + cst: s.cst, + } + + if s.Name != nil { + s2.Name = s.Name.Clone().(*Token) + s2.Name.SetParent(s2) + } + s2.Fields = make([]*Field, len(s.Fields)) + for i, child := range s2.Fields { + s2.Fields[i] = child.Clone().(*Field) + s2.Fields[i].SetParent(s2) + } + s2.StaticFields = make([]*Field, len(s.StaticFields)) + for i, child := range s2.StaticFields { + s2.StaticFields[i] = child.Clone().(*Field) + s2.StaticFields[i].SetParent(s2) + } + + return s2 +} + func (s *Struct) String() string { return "" } @@ -173,6 +196,33 @@ func (e *Enum) AcceptChildren(visitor Visitor) { } } +func (e *Enum) Clone() Node { + e2 := &Enum{ + cst: e.cst, + ActualType: e.ActualType, + } + + if e.Name != nil { + e2.Name = e.Name.Clone().(*Token) + e2.Name.SetParent(e2) + } + if e.Type != nil { + e2.Type = e.Type.Clone().(Type) + e2.Type.SetParent(e2) + } + if e.ActualType != nil { + e2.ActualType = e.ActualType.Clone().(Type) + e2.ActualType.SetParent(e2) + } + e2.Cases = make([]*EnumCase, len(e.Cases)) + for i, child := range e2.Cases { + e2.Cases[i] = child.Clone().(*EnumCase) + e2.Cases[i].SetParent(e2) + } + + return e2 +} + func (e *Enum) String() string { return "" } @@ -246,6 +296,29 @@ func (i *Impl) AcceptChildren(visitor Visitor) { } } +func (i *Impl) Clone() Node { + i2 := &Impl{ + cst: i.cst, + Type: i.Type, + } + + if i.Struct != nil { + i2.Struct = i.Struct.Clone().(*Token) + i2.Struct.SetParent(i2) + } + if i.Type != nil { + i2.Type = i.Type.Clone().(Type) + i2.Type.SetParent(i2) + } + i2.Methods = make([]*Func, len(i.Methods)) + for i, child := range i2.Methods { + i2.Methods[i] = child.Clone().(*Func) + i2.Methods[i].SetParent(i2) + } + + return i2 +} + func (i *Impl) String() string { return "" } @@ -344,6 +417,39 @@ func (f *Func) AcceptChildren(visitor Visitor) { } } +func (f *Func) Clone() Node { + f2 := &Func{ + cst: f.cst, + Flags: f.Flags, + } + + f2.Attributes = make([]*Attribute, len(f.Attributes)) + for i, child := range f2.Attributes { + f2.Attributes[i] = child.Clone().(*Attribute) + f2.Attributes[i].SetParent(f2) + } + if f.Name != nil { + f2.Name = f.Name.Clone().(*Token) + f2.Name.SetParent(f2) + } + f2.Params = make([]*Param, len(f.Params)) + for i, child := range f2.Params { + f2.Params[i] = child.Clone().(*Param) + f2.Params[i].SetParent(f2) + } + if f.Returns != nil { + f2.Returns = f.Returns.Clone().(Type) + f2.Returns.SetParent(f2) + } + f2.Body = make([]Stmt, len(f.Body)) + for i, child := range f2.Body { + f2.Body[i] = child.Clone().(Stmt) + f2.Body[i].SetParent(f2) + } + + return f2 +} + func (f *Func) String() string { return "" } diff --git a/core/ast/expressions.go b/core/ast/expressions.go index 8638098..7103c97 100644 --- a/core/ast/expressions.go +++ b/core/ast/expressions.go @@ -91,6 +91,19 @@ func (p *Paren) AcceptChildren(visitor Visitor) { } } +func (p *Paren) Clone() Node { + p2 := &Paren{ + cst: p.cst, + } + + if p.Expr != nil { + p2.Expr = p.Expr.Clone().(Expr) + p2.Expr.SetParent(p2) + } + + return p2 +} + func (p *Paren) String() string { return "" } @@ -171,6 +184,24 @@ func (u *Unary) AcceptChildren(visitor Visitor) { } } +func (u *Unary) Clone() Node { + u2 := &Unary{ + cst: u.cst, + Prefix: u.Prefix, + } + + if u.Operator != nil { + u2.Operator = u.Operator.Clone().(*Token) + u2.Operator.SetParent(u2) + } + if u.Value != nil { + u2.Value = u.Value.Clone().(Expr) + u2.Value.SetParent(u2) + } + + return u2 +} + func (u *Unary) String() string { return "" } @@ -257,6 +288,27 @@ func (b *Binary) AcceptChildren(visitor Visitor) { } } +func (b *Binary) Clone() Node { + b2 := &Binary{ + cst: b.cst, + } + + if b.Left != nil { + b2.Left = b.Left.Clone().(Expr) + b2.Left.SetParent(b2) + } + if b.Operator != nil { + b2.Operator = b.Operator.Clone().(*Token) + b2.Operator.SetParent(b2) + } + if b.Right != nil { + b2.Right = b.Right.Clone().(Expr) + b2.Right.SetParent(b2) + } + + return b2 +} + func (b *Binary) String() string { return "" } @@ -343,6 +395,27 @@ func (l *Logical) AcceptChildren(visitor Visitor) { } } +func (l *Logical) Clone() Node { + l2 := &Logical{ + cst: l.cst, + } + + if l.Left != nil { + l2.Left = l.Left.Clone().(Expr) + l2.Left.SetParent(l2) + } + if l.Operator != nil { + l2.Operator = l.Operator.Clone().(*Token) + l2.Operator.SetParent(l2) + } + if l.Right != nil { + l2.Right = l.Right.Clone().(Expr) + l2.Right.SetParent(l2) + } + + return l2 +} + func (l *Logical) String() string { return "" } @@ -429,6 +502,27 @@ func (a *Assignment) AcceptChildren(visitor Visitor) { } } +func (a *Assignment) Clone() Node { + a2 := &Assignment{ + cst: a.cst, + } + + if a.Assignee != nil { + a2.Assignee = a.Assignee.Clone().(Expr) + a2.Assignee.SetParent(a2) + } + if a.Operator != nil { + a2.Operator = a.Operator.Clone().(*Token) + a2.Operator.SetParent(a2) + } + if a.Value != nil { + a2.Value = a.Value.Clone().(Expr) + a2.Value.SetParent(a2) + } + + return a2 +} + func (a *Assignment) String() string { return "" } @@ -507,6 +601,23 @@ func (m *Member) AcceptChildren(visitor Visitor) { } } +func (m *Member) Clone() Node { + m2 := &Member{ + cst: m.cst, + } + + if m.Value != nil { + m2.Value = m.Value.Clone().(Expr) + m2.Value.SetParent(m2) + } + if m.Name != nil { + m2.Name = m.Name.Clone().(*Token) + m2.Name.SetParent(m2) + } + + return m2 +} + func (m *Member) String() string { return "" } @@ -585,6 +696,23 @@ func (i *Index) AcceptChildren(visitor Visitor) { } } +func (i *Index) Clone() Node { + i2 := &Index{ + cst: i.cst, + } + + if i.Value != nil { + i2.Value = i.Value.Clone().(Expr) + i2.Value.SetParent(i2) + } + if i.Index != nil { + i2.Index = i.Index.Clone().(Expr) + i2.Index.SetParent(i2) + } + + return i2 +} + func (i *Index) String() string { return "" } @@ -663,6 +791,23 @@ func (c *Cast) AcceptChildren(visitor Visitor) { } } +func (c *Cast) Clone() Node { + c2 := &Cast{ + cst: c.cst, + } + + if c.Value != nil { + c2.Value = c.Value.Clone().(Expr) + c2.Value.SetParent(c2) + } + if c.Target != nil { + c2.Target = c.Target.Clone().(Type) + c2.Target.SetParent(c2) + } + + return c2 +} + func (c *Cast) String() string { return "" } @@ -741,6 +886,24 @@ func (c *Call) AcceptChildren(visitor Visitor) { } } +func (c *Call) Clone() Node { + c2 := &Call{ + cst: c.cst, + } + + if c.Callee != nil { + c2.Callee = c.Callee.Clone().(Expr) + c2.Callee.SetParent(c2) + } + c2.Args = make([]Expr, len(c.Args)) + for i, child := range c2.Args { + c2.Args[i] = child.Clone().(Expr) + c2.Args[i].SetParent(c2) + } + + return c2 +} + func (c *Call) String() string { return "" } @@ -819,6 +982,23 @@ func (t *TypeCall) AcceptChildren(visitor Visitor) { } } +func (t *TypeCall) Clone() Node { + t2 := &TypeCall{ + cst: t.cst, + } + + if t.Callee != nil { + t2.Callee = t.Callee.Clone().(*Token) + t2.Callee.SetParent(t2) + } + if t.Arg != nil { + t2.Arg = t.Arg.Clone().(Type) + t2.Arg.SetParent(t2) + } + + return t2 +} + func (t *TypeCall) String() string { return "" } @@ -899,6 +1079,25 @@ func (s *StructInitializer) AcceptChildren(visitor Visitor) { } } +func (s *StructInitializer) Clone() Node { + s2 := &StructInitializer{ + cst: s.cst, + New: s.New, + } + + if s.Type != nil { + s2.Type = s.Type.Clone().(Type) + s2.Type.SetParent(s2) + } + s2.Fields = make([]*InitField, len(s.Fields)) + for i, child := range s2.Fields { + s2.Fields[i] = child.Clone().(*InitField) + s2.Fields[i].SetParent(s2) + } + + return s2 +} + func (s *StructInitializer) String() string { return "" } @@ -969,6 +1168,20 @@ func (a *ArrayInitializer) AcceptChildren(visitor Visitor) { } } +func (a *ArrayInitializer) Clone() Node { + a2 := &ArrayInitializer{ + cst: a.cst, + } + + a2.Values = make([]Expr, len(a.Values)) + for i, child := range a2.Values { + a2.Values[i] = child.Clone().(Expr) + a2.Values[i].SetParent(a2) + } + + return a2 +} + func (a *ArrayInitializer) String() string { return "" } @@ -1047,6 +1260,23 @@ func (a *AllocateArray) AcceptChildren(visitor Visitor) { } } +func (a *AllocateArray) Clone() Node { + a2 := &AllocateArray{ + cst: a.cst, + } + + if a.Type != nil { + a2.Type = a.Type.Clone().(Type) + a2.Type.SetParent(a2) + } + if a.Count != nil { + a2.Count = a.Count.Clone().(Expr) + a2.Count.SetParent(a2) + } + + return a2 +} + func (a *AllocateArray) String() string { return "" } @@ -1111,6 +1341,16 @@ func (i *Identifier) SetParent(parent Node) { func (i *Identifier) AcceptChildren(visitor Visitor) { } +func (i *Identifier) Clone() Node { + i2 := &Identifier{ + cst: i.cst, + Name: i.Name, + Kind: i.Kind, + } + + return i2 +} + func (i *Identifier) String() string { return i.Name.String() } @@ -1174,6 +1414,15 @@ func (l *Literal) SetParent(parent Node) { func (l *Literal) AcceptChildren(visitor Visitor) { } +func (l *Literal) Clone() Node { + l2 := &Literal{ + cst: l.cst, + Token_: l.Token_, + } + + return l2 +} + func (l *Literal) String() string { return l.Token_.String() } diff --git a/core/ast/other.go b/core/ast/other.go index 3fb9161..f4f49b9 100644 --- a/core/ast/other.go +++ b/core/ast/other.go @@ -59,6 +59,21 @@ func (f *File) AcceptChildren(visitor Visitor) { } } +func (f *File) Clone() Node { + f2 := &File{ + cst: f.cst, + Path: f.Path, + } + + f2.Decls = make([]Decl, len(f.Decls)) + for i, child := range f2.Decls { + f2.Decls[i] = child.Clone().(Decl) + f2.Decls[i].SetParent(f2) + } + + return f2 +} + func (f *File) String() string { return "" } @@ -127,6 +142,23 @@ func (f *Field) AcceptChildren(visitor Visitor) { } } +func (f *Field) Clone() Node { + f2 := &Field{ + cst: f.cst, + } + + if f.Name != nil { + f2.Name = f.Name.Clone().(*Token) + f2.Name.SetParent(f2) + } + if f.Type != nil { + f2.Type = f.Type.Clone().(Type) + f2.Type.SetParent(f2) + } + + return f2 +} + func (f *Field) String() string { return "" } @@ -195,6 +227,23 @@ func (i *InitField) AcceptChildren(visitor Visitor) { } } +func (i *InitField) Clone() Node { + i2 := &InitField{ + cst: i.cst, + } + + if i.Name != nil { + i2.Name = i.Name.Clone().(*Token) + i2.Name.SetParent(i2) + } + if i.Value != nil { + i2.Value = i.Value.Clone().(Expr) + i2.Value.SetParent(i2) + } + + return i2 +} + func (i *InitField) String() string { return "" } @@ -264,6 +313,24 @@ func (e *EnumCase) AcceptChildren(visitor Visitor) { } } +func (e *EnumCase) Clone() Node { + e2 := &EnumCase{ + cst: e.cst, + ActualValue: e.ActualValue, + } + + if e.Name != nil { + e2.Name = e.Name.Clone().(*Token) + e2.Name.SetParent(e2) + } + if e.Value != nil { + e2.Value = e.Value.Clone().(*Token) + e2.Value.SetParent(e2) + } + + return e2 +} + func (e *EnumCase) String() string { return "" } @@ -332,6 +399,23 @@ func (p *Param) AcceptChildren(visitor Visitor) { } } +func (p *Param) Clone() Node { + p2 := &Param{ + cst: p.cst, + } + + if p.Name != nil { + p2.Name = p.Name.Clone().(*Token) + p2.Name.SetParent(p2) + } + if p.Type != nil { + p2.Type = p.Type.Clone().(Type) + p2.Type.SetParent(p2) + } + + return p2 +} + func (p *Param) String() string { return "" } @@ -400,6 +484,24 @@ func (a *Attribute) AcceptChildren(visitor Visitor) { } } +func (a *Attribute) Clone() Node { + a2 := &Attribute{ + cst: a.cst, + } + + if a.Name != nil { + a2.Name = a.Name.Clone().(*Token) + a2.Name.SetParent(a2) + } + a2.Args = make([]*Token, len(a.Args)) + for i, child := range a2.Args { + a2.Args[i] = child.Clone().(*Token) + a2.Args[i].SetParent(a2) + } + + return a2 +} + func (a *Attribute) String() string { return "" } @@ -453,6 +555,15 @@ func (t *Token) SetParent(parent Node) { func (t *Token) AcceptChildren(visitor Visitor) { } +func (t *Token) Clone() Node { + t2 := &Token{ + cst: t.cst, + Token_: t.Token_, + } + + return t2 +} + func (t *Token) String() string { return t.Token_.String() } diff --git a/core/ast/statements.go b/core/ast/statements.go index e409c01..f859e7c 100644 --- a/core/ast/statements.go +++ b/core/ast/statements.go @@ -80,6 +80,19 @@ func (e *Expression) AcceptChildren(visitor Visitor) { } } +func (e *Expression) Clone() Node { + e2 := &Expression{ + cst: e.cst, + } + + if e.Expr != nil { + e2.Expr = e.Expr.Clone().(Expr) + e2.Expr.SetParent(e2) + } + + return e2 +} + func (e *Expression) String() string { return "" } @@ -144,6 +157,20 @@ func (b *Block) AcceptChildren(visitor Visitor) { } } +func (b *Block) Clone() Node { + b2 := &Block{ + cst: b.cst, + } + + b2.Stmts = make([]Stmt, len(b.Stmts)) + for i, child := range b2.Stmts { + b2.Stmts[i] = child.Clone().(Stmt) + b2.Stmts[i].SetParent(b2) + } + + return b2 +} + func (b *Block) String() string { return "" } @@ -225,6 +252,32 @@ func (v *Var) AcceptChildren(visitor Visitor) { } } +func (v *Var) Clone() Node { + v2 := &Var{ + cst: v.cst, + ActualType: v.ActualType, + } + + if v.Name != nil { + v2.Name = v.Name.Clone().(*Token) + v2.Name.SetParent(v2) + } + if v.Type != nil { + v2.Type = v.Type.Clone().(Type) + v2.Type.SetParent(v2) + } + if v.ActualType != nil { + v2.ActualType = v.ActualType.Clone().(Type) + v2.ActualType.SetParent(v2) + } + if v.Value != nil { + v2.Value = v.Value.Clone().(Expr) + v2.Value.SetParent(v2) + } + + return v2 +} + func (v *Var) String() string { return "" } @@ -305,6 +358,27 @@ func (i *If) AcceptChildren(visitor Visitor) { } } +func (i *If) Clone() Node { + i2 := &If{ + cst: i.cst, + } + + if i.Condition != nil { + i2.Condition = i.Condition.Clone().(Expr) + i2.Condition.SetParent(i2) + } + if i.Then != nil { + i2.Then = i.Then.Clone().(Stmt) + i2.Then.SetParent(i2) + } + if i.Else != nil { + i2.Else = i.Else.Clone().(Stmt) + i2.Else.SetParent(i2) + } + + return i2 +} + func (i *If) String() string { return "" } @@ -393,6 +467,31 @@ func (f *For) AcceptChildren(visitor Visitor) { } } +func (f *For) Clone() Node { + f2 := &For{ + cst: f.cst, + } + + if f.Initializer != nil { + f2.Initializer = f.Initializer.Clone().(Stmt) + f2.Initializer.SetParent(f2) + } + if f.Condition != nil { + f2.Condition = f.Condition.Clone().(Expr) + f2.Condition.SetParent(f2) + } + if f.Increment != nil { + f2.Increment = f.Increment.Clone().(Expr) + f2.Increment.SetParent(f2) + } + if f.Body != nil { + f2.Body = f.Body.Clone().(Stmt) + f2.Body.SetParent(f2) + } + + return f2 +} + func (f *For) String() string { return "" } @@ -457,6 +556,19 @@ func (r *Return) AcceptChildren(visitor Visitor) { } } +func (r *Return) Clone() Node { + r2 := &Return{ + cst: r.cst, + } + + if r.Value != nil { + r2.Value = r.Value.Clone().(Expr) + r2.Value.SetParent(r2) + } + + return r2 +} + func (r *Return) String() string { return "" } @@ -507,6 +619,14 @@ func (b *Break) SetParent(parent Node) { func (b *Break) AcceptChildren(visitor Visitor) { } +func (b *Break) Clone() Node { + b2 := &Break{ + cst: b.cst, + } + + return b2 +} + func (b *Break) String() string { return "" } @@ -557,6 +677,14 @@ func (c *Continue) SetParent(parent Node) { func (c *Continue) AcceptChildren(visitor Visitor) { } +func (c *Continue) Clone() Node { + c2 := &Continue{ + cst: c.cst, + } + + return c2 +} + func (c *Continue) String() string { return "" } diff --git a/core/ast/types.go b/core/ast/types.go index c70cc5b..465a0a1 100644 --- a/core/ast/types.go +++ b/core/ast/types.go @@ -82,6 +82,16 @@ func (p *Primitive) SetParent(parent Node) { func (p *Primitive) AcceptChildren(visitor Visitor) { } +func (p *Primitive) Clone() Node { + p2 := &Primitive{ + cst: p.cst, + Kind: p.Kind, + Token_: p.Token_, + } + + return p2 +} + func (p *Primitive) String() string { return p.Token_.String() } @@ -150,6 +160,19 @@ func (p *Pointer) AcceptChildren(visitor Visitor) { } } +func (p *Pointer) Clone() Node { + p2 := &Pointer{ + cst: p.cst, + } + + if p.Pointee != nil { + p2.Pointee = p.Pointee.Clone().(Type) + p2.Pointee.SetParent(p2) + } + + return p2 +} + func (p *Pointer) String() string { return "" } @@ -220,6 +243,20 @@ func (a *Array) AcceptChildren(visitor Visitor) { } } +func (a *Array) Clone() Node { + a2 := &Array{ + cst: a.cst, + Count: a.Count, + } + + if a.Base != nil { + a2.Base = a.Base.Clone().(Type) + a2.Base.SetParent(a2) + } + + return a2 +} + func (a *Array) String() string { return "" } @@ -282,6 +319,21 @@ func (r *Resolvable) SetParent(parent Node) { func (r *Resolvable) AcceptChildren(visitor Visitor) { } +func (r *Resolvable) Clone() Node { + r2 := &Resolvable{ + cst: r.cst, + Name: r.Name, + Type: r.Type, + } + + if r.Type != nil { + r2.Type = r.Type.Clone().(Type) + r2.Type.SetParent(r2) + } + + return r2 +} + func (r *Resolvable) String() string { return r.Name.String() } diff --git a/gen/main.go b/gen/main.go index e871c7d..641d007 100644 --- a/gen/main.go +++ b/gen/main.go @@ -185,6 +185,60 @@ func genNode(w *Writer, node Node, visitor string) { w.write("}") w.write("") + // Clone() + + w.write("%s Clone() Node {", method) + + w.write("%s2 := &%s{", this, node.name) + w.write("cst: %s.cst,", this) + + for _, field := range node.fields { + if !field.type_.node() || field.public { + w.write("%s: %s.%s,", name(field.name), this, name(field.name)) + } + } + + w.write("}") + w.write("") + + setParents := false + + for _, field := range node.fields { + if !field.type_.node() { + continue + } + + fieldName := name(field.name) + + castTo := field.type_.name + if field.type_.concreteNode() { + castTo = "*" + castTo + } + + if field.type_.array { + w.write("%s2.%s = make(%s, len(%s.%s))", this, fieldName, field.type_, this, fieldName) + w.write("for i, child := range %s2.%s {", this, fieldName) + w.write("%s2.%s[i] = child.Clone().(%s)", this, fieldName, castTo) + w.write("%s2.%s[i].SetParent(%s2)", this, fieldName, this) + w.write("}") + } else { + w.write("if %s.%s != nil {", this, fieldName) + w.write("%s2.%s = %s.%s.Clone().(%s)", this, fieldName, this, fieldName, castTo) + w.write("%s2.%s.SetParent(%s2)", this, fieldName, this) + w.write("}") + } + + setParents = true + } + + if setParents { + w.write("") + } + + w.write("return %s2", this) + w.write("}") + w.write("") + // String() w.write("%s String() string {", method)