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

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

muirdm opened this issue Sep 10, 2019 · 4 comments

Comments

@muirdm
Copy link

@muirdm 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
Copy link
Contributor

@toothrot toothrot commented Sep 16, 2019

/cc @griesemer, who owns go/parser.

@smasher164
Copy link
Member

@smasher164 smasher164 commented Sep 17, 2019

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

@griesemer griesemer commented Sep 17, 2019

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

@gopherbot gopherbot commented Sep 17, 2019

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

@gopherbot gopherbot closed this in 99aa56a Sep 18, 2019
@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.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants
You can’t perform that action at this time.