Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

go/parser: ParseExpr should return (partial) result even in case of an error #34211

Closed
muirdm opened this issue Sep 10, 2019 · 4 comments
Closed
Labels
FeatureRequest FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@muirdm
Copy link

muirdm commented Sep 10, 2019

What version of Go are you using (go version)?

$ go version
go version go1.13 darwin/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/muir/Library/Caches/go-build"
GOENV="/Users/muir/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/muir/projects//go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/muir/projects/tools/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/96/wknz1jg92yl623qgplk6qw2h0000gn/T/go-build870832008=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

I used parser.ParseExpr to parse an expression with a syntax error. See https://play.golang.org/p/ypR5PPn3IM4

What did you expect to see?

I expected it to behave similarly to ParseFile in that it is resilient to errors and returns a best effort result with *ast.BadExpr nodes as necessary.

What did you see instead?

ParseExpr fails hard on any error, returning no results.

For context, this came up as we've been fixing gopls completions to work in the face of certain kinds of syntax errors. When a top down parse fails we try to extract an expression that we can parse. However, we can't use ParseExpr because it is not resilient to errors, so we must use ParseFile and wrap our expression.

I'm not sure we can change ParseExpr since there is likely code depending on the current behavior. Perhaps there is room for something new? Something else that might be useful is an interface that will read an expression and not complain if there is data left after reading the expression. That obviates the need to manually find the end of the expression when extracting from larger context.

/cc @stamblerre

@toothrot toothrot added FeatureRequest NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Sep 16, 2019
@toothrot toothrot added this to the Go1.14 milestone Sep 16, 2019
@toothrot
Copy link
Contributor

/cc @griesemer, who owns go/parser.

@smasher164
Copy link
Member

parser.ParseExpr doesn't say anything about guaranteeing a nil ast.Expr when err != nil. Clients should be checking the error anyway, so it could still potentially be modified. Another option is to introduce a named type that is type-asserted for the src parameter in ParseExprFrom, like SrcWithOptions or something, but that might be gross.

If we do introduce a new API for a "reentrant" expression parser, an x/ repo like x/parserutil would be a good place. A "reentrant" parser could take a cursor like in astutil, which would allow it to keep track of state, e.g.

func ParseExpr(*Cursor) (ast.Expr, error)

@griesemer griesemer self-assigned this Sep 17, 2019
@griesemer
Copy link
Contributor

ParseExpr is as resilient as the rest of the parser, it simply doesn't return a partial result.

@griesemer griesemer changed the title go/parser: ParseExpr not resilient to errors go/parser: ParseExpr should return (partial) result even in case of an error Sep 17, 2019
@gopherbot
Copy link

Change https://golang.org/cl/196077 mentions this issue: go/parser: return partial result from ParseExpr in case of error

@golang golang locked and limited conversation to collaborators Sep 17, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FeatureRequest FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

5 participants