Source file src/encoding/json/v2/inline_test.go

     1  // Copyright 2020 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build goexperiment.jsonv2
     6  
     7  package json
     8  
     9  import (
    10  	"os"
    11  	"os/exec"
    12  	"strings"
    13  	"testing"
    14  )
    15  
    16  // Whether a function is inlinable is dependent on the Go compiler version
    17  // and also relies on the presence of the Go toolchain itself being installed.
    18  // This test is disabled by default and explicitly enabled with an
    19  // environment variable that is specified in our integration tests,
    20  // which have fine control over exactly which Go version is being tested.
    21  var testInline = os.Getenv("TEST_INLINE") != ""
    22  
    23  func TestInline(t *testing.T) {
    24  	if !testInline {
    25  		t.SkipNow()
    26  	}
    27  
    28  	pkgs := map[string]map[string]bool{
    29  		".": {
    30  			"hash64":   true,
    31  			"foldName": true, // thin wrapper over appendFoldedName
    32  		},
    33  		"./internal/jsonwire": {
    34  			"ConsumeWhitespace":    true,
    35  			"ConsumeNull":          true,
    36  			"ConsumeFalse":         true,
    37  			"ConsumeTrue":          true,
    38  			"ConsumeSimpleString":  true,
    39  			"ConsumeString":        true, // thin wrapper over consumeStringResumable
    40  			"ConsumeSimpleNumber":  true,
    41  			"ConsumeNumber":        true, // thin wrapper over consumeNumberResumable
    42  			"UnquoteMayCopy":       true, // thin wrapper over unescapeString
    43  			"HasSuffixByte":        true,
    44  			"TrimSuffixByte":       true,
    45  			"TrimSuffixString":     true,
    46  			"TrimSuffixWhitespace": true,
    47  		},
    48  		"./jsontext": {
    49  			"encoderState.NeedFlush":                  true,
    50  			"Decoder.ReadToken":                       true, // thin wrapper over decoderState.ReadToken
    51  			"Decoder.ReadValue":                       true, // thin wrapper over decoderState.ReadValue
    52  			"Encoder.WriteToken":                      true, // thin wrapper over encoderState.WriteToken
    53  			"Encoder.WriteValue":                      true, // thin wrapper over encoderState.WriteValue
    54  			"decodeBuffer.needMore":                   true,
    55  			"stateMachine.appendLiteral":              true,
    56  			"stateMachine.appendNumber":               true,
    57  			"stateMachine.appendString":               true,
    58  			"stateMachine.Depth":                      true,
    59  			"stateMachine.reset":                      true,
    60  			"stateMachine.MayAppendDelim":             true,
    61  			"stateMachine.needDelim":                  true,
    62  			"stateMachine.popArray":                   true,
    63  			"stateMachine.popObject":                  true,
    64  			"stateMachine.pushArray":                  true,
    65  			"stateMachine.pushObject":                 true,
    66  			"stateEntry.Increment":                    true,
    67  			"stateEntry.decrement":                    true,
    68  			"stateEntry.isArray":                      true,
    69  			"stateEntry.isObject":                     true,
    70  			"stateEntry.Length":                       true,
    71  			"stateEntry.needImplicitColon":            true,
    72  			"stateEntry.needImplicitComma":            true,
    73  			"stateEntry.NeedObjectName":               true,
    74  			"stateEntry.needObjectValue":              true,
    75  			"objectNameStack.reset":                   true,
    76  			"objectNameStack.length":                  true,
    77  			"objectNameStack.getUnquoted":             true,
    78  			"objectNameStack.push":                    true,
    79  			"objectNameStack.ReplaceLastQuotedOffset": true,
    80  			"objectNameStack.replaceLastUnquotedName": true,
    81  			"objectNameStack.pop":                     true,
    82  			"objectNameStack.ensureCopiedBuffer":      true,
    83  			"objectNamespace.insertQuoted":            true, // thin wrapper over objectNamespace.insert
    84  			"objectNamespace.InsertUnquoted":          true, // thin wrapper over objectNamespace.insert
    85  			"Token.String":                            true, // thin wrapper over Token.string
    86  		},
    87  	}
    88  
    89  	for pkg, fncs := range pkgs {
    90  		cmd := exec.Command("go", "build", "-gcflags=-m", pkg)
    91  		b, err := cmd.CombinedOutput()
    92  		if err != nil {
    93  			t.Fatalf("exec.Command error: %v\n\n%s", err, b)
    94  		}
    95  		for _, line := range strings.Split(string(b), "\n") {
    96  			const phrase = ": can inline "
    97  			if i := strings.Index(line, phrase); i >= 0 {
    98  				fnc := line[i+len(phrase):]
    99  				fnc = strings.ReplaceAll(fnc, "(", "")
   100  				fnc = strings.ReplaceAll(fnc, "*", "")
   101  				fnc = strings.ReplaceAll(fnc, ")", "")
   102  				delete(fncs, fnc)
   103  			}
   104  		}
   105  		for fnc := range fncs {
   106  			t.Errorf("%v is not inlinable, expected it to be", fnc)
   107  		}
   108  	}
   109  }
   110  

View as plain text