Skip to content

Instantly share code, notes, and snippets.

@leitzler
Created July 29, 2021 19:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leitzler/d50361de1e196bebf074822062f98990 to your computer and use it in GitHub Desktop.
Save leitzler/d50361de1e196bebf074822062f98990 to your computer and use it in GitHub Desktop.
Ranged semantic token request at startup.
serve.go:476: debug server listening at http://localhost:51950
[Trace - 21:24:57.225 PM] Received notification 'window/logMessage'.
Params: {"type":3,"message":"2021/07/29 21:24:57 Handshake session update\n\tupdate_session=1\n\tdebug_address=\"127.0.0.1:51950\"\n\tlogfile=\"/var/folders/j4/l2j99h6d5qd6knjlllql0bb80000gn/T/semanticgopls.log\"\n\tserver=\"1\"\n\tgopls_path=\"/Users/leitzler/proj/govim/cmd_govim_semtok/cmd/govim/.bin/7b9c33cde32f91e5e438b06fe339059b4eab8ea1/gopls\"\n"}
[Trace - 21:24:57.225 PM] Sending request 'initialize - (1)'.
Params: {"processId":0,"clientInfo":{"name":""},"rootUri":"file:///Users/leitzler/proj/tools/master","capabilities":{"workspace":{"didChangeConfiguration":{"dynamicRegistration":true},"didChangeWatchedFiles":{"dynamicRegistration":true},"executeCommand":{},"semanticTokens":{},"codeLens":{},"configuration":true},"textDocument":{"synchronization":{},"completion":{"completionItem":{"tagSupport":{"valueSet":null},"resolveSupport":{"properties":null},"insertTextModeSupport":{"valueSet":null}},"completionItemKind":{}},"hover":{"contentFormat":["plaintext"]},"signatureHelp":{"signatureInformation":{"parameterInformation":{}}},"declaration":{},"definition":{},"typeDefinition":{},"implementation":{},"references":{},"documentHighlight":{},"documentSymbol":{"symbolKind":{},"tagSupport":{"valueSet":null}},"codeAction":{"codeActionLiteralSupport":{"codeActionKind":{"valueSet":null}},"resolveSupport":{"properties":null}},"codeLens":{},"documentLink":{},"
colorProvider":{},"formatting":{},"rangeFormatting":{},"onTypeFormatting":{},"rename":{},"foldingRange":{},"selectionRange":{},"publishDiagnostics":{"tagSupport":{"valueSet":null}},"callHierarchy":{},"semanticTokens":{"dynamicRegistration":true,"requests":{},"tokenTypes":["string","type","keyword","variable","function","member","comment","number","operator","namespace","parameter"],"tokenModifiers":["declaration","definition","readonly","static","depricated","abstract","async","modification","documentation","defaultLibrary"],"formats":["relative"],"overlappingTokenSupport":true},"linkedEditingRange":{},"moniker":{}},"window":{"workDoneProgress":true,"showMessage":{"messageActionItem":{}},"showDocument":{"support":false}},"general":{"staleRequestSupport":{"cancel":false,"retryOnContentModified":null},"regularExpressions":{"engine":""},"markdown":{"parser":""}}},"initializationOptions":{"allowModfileModifications":false,"semanticTokens":true,
"symbolMatcher":"fuzzy","symbolStyle":"full"},"workspaceFolders":null}
[Trace - 21:24:57.361 PM] Received response 'initialize - (1)' in 135ms.
Result: {"capabilities":{"textDocumentSync":{"change":2,"openClose":true,"save":{}},"completionProvider":{"triggerCharacters":["."],"completionItem":{}},"hoverProvider":true,"signatureHelpProvider":{"triggerCharacters":["(",","]},"definitionProvider":true,"typeDefinitionProvider":true,"implementationProvider":true,"referencesProvider":true,"documentHighlightProvider":true,"documentSymbolProvider":true,"codeActionProvider":true,"codeLensProvider":{},"documentLinkProvider":{},"workspaceSymbolProvider":true,"documentFormattingProvider":true,"documentOnTypeFormattingProvider":{"firstTriggerCharacter":""},"renameProvider":true,"foldingRangeProvider":true,"executeCommandProvider":{"commands":["gopls.add_dependency","gopls.add_import","gopls.apply_fix","gopls.check_upgrades","gopls.gc_details","gopls.generate","gopls.generate_gopls_mod","gopls.go_get_package","gopls.list_known_packages","gopls.regenerate_cgo","gopls.remove_dependency","gopls.run_t
ests","gopls.start_debugging","gopls.test","gopls.tidy","gopls.toggle_gc_details","gopls.update_go_sum","gopls.upgrade_dependency","gopls.vendor","gopls.workspace_metadata"]},"callHierarchyProvider":true,"workspace":{"workspaceFolders":{"supported":true,"changeNotifications":"workspace/didChangeWorkspaceFolders"}}},"serverInfo":{"name":"gopls","version":"{\"path\":\"golang.org/x/tools/gopls\",\"version\":\"v0.0.0-20210708231608-69948257bde7\",\"sum\":\"h1:/n4EHdXnDw762moODVWkMAypkcQUAReWeuZvmccc6gQ=\",\"deps\":[{\"path\":\"github.com/BurntSushi/toml\",\"version\":\"v0.3.1\",\"sum\":\"h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=\"},{\"path\":\"github.com/google/go-cmp\",\"version\":\"v0.5.5\",\"sum\":\"h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=\"},{\"path\":\"github.com/sergi/go-diff\",\"version\":\"v1.1.0\",\"sum\":\"h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=\"},{\"path\":\"golang.org/x/mod\",\"version\":\"v0.4.2\",\"sum\":\"h1
:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=\"},{\"path\":\"golang.org/x/sync\",\"version\":\"v0.0.0-20210220032951-036812b2e83c\",\"sum\":\"h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=\"},{\"path\":\"golang.org/x/sys\",\"version\":\"v0.0.0-20210510120138-977fb7262007\",\"sum\":\"h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=\"},{\"path\":\"golang.org/x/tools\",\"version\":\"v0.1.5-0.20210708231608-69948257bde7\",\"sum\":\"h1:SibCusD7QqyUXqDhocM0mxP50U93XQ18LWR8JLgxnOM=\"},{\"path\":\"golang.org/x/xerrors\",\"version\":\"v0.0.0-20200804184101-5ec99f83aff1\",\"sum\":\"h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=\"},{\"path\":\"honnef.co/go/tools\",\"version\":\"v0.2.0\",\"sum\":\"h1:ws8AfbgTX3oIczLPNPCu5166oBg9ST2vNs0rcht+mDE=\"},{\"path\":\"mvdan.cc/gofumpt\",\"version\":\"v0.1.1\",\"sum\":\"h1:bi/1aS/5W00E2ny5q65w9SnKpWEF/UIOqDYBILpo9rA=\"},{\"path\":\"mvdan.cc/xurls/v2\",\"version\":\"v2.2.0\",\"sum\":\"h1:NSZPykBXJFCetGZykLAxaL6S
IpvbVy/UFEniIfHAa8A=\"}]}"}}
[Trace - 21:24:57.362 PM] Sending notification 'initialized'.
Params: {}
[Trace - 21:24:57.363 PM] Received request 'window/workDoneProgress/create - (1)'.
Params: {"token":"5577006791947779410"}
[Trace - 21:24:57.374 PM] Sending response 'window/workDoneProgress/create - (1)' in 11ms.
Result:
[Trace - 21:24:57.375 PM] Received notification '$/progress'.
Params: {"token":"5577006791947779410","value":{"kind":"begin","message":"Loading packages...","title":"Setting up workspace"}}
[Trace - 21:24:57.375 PM] Received request 'workspace/configuration - (2)'.
Params: {"items":[{"scopeUri":"file:///Users/leitzler/proj/tools/master","section":"gopls"}]}
[Trace - 21:24:57.376 PM] Sending response 'workspace/configuration - (2)' in 1ms.
Result: [{"analyses":{"fieldalignment":true,"unusedparam":true},"codelenses":{"gc_details":true},"gofumpt":true,"hoverKind":"FullDocumentation","staticcheck":true,"tempModfile":true}]
[Trace - 21:24:57.377 PM] Sending request 'textDocument/semanticTokens/range - (2)'.
Params: {"textDocument":{"uri":"file:///Users/leitzler/proj/tools/master/internal/lsp/semantic.go"},"range":{"start":{"line":0,"character":0},"end":{"line":34,"character":0}}}
[Trace - 21:24:57.378 PM] Sending notification 'textDocument/didOpen'.
Params: {"textDocument":{"uri":"file:///Users/leitzler/proj/tools/master/internal/lsp/semantic.go","languageId":"go","version":1,"text":"// Copyright 2020 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage lsp\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"go/ast\"\n\t\"go/token\"\n\t\"go/types\"\n\t\"path/filepath\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n\n\t\"golang.org/x/tools/internal/event\"\n\t\"golang.org/x/tools/internal/lsp/protocol\"\n\t\"golang.org/x/tools/internal/lsp/source\"\n\t\"golang.org/x/tools/internal/lsp/template\"\n\terrors \"golang.org/x/xerrors\"\n)\n\n// The LSP says that errors for the semantic token requests should only be returned\n// for exceptions (a word not otherwise defined). This code treats a too-large file\n// as an exception. On parse errors, the code does what it can.\n\n// reject full semantic token requests for large files\nconst maxFullFileSize int = 100000\n\nfunc (s *Server) semanticTokensFull(ctx context.Context, p *protocol.SemanticTokensParams) (*protocol.SemanticTokens, error) {\n\tret, err := s.computeSemanticTokens(ctx, p.TextDocument, nil)\n\treturn ret, err\n}\n\nfunc (s *Server) semanticTokensFullDelta(ctx context.Context, p *protocol.SemanticTokensDeltaParams) (interface{}, error) {\n\treturn nil, errors.Errorf(\"implement SemanticTokensFullDelta\")\n}\n\nfunc (s *Server) semanticTokensRange(ctx context.Context, p *protocol.SemanticTokensRangeParams) (*protocol.SemanticTokens, error) {\n\tret, err := s.computeSemanticTokens(ctx, p.TextDocument, \u0026p.Range)\n\treturn ret, err\n}\n\nfunc (s *Server) semanticTokensRefresh(ctx context.Context) error {\n\t// in the code, but not in the protocol spec\n\treturn errors.Errorf(\"implement SemanticTokensRefresh\")\n}\n\nfunc (s *Server) computeSemanticTokens(ctx context.Context, td protocol.TextDocumentIdentifier, rng *protocol.Range) (*protocol.SemanticTokens, error) {\n\tans := protocol.SemanticTokens{\n\t\tData: []uint32{},\n\t}\n\tsnapshot, fh, ok, release, err := s.beginFileRequest(ctx, td.URI, source.UnknownKind)\n\tdefer release()\n\tif !ok {\n\t\treturn nil, err\n\t}\n\tvv := snapshot.View()\n\tif !vv.Options().SemanticTokens {\n\t\t// return an error, so if the option changes\n\t\t// the client won't remember the wrong answer\n\t\treturn nil, errors.Errorf(\"semantictokens are disabled\")\n\t}\n\tif fh.Kind() == source.Tmpl {\n\t\t// this is a little cumbersome to avoid both exporting 'encoded' and its methods\n\t\t// and to avoid import cycles\n\t\te := \u0026encoded{\n\t\t\tctx: ctx,\n\t\t\trng: rng,\n\t\t\ttokTypes: s.session.Options().SemanticTypes,\n\t\t\ttokMods: s.session.Options().SemanticMods,\n\t\t}\n\t\tadd := func(line, start uint32, len uint32) {\n\t\t\te.add(line, start, len, tokMacro, nil)\n\t\t}\n\t\tdata := func() []uint32 {\n\t\t\treturn e.Data()\n\t\t}\n\t\treturn template.SemanticTokens(ctx, snapshot, fh.URI(), add, data)\n\t}\n\tif fh.Kind() != source.Go {\n\t\treturn nil, nil\n\t}\n\tpkg, err := snapshot.PackageForFile(ctx, fh.URI(), source.TypecheckFull, source.WidestPackage)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tinfo := pkg.GetTypesInfo()\n\tpgf, err := pkg.File(fh.URI())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t// ignore pgf.ParseErr. Do what we can.\n\tif rng == nil \u0026\u0026 len(pgf.Src) \u003e maxFullFileSize {\n\t\terr := fmt.Errorf(\"semantic tokens: file %s too large for full (%d\u003e%d)\",\n\t\t\tfh.URI().Filename(), len(pgf.Src), maxFullFileSize)\n\t\treturn nil, err\n\t}\n\te := \u0026encoded{\n\t\tctx: ctx,\n\t\tpgf: pgf,\n\t\trng: rng,\n\t\tti: info,\n\t\tfset: snapshot.FileSet(),\n\t\ttokTypes: s.session.Options().SemanticTypes,\n\t\ttokMods: s.session.Options().SemanticMods,\n\t}\n\tif err := e.init(); err != nil {\n\t\t// e.init should never return an error, unless there's some\n\t\t// seemingly impossible race condition\n\t\treturn nil, err\n\t}\n\te.semantics()\n\tans.Data = e.Data()\n\t// For delta requests, but we've never seen any.\n\tans.ResultID = fmt.Sprintf(\"%v\", time.Now())\n\treturn \u0026ans, nil\n}\n\nfunc (e *encoded) semantics() {\n\tf := e.pgf.File\n\t// may not be in range, but harmless\n\te.token(f.Package, len(\"package\"), tokKeyword, nil)\n\te.token(f.Name.NamePos, len(f.Name.Name), tokNamespace, nil)\n\tinspect := func(n ast.Node) bool {\n\t\treturn e.inspector(n)\n\t}\n\tfor _, d := range f.Decls {\n\t\t// only look at the decls that overlap the range\n\t\tstart, end := d.Pos(), d.End()\n\t\tif end \u003c= e.start || start \u003e= e.end {\n\t\t\tcontinue\n\t\t}\n\t\tast.Inspect(d, inspect)\n\t}\n\tfor _, cg := range f.Comments {\n\t\tfor _, c := range cg.List {\n\t\t\tif !strings.Contains(c.Text, \"\\n\") {\n\t\t\t\te.token(c.Pos(), len(c.Text), tokComment, nil)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\te.multiline(c.Pos(), c.End(), c.Text, tokComment)\n\t\t}\n\t}\n}\n\ntype tokenType string\n\nconst (\n\ttokNamespace tokenType = \"namespace\"\n\ttokType tokenType = \"type\"\n\ttokInterface tokenType = \"interface\"\n\ttokParameter tokenType = \"parameter\"\n\ttokVariable tokenType = \"variable\"\n\ttokMember tokenType = \"member\"\n\ttokFunction tokenType = \"function\"\n\ttokKeyword tokenType = \"keyword\"\n\ttokComment tokenType = \"comment\"\n\ttokString tokenType = \"string\"\n\ttokNumber tokenType = \"number\"\n\ttokOperator tokenType = \"operator\"\n\n\ttokMacro tokenType = \"macro\" // for templates\n)\n\nfunc (e *encoded) token(start token.Pos, leng int, typ tokenType, mods []string) {\n\n\tif !start.IsValid() {\n\t\t// This is not worth reporting\n\t\t//e.unexpected(\"token at token.NoPos\")\n\t\treturn\n\t}\n\tif start \u003e= e.end || start+token.Pos(leng) \u003c= e.start {\n\t\treturn\n\t}\n\t// want a line and column from start (in LSP coordinates)\n\t// [//line directives should be ignored]\n\trng := source.NewMappedRange(e.fset, e.pgf.Mapper, start, start+token.Pos(leng))\n\tlspRange, err := rng.Range()\n\tif err != nil {\n\t\t// possibly a //line directive. TODO(pjw): fix this somehow\n\t\t// \"column mapper is for file...instead of...\"\n\t\t// \"line is beyond end of file...\"\n\t\t// see line 116 of internal/span/token.go which uses Position not PositionFor\n\t\t// (it is too verbose to print the error on every token. some other RPC will fail)\n\t\t// event.Error(e.ctx, \"failed to convert to range\", err)\n\t\treturn\n\t}\n\tif lspRange.End.Line != lspRange.Start.Line {\n\t\t// this happens if users are typing at the end of the file, but report nothing\n\t\treturn\n\t}\n\t// token is all on one line\n\tlength := lspRange.End.Character - lspRange.Start.Character\n\te.add(lspRange.Start.Line, lspRange.Start.Character, length, typ, mods)\n}\n\nfunc (e *encoded) add(line, start uint32, len uint32, tok tokenType, mod []string) {\n\tx := semItem{line, start, len, tok, mod}\n\te.items = append(e.items, x)\n}\n\n// semItem represents a token found walking the parse tree\ntype semItem struct {\n\tline, start uint32\n\tlen uint32\n\ttypeStr tokenType\n\tmods []string\n}\n\ntype encoded struct {\n\t// the generated data\n\titems []semItem\n\n\tctx context.Context\n\ttokTypes, tokMods []string\n\tpgf *source.ParsedGoFile\n\trng *protocol.Range\n\tti *types.Info\n\tfset *token.FileSet\n\t// allowed starting and ending token.Pos, set by init\n\t// used to avoid looking at declarations not in range\n\tstart, end token.Pos\n\t// path from the root of the parse tree, used for debugging\n\tstack []ast.Node\n}\n\n// convert the stack to a string, for debugging\nfunc (e *encoded) strStack() string {\n\tmsg := []string{\"[\"}\n\tfor _, s := range e.stack {\n\t\tmsg = append(msg, fmt.Sprintf(\"%T\", s)[5:])\n\t}\n\tif len(e.stack) \u003e 0 {\n\t\tloc := e.stack[len(e.stack)-1].Pos()\n\t\tadd := e.pgf.Tok.PositionFor(loc, false)\n\t\tnm := filepath.Base(add.Filename)\n\t\tmsg = append(msg, fmt.Sprintf(\"(%s:%d,col:%d)\", nm, add.Line, add.Column))\n\t}\n\tmsg = append(msg, \"]\")\n\treturn strings.Join(msg, \" \")\n}\n\n// find the line in the source\nfunc (e *encoded) srcLine(x ast.Node) string {\n\tfile := e.pgf.Tok\n\tline := file.Line(x.Pos())\n\tstart := file.Offset(file.LineStart(line))\n\tend := start\n\tfor ; end \u003c len(e.pgf.Src) \u0026\u0026 e.pgf.Src[end] != '\\n'; end++ {\n\n\t}\n\tans := e.pgf.Src[start:end]\n\treturn string(ans)\n}\n\nfunc (e *encoded) inspector(n ast.Node) bool {\n\tpop := func() {\n\t\te.stack = e.stack[:len(e.stack)-1]\n\t}\n\tif n == nil {\n\t\tpop()\n\t\treturn true\n\t}\n\te.stack = append(e.stack, n)\n\tswitch x := n.(type) {\n\tcase *ast.ArrayType:\n\tcase *ast.AssignStmt:\n\t\te.token(x.TokPos, len(x.Tok.String()), tokOperator, nil)\n\tcase *ast.BasicLit:\n\t\tif strings.Contains(x.Value, \"\\n\") {\n\t\t\t// has to be a string\n\t\t\te.multiline(x.Pos(), x.End(), x.Value, tokString)\n\t\t\tbreak\n\t\t}\n\t\tln := len(x.Value)\n\t\twhat := tokNumber\n\t\tif x.Kind == token.STRING {\n\t\t\twhat = tokString\n\t\t\tif _, ok := e.stack[len(e.stack)-2].(*ast.Field); ok {\n\t\t\t\t// struct tags (this is probably pointless, as the\n\t\t\t\t// TextMate grammar will treat all the other comments the same)\n\t\t\t\twhat = tokComment\n\t\t\t}\n\t\t}\n\t\te.token(x.Pos(), ln, what, nil)\n\tcase *ast.BinaryExpr:\n\t\te.token(x.OpPos, len(x.Op.String()), tokOperator, nil)\n\tcase *ast.BlockStmt:\n\tcase *ast.BranchStmt:\n\t\te.token(x.TokPos, len(x.Tok.String()), tokKeyword, nil)\n\t\t// There's no semantic encoding for labels\n\tcase *ast.CallExpr:\n\t\tif x.Ellipsis != token.NoPos {\n\t\t\te.token(x.Ellipsis, len(\"...\"), tokOperator, nil)\n\t\t}\n\tcase *ast.CaseClause:\n\t\tiam := \"case\"\n\t\tif x.List == nil {\n\t\t\tiam = \"default\"\n\t\t}\n\t\te.token(x.Case, len(iam), tokKeyword, nil)\n\tcase *ast.ChanType:\n\t\t// chan | chan \u003c- | \u003c- chan\n\t\tif x.Arrow == token.NoPos || x.Arrow != x.Begin {\n\t\t\te.token(x.Begin, len(\"chan\"), tokKeyword, nil)\n\t\t\tbreak\n\t\t}\n\t\tpos := e.findKeyword(\"chan\", x.Begin+2, x.Value.Pos())\n\t\te.token(pos, len(\"chan\"), tokKeyword, nil)\n\tcase *ast.CommClause:\n\t\tiam := len(\"case\")\n\t\tif x.Comm == nil {\n\t\t\tiam = len(\"default\")\n\t\t}\n\t\te.token(x.Case, iam, tokKeyword, nil)\n\tcase *ast.CompositeLit:\n\tcase *ast.DeclStmt:\n\tcase *ast.DeferStmt:\n\t\te.token(x.Defer, len(\"defer\"), tokKeyword, nil)\n\tcase *ast.Ellipsis:\n\t\te.token(x.Ellipsis, len(\"...\"), tokOperator, nil)\n\tcase *ast.EmptyStmt:\n\tcase *ast.ExprStmt:\n\tcase *ast.Field:\n\tcase *ast.FieldList:\n\tcase *ast.ForStmt:\n\t\te.token(x.For, len(\"for\"), tokKeyword, nil)\n\tcase *ast.FuncDecl:\n\tcase *ast.FuncLit:\n\tcase *ast.FuncType:\n\t\tif x.Func != token.NoPos {\n\t\t\te.token(x.Func, len(\"func\"), tokKeyword, nil)\n\t\t}\n\tcase *ast.GenDecl:\n\t\te.token(x.TokPos, len(x.Tok.String()), tokKeyword, nil)\n\tcase *ast.GoStmt:\n\t\te.token(x.Go, len(\"go\"), tokKeyword, nil)\n\tcase *ast.Ident:\n\t\te.ident(x)\n\tcase *ast.IfStmt:\n\t\te.token(x.If, len(\"if\"), tokKeyword, nil)\n\t\tif x.Else != nil {\n\t\t\t// x.Body.End() or x.Body.End()+1, not that it matters\n\t\t\tpos := e.findKeyword(\"else\", x.Body.End(), x.Else.Pos())\n\t\t\te.token(pos, len(\"else\"), tokKeyword, nil)\n\t\t}\n\tcase *ast.ImportSpec:\n\t\te.importSpec(x)\n\t\tpop()\n\t\treturn false\n\tcase *ast.IncDecStmt:\n\t\te.token(x.TokPos, len(x.Tok.String()), tokOperator, nil)\n\tcase *ast.IndexExpr:\n\tcase *ast.InterfaceType:\n\t\te.token(x.Interface, len(\"interface\"), tokKeyword, nil)\n\tcase *ast.KeyValueExpr:\n\tcase *ast.LabeledStmt:\n\tcase *ast.MapType:\n\t\te.token(x.Map, len(\"map\"), tokKeyword, nil)\n\tcase *ast.ParenExpr:\n\tcase *ast.RangeStmt:\n\t\te.token(x.For, len(\"for\"), tokKeyword, nil)\n\t\t// x.TokPos == token.NoPos is legal (for range foo {})\n\t\toffset := x.TokPos\n\t\tif offset == token.NoPos {\n\t\t\toffset = x.For\n\t\t}\n\t\tpos := e.findKeyword(\"range\", offset, x.X.Pos())\n\t\te.token(pos, len(\"range\"), tokKeyword, nil)\n\tcase *ast.ReturnStmt:\n\t\te.token(x.Return, len(\"return\"), tokKeyword, nil)\n\tcase *ast.SelectStmt:\n\t\te.token(x.Select, len(\"select\"), tokKeyword, nil)\n\tcase *ast.SelectorExpr:\n\tcase *ast.SendStmt:\n\t\te.token(x.Arrow, len(\"\u003c-\"), tokOperator, nil)\n\tcase *ast.SliceExpr:\n\tcase *ast.StarExpr:\n\t\te.token(x.Star, len(\"*\"), tokOperator, nil)\n\tcase *ast.StructType:\n\t\te.token(x.Struct, len(\"struct\"), tokKeyword, nil)\n\tcase *ast.SwitchStmt:\n\t\te.token(x.Switch, len(\"switch\"), tokKeyword, nil)\n\tcase *ast.TypeAssertExpr:\n\t\tif x.Type == nil {\n\t\t\tpos := e.findKeyword(\"type\", x.Lparen, x.Rparen)\n\t\t\te.token(pos, len(\"type\"), tokKeyword, nil)\n\t\t}\n\tcase *ast.TypeSpec:\n\tcase *ast.TypeSwitchStmt:\n\t\te.token(x.Switch, len(\"switch\"), tokKeyword, nil)\n\tcase *ast.UnaryExpr:\n\t\te.token(x.OpPos, len(x.Op.String()), tokOperator, nil)\n\tcase *ast.ValueSpec:\n\t// things only seen with parsing or type errors, so ignore them\n\tcase *ast.BadDecl, *ast.BadExpr, *ast.BadStmt:\n\t\treturn true\n\t// not going to see these\n\tcase *ast.File, *ast.Package:\n\t\te.unexpected(fmt.Sprintf(\"implement %T %s\", x, e.pgf.Tok.PositionFor(x.Pos(), false)))\n\t// other things we knowingly ignore\n\tcase *ast.Comment, *ast.CommentGroup:\n\t\tpop()\n\t\treturn false\n\tdefault: // just to be super safe.\n\t\te.unexpected(fmt.Sprintf(\"failed to implement %T\", x))\n\t}\n\treturn true\n}\n\nfunc (e *encoded) ident(x *ast.Ident) {\n\tdef := e.ti.Defs[x]\n\tif def != nil {\n\t\twhat, mods := e.definitionFor(x)\n\t\tif what != \"\" {\n\t\t\te.token(x.Pos(), len(x.String()), what, mods)\n\t\t}\n\t\treturn\n\t}\n\tuse := e.ti.Uses[x]\n\tswitch y := use.(type) {\n\tcase nil:\n\t\te.unkIdent(x)\n\t\treturn\n\tcase *types.Builtin:\n\t\te.token(x.NamePos, len(x.Name), tokFunction, []string{\"defaultLibrary\"})\n\tcase *types.Const:\n\t\tmods := []string{\"readonly\"}\n\t\ttt := y.Type()\n\t\tif _, ok := tt.(*types.Basic); ok {\n\t\t\te.token(x.Pos(), len(x.String()), tokVariable, mods)\n\t\t\tbreak\n\t\t}\n\t\tif ttx, ok := tt.(*types.Named); ok {\n\t\t\tif x.String() == \"iota\" {\n\t\t\t\te.unexpected(fmt.Sprintf(\"iota:%T\", ttx))\n\t\t\t}\n\t\t\tif _, ok := ttx.Underlying().(*types.Basic); ok {\n\t\t\t\te.token(x.Pos(), len(x.String()), tokVariable, mods)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\te.unexpected(fmt.Sprintf(\"%q/%T\", x.String(), tt))\n\t\t}\n\t\t// can this happen? Don't think so\n\t\te.unexpected(fmt.Sprintf(\"%s %T %#v\", x.String(), tt, tt))\n\tcase *types.Func:\n\t\te.token(x.Pos(), len(x.Name), tokFunction, nil)\n\tcase *types.Label:\n\t\t// nothing to map it to\n\tcase *types.Nil:\n\t\t// nil is a predeclared identifier\n\t\te.token(x.Pos(), len(\"nil\"), tokVariable, []string{\"readonly\", \"defaultLibrary\"})\n\tcase *types.PkgName:\n\t\te.token(x.Pos(), len(x.Name), tokNamespace, nil)\n\tcase *types.TypeName:\n\t\tvar mods []string\n\t\tif _, ok := y.Type().(*types.Basic); ok {\n\t\t\tmods = []string{\"defaultLibrary\"}\n\t\t}\n\t\te.token(x.Pos(), len(x.String()), tokType, mods)\n\tcase *types.Var:\n\t\te.token(x.Pos(), len(x.Name), tokVariable, nil)\n\tdefault:\n\t\t// can't happen\n\t\tif use == nil {\n\t\t\tmsg := fmt.Sprintf(\"%#v/%#v %#v %#v\", x, x.Obj, e.ti.Defs[x], e.ti.Uses[x])\n\t\t\te.unexpected(msg)\n\t\t}\n\t\tif use.Type() != nil {\n\t\t\te.unexpected(fmt.Sprintf(\"%s %T/%T,%#v\", x.String(), use, use.Type(), use))\n\t\t} else {\n\t\t\te.unexpected(fmt.Sprintf(\"%s %T\", x.String(), use))\n\t\t}\n\t}\n}\n\n// both e.ti.Defs and e.ti.Uses are nil. use the parse stack\n// a lot of these only happen when the package doesn't compile\nfunc (e *encoded) unkIdent(x *ast.Ident) {\n\ttok := func(tok tokenType, mod []string) {\n\t\te.token(x.Pos(), len(x.Name), tok, mod)\n\t}\n\tdef := []string{\"definition\"}\n\tn := len(e.stack) - 2 // parent of Ident\n\tif n \u003c 0 {\n\t\te.unexpected(\"no stack?\")\n\t\treturn\n\t}\n\tswitch nd := e.stack[n].(type) {\n\tcase *ast.BinaryExpr, *ast.UnaryExpr, *ast.ParenExpr, *ast.StarExpr,\n\t\t*ast.IncDecStmt, *ast.SliceExpr, *ast.ExprStmt, *ast.IndexExpr,\n\t\t*ast.ReturnStmt,\n\t\t*ast.IfStmt, /* condition */\n\t\t*ast.KeyValueExpr: // either key or value\n\t\ttok(tokVariable, nil)\n\tcase *ast.Ellipsis:\n\t\ttok(tokType, nil)\n\tcase *ast.CaseClause:\n\t\tif n-2 \u003e= 0 {\n\t\t\tif _, ok := e.stack[n-2].(*ast.TypeSwitchStmt); ok {\n\t\t\t\ttok(tokType, nil)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\ttok(tokVariable, nil)\n\tcase *ast.ArrayType:\n\t\tif x == nd.Len {\n\t\t\ttok(tokVariable, nil)\n\t\t} else {\n\t\t\ttok(tokType, nil)\n\t\t}\n\tcase *ast.MapType:\n\t\ttok(tokType, nil)\n\tcase *ast.CallExpr:\n\t\tif x == nd.Fun {\n\t\t\ttok(tokFunction, nil)\n\t\t\treturn\n\t\t}\n\t\ttok(tokVariable, nil)\n\tcase *ast.TypeAssertExpr:\n\t\tif x == nd.X {\n\t\t\ttok(tokVariable, nil)\n\t\t} else if x == nd.Type {\n\t\t\ttok(tokType, nil)\n\t\t}\n\tcase *ast.ValueSpec:\n\t\tfor _, p := range nd.Names {\n\t\t\tif p == x {\n\t\t\t\ttok(tokVariable, def)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tfor _, p := range nd.Values {\n\t\t\tif p == x {\n\t\t\t\ttok(tokVariable, nil)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\ttok(tokType, nil)\n\tcase *ast.SelectorExpr: // e.ti.Selections[nd] is nil, so no help\n\t\tif n-1 \u003e= 0 {\n\t\t\tif ce, ok := e.stack[n-1].(*ast.CallExpr); ok {\n\t\t\t\t// ... CallExpr SelectorExpr Ident (_.x())\n\t\t\t\tif ce.Fun == nd \u0026\u0026 nd.Sel == x {\n\t\t\t\t\ttok(tokFunction, nil)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\ttok(tokVariable, nil)\n\tcase *ast.AssignStmt:\n\t\tfor _, p := range nd.Lhs {\n\t\t\t// x := ..., or x = ...\n\t\t\tif p == x {\n\t\t\t\tif nd.Tok != token.DEFINE {\n\t\t\t\t\tdef = nil\n\t\t\t\t}\n\t\t\t\ttok(tokVariable, def)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\t// RHS, = x\n\t\ttok(tokVariable, nil)\n\tcase *ast.TypeSpec: // it's a type if it is either the Name or the Type\n\t\tif x == nd.Type {\n\t\t\tdef = nil\n\t\t}\n\t\ttok(tokType, def)\n\tcase *ast.Field:\n\t\t// ident could be type in a field, or a method in an interface type, or a variable\n\t\tif x == nd.Type {\n\t\t\ttok(tokType, nil)\n\t\t\treturn\n\t\t}\n\t\tif n-2 \u003e= 0 {\n\t\t\t_, okit := e.stack[n-2].(*ast.InterfaceType)\n\t\t\t_, okfl := e.stack[n-1].(*ast.FieldList)\n\t\t\tif okit \u0026\u0026 okfl {\n\t\t\t\ttok(tokMember, def)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\ttok(tokVariable, nil)\n\tcase *ast.LabeledStmt, *ast.BranchStmt:\n\t\t// nothing to report\n\tcase *ast.CompositeLit:\n\t\tif nd.Type == x {\n\t\t\ttok(tokType, nil)\n\t\t\treturn\n\t\t}\n\t\ttok(tokVariable, nil)\n\tcase *ast.RangeStmt:\n\t\tif nd.Tok != token.DEFINE {\n\t\t\tdef = nil\n\t\t}\n\t\ttok(tokVariable, def)\n\tcase *ast.FuncDecl:\n\t\ttok(tokFunction, def)\n\tdefault:\n\t\tmsg := fmt.Sprintf(\"%T undexpected: %s %s%q\", nd, x.Name, e.strStack(), e.srcLine(x))\n\t\te.unexpected(msg)\n\t}\n}\n\nfunc isDeprecated(n *ast.CommentGroup) bool {\n\tif n == nil {\n\t\treturn false\n\t}\n\tfor _, c := range n.List {\n\t\tif strings.HasPrefix(c.Text, \"// Deprecated\") {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (e *encoded) definitionFor(x *ast.Ident) (tokenType, []string) {\n\tmods := []string{\"definition\"}\n\tfor i := len(e.stack) - 1; i \u003e= 0; i-- {\n\t\ts := e.stack[i]\n\t\tswitch y := s.(type) {\n\t\tcase *ast.AssignStmt, *ast.RangeStmt:\n\t\t\tif x.Name == \"_\" {\n\t\t\t\treturn \"\", nil // not really a variable\n\t\t\t}\n\t\t\treturn \"variable\", mods\n\t\tcase *ast.GenDecl:\n\t\t\tif isDeprecated(y.Doc) {\n\t\t\t\tmods = append(mods, \"deprecated\")\n\t\t\t}\n\t\t\tif y.Tok == token.CONST {\n\t\t\t\tmods = append(mods, \"readonly\")\n\t\t\t}\n\t\t\treturn tokVariable, mods\n\t\tcase *ast.FuncDecl:\n\t\t\t// If x is immediately under a FuncDecl, it is a function or method\n\t\t\tif i == len(e.stack)-2 {\n\t\t\t\tif isDeprecated(y.Doc) {\n\t\t\t\t\tmods = append(mods, \"deprecated\")\n\t\t\t\t}\n\t\t\t\tif y.Recv != nil {\n\t\t\t\t\treturn tokMember, mods\n\t\t\t\t}\n\t\t\t\treturn tokFunction, mods\n\t\t\t}\n\t\t\t// if x \u003c ... \u003c FieldList \u003c FuncDecl, this is the receiver, a variable\n\t\t\tif _, ok := e.stack[i+1].(*ast.FieldList); ok {\n\t\t\t\treturn tokVariable, nil\n\t\t\t}\n\t\t\t// if x \u003c ... \u003c FieldList \u003c FuncType \u003c FuncDecl, this is a param\n\t\t\treturn tokParameter, mods\n\t\tcase *ast.InterfaceType:\n\t\t\treturn tokMember, mods\n\t\tcase *ast.TypeSpec:\n\t\t\t// GenDecl/Typespec/FuncType/FieldList/Field/Ident\n\t\t\t// (type A func(b uint64)) (err error)\n\t\t\t// b and err should not be tokType, but tokVaraible\n\t\t\t// and in GenDecl/TpeSpec/StructType/FieldList/Field/Ident\n\t\t\t// (type A struct{b uint64}\n\t\t\t// but on type B struct{C}), C is a type, but is not being defined.\n\t\t\tfldm := e.stack[len(e.stack)-2]\n\t\t\tif fld, ok := fldm.(*ast.Field); ok {\n\t\t\t\t// if len(fld.names) == 0 this is a tokType, being used\n\t\t\t\tif len(fld.Names) == 0 {\n\t\t\t\t\treturn tokType, nil\n\t\t\t\t}\n\t\t\t\treturn tokVariable, mods\n\t\t\t}\n\t\t\treturn tokType, mods\n\t\t}\n\t}\n\t// can't happen\n\tmsg := fmt.Sprintf(\"failed to find the decl for %s\", e.pgf.Tok.PositionFor(x.Pos(), false))\n\te.unexpected(msg)\n\treturn \"\", []string{\"\"}\n}\n\nfunc (e *encoded) multiline(start, end token.Pos, val string, tok tokenType) {\n\tf := e.fset.File(start)\n\t// the hard part is finding the lengths of lines. include the \\n\n\tleng := func(line int) int {\n\t\tn := f.LineStart(line)\n\t\tif line \u003e= f.LineCount() {\n\t\t\treturn f.Size() - int(n)\n\t\t}\n\t\treturn int(f.LineStart(line+1) - n)\n\t}\n\tspos := e.fset.PositionFor(start, false)\n\tepos := e.fset.PositionFor(end, false)\n\tsline := spos.Line\n\teline := epos.Line\n\t// first line is from spos.Column to end\n\te.token(start, leng(sline)-spos.Column, tok, nil) // leng(sline)-1 - (spos.Column-1)\n\tfor i := sline + 1; i \u003c eline; i++ {\n\t\t// intermediate lines are from 1 to end\n\t\te.token(f.LineStart(i), leng(i)-1, tok, nil) // avoid the newline\n\t}\n\t// last line is from 1 to epos.Column\n\te.token(f.LineStart(eline), epos.Column-1, tok, nil) // columns are 1-based\n}\n\n// findKeyword finds a keyword rather than guessing its location\nfunc (e *encoded) findKeyword(keyword string, start, end token.Pos) token.Pos {\n\toffset := int(start) - e.pgf.Tok.Base()\n\tlast := int(end) - e.pgf.Tok.Base()\n\tbuf := e.pgf.Src\n\tidx := bytes.Index(buf[offset:last], []byte(keyword))\n\tif idx != -1 {\n\t\treturn start + token.Pos(idx)\n\t}\n\t// can't happen\n\te.unexpected(fmt.Sprintf(\"not found:%s %v\", keyword, e.fset.PositionFor(start, false)))\n\treturn token.NoPos\n}\n\nfunc (e *encoded) init() error {\n\te.start = token.Pos(e.pgf.Tok.Base())\n\te.end = e.start + token.Pos(e.pgf.Tok.Size())\n\tif e.rng == nil {\n\t\treturn nil\n\t}\n\tspan, err := e.pgf.Mapper.RangeSpan(*e.rng)\n\tif err != nil {\n\t\treturn errors.Errorf(\"range span (%w) error for %s\", err, e.pgf.File.Name)\n\t}\n\te.end = e.start + token.Pos(span.End().Offset())\n\te.start += token.Pos(span.Start().Offset())\n\treturn nil\n}\n\nfunc (e *encoded) Data() []uint32 {\n\t// binary operators, at least, will be out of order\n\tsort.Slice(e.items, func(i, j int) bool {\n\t\tif e.items[i].line != e.items[j].line {\n\t\t\treturn e.items[i].line \u003c e.items[j].line\n\t\t}\n\t\treturn e.items[i].start \u003c e.items[j].start\n\t})\n\ttypeMap, modMap := e.maps()\n\t// each semantic token needs five values\n\t// (see Integer Encoding for Tokens in the LSP spec)\n\tx := make([]uint32, 5*len(e.items))\n\tfor i := 0; i \u003c len(e.items); i++ {\n\t\tj := 5 * i\n\t\tif i == 0 {\n\t\t\tx[0] = e.items[0].line\n\t\t} else {\n\t\t\tx[j] = e.items[i].line - e.items[i-1].line\n\t\t}\n\t\tx[j+1] = e.items[i].start\n\t\tif i \u003e 0 \u0026\u0026 e.items[i].line == e.items[i-1].line {\n\t\t\tx[j+1] = e.items[i].start - e.items[i-1].start\n\t\t}\n\t\tx[j+2] = e.items[i].len\n\t\ttyp, ok := typeMap[e.items[i].typeStr]\n\t\tif !ok {\n\t\t\tcontinue // client doesn't want typeStr\n\t\t}\n\t\tx[j+3] = uint32(typ)\n\t\tmask := 0\n\t\tfor _, s := range e.items[i].mods {\n\t\t\t// modMpa[s] is 0 if the client doesn't want this modifier\n\t\t\tmask |= modMap[s]\n\t\t}\n\t\tx[j+4] = uint32(mask)\n\t}\n\treturn x\n}\n\nfunc (e *encoded) importSpec(d *ast.ImportSpec) {\n\t// a local package name or the last component of the Path\n\tif d.Name != nil {\n\t\tnm := d.Name.String()\n\t\t// import . x =\u003e x is not a namespace\n\t\t// import _ x =\u003e x is a namespace\n\t\tif nm != \"_\" \u0026\u0026 nm != \".\" {\n\t\t\te.token(d.Name.Pos(), len(nm), tokNamespace, nil)\n\t\t\treturn\n\t\t}\n\t\tif nm == \".\" {\n\t\t\treturn\n\t\t}\n\t\t// and fall through for _\n\t}\n\tval := d.Path.Value\n\tif len(val) \u003c 2 || val[0] != '\"' || val[len(val)-1] != '\"' {\n\t\t// avoid panics on imports without a properly quoted string\n\t\treturn\n\t}\n\tnm := val[1 : len(val)-1] // remove surrounding \"s\n\tnm = filepath.Base(nm)\n\t// in import \"lib/math\", 'math' is the package name\n\tstart := d.Path.End() - token.Pos(1+len(nm))\n\te.token(start, len(nm), tokNamespace, nil)\n\t// There may be more cases, as import strings are implementation defined.\n}\n\n// log unexpected state\nfunc (e *encoded) unexpected(msg string) {\n\tevent.Error(e.ctx, e.strStack(), errors.New(msg))\n}\n\n// SemType returns a string equivalent of the type, for gopls semtok\nfunc SemType(n int) string {\n\ttokTypes := SemanticTypes()\n\ttokMods := SemanticModifiers()\n\tif n \u003e= 0 \u0026\u0026 n \u003c len(tokTypes) {\n\t\treturn tokTypes[n]\n\t}\n\treturn fmt.Sprintf(\"?%d[%d,%d]?\", n, len(tokTypes), len(tokMods))\n}\n\n// SemMods returns the []string equivalent of the mods, for gopls semtok.\nfunc SemMods(n int) []string {\n\ttokMods := SemanticModifiers()\n\tmods := []string{}\n\tfor i := 0; i \u003c len(tokMods); i++ {\n\t\tif (n \u0026 (1 \u003c\u003c uint(i))) != 0 {\n\t\t\tmods = append(mods, tokMods[i])\n\t\t}\n\t}\n\treturn mods\n}\n\nfunc (e *encoded) maps() (map[tokenType]int, map[string]int) {\n\ttmap := make(map[tokenType]int)\n\tmmap := make(map[string]int)\n\tfor i, t := range e.tokTypes {\n\t\ttmap[tokenType(t)] = i\n\t}\n\tfor i, m := range e.tokMods {\n\t\tmmap[m] = 1 \u003c\u003c uint(i) // go 1.12 compatibility\n\t}\n\treturn tmap, mmap\n}\n\n// SemanticTypes to use in case there is no client, as in the command line, or tests\nfunc SemanticTypes() []string {\n\treturn semanticTypes[:]\n}\n\n// SemanticModifiers to use in case there is no client.\nfunc SemanticModifiers() []string {\n\treturn semanticModifiers[:]\n}\n\nvar (\n\tsemanticTypes = [...]string{\n\t\t\"namespace\", \"type\", \"class\", \"enum\", \"interface\",\n\t\t\"struct\", \"typeParameter\", \"parameter\", \"variable\", \"property\", \"enumMember\",\n\t\t\"event\", \"function\", \"member\", \"macro\", \"keyword\", \"modifier\", \"comment\",\n\t\t\"string\", \"number\", \"regexp\", \"operator\",\n\t}\n\tsemanticModifiers = [...]string{\n\t\t\"declaration\", \"definition\", \"readonly\", \"static\",\n\t\t\"deprecated\", \"abstract\", \"async\", \"modification\", \"documentation\", \"defaultLibrary\",\n\t}\n)\n"}}
[Trace - 21:24:57.455 PM] Received notification 'window/logMessage'.
Params: {"type":3,"message":"2021/07/29 21:24:57 go env for /Users/leitzler/proj/tools/master\n(root /Users/leitzler/proj/tools/master)\n(go version go version devel go1.17-912f075047 Fri Jul 2 21:06:08 2021 +0000 darwin/amd64)\n(valid build configuration = true)\n(build flags: [])\nGOPATH=/Users/leitzler/go\nGOROOT=/Users/leitzler/sdk/gotip\nGOFLAGS=\nGOPROXY=https://proxy.golang.org,direct\nGOSUMDB=sum.golang.org\nGO111MODULE=\nGOMODCACHE=/Users/leitzler/go/pkg/mod\nGOMOD=/Users/leitzler/proj/tools/master/go.mod\nGONOSUMDB=\nGOPRIVATE=\nGOCACHE=/Users/leitzler/Library/Caches/go-build\nGONOPROXY=\nGOINSECURE=\n\n"}
[Trace - 21:24:58.332 PM] Received notification 'window/logMessage'.
Params: {"type":3,"message":"2021/07/29 21:24:58 go/packages.Load\n\tsnapshot=0\n\tdirectory=/Users/leitzler/proj/tools/master\n\tquery=[builtin golang.org/x/tools/...]\n\tpackages=511\n"}
[Trace - 21:24:58.530 PM] Received notification '$/progress'.
Params: {"token":"5577006791947779410","value":{"kind":"end","message":"Finished loading packages."}}
[Trace - 21:24:58.535 PM] Received request 'client/registerCapability - (3)'.
Params: {"registrations":[{"id":"workspace/didChangeWatchedFiles-0","method":"workspace/didChangeWatchedFiles","registerOptions":{"watchers":[{"globPattern":"**/*.*tmpl","kind":7},{"globPattern":"{/Users/leitzler/proj/tools/master/benchmark,/Users/leitzler/proj/tools/master/benchmark/parse,/Users/leitzler/proj/tools/master/blog,/Users/leitzler/proj/tools/master/blog/atom,/Users/leitzler/proj/tools/master/cmd,/Users/leitzler/proj/tools/master/cmd/auth,/Users/leitzler/proj/tools/master/cmd/auth/authtest,/Users/leitzler/proj/tools/master/cmd/auth/cookieauth,/Users/leitzler/proj/tools/master/cmd/auth/gitauth,/Users/leitzler/proj/tools/master/cmd/auth/netrcauth,/Users/leitzler/proj/tools/master/cmd/benchcmp,/Users/leitzler/proj/tools/master/cmd/bundle,/Users/leitzler/proj/tools/master/cmd/callgraph,/Users/leitzler/proj/tools/master/cmd/compilebench,/Users/leitzler/proj/tools/master/cmd/cover,/Users/leitzler/proj/tools/master/cmd/digraph,/Users/leitzler/proj/tools/master/cmd/eg,/Users/leitzler/proj/tools/master/cmd/fiximports,/Users/leitzler/proj/tools/master/cmd/getgo,/Users/leitzler/proj/tools/master/cmd/getgo/server,/Users/leitzler/proj/tools/master/cmd/go-contrib-init,/Users/leitzler/proj/tools/master/cmd/godex,/Users/leitzler/proj/tools/master/cmd/godoc,/Users/leitzler/proj/tools/master/cmd/goimports,/Users/leitzler/proj/tools/master/cmd/gomvpkg,/Users/leitzler/proj/tools/master/cmd/gorename,/Users/leitzler/proj/tools/master/cmd/gotype,/Users/leitzler/proj/tools/master/cmd/goyacc,/Users/leitzler/proj/tools/master/cmd/guru,/Users/leitzler/proj/tools/master/cmd/guru/serial,/Users/leitzler/proj/tools/master/cmd/html2article,/Users/leitzler/proj/tools/master/cmd/present,/Users/leitzler/proj/tools/master/cmd/present2md,/Users/leitzler/proj/tools/master/cmd/splitdwarf,/Users/leitzler/proj/tools/master/cmd/splitdwarf/internal,/Users/leitzler/proj/tools/master/cmd/splitdwarf/internal/macho,/Users/leitzler/proj/tools/master/cmd/ssadump,/Users/leitzler/proj/tools/master/cmd/stress,/Users/leitzler/proj/tools/master/cmd/stringer,/Users/leitzler/proj/tools/master/cmd/toolstash,/Users/leitzler/proj/tools/master/container,/Users/leitzler/proj/tools/master/container/intsets,/Users/leitzler/proj/tools/master/copyright,/Users/leitzler/proj/tools/master/cover,/Users/leitzler/proj/tools/master/go,/Users/leitzler/proj/tools/master/go/analysis,/Users/leitzler/proj/tools/master/go/analysis/analysistest,/Users/leitzler/proj/tools/master/go/analysis/internal,/Users/leitzler/proj/tools/master/go/analysis/internal/analysisflags,/Users/leitzler/proj/tools/master/go/analysis/internal/checker,/Users/leitzler/proj/tools/master/go/analysis/internal/facts,/Users/leitzler/proj/tools/master/go/analysis/multichecker,/Users/leitzler/proj/tools/master/go/analysis/passes,/Users/leitzler/proj/tools/master/go/analysis/passes/asmdecl,/Users/leitzler/proj/tools/master/go/analysis/passes/assign,/Users/leitzler/proj/tools/master/go/analysis/passes/atomic,/Users/leitzler/proj/tools/master/go/analysis/passes/atomicalign,/Users/leitzler/proj/tools/master/go/analysis/passes/bools,/Users/leitzler/proj/tools/master/go/analysis/passes/buildssa,/Users/leitzler/proj/tools/master/go/analysis/passes/buildtag,/Users/leitzler/proj/tools/master/go/analysis/passes/cgocall,/Users/leitzler/proj/tools/master/go/analysis/passes/composite,/Users/leitzler/proj/tools/master/go/analysis/passes/copylock,/Users/leitzler/proj/tools/master/go/analysis/passes/ctrlflow,/Users/leitzler/proj/tools/master/go/analysis/passes/deepequalerrors,/Users/leitzler/proj/tools/master/go/analysis/passes/errorsas,/Users/leitzler/proj/tools/master/go/analysis/passes/fieldalignment,/Users/leitzler/proj/tools/master/go/analysis/passes/fieldalignment/cmd,/Users/leitzler/proj/tools/master/go/analysis/passes/fieldalignment/cmd/fieldalignment,/Users/leitzler/proj/tools/master/go/analysis/passes/findcall,/Users/leitzler/proj/tools/master/go/analysis/passes/findcall/cmd,/Users/leitzler/proj/tools/master/go/analysis/passes/findcall/cmd/findcall,/Users/leitzler/proj/tools/master/go/analysis/passes/framepointer,/Users/leitzler/proj/tools/master/go/analysis/passes/httpresponse,/Users/leitzler/proj/tools/master/go/analysis/passes/ifaceassert,/Users/leitzler/proj/tools/master/go/analysis/passes/ifaceassert/cmd,/Users/leitzler/proj/tools/master/go/analysis/passes/ifaceassert/cmd/ifaceassert,/Users/leitzler/proj/tools/master/go/analysis/passes/inspect,/Users/leitzler/proj/tools/master/go/analysis/passes/internal,/Users/leitzler/proj/tools/master/go/analysis/passes/internal/analysisutil,/Users/leitzler/proj/tools/master/go/analysis/passes/loopclosure,/Users/leitzler/proj/tools/master/go/analysis/passes/lostcancel,/Users/leitzler/proj/tools/master/go/analysis/passes/lostcancel/cmd,/Users/leitzler/proj/tools/master/go/analysis/passes/lostcancel/cmd/lostcancel,/Users/leitzler/proj/tools/master/go/analysis/passes/nilfunc,/Users/leitzler/proj/tools/master/go/analysis/passes/nilness,/Users/leitzler/proj/tools/master/go/analysis/passes/nilness/cmd,/Users/leitzler/proj/tools/master/go/analysis/passes/nilness/cmd/nilness,/Users/leitzler/proj/tools/master/go/analysis/passes/pkgfact,/Users/leitzler/proj/tools/master/go/analysis/passes/printf,/Users/leitzler/proj/tools/master/go/analysis/passes/reflectvaluecompare,/Users/leitzler/proj/tools/master/go/analysis/passes/shadow,/Users/leitzler/proj/tools/master/go/analysis/passes/shadow/cmd,/Users/leitzler/proj/tools/master/go/analysis/passes/shadow/cmd/shadow,/Users/leitzler/proj/tools/master/go/analysis/passes/shift,/Users/leitzler/proj/tools/master/go/analysis/passes/sigchanyzer,/Users/leitzler/proj/tools/master/go/analysis/passes/sortslice,/Users/leitzler/proj/tools/master/go/analysis/passes/stdmethods,/Users/leitzler/proj/tools/master/go/analysis/passes/stringintconv,/Users/leitzler/proj/tools/master/go/analysis/passes/stringintconv/cmd,/Users/leitzler/proj/tools/master/go/analysis/passes/stringintconv/cmd/stringintconv,/Users/leitzler/proj/tools/master/go/analysis/passes/structtag,/Users/leitzler/proj/tools/master/go/analysis/passes/testinggoroutine,/Users/leitzler/proj/tools/master/go/analysis/passes/tests,/Users/leitzler/proj/tools/master/go/analysis/passes/unmarshal,/Users/leitzler/proj/tools/master/go/analysis/passes/unmarshal/cmd,/Users/leitzler/proj/tools/master/go/analysis/passes/unmarshal/cmd/unmarshal,/Users/leitzler/proj/tools/master/go/analysis/passes/unreachable,/Users/leitzler/proj/tools/master/go/analysis/passes/unsafeptr,/Users/leitzler/proj/tools/master/go/analysis/passes/unusedresult,/Users/leitzler/proj/tools/master/go/analysis/passes/unusedwrite,/Users/leitzler/proj/tools/master/go/analysis/singlechecker,/Users/leitzler/proj/tools/master/go/analysis/unitchecker,/Users/leitzler/proj/tools/master/go/ast,/Users/leitzler/proj/tools/master/go/ast/astutil,/Users/leitzler/proj/tools/master/go/ast/inspector,/Users/leitzler/proj/tools/master/go/buildutil,/Users/leitzler/proj/tools/master/go/callgraph,/Users/leitzler/proj/tools/master/go/callgraph/cha,/Users/leitzler/proj/tools/master/go/callgraph/rta,/Users/leitzler/proj/tools/master/go/callgraph/static,/Users/leitzler/proj/tools/master/go/callgraph/vta,/Users/leitzler/proj/tools/master/go/cfg,/Users/leitzler/proj/tools/master/go/expect,/Users/leitzler/proj/tools/master/go/gccgoexportdata,/Users/leitzler/proj/tools/master/go/gcexportdata,/Users/leitzler/proj/tools/master/go/internal,/Users/leitzler/proj/tools/master/go/internal/cgo,/Users/leitzler/proj/tools/master/go/internal/gccgoimporter,/Users/leitzler/proj/tools/master/go/internal/gcimporter,/Users/leitzler/proj/tools/master/go/internal/packagesdriver,/Users/leitzler/proj/tools/master/go/loader,/Users/leitzler/proj/tools/master/go/packages,/Users/leitzler/proj/tools/master/go/packages/gopackages,/Users/leitzler/proj/tools/master/go/packages/packagestest,/Users/leitzler/proj/tools/master/go/pointer,/Users/leitzler/proj/tools/master/go/ssa,/Users/leitzler/proj/tools/master/go/ssa/interp,/Users/leitzler/proj/tools/master/go/ssa/ssautil,/Users/leitzler/proj/tools/master/go/types,/Users/leitzler/proj/tools/master/go/types/objectpath,/Users/leitzler/proj/tools/master/go/types/typeutil,/Users/leitzler/proj/tools/master/go/vcs,/Users/leitzler/proj/tools/master/godoc,/Users/leitzler/proj/tools/master/godoc/analysis,/Users/leitzler/proj/tools/master/godoc/redirect,/Users/leitzler/proj/tools/master/godoc/static,/Users/leitzler/proj/tools/master/godoc/util,/Users/leitzler/proj/tools/master/godoc/vfs,/Users/leitzler/proj/tools/master/godoc/vfs/gatefs,/Users/leitzler/proj/tools/master/godoc/vfs/httpfs,/Users/leitzler/proj/tools/master/godoc/vfs/mapfs,/Users/leitzler/proj/tools/master/godoc/vfs/zipfs,/Users/leitzler/proj/tools/master/imports,/Users/leitzler/proj/tools/master/internal,/Users/leitzler/proj/tools/master/internal/analysisinternal,/Users/leitzler/proj/tools/master/internal/apidiff,/Users/leitzler/proj/tools/master/internal/event,/Users/leitzler/proj/tools/master/internal/event/core,/Users/leitzler/proj/tools/master/internal/event/export,/Users/leitzler/proj/tools/master/internal/event/export/eventtest,/Users/leitzler/proj/tools/master/internal/event/export/metric,/Users/leitzler/proj/tools/master/internal/event/export/ocagent,/Users/leitzler/proj/tools/master/internal/event/export/ocagent/wire,/Users/leitzler/proj/tools/master/internal/event/export/prometheus,/Users/leitzler/proj/tools/master/internal/event/keys,/Users/leitzler/proj/tools/master/internal/event/label,/Users/leitzler/proj/tools/master/internal/fakenet,/Users/leitzler/proj/tools/master/internal/fastwalk,/Users/leitzler/proj/tools/master/internal/gocommand,/Users/leitzler/proj/tools/master/internal/gopathwalk,/Users/leitzler/proj/tools/master/internal/imports,/Users/leitzler/proj/tools/master/internal/jsonrpc2,/Users/leitzler/proj/tools/master/internal/jsonrpc2/servertest,/Users/leitzler/proj/tools/master/internal/jsonrpc2_v2,/Users/leitzler/proj/tools/master/internal/lsp,/Users/leitzler/proj/tools/master/internal/lsp/analysis,/Users/leitzler/proj/tools/master/internal/lsp/analysis/fillreturns,/Users/leitzler/proj/tools/master/internal/lsp/analysis/fillstruct,/Users/leitzler/proj/tools/master/internal/lsp/analysis/nonewvars,/Users/leitzler/proj/tools/master/internal/lsp/analysis/noresultvalues,/Users/leitzler/proj/tools/master/internal/lsp/analysis/simplifycompositelit,/Users/leitzler/proj/tools/master/internal/lsp/analysis/simplifyrange,/Users/leitzler/proj/tools/master/internal/lsp/analysis/simplifyslice,/Users/leitzler/proj/tools/master/internal/lsp/analysis/undeclaredname,/Users/leitzler/proj/tools/master/internal/lsp/analysis/unusedparams,/Users/leitzler/proj/tools/master/internal/lsp/browser,/Users/leitzler/proj/tools/master/internal/lsp/cache,/Users/leitzler/proj/tools/master/internal/lsp/cmd,/Users/leitzler/proj/tools/master/internal/lsp/cmd/test,/Users/leitzler/proj/tools/master/internal/lsp/command,/Users/leitzler/proj/tools/master/internal/lsp/command/commandmeta,/Users/leitzler/proj/tools/master/internal/lsp/command/gen,/Users/leitzler/proj/tools/master/internal/lsp/debug,/Users/leitzler/proj/tools/master/internal/lsp/debug/log,/Users/leitzler/proj/tools/master/internal/lsp/debug/tag,/Users/leitzler/proj/tools/master/internal/lsp/diff,/Users/leitzler/proj/tools/master/internal/lsp/diff/difftest,/Users/leitzler/proj/tools/master/internal/lsp/diff/myers,/Users/leitzler/proj/tools/master/internal/lsp/fake,/Users/leitzler/proj/tools/master/internal/lsp/fuzzy,/Users/leitzler/proj/tools/master/internal/lsp/helper,/Users/leitzler/proj/tools/master/internal/lsp/lsprpc,/Users/leitzler/proj/tools/master/internal/lsp/mod,/Users/leitzler/proj/tools/master/internal/lsp/progress,/Users/leitzler/proj/tools/master/internal/lsp/protocol,/Users/leitzler/proj/tools/master/internal/lsp/regtest,/Users/leitzler/proj/tools/master/internal/lsp/snippet,/Users/leitzler/proj/tools/master/internal/lsp/source,/Users/leitzler/proj/tools/master/internal/lsp/source/completion,/Users/leitzler/proj/tools/master/internal/lsp/template,/Users/leitzler/proj/tools/master/internal/lsp/tests,/Users/leitzler/proj/tools/master/internal/memoize,/Users/leitzler/proj/tools/master/internal/mod,/Users/leitzler/proj/tools/master/internal/mod/lazyregexp,/Users/leitzler/proj/tools/master/internal/mod/modfile,/Users/leitzler/proj/tools/master/internal/packagesinternal,/Users/leitzler/proj/tools/master/internal/proxydir,/Users/leitzler/proj/tools/master/internal/span,/Users/leitzler/proj/tools/master/internal/stack,/Users/leitzler/proj/tools/master/internal/stack/gostacks,/Users/leitzler/proj/tools/master/internal/stack/stacktest,/Users/leitzler/proj/tools/master/internal/testenv,/Users/leitzler/proj/tools/master/internal/tool,/Users/leitzler/proj/tools/master/internal/typeparams,/Users/leitzler/proj/tools/master/internal/typesinternal,/Users/leitzler/proj/tools/master/internal/xcontext,/Users/leitzler/proj/tools/master/playground,/Users/leitzler/proj/tools/master/playground/socket,/Users/leitzler/proj/tools/master/present,/Users/leitzler/proj/tools/master/refactor,/Users/leitzler/proj/tools/master/refactor/eg,/Users/leitzler/proj/tools/master/refactor/importgraph,/Users/leitzler/proj/tools/master/refactor/rename,/Users/leitzler/proj/tools/master/refactor/satisfy,/Users/leitzler/proj/tools/master/txtar}","kind":7},{"globPattern":"**/*.{go,mod,sum}","kind":7}]}}]}
[Trace - 21:24:58.542 PM] Sending response 'client/registerCapability - (3)' in 7ms.
Result:
[Trace - 21:24:58.544 PM] Received request 'client/registerCapability - (4)'.
Params: {"registrations":[{"id":"workspace/didChangeConfiguration","method":"workspace/didChangeConfiguration"},{"id":"workspace/didChangeWorkspaceFolders","method":"workspace/didChangeWorkspaceFolders"},{"id":"textDocument/semanticTokens","method":"textDocument/semanticTokens","registerOptions":{"full":true,"legend":{"tokenModifiers":["declaration","definition","readonly","static","depricated","abstract","async","modification","documentation","defaultLibrary"],"tokenTypes":["string","type","keyword","variable","function","member","comment","number","operator","namespace","parameter"]},"range":true}}]}
[Trace - 21:24:58.547 PM] Sending response 'client/registerCapability - (4)' in 3ms.
Result:
[Trace - 21:24:58.724 PM] Received notification 'window/logMessage'.
Params: {"type":3,"message":"2021/07/29 21:24:58 discovered missing identifiers: map[memRecordCycle:true pageBits:true]\n\tpackage=\"runtime\"\n"}
[Trace - 21:24:58.793 PM] Received notification 'window/logMessage'.
Params: {"type":3,"message":"2021/07/29 21:24:58 falling back to safe trimming due to type errors: [/Users/leitzler/sdk/gotip/src/internal/buildcfg/exp.go:24:38: 2-valued (func() (goexperiment.Flags, goexperiment.Flags) literal)() (value of type (goexperiment.Flags, goexperiment.Flags)) where single value is expected] or still-missing identifiers: map[]\n\tpackage=\"internal/buildcfg\"\n"}
[Trace - 21:24:58.794 PM] Received notification 'window/logMessage'.
Params: {"type":3,"message":"2021/07/29 21:24:58 discovered missing identifiers: map[message:true]\n\tpackage=\"internal/profile\"\n"}
[Trace - 21:24:58.795 PM] Received notification 'window/logMessage'.
Params: {"type":3,"message":"2021/07/29 21:24:58 discovered missing identifiers: map[options:true]\n\tpackage=\"vendor/golang.org/x/text/unicode/bidi\"\n"}
[Trace - 21:24:58.968 PM] Received notification 'window/logMessage'.
Params: {"type":3,"message":"2021/07/29 21:24:58 discovered missing identifiers: map[markdown:true]\n\tpackage=\"github.com/yuin/goldmark\"\n"}
[Trace - 21:24:58.982 PM] Received notification 'window/logMessage'.
Params: {"type":3,"message":"2021/07/29 21:24:58 falling back to safe trimming due to type errors: [/Users/leitzler/sdk/gotip/src/os/user/cgo_lookup_unix.go:200:19: int not declared by package C /Users/leitzler/sdk/gotip/src/os/user/cgo_lookup_unix.go:203:16: bufferKind(C._SC_GETPW_R_SIZE_MAX) (value of type bufferKind) is not constant /Users/leitzler/sdk/gotip/src/os/user/cgo_lookup_unix.go:204:16: bufferKind(C._SC_GETGR_R_SIZE_MAX) (value of type bufferKind) is not constant] or still-missing identifiers: map[]\n\tpackage=\"os/user\"\n"}
[Trace - 21:24:59.036 PM] Received response 'textDocument/semanticTokens/range - (2)' in 1658ms.
Result: {"resultId":"2021-07-29 21:24:59.035662 +0200 CEST m=+2.811627468","data":[0,0,54,6,0,1,0,53,6,0,1,0,49,6,0,2,0,7,2,0,0,8,3,9,0,2,0,6,2,0,1,2,5,9,0,1,2,7,9,0,1,2,3,9,0,1,5,3,9,0,1,5,5,9,0,1,5,5,9,0,1,7,8,9,0,1,2,4,9,0,1,2,7,9,0,1,2,4,9,0,2,30,5,9,0,1,34,8,9,0,1,34,6,9,0,1,34,8,9,0,1,1,6,9,0,3,0,83,6,0,1,0,83,6,0,1,0,63,6,0,2,0,54,6,0,1,0,5,2,0,0,6,15,3,6,0,16,3,1,512,0,6,6,7,0,2,0,4,2,0,0,6,1,3,0,0,2,1,8,0,0,1,6,1,0,0,8,18,5,2,0,19,3,10,2,0,4,7,9,0,0,8,7,1,0,0,9,1,10,2,0,2,1,8,0,0,1,8,9,0,0,9,20,1,0,0,23,1,8,0,0,1,8,9,0,0,9,14,1,0,0,16,5,1,0,1,1,3,3,2,0,5,3,3,2,0,4,2,8,0,0,3,1,3,0,0,2,21,4,0,0,22,3,3,0,0,5,1,3,0,0,2,12,3,0,0,14,3,3,516]}
[Trace - 21:24:59.332 PM] Received notification 'textDocument/publishDiagnostics'.
Params: {"uri":"file:///Users/leitzler/proj/tools/master/internal/lsp/semantic.go","version":1,"diagnostics":[{"range":{"start":{"line":206,"character":13},"end":{"line":206,"character":19}},"severity":2,"source":"fieldalignment","message":"struct with 40 pointer bytes could be 24"},{"range":{"start":{"line":213,"character":13},"end":{"line":213,"character":19}},"severity":2,"source":"fieldalignment","message":"struct with 144 pointer bytes could be 128"},{"range":{"start":{"line":524,"character":2},"end":{"line":524,"character":14}},"severity":3,"source":"QF1003","message":"could use tagged switch on x"}]}
[Trace - 21:24:59.332 PM] Received notification 'textDocument/publishDiagnostics'.
Params: {"uri":"file:///Users/leitzler/proj/tools/master/internal/lsp/lsp_test.go","diagnostics":[{"range":{"start":{"line":37,"character":12},"end":{"line":37,"character":18}},"severity":2,"source":"fieldalignment","message":"struct with 72 pointer bytes could be 56"}]}
[Trace - 21:24:59.332 PM] Received notification 'textDocument/publishDiagnostics'.
Params: {"uri":"file:///Users/leitzler/proj/tools/master/internal/lsp/diagnostics.go","diagnostics":[{"range":{"start":{"line":40,"character":22},"end":{"line":40,"character":28}},"severity":2,"source":"fieldalignment","message":"struct with 32 pointer bytes could be 16"},{"range":{"start":{"line":48,"character":17},"end":{"line":48,"character":23}},"severity":2,"source":"fieldalignment","message":"struct with 32 pointer bytes could be 16"}]}
[Trace - 21:24:59.332 PM] Received notification 'textDocument/publishDiagnostics'.
Params: {"uri":"file:///Users/leitzler/proj/tools/master/internal/lsp/command.go","diagnostics":[{"range":{"start":{"line":55,"character":19},"end":{"line":55,"character":25}},"severity":2,"source":"fieldalignment","message":"struct with 32 pointer bytes could be 24"}]}
[Trace - 21:24:59.332 PM] Received notification 'textDocument/publishDiagnostics'.
Params: {"uri":"file:///Users/leitzler/proj/tools/master/internal/lsp/debounce.go","diagnostics":[{"range":{"start":{"line":11,"character":19},"end":{"line":11,"character":25}},"severity":2,"source":"fieldalignment","message":"struct with 16 pointer bytes could be 8"},{"range":{"start":{"line":60,"character":10},"end":{"line":62,"character":4}},"severity":2,"source":"SA9003","message":"empty branch"}]}
[Trace - 21:24:59.332 PM] Received notification 'textDocument/publishDiagnostics'.
Params: {"uri":"file:///Users/leitzler/proj/tools/master/internal/lsp/server.go","diagnostics":[{"range":{"start":{"line":65,"character":12},"end":{"line":65,"character":18}},"severity":2,"source":"fieldalignment","message":"struct with 208 pointer bytes could be 176"}]}
[Trace - 21:24:59.732 PM] Received notification 'window/logMessage'.
Params: {"type":3,"message":"2021/07/29 21:24:59 discovered missing identifiers: map[parser:true]\n\tpackage=\"golang.org/x/net/html\"\n"}
[Trace - 21:25:00.847 PM] Sending request 'textDocument/semanticTokens/range - (3)'.
Params: {"textDocument":{"uri":"file:///Users/leitzler/proj/tools/master/internal/lsp/semantic.go"},"range":{"start":{"line":0,"character":0},"end":{"line":34,"character":0}}}
[Trace - 21:25:00.850 PM] Received response 'textDocument/semanticTokens/range - (3)' in 2ms.
Result: {"resultId":"2021-07-29 21:25:00.849505 +0200 CEST m=+4.625429175","data":[0,0,54,6,0,1,0,53,6,0,1,0,49,6,0,2,0,7,2,0,0,8,3,9,0,2,0,6,2,0,1,2,5,9,0,1,2,7,9,0,1,2,3,9,0,1,5,3,9,0,1,5,5,9,0,1,5,5,9,0,1,7,8,9,0,1,2,4,9,0,1,2,7,9,0,1,2,4,9,0,2,30,5,9,0,1,34,8,9,0,1,34,6,9,0,1,34,8,9,0,1,1,6,9,0,3,0,83,6,0,1,0,83,6,0,1,0,63,6,0,2,0,54,6,0,1,0,5,2,0,0,6,15,3,6,0,16,3,1,512,0,6,6,7,0,2,0,4,2,0,0,6,1,3,0,0,2,1,8,0,0,1,6,1,0,0,8,18,5,2,0,19,3,10,2,0,4,7,9,0,0,8,7,1,0,0,9,1,10,2,0,2,1,8,0,0,1,8,9,0,0,9,20,1,0,0,23,1,8,0,0,1,8,9,0,0,9,14,1,0,0,16,5,1,0,1,1,3,3,2,0,5,3,3,2,0,4,2,8,0,0,3,1,3,0,0,2,21,4,0,0,22,3,3,0,0,5,1,3,0,0,2,12,3,0,0,14,3,3,516]}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment