How to use Clone method of ast Package

Best Syzkaller code snippet using ast.Clone

types_format.go

Source:types_format.go Github

copy

Full Screen

1// Copyright 2020 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.4package source5import (6 "bytes"7 "context"8 "fmt"9 "go/ast"10 "go/doc"11 "go/printer"12 "go/token"13 "go/types"14 "strings"15 "golang.org/x/tools/internal/event"16 "golang.org/x/tools/internal/lsp/debug/tag"17 "golang.org/x/tools/internal/lsp/protocol"18)19// FormatType returns the detail and kind for a types.Type.20func FormatType(typ types.Type, qf types.Qualifier) (detail string, kind protocol.CompletionItemKind) {21 if types.IsInterface(typ) {22 detail = "interface{...}"23 kind = protocol.InterfaceCompletion24 } else if _, ok := typ.(*types.Struct); ok {25 detail = "struct{...}"26 kind = protocol.StructCompletion27 } else if typ != typ.Underlying() {28 detail, kind = FormatType(typ.Underlying(), qf)29 } else {30 detail = types.TypeString(typ, qf)31 kind = protocol.ClassCompletion32 }33 return detail, kind34}35type signature struct {36 name, doc string37 params, results []string38 variadic bool39 needResultParens bool40}41func (s *signature) Format() string {42 var b strings.Builder43 b.WriteByte('(')44 for i, p := range s.params {45 if i > 0 {46 b.WriteString(", ")47 }48 b.WriteString(p)49 }50 b.WriteByte(')')51 // Add space between parameters and results.52 if len(s.results) > 0 {53 b.WriteByte(' ')54 }55 if s.needResultParens {56 b.WriteByte('(')57 }58 for i, r := range s.results {59 if i > 0 {60 b.WriteString(", ")61 }62 b.WriteString(r)63 }64 if s.needResultParens {65 b.WriteByte(')')66 }67 return b.String()68}69func (s *signature) Params() []string {70 return s.params71}72// NewBuiltinSignature returns signature for the builtin object with a given73// name, if a builtin object with the name exists.74func NewBuiltinSignature(ctx context.Context, s Snapshot, name string) (*signature, error) {75 builtin, err := s.BuiltinFile(ctx)76 if err != nil {77 return nil, err78 }79 obj := builtin.File.Scope.Lookup(name)80 if obj == nil {81 return nil, fmt.Errorf("no builtin object for %s", name)82 }83 decl, ok := obj.Decl.(*ast.FuncDecl)84 if !ok {85 return nil, fmt.Errorf("no function declaration for builtin: %s", name)86 }87 if decl.Type == nil {88 return nil, fmt.Errorf("no type for builtin decl %s", decl.Name)89 }90 var variadic bool91 if decl.Type.Params.List != nil {92 numParams := len(decl.Type.Params.List)93 lastParam := decl.Type.Params.List[numParams-1]94 if _, ok := lastParam.Type.(*ast.Ellipsis); ok {95 variadic = true96 }97 }98 params, _ := formatFieldList(ctx, s, decl.Type.Params, variadic)99 results, needResultParens := formatFieldList(ctx, s, decl.Type.Results, false)100 d := decl.Doc.Text()101 switch s.View().Options().HoverKind {102 case SynopsisDocumentation:103 d = doc.Synopsis(d)104 case NoDocumentation:105 d = ""106 }107 return &signature{108 doc: d,109 name: name,110 needResultParens: needResultParens,111 params: params,112 results: results,113 variadic: variadic,114 }, nil115}116var replacer = strings.NewReplacer(117 `ComplexType`, `complex128`,118 `FloatType`, `float64`,119 `IntegerType`, `int`,120)121func formatFieldList(ctx context.Context, snapshot Snapshot, list *ast.FieldList, variadic bool) ([]string, bool) {122 if list == nil {123 return nil, false124 }125 var writeResultParens bool126 var result []string127 for i := 0; i < len(list.List); i++ {128 if i >= 1 {129 writeResultParens = true130 }131 p := list.List[i]132 cfg := printer.Config{Mode: printer.UseSpaces | printer.TabIndent, Tabwidth: 4}133 b := &bytes.Buffer{}134 if err := cfg.Fprint(b, snapshot.FileSet(), p.Type); err != nil {135 event.Error(ctx, "unable to print type", nil, tag.Type.Of(p.Type))136 continue137 }138 typ := replacer.Replace(b.String())139 if len(p.Names) == 0 {140 result = append(result, typ)141 }142 for _, name := range p.Names {143 if name.Name != "" {144 if i == 0 {145 writeResultParens = true146 }147 result = append(result, fmt.Sprintf("%s %s", name.Name, typ))148 } else {149 result = append(result, typ)150 }151 }152 }153 if variadic {154 result[len(result)-1] = strings.Replace(result[len(result)-1], "[]", "...", 1)155 }156 return result, writeResultParens157}158// NewSignature returns formatted signature for a types.Signature struct.159func NewSignature(ctx context.Context, s Snapshot, pkg Package, sig *types.Signature, comment *ast.CommentGroup, qf types.Qualifier) *signature {160 params := make([]string, 0, sig.Params().Len())161 for i := 0; i < sig.Params().Len(); i++ {162 el := sig.Params().At(i)163 typ := FormatVarType(ctx, s, pkg, el, qf)164 p := typ165 if el.Name() != "" {166 p = el.Name() + " " + typ167 }168 params = append(params, p)169 }170 var needResultParens bool171 results := make([]string, 0, sig.Results().Len())172 for i := 0; i < sig.Results().Len(); i++ {173 if i >= 1 {174 needResultParens = true175 }176 el := sig.Results().At(i)177 typ := FormatVarType(ctx, s, pkg, el, qf)178 if el.Name() == "" {179 results = append(results, typ)180 } else {181 if i == 0 {182 needResultParens = true183 }184 results = append(results, el.Name()+" "+typ)185 }186 }187 var d string188 if comment != nil {189 d = comment.Text()190 }191 switch s.View().Options().HoverKind {192 case SynopsisDocumentation:193 d = doc.Synopsis(d)194 case NoDocumentation:195 d = ""196 }197 return &signature{198 doc: d,199 params: params,200 results: results,201 variadic: sig.Variadic(),202 needResultParens: needResultParens,203 }204}205// FormatVarType formats a *types.Var, accounting for type aliases.206// To do this, it looks in the AST of the file in which the object is declared.207// On any errors, it always fallbacks back to types.TypeString.208func FormatVarType(ctx context.Context, snapshot Snapshot, srcpkg Package, obj *types.Var, qf types.Qualifier) string {209 pkg, err := FindPackageFromPos(ctx, snapshot, obj.Pos())210 if err != nil {211 return types.TypeString(obj.Type(), qf)212 }213 expr, err := varType(ctx, snapshot, pkg, obj)214 if err != nil {215 return types.TypeString(obj.Type(), qf)216 }217 // The type names in the AST may not be correctly qualified.218 // Determine the package name to use based on the package that originated219 // the query and the package in which the type is declared.220 // We then qualify the value by cloning the AST node and editing it.221 clonedInfo := make(map[token.Pos]*types.PkgName)222 qualified := cloneExpr(expr, pkg.GetTypesInfo(), clonedInfo)223 // If the request came from a different package than the one in which the224 // types are defined, we may need to modify the qualifiers.225 qualified = qualifyExpr(qualified, srcpkg, pkg, clonedInfo, qf)226 fmted := FormatNode(snapshot.FileSet(), qualified)227 return fmted228}229// varType returns the type expression for a *types.Var.230func varType(ctx context.Context, snapshot Snapshot, pkg Package, obj *types.Var) (ast.Expr, error) {231 field, err := snapshot.PosToField(ctx, pkg, obj.Pos())232 if err != nil {233 return nil, err234 }235 if field == nil {236 return nil, fmt.Errorf("no declaration for object %s", obj.Name())237 }238 typ, ok := field.Type.(ast.Expr)239 if !ok {240 return nil, fmt.Errorf("unexpected type for node (%T)", field.Type)241 }242 return typ, nil243}244// qualifyExpr applies the "pkgName." prefix to any *ast.Ident in the expr.245func qualifyExpr(expr ast.Expr, srcpkg, pkg Package, clonedInfo map[token.Pos]*types.PkgName, qf types.Qualifier) ast.Expr {246 ast.Inspect(expr, func(n ast.Node) bool {247 switch n := n.(type) {248 case *ast.ArrayType, *ast.ChanType, *ast.Ellipsis,249 *ast.FuncType, *ast.MapType, *ast.ParenExpr,250 *ast.StarExpr, *ast.StructType:251 // These are the only types that are cloned by cloneExpr below,252 // so these are the only types that we can traverse and potentially253 // modify. This is not an ideal approach, but it works for now.254 return true255 case *ast.SelectorExpr:256 // We may need to change any selectors in which the X is a package257 // name and the Sel is exported.258 x, ok := n.X.(*ast.Ident)259 if !ok {260 return false261 }262 obj, ok := clonedInfo[x.Pos()]263 if !ok {264 return false265 }266 x.Name = qf(obj.Imported())267 return false268 case *ast.Ident:269 if srcpkg == pkg {270 return false271 }272 // Only add the qualifier if the identifier is exported.273 if ast.IsExported(n.Name) {274 pkgName := qf(pkg.GetTypes())275 n.Name = pkgName + "." + n.Name276 }277 }278 return false279 })280 return expr281}282// cloneExpr only clones expressions that appear in the parameters or return283// values of a function declaration. The original expression may be returned284// to the caller in 2 cases:285// (1) The expression has no pointer fields.286// (2) The expression cannot appear in an *ast.FuncType, making it287// unnecessary to clone.288// This function also keeps track of selector expressions in which the X is a289// package name and marks them in a map along with their type information, so290// that this information can be used when rewriting the expression.291//292// NOTE: This function is tailored to the use case of qualifyExpr, and should293// be used with caution.294func cloneExpr(expr ast.Expr, info *types.Info, clonedInfo map[token.Pos]*types.PkgName) ast.Expr {295 switch expr := expr.(type) {296 case *ast.ArrayType:297 return &ast.ArrayType{298 Lbrack: expr.Lbrack,299 Elt: cloneExpr(expr.Elt, info, clonedInfo),300 Len: expr.Len,301 }302 case *ast.ChanType:303 return &ast.ChanType{304 Arrow: expr.Arrow,305 Begin: expr.Begin,306 Dir: expr.Dir,307 Value: cloneExpr(expr.Value, info, clonedInfo),308 }309 case *ast.Ellipsis:310 return &ast.Ellipsis{311 Ellipsis: expr.Ellipsis,312 Elt: cloneExpr(expr.Elt, info, clonedInfo),313 }314 case *ast.FuncType:315 return &ast.FuncType{316 Func: expr.Func,317 Params: cloneFieldList(expr.Params, info, clonedInfo),318 Results: cloneFieldList(expr.Results, info, clonedInfo),319 }320 case *ast.Ident:321 return cloneIdent(expr)322 case *ast.MapType:323 return &ast.MapType{324 Map: expr.Map,325 Key: cloneExpr(expr.Key, info, clonedInfo),326 Value: cloneExpr(expr.Value, info, clonedInfo),327 }328 case *ast.ParenExpr:329 return &ast.ParenExpr{330 Lparen: expr.Lparen,331 Rparen: expr.Rparen,332 X: cloneExpr(expr.X, info, clonedInfo),333 }334 case *ast.SelectorExpr:335 s := &ast.SelectorExpr{336 Sel: cloneIdent(expr.Sel),337 X: cloneExpr(expr.X, info, clonedInfo),338 }339 if x, ok := expr.X.(*ast.Ident); ok && ast.IsExported(expr.Sel.Name) {340 if obj, ok := info.ObjectOf(x).(*types.PkgName); ok {341 clonedInfo[s.X.Pos()] = obj342 }343 }344 return s345 case *ast.StarExpr:346 return &ast.StarExpr{347 Star: expr.Star,348 X: cloneExpr(expr.X, info, clonedInfo),349 }350 case *ast.StructType:351 return &ast.StructType{352 Struct: expr.Struct,353 Fields: cloneFieldList(expr.Fields, info, clonedInfo),354 Incomplete: expr.Incomplete,355 }356 default:357 return expr358 }359}360func cloneFieldList(fl *ast.FieldList, info *types.Info, clonedInfo map[token.Pos]*types.PkgName) *ast.FieldList {361 if fl == nil {362 return nil363 }364 if fl.List == nil {365 return &ast.FieldList{366 Closing: fl.Closing,367 Opening: fl.Opening,368 }369 }370 list := make([]*ast.Field, 0, len(fl.List))371 for _, f := range fl.List {372 var names []*ast.Ident373 for _, n := range f.Names {374 names = append(names, cloneIdent(n))375 }376 list = append(list, &ast.Field{377 Comment: f.Comment,378 Doc: f.Doc,379 Names: names,380 Tag: f.Tag,381 Type: cloneExpr(f.Type, info, clonedInfo),382 })383 }384 return &ast.FieldList{385 Closing: fl.Closing,386 Opening: fl.Opening,387 List: list,388 }389}390func cloneIdent(ident *ast.Ident) *ast.Ident {391 return &ast.Ident{392 NamePos: ident.NamePos,393 Name: ident.Name,394 Obj: ident.Obj,395 }396}...

