-
Notifications
You must be signed in to change notification settings - Fork 567
Description
We have a large system (B/OSS) written mostly in Go. Recently I tried to switch from the pre-1.0 plugin to 1.0 and found it hangs on indexing. After a bit of fiddleing I nailed it down to a single reason.
We employ source generators heavily. For the CLI module we have generator which parses cli package and generates parameters validating wrappers for every function together with a syntax tree for a CLI language. For example, given the source file
// @short Returns its parameter
// @cmd echo <string>:text
func echo(text string) string {
return text
}
// @short Returns server time
// @cmd show server time
// @cmd get server time
func get_server_time() time.Time {
return time.Now()
}
// @short here goes an unnecessary long command
// @cmd debug idea patience for tree with nested level more than <number>:depth
func debug_ide(depth int) string {
return "Ok!"
}generator produces a "generated.go" file which would include wrappers for these functions as well as the following AST:
var θ_parse_tree = θ_parse_node{"", true, []int{}, nil, "", []θ_parse_node{θ_parse_node{"debug", true, []int{}, nil, "", []θ_parse_node{θ_parse_node{"idea", true, []int{}, nil, "", []θ_parse_node{θ_parse_node{"patience", true, []int{}, nil, "", []θ_parse_node{θ_parse_node{"for", true, []int{}, nil, "", []θ_parse_node{θ_parse_node{"tree", true, []int{}, nil, "", []θ_parse_node{θ_parse_node{"with", true, []int{}, nil, "", []θ_parse_node{θ_parse_node{"nested", true, []int{}, nil, "", []θ_parse_node{θ_parse_node{"level", true, []int{}, nil, "", []θ_parse_node{θ_parse_node{"more", true, []int{}, nil, "", []θ_parse_node{θ_parse_node{"than", true, []int{}, nil, "", []θ_parse_node{θ_parse_node{"<number>", false, []int{0}, (*session).θ_debug_ide, "here goes an unnecessary long command", []θ_parse_node{}}}}}}}}}}}}}}}}}}}}}}, θ_parse_node{"echo", true, []int{}, nil, "", []θ_parse_node{θ_parse_node{"<string>", false, []int{0}, (*session).θ_echo, "Returns its parameter", []θ_parse_node{}}}}, θ_parse_node{"get", true, []int{}, nil, "", []θ_parse_node{θ_parse_node{"output", true, []int{}, nil, "", []θ_parse_node{θ_parse_node{"type", true, []int{}, (*session).θ_get_output_type, "returns current output type", []θ_parse_node{}}}}, θ_parse_node{"server", true, []int{}, nil, "", []θ_parse_node{θ_parse_node{"time", true, []int{}, (*session).θ_get_server_time, "Returns server time", []θ_parse_node{}}}}}}, θ_parse_node{"quit", true, []int{}, (*session).θ_quit, "closes CLI connection", []θ_parse_node{}}, θ_parse_node{"set", true, []int{}, nil, "", []θ_parse_node{θ_parse_node{"output", true, []int{}, nil, "", []θ_parse_node{θ_parse_node{"type", true, []int{}, nil, "", []θ_parse_node{θ_parse_node{"to", true, []int{}, nil, "", []θ_parse_node{θ_parse_node{"<string>", false, []int{0}, (*session).θ_set_output_type, "sets current output type (either json or text)", []θ_parse_node{}}}}}}}}}}, θ_parse_node{"show", true, []int{}, nil, "", []θ_parse_node{θ_parse_node{"server", true, []int{}, nil, "", []θ_parse_node{θ_parse_node{"time", true, []int{}, (*session).θ_get_server_time, "Returns server time", []θ_parse_node{}}}}}}}}(the "θ_" prefix is a simple way to avoid names conflicts since the generated file is placed into the same package)
It seems that plugin got offended not by the size of the tree (since I got it working on the almost full list -- circa 60 commands), but rather by the depth of it.
See https://gist.github.com/growler/ea83fe19845daf86f707 for the full sources (these two files are enough to trigger the bug)