| // Copyright 2020 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| //go:build goexperiment.jsonv2 | |
| package json | |
| import ( | |
| "os" | |
| "os/exec" | |
| "strings" | |
| "testing" | |
| ) | |
| // Whether a function is inlinable is dependent on the Go compiler version | |
| // and also relies on the presence of the Go toolchain itself being installed. | |
| // This test is disabled by default and explicitly enabled with an | |
| // environment variable that is specified in our integration tests, | |
| // which have fine control over exactly which Go version is being tested. | |
| var testInline = os.Getenv("TEST_INLINE") != "" | |
| func TestInline(t *testing.T) { | |
| if !testInline { | |
| t.SkipNow() | |
| } | |
| pkgs := map[string]map[string]bool{ | |
| ".": { | |
| "hash64": true, | |
| "foldName": true, // thin wrapper over appendFoldedName | |
| }, | |
| "./internal/jsonwire": { | |
| "ConsumeWhitespace": true, | |
| "ConsumeNull": true, | |
| "ConsumeFalse": true, | |
| "ConsumeTrue": true, | |
| "ConsumeSimpleString": true, | |
| "ConsumeString": true, // thin wrapper over consumeStringResumable | |
| "ConsumeSimpleNumber": true, | |
| "ConsumeNumber": true, // thin wrapper over consumeNumberResumable | |
| "UnquoteMayCopy": true, // thin wrapper over unescapeString | |
| "HasSuffixByte": true, | |
| "TrimSuffixByte": true, | |
| "TrimSuffixString": true, | |
| "TrimSuffixWhitespace": true, | |
| }, | |
| "./jsontext": { | |
| "encoderState.NeedFlush": true, | |
| "Decoder.ReadToken": true, // thin wrapper over decoderState.ReadToken | |
| "Decoder.ReadValue": true, // thin wrapper over decoderState.ReadValue | |
| "Encoder.WriteToken": true, // thin wrapper over encoderState.WriteToken | |
| "Encoder.WriteValue": true, // thin wrapper over encoderState.WriteValue | |
| "decodeBuffer.needMore": true, | |
| "stateMachine.appendLiteral": true, | |
| "stateMachine.appendNumber": true, | |
| "stateMachine.appendString": true, | |
| "stateMachine.Depth": true, | |
| "stateMachine.reset": true, | |
| "stateMachine.MayAppendDelim": true, | |
| "stateMachine.needDelim": true, | |
| "stateMachine.popArray": true, | |
| "stateMachine.popObject": true, | |
| "stateMachine.pushArray": true, | |
| "stateMachine.pushObject": true, | |
| "stateEntry.Increment": true, | |
| "stateEntry.decrement": true, | |
| "stateEntry.isArray": true, | |
| "stateEntry.isObject": true, | |
| "stateEntry.Length": true, | |
| "stateEntry.needImplicitColon": true, | |
| "stateEntry.needImplicitComma": true, | |
| "stateEntry.NeedObjectName": true, | |
| "stateEntry.needObjectValue": true, | |
| "objectNameStack.reset": true, | |
| "objectNameStack.length": true, | |
| "objectNameStack.getUnquoted": true, | |
| "objectNameStack.push": true, | |
| "objectNameStack.ReplaceLastQuotedOffset": true, | |
| "objectNameStack.replaceLastUnquotedName": true, | |
| "objectNameStack.pop": true, | |
| "objectNameStack.ensureCopiedBuffer": true, | |
| "objectNamespace.insertQuoted": true, // thin wrapper over objectNamespace.insert | |
| "objectNamespace.InsertUnquoted": true, // thin wrapper over objectNamespace.insert | |
| "Token.String": true, // thin wrapper over Token.string | |
| }, | |
| } | |
| for pkg, fncs := range pkgs { | |
| cmd := exec.Command("go", "build", "-gcflags=-m", pkg) | |
| b, err := cmd.CombinedOutput() | |
| if err != nil { | |
| t.Fatalf("exec.Command error: %v\n\n%s", err, b) | |
| } | |
| for _, line := range strings.Split(string(b), "\n") { | |
| const phrase = ": can inline " | |
| if i := strings.Index(line, phrase); i >= 0 { | |
| fnc := line[i+len(phrase):] | |
| fnc = strings.ReplaceAll(fnc, "(", "") | |
| fnc = strings.ReplaceAll(fnc, "*", "") | |
| fnc = strings.ReplaceAll(fnc, ")", "") | |
| delete(fncs, fnc) | |
| } | |
| } | |
| for fnc := range fncs { | |
| t.Errorf("%v is not inlinable, expected it to be", fnc) | |
| } | |
| } | |
| } |