本文整理汇总了Golang中go/ast.GenDecl.Specs方法的典型用法代码示例。如果您正苦于以下问题:Golang GenDecl.Specs方法的具体用法?Golang GenDecl.Specs怎么用?Golang GenDecl.Specs使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类go/ast.GenDecl
的用法示例。
在下文中一共展示了GenDecl.Specs方法的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: constDecl
func constDecl(kind token.Token, args ...string) *ast.GenDecl {
decl := ast.GenDecl{Tok: token.CONST}
if len(args)%3 != 0 {
panic("Number of values passed to ConstString must be a multiple of 3")
}
for i := 0; i < len(args); i += 3 {
name, typ, val := args[i], args[i+1], args[i+2]
lit := &ast.BasicLit{Kind: kind}
if kind == token.STRING {
lit.Value = strconv.Quote(val)
} else {
lit.Value = val
}
a := &ast.ValueSpec{
Names: []*ast.Ident{ast.NewIdent(name)},
Values: []ast.Expr{lit},
}
if typ != "" {
a.Type = ast.NewIdent(typ)
}
decl.Specs = append(decl.Specs, a)
}
if len(decl.Specs) > 1 {
decl.Lparen = 1
}
return &decl
}
示例2: addImport
// addImport adds the import path to the file f, if absent.
func addImport(f *ast.File, path string) {
if imports(f, path) {
return
}
newImport := &ast.ImportSpec{
Path: &ast.BasicLit{
Kind: token.STRING,
Value: strconv.Quote(path),
},
}
var impdecl *ast.GenDecl
// Find an import decl to add to.
for _, decl := range f.Decls {
gen, ok := decl.(*ast.GenDecl)
if ok && gen.Tok == token.IMPORT {
impdecl = gen
break
}
}
// No import decl found. Add one.
if impdecl == nil {
impdecl = &ast.GenDecl{
Tok: token.IMPORT,
}
f.Decls = append(f.Decls, nil)
copy(f.Decls[1:], f.Decls)
f.Decls[0] = impdecl
}
// Ensure the import decl has parentheses, if needed.
if len(impdecl.Specs) > 0 && !impdecl.Lparen.IsValid() {
impdecl.Lparen = impdecl.Pos()
}
// Assume the import paths are alphabetically ordered.
// If they are not, the result is ugly, but legal.
insertAt := len(impdecl.Specs) // default to end of specs
for i, spec := range impdecl.Specs {
impspec := spec.(*ast.ImportSpec)
if importPath(impspec) > path {
insertAt = i
break
}
}
impdecl.Specs = append(impdecl.Specs, nil)
copy(impdecl.Specs[insertAt+1:], impdecl.Specs[insertAt:])
impdecl.Specs[insertAt] = newImport
f.Imports = append(f.Imports, newImport)
}
示例3: ast_decl_split
func ast_decl_split(d ast.Decl) []ast.Decl {
var decls []ast.Decl
if t, ok := d.(*ast.GenDecl); ok {
decls = make([]ast.Decl, len(t.Specs))
for i, s := range t.Specs {
decl := new(ast.GenDecl)
*decl = *t
decl.Specs = make([]ast.Spec, 1)
decl.Specs[0] = s
decls[i] = decl
}
} else {
decls = make([]ast.Decl, 1)
decls[0] = d
}
return decls
}
示例4: AddNamedImport
// AddNamedImport adds the import path to the file f, if absent.
// If name is not empty, it is used to rename the import.
//
// For example, calling
// AddNamedImport(fset, f, "pathpkg", "path")
// adds
// import pathpkg "path"
func AddNamedImport(fset *token.FileSet, f *ast.File, name, ipath string) (added bool) {
if imports(f, ipath) {
return false
}
newImport := &ast.ImportSpec{
Path: &ast.BasicLit{
Kind: token.STRING,
Value: strconv.Quote(ipath),
},
}
if name != "" {
newImport.Name = &ast.Ident{Name: name}
}
// Find an import decl to add to.
// The goal is to find an existing import
// whose import path has the longest shared
// prefix with ipath.
var (
bestMatch = -1 // length of longest shared prefix
lastImport = -1 // index in f.Decls of the file's final import decl
impDecl *ast.GenDecl // import decl containing the best match
impIndex = -1 // spec index in impDecl containing the best match
)
for i, decl := range f.Decls {
gen, ok := decl.(*ast.GenDecl)
if ok && gen.Tok == token.IMPORT {
lastImport = i
// Do not add to import "C", to avoid disrupting the
// association with its doc comment, breaking cgo.
if declImports(gen, "C") {
continue
}
// Match an empty import decl if that's all that is available.
if len(gen.Specs) == 0 && bestMatch == -1 {
impDecl = gen
}
// Compute longest shared prefix with imports in this group.
for j, spec := range gen.Specs {
impspec := spec.(*ast.ImportSpec)
n := matchLen(importPath(impspec), ipath)
if n > bestMatch {
bestMatch = n
impDecl = gen
impIndex = j
}
}
}
}
// If no import decl found, add one after the last import.
if impDecl == nil {
impDecl = &ast.GenDecl{
Tok: token.IMPORT,
}
if lastImport >= 0 {
impDecl.TokPos = f.Decls[lastImport].End()
} else {
// There are no existing imports.
// Our new import goes after the package declaration and after
// the comment, if any, that starts on the same line as the
// package declaration.
impDecl.TokPos = f.Package
file := fset.File(f.Package)
pkgLine := file.Line(f.Package)
for _, c := range f.Comments {
if file.Line(c.Pos()) > pkgLine {
break
}
impDecl.TokPos = c.End()
}
}
f.Decls = append(f.Decls, nil)
copy(f.Decls[lastImport+2:], f.Decls[lastImport+1:])
f.Decls[lastImport+1] = impDecl
}
// Insert new import at insertAt.
insertAt := 0
if impIndex >= 0 {
// insert after the found import
insertAt = impIndex + 1
}
impDecl.Specs = append(impDecl.Specs, nil)
copy(impDecl.Specs[insertAt+1:], impDecl.Specs[insertAt:])
impDecl.Specs[insertAt] = newImport
pos := impDecl.Pos()
if insertAt > 0 {
// If there is a comment after an existing import, preserve the comment
//.........这里部分代码省略.........
示例5: imp
func imp(fset *token.FileSet, af *ast.File, toggle []ImportDeclArg) *ast.File {
add := map[ImportDecl]bool{}
del := map[ImportDecl]bool{}
for _, sda := range toggle {
sd := ImportDecl{
Path: sda.Path,
Name: sda.Name,
}
if sda.Add {
add[sd] = true
} else {
del[sd] = true
}
}
var firstDecl *ast.GenDecl
imports := map[ImportDecl]bool{}
for _, decl := range af.Decls {
if gdecl, ok := decl.(*ast.GenDecl); ok && len(gdecl.Specs) > 0 {
hasC := false
sj := 0
for _, spec := range gdecl.Specs {
if ispec, ok := spec.(*ast.ImportSpec); ok {
sd := ImportDecl{
Path: unquote(ispec.Path.Value),
}
if ispec.Name != nil {
sd.Name = ispec.Name.String()
}
if sd.Path == "C" {
hasC = true
} else if del[sd] {
if sj > 0 {
if lspec, ok := gdecl.Specs[sj-1].(*ast.ImportSpec); ok {
lspec.EndPos = ispec.Pos()
}
}
continue
} else {
imports[sd] = true
}
}
gdecl.Specs[sj] = spec
sj += 1
}
gdecl.Specs = gdecl.Specs[:sj]
if !hasC && firstDecl == nil {
firstDecl = gdecl
}
}
}
if len(add) > 0 {
if firstDecl == nil {
firstDecl = &ast.GenDecl{
Tok: token.IMPORT,
Lparen: 1,
}
af.Decls = append(af.Decls, firstDecl)
} else if firstDecl.Lparen == token.NoPos {
firstDecl.Lparen = 1
}
for sd, _ := range add {
if !imports[sd] {
ispec := &ast.ImportSpec{
Path: &ast.BasicLit{
Value: quote(sd.Path),
Kind: token.STRING,
},
}
if sd.Name != "" {
ispec.Name = &ast.Ident{
Name: sd.Name,
}
}
firstDecl.Specs = append(firstDecl.Specs, ispec)
imports[sd] = true
}
}
}
dj := 0
for _, decl := range af.Decls {
if gdecl, ok := decl.(*ast.GenDecl); ok {
if len(gdecl.Specs) == 0 {
continue
}
}
af.Decls[dj] = decl
dj += 1
}
af.Decls = af.Decls[:dj]
ast.SortImports(fset, af)
return af
}
示例6: AddNamedImport
// AddNamedImport adds the import path to the file f, if absent.
// If name is not empty, it is used to rename the import.
//
// For example, calling
// AddNamedImport(fset, f, "pathpkg", "path")
// adds
// import pathpkg "path"
func AddNamedImport(fset *token.FileSet, f *ast.File, name, ipath string) (added bool) {
if imports(f, ipath) {
return false
}
newImport := &ast.ImportSpec{
Path: &ast.BasicLit{
Kind: token.STRING,
Value: strconv.Quote(ipath),
},
}
if name != "" {
newImport.Name = &ast.Ident{Name: name}
}
// Find an import decl to add to.
var (
bestMatch = -1
lastImport = -1
impDecl *ast.GenDecl
impIndex = -1
hasImports = false
)
for i, decl := range f.Decls {
gen, ok := decl.(*ast.GenDecl)
if ok && gen.Tok == token.IMPORT {
hasImports = true
lastImport = i
// Do not add to import "C", to avoid disrupting the
// association with its doc comment, breaking cgo.
if declImports(gen, "C") {
continue
}
// Compute longest shared prefix with imports in this block.
for j, spec := range gen.Specs {
impspec := spec.(*ast.ImportSpec)
n := matchLen(importPath(impspec), ipath)
if n > bestMatch {
bestMatch = n
impDecl = gen
impIndex = j
}
}
}
}
// If no import decl found, add one after the last import.
if impDecl == nil {
// TODO(bradfitz): remove this hack. See comment below on
// addImportViaSourceModification.
if !hasImports {
f2, err := addImportViaSourceModification(fset, f, name, ipath)
if err == nil {
*f = *f2
return true
}
log.Printf("addImportViaSourceModification error: %v", err)
}
// TODO(bradfitz): fix above and resume using this old code:
impDecl = &ast.GenDecl{
Tok: token.IMPORT,
}
f.Decls = append(f.Decls, nil)
copy(f.Decls[lastImport+2:], f.Decls[lastImport+1:])
f.Decls[lastImport+1] = impDecl
}
// Ensure the import decl has parentheses, if needed.
if len(impDecl.Specs) > 0 && !impDecl.Lparen.IsValid() {
impDecl.Lparen = impDecl.Pos()
}
insertAt := impIndex + 1
if insertAt == 0 {
insertAt = len(impDecl.Specs)
}
impDecl.Specs = append(impDecl.Specs, nil)
copy(impDecl.Specs[insertAt+1:], impDecl.Specs[insertAt:])
impDecl.Specs[insertAt] = newImport
if insertAt > 0 {
// Assign same position as the previous import,
// so that the sorter sees it as being in the same block.
prev := impDecl.Specs[insertAt-1]
newImport.Path.ValuePos = prev.Pos()
newImport.EndPos = prev.Pos()
}
if len(impDecl.Specs) > 1 && impDecl.Lparen == 0 {
// set Lparen to something not zero, so the printer prints
// the full block rather just the first ImportSpec.
impDecl.Lparen = 1
}
//.........这里部分代码省略.........
示例7: addImport
// addImport adds the import path to the file f, if absent.
func addImport(f *ast.File, ipath string) (added bool) {
if imports(f, ipath) {
return false
}
// Determine name of import.
// Assume added imports follow convention of using last element.
_, name := path.Split(ipath)
// Rename any conflicting top-level references from name to name_.
renameTop(f, name, name+"_")
newImport := &ast.ImportSpec{
Path: &ast.BasicLit{
Kind: token.STRING,
Value: strconv.Quote(ipath),
},
}
// Find an import decl to add to.
var (
bestMatch = -1
lastImport = -1
impDecl *ast.GenDecl
impIndex = -1
)
for i, decl := range f.Decls {
gen, ok := decl.(*ast.GenDecl)
if ok && gen.Tok == token.IMPORT {
lastImport = i
// Do not add to import "C", to avoid disrupting the
// association with its doc comment, breaking cgo.
if declImports(gen, "C") {
continue
}
// Compute longest shared prefix with imports in this block.
for j, spec := range gen.Specs {
impspec := spec.(*ast.ImportSpec)
n := matchLen(importPath(impspec), ipath)
if n > bestMatch {
bestMatch = n
impDecl = gen
impIndex = j
}
}
}
}
// If no import decl found, add one after the last import.
if impDecl == nil {
impDecl = &ast.GenDecl{
Tok: token.IMPORT,
}
f.Decls = append(f.Decls, nil)
copy(f.Decls[lastImport+2:], f.Decls[lastImport+1:])
f.Decls[lastImport+1] = impDecl
}
// Ensure the import decl has parentheses, if needed.
if len(impDecl.Specs) > 0 && !impDecl.Lparen.IsValid() {
impDecl.Lparen = impDecl.Pos()
}
insertAt := impIndex + 1
if insertAt == 0 {
insertAt = len(impDecl.Specs)
}
impDecl.Specs = append(impDecl.Specs, nil)
copy(impDecl.Specs[insertAt+1:], impDecl.Specs[insertAt:])
impDecl.Specs[insertAt] = newImport
if insertAt > 0 {
// Assign same position as the previous import,
// so that the sorter sees it as being in the same block.
prev := impDecl.Specs[insertAt-1]
newImport.Path.ValuePos = prev.Pos()
newImport.EndPos = prev.Pos()
}
f.Imports = append(f.Imports, newImport)
return true
}
示例8: clone
// TODO(bradfitz): delete this function (and whole file) once
// http://golang.org/issue/4380 is fixed.
func clone(i interface{}) (cloned interface{}) {
if debugClone {
defer func() {
if !reflect.DeepEqual(i, cloned) {
log.Printf("cloned %T doesn't match: in=%#v out=%#v", i, i, cloned)
}
}()
}
switch v := i.(type) {
case nil:
return nil
case *ast.File:
o := &ast.File{
Doc: v.Doc, // shallow
Package: v.Package,
Comments: v.Comments, // shallow
Name: v.Name,
Scope: v.Scope,
}
for _, x := range v.Decls {
o.Decls = append(o.Decls, clone(x).(ast.Decl))
}
for _, x := range v.Imports {
o.Imports = append(o.Imports, clone(x).(*ast.ImportSpec))
}
for _, x := range v.Unresolved {
o.Unresolved = append(o.Unresolved, x)
}
return o
case *ast.GenDecl:
o := new(ast.GenDecl)
*o = *v
o.Specs = nil
for _, x := range v.Specs {
o.Specs = append(o.Specs, clone(x).(ast.Spec))
}
return o
case *ast.TypeSpec:
o := new(ast.TypeSpec)
*o = *v
o.Type = cloneExpr(v.Type)
return o
case *ast.InterfaceType:
o := new(ast.InterfaceType)
*o = *v
o.Methods = clone(v.Methods).(*ast.FieldList)
return o
case *ast.FieldList:
if v == nil {
return v
}
o := new(ast.FieldList)
*o = *v
o.List = nil
for _, x := range v.List {
o.List = append(o.List, clone(x).(*ast.Field))
}
return o
case *ast.Field:
o := &ast.Field{
Doc: v.Doc, // shallow
Type: cloneExpr(v.Type),
Tag: clone(v.Tag).(*ast.BasicLit),
Comment: v.Comment, // shallow
}
for _, x := range v.Names {
o.Names = append(o.Names, clone(x).(*ast.Ident))
}
return o
case *ast.FuncType:
if v == nil {
return v
}
return &ast.FuncType{
Func: v.Func,
Params: clone(v.Params).(*ast.FieldList),
Results: clone(v.Results).(*ast.FieldList),
}
case *ast.FuncDecl:
if v == nil {
return v
}
return &ast.FuncDecl{
Recv: clone(v.Recv).(*ast.FieldList),
Name: v.Name,
Type: clone(v.Type).(*ast.FuncType),
Body: v.Body, // shallow
}
case *ast.ValueSpec:
if v == nil {
return v
}
o := &ast.ValueSpec{
Type: cloneExpr(v.Type),
}
for _, x := range v.Names {
o.Names = append(o.Names, x)
}
//.........这里部分代码省略.........