// 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) } } }