...

Source file src/go/ast/commentmap_test.go

Documentation: go/ast

		 1  // Copyright 2012 The Go Authors. All rights reserved.
		 2  // Use of this source code is governed by a BSD-style
		 3  // license that can be found in the LICENSE file.
		 4  
		 5  // To avoid a cyclic dependency with go/parser, this file is in a separate package.
		 6  
		 7  package ast_test
		 8  
		 9  import (
		10  	"bytes"
		11  	"fmt"
		12  	. "go/ast"
		13  	"go/parser"
		14  	"go/token"
		15  	"sort"
		16  	"testing"
		17  )
		18  
		19  const src = `
		20  // the very first comment
		21  
		22  // package p
		23  package p /* the name is p */
		24  
		25  // imports
		26  import (
		27  	"bytes"		 // bytes
		28  	"fmt"			 // fmt
		29  	"go/ast"
		30  	"go/parser"
		31  )
		32  
		33  // T
		34  type T struct {
		35  	a, b, c int // associated with a, b, c
		36  	// associated with x, y
		37  	x, y float64		// float values
		38  	z		complex128 // complex value
		39  }
		40  // also associated with T
		41  
		42  // x
		43  var x = 0 // x = 0
		44  // also associated with x
		45  
		46  // f1
		47  func f1() {
		48  	/* associated with s1 */
		49  	s1()
		50  	// also associated with s1
		51  	
		52  	// associated with s2
		53  	
		54  	// also associated with s2
		55  	s2() // line comment for s2
		56  }
		57  // associated with f1
		58  // also associated with f1
		59  
		60  // associated with f2
		61  
		62  // f2
		63  func f2() {
		64  }
		65  
		66  func f3() {
		67  	i := 1 /* 1 */ + 2 // addition
		68  	_ = i
		69  }
		70  
		71  // the very last comment
		72  `
		73  
		74  // res maps a key of the form "line number: node type"
		75  // to the associated comments' text.
		76  //
		77  var res = map[string]string{
		78  	" 5: *ast.File":			 "the very first comment\npackage p\n",
		79  	" 5: *ast.Ident":			" the name is p\n",
		80  	" 8: *ast.GenDecl":		"imports\n",
		81  	" 9: *ast.ImportSpec": "bytes\n",
		82  	"10: *ast.ImportSpec": "fmt\n",
		83  	"16: *ast.GenDecl":		"T\nalso associated with T\n",
		84  	"17: *ast.Field":			"associated with a, b, c\n",
		85  	"19: *ast.Field":			"associated with x, y\nfloat values\n",
		86  	"20: *ast.Field":			"complex value\n",
		87  	"25: *ast.GenDecl":		"x\nx = 0\nalso associated with x\n",
		88  	"29: *ast.FuncDecl":	 "f1\nassociated with f1\nalso associated with f1\n",
		89  	"31: *ast.ExprStmt":	 " associated with s1\nalso associated with s1\n",
		90  	"37: *ast.ExprStmt":	 "associated with s2\nalso associated with s2\nline comment for s2\n",
		91  	"45: *ast.FuncDecl":	 "associated with f2\nf2\n",
		92  	"49: *ast.AssignStmt": "addition\n",
		93  	"49: *ast.BasicLit":	 " 1\n",
		94  	"50: *ast.Ident":			"the very last comment\n",
		95  }
		96  
		97  func ctext(list []*CommentGroup) string {
		98  	var buf bytes.Buffer
		99  	for _, g := range list {
	 100  		buf.WriteString(g.Text())
	 101  	}
	 102  	return buf.String()
	 103  }
	 104  
	 105  func TestCommentMap(t *testing.T) {
	 106  	fset := token.NewFileSet()
	 107  	f, err := parser.ParseFile(fset, "", src, parser.ParseComments)
	 108  	if err != nil {
	 109  		t.Fatal(err)
	 110  	}
	 111  	cmap := NewCommentMap(fset, f, f.Comments)
	 112  
	 113  	// very correct association of comments
	 114  	for n, list := range cmap {
	 115  		key := fmt.Sprintf("%2d: %T", fset.Position(n.Pos()).Line, n)
	 116  		got := ctext(list)
	 117  		want := res[key]
	 118  		if got != want {
	 119  			t.Errorf("%s: got %q; want %q", key, got, want)
	 120  		}
	 121  	}
	 122  
	 123  	// verify that no comments got lost
	 124  	if n := len(cmap.Comments()); n != len(f.Comments) {
	 125  		t.Errorf("got %d comment groups in map; want %d", n, len(f.Comments))
	 126  	}
	 127  
	 128  	// support code to update test:
	 129  	// set genMap to true to generate res map
	 130  	const genMap = false
	 131  	if genMap {
	 132  		out := make([]string, 0, len(cmap))
	 133  		for n, list := range cmap {
	 134  			out = append(out, fmt.Sprintf("\t\"%2d: %T\":\t%q,", fset.Position(n.Pos()).Line, n, ctext(list)))
	 135  		}
	 136  		sort.Strings(out)
	 137  		for _, s := range out {
	 138  			fmt.Println(s)
	 139  		}
	 140  	}
	 141  }
	 142  
	 143  func TestFilter(t *testing.T) {
	 144  	fset := token.NewFileSet()
	 145  	f, err := parser.ParseFile(fset, "", src, parser.ParseComments)
	 146  	if err != nil {
	 147  		t.Fatal(err)
	 148  	}
	 149  	cmap := NewCommentMap(fset, f, f.Comments)
	 150  
	 151  	// delete variable declaration
	 152  	for i, decl := range f.Decls {
	 153  		if gen, ok := decl.(*GenDecl); ok && gen.Tok == token.VAR {
	 154  			copy(f.Decls[i:], f.Decls[i+1:])
	 155  			f.Decls = f.Decls[:len(f.Decls)-1]
	 156  			break
	 157  		}
	 158  	}
	 159  
	 160  	// check if comments are filtered correctly
	 161  	cc := cmap.Filter(f)
	 162  	for n, list := range cc {
	 163  		key := fmt.Sprintf("%2d: %T", fset.Position(n.Pos()).Line, n)
	 164  		got := ctext(list)
	 165  		want := res[key]
	 166  		if key == "25: *ast.GenDecl" || got != want {
	 167  			t.Errorf("%s: got %q; want %q", key, got, want)
	 168  		}
	 169  	}
	 170  }
	 171  

View as plain text