| // Copyright 2019 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package ast_test |
| |
| import ( |
| "go/ast" |
| "go/parser" |
| "go/token" |
| "testing" |
| ) |
| |
| func TestIssue33649(t *testing.T) { |
| for _, src := range []string{ |
| `package p; func _()`, |
| `package p; func _() {`, |
| `package p; func _() { _ = 0`, |
| `package p; func _() { _ = 0 }`, |
| } { |
| fset := token.NewFileSet() |
| f, _ := parser.ParseFile(fset, "", src, parser.AllErrors) |
| if f == nil { |
| panic("invalid test setup: parser didn't return an AST") |
| } |
| |
| // find corresponding token.File |
| var tf *token.File |
| fset.Iterate(func(f *token.File) bool { |
| tf = f |
| return true |
| }) |
| tfEnd := tf.Base() + tf.Size() |
| |
| fd := f.Decls[len(f.Decls)-1].(*ast.FuncDecl) |
| fdEnd := int(fd.End()) |
| |
| if fdEnd != tfEnd { |
| t.Errorf("%q: got fdEnd = %d; want %d (base = %d, size = %d)", src, fdEnd, tfEnd, tf.Base(), tf.Size()) |
| } |
| } |
| } |
| |
| // TestIssue28089 exercises the IsGenerated function. |
| func TestIssue28089(t *testing.T) { |
| for i, test := range []struct { |
| src string |
| want bool |
| }{ |
| // No file comments. |
| {`package p`, false}, |
| // Irrelevant file comments. |
| {`// Package p doc. |
| package p`, false}, |
| // Special comment misplaced after package decl. |
| {`// Package p doc. |
| package p |
| // Code generated by gen. DO NOT EDIT. |
| `, false}, |
| // Special comment appears inside string literal. |
| {`// Package p doc. |
| package p |
| const c = "` + "`" + ` |
| // Code generated by gen. DO NOT EDIT. |
| ` + "`" + ` |
| `, false}, |
| // Special comment appears properly. |
| {`// Copyright 2019 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| // Package p doc comment goes here. |
| // |
| // Code generated by gen. DO NOT EDIT. |
| package p |
| |
| ... `, true}, |
| // Special comment is indented. |
| // |
| // Strictly, the indent should cause IsGenerated to |
| // yield false, but we cannot detect the indent |
| // without either source text or a token.File. |
| // In other words, the function signature cannot |
| // implement the spec. Let's brush this under the |
| // rug since well-formatted code has no indent. |
| {`// Package p doc comment goes here. |
| // |
| // Code generated by gen. DO NOT EDIT. |
| package p |
| |
| ... `, true}, |
| // Special comment has unwanted spaces after "DO NOT EDIT." |
| {`// Copyright 2019 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| // Package p doc comment goes here. |
| // |
| // Code generated by gen. DO NOT EDIT. |
| package p |
| |
| ... `, false}, |
| // Special comment has rogue interior space. |
| {`// Code generated by gen. DO NOT EDIT. |
| package p |
| `, false}, |
| // Special comment lacks the middle portion. |
| {`// Code generated DO NOT EDIT. |
| package p |
| `, false}, |
| // Special comment (incl. "//") appears within a /* block */ comment, |
| // an obscure corner case of the spec. |
| {`/* start of a general comment |
| |
| // Code generated by tool; DO NOT EDIT. |
| |
| end of a general comment */ |
| |
| // +build !dev |
| |
| // Package comment. |
| package p |
| |
| // Does match even though it's inside general comment (/*-style). |
| `, true}, |
| } { |
| fset := token.NewFileSet() |
| f, err := parser.ParseFile(fset, "", test.src, parser.PackageClauseOnly|parser.ParseComments) |
| if f == nil { |
| t.Fatalf("parse %d failed to return AST: %v", i, err) |
| } |
| |
| got := ast.IsGenerated(f) |
| if got != test.want { |
| t.Errorf("%d: IsGenerated on <<%s>> returned %t", i, test.src, got) |
| } |
| } |
| |
| } |