Full Screen

Full Screen

clone.go

Source:clone.go Github

copy

Full Screen

...30}31// Updates fields of field to point to deep clones.32func cloneField(field *ObjectField) {33 if field.Method != nil {34 field.Method = Clone(field.Method).(*Function)35 }36 clone(&field.Expr1)37 clone(&field.Expr2)38 clone(&field.Expr3)39}40// Updates fields of field to point to deep clones.41func cloneDesugaredField(field *DesugaredObjectField) {42 clone(&field.Name)43 clone(&field.Body)44}45// Updates the NodeBase fields of astPtr to point to deep clones.46func cloneNodeBase(astPtr Node) {47 if astPtr.Context() != nil {48 newContext := new(string)49 *newContext = *astPtr.Context()50 astPtr.SetContext(newContext)51 }52 astPtr.SetFreeVariables(append(make(Identifiers, 0), astPtr.FreeVariables()...))53}54func cloneCommaSeparatedExprs(list []CommaSeparatedExpr) []CommaSeparatedExpr {55 r := append(make([]CommaSeparatedExpr, 0), list...)56 for i := range list {57 clone(&r[i].Expr)58 }59 return r60}61// Updates *astPtr to point to a deep clone of what it originally pointed at.62func clone(astPtr *Node) {63 node := *astPtr64 if node == nil {65 return66 }67 switch node := node.(type) {68 case *Apply:69 r := new(Apply)70 *astPtr = r71 *r = *node72 clone(&r.Target)73 r.Arguments.Positional = cloneCommaSeparatedExprs(r.Arguments.Positional)74 r.Arguments.Named = append(make([]NamedArgument, 0), r.Arguments.Named...)75 for i := range r.Arguments.Named {76 clone(&r.Arguments.Named[i].Arg)77 }78 case *ApplyBrace:79 r := new(ApplyBrace)80 *astPtr = r81 *r = *node82 clone(&r.Left)83 clone(&r.Right)84 case *Array:85 r := new(Array)86 *astPtr = r87 *r = *node88 r.Elements = cloneCommaSeparatedExprs(r.Elements)89 case *ArrayComp:90 r := new(ArrayComp)91 *astPtr = r92 *r = *node93 clone(&r.Body)94 cloneForSpec(&r.Spec)95 case *Assert:96 r := new(Assert)97 *astPtr = r98 *r = *node99 clone(&r.Cond)100 clone(&r.Message)101 clone(&r.Rest)102 case *Binary:103 r := new(Binary)104 *astPtr = r105 *r = *node106 clone(&r.Left)107 clone(&r.Right)108 case *Conditional:109 r := new(Conditional)110 *astPtr = r111 *r = *node112 clone(&r.Cond)113 clone(&r.BranchTrue)114 clone(&r.BranchFalse)115 case *Dollar:116 r := new(Dollar)117 *astPtr = r118 *r = *node119 case *Error:120 r := new(Error)121 *astPtr = r122 *r = *node123 clone(&r.Expr)124 case *Function:125 r := new(Function)126 *astPtr = r127 *r = *node128 if r.Parameters != nil {129 r.Parameters = append(make([]Parameter, 0), r.Parameters...)130 for i := range r.Parameters {131 clone(&r.Parameters[i].DefaultArg)132 }133 }134 clone(&r.Body)135 case *Import:136 r := new(Import)137 *astPtr = r138 *r = *node139 r.File = new(LiteralString)140 *r.File = *node.File141 case *ImportStr:142 r := new(ImportStr)143 *astPtr = r144 *r = *node145 r.File = new(LiteralString)146 *r.File = *node.File147 case *Index:148 r := new(Index)149 *astPtr = r150 *r = *node151 clone(&r.Target)152 clone(&r.Index)153 case *Slice:154 r := new(Slice)155 *astPtr = r156 *r = *node157 clone(&r.Target)158 clone(&r.BeginIndex)159 clone(&r.EndIndex)160 clone(&r.Step)161 case *Local:162 r := new(Local)163 *astPtr = r164 *r = *node165 r.Binds = append(make(LocalBinds, 0), r.Binds...)166 for i := range r.Binds {167 if r.Binds[i].Fun != nil {168 r.Binds[i].Fun = Clone(r.Binds[i].Fun).(*Function)169 }170 clone(&r.Binds[i].Body)171 }172 clone(&r.Body)173 case *LiteralBoolean:174 r := new(LiteralBoolean)175 *astPtr = r176 *r = *node177 case *LiteralNull:178 r := new(LiteralNull)179 *astPtr = r180 *r = *node181 case *LiteralNumber:182 r := new(LiteralNumber)183 *astPtr = r184 *r = *node185 case *LiteralString:186 r := new(LiteralString)187 *astPtr = r188 *r = *node189 case *Object:190 r := new(Object)191 *astPtr = r192 *r = *node193 r.Fields = append(make(ObjectFields, 0), r.Fields...)194 for i := range r.Fields {195 cloneField(&r.Fields[i])196 }197 case *DesugaredObject:198 r := new(DesugaredObject)199 *astPtr = r200 *r = *node201 r.Fields = append(make(DesugaredObjectFields, 0), r.Fields...)202 for i := range r.Fields {203 cloneDesugaredField(&r.Fields[i])204 }205 case *ObjectComp:206 r := new(ObjectComp)207 *astPtr = r208 *r = *node209 r.Fields = append(make(ObjectFields, 0), r.Fields...)210 for i := range r.Fields {211 cloneField(&r.Fields[i])212 }213 cloneForSpec(&r.Spec)214 case *Parens:215 r := new(Parens)216 *astPtr = r217 *r = *node218 clone(&r.Inner)219 case *Self:220 r := new(Self)221 *astPtr = r222 *r = *node223 case *SuperIndex:224 r := new(SuperIndex)225 *astPtr = r226 *r = *node227 clone(&r.Index)228 case *InSuper:229 r := new(InSuper)230 *astPtr = r231 *r = *node232 clone(&r.Index)233 case *Unary:234 r := new(Unary)235 *astPtr = r236 *r = *node237 clone(&r.Expr)238 case *Var:239 r := new(Var)240 *astPtr = r241 *r = *node242 default:243 panic(fmt.Sprintf("ast.Clone() does not recognize ast: %s", reflect.TypeOf(node)))244 }245 cloneNodeBase(*astPtr)246}247// Clone creates an independent copy of an AST248func Clone(astPtr Node) Node {249 clone(&astPtr)250 return astPtr251}...

