From 8948fa0ea35caa767afaf6d0707e5d7006aedb2c Mon Sep 17 00:00:00 2001 From: Mauri de Souza Meneguzzo Date: Tue, 17 Oct 2023 11:03:42 -0300 Subject: [PATCH] go/printer: fix invalid output for empty decls The current output for empty declarations such as var, const, import results in "var", "const", "import" respectively. These are not valid syntax and the parser will promptly reject them as invalid syntax. This CL updates this behavior by adding "()" to the output of empty decls so the syntax becomes valid, e.g "var ()" instead of "var". Fixes #63566 --- src/go/printer/nodes.go | 9 +++++++++ src/go/printer/printer_test.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/go/printer/nodes.go b/src/go/printer/nodes.go index 0a693b6667..b9dac5da64 100644 --- a/src/go/printer/nodes.go +++ b/src/go/printer/nodes.go @@ -1739,6 +1739,15 @@ func (p *printer) genDecl(d *ast.GenDecl) { p.setPos(d.Pos()) p.print(d.Tok, blank) + // Empty decls for "var ()", "const ()", "import ()" + if len(d.Specs) == 0 { + switch d.Tok { + case token.VAR, token.CONST, token.IMPORT: + p.print(token.LPAREN, token.RPAREN) + return + } + } + if d.Lparen.IsValid() || len(d.Specs) > 1 { // group of parenthesized declarations p.setPos(d.Lparen) diff --git a/src/go/printer/printer_test.go b/src/go/printer/printer_test.go index 8e78bc640e..f5e1419dde 100644 --- a/src/go/printer/printer_test.go +++ b/src/go/printer/printer_test.go @@ -848,3 +848,35 @@ func TestSourcePosNewline(t *testing.T) { t.Errorf("unexpected Fprint output:\n%s", buf.Bytes()) } } + +// TestEmptyDecl tests that empty decls for const, var, import are printed with +// valid syntax e.g "var ()" instead of just "var", which is invalid and cannot +// be parsed. +func TestEmptyDecl(t *testing.T) { // issue 63566 + var tableTests = []struct { + tok token.Token + expected string + }{ + { + tok: token.VAR, + expected: "var ()", + }, + { + tok: token.CONST, + expected: "const ()", + }, + { + tok: token.IMPORT, + expected: "import ()", + }, + } + + for _, tt := range tableTests { + var buf bytes.Buffer + Fprint(&buf, token.NewFileSet(), &ast.GenDecl{Tok: tt.tok}) + got := buf.String() + if got != tt.expected { + t.Errorf("got %q, expected %q\n", got, tt.expected) + } + } +}