Repository: goplus/gop
Pull request #1510 (2023-11-01 12:03:35)

cl: commentFunc add line
coverprofile 格式 filename:line1.col1,line2.col2 numStmts cover 。如果 //line 带有 col 偏移，则计算函数开始结束的 { } col 位置，所以 shadow main 的 line 不加 :col ，在 vscode 插件中将 col 0 修正为 1 即可。

```
最后一行 main.gop:40.0 对应 shadow main func
mode: set
github.com/goplus/gop/cmd/demo/Rect.gox:6.27,8.2 1 0
github.com/goplus/gop/cmd/demo/demo.go:10.26,12.2 1 1
github.com/goplus/gop/cmd/demo/demo.go:14.15,18.2 3 0
github.com/goplus/gop/cmd/demo/main.gop:18.24,20.2 1 1
github.com/goplus/gop/cmd/demo/main.gop:22.15,26.2 3 0
github.com/goplus/gop/cmd/demo/main.gop:28.20,32.11 4 1
github.com/goplus/gop/cmd/demo/main.gop:32.11,34.3 1 0
github.com/goplus/gop/cmd/demo/main.gop:35.2,35.11 1 1
github.com/goplus/gop/cmd/demo/main.gop:40.0,45.2 4 0
```

support `gop test  -coverprofile mycover`

func **//line filename:line:col**
```
//line main.gop:18:1
func (p *Point) Test() {
//line main.gop:19:1
	fmt.Println(p.x, p.y, p.Info, p.info, p.Info.info, p.i.info)
}
```

shadow func **//line filename:line**
```
//line main.gop:40
func main() {
//line main.gop:40:1
	fmt.Println("hello")
}
```


Patch:
diff --git a/cl/compile.go b/cl/compile.go
index 1fd3d019..67d4da0f 100644
--- a/cl/compile.go
+++ b/cl/compile.go
@@ -1041,9 +1041,7 @@ func loadFunc(ctx *blockCtx, recv *types.Var, d *ast.FuncDecl, genBody bool) {
 		ctx.handleErr(err)
 		return
 	}
-	if d.Doc != nil {
-		fn.SetComments(pkg, d.Doc)
-	}
+	commentFunc(ctx, fn, d)
 	if rec := ctx.recorder(); rec != nil {
 		rec.Def(d.Name, fn.Func)
 		if recv == nil {
diff --git a/cl/stmt.go b/cl/stmt.go
index 0a4146b1..b236c61c 100644
--- a/cl/stmt.go
+++ b/cl/stmt.go
@@ -49,7 +49,7 @@ func commentStmt(ctx *blockCtx, stmt ast.Stmt) {
 		if ctx.relativePath {
 			pos.Filename = relFile(ctx.targetDir, pos.Filename)
 		}
-		line := fmt.Sprintf("\n//line %s:%d", pos.Filename, pos.Line)
+		line := fmt.Sprintf("\n//line %s:%d:1", pos.Filename, pos.Line)
 		comments := &goast.CommentGroup{
 			List: []*goast.Comment{{Text: line}},
 		}
@@ -57,6 +57,31 @@ func commentStmt(ctx *blockCtx, stmt ast.Stmt) {
 	}
 }
 
+func commentFunc(ctx *blockCtx, fn *gox.Func, decl *ast.FuncDecl) {
+	if ctx.fileLine {
+		start := decl.Name.Pos()
+		pos := ctx.fset.Position(start)
+		if ctx.relativePath {
+			pos.Filename = relFile(ctx.targetDir, pos.Filename)
+		}
+		var line string
+		if decl.Shadow {
+			line = fmt.Sprintf("//line %s:%d", pos.Filename, pos.Line)
+		} else {
+			line = fmt.Sprintf("//line %s:%d:1", pos.Filename, pos.Line)
+		}
+		doc := &goast.CommentGroup{}
+		if decl.Doc != nil {
+			doc.List = append(doc.List, decl.Doc.List...)
+			doc.List = append(doc.List, &goast.Comment{Text: "//"})
+		}
+		doc.List = append(doc.List, &goast.Comment{Text: line})
+		fn.SetComments(ctx.pkg, doc)
+	} else if decl.Doc != nil {
+		fn.SetComments(ctx.pkg, decl.Doc)
+	}
+}
+
 func compileStmts(ctx *blockCtx, body []ast.Stmt) {
 	for _, stmt := range body {
 		if v, ok := stmt.(*ast.LabeledStmt); ok {


Test patch:
diff --git a/cl/compile_test.go b/cl/compile_test.go
index 3a54eeb8..e058472a 100644
--- a/cl/compile_test.go
+++ b/cl/compile_test.go
@@ -38,8 +38,9 @@ const (
 )
 
 var (
-	gblFset *token.FileSet
-	gblConf *cl.Config
+	gblFset     *token.FileSet
+	gblConf     *cl.Config
+	gblConfLine *cl.Config
 )
 
 func init() {
@@ -57,6 +58,18 @@ func init() {
 		NoFileLine:    true,
 		NoAutoGenMain: true,
 	}
+	gblConfLine = &cl.Config{
+		Fset:          gblFset,
+		Importer:      imp,
+		Recorder:      gopRecorder{},
+		LookupClass:   lookupClass,
+		LookupPub:     lookupPub,
+		C2goBase:      "github.com/goplus/gop/cl/internal",
+		NoFileLine:    false,
+		NoAutoGenMain: true,
+		RelativePath:  true,
+		TargetDir:     ".",
+	}
 }
 
 func gopClNamedTest(t *testing.T, name string, gopcode, expected string) {
@@ -4588,3 +4601,54 @@ func (this *Rect) Test() {
 }
 `, "Rect.gox")
 }
+
+func TestCommentLine(t *testing.T) {
+	gopClTestEx(t, gblConfLine, "main", `
+type Point struct {
+	x int
+	y int
+}
+
+func (pt *Point) Test() {
+	println(pt.x, pt.y)
+}
+
+// testPoint is test point
+func testPoint() {
+	var pt Point
+	pt.Test()
+}
+
+println "hello"
+testPoint()
+`, `package main
+
+import "fmt"
+
+type Point struct {
+	x int
+	y int
+}
+//line /foo/bar.gop:7:1
+func (pt *Point) Test() {
+//line /foo/bar.gop:8:1
+	fmt.Println(pt.x, pt.y)
+}
+// testPoint is test point
+//
+//line /foo/bar.gop:12:1
+func testPoint() {
+//line /foo/bar.gop:13:1
+	var pt Point
+//line /foo/bar.gop:14:1
+	pt.Test()
+}
+//line /foo/bar.gop:17
+func main() {
+//line /foo/bar.gop:17:1
+	fmt.Println("hello")
+//line /foo/bar.gop:18:1
+	testPoint()
+}
+`)
+}