Full Screen

Full Screen

Clone

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 f, err := parser.ParseFile(fset, "sample.go", nil, parser.ParseComments)4 if err != nil {5 fmt.Println(err)6 }7 fmt.Println("8 ast.Print(fset, f)9 f2 := f.Clone().(*ast.File)10 f2.Name = ast.NewIdent("sample2")11 fmt.Println("12 ast.Print(fset, f2)13}14import (15func main() {16 f, err := parser.ParseFile(fset, "sample.go", nil, parser.ParseComments)17 if err != nil {18 fmt.Println(err)19 }20 fmt.Println("21 ast.Print(fset, f)22 f2 := f.Clone().(*ast.File)23 f2.Name = ast.NewIdent("sample2")24 fmt.Println("25 ast.Print(fset, f2)26}27import (28func main() {29 f, err := parser.ParseFile(fset, "sample.go", nil, parser.ParseComments)30 if err != nil {31 fmt.Println(err)32 }33 fmt.Println("34 ast.Print(fset, f)35 f2 := f.Clone().(*ast.File)36 f2.Name = ast.NewIdent("sample2")37 fmt.Println("38 ast.Print(fset, f2)39}

Full Screen

Full Screen

Clone

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 fset := token.NewFileSet()4 node, err := parser.ParseFile(fset, "1.go", nil, parser.ParseComments)5 if err != nil {6 fmt.Println(err)7 }8 clone := node.Decls[0].(*ast.FuncDecl).Body.List[0].(*ast.AssignStmt).Rhs[0].(*ast.CompositeLit).Elts[0].(*ast.KeyValueExpr).Value.(*ast.Ident).Clone()9 fmt.Println(clone)10}

Full Screen

Full Screen

Clone

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 fset := token.NewFileSet()4 f, err := parser.ParseFile(fset, "1.go", nil, parser.ParseComments)5 if err != nil {6 panic(err)7 }8 ast.Print(fset, f)9 c := f.Clone()10 ast.Print(fset, c)11 ast.Print(fset, c)12 ast.Print(fset, f)13}

Full Screen

Full Screen

Clone

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 fset := token.NewFileSet()4 f, err := parser.ParseFile(fset, "1.go", nil, 0)5 if err != nil {6 panic(err)7 }

Full Screen

Full Screen

Clone

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 fset := token.NewFileSet()4 node, err := parser.ParseFile(fset, "1.go", nil, 0)5 if err != nil {6 fmt.Println(err)7 }8 ast.Print(fset, node)9 cloneNode := node.Clone()10 ast.Print(fset, cloneNode)11}12import "fmt"13func main() {14 fmt.Println("Hello World")15}16import "fmt"17func main() {18 fmt.Println("Hello World")19}

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful