Skip to content

Commit 08fffb5

Browse files
authored
Merge pull request #191 from WillAbides/directive
Directives without leading whitespace
2 parents 2e873f3 + 233a685 commit 08fffb5

File tree

5 files changed

+175
-6
lines changed

5 files changed

+175
-6
lines changed

comments/parse_docs.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func parseFunctions(fset *token.FileSet, pkg *types.Package, decl *ast.GenDecl,
9393
name := value.Names[0].Name
9494

9595
location := fileWithLine(fset.Position(value.Pos()))
96-
result[name] = parseRawLines(location, value.Doc.Text())
96+
result[name] = parseRawLines(location, parse.CommentToString(value.Doc))
9797
}
9898

9999
converter := config.RawConverter{
@@ -107,7 +107,7 @@ func parseFunctions(fset *token.FileSet, pkg *types.Package, decl *ast.GenDecl,
107107
}
108108

109109
func parseGenDecl(fset *token.FileSet, pkg *types.Package, decl *ast.GenDecl) ([]config.RawConverter, error) {
110-
declDocs := decl.Doc.Text()
110+
declDocs := parse.CommentToString(decl.Doc)
111111

112112
if strings.Contains(declDocs, variablesMarker) {
113113
return parseFunctions(fset, pkg, decl, declDocs)
@@ -135,8 +135,8 @@ func parseGenDecl(fset *token.FileSet, pkg *types.Package, decl *ast.GenDecl) ([
135135
var converters []config.RawConverter
136136

137137
for _, spec := range decl.Specs {
138-
if typeSpec, ok := spec.(*ast.TypeSpec); ok && strings.Contains(typeSpec.Doc.Text(), converterMarker) {
139-
c, err := parseInterface(fset, pkg, typeSpec, typeSpec.Doc.Text())
138+
if typeSpec, ok := spec.(*ast.TypeSpec); ok && strings.Contains(parse.CommentToString(typeSpec.Doc), converterMarker) {
139+
c, err := parseInterface(fset, pkg, typeSpec, parse.CommentToString(typeSpec.Doc))
140140
if err != nil {
141141
return nil, err
142142
}
@@ -180,7 +180,7 @@ func parseInterfaceMethods(location *token.FileSet, inter *ast.InterfaceType) (m
180180
name := method.Names[0].String()
181181

182182
location := location.Position(method.Pos())
183-
result[name] = parseRawLines(fileWithLine(location), method.Doc.Text())
183+
result[name] = parseRawLines(fileWithLine(location), parse.CommentToString(method.Doc))
184184
}
185185
return result, nil
186186
}

config/parse/comment.go

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// CommentToString is a modified version of ast.CommentGroup.Text() that doesn't skip directives.
2+
// https://github.com/golang/go/blob/b70244ff7a043786c211775b68259de6104ff91c/src/go/ast/ast.go#L97
3+
//
4+
// Copyright 2009 The Go Authors.
5+
//
6+
// Redistribution and use in source and binary forms, with or without
7+
// modification, are permitted provided that the following conditions are
8+
// met:
9+
//
10+
// * Redistributions of source code must retain the above copyright
11+
// notice, this list of conditions and the following disclaimer.
12+
// * Redistributions in binary form must reproduce the above
13+
// copyright notice, this list of conditions and the following disclaimer
14+
// in the documentation and/or other materials provided with the
15+
// distribution.
16+
// * Neither the name of Google LLC nor the names of its
17+
// contributors may be used to endorse or promote products derived from
18+
// this software without specific prior written permission.
19+
//
20+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22+
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23+
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24+
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25+
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26+
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27+
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28+
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+
32+
package parse
33+
34+
import (
35+
"go/ast"
36+
"strings"
37+
)
38+
39+
func CommentToString(g *ast.CommentGroup) string {
40+
if g == nil {
41+
return ""
42+
}
43+
comments := make([]string, len(g.List))
44+
for i, c := range g.List {
45+
comments[i] = c.Text
46+
}
47+
48+
lines := make([]string, 0, 10) // most comments are less than 10 lines
49+
for _, c := range comments {
50+
// Remove comment markers.
51+
// The parser has given us exactly the comment text.
52+
switch c[1] {
53+
case '/':
54+
//-style comment (no newline at the end)
55+
c = c[2:]
56+
if len(c) == 0 {
57+
// empty line
58+
break
59+
}
60+
if c[0] == ' ' {
61+
// strip first space - required for Example tests
62+
c = c[1:]
63+
break
64+
}
65+
66+
// This is where [*ast.CommentGroup.Text] detects and skips directives.
67+
68+
case '*':
69+
/*-style comment */
70+
c = c[2 : len(c)-2]
71+
}
72+
73+
// Split on newlines.
74+
cl := strings.Split(c, "\n")
75+
76+
// Walk lines, stripping trailing white space and adding to list.
77+
for _, l := range cl {
78+
lines = append(lines, stripTrailingWhitespace(l))
79+
}
80+
}
81+
82+
// Remove leading blank lines; convert runs of
83+
// interior blank lines to a single blank line.
84+
n := 0
85+
for _, line := range lines {
86+
if line != "" || n > 0 && lines[n-1] != "" {
87+
lines[n] = line
88+
n++
89+
}
90+
}
91+
lines = lines[0:n]
92+
93+
// Add final "" entry to get trailing newline from Join.
94+
if n > 0 && lines[n-1] != "" {
95+
lines = append(lines, "")
96+
}
97+
98+
return strings.Join(lines, "\n")
99+
}
100+
101+
func isWhitespace(ch byte) bool { return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' }
102+
103+
func stripTrailingWhitespace(s string) string {
104+
i := len(s)
105+
for i > 0 && isWhitespace(s[i-1]) {
106+
i--
107+
}
108+
return s[0:i]
109+
}

docs/changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import GH from './GH.vue';
66

77
## unreleased
88

9+
- Allow specifying `goverter:` settings without leading space e.g.
10+
`//goverter:converter` <GH issue="190" pr="191"/>
11+
912
## v1.8.0
1013

1114
- Fix go1.24 support. <GH issue="186" pr="187"/>

pkgload/pkgload.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ func (g *PackageLoader) localConfig(pkg *packages.Package, name string) method.L
108108
for _, file := range pkg.Syntax {
109109
for _, decl := range file.Decls {
110110
if fn, ok := decl.(*ast.FuncDecl); ok {
111-
lines := parse.SettingLines(fn.Doc.Text())
111+
lines := parse.SettingLines(parse.CommentToString(fn.Doc))
112112
if len(lines) == 0 {
113113
continue
114114
}

scenario/directive.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
input:
2+
input.go: |
3+
package directive
4+
5+
//goverter:converter
6+
type Simple interface {
7+
//goverter:context c
8+
//goverter:map Value | FromContext
9+
Convert(source struct{ Value int }, c string) struct{ Value string }
10+
}
11+
12+
type (
13+
//goverter:converter
14+
One interface{}
15+
Two interface{}
16+
)
17+
18+
//goverter:variables
19+
var (
20+
Convert func(string) string
21+
)
22+
23+
//goverter:context c
24+
func FromContext(c string) string { return c }
25+
success:
26+
- generated/generated.go: |
27+
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.
28+
29+
package generated
30+
31+
import execution "github.com/jmattheis/goverter/execution"
32+
33+
type OneImpl struct{}
34+
type SimpleImpl struct{}
35+
36+
func (c *SimpleImpl) Convert(source struct {
37+
Value int
38+
}, context string) struct {
39+
Value string
40+
} {
41+
var unnamed struct {
42+
Value string
43+
}
44+
unnamed.Value = execution.FromContext(context)
45+
_ = source
46+
return unnamed
47+
}
48+
- input.gen.go: |
49+
// Code generated by github.com/jmattheis/goverter, DO NOT EDIT.
50+
51+
package directive
52+
53+
func init() {
54+
Convert = func(source string) string {
55+
return source
56+
}
57+
}

0 commit comments

Comments
 (0)