| // 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) |
| } |
| } |
| } |