mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-30 23:12:25 -05:00 
			
		
		
		
	bumps our fork of modernc.org/sqlite to v1.34.5 (#3731)
This commit is contained in:
		
					parent
					
						
							
								053d820845
							
						
					
				
			
			
				commit
				
					
						a24048fc05
					
				
			
		
					 42 changed files with 52 additions and 18306 deletions
				
			
		
							
								
								
									
										6
									
								
								go.mod
									
										
									
									
									
								
							
							
						
						
									
										6
									
								
								go.mod
									
										
									
									
									
								
							|  | @ -6,7 +6,7 @@ go 1.23 | |||
| replace github.com/go-swagger/go-swagger => github.com/superseriousbusiness/go-swagger v0.31.0-gts-go1.23-fix | ||||
| 
 | ||||
| // Replace modernc/sqlite with our version that fixes the concurrency INTERRUPT issue | ||||
| replace modernc.org/sqlite => gitlab.com/NyaaaWhatsUpDoc/sqlite v1.34.2-concurrency-workaround | ||||
| replace modernc.org/sqlite => gitlab.com/NyaaaWhatsUpDoc/sqlite v1.34.5-concurrency-workaround | ||||
| 
 | ||||
| // Below pin otel libraries to v1.29.0 until we can figure out issues | ||||
| replace go.opentelemetry.io/otel => go.opentelemetry.io/otel v1.29.0 | ||||
|  | @ -161,7 +161,6 @@ require ( | |||
| 	github.com/gorilla/securecookie v1.1.2 // indirect | ||||
| 	github.com/gorilla/sessions v1.2.2 // indirect | ||||
| 	github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect | ||||
| 	github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect | ||||
| 	github.com/hashicorp/hcl v1.0.0 // indirect | ||||
| 	github.com/huandu/xstrings v1.4.0 // indirect | ||||
| 	github.com/imdario/mergo v0.3.16 // indirect | ||||
|  | @ -235,10 +234,7 @@ require ( | |||
| 	google.golang.org/protobuf v1.36.2 // indirect | ||||
| 	gopkg.in/ini.v1 v1.67.0 // indirect | ||||
| 	gopkg.in/yaml.v2 v2.4.0 // indirect | ||||
| 	modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect | ||||
| 	modernc.org/libc v1.55.3 // indirect | ||||
| 	modernc.org/mathutil v1.6.0 // indirect | ||||
| 	modernc.org/memory v1.8.0 // indirect | ||||
| 	modernc.org/strutil v1.2.0 // indirect | ||||
| 	modernc.org/token v1.1.0 // indirect | ||||
| ) | ||||
|  |  | |||
							
								
								
									
										8
									
								
								go.sum
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								go.sum
									
										
									
										generated
									
									
									
								
							|  | @ -328,8 +328,6 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjw | |||
| github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= | ||||
| github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= | ||||
| github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= | ||||
| github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= | ||||
| github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= | ||||
| github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= | ||||
| github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= | ||||
| github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= | ||||
|  | @ -615,8 +613,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de | |||
| github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= | ||||
| github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= | ||||
| github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= | ||||
| gitlab.com/NyaaaWhatsUpDoc/sqlite v1.34.2-concurrency-workaround h1:Z/9vgdPNZm8ZDANnIJ7ZGeYKJ5biqPY1OQbN+DLCtec= | ||||
| gitlab.com/NyaaaWhatsUpDoc/sqlite v1.34.2-concurrency-workaround/go.mod h1:dnR723UrTtjKpoHCAMN0Q/gZ9MT4r+iRvIBb9umWFkU= | ||||
| gitlab.com/NyaaaWhatsUpDoc/sqlite v1.34.5-concurrency-workaround h1:BLmmUkkZ2KiS8k2lePZRQo7Z5puFrfxuFq9BrJQmS9o= | ||||
| gitlab.com/NyaaaWhatsUpDoc/sqlite v1.34.5-concurrency-workaround/go.mod h1:YLuNmX9NKs8wRNK2ko1LW1NGYcc9FkBO69JOt1AR9JE= | ||||
| go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= | ||||
| go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= | ||||
| go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= | ||||
|  | @ -1012,8 +1010,6 @@ modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= | |||
| modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= | ||||
| modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw= | ||||
| modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= | ||||
| modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= | ||||
| modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= | ||||
| modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U= | ||||
| modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w= | ||||
| modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= | ||||
|  |  | |||
							
								
								
									
										23
									
								
								vendor/github.com/hashicorp/golang-lru/v2/.gitignore
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								vendor/github.com/hashicorp/golang-lru/v2/.gitignore
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,23 +0,0 @@ | |||
| # Compiled Object files, Static and Dynamic libs (Shared Objects) | ||||
| *.o | ||||
| *.a | ||||
| *.so | ||||
| 
 | ||||
| # Folders | ||||
| _obj | ||||
| _test | ||||
| 
 | ||||
| # Architecture specific extensions/prefixes | ||||
| *.[568vq] | ||||
| [568vq].out | ||||
| 
 | ||||
| *.cgo1.go | ||||
| *.cgo2.c | ||||
| _cgo_defun.c | ||||
| _cgo_gotypes.go | ||||
| _cgo_export.* | ||||
| 
 | ||||
| _testmain.go | ||||
| 
 | ||||
| *.exe | ||||
| *.test | ||||
							
								
								
									
										46
									
								
								vendor/github.com/hashicorp/golang-lru/v2/.golangci.yml
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										46
									
								
								vendor/github.com/hashicorp/golang-lru/v2/.golangci.yml
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,46 +0,0 @@ | |||
| # Copyright (c) HashiCorp, Inc. | ||||
| # SPDX-License-Identifier: MPL-2.0 | ||||
| 
 | ||||
| linters: | ||||
|   fast: false | ||||
|   disable-all: true | ||||
|   enable: | ||||
|     - revive | ||||
|     - megacheck | ||||
|     - govet | ||||
|     - unconvert | ||||
|     - gas | ||||
|     - gocyclo | ||||
|     - dupl | ||||
|     - misspell | ||||
|     - unparam | ||||
|     - unused | ||||
|     - typecheck | ||||
|     - ineffassign | ||||
|     # - stylecheck | ||||
|     - exportloopref | ||||
|     - gocritic | ||||
|     - nakedret | ||||
|     - gosimple | ||||
|     - prealloc | ||||
| 
 | ||||
| # golangci-lint configuration file | ||||
| linters-settings: | ||||
|   revive: | ||||
|     ignore-generated-header: true | ||||
|     severity: warning | ||||
|     rules: | ||||
|       - name: package-comments | ||||
|         severity: warning | ||||
|         disabled: true | ||||
|       - name: exported | ||||
|         severity: warning | ||||
|         disabled: false | ||||
|         arguments: ["checkPrivateReceivers", "disableStutteringCheck"] | ||||
| 
 | ||||
| issues: | ||||
|   exclude-use-default: false | ||||
|   exclude-rules: | ||||
|     - path: _test\.go | ||||
|       linters: | ||||
|         - dupl | ||||
							
								
								
									
										267
									
								
								vendor/github.com/hashicorp/golang-lru/v2/2q.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										267
									
								
								vendor/github.com/hashicorp/golang-lru/v2/2q.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,267 +0,0 @@ | |||
| // Copyright (c) HashiCorp, Inc. | ||||
| // SPDX-License-Identifier: MPL-2.0 | ||||
| 
 | ||||
| package lru | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"sync" | ||||
| 
 | ||||
| 	"github.com/hashicorp/golang-lru/v2/simplelru" | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	// Default2QRecentRatio is the ratio of the 2Q cache dedicated | ||||
| 	// to recently added entries that have only been accessed once. | ||||
| 	Default2QRecentRatio = 0.25 | ||||
| 
 | ||||
| 	// Default2QGhostEntries is the default ratio of ghost | ||||
| 	// entries kept to track entries recently evicted | ||||
| 	Default2QGhostEntries = 0.50 | ||||
| ) | ||||
| 
 | ||||
| // TwoQueueCache is a thread-safe fixed size 2Q cache. | ||||
| // 2Q is an enhancement over the standard LRU cache | ||||
| // in that it tracks both frequently and recently used | ||||
| // entries separately. This avoids a burst in access to new | ||||
| // entries from evicting frequently used entries. It adds some | ||||
| // additional tracking overhead to the standard LRU cache, and is | ||||
| // computationally about 2x the cost, and adds some metadata over | ||||
| // head. The ARCCache is similar, but does not require setting any | ||||
| // parameters. | ||||
| type TwoQueueCache[K comparable, V any] struct { | ||||
| 	size        int | ||||
| 	recentSize  int | ||||
| 	recentRatio float64 | ||||
| 	ghostRatio  float64 | ||||
| 
 | ||||
| 	recent      simplelru.LRUCache[K, V] | ||||
| 	frequent    simplelru.LRUCache[K, V] | ||||
| 	recentEvict simplelru.LRUCache[K, struct{}] | ||||
| 	lock        sync.RWMutex | ||||
| } | ||||
| 
 | ||||
| // New2Q creates a new TwoQueueCache using the default | ||||
| // values for the parameters. | ||||
| func New2Q[K comparable, V any](size int) (*TwoQueueCache[K, V], error) { | ||||
| 	return New2QParams[K, V](size, Default2QRecentRatio, Default2QGhostEntries) | ||||
| } | ||||
| 
 | ||||
| // New2QParams creates a new TwoQueueCache using the provided | ||||
| // parameter values. | ||||
| func New2QParams[K comparable, V any](size int, recentRatio, ghostRatio float64) (*TwoQueueCache[K, V], error) { | ||||
| 	if size <= 0 { | ||||
| 		return nil, errors.New("invalid size") | ||||
| 	} | ||||
| 	if recentRatio < 0.0 || recentRatio > 1.0 { | ||||
| 		return nil, errors.New("invalid recent ratio") | ||||
| 	} | ||||
| 	if ghostRatio < 0.0 || ghostRatio > 1.0 { | ||||
| 		return nil, errors.New("invalid ghost ratio") | ||||
| 	} | ||||
| 
 | ||||
| 	// Determine the sub-sizes | ||||
| 	recentSize := int(float64(size) * recentRatio) | ||||
| 	evictSize := int(float64(size) * ghostRatio) | ||||
| 
 | ||||
| 	// Allocate the LRUs | ||||
| 	recent, err := simplelru.NewLRU[K, V](size, nil) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	frequent, err := simplelru.NewLRU[K, V](size, nil) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	recentEvict, err := simplelru.NewLRU[K, struct{}](evictSize, nil) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	// Initialize the cache | ||||
| 	c := &TwoQueueCache[K, V]{ | ||||
| 		size:        size, | ||||
| 		recentSize:  recentSize, | ||||
| 		recentRatio: recentRatio, | ||||
| 		ghostRatio:  ghostRatio, | ||||
| 		recent:      recent, | ||||
| 		frequent:    frequent, | ||||
| 		recentEvict: recentEvict, | ||||
| 	} | ||||
| 	return c, nil | ||||
| } | ||||
| 
 | ||||
| // Get looks up a key's value from the cache. | ||||
| func (c *TwoQueueCache[K, V]) Get(key K) (value V, ok bool) { | ||||
| 	c.lock.Lock() | ||||
| 	defer c.lock.Unlock() | ||||
| 
 | ||||
| 	// Check if this is a frequent value | ||||
| 	if val, ok := c.frequent.Get(key); ok { | ||||
| 		return val, ok | ||||
| 	} | ||||
| 
 | ||||
| 	// If the value is contained in recent, then we | ||||
| 	// promote it to frequent | ||||
| 	if val, ok := c.recent.Peek(key); ok { | ||||
| 		c.recent.Remove(key) | ||||
| 		c.frequent.Add(key, val) | ||||
| 		return val, ok | ||||
| 	} | ||||
| 
 | ||||
| 	// No hit | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Add adds a value to the cache. | ||||
| func (c *TwoQueueCache[K, V]) Add(key K, value V) { | ||||
| 	c.lock.Lock() | ||||
| 	defer c.lock.Unlock() | ||||
| 
 | ||||
| 	// Check if the value is frequently used already, | ||||
| 	// and just update the value | ||||
| 	if c.frequent.Contains(key) { | ||||
| 		c.frequent.Add(key, value) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	// Check if the value is recently used, and promote | ||||
| 	// the value into the frequent list | ||||
| 	if c.recent.Contains(key) { | ||||
| 		c.recent.Remove(key) | ||||
| 		c.frequent.Add(key, value) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	// If the value was recently evicted, add it to the | ||||
| 	// frequently used list | ||||
| 	if c.recentEvict.Contains(key) { | ||||
| 		c.ensureSpace(true) | ||||
| 		c.recentEvict.Remove(key) | ||||
| 		c.frequent.Add(key, value) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	// Add to the recently seen list | ||||
| 	c.ensureSpace(false) | ||||
| 	c.recent.Add(key, value) | ||||
| } | ||||
| 
 | ||||
| // ensureSpace is used to ensure we have space in the cache | ||||
| func (c *TwoQueueCache[K, V]) ensureSpace(recentEvict bool) { | ||||
| 	// If we have space, nothing to do | ||||
| 	recentLen := c.recent.Len() | ||||
| 	freqLen := c.frequent.Len() | ||||
| 	if recentLen+freqLen < c.size { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	// If the recent buffer is larger than | ||||
| 	// the target, evict from there | ||||
| 	if recentLen > 0 && (recentLen > c.recentSize || (recentLen == c.recentSize && !recentEvict)) { | ||||
| 		k, _, _ := c.recent.RemoveOldest() | ||||
| 		c.recentEvict.Add(k, struct{}{}) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	// Remove from the frequent list otherwise | ||||
| 	c.frequent.RemoveOldest() | ||||
| } | ||||
| 
 | ||||
| // Len returns the number of items in the cache. | ||||
| func (c *TwoQueueCache[K, V]) Len() int { | ||||
| 	c.lock.RLock() | ||||
| 	defer c.lock.RUnlock() | ||||
| 	return c.recent.Len() + c.frequent.Len() | ||||
| } | ||||
| 
 | ||||
| // Resize changes the cache size. | ||||
| func (c *TwoQueueCache[K, V]) Resize(size int) (evicted int) { | ||||
| 	c.lock.Lock() | ||||
| 	defer c.lock.Unlock() | ||||
| 
 | ||||
| 	// Recalculate the sub-sizes | ||||
| 	recentSize := int(float64(size) * c.recentRatio) | ||||
| 	evictSize := int(float64(size) * c.ghostRatio) | ||||
| 	c.size = size | ||||
| 	c.recentSize = recentSize | ||||
| 
 | ||||
| 	// ensureSpace | ||||
| 	diff := c.recent.Len() + c.frequent.Len() - size | ||||
| 	if diff < 0 { | ||||
| 		diff = 0 | ||||
| 	} | ||||
| 	for i := 0; i < diff; i++ { | ||||
| 		c.ensureSpace(true) | ||||
| 	} | ||||
| 
 | ||||
| 	// Reallocate the LRUs | ||||
| 	c.recent.Resize(size) | ||||
| 	c.frequent.Resize(size) | ||||
| 	c.recentEvict.Resize(evictSize) | ||||
| 
 | ||||
| 	return diff | ||||
| } | ||||
| 
 | ||||
| // Keys returns a slice of the keys in the cache. | ||||
| // The frequently used keys are first in the returned slice. | ||||
| func (c *TwoQueueCache[K, V]) Keys() []K { | ||||
| 	c.lock.RLock() | ||||
| 	defer c.lock.RUnlock() | ||||
| 	k1 := c.frequent.Keys() | ||||
| 	k2 := c.recent.Keys() | ||||
| 	return append(k1, k2...) | ||||
| } | ||||
| 
 | ||||
| // Values returns a slice of the values in the cache. | ||||
| // The frequently used values are first in the returned slice. | ||||
| func (c *TwoQueueCache[K, V]) Values() []V { | ||||
| 	c.lock.RLock() | ||||
| 	defer c.lock.RUnlock() | ||||
| 	v1 := c.frequent.Values() | ||||
| 	v2 := c.recent.Values() | ||||
| 	return append(v1, v2...) | ||||
| } | ||||
| 
 | ||||
| // Remove removes the provided key from the cache. | ||||
| func (c *TwoQueueCache[K, V]) Remove(key K) { | ||||
| 	c.lock.Lock() | ||||
| 	defer c.lock.Unlock() | ||||
| 	if c.frequent.Remove(key) { | ||||
| 		return | ||||
| 	} | ||||
| 	if c.recent.Remove(key) { | ||||
| 		return | ||||
| 	} | ||||
| 	if c.recentEvict.Remove(key) { | ||||
| 		return | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Purge is used to completely clear the cache. | ||||
| func (c *TwoQueueCache[K, V]) Purge() { | ||||
| 	c.lock.Lock() | ||||
| 	defer c.lock.Unlock() | ||||
| 	c.recent.Purge() | ||||
| 	c.frequent.Purge() | ||||
| 	c.recentEvict.Purge() | ||||
| } | ||||
| 
 | ||||
| // Contains is used to check if the cache contains a key | ||||
| // without updating recency or frequency. | ||||
| func (c *TwoQueueCache[K, V]) Contains(key K) bool { | ||||
| 	c.lock.RLock() | ||||
| 	defer c.lock.RUnlock() | ||||
| 	return c.frequent.Contains(key) || c.recent.Contains(key) | ||||
| } | ||||
| 
 | ||||
| // Peek is used to inspect the cache value of a key | ||||
| // without updating recency or frequency. | ||||
| func (c *TwoQueueCache[K, V]) Peek(key K) (value V, ok bool) { | ||||
| 	c.lock.RLock() | ||||
| 	defer c.lock.RUnlock() | ||||
| 	if val, ok := c.frequent.Peek(key); ok { | ||||
| 		return val, ok | ||||
| 	} | ||||
| 	return c.recent.Peek(key) | ||||
| } | ||||
							
								
								
									
										364
									
								
								vendor/github.com/hashicorp/golang-lru/v2/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										364
									
								
								vendor/github.com/hashicorp/golang-lru/v2/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,364 +0,0 @@ | |||
| Copyright (c) 2014 HashiCorp, Inc. | ||||
| 
 | ||||
| Mozilla Public License, version 2.0 | ||||
| 
 | ||||
| 1. Definitions | ||||
| 
 | ||||
| 1.1. "Contributor" | ||||
| 
 | ||||
|      means each individual or legal entity that creates, contributes to the | ||||
|      creation of, or owns Covered Software. | ||||
| 
 | ||||
| 1.2. "Contributor Version" | ||||
| 
 | ||||
|      means the combination of the Contributions of others (if any) used by a | ||||
|      Contributor and that particular Contributor's Contribution. | ||||
| 
 | ||||
| 1.3. "Contribution" | ||||
| 
 | ||||
|      means Covered Software of a particular Contributor. | ||||
| 
 | ||||
| 1.4. "Covered Software" | ||||
| 
 | ||||
|      means Source Code Form to which the initial Contributor has attached the | ||||
|      notice in Exhibit A, the Executable Form of such Source Code Form, and | ||||
|      Modifications of such Source Code Form, in each case including portions | ||||
|      thereof. | ||||
| 
 | ||||
| 1.5. "Incompatible With Secondary Licenses" | ||||
|      means | ||||
| 
 | ||||
|      a. that the initial Contributor has attached the notice described in | ||||
|         Exhibit B to the Covered Software; or | ||||
| 
 | ||||
|      b. that the Covered Software was made available under the terms of | ||||
|         version 1.1 or earlier of the License, but not also under the terms of | ||||
|         a Secondary License. | ||||
| 
 | ||||
| 1.6. "Executable Form" | ||||
| 
 | ||||
|      means any form of the work other than Source Code Form. | ||||
| 
 | ||||
| 1.7. "Larger Work" | ||||
| 
 | ||||
|      means a work that combines Covered Software with other material, in a | ||||
|      separate file or files, that is not Covered Software. | ||||
| 
 | ||||
| 1.8. "License" | ||||
| 
 | ||||
|      means this document. | ||||
| 
 | ||||
| 1.9. "Licensable" | ||||
| 
 | ||||
|      means having the right to grant, to the maximum extent possible, whether | ||||
|      at the time of the initial grant or subsequently, any and all of the | ||||
|      rights conveyed by this License. | ||||
| 
 | ||||
| 1.10. "Modifications" | ||||
| 
 | ||||
|      means any of the following: | ||||
| 
 | ||||
|      a. any file in Source Code Form that results from an addition to, | ||||
|         deletion from, or modification of the contents of Covered Software; or | ||||
| 
 | ||||
|      b. any new file in Source Code Form that contains any Covered Software. | ||||
| 
 | ||||
| 1.11. "Patent Claims" of a Contributor | ||||
| 
 | ||||
|       means any patent claim(s), including without limitation, method, | ||||
|       process, and apparatus claims, in any patent Licensable by such | ||||
|       Contributor that would be infringed, but for the grant of the License, | ||||
|       by the making, using, selling, offering for sale, having made, import, | ||||
|       or transfer of either its Contributions or its Contributor Version. | ||||
| 
 | ||||
| 1.12. "Secondary License" | ||||
| 
 | ||||
|       means either the GNU General Public License, Version 2.0, the GNU Lesser | ||||
|       General Public License, Version 2.1, the GNU Affero General Public | ||||
|       License, Version 3.0, or any later versions of those licenses. | ||||
| 
 | ||||
| 1.13. "Source Code Form" | ||||
| 
 | ||||
|       means the form of the work preferred for making modifications. | ||||
| 
 | ||||
| 1.14. "You" (or "Your") | ||||
| 
 | ||||
|       means an individual or a legal entity exercising rights under this | ||||
|       License. For legal entities, "You" includes any entity that controls, is | ||||
|       controlled by, or is under common control with You. For purposes of this | ||||
|       definition, "control" means (a) the power, direct or indirect, to cause | ||||
|       the direction or management of such entity, whether by contract or | ||||
|       otherwise, or (b) ownership of more than fifty percent (50%) of the | ||||
|       outstanding shares or beneficial ownership of such entity. | ||||
| 
 | ||||
| 
 | ||||
| 2. License Grants and Conditions | ||||
| 
 | ||||
| 2.1. Grants | ||||
| 
 | ||||
|      Each Contributor hereby grants You a world-wide, royalty-free, | ||||
|      non-exclusive license: | ||||
| 
 | ||||
|      a. under intellectual property rights (other than patent or trademark) | ||||
|         Licensable by such Contributor to use, reproduce, make available, | ||||
|         modify, display, perform, distribute, and otherwise exploit its | ||||
|         Contributions, either on an unmodified basis, with Modifications, or | ||||
|         as part of a Larger Work; and | ||||
| 
 | ||||
|      b. under Patent Claims of such Contributor to make, use, sell, offer for | ||||
|         sale, have made, import, and otherwise transfer either its | ||||
|         Contributions or its Contributor Version. | ||||
| 
 | ||||
| 2.2. Effective Date | ||||
| 
 | ||||
|      The licenses granted in Section 2.1 with respect to any Contribution | ||||
|      become effective for each Contribution on the date the Contributor first | ||||
|      distributes such Contribution. | ||||
| 
 | ||||
| 2.3. Limitations on Grant Scope | ||||
| 
 | ||||
|      The licenses granted in this Section 2 are the only rights granted under | ||||
|      this License. No additional rights or licenses will be implied from the | ||||
|      distribution or licensing of Covered Software under this License. | ||||
|      Notwithstanding Section 2.1(b) above, no patent license is granted by a | ||||
|      Contributor: | ||||
| 
 | ||||
|      a. for any code that a Contributor has removed from Covered Software; or | ||||
| 
 | ||||
|      b. for infringements caused by: (i) Your and any other third party's | ||||
|         modifications of Covered Software, or (ii) the combination of its | ||||
|         Contributions with other software (except as part of its Contributor | ||||
|         Version); or | ||||
| 
 | ||||
|      c. under Patent Claims infringed by Covered Software in the absence of | ||||
|         its Contributions. | ||||
| 
 | ||||
|      This License does not grant any rights in the trademarks, service marks, | ||||
|      or logos of any Contributor (except as may be necessary to comply with | ||||
|      the notice requirements in Section 3.4). | ||||
| 
 | ||||
| 2.4. Subsequent Licenses | ||||
| 
 | ||||
|      No Contributor makes additional grants as a result of Your choice to | ||||
|      distribute the Covered Software under a subsequent version of this | ||||
|      License (see Section 10.2) or under the terms of a Secondary License (if | ||||
|      permitted under the terms of Section 3.3). | ||||
| 
 | ||||
| 2.5. Representation | ||||
| 
 | ||||
|      Each Contributor represents that the Contributor believes its | ||||
|      Contributions are its original creation(s) or it has sufficient rights to | ||||
|      grant the rights to its Contributions conveyed by this License. | ||||
| 
 | ||||
| 2.6. Fair Use | ||||
| 
 | ||||
|      This License is not intended to limit any rights You have under | ||||
|      applicable copyright doctrines of fair use, fair dealing, or other | ||||
|      equivalents. | ||||
| 
 | ||||
| 2.7. Conditions | ||||
| 
 | ||||
|      Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in | ||||
|      Section 2.1. | ||||
| 
 | ||||
| 
 | ||||
| 3. Responsibilities | ||||
| 
 | ||||
| 3.1. Distribution of Source Form | ||||
| 
 | ||||
|      All distribution of Covered Software in Source Code Form, including any | ||||
|      Modifications that You create or to which You contribute, must be under | ||||
|      the terms of this License. You must inform recipients that the Source | ||||
|      Code Form of the Covered Software is governed by the terms of this | ||||
|      License, and how they can obtain a copy of this License. You may not | ||||
|      attempt to alter or restrict the recipients' rights in the Source Code | ||||
|      Form. | ||||
| 
 | ||||
| 3.2. Distribution of Executable Form | ||||
| 
 | ||||
|      If You distribute Covered Software in Executable Form then: | ||||
| 
 | ||||
|      a. such Covered Software must also be made available in Source Code Form, | ||||
|         as described in Section 3.1, and You must inform recipients of the | ||||
|         Executable Form how they can obtain a copy of such Source Code Form by | ||||
|         reasonable means in a timely manner, at a charge no more than the cost | ||||
|         of distribution to the recipient; and | ||||
| 
 | ||||
|      b. You may distribute such Executable Form under the terms of this | ||||
|         License, or sublicense it under different terms, provided that the | ||||
|         license for the Executable Form does not attempt to limit or alter the | ||||
|         recipients' rights in the Source Code Form under this License. | ||||
| 
 | ||||
| 3.3. Distribution of a Larger Work | ||||
| 
 | ||||
|      You may create and distribute a Larger Work under terms of Your choice, | ||||
|      provided that You also comply with the requirements of this License for | ||||
|      the Covered Software. If the Larger Work is a combination of Covered | ||||
|      Software with a work governed by one or more Secondary Licenses, and the | ||||
|      Covered Software is not Incompatible With Secondary Licenses, this | ||||
|      License permits You to additionally distribute such Covered Software | ||||
|      under the terms of such Secondary License(s), so that the recipient of | ||||
|      the Larger Work may, at their option, further distribute the Covered | ||||
|      Software under the terms of either this License or such Secondary | ||||
|      License(s). | ||||
| 
 | ||||
| 3.4. Notices | ||||
| 
 | ||||
|      You may not remove or alter the substance of any license notices | ||||
|      (including copyright notices, patent notices, disclaimers of warranty, or | ||||
|      limitations of liability) contained within the Source Code Form of the | ||||
|      Covered Software, except that You may alter any license notices to the | ||||
|      extent required to remedy known factual inaccuracies. | ||||
| 
 | ||||
| 3.5. Application of Additional Terms | ||||
| 
 | ||||
|      You may choose to offer, and to charge a fee for, warranty, support, | ||||
|      indemnity or liability obligations to one or more recipients of Covered | ||||
|      Software. However, You may do so only on Your own behalf, and not on | ||||
|      behalf of any Contributor. You must make it absolutely clear that any | ||||
|      such warranty, support, indemnity, or liability obligation is offered by | ||||
|      You alone, and You hereby agree to indemnify every Contributor for any | ||||
|      liability incurred by such Contributor as a result of warranty, support, | ||||
|      indemnity or liability terms You offer. You may include additional | ||||
|      disclaimers of warranty and limitations of liability specific to any | ||||
|      jurisdiction. | ||||
| 
 | ||||
| 4. Inability to Comply Due to Statute or Regulation | ||||
| 
 | ||||
|    If it is impossible for You to comply with any of the terms of this License | ||||
|    with respect to some or all of the Covered Software due to statute, | ||||
|    judicial order, or regulation then You must: (a) comply with the terms of | ||||
|    this License to the maximum extent possible; and (b) describe the | ||||
|    limitations and the code they affect. Such description must be placed in a | ||||
|    text file included with all distributions of the Covered Software under | ||||
|    this License. Except to the extent prohibited by statute or regulation, | ||||
|    such description must be sufficiently detailed for a recipient of ordinary | ||||
|    skill to be able to understand it. | ||||
| 
 | ||||
| 5. Termination | ||||
| 
 | ||||
| 5.1. The rights granted under this License will terminate automatically if You | ||||
|      fail to comply with any of its terms. However, if You become compliant, | ||||
|      then the rights granted under this License from a particular Contributor | ||||
|      are reinstated (a) provisionally, unless and until such Contributor | ||||
|      explicitly and finally terminates Your grants, and (b) on an ongoing | ||||
|      basis, if such Contributor fails to notify You of the non-compliance by | ||||
|      some reasonable means prior to 60 days after You have come back into | ||||
|      compliance. Moreover, Your grants from a particular Contributor are | ||||
|      reinstated on an ongoing basis if such Contributor notifies You of the | ||||
|      non-compliance by some reasonable means, this is the first time You have | ||||
|      received notice of non-compliance with this License from such | ||||
|      Contributor, and You become compliant prior to 30 days after Your receipt | ||||
|      of the notice. | ||||
| 
 | ||||
| 5.2. If You initiate litigation against any entity by asserting a patent | ||||
|      infringement claim (excluding declaratory judgment actions, | ||||
|      counter-claims, and cross-claims) alleging that a Contributor Version | ||||
|      directly or indirectly infringes any patent, then the rights granted to | ||||
|      You by any and all Contributors for the Covered Software under Section | ||||
|      2.1 of this License shall terminate. | ||||
| 
 | ||||
| 5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user | ||||
|      license agreements (excluding distributors and resellers) which have been | ||||
|      validly granted by You or Your distributors under this License prior to | ||||
|      termination shall survive termination. | ||||
| 
 | ||||
| 6. Disclaimer of Warranty | ||||
| 
 | ||||
|    Covered Software is provided under this License on an "as is" basis, | ||||
|    without warranty of any kind, either expressed, implied, or statutory, | ||||
|    including, without limitation, warranties that the Covered Software is free | ||||
|    of defects, merchantable, fit for a particular purpose or non-infringing. | ||||
|    The entire risk as to the quality and performance of the Covered Software | ||||
|    is with You. Should any Covered Software prove defective in any respect, | ||||
|    You (not any Contributor) assume the cost of any necessary servicing, | ||||
|    repair, or correction. This disclaimer of warranty constitutes an essential | ||||
|    part of this License. No use of  any Covered Software is authorized under | ||||
|    this License except under this disclaimer. | ||||
| 
 | ||||
| 7. Limitation of Liability | ||||
| 
 | ||||
|    Under no circumstances and under no legal theory, whether tort (including | ||||
|    negligence), contract, or otherwise, shall any Contributor, or anyone who | ||||
|    distributes Covered Software as permitted above, be liable to You for any | ||||
|    direct, indirect, special, incidental, or consequential damages of any | ||||
|    character including, without limitation, damages for lost profits, loss of | ||||
|    goodwill, work stoppage, computer failure or malfunction, or any and all | ||||
|    other commercial damages or losses, even if such party shall have been | ||||
|    informed of the possibility of such damages. This limitation of liability | ||||
|    shall not apply to liability for death or personal injury resulting from | ||||
|    such party's negligence to the extent applicable law prohibits such | ||||
|    limitation. Some jurisdictions do not allow the exclusion or limitation of | ||||
|    incidental or consequential damages, so this exclusion and limitation may | ||||
|    not apply to You. | ||||
| 
 | ||||
| 8. Litigation | ||||
| 
 | ||||
|    Any litigation relating to this License may be brought only in the courts | ||||
|    of a jurisdiction where the defendant maintains its principal place of | ||||
|    business and such litigation shall be governed by laws of that | ||||
|    jurisdiction, without reference to its conflict-of-law provisions. Nothing | ||||
|    in this Section shall prevent a party's ability to bring cross-claims or | ||||
|    counter-claims. | ||||
| 
 | ||||
| 9. Miscellaneous | ||||
| 
 | ||||
|    This License represents the complete agreement concerning the subject | ||||
|    matter hereof. If any provision of this License is held to be | ||||
|    unenforceable, such provision shall be reformed only to the extent | ||||
|    necessary to make it enforceable. Any law or regulation which provides that | ||||
|    the language of a contract shall be construed against the drafter shall not | ||||
|    be used to construe this License against a Contributor. | ||||
| 
 | ||||
| 
 | ||||
| 10. Versions of the License | ||||
| 
 | ||||
| 10.1. New Versions | ||||
| 
 | ||||
|       Mozilla Foundation is the license steward. Except as provided in Section | ||||
|       10.3, no one other than the license steward has the right to modify or | ||||
|       publish new versions of this License. Each version will be given a | ||||
|       distinguishing version number. | ||||
| 
 | ||||
| 10.2. Effect of New Versions | ||||
| 
 | ||||
|       You may distribute the Covered Software under the terms of the version | ||||
|       of the License under which You originally received the Covered Software, | ||||
|       or under the terms of any subsequent version published by the license | ||||
|       steward. | ||||
| 
 | ||||
| 10.3. Modified Versions | ||||
| 
 | ||||
|       If you create software not governed by this License, and you want to | ||||
|       create a new license for such software, you may create and use a | ||||
|       modified version of this License if you rename the license and remove | ||||
|       any references to the name of the license steward (except to note that | ||||
|       such modified license differs from this License). | ||||
| 
 | ||||
| 10.4. Distributing Source Code Form that is Incompatible With Secondary | ||||
|       Licenses If You choose to distribute Source Code Form that is | ||||
|       Incompatible With Secondary Licenses under the terms of this version of | ||||
|       the License, the notice described in Exhibit B of this License must be | ||||
|       attached. | ||||
| 
 | ||||
| Exhibit A - Source Code Form License Notice | ||||
| 
 | ||||
|       This Source Code Form is subject to the | ||||
|       terms of the Mozilla Public License, v. | ||||
|       2.0. If a copy of the MPL was not | ||||
|       distributed with this file, You can | ||||
|       obtain one at | ||||
|       http://mozilla.org/MPL/2.0/. | ||||
| 
 | ||||
| If it is not possible or desirable to put the notice in a particular file, | ||||
| then You may include the notice in a location (such as a LICENSE file in a | ||||
| relevant directory) where a recipient would be likely to look for such a | ||||
| notice. | ||||
| 
 | ||||
| You may add additional accurate notices of copyright ownership. | ||||
| 
 | ||||
| Exhibit B - "Incompatible With Secondary Licenses" Notice | ||||
| 
 | ||||
|       This Source Code Form is "Incompatible | ||||
|       With Secondary Licenses", as defined by | ||||
|       the Mozilla Public License, v. 2.0. | ||||
							
								
								
									
										79
									
								
								vendor/github.com/hashicorp/golang-lru/v2/README.md
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										79
									
								
								vendor/github.com/hashicorp/golang-lru/v2/README.md
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,79 +0,0 @@ | |||
| golang-lru | ||||
| ========== | ||||
| 
 | ||||
| This provides the `lru` package which implements a fixed-size | ||||
| thread safe LRU cache. It is based on the cache in Groupcache. | ||||
| 
 | ||||
| Documentation | ||||
| ============= | ||||
| 
 | ||||
| Full docs are available on [Go Packages](https://pkg.go.dev/github.com/hashicorp/golang-lru/v2) | ||||
| 
 | ||||
| LRU cache example | ||||
| ================= | ||||
| 
 | ||||
| ```go | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"github.com/hashicorp/golang-lru/v2" | ||||
| ) | ||||
| 
 | ||||
| func main() { | ||||
| 	l, _ := lru.New[int, any](128) | ||||
| 	for i := 0; i < 256; i++ { | ||||
| 		l.Add(i, nil) | ||||
| 	} | ||||
| 	if l.Len() != 128 { | ||||
| 		panic(fmt.Sprintf("bad len: %v", l.Len())) | ||||
| 	} | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| Expirable LRU cache example | ||||
| =========================== | ||||
| 
 | ||||
| ```go | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/hashicorp/golang-lru/v2/expirable" | ||||
| ) | ||||
| 
 | ||||
| func main() { | ||||
| 	// make cache with 10ms TTL and 5 max keys | ||||
| 	cache := expirable.NewLRU[string, string](5, nil, time.Millisecond*10) | ||||
| 
 | ||||
| 
 | ||||
| 	// set value under key1. | ||||
| 	cache.Add("key1", "val1") | ||||
| 
 | ||||
| 	// get value under key1 | ||||
| 	r, ok := cache.Get("key1") | ||||
| 
 | ||||
| 	// check for OK value | ||||
| 	if ok { | ||||
| 		fmt.Printf("value before expiration is found: %v, value: %q\n", ok, r) | ||||
| 	} | ||||
| 
 | ||||
| 	// wait for cache to expire | ||||
| 	time.Sleep(time.Millisecond * 12) | ||||
| 
 | ||||
| 	// get value under key1 after key expiration | ||||
| 	r, ok = cache.Get("key1") | ||||
| 	fmt.Printf("value after expiration is found: %v, value: %q\n", ok, r) | ||||
| 
 | ||||
| 	// set value under key2, would evict old entry because it is already expired. | ||||
| 	cache.Add("key2", "val2") | ||||
| 
 | ||||
| 	fmt.Printf("Cache len: %d\n", cache.Len()) | ||||
| 	// Output: | ||||
| 	// value before expiration is found: true, value: "val1" | ||||
| 	// value after expiration is found: false, value: "" | ||||
| 	// Cache len: 1 | ||||
| } | ||||
| ``` | ||||
							
								
								
									
										24
									
								
								vendor/github.com/hashicorp/golang-lru/v2/doc.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								vendor/github.com/hashicorp/golang-lru/v2/doc.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,24 +0,0 @@ | |||
| // Copyright (c) HashiCorp, Inc. | ||||
| // SPDX-License-Identifier: MPL-2.0 | ||||
| 
 | ||||
| // Package lru provides three different LRU caches of varying sophistication. | ||||
| // | ||||
| // Cache is a simple LRU cache. It is based on the LRU implementation in | ||||
| // groupcache: https://github.com/golang/groupcache/tree/master/lru | ||||
| // | ||||
| // TwoQueueCache tracks frequently used and recently used entries separately. | ||||
| // This avoids a burst of accesses from taking out frequently used entries, at | ||||
| // the cost of about 2x computational overhead and some extra bookkeeping. | ||||
| // | ||||
| // ARCCache is an adaptive replacement cache. It tracks recent evictions as well | ||||
| // as recent usage in both the frequent and recent caches. Its computational | ||||
| // overhead is comparable to TwoQueueCache, but the memory overhead is linear | ||||
| // with the size of the cache. | ||||
| // | ||||
| // ARC has been patented by IBM, so do not use it if that is problematic for | ||||
| // your program. For this reason, it is in a separate go module contained within | ||||
| // this repository. | ||||
| // | ||||
| // All caches in this package take locks while operating, and are therefore | ||||
| // thread-safe for consumers. | ||||
| package lru | ||||
							
								
								
									
										142
									
								
								vendor/github.com/hashicorp/golang-lru/v2/internal/list.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										142
									
								
								vendor/github.com/hashicorp/golang-lru/v2/internal/list.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,142 +0,0 @@ | |||
| // Copyright 2009 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_list file. | ||||
| 
 | ||||
| package internal | ||||
| 
 | ||||
| import "time" | ||||
| 
 | ||||
| // Entry is an LRU Entry | ||||
| type Entry[K comparable, V any] struct { | ||||
| 	// Next and previous pointers in the doubly-linked list of elements. | ||||
| 	// To simplify the implementation, internally a list l is implemented | ||||
| 	// as a ring, such that &l.root is both the next element of the last | ||||
| 	// list element (l.Back()) and the previous element of the first list | ||||
| 	// element (l.Front()). | ||||
| 	next, prev *Entry[K, V] | ||||
| 
 | ||||
| 	// The list to which this element belongs. | ||||
| 	list *LruList[K, V] | ||||
| 
 | ||||
| 	// The LRU Key of this element. | ||||
| 	Key K | ||||
| 
 | ||||
| 	// The Value stored with this element. | ||||
| 	Value V | ||||
| 
 | ||||
| 	// The time this element would be cleaned up, optional | ||||
| 	ExpiresAt time.Time | ||||
| 
 | ||||
| 	// The expiry bucket item was put in, optional | ||||
| 	ExpireBucket uint8 | ||||
| } | ||||
| 
 | ||||
| // PrevEntry returns the previous list element or nil. | ||||
| func (e *Entry[K, V]) PrevEntry() *Entry[K, V] { | ||||
| 	if p := e.prev; e.list != nil && p != &e.list.root { | ||||
| 		return p | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // LruList represents a doubly linked list. | ||||
| // The zero Value for LruList is an empty list ready to use. | ||||
| type LruList[K comparable, V any] struct { | ||||
| 	root Entry[K, V] // sentinel list element, only &root, root.prev, and root.next are used | ||||
| 	len  int         // current list Length excluding (this) sentinel element | ||||
| } | ||||
| 
 | ||||
| // Init initializes or clears list l. | ||||
| func (l *LruList[K, V]) Init() *LruList[K, V] { | ||||
| 	l.root.next = &l.root | ||||
| 	l.root.prev = &l.root | ||||
| 	l.len = 0 | ||||
| 	return l | ||||
| } | ||||
| 
 | ||||
| // NewList returns an initialized list. | ||||
| func NewList[K comparable, V any]() *LruList[K, V] { return new(LruList[K, V]).Init() } | ||||
| 
 | ||||
| // Length returns the number of elements of list l. | ||||
| // The complexity is O(1). | ||||
| func (l *LruList[K, V]) Length() int { return l.len } | ||||
| 
 | ||||
| // Back returns the last element of list l or nil if the list is empty. | ||||
| func (l *LruList[K, V]) Back() *Entry[K, V] { | ||||
| 	if l.len == 0 { | ||||
| 		return nil | ||||
| 	} | ||||
| 	return l.root.prev | ||||
| } | ||||
| 
 | ||||
| // lazyInit lazily initializes a zero List Value. | ||||
| func (l *LruList[K, V]) lazyInit() { | ||||
| 	if l.root.next == nil { | ||||
| 		l.Init() | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // insert inserts e after at, increments l.len, and returns e. | ||||
| func (l *LruList[K, V]) insert(e, at *Entry[K, V]) *Entry[K, V] { | ||||
| 	e.prev = at | ||||
| 	e.next = at.next | ||||
| 	e.prev.next = e | ||||
| 	e.next.prev = e | ||||
| 	e.list = l | ||||
| 	l.len++ | ||||
| 	return e | ||||
| } | ||||
| 
 | ||||
| // insertValue is a convenience wrapper for insert(&Entry{Value: v, ExpiresAt: ExpiresAt}, at). | ||||
| func (l *LruList[K, V]) insertValue(k K, v V, expiresAt time.Time, at *Entry[K, V]) *Entry[K, V] { | ||||
| 	return l.insert(&Entry[K, V]{Value: v, Key: k, ExpiresAt: expiresAt}, at) | ||||
| } | ||||
| 
 | ||||
| // Remove removes e from its list, decrements l.len | ||||
| func (l *LruList[K, V]) Remove(e *Entry[K, V]) V { | ||||
| 	e.prev.next = e.next | ||||
| 	e.next.prev = e.prev | ||||
| 	e.next = nil // avoid memory leaks | ||||
| 	e.prev = nil // avoid memory leaks | ||||
| 	e.list = nil | ||||
| 	l.len-- | ||||
| 
 | ||||
| 	return e.Value | ||||
| } | ||||
| 
 | ||||
| // move moves e to next to at. | ||||
| func (l *LruList[K, V]) move(e, at *Entry[K, V]) { | ||||
| 	if e == at { | ||||
| 		return | ||||
| 	} | ||||
| 	e.prev.next = e.next | ||||
| 	e.next.prev = e.prev | ||||
| 
 | ||||
| 	e.prev = at | ||||
| 	e.next = at.next | ||||
| 	e.prev.next = e | ||||
| 	e.next.prev = e | ||||
| } | ||||
| 
 | ||||
| // PushFront inserts a new element e with value v at the front of list l and returns e. | ||||
| func (l *LruList[K, V]) PushFront(k K, v V) *Entry[K, V] { | ||||
| 	l.lazyInit() | ||||
| 	return l.insertValue(k, v, time.Time{}, &l.root) | ||||
| } | ||||
| 
 | ||||
| // PushFrontExpirable inserts a new expirable element e with Value v at the front of list l and returns e. | ||||
| func (l *LruList[K, V]) PushFrontExpirable(k K, v V, expiresAt time.Time) *Entry[K, V] { | ||||
| 	l.lazyInit() | ||||
| 	return l.insertValue(k, v, expiresAt, &l.root) | ||||
| } | ||||
| 
 | ||||
| // MoveToFront moves element e to the front of list l. | ||||
| // If e is not an element of l, the list is not modified. | ||||
| // The element must not be nil. | ||||
| func (l *LruList[K, V]) MoveToFront(e *Entry[K, V]) { | ||||
| 	if e.list != l || l.root.next == e { | ||||
| 		return | ||||
| 	} | ||||
| 	// see comment in List.Remove about initialization of l | ||||
| 	l.move(e, &l.root) | ||||
| } | ||||
							
								
								
									
										250
									
								
								vendor/github.com/hashicorp/golang-lru/v2/lru.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										250
									
								
								vendor/github.com/hashicorp/golang-lru/v2/lru.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,250 +0,0 @@ | |||
| // Copyright (c) HashiCorp, Inc. | ||||
| // SPDX-License-Identifier: MPL-2.0 | ||||
| 
 | ||||
| package lru | ||||
| 
 | ||||
| import ( | ||||
| 	"sync" | ||||
| 
 | ||||
| 	"github.com/hashicorp/golang-lru/v2/simplelru" | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	// DefaultEvictedBufferSize defines the default buffer size to store evicted key/val | ||||
| 	DefaultEvictedBufferSize = 16 | ||||
| ) | ||||
| 
 | ||||
| // Cache is a thread-safe fixed size LRU cache. | ||||
| type Cache[K comparable, V any] struct { | ||||
| 	lru         *simplelru.LRU[K, V] | ||||
| 	evictedKeys []K | ||||
| 	evictedVals []V | ||||
| 	onEvictedCB func(k K, v V) | ||||
| 	lock        sync.RWMutex | ||||
| } | ||||
| 
 | ||||
| // New creates an LRU of the given size. | ||||
| func New[K comparable, V any](size int) (*Cache[K, V], error) { | ||||
| 	return NewWithEvict[K, V](size, nil) | ||||
| } | ||||
| 
 | ||||
| // NewWithEvict constructs a fixed size cache with the given eviction | ||||
| // callback. | ||||
| func NewWithEvict[K comparable, V any](size int, onEvicted func(key K, value V)) (c *Cache[K, V], err error) { | ||||
| 	// create a cache with default settings | ||||
| 	c = &Cache[K, V]{ | ||||
| 		onEvictedCB: onEvicted, | ||||
| 	} | ||||
| 	if onEvicted != nil { | ||||
| 		c.initEvictBuffers() | ||||
| 		onEvicted = c.onEvicted | ||||
| 	} | ||||
| 	c.lru, err = simplelru.NewLRU(size, onEvicted) | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (c *Cache[K, V]) initEvictBuffers() { | ||||
| 	c.evictedKeys = make([]K, 0, DefaultEvictedBufferSize) | ||||
| 	c.evictedVals = make([]V, 0, DefaultEvictedBufferSize) | ||||
| } | ||||
| 
 | ||||
| // onEvicted save evicted key/val and sent in externally registered callback | ||||
| // outside of critical section | ||||
| func (c *Cache[K, V]) onEvicted(k K, v V) { | ||||
| 	c.evictedKeys = append(c.evictedKeys, k) | ||||
| 	c.evictedVals = append(c.evictedVals, v) | ||||
| } | ||||
| 
 | ||||
| // Purge is used to completely clear the cache. | ||||
| func (c *Cache[K, V]) Purge() { | ||||
| 	var ks []K | ||||
| 	var vs []V | ||||
| 	c.lock.Lock() | ||||
| 	c.lru.Purge() | ||||
| 	if c.onEvictedCB != nil && len(c.evictedKeys) > 0 { | ||||
| 		ks, vs = c.evictedKeys, c.evictedVals | ||||
| 		c.initEvictBuffers() | ||||
| 	} | ||||
| 	c.lock.Unlock() | ||||
| 	// invoke callback outside of critical section | ||||
| 	if c.onEvictedCB != nil { | ||||
| 		for i := 0; i < len(ks); i++ { | ||||
| 			c.onEvictedCB(ks[i], vs[i]) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Add adds a value to the cache. Returns true if an eviction occurred. | ||||
| func (c *Cache[K, V]) Add(key K, value V) (evicted bool) { | ||||
| 	var k K | ||||
| 	var v V | ||||
| 	c.lock.Lock() | ||||
| 	evicted = c.lru.Add(key, value) | ||||
| 	if c.onEvictedCB != nil && evicted { | ||||
| 		k, v = c.evictedKeys[0], c.evictedVals[0] | ||||
| 		c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0] | ||||
| 	} | ||||
| 	c.lock.Unlock() | ||||
| 	if c.onEvictedCB != nil && evicted { | ||||
| 		c.onEvictedCB(k, v) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Get looks up a key's value from the cache. | ||||
| func (c *Cache[K, V]) Get(key K) (value V, ok bool) { | ||||
| 	c.lock.Lock() | ||||
| 	value, ok = c.lru.Get(key) | ||||
| 	c.lock.Unlock() | ||||
| 	return value, ok | ||||
| } | ||||
| 
 | ||||
| // Contains checks if a key is in the cache, without updating the | ||||
| // recent-ness or deleting it for being stale. | ||||
| func (c *Cache[K, V]) Contains(key K) bool { | ||||
| 	c.lock.RLock() | ||||
| 	containKey := c.lru.Contains(key) | ||||
| 	c.lock.RUnlock() | ||||
| 	return containKey | ||||
| } | ||||
| 
 | ||||
| // Peek returns the key value (or undefined if not found) without updating | ||||
| // the "recently used"-ness of the key. | ||||
| func (c *Cache[K, V]) Peek(key K) (value V, ok bool) { | ||||
| 	c.lock.RLock() | ||||
| 	value, ok = c.lru.Peek(key) | ||||
| 	c.lock.RUnlock() | ||||
| 	return value, ok | ||||
| } | ||||
| 
 | ||||
| // ContainsOrAdd checks if a key is in the cache without updating the | ||||
| // recent-ness or deleting it for being stale, and if not, adds the value. | ||||
| // Returns whether found and whether an eviction occurred. | ||||
| func (c *Cache[K, V]) ContainsOrAdd(key K, value V) (ok, evicted bool) { | ||||
| 	var k K | ||||
| 	var v V | ||||
| 	c.lock.Lock() | ||||
| 	if c.lru.Contains(key) { | ||||
| 		c.lock.Unlock() | ||||
| 		return true, false | ||||
| 	} | ||||
| 	evicted = c.lru.Add(key, value) | ||||
| 	if c.onEvictedCB != nil && evicted { | ||||
| 		k, v = c.evictedKeys[0], c.evictedVals[0] | ||||
| 		c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0] | ||||
| 	} | ||||
| 	c.lock.Unlock() | ||||
| 	if c.onEvictedCB != nil && evicted { | ||||
| 		c.onEvictedCB(k, v) | ||||
| 	} | ||||
| 	return false, evicted | ||||
| } | ||||
| 
 | ||||
| // PeekOrAdd checks if a key is in the cache without updating the | ||||
| // recent-ness or deleting it for being stale, and if not, adds the value. | ||||
| // Returns whether found and whether an eviction occurred. | ||||
| func (c *Cache[K, V]) PeekOrAdd(key K, value V) (previous V, ok, evicted bool) { | ||||
| 	var k K | ||||
| 	var v V | ||||
| 	c.lock.Lock() | ||||
| 	previous, ok = c.lru.Peek(key) | ||||
| 	if ok { | ||||
| 		c.lock.Unlock() | ||||
| 		return previous, true, false | ||||
| 	} | ||||
| 	evicted = c.lru.Add(key, value) | ||||
| 	if c.onEvictedCB != nil && evicted { | ||||
| 		k, v = c.evictedKeys[0], c.evictedVals[0] | ||||
| 		c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0] | ||||
| 	} | ||||
| 	c.lock.Unlock() | ||||
| 	if c.onEvictedCB != nil && evicted { | ||||
| 		c.onEvictedCB(k, v) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Remove removes the provided key from the cache. | ||||
| func (c *Cache[K, V]) Remove(key K) (present bool) { | ||||
| 	var k K | ||||
| 	var v V | ||||
| 	c.lock.Lock() | ||||
| 	present = c.lru.Remove(key) | ||||
| 	if c.onEvictedCB != nil && present { | ||||
| 		k, v = c.evictedKeys[0], c.evictedVals[0] | ||||
| 		c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0] | ||||
| 	} | ||||
| 	c.lock.Unlock() | ||||
| 	if c.onEvictedCB != nil && present { | ||||
| 		c.onEvictedCB(k, v) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Resize changes the cache size. | ||||
| func (c *Cache[K, V]) Resize(size int) (evicted int) { | ||||
| 	var ks []K | ||||
| 	var vs []V | ||||
| 	c.lock.Lock() | ||||
| 	evicted = c.lru.Resize(size) | ||||
| 	if c.onEvictedCB != nil && evicted > 0 { | ||||
| 		ks, vs = c.evictedKeys, c.evictedVals | ||||
| 		c.initEvictBuffers() | ||||
| 	} | ||||
| 	c.lock.Unlock() | ||||
| 	if c.onEvictedCB != nil && evicted > 0 { | ||||
| 		for i := 0; i < len(ks); i++ { | ||||
| 			c.onEvictedCB(ks[i], vs[i]) | ||||
| 		} | ||||
| 	} | ||||
| 	return evicted | ||||
| } | ||||
| 
 | ||||
| // RemoveOldest removes the oldest item from the cache. | ||||
| func (c *Cache[K, V]) RemoveOldest() (key K, value V, ok bool) { | ||||
| 	var k K | ||||
| 	var v V | ||||
| 	c.lock.Lock() | ||||
| 	key, value, ok = c.lru.RemoveOldest() | ||||
| 	if c.onEvictedCB != nil && ok { | ||||
| 		k, v = c.evictedKeys[0], c.evictedVals[0] | ||||
| 		c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0] | ||||
| 	} | ||||
| 	c.lock.Unlock() | ||||
| 	if c.onEvictedCB != nil && ok { | ||||
| 		c.onEvictedCB(k, v) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // GetOldest returns the oldest entry | ||||
| func (c *Cache[K, V]) GetOldest() (key K, value V, ok bool) { | ||||
| 	c.lock.RLock() | ||||
| 	key, value, ok = c.lru.GetOldest() | ||||
| 	c.lock.RUnlock() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Keys returns a slice of the keys in the cache, from oldest to newest. | ||||
| func (c *Cache[K, V]) Keys() []K { | ||||
| 	c.lock.RLock() | ||||
| 	keys := c.lru.Keys() | ||||
| 	c.lock.RUnlock() | ||||
| 	return keys | ||||
| } | ||||
| 
 | ||||
| // Values returns a slice of the values in the cache, from oldest to newest. | ||||
| func (c *Cache[K, V]) Values() []V { | ||||
| 	c.lock.RLock() | ||||
| 	values := c.lru.Values() | ||||
| 	c.lock.RUnlock() | ||||
| 	return values | ||||
| } | ||||
| 
 | ||||
| // Len returns the number of items in the cache. | ||||
| func (c *Cache[K, V]) Len() int { | ||||
| 	c.lock.RLock() | ||||
| 	length := c.lru.Len() | ||||
| 	c.lock.RUnlock() | ||||
| 	return length | ||||
| } | ||||
							
								
								
									
										29
									
								
								vendor/github.com/hashicorp/golang-lru/v2/simplelru/LICENSE_list
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										29
									
								
								vendor/github.com/hashicorp/golang-lru/v2/simplelru/LICENSE_list
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,29 +0,0 @@ | |||
| This license applies to simplelru/list.go | ||||
| 
 | ||||
| Copyright (c) 2009 The Go Authors. All rights reserved. | ||||
| 
 | ||||
| Redistribution and use in source and binary forms, with or without | ||||
| modification, are permitted provided that the following conditions are | ||||
| met: | ||||
| 
 | ||||
|    * Redistributions of source code must retain the above copyright | ||||
| notice, this list of conditions and the following disclaimer. | ||||
|    * Redistributions in binary form must reproduce the above | ||||
| copyright notice, this list of conditions and the following disclaimer | ||||
| in the documentation and/or other materials provided with the | ||||
| distribution. | ||||
|    * Neither the name of Google Inc. nor the names of its | ||||
| contributors may be used to endorse or promote products derived from | ||||
| this software without specific prior written permission. | ||||
| 
 | ||||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||
| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||
| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
							
								
								
									
										177
									
								
								vendor/github.com/hashicorp/golang-lru/v2/simplelru/lru.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										177
									
								
								vendor/github.com/hashicorp/golang-lru/v2/simplelru/lru.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,177 +0,0 @@ | |||
| // Copyright (c) HashiCorp, Inc. | ||||
| // SPDX-License-Identifier: MPL-2.0 | ||||
| 
 | ||||
| package simplelru | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 
 | ||||
| 	"github.com/hashicorp/golang-lru/v2/internal" | ||||
| ) | ||||
| 
 | ||||
| // EvictCallback is used to get a callback when a cache entry is evicted | ||||
| type EvictCallback[K comparable, V any] func(key K, value V) | ||||
| 
 | ||||
| // LRU implements a non-thread safe fixed size LRU cache | ||||
| type LRU[K comparable, V any] struct { | ||||
| 	size      int | ||||
| 	evictList *internal.LruList[K, V] | ||||
| 	items     map[K]*internal.Entry[K, V] | ||||
| 	onEvict   EvictCallback[K, V] | ||||
| } | ||||
| 
 | ||||
| // NewLRU constructs an LRU of the given size | ||||
| func NewLRU[K comparable, V any](size int, onEvict EvictCallback[K, V]) (*LRU[K, V], error) { | ||||
| 	if size <= 0 { | ||||
| 		return nil, errors.New("must provide a positive size") | ||||
| 	} | ||||
| 
 | ||||
| 	c := &LRU[K, V]{ | ||||
| 		size:      size, | ||||
| 		evictList: internal.NewList[K, V](), | ||||
| 		items:     make(map[K]*internal.Entry[K, V]), | ||||
| 		onEvict:   onEvict, | ||||
| 	} | ||||
| 	return c, nil | ||||
| } | ||||
| 
 | ||||
| // Purge is used to completely clear the cache. | ||||
| func (c *LRU[K, V]) Purge() { | ||||
| 	for k, v := range c.items { | ||||
| 		if c.onEvict != nil { | ||||
| 			c.onEvict(k, v.Value) | ||||
| 		} | ||||
| 		delete(c.items, k) | ||||
| 	} | ||||
| 	c.evictList.Init() | ||||
| } | ||||
| 
 | ||||
| // Add adds a value to the cache.  Returns true if an eviction occurred. | ||||
| func (c *LRU[K, V]) Add(key K, value V) (evicted bool) { | ||||
| 	// Check for existing item | ||||
| 	if ent, ok := c.items[key]; ok { | ||||
| 		c.evictList.MoveToFront(ent) | ||||
| 		ent.Value = value | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	// Add new item | ||||
| 	ent := c.evictList.PushFront(key, value) | ||||
| 	c.items[key] = ent | ||||
| 
 | ||||
| 	evict := c.evictList.Length() > c.size | ||||
| 	// Verify size not exceeded | ||||
| 	if evict { | ||||
| 		c.removeOldest() | ||||
| 	} | ||||
| 	return evict | ||||
| } | ||||
| 
 | ||||
| // Get looks up a key's value from the cache. | ||||
| func (c *LRU[K, V]) Get(key K) (value V, ok bool) { | ||||
| 	if ent, ok := c.items[key]; ok { | ||||
| 		c.evictList.MoveToFront(ent) | ||||
| 		return ent.Value, true | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Contains checks if a key is in the cache, without updating the recent-ness | ||||
| // or deleting it for being stale. | ||||
| func (c *LRU[K, V]) Contains(key K) (ok bool) { | ||||
| 	_, ok = c.items[key] | ||||
| 	return ok | ||||
| } | ||||
| 
 | ||||
| // Peek returns the key value (or undefined if not found) without updating | ||||
| // the "recently used"-ness of the key. | ||||
| func (c *LRU[K, V]) Peek(key K) (value V, ok bool) { | ||||
| 	var ent *internal.Entry[K, V] | ||||
| 	if ent, ok = c.items[key]; ok { | ||||
| 		return ent.Value, true | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Remove removes the provided key from the cache, returning if the | ||||
| // key was contained. | ||||
| func (c *LRU[K, V]) Remove(key K) (present bool) { | ||||
| 	if ent, ok := c.items[key]; ok { | ||||
| 		c.removeElement(ent) | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // RemoveOldest removes the oldest item from the cache. | ||||
| func (c *LRU[K, V]) RemoveOldest() (key K, value V, ok bool) { | ||||
| 	if ent := c.evictList.Back(); ent != nil { | ||||
| 		c.removeElement(ent) | ||||
| 		return ent.Key, ent.Value, true | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // GetOldest returns the oldest entry | ||||
| func (c *LRU[K, V]) GetOldest() (key K, value V, ok bool) { | ||||
| 	if ent := c.evictList.Back(); ent != nil { | ||||
| 		return ent.Key, ent.Value, true | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Keys returns a slice of the keys in the cache, from oldest to newest. | ||||
| func (c *LRU[K, V]) Keys() []K { | ||||
| 	keys := make([]K, c.evictList.Length()) | ||||
| 	i := 0 | ||||
| 	for ent := c.evictList.Back(); ent != nil; ent = ent.PrevEntry() { | ||||
| 		keys[i] = ent.Key | ||||
| 		i++ | ||||
| 	} | ||||
| 	return keys | ||||
| } | ||||
| 
 | ||||
| // Values returns a slice of the values in the cache, from oldest to newest. | ||||
| func (c *LRU[K, V]) Values() []V { | ||||
| 	values := make([]V, len(c.items)) | ||||
| 	i := 0 | ||||
| 	for ent := c.evictList.Back(); ent != nil; ent = ent.PrevEntry() { | ||||
| 		values[i] = ent.Value | ||||
| 		i++ | ||||
| 	} | ||||
| 	return values | ||||
| } | ||||
| 
 | ||||
| // Len returns the number of items in the cache. | ||||
| func (c *LRU[K, V]) Len() int { | ||||
| 	return c.evictList.Length() | ||||
| } | ||||
| 
 | ||||
| // Resize changes the cache size. | ||||
| func (c *LRU[K, V]) Resize(size int) (evicted int) { | ||||
| 	diff := c.Len() - size | ||||
| 	if diff < 0 { | ||||
| 		diff = 0 | ||||
| 	} | ||||
| 	for i := 0; i < diff; i++ { | ||||
| 		c.removeOldest() | ||||
| 	} | ||||
| 	c.size = size | ||||
| 	return diff | ||||
| } | ||||
| 
 | ||||
| // removeOldest removes the oldest item from the cache. | ||||
| func (c *LRU[K, V]) removeOldest() { | ||||
| 	if ent := c.evictList.Back(); ent != nil { | ||||
| 		c.removeElement(ent) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // removeElement is used to remove a given list element from the cache | ||||
| func (c *LRU[K, V]) removeElement(e *internal.Entry[K, V]) { | ||||
| 	c.evictList.Remove(e) | ||||
| 	delete(c.items, e.Key) | ||||
| 	if c.onEvict != nil { | ||||
| 		c.onEvict(e.Key, e.Value) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										46
									
								
								vendor/github.com/hashicorp/golang-lru/v2/simplelru/lru_interface.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										46
									
								
								vendor/github.com/hashicorp/golang-lru/v2/simplelru/lru_interface.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,46 +0,0 @@ | |||
| // Copyright (c) HashiCorp, Inc. | ||||
| // SPDX-License-Identifier: MPL-2.0 | ||||
| 
 | ||||
| // Package simplelru provides simple LRU implementation based on build-in container/list. | ||||
| package simplelru | ||||
| 
 | ||||
| // LRUCache is the interface for simple LRU cache. | ||||
| type LRUCache[K comparable, V any] interface { | ||||
| 	// Adds a value to the cache, returns true if an eviction occurred and | ||||
| 	// updates the "recently used"-ness of the key. | ||||
| 	Add(key K, value V) bool | ||||
| 
 | ||||
| 	// Returns key's value from the cache and | ||||
| 	// updates the "recently used"-ness of the key. #value, isFound | ||||
| 	Get(key K) (value V, ok bool) | ||||
| 
 | ||||
| 	// Checks if a key exists in cache without updating the recent-ness. | ||||
| 	Contains(key K) (ok bool) | ||||
| 
 | ||||
| 	// Returns key's value without updating the "recently used"-ness of the key. | ||||
| 	Peek(key K) (value V, ok bool) | ||||
| 
 | ||||
| 	// Removes a key from the cache. | ||||
| 	Remove(key K) bool | ||||
| 
 | ||||
| 	// Removes the oldest entry from cache. | ||||
| 	RemoveOldest() (K, V, bool) | ||||
| 
 | ||||
| 	// Returns the oldest entry from the cache. #key, value, isFound | ||||
| 	GetOldest() (K, V, bool) | ||||
| 
 | ||||
| 	// Returns a slice of the keys in the cache, from oldest to newest. | ||||
| 	Keys() []K | ||||
| 
 | ||||
| 	// Values returns a slice of the values in the cache, from oldest to newest. | ||||
| 	Values() []V | ||||
| 
 | ||||
| 	// Returns the number of items in the cache. | ||||
| 	Len() int | ||||
| 
 | ||||
| 	// Clears all cache entries. | ||||
| 	Purge() | ||||
| 
 | ||||
| 	// Resizes cache, returning number evicted | ||||
| 	Resize(int) int | ||||
| } | ||||
							
								
								
									
										27
									
								
								vendor/modernc.org/gc/v3/GO-LICENSE
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										27
									
								
								vendor/modernc.org/gc/v3/GO-LICENSE
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,27 +0,0 @@ | |||
| Copyright (c) 2009 The Go Authors. All rights reserved. | ||||
| 
 | ||||
| Redistribution and use in source and binary forms, with or without | ||||
| modification, are permitted provided that the following conditions are | ||||
| met: | ||||
| 
 | ||||
|    * Redistributions of source code must retain the above copyright | ||||
| notice, this list of conditions and the following disclaimer. | ||||
|    * Redistributions in binary form must reproduce the above | ||||
| copyright notice, this list of conditions and the following disclaimer | ||||
| in the documentation and/or other materials provided with the | ||||
| distribution. | ||||
|    * Neither the name of Google Inc. nor the names of its | ||||
| contributors may be used to endorse or promote products derived from | ||||
| this software without specific prior written permission. | ||||
| 
 | ||||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||
| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||
| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
							
								
								
									
										69
									
								
								vendor/modernc.org/gc/v3/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										69
									
								
								vendor/modernc.org/gc/v3/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,69 +0,0 @@ | |||
| ------------------------------------------------------------------------------- | ||||
| Copyright (c) 2016 The GC Authors. All rights reserved. | ||||
| 
 | ||||
| Redistribution and use in source and binary forms, with or without | ||||
| modification, are permitted provided that the following conditions are | ||||
| met: | ||||
| 
 | ||||
|    * Redistributions of source code must retain the above copyright | ||||
| notice, this list of conditions and the following disclaimer. | ||||
|    * Redistributions in binary form must reproduce the above | ||||
| copyright notice, this list of conditions and the following disclaimer | ||||
| in the documentation and/or other materials provided with the | ||||
| distribution. | ||||
|    * Neither the names of the authors nor the names of the | ||||
| contributors may be used to endorse or promote products derived from | ||||
| this software without specific prior written permission. | ||||
| 
 | ||||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||
| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||
| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
| ------------------------------------------------------------------------------- | ||||
| 
 | ||||
| Code in this repository contains or may contain | ||||
| 
 | ||||
| 	- copied original code from | ||||
| 	- code based on original code from | ||||
| 	- code inspired by original code in | ||||
| 
 | ||||
|     "The Go Programming Language" project at https://go.googlesource.com/go/. | ||||
| 
 | ||||
| Copy of the license of the original code follows below | ||||
| 
 | ||||
| ------------------------------------------------------------------------------- | ||||
| Copyright (c) 2009 The Go Authors. All rights reserved. | ||||
| 
 | ||||
| Redistribution and use in source and binary forms, with or without | ||||
| modification, are permitted provided that the following conditions are | ||||
| met: | ||||
| 
 | ||||
|    * Redistributions of source code must retain the above copyright | ||||
| notice, this list of conditions and the following disclaimer. | ||||
|    * Redistributions in binary form must reproduce the above | ||||
| copyright notice, this list of conditions and the following disclaimer | ||||
| in the documentation and/or other materials provided with the | ||||
| distribution. | ||||
|    * Neither the name of Google Inc. nor the names of its | ||||
| contributors may be used to endorse or promote products derived from | ||||
| this software without specific prior written permission. | ||||
| 
 | ||||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||
| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||
| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
| ------------------------------------------------------------------------------- | ||||
							
								
								
									
										113
									
								
								vendor/modernc.org/gc/v3/Makefile
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										113
									
								
								vendor/modernc.org/gc/v3/Makefile
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,113 +0,0 @@ | |||
| .PHONY:	all clean edit editor test test2 back report report2 parser2 benchmarks benchmarks2 mem memgo race nreport build_all_targets | ||||
| 
 | ||||
| all: | ||||
| 
 | ||||
| build_all_targets: | ||||
| 	GOOS=darwin GOARCH=amd64 go test -c -o /dev/null | ||||
| 	GOOS=darwin GOARCH=arm64 go test -c -o /dev/null | ||||
| 	GOOS=freebsd GOARCH=386 go test -c -o /dev/null | ||||
| 	GOOS=freebsd GOARCH=amd64 go test -c -o /dev/null | ||||
| 	GOOS=freebsd GOARCH=arm go test -c -o /dev/null | ||||
| 	GOOS=freebsd GOARCH=arm64 go test -c -o /dev/null | ||||
| 	GOOS=illumos GOARCH=amd64 go test -c -o /dev/null | ||||
| 	GOOS=linux GOARCH=386 go test -c -o /dev/null | ||||
| 	GOOS=linux GOARCH=amd64 go test -c -o /dev/null | ||||
| 	GOOS=linux GOARCH=arm go test -c -o /dev/null | ||||
| 	GOOS=linux GOARCH=arm64 go test -c -o /dev/null | ||||
| 	GOOS=linux GOARCH=ppc64le go test -c -o /dev/null | ||||
| 	GOOS=linux GOARCH=riscv64 go test -c -o /dev/null | ||||
| 	GOOS=linux GOARCH=s390x go test -c -o /dev/null | ||||
| 	GOOS=netbsd GOARCH=386 go test -c -o /dev/null | ||||
| 	GOOS=netbsd GOARCH=amd64 go test -c -o /dev/null | ||||
| 	GOOS=netbsd GOARCH=arm go test -c -o /dev/null | ||||
| 	GOOS=openbsd GOARCH=386 go test -c -o /dev/null | ||||
| 	GOOS=openbsd GOARCH=amd64 go test -c -o /dev/null | ||||
| 	GOOS=openbsd GOARCH=arm64 go test -c -o /dev/null | ||||
| 	GOOS=windows GOARCH=386 go test -c -o /dev/null | ||||
| 	GOOS=windows GOARCH=amd64 go test -c -o /dev/null | ||||
| 	GOOS=windows GOARCH=arm64 go test -c -o /dev/null | ||||
| 
 | ||||
| clean: | ||||
| 	rm -f cpu.test mem.test *.out | ||||
| 	go clean | ||||
| 
 | ||||
| edit: | ||||
| 	@touch log | ||||
| 	@if [ -f "Session.vim" ]; then gvim -S & else gvim -p Makefile all_test.go gc.go & fi | ||||
| 
 | ||||
| editor: | ||||
| 	gofmt -l -s -w *.go | ||||
| 	go test -c -o /dev/null 2>&1 | tee log-editor | ||||
| 
 | ||||
| race: | ||||
| 	go test -v -failfast -heap -race 2>&1 | tee log-test | ||||
| 	@git diff testdata/ || true | ||||
| 	@git status | ||||
| 	@grep TOTAL log-test || true | ||||
| 	grep 'FAIL\|TODO' log-test || true | ||||
| 
 | ||||
| test: | ||||
| 	go test -v -failfast -trctodo -exterr -heap 2>&1 | tee log-test | ||||
| 	@git diff testdata/ || true | ||||
| 	@git status | ||||
| 	@grep TOTAL log-test || true | ||||
| 	grep 'FAIL\|TODO' log-test || true | ||||
| 
 | ||||
| test2: | ||||
| 	go test -v -failfast -trctodo -exterr -src $$HOME/src 2>&1 | tee log-test2 | ||||
| 	@git diff testdata/ || true | ||||
| 	@git status | ||||
| 	@grep TOTAL log-test2 || true | ||||
| 	grep 'FAIL\|TODO' log-test2 || true | ||||
| 
 | ||||
| parser2: | ||||
| 	go test -v -failfast -run TestParser -src $$HOME/src 2>&1 | tee log-parser2 | ||||
| 	@git diff testdata/ || true | ||||
| 	@git status | ||||
| 	@grep TOTAL log-parser2 || true | ||||
| 	grep 'FAIL\|TODO' log-parser2 || true | ||||
| 
 | ||||
| back: | ||||
| 	go test -v -failfast -noback 2>&1 | tee log-back | ||||
| 	@git diff testdata/ || true | ||||
| 	@git status | ||||
| 	@grep TOTAL log-back || true | ||||
| 	grep 'FAIL\|TODO' log-back || true | ||||
| 
 | ||||
| nreport: | ||||
| 	touch log-nreport | ||||
| 	cp log-nreport log-nreport0 | ||||
| 	go test -v -failfast -run TestParser -heap -nreport 2>&1 | tee log-nreport | ||||
| 	@git diff testdata/ || true | ||||
| 	@git status | ||||
| 	@grep TOTAL log-report || true | ||||
| 	grep 'FAIL\|TODO' log-report || true | ||||
| 
 | ||||
| report: | ||||
| 	go test -v -failfast -run TestParser -report 2>&1 | tee log-report | ||||
| 	@git diff testdata/ || true | ||||
| 	@git status | ||||
| 	@grep TOTAL log-report || true | ||||
| 	grep 'FAIL\|TODO' log-report || true | ||||
| 
 | ||||
| report2: | ||||
| 	go test -v -failfast -run TestParser -src $$HOME/src -report 2>&1 | tee log-report2 | ||||
| 	@git diff testdata/ || true | ||||
| 	@git status | ||||
| 	@grep TOTAL log-report2 || true | ||||
| 	grep 'FAIL\|TODO' log-report2 || true | ||||
| 
 | ||||
| 
 | ||||
| benchmarks: | ||||
| 	go test -v -run @ -bench . 2>&1 | tee log-benchmarks | ||||
| 
 | ||||
| benchmarks2: | ||||
| 	go test -v -run @ -bench . -bsrc $$HOME/src 2>&1 | tee log-benchmarks2 | ||||
| 
 | ||||
| mem: | ||||
| 	go test -run @ -bench BenchmarkParser -memprofile mem.out | ||||
| 	go tool pprof --lines --alloc_space *.test mem.out | ||||
| 
 | ||||
| memgo: | ||||
| 	go test -run @ -bench BenchmarkGoParser -memprofile mem.out | ||||
| 	go tool pprof --lines --alloc_space *.test mem.out | ||||
							
								
								
									
										682
									
								
								vendor/modernc.org/gc/v3/abi.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										682
									
								
								vendor/modernc.org/gc/v3/abi.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,682 +0,0 @@ | |||
| // Copyright 2022 The Gc Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| package gc // import "modernc.org/gc/v3" | ||||
| 
 | ||||
| import ( | ||||
| 	"encoding/binary" | ||||
| 	"fmt" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	byteOrders = map[string]binary.ByteOrder{ | ||||
| 		"386":     binary.LittleEndian, | ||||
| 		"amd64":   binary.LittleEndian, | ||||
| 		"arm":     binary.LittleEndian, | ||||
| 		"arm64":   binary.LittleEndian, | ||||
| 		"ppc64le": binary.LittleEndian, | ||||
| 		"riscv64": binary.LittleEndian, | ||||
| 		"s390x":   binary.BigEndian, | ||||
| 	} | ||||
| 
 | ||||
| 	abiTypes = map[[2]string]map[Kind]ABIType{ | ||||
| 		// go1.19.1 | ||||
| 		{"freebsd", "386"}: { | ||||
| 			Bool:          {1, 1, 1}, | ||||
| 			Chan:          {4, 4, 4}, | ||||
| 			Complex128:    {16, 4, 4}, | ||||
| 			Complex64:     {8, 4, 4}, | ||||
| 			Float32:       {4, 4, 4}, | ||||
| 			Float64:       {8, 4, 4}, | ||||
| 			Function:      {4, 4, 4}, | ||||
| 			Int:           {4, 4, 4}, | ||||
| 			Int16:         {2, 2, 2}, | ||||
| 			Int32:         {4, 4, 4}, | ||||
| 			Int64:         {8, 4, 4}, | ||||
| 			Int8:          {1, 1, 1}, | ||||
| 			Interface:     {8, 4, 4}, | ||||
| 			Map:           {4, 4, 4}, | ||||
| 			Pointer:       {4, 4, 4}, | ||||
| 			Slice:         {12, 4, 4}, | ||||
| 			String:        {8, 4, 4}, | ||||
| 			Uint:          {4, 4, 4}, | ||||
| 			Uint16:        {2, 2, 2}, | ||||
| 			Uint32:        {4, 4, 4}, | ||||
| 			Uint64:        {8, 4, 4}, | ||||
| 			Uint8:         {1, 1, 1}, | ||||
| 			Uintptr:       {4, 4, 4}, | ||||
| 			UnsafePointer: {4, 4, 4}, | ||||
| 		}, | ||||
| 		// go1.19.1 | ||||
| 		{"freebsd", "amd64"}: { | ||||
| 			Bool:          {1, 1, 1}, | ||||
| 			Chan:          {8, 8, 8}, | ||||
| 			Complex128:    {16, 8, 8}, | ||||
| 			Complex64:     {8, 4, 4}, | ||||
| 			Float32:       {4, 4, 4}, | ||||
| 			Float64:       {8, 8, 8}, | ||||
| 			Function:      {8, 8, 8}, | ||||
| 			Int:           {8, 8, 8}, | ||||
| 			Int16:         {2, 2, 2}, | ||||
| 			Int32:         {4, 4, 4}, | ||||
| 			Int64:         {8, 8, 8}, | ||||
| 			Int8:          {1, 1, 1}, | ||||
| 			Interface:     {16, 8, 8}, | ||||
| 			Map:           {8, 8, 8}, | ||||
| 			Pointer:       {8, 8, 8}, | ||||
| 			Slice:         {24, 8, 8}, | ||||
| 			String:        {16, 8, 8}, | ||||
| 			Uint:          {8, 8, 8}, | ||||
| 			Uint16:        {2, 2, 2}, | ||||
| 			Uint32:        {4, 4, 4}, | ||||
| 			Uint64:        {8, 8, 8}, | ||||
| 			Uint8:         {1, 1, 1}, | ||||
| 			Uintptr:       {8, 8, 8}, | ||||
| 			UnsafePointer: {8, 8, 8}, | ||||
| 		}, | ||||
| 		// go1.18.5 | ||||
| 		{"freebsd", "arm"}: { | ||||
| 			Bool:          {1, 1, 1}, | ||||
| 			Chan:          {4, 4, 4}, | ||||
| 			Complex128:    {16, 4, 4}, | ||||
| 			Complex64:     {8, 4, 4}, | ||||
| 			Float32:       {4, 4, 4}, | ||||
| 			Float64:       {8, 4, 4}, | ||||
| 			Function:      {4, 4, 4}, | ||||
| 			Int:           {4, 4, 4}, | ||||
| 			Int16:         {2, 2, 2}, | ||||
| 			Int32:         {4, 4, 4}, | ||||
| 			Int64:         {8, 4, 4}, | ||||
| 			Int8:          {1, 1, 1}, | ||||
| 			Interface:     {8, 4, 4}, | ||||
| 			Map:           {4, 4, 4}, | ||||
| 			Pointer:       {4, 4, 4}, | ||||
| 			Slice:         {12, 4, 4}, | ||||
| 			String:        {8, 4, 4}, | ||||
| 			Uint:          {4, 4, 4}, | ||||
| 			Uint16:        {2, 2, 2}, | ||||
| 			Uint32:        {4, 4, 4}, | ||||
| 			Uint64:        {8, 4, 4}, | ||||
| 			Uint8:         {1, 1, 1}, | ||||
| 			Uintptr:       {4, 4, 4}, | ||||
| 			UnsafePointer: {4, 4, 4}, | ||||
| 		}, | ||||
| 		// go1.19 | ||||
| 		{"freebsd", "arm64"}: { | ||||
| 			Bool:          {1, 1, 1}, | ||||
| 			Chan:          {8, 8, 8}, | ||||
| 			Complex128:    {16, 8, 8}, | ||||
| 			Complex64:     {8, 4, 4}, | ||||
| 			Float32:       {4, 4, 4}, | ||||
| 			Float64:       {8, 8, 8}, | ||||
| 			Function:      {8, 8, 8}, | ||||
| 			Int:           {8, 8, 8}, | ||||
| 			Int16:         {2, 2, 2}, | ||||
| 			Int32:         {4, 4, 4}, | ||||
| 			Int64:         {8, 8, 8}, | ||||
| 			Int8:          {1, 1, 1}, | ||||
| 			Interface:     {16, 8, 8}, | ||||
| 			Map:           {8, 8, 8}, | ||||
| 			Pointer:       {8, 8, 8}, | ||||
| 			Slice:         {24, 8, 8}, | ||||
| 			String:        {16, 8, 8}, | ||||
| 			Uint:          {8, 8, 8}, | ||||
| 			Uint16:        {2, 2, 2}, | ||||
| 			Uint32:        {4, 4, 4}, | ||||
| 			Uint64:        {8, 8, 8}, | ||||
| 			Uint8:         {1, 1, 1}, | ||||
| 			Uintptr:       {8, 8, 8}, | ||||
| 			UnsafePointer: {8, 8, 8}, | ||||
| 		}, | ||||
| 		// go1.19.1 | ||||
| 		{"darwin", "amd64"}: { | ||||
| 			Bool:          {1, 1, 1}, | ||||
| 			Chan:          {8, 8, 8}, | ||||
| 			Complex128:    {16, 8, 8}, | ||||
| 			Complex64:     {8, 4, 4}, | ||||
| 			Float32:       {4, 4, 4}, | ||||
| 			Float64:       {8, 8, 8}, | ||||
| 			Function:      {8, 8, 8}, | ||||
| 			Int:           {8, 8, 8}, | ||||
| 			Int16:         {2, 2, 2}, | ||||
| 			Int32:         {4, 4, 4}, | ||||
| 			Int64:         {8, 8, 8}, | ||||
| 			Int8:          {1, 1, 1}, | ||||
| 			Interface:     {16, 8, 8}, | ||||
| 			Map:           {8, 8, 8}, | ||||
| 			Pointer:       {8, 8, 8}, | ||||
| 			Slice:         {24, 8, 8}, | ||||
| 			String:        {16, 8, 8}, | ||||
| 			Uint:          {8, 8, 8}, | ||||
| 			Uint16:        {2, 2, 2}, | ||||
| 			Uint32:        {4, 4, 4}, | ||||
| 			Uint64:        {8, 8, 8}, | ||||
| 			Uint8:         {1, 1, 1}, | ||||
| 			Uintptr:       {8, 8, 8}, | ||||
| 			UnsafePointer: {8, 8, 8}, | ||||
| 		}, | ||||
| 		// go1.19.1 | ||||
| 		{"darwin", "arm64"}: { | ||||
| 			Bool:          {1, 1, 1}, | ||||
| 			Chan:          {8, 8, 8}, | ||||
| 			Complex128:    {16, 8, 8}, | ||||
| 			Complex64:     {8, 4, 4}, | ||||
| 			Float32:       {4, 4, 4}, | ||||
| 			Float64:       {8, 8, 8}, | ||||
| 			Function:      {8, 8, 8}, | ||||
| 			Int:           {8, 8, 8}, | ||||
| 			Int16:         {2, 2, 2}, | ||||
| 			Int32:         {4, 4, 4}, | ||||
| 			Int64:         {8, 8, 8}, | ||||
| 			Int8:          {1, 1, 1}, | ||||
| 			Interface:     {16, 8, 8}, | ||||
| 			Map:           {8, 8, 8}, | ||||
| 			Pointer:       {8, 8, 8}, | ||||
| 			Slice:         {24, 8, 8}, | ||||
| 			String:        {16, 8, 8}, | ||||
| 			Uint:          {8, 8, 8}, | ||||
| 			Uint16:        {2, 2, 2}, | ||||
| 			Uint32:        {4, 4, 4}, | ||||
| 			Uint64:        {8, 8, 8}, | ||||
| 			Uint8:         {1, 1, 1}, | ||||
| 			Uintptr:       {8, 8, 8}, | ||||
| 			UnsafePointer: {8, 8, 8}, | ||||
| 		}, | ||||
| 		// go1.19.1 | ||||
| 		{"linux", "386"}: { | ||||
| 			Bool:          {1, 1, 1}, | ||||
| 			Chan:          {4, 4, 4}, | ||||
| 			Complex128:    {16, 4, 4}, | ||||
| 			Complex64:     {8, 4, 4}, | ||||
| 			Float32:       {4, 4, 4}, | ||||
| 			Float64:       {8, 4, 4}, | ||||
| 			Function:      {4, 4, 4}, | ||||
| 			Int:           {4, 4, 4}, | ||||
| 			Int16:         {2, 2, 2}, | ||||
| 			Int32:         {4, 4, 4}, | ||||
| 			Int64:         {8, 4, 4}, | ||||
| 			Int8:          {1, 1, 1}, | ||||
| 			Interface:     {8, 4, 4}, | ||||
| 			Map:           {4, 4, 4}, | ||||
| 			Pointer:       {4, 4, 4}, | ||||
| 			Slice:         {12, 4, 4}, | ||||
| 			String:        {8, 4, 4}, | ||||
| 			Uint:          {4, 4, 4}, | ||||
| 			Uint16:        {2, 2, 2}, | ||||
| 			Uint32:        {4, 4, 4}, | ||||
| 			Uint64:        {8, 4, 4}, | ||||
| 			Uint8:         {1, 1, 1}, | ||||
| 			Uintptr:       {4, 4, 4}, | ||||
| 			UnsafePointer: {4, 4, 4}, | ||||
| 		}, | ||||
| 		// go1.19.1 | ||||
| 		{"linux", "amd64"}: { | ||||
| 			Bool:          {1, 1, 1}, | ||||
| 			Chan:          {8, 8, 8}, | ||||
| 			Complex128:    {16, 8, 8}, | ||||
| 			Complex64:     {8, 4, 4}, | ||||
| 			Float32:       {4, 4, 4}, | ||||
| 			Float64:       {8, 8, 8}, | ||||
| 			Function:      {8, 8, 8}, | ||||
| 			Int:           {8, 8, 8}, | ||||
| 			Int16:         {2, 2, 2}, | ||||
| 			Int32:         {4, 4, 4}, | ||||
| 			Int64:         {8, 8, 8}, | ||||
| 			Int8:          {1, 1, 1}, | ||||
| 			Interface:     {16, 8, 8}, | ||||
| 			Map:           {8, 8, 8}, | ||||
| 			Pointer:       {8, 8, 8}, | ||||
| 			Slice:         {24, 8, 8}, | ||||
| 			String:        {16, 8, 8}, | ||||
| 			Uint:          {8, 8, 8}, | ||||
| 			Uint16:        {2, 2, 2}, | ||||
| 			Uint32:        {4, 4, 4}, | ||||
| 			Uint64:        {8, 8, 8}, | ||||
| 			Uint8:         {1, 1, 1}, | ||||
| 			Uintptr:       {8, 8, 8}, | ||||
| 			UnsafePointer: {8, 8, 8}, | ||||
| 		}, | ||||
| 		// go1.19.1 | ||||
| 		{"linux", "arm"}: { | ||||
| 			Bool:          {1, 1, 1}, | ||||
| 			Chan:          {4, 4, 4}, | ||||
| 			Complex128:    {16, 4, 4}, | ||||
| 			Complex64:     {8, 4, 4}, | ||||
| 			Float32:       {4, 4, 4}, | ||||
| 			Float64:       {8, 4, 4}, | ||||
| 			Function:      {4, 4, 4}, | ||||
| 			Int:           {4, 4, 4}, | ||||
| 			Int16:         {2, 2, 2}, | ||||
| 			Int32:         {4, 4, 4}, | ||||
| 			Int64:         {8, 4, 4}, | ||||
| 			Int8:          {1, 1, 1}, | ||||
| 			Interface:     {8, 4, 4}, | ||||
| 			Map:           {4, 4, 4}, | ||||
| 			Pointer:       {4, 4, 4}, | ||||
| 			Slice:         {12, 4, 4}, | ||||
| 			String:        {8, 4, 4}, | ||||
| 			Uint:          {4, 4, 4}, | ||||
| 			Uint16:        {2, 2, 2}, | ||||
| 			Uint32:        {4, 4, 4}, | ||||
| 			Uint64:        {8, 4, 4}, | ||||
| 			Uint8:         {1, 1, 1}, | ||||
| 			Uintptr:       {4, 4, 4}, | ||||
| 			UnsafePointer: {4, 4, 4}, | ||||
| 		}, | ||||
| 		// go1.19.1 | ||||
| 		{"linux", "arm64"}: { | ||||
| 			Bool:          {1, 1, 1}, | ||||
| 			Chan:          {8, 8, 8}, | ||||
| 			Complex128:    {16, 8, 8}, | ||||
| 			Complex64:     {8, 4, 4}, | ||||
| 			Float32:       {4, 4, 4}, | ||||
| 			Float64:       {8, 8, 8}, | ||||
| 			Function:      {8, 8, 8}, | ||||
| 			Int:           {8, 8, 8}, | ||||
| 			Int16:         {2, 2, 2}, | ||||
| 			Int32:         {4, 4, 4}, | ||||
| 			Int64:         {8, 8, 8}, | ||||
| 			Int8:          {1, 1, 1}, | ||||
| 			Interface:     {16, 8, 8}, | ||||
| 			Map:           {8, 8, 8}, | ||||
| 			Pointer:       {8, 8, 8}, | ||||
| 			Slice:         {24, 8, 8}, | ||||
| 			String:        {16, 8, 8}, | ||||
| 			Uint:          {8, 8, 8}, | ||||
| 			Uint16:        {2, 2, 2}, | ||||
| 			Uint32:        {4, 4, 4}, | ||||
| 			Uint64:        {8, 8, 8}, | ||||
| 			Uint8:         {1, 1, 1}, | ||||
| 			Uintptr:       {8, 8, 8}, | ||||
| 			UnsafePointer: {8, 8, 8}, | ||||
| 		}, | ||||
| 		// go1.19.1 | ||||
| 		{"linux", "s390x"}: { | ||||
| 			Bool:          {1, 1, 1}, | ||||
| 			Chan:          {8, 8, 8}, | ||||
| 			Complex128:    {16, 8, 8}, | ||||
| 			Complex64:     {8, 4, 4}, | ||||
| 			Float32:       {4, 4, 4}, | ||||
| 			Float64:       {8, 8, 8}, | ||||
| 			Function:      {8, 8, 8}, | ||||
| 			Int:           {8, 8, 8}, | ||||
| 			Int16:         {2, 2, 2}, | ||||
| 			Int32:         {4, 4, 4}, | ||||
| 			Int64:         {8, 8, 8}, | ||||
| 			Int8:          {1, 1, 1}, | ||||
| 			Interface:     {16, 8, 8}, | ||||
| 			Map:           {8, 8, 8}, | ||||
| 			Pointer:       {8, 8, 8}, | ||||
| 			Slice:         {24, 8, 8}, | ||||
| 			String:        {16, 8, 8}, | ||||
| 			Uint:          {8, 8, 8}, | ||||
| 			Uint16:        {2, 2, 2}, | ||||
| 			Uint32:        {4, 4, 4}, | ||||
| 			Uint64:        {8, 8, 8}, | ||||
| 			Uint8:         {1, 1, 1}, | ||||
| 			Uintptr:       {8, 8, 8}, | ||||
| 			UnsafePointer: {8, 8, 8}, | ||||
| 		}, | ||||
| 		// go1.19.1 | ||||
| 		{"linux", "ppc64le"}: { | ||||
| 			Bool:          {1, 1, 1}, | ||||
| 			Chan:          {8, 8, 8}, | ||||
| 			Complex128:    {16, 8, 8}, | ||||
| 			Complex64:     {8, 4, 4}, | ||||
| 			Float32:       {4, 4, 4}, | ||||
| 			Float64:       {8, 8, 8}, | ||||
| 			Function:      {8, 8, 8}, | ||||
| 			Int:           {8, 8, 8}, | ||||
| 			Int16:         {2, 2, 2}, | ||||
| 			Int32:         {4, 4, 4}, | ||||
| 			Int64:         {8, 8, 8}, | ||||
| 			Int8:          {1, 1, 1}, | ||||
| 			Interface:     {16, 8, 8}, | ||||
| 			Map:           {8, 8, 8}, | ||||
| 			Pointer:       {8, 8, 8}, | ||||
| 			Slice:         {24, 8, 8}, | ||||
| 			String:        {16, 8, 8}, | ||||
| 			Uint:          {8, 8, 8}, | ||||
| 			Uint16:        {2, 2, 2}, | ||||
| 			Uint32:        {4, 4, 4}, | ||||
| 			Uint64:        {8, 8, 8}, | ||||
| 			Uint8:         {1, 1, 1}, | ||||
| 			Uintptr:       {8, 8, 8}, | ||||
| 			UnsafePointer: {8, 8, 8}, | ||||
| 		}, | ||||
| 		// go1.19.1 | ||||
| 		{"linux", "riscv64"}: { | ||||
| 			Bool:          {1, 1, 1}, | ||||
| 			Chan:          {8, 8, 8}, | ||||
| 			Complex128:    {16, 8, 8}, | ||||
| 			Complex64:     {8, 4, 4}, | ||||
| 			Float32:       {4, 4, 4}, | ||||
| 			Float64:       {8, 8, 8}, | ||||
| 			Function:      {8, 8, 8}, | ||||
| 			Int:           {8, 8, 8}, | ||||
| 			Int16:         {2, 2, 2}, | ||||
| 			Int32:         {4, 4, 4}, | ||||
| 			Int64:         {8, 8, 8}, | ||||
| 			Int8:          {1, 1, 1}, | ||||
| 			Interface:     {16, 8, 8}, | ||||
| 			Map:           {8, 8, 8}, | ||||
| 			Pointer:       {8, 8, 8}, | ||||
| 			Slice:         {24, 8, 8}, | ||||
| 			String:        {16, 8, 8}, | ||||
| 			Uint:          {8, 8, 8}, | ||||
| 			Uint16:        {2, 2, 2}, | ||||
| 			Uint32:        {4, 4, 4}, | ||||
| 			Uint64:        {8, 8, 8}, | ||||
| 			Uint8:         {1, 1, 1}, | ||||
| 			Uintptr:       {8, 8, 8}, | ||||
| 			UnsafePointer: {8, 8, 8}, | ||||
| 		}, | ||||
| 		// go1.18.3 | ||||
| 		{"netbsd", "386"}: { | ||||
| 			Bool:          {1, 1, 1}, | ||||
| 			Chan:          {4, 4, 4}, | ||||
| 			Complex128:    {16, 4, 4}, | ||||
| 			Complex64:     {8, 4, 4}, | ||||
| 			Float32:       {4, 4, 4}, | ||||
| 			Float64:       {8, 4, 4}, | ||||
| 			Function:      {4, 4, 4}, | ||||
| 			Int:           {4, 4, 4}, | ||||
| 			Int16:         {2, 2, 2}, | ||||
| 			Int32:         {4, 4, 4}, | ||||
| 			Int64:         {8, 4, 4}, | ||||
| 			Int8:          {1, 1, 1}, | ||||
| 			Interface:     {8, 4, 4}, | ||||
| 			Map:           {4, 4, 4}, | ||||
| 			Pointer:       {4, 4, 4}, | ||||
| 			Slice:         {12, 4, 4}, | ||||
| 			String:        {8, 4, 4}, | ||||
| 			Uint:          {4, 4, 4}, | ||||
| 			Uint16:        {2, 2, 2}, | ||||
| 			Uint32:        {4, 4, 4}, | ||||
| 			Uint64:        {8, 4, 4}, | ||||
| 			Uint8:         {1, 1, 1}, | ||||
| 			Uintptr:       {4, 4, 4}, | ||||
| 			UnsafePointer: {4, 4, 4}, | ||||
| 		}, | ||||
| 		// go1.18.3 | ||||
| 		{"netbsd", "amd64"}: { | ||||
| 			Bool:          {1, 1, 1}, | ||||
| 			Chan:          {8, 8, 8}, | ||||
| 			Complex128:    {16, 8, 8}, | ||||
| 			Complex64:     {8, 4, 4}, | ||||
| 			Float32:       {4, 4, 4}, | ||||
| 			Float64:       {8, 8, 8}, | ||||
| 			Function:      {8, 8, 8}, | ||||
| 			Int:           {8, 8, 8}, | ||||
| 			Int16:         {2, 2, 2}, | ||||
| 			Int32:         {4, 4, 4}, | ||||
| 			Int64:         {8, 8, 8}, | ||||
| 			Int8:          {1, 1, 1}, | ||||
| 			Interface:     {16, 8, 8}, | ||||
| 			Map:           {8, 8, 8}, | ||||
| 			Pointer:       {8, 8, 8}, | ||||
| 			Slice:         {24, 8, 8}, | ||||
| 			String:        {16, 8, 8}, | ||||
| 			Uint:          {8, 8, 8}, | ||||
| 			Uint16:        {2, 2, 2}, | ||||
| 			Uint32:        {4, 4, 4}, | ||||
| 			Uint64:        {8, 8, 8}, | ||||
| 			Uint8:         {1, 1, 1}, | ||||
| 			Uintptr:       {8, 8, 8}, | ||||
| 			UnsafePointer: {8, 8, 8}, | ||||
| 		}, | ||||
| 		// go1.18.3 | ||||
| 		{"netbsd", "arm"}: { | ||||
| 			Bool:          {1, 1, 1}, | ||||
| 			Chan:          {4, 4, 4}, | ||||
| 			Complex128:    {16, 4, 4}, | ||||
| 			Complex64:     {8, 4, 4}, | ||||
| 			Float32:       {4, 4, 4}, | ||||
| 			Float64:       {8, 4, 4}, | ||||
| 			Function:      {4, 4, 4}, | ||||
| 			Int:           {4, 4, 4}, | ||||
| 			Int16:         {2, 2, 2}, | ||||
| 			Int32:         {4, 4, 4}, | ||||
| 			Int64:         {8, 4, 4}, | ||||
| 			Int8:          {1, 1, 1}, | ||||
| 			Interface:     {8, 4, 4}, | ||||
| 			Map:           {4, 4, 4}, | ||||
| 			Pointer:       {4, 4, 4}, | ||||
| 			Slice:         {12, 4, 4}, | ||||
| 			String:        {8, 4, 4}, | ||||
| 			Uint:          {4, 4, 4}, | ||||
| 			Uint16:        {2, 2, 2}, | ||||
| 			Uint32:        {4, 4, 4}, | ||||
| 			Uint64:        {8, 4, 4}, | ||||
| 			Uint8:         {1, 1, 1}, | ||||
| 			Uintptr:       {4, 4, 4}, | ||||
| 			UnsafePointer: {4, 4, 4}, | ||||
| 		}, | ||||
| 		// go1.19 | ||||
| 		{"openbsd", "amd64"}: { | ||||
| 			Bool:          {1, 1, 1}, | ||||
| 			Chan:          {8, 8, 8}, | ||||
| 			Complex128:    {16, 8, 8}, | ||||
| 			Complex64:     {8, 4, 4}, | ||||
| 			Float32:       {4, 4, 4}, | ||||
| 			Float64:       {8, 8, 8}, | ||||
| 			Function:      {8, 8, 8}, | ||||
| 			Int:           {8, 8, 8}, | ||||
| 			Int16:         {2, 2, 2}, | ||||
| 			Int32:         {4, 4, 4}, | ||||
| 			Int64:         {8, 8, 8}, | ||||
| 			Int8:          {1, 1, 1}, | ||||
| 			Interface:     {16, 8, 8}, | ||||
| 			Map:           {8, 8, 8}, | ||||
| 			Pointer:       {8, 8, 8}, | ||||
| 			Slice:         {24, 8, 8}, | ||||
| 			String:        {16, 8, 8}, | ||||
| 			Uint:          {8, 8, 8}, | ||||
| 			Uint16:        {2, 2, 2}, | ||||
| 			Uint32:        {4, 4, 4}, | ||||
| 			Uint64:        {8, 8, 8}, | ||||
| 			Uint8:         {1, 1, 1}, | ||||
| 			Uintptr:       {8, 8, 8}, | ||||
| 			UnsafePointer: {8, 8, 8}, | ||||
| 		}, | ||||
| 		// go1.19 | ||||
| 		{"openbsd", "arm64"}: { | ||||
| 			Bool:          {1, 1, 1}, | ||||
| 			Chan:          {8, 8, 8}, | ||||
| 			Complex128:    {16, 8, 8}, | ||||
| 			Complex64:     {8, 4, 4}, | ||||
| 			Float32:       {4, 4, 4}, | ||||
| 			Float64:       {8, 8, 8}, | ||||
| 			Function:      {8, 8, 8}, | ||||
| 			Int:           {8, 8, 8}, | ||||
| 			Int16:         {2, 2, 2}, | ||||
| 			Int32:         {4, 4, 4}, | ||||
| 			Int64:         {8, 8, 8}, | ||||
| 			Int8:          {1, 1, 1}, | ||||
| 			Interface:     {16, 8, 8}, | ||||
| 			Map:           {8, 8, 8}, | ||||
| 			Pointer:       {8, 8, 8}, | ||||
| 			Slice:         {24, 8, 8}, | ||||
| 			String:        {16, 8, 8}, | ||||
| 			Uint:          {8, 8, 8}, | ||||
| 			Uint16:        {2, 2, 2}, | ||||
| 			Uint32:        {4, 4, 4}, | ||||
| 			Uint64:        {8, 8, 8}, | ||||
| 			Uint8:         {1, 1, 1}, | ||||
| 			Uintptr:       {8, 8, 8}, | ||||
| 			UnsafePointer: {8, 8, 8}, | ||||
| 		}, | ||||
| 		// go1.19 | ||||
| 		{"openbsd", "386"}: { | ||||
| 			Bool:          {1, 1, 1}, | ||||
| 			Chan:          {4, 4, 4}, | ||||
| 			Complex128:    {16, 4, 4}, | ||||
| 			Complex64:     {8, 4, 4}, | ||||
| 			Float32:       {4, 4, 4}, | ||||
| 			Float64:       {8, 4, 4}, | ||||
| 			Function:      {4, 4, 4}, | ||||
| 			Int:           {4, 4, 4}, | ||||
| 			Int16:         {2, 2, 2}, | ||||
| 			Int32:         {4, 4, 4}, | ||||
| 			Int64:         {8, 4, 4}, | ||||
| 			Int8:          {1, 1, 1}, | ||||
| 			Interface:     {8, 4, 4}, | ||||
| 			Map:           {4, 4, 4}, | ||||
| 			Pointer:       {4, 4, 4}, | ||||
| 			Slice:         {12, 4, 4}, | ||||
| 			String:        {8, 4, 4}, | ||||
| 			Uint:          {4, 4, 4}, | ||||
| 			Uint16:        {2, 2, 2}, | ||||
| 			Uint32:        {4, 4, 4}, | ||||
| 			Uint64:        {8, 4, 4}, | ||||
| 			Uint8:         {1, 1, 1}, | ||||
| 			Uintptr:       {4, 4, 4}, | ||||
| 			UnsafePointer: {4, 4, 4}, | ||||
| 		}, | ||||
| 		// go1.19.1 | ||||
| 		{"windows", "386"}: { | ||||
| 			Bool:          {1, 1, 1}, | ||||
| 			Chan:          {4, 4, 4}, | ||||
| 			Complex128:    {16, 4, 4}, | ||||
| 			Complex64:     {8, 4, 4}, | ||||
| 			Float32:       {4, 4, 4}, | ||||
| 			Float64:       {8, 4, 4}, | ||||
| 			Function:      {4, 4, 4}, | ||||
| 			Int:           {4, 4, 4}, | ||||
| 			Int16:         {2, 2, 2}, | ||||
| 			Int32:         {4, 4, 4}, | ||||
| 			Int64:         {8, 4, 4}, | ||||
| 			Int8:          {1, 1, 1}, | ||||
| 			Interface:     {8, 4, 4}, | ||||
| 			Map:           {4, 4, 4}, | ||||
| 			Pointer:       {4, 4, 4}, | ||||
| 			Slice:         {12, 4, 4}, | ||||
| 			String:        {8, 4, 4}, | ||||
| 			Uint:          {4, 4, 4}, | ||||
| 			Uint16:        {2, 2, 2}, | ||||
| 			Uint32:        {4, 4, 4}, | ||||
| 			Uint64:        {8, 4, 4}, | ||||
| 			Uint8:         {1, 1, 1}, | ||||
| 			Uintptr:       {4, 4, 4}, | ||||
| 			UnsafePointer: {4, 4, 4}, | ||||
| 		}, | ||||
| 		// go1.19.1 | ||||
| 		{"windows", "amd64"}: { | ||||
| 			Bool:          {1, 1, 1}, | ||||
| 			Chan:          {8, 8, 8}, | ||||
| 			Complex128:    {16, 8, 8}, | ||||
| 			Complex64:     {8, 4, 4}, | ||||
| 			Float32:       {4, 4, 4}, | ||||
| 			Float64:       {8, 8, 8}, | ||||
| 			Function:      {8, 8, 8}, | ||||
| 			Int:           {8, 8, 8}, | ||||
| 			Int16:         {2, 2, 2}, | ||||
| 			Int32:         {4, 4, 4}, | ||||
| 			Int64:         {8, 8, 8}, | ||||
| 			Int8:          {1, 1, 1}, | ||||
| 			Interface:     {16, 8, 8}, | ||||
| 			Map:           {8, 8, 8}, | ||||
| 			Pointer:       {8, 8, 8}, | ||||
| 			Slice:         {24, 8, 8}, | ||||
| 			String:        {16, 8, 8}, | ||||
| 			Uint:          {8, 8, 8}, | ||||
| 			Uint16:        {2, 2, 2}, | ||||
| 			Uint32:        {4, 4, 4}, | ||||
| 			Uint64:        {8, 8, 8}, | ||||
| 			Uint8:         {1, 1, 1}, | ||||
| 			Uintptr:       {8, 8, 8}, | ||||
| 			UnsafePointer: {8, 8, 8}, | ||||
| 		}, | ||||
| 		// go1.19.1 | ||||
| 		{"windows", "arm64"}: { | ||||
| 			Bool:          {1, 1, 1}, | ||||
| 			Chan:          {8, 8, 8}, | ||||
| 			Complex128:    {16, 8, 8}, | ||||
| 			Complex64:     {8, 4, 4}, | ||||
| 			Float32:       {4, 4, 4}, | ||||
| 			Float64:       {8, 8, 8}, | ||||
| 			Function:      {8, 8, 8}, | ||||
| 			Int:           {8, 8, 8}, | ||||
| 			Int16:         {2, 2, 2}, | ||||
| 			Int32:         {4, 4, 4}, | ||||
| 			Int64:         {8, 8, 8}, | ||||
| 			Int8:          {1, 1, 1}, | ||||
| 			Interface:     {16, 8, 8}, | ||||
| 			Map:           {8, 8, 8}, | ||||
| 			Pointer:       {8, 8, 8}, | ||||
| 			Slice:         {24, 8, 8}, | ||||
| 			String:        {16, 8, 8}, | ||||
| 			Uint:          {8, 8, 8}, | ||||
| 			Uint16:        {2, 2, 2}, | ||||
| 			Uint32:        {4, 4, 4}, | ||||
| 			Uint64:        {8, 8, 8}, | ||||
| 			Uint8:         {1, 1, 1}, | ||||
| 			Uintptr:       {8, 8, 8}, | ||||
| 			UnsafePointer: {8, 8, 8}, | ||||
| 		}, | ||||
| 		// go1.19.3 | ||||
| 		{"illumos", "amd64"}: { | ||||
| 			Bool:          {1, 1, 1}, | ||||
| 			Chan:          {8, 8, 8}, | ||||
| 			Complex128:    {16, 8, 8}, | ||||
| 			Complex64:     {8, 4, 4}, | ||||
| 			Float32:       {4, 4, 4}, | ||||
| 			Float64:       {8, 8, 8}, | ||||
| 			Function:      {8, 8, 8}, | ||||
| 			Int:           {8, 8, 8}, | ||||
| 			Int16:         {2, 2, 2}, | ||||
| 			Int32:         {4, 4, 4}, | ||||
| 			Int64:         {8, 8, 8}, | ||||
| 			Int8:          {1, 1, 1}, | ||||
| 			Interface:     {16, 8, 8}, | ||||
| 			Map:           {8, 8, 8}, | ||||
| 			Pointer:       {8, 8, 8}, | ||||
| 			Slice:         {24, 8, 8}, | ||||
| 			String:        {16, 8, 8}, | ||||
| 			Uint:          {8, 8, 8}, | ||||
| 			Uint16:        {2, 2, 2}, | ||||
| 			Uint32:        {4, 4, 4}, | ||||
| 			Uint64:        {8, 8, 8}, | ||||
| 			Uint8:         {1, 1, 1}, | ||||
| 			Uintptr:       {8, 8, 8}, | ||||
| 			UnsafePointer: {8, 8, 8}, | ||||
| 		}, | ||||
| 	} | ||||
| ) | ||||
| 
 | ||||
| // ABI describes selected parts of the Application Binary Interface. | ||||
| type ABI struct { | ||||
| 	ByteOrder binary.ByteOrder | ||||
| 	goarch    string | ||||
| 	goos      string | ||||
| 	Types     map[Kind]ABIType | ||||
| } | ||||
| 
 | ||||
| type ABIType struct { | ||||
| 	Size       int64 | ||||
| 	Align      int64 | ||||
| 	FieldAlign int64 | ||||
| } | ||||
| 
 | ||||
| // NewABI creates an ABI based on the os+arch pair. | ||||
| func NewABI(os, arch string) (*ABI, error) { | ||||
| 	byteOrder, ok := byteOrders[arch] | ||||
| 	if !ok { | ||||
| 		return nil, fmt.Errorf("unsupported arch: %s", arch) | ||||
| 	} | ||||
| 
 | ||||
| 	types0, ok := abiTypes[[2]string{os, arch}] | ||||
| 	if !ok { | ||||
| 		return nil, fmt.Errorf("unsupported os/arch: %s/%s", os, arch) | ||||
| 	} | ||||
| 
 | ||||
| 	types := make(map[Kind]ABIType, len(types0)) | ||||
| 	for k, v := range types0 { | ||||
| 		types[k] = v | ||||
| 	} | ||||
| 	return &ABI{ | ||||
| 		ByteOrder: byteOrder, | ||||
| 		Types:     types, | ||||
| 	}, nil | ||||
| } | ||||
							
								
								
									
										598
									
								
								vendor/modernc.org/gc/v3/check.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										598
									
								
								vendor/modernc.org/gc/v3/check.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,598 +0,0 @@ | |||
| // Copyright 2022 The Gc Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| package gc // modernc.org/gc/v3 | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"go/constant" | ||||
| 	"go/token" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| ) | ||||
| 
 | ||||
| type ctx struct { | ||||
| 	ast  *AST | ||||
| 	cfg  *Config | ||||
| 	errs errList | ||||
| 	iota int64 | ||||
| 	pkg  *Package | ||||
| 
 | ||||
| 	int32         Type // Set by newCtx | ||||
| 	untypedFloat  Type // Set by newCtx | ||||
| 	untypedInt    Type // Set by newCtx | ||||
| 	untypedString Type // Set by newCtx | ||||
| } | ||||
| 
 | ||||
| func newCtx(cfg *Config) (r *ctx) { | ||||
| 	r = &ctx{ | ||||
| 		cfg:  cfg, | ||||
| 		iota: -1, // -> Invalid | ||||
| 	} | ||||
| 	r.int32 = r.newPredeclaredType(znode, Int32) | ||||
| 	r.untypedFloat = r.newPredeclaredType(znode, UntypedFloat) | ||||
| 	r.untypedInt = r.newPredeclaredType(znode, UntypedInt) | ||||
| 	r.untypedString = r.newPredeclaredType(znode, UntypedString) | ||||
| 	return r | ||||
| } | ||||
| 
 | ||||
| func (c *ctx) err(n Node, msg string, args ...interface{}) { | ||||
| 	var pos token.Position | ||||
| 	if n != nil { | ||||
| 		pos = n.Position() | ||||
| 	} | ||||
| 	s := fmt.Sprintf(msg, args...) | ||||
| 	if trcTODOs && strings.HasPrefix(s, "TODO") { | ||||
| 		fmt.Fprintf(os.Stderr, "%v: %s (%v)\n", pos, s, origin(2)) | ||||
| 		os.Stderr.Sync() | ||||
| 	} | ||||
| 	switch { | ||||
| 	case extendedErrors: | ||||
| 		c.errs.err(pos, "%s (%v: %v: %v)", s, origin(4), origin(3), origin(2)) | ||||
| 	default: | ||||
| 		c.errs.err(pos, s) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (c *ctx) isBuiltin() bool { return c.pkg.Scope.kind == UniverseScope } | ||||
| func (c *ctx) isUnsafe() bool  { return c.pkg.isUnsafe } | ||||
| 
 | ||||
| func (c *ctx) lookup(sc *Scope, id Token) (pkg *Package, in *Scope, r named) { | ||||
| 	sc0 := sc | ||||
| 	pkg = c.pkg | ||||
| 	for { | ||||
| 		switch in, nm := sc.lookup(id); x := nm.n.(type) { | ||||
| 		case *TypeDefNode: | ||||
| 			if sc.kind == UniverseScope { | ||||
| 				if sc0.kind != UniverseScope && token.IsExported(id.Src()) { | ||||
| 					// trc("%v: %q %v %v", id.Position(), id.Src(), sc0.kind, sc.kind) | ||||
| 					return nil, nil, r | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			return x.pkg, in, nm | ||||
| 		default: | ||||
| 			panic(todo("%v: %q %T", id.Position(), id.Src(), x)) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (n *Package) check(c *ctx) (err error) { | ||||
| 	if n == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	c.pkg = n | ||||
| 	// trc("PKG %q", n.ImportPath) | ||||
| 	// defer func() { trc("PKG %q -> err: %v", n.ImportPath, err) }() | ||||
| 	for _, v := range n.GoFiles { | ||||
| 		path := filepath.Join(n.FSPath, v.Name()) | ||||
| 		n.AST[path].check(c) | ||||
| 	} | ||||
| 	return c.errs.Err() | ||||
| } | ||||
| 
 | ||||
| func (n *AST) check(c *ctx) { | ||||
| 	if n == nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	c.ast = n | ||||
| 	n.SourceFile.check(c) | ||||
| } | ||||
| 
 | ||||
| func (n *SourceFileNode) check(c *ctx) { | ||||
| 	if n == nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	n.PackageClause.check(c) | ||||
| 	for l := n.ImportDeclList; l != nil; l = l.List { | ||||
| 		l.ImportDecl.check(c) | ||||
| 	} | ||||
| 	for l := n.TopLevelDeclList; l != nil; l = l.List { | ||||
| 		switch x := l.TopLevelDecl.(type) { | ||||
| 		case *TypeDeclNode: | ||||
| 			x.check(c) | ||||
| 		case *ConstDeclNode: | ||||
| 			x.check(c) | ||||
| 		case *VarDeclNode: | ||||
| 			x.check(c) | ||||
| 		case *FunctionDeclNode: | ||||
| 			x.check(c) | ||||
| 		case *MethodDeclNode: | ||||
| 			x.check(c) | ||||
| 		default: | ||||
| 			panic(todo("%v: %T %s", x.Position(), x, x.Source(false))) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (n *MethodDeclNode) check(c *ctx) { | ||||
| 	if n == nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	n.Receiver.check(c) | ||||
| 	n.Signature.check(c) | ||||
| } | ||||
| 
 | ||||
| func (n *FunctionDeclNode) check(c *ctx) { | ||||
| 	if n == nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if c.isBuiltin() { | ||||
| 		switch nm := n.FunctionName.IDENT.Src(); nm { | ||||
| 		case | ||||
| 			"append", | ||||
| 			"cap", | ||||
| 			"close", | ||||
| 			"complex", | ||||
| 			"copy", | ||||
| 			"delete", | ||||
| 			"imag", | ||||
| 			"len", | ||||
| 			"make", | ||||
| 			"new", | ||||
| 			"panic", | ||||
| 			"print", | ||||
| 			"println", | ||||
| 			"real", | ||||
| 			"recover", | ||||
| 
 | ||||
| 			// Go 1.21 | ||||
| 			"max", | ||||
| 			"min", | ||||
| 			"clear": | ||||
| 
 | ||||
| 			n.Signature.t = c.newPredeclaredType(n, Function) | ||||
| 		default: | ||||
| 			panic(todo("%v: %q %s", n.Position(), nm, n.Source(false))) | ||||
| 		} | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	n.Signature.check(c) | ||||
| 	if n.TypeParameters != nil { | ||||
| 		panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (n *SignatureNode) check(c *ctx) Type { | ||||
| 	if n == nil { | ||||
| 		return Invalid | ||||
| 	} | ||||
| 
 | ||||
| 	if !n.enter(c, n) { | ||||
| 		return n.Type() | ||||
| 	} | ||||
| 
 | ||||
| 	in := n.Parameters.check(c) | ||||
| 	out := n.Result.check(c) | ||||
| 	return n.setType(newTupleType(n.Parameters, []Type{in, out})) | ||||
| } | ||||
| 
 | ||||
| func (n *ResultNode) check(c *ctx) Type { | ||||
| 	if n == nil { | ||||
| 		return Invalid | ||||
| 	} | ||||
| 
 | ||||
| 	switch { | ||||
| 	case n.Parameters != nil: | ||||
| 		return n.Parameters.check(c) | ||||
| 	case n.TypeNode != nil: | ||||
| 		return n.TypeNode.check(c) | ||||
| 	default: | ||||
| 		panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (n *ParametersNode) check(c *ctx) Type { | ||||
| 	if n == nil { | ||||
| 		return Invalid | ||||
| 	} | ||||
| 
 | ||||
| 	r := newTupleType(n, nil) | ||||
| 	for l := n.ParameterDeclList; l != nil; l = l.List { | ||||
| 		r.Types = append(r.Types, l.ParameterDecl.check(c)...) | ||||
| 	} | ||||
| 	return r | ||||
| } | ||||
| 
 | ||||
| func (n *ParameterDeclNode) check(c *ctx) (r []Type) { | ||||
| 	if n == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	t := n.TypeNode.check(c) | ||||
| 	for l := n.IdentifierList; l != nil; l = l.List { | ||||
| 		r = append(r, t) | ||||
| 	} | ||||
| 	return r | ||||
| } | ||||
| 
 | ||||
| func (n *VarDeclNode) check(c *ctx) { | ||||
| 	if n == nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	switch x := n.VarSpec.(type) { | ||||
| 	case *VarSpecNode: | ||||
| 		x.check(c) | ||||
| 	default: | ||||
| 		panic(todo("%v: %T %s", n.Position(), x, n.Source(false))) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (n *VarSpecNode) check(c *ctx) { | ||||
| 	if n == nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if c.isBuiltin() { | ||||
| 		switch nm := n.IDENT.Src(); nm { | ||||
| 		case "nil": | ||||
| 			n.TypeNode = c.newPredeclaredType(n, UntypedNil) | ||||
| 		default: | ||||
| 			panic(todo("%v: %q", n.IDENT.Position(), nm)) | ||||
| 		} | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if n.TypeNode != nil { | ||||
| 		c.err(n, "TODO %v", n.TypeNode.Source(false)) | ||||
| 	} | ||||
| 	var e []Expression | ||||
| 	for l := n.ExpressionList; l != nil; l = l.List { | ||||
| 		e = append(e, l.Expression.checkExpr(c)) | ||||
| 	} | ||||
| 	switch len(e) { | ||||
| 	default: | ||||
| 		panic(todo("", len(e))) | ||||
| 		c.err(n, "TODO %v", len(e)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (n *ConstDeclNode) check(c *ctx) { | ||||
| 	if n == nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	switch x := n.ConstSpec.(type) { | ||||
| 	case *ConstSpecListNode: | ||||
| 		var prev Node | ||||
| 		for l := x; l != nil; l = l.List { | ||||
| 			switch y := l.ConstSpec.(type) { | ||||
| 			case *ConstSpecNode: | ||||
| 				y.check(c, prev) | ||||
| 				if y.Expression != nil || y.TypeNode != nil { | ||||
| 					prev = y | ||||
| 				} | ||||
| 			default: | ||||
| 				panic(todo("%v: %T %s", n.Position(), y, n.Source(false))) | ||||
| 			} | ||||
| 		} | ||||
| 	case *ConstSpecNode: | ||||
| 		x.check(c, nil) | ||||
| 	default: | ||||
| 		panic(todo("%v: %T %s", n.Position(), x, n.Source(false))) | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| func (n *ConstSpecNode) check(c *ctx, prev Node) { | ||||
| 	if n == nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if !n.enter(c, n) { | ||||
| 		if n.guard == guardChecking { | ||||
| 			panic(todo("")) // report recursive | ||||
| 		} | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	defer func() { n.guard = guardChecked }() | ||||
| 
 | ||||
| 	if c.isBuiltin() { | ||||
| 		switch n.IDENT.Src() { | ||||
| 		case "true": | ||||
| 			switch x := n.Expression.(type) { | ||||
| 			case *BinaryExpressionNode: | ||||
| 				x.setValue(trueVal) | ||||
| 				x.setType(c.newPredeclaredType(x, UntypedBool)) | ||||
| 			default: | ||||
| 				panic(todo("%v: %T %s", n.Position(), x, n.Source(false))) | ||||
| 			} | ||||
| 		case "false": | ||||
| 			switch x := n.Expression.(type) { | ||||
| 			case *BinaryExpressionNode: | ||||
| 				x.setValue(falseVal) | ||||
| 				x.setType(c.newPredeclaredType(x, UntypedBool)) | ||||
| 			default: | ||||
| 				panic(todo("%v: %T %s", n.Position(), x, n.Source(false))) | ||||
| 			} | ||||
| 		case "iota": | ||||
| 			switch x := n.Expression.(type) { | ||||
| 			case *BasicLitNode: | ||||
| 				// ok | ||||
| 			default: | ||||
| 				panic(todo("%v: %T %s", n.Position(), x, n.Source(false))) | ||||
| 			} | ||||
| 		default: | ||||
| 			panic(todo("", n.Position(), n.Source(false))) | ||||
| 		} | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	save := c.iota | ||||
| 	c.iota = n.iota | ||||
| 
 | ||||
| 	defer func() { c.iota = save }() | ||||
| 
 | ||||
| 	switch { | ||||
| 	case n.Expression != nil: | ||||
| 		n.Expression = n.Expression.checkExpr(c) | ||||
| 		if n.TypeNode == nil { | ||||
| 			n.TypeNode = n.Expression.Type() | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		t := n.TypeNode.check(c) | ||||
| 		trc("", t) | ||||
| 		panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| 	default: | ||||
| 		// var e Expression | ||||
| 		// var pe *Expression | ||||
| 		// switch { | ||||
| 		// case n.Expression != nil: | ||||
| 		// 	e = n.Expression | ||||
| 		// 	pe = &n.Expression | ||||
| 		// default: | ||||
| 		// 	switch x := prev.(type) { | ||||
| 		// 	case *ConstSpecNode: | ||||
| 		// 		e = x.Expression.clone() | ||||
| 		// 		pe = &e | ||||
| 		// 	default: | ||||
| 		// 		panic(todo("%v: %T %s", n.Position(), x, n.Source(false))) | ||||
| 		// 	} | ||||
| 		// } | ||||
| 		// ev, et := e.checkExpr(c, pe) | ||||
| 		// e = *pe | ||||
| 		// if ev.Kind() == constant.Unknown { | ||||
| 		// 	c.err(e, "%s is not a constant", e.Source(false)) | ||||
| 		// 	n.t = Invalid | ||||
| 		// 	n.setValue(unknown) | ||||
| 		// 	return Invalid | ||||
| 		// } | ||||
| 		// switch { | ||||
| 		// case n.t == nil: | ||||
| 		// 	n.t = et | ||||
| 		// default: | ||||
| 
 | ||||
| 		// 		c.err(n.Expression, "cannot assign %v (type %v) to type %v", ev, et, n.Type()) | ||||
| 		// 		return Invalid | ||||
| 		// 	} else { | ||||
| 		// 		n.setValue(convertValue(c, e, ev, n.Type())) | ||||
| 		// 	} | ||||
| 		// } | ||||
| 		// return n.Type() | ||||
| 		panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| func (n *TypeDeclNode) check(c *ctx) { | ||||
| 	if n == nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	for l := n.TypeSpecList; l != nil; l = l.List { | ||||
| 		switch x := l.TypeSpec.(type) { | ||||
| 		case *TypeDefNode: | ||||
| 			switch { | ||||
| 			case c.isBuiltin(): | ||||
| 				x.pkg = c.pkg | ||||
| 				switch nm := x.IDENT.Src(); nm { | ||||
| 				case "bool": | ||||
| 					x.TypeNode = c.newPredeclaredType(x, Bool) | ||||
| 				case "int": | ||||
| 					x.TypeNode = c.newPredeclaredType(x, Int) | ||||
| 					c.cfg.int = x.TypeNode | ||||
| 				case "int8": | ||||
| 					x.TypeNode = c.newPredeclaredType(x, Int8) | ||||
| 				case "int16": | ||||
| 					x.TypeNode = c.newPredeclaredType(x, Int16) | ||||
| 				case "int32": | ||||
| 					x.TypeNode = c.newPredeclaredType(x, Int32) | ||||
| 				case "int64": | ||||
| 					x.TypeNode = c.newPredeclaredType(x, Int64) | ||||
| 				case "uint": | ||||
| 					x.TypeNode = c.newPredeclaredType(x, Uint) | ||||
| 					c.cfg.uint = x.TypeNode | ||||
| 				case "uint8": | ||||
| 					x.TypeNode = c.newPredeclaredType(x, Uint8) | ||||
| 				case "uint16": | ||||
| 					x.TypeNode = c.newPredeclaredType(x, Uint16) | ||||
| 				case "uint32": | ||||
| 					x.TypeNode = c.newPredeclaredType(x, Uint32) | ||||
| 				case "uint64": | ||||
| 					x.TypeNode = c.newPredeclaredType(x, Uint64) | ||||
| 				case "uintptr": | ||||
| 					x.TypeNode = c.newPredeclaredType(x, Uintptr) | ||||
| 				case "string": | ||||
| 					x.TypeNode = c.newPredeclaredType(x, String) | ||||
| 				case "float32": | ||||
| 					x.TypeNode = c.newPredeclaredType(x, Float32) | ||||
| 				case "float64": | ||||
| 					x.TypeNode = c.newPredeclaredType(x, Float64) | ||||
| 				case "complex64": | ||||
| 					x.TypeNode = c.newPredeclaredType(x, Complex64) | ||||
| 				case "complex128": | ||||
| 					x.TypeNode = c.newPredeclaredType(x, Complex128) | ||||
| 				case "comparable": | ||||
| 					x.TypeNode = c.newPredeclaredType(x, Interface) | ||||
| 				case "error": | ||||
| 					x.check(c) | ||||
| 				default: | ||||
| 					if token.IsExported(nm) { | ||||
| 						delete(c.pkg.Scope.nodes, nm) | ||||
| 						return | ||||
| 					} | ||||
| 
 | ||||
| 					panic(todo("%v: %T %s", x.Position(), x, x.Source(false))) | ||||
| 				} | ||||
| 			case c.isUnsafe(): | ||||
| 				switch nm := x.IDENT.Src(); nm { | ||||
| 				case "ArbitraryType", "IntegerType", "Pointer": | ||||
| 					x.TypeNode.check(c) | ||||
| 				default: | ||||
| 					panic(todo("%v: %T %s", x.Position(), x, x.Source(false))) | ||||
| 				} | ||||
| 			default: | ||||
| 				switch { | ||||
| 				case x.TypeParameters != nil: | ||||
| 					panic(todo("%v: %T %s", x.Position(), x, x.Source(false))) | ||||
| 				default: | ||||
| 					x.check(c) | ||||
| 				} | ||||
| 			} | ||||
| 		case *AliasDeclNode: | ||||
| 			x.check(c) | ||||
| 		default: | ||||
| 			panic(todo("%v: %T %s", x.Position(), x, x.Source(false))) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (n *AliasDeclNode) check(c *ctx) { | ||||
| 	if n == nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	n.TypeNode.check(c) | ||||
| } | ||||
| 
 | ||||
| func (n *ImportDeclNode) check(c *ctx) { | ||||
| 	if n == nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	type result struct { | ||||
| 		spec *ImportSpecNode | ||||
| 		pkg  *Package | ||||
| 		err  error | ||||
| 	} | ||||
| 	var a []*result | ||||
| 	var wg sync.WaitGroup | ||||
| 	for l := n.ImportSpecList; l != nil; l = l.List { | ||||
| 		r := &result{} | ||||
| 		a = append(a, r) | ||||
| 		wg.Add(1) | ||||
| 		go func(isln *ImportSpecListNode, r *result) { | ||||
| 
 | ||||
| 			defer wg.Done() | ||||
| 
 | ||||
| 			r.spec = isln.ImportSpec | ||||
| 			r.pkg, r.err = r.spec.check(c) | ||||
| 			r.spec.pkg = r.pkg | ||||
| 		}(l, r) | ||||
| 	} | ||||
| 	wg.Wait() | ||||
| 	fileScope := c.ast.FileScope | ||||
| 	pkgScope := c.pkg.Scope | ||||
| 	for _, v := range a { | ||||
| 		switch x := v.err.(type) { | ||||
| 		case nil: | ||||
| 			// ok | ||||
| 		default: | ||||
| 			panic(todo("%v: %T: %s", v.spec.Position(), x, x)) | ||||
| 		} | ||||
| 		if c.pkg.ImportPath == "builtin" && v.spec.ImportPath.Src() == `"cmp"` { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		switch ex := fileScope.declare(v.pkg.Name, v.spec, 0, nil, true); { | ||||
| 		case ex.declTok.IsValid(): | ||||
| 			c.err(n, "%s redeclared, previous declaration at %v:", v.pkg.Name.Src(), ex.declTok.Position()) | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		switch ex := pkgScope.declare(v.pkg.Name, v.spec, 0, nil, true); { | ||||
| 		case ex.declTok.IsValid(): | ||||
| 			c.err(n, "%s redeclared, previous declaration at %v:", v.pkg.Name.Src(), ex.declTok.Position()) | ||||
| 			continue | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (n *ImportSpecNode) check(c *ctx) (*Package, error) { | ||||
| 	if n == nil { | ||||
| 		return nil, nil | ||||
| 	} | ||||
| 
 | ||||
| 	switch { | ||||
| 	case n.PERIOD.IsValid(): | ||||
| 		panic(todo("", n.Position(), n.Source(false))) | ||||
| 	case n.PackageName.IsValid(): | ||||
| 		//TODO version | ||||
| 		check := c.pkg.typeCheck | ||||
| 		switch check { | ||||
| 		case TypeCheckAll: | ||||
| 			// nop | ||||
| 		default: | ||||
| 			panic(todo("", check)) | ||||
| 		} | ||||
| 		return c.cfg.newPackage(c.pkg.FSPath, constant.StringVal(n.ImportPath.Value()), "", nil, false, check, c.pkg.guard) | ||||
| 	default: | ||||
| 		//TODO version | ||||
| 		check := c.pkg.typeCheck | ||||
| 		switch check { | ||||
| 		case TypeCheckAll: | ||||
| 			// nop | ||||
| 		default: | ||||
| 			if c.pkg.ImportPath == "builtin" && n.ImportPath.Src() == `"cmp"` { | ||||
| 				return nil, nil | ||||
| 			} | ||||
| 		} | ||||
| 		return c.cfg.newPackage(c.pkg.FSPath, constant.StringVal(n.ImportPath.Value()), "", nil, false, check, c.pkg.guard) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (n *PackageClauseNode) check(c *ctx) { | ||||
| 	if n == nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	nm := n.PackageName.Src() | ||||
| 	if ex := c.pkg.Name; ex.IsValid() && ex.Src() != nm { | ||||
| 		c.err(n.PackageName, "found different packages %q and %q", ex.Src(), nm) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	c.pkg.Name = n.PackageName | ||||
| } | ||||
							
								
								
									
										559
									
								
								vendor/modernc.org/gc/v3/etc.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										559
									
								
								vendor/modernc.org/gc/v3/etc.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,559 +0,0 @@ | |||
| // Copyright 2022 The Gc Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| package gc // modernc.org/gc/v3 | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"go/token" | ||||
| 	"math" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"runtime" | ||||
| 	"sort" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| 
 | ||||
| 	"github.com/dustin/go-humanize" | ||||
| ) | ||||
| 
 | ||||
| // The list of tokens. | ||||
| const ( | ||||
| 	// Special tokens | ||||
| 	ILLEGAL = token.ILLEGAL | ||||
| 	EOF     = token.EOF | ||||
| 	COMMENT = token.COMMENT | ||||
| 
 | ||||
| 	// Identifiers and basic type literals | ||||
| 	// (these tokens stand for classes of literals) | ||||
| 	IDENT  = token.IDENT  // main | ||||
| 	INT    = token.INT    // 12345 | ||||
| 	FLOAT  = token.FLOAT  // 123.45 | ||||
| 	IMAG   = token.IMAG   // 123.45i | ||||
| 	CHAR   = token.CHAR   // 'a' | ||||
| 	STRING = token.STRING // "abc" | ||||
| 
 | ||||
| 	// Operators and delimiters | ||||
| 	ADD = token.ADD // + | ||||
| 	SUB = token.SUB // - | ||||
| 	MUL = token.MUL // * | ||||
| 	QUO = token.QUO // / | ||||
| 	REM = token.REM // % | ||||
| 
 | ||||
| 	AND     = token.AND     // & | ||||
| 	OR      = token.OR      // | | ||||
| 	XOR     = token.XOR     // ^ | ||||
| 	SHL     = token.SHL     // << | ||||
| 	SHR     = token.SHR     // >> | ||||
| 	AND_NOT = token.AND_NOT // &^ | ||||
| 
 | ||||
| 	ADD_ASSIGN = token.ADD_ASSIGN // += | ||||
| 	SUB_ASSIGN = token.SUB_ASSIGN // -= | ||||
| 	MUL_ASSIGN = token.MUL_ASSIGN // *= | ||||
| 	QUO_ASSIGN = token.QUO_ASSIGN // /= | ||||
| 	REM_ASSIGN = token.REM_ASSIGN // %= | ||||
| 
 | ||||
| 	AND_ASSIGN     = token.AND_ASSIGN     // &= | ||||
| 	OR_ASSIGN      = token.OR_ASSIGN      // |= | ||||
| 	XOR_ASSIGN     = token.XOR_ASSIGN     // ^= | ||||
| 	SHL_ASSIGN     = token.SHL_ASSIGN     // <<= | ||||
| 	SHR_ASSIGN     = token.SHR_ASSIGN     // >>= | ||||
| 	AND_NOT_ASSIGN = token.AND_NOT_ASSIGN // &^= | ||||
| 
 | ||||
| 	LAND  = token.LAND  // && | ||||
| 	LOR   = token.LOR   // || | ||||
| 	ARROW = token.ARROW // <- | ||||
| 	INC   = token.INC   // ++ | ||||
| 	DEC   = token.DEC   // -- | ||||
| 
 | ||||
| 	EQL    = token.EQL    // == | ||||
| 	LSS    = token.LSS    // < | ||||
| 	GTR    = token.GTR    // > | ||||
| 	ASSIGN = token.ASSIGN // = | ||||
| 	NOT    = token.NOT    // ! | ||||
| 
 | ||||
| 	NEQ      = token.NEQ      // != | ||||
| 	LEQ      = token.LEQ      // <= | ||||
| 	GEQ      = token.GEQ      // >= | ||||
| 	DEFINE   = token.DEFINE   // := | ||||
| 	ELLIPSIS = token.ELLIPSIS // ... | ||||
| 
 | ||||
| 	LPAREN = token.LPAREN // ( | ||||
| 	LBRACK = token.LBRACK // [ | ||||
| 	LBRACE = token.LBRACE // { | ||||
| 	COMMA  = token.COMMA  // , | ||||
| 	PERIOD = token.PERIOD // . | ||||
| 
 | ||||
| 	RPAREN    = token.RPAREN    // ) | ||||
| 	RBRACK    = token.RBRACK    // ] | ||||
| 	RBRACE    = token.RBRACE    // } | ||||
| 	SEMICOLON = token.SEMICOLON // ; | ||||
| 	COLON     = token.COLON     // : | ||||
| 
 | ||||
| 	// Keywords | ||||
| 	BREAK    = token.BREAK | ||||
| 	CASE     = token.CASE | ||||
| 	CHAN     = token.CHAN | ||||
| 	CONST    = token.CONST | ||||
| 	CONTINUE = token.CONTINUE | ||||
| 
 | ||||
| 	DEFAULT     = token.DEFAULT | ||||
| 	DEFER       = token.DEFER | ||||
| 	ELSE        = token.ELSE | ||||
| 	FALLTHROUGH = token.FALLTHROUGH | ||||
| 	FOR         = token.FOR | ||||
| 
 | ||||
| 	FUNC   = token.FUNC | ||||
| 	GO     = token.GO | ||||
| 	GOTO   = token.GOTO | ||||
| 	IF     = token.IF | ||||
| 	IMPORT = token.IMPORT | ||||
| 
 | ||||
| 	INTERFACE = token.INTERFACE | ||||
| 	MAP       = token.MAP | ||||
| 	PACKAGE   = token.PACKAGE | ||||
| 	RANGE     = token.RANGE | ||||
| 	RETURN    = token.RETURN | ||||
| 
 | ||||
| 	SELECT = token.SELECT | ||||
| 	STRUCT = token.STRUCT | ||||
| 	SWITCH = token.SWITCH | ||||
| 	TYPE   = token.TYPE | ||||
| 	VAR    = token.VAR | ||||
| 
 | ||||
| 	// additional tokens, handled in an ad-hoc manner | ||||
| 	TILDE = token.TILDE | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	trcTODOs       bool | ||||
| 	extendedErrors bool | ||||
| ) | ||||
| 
 | ||||
| // origin returns caller's short position, skipping skip frames. | ||||
| func origin(skip int) string { | ||||
| 	pc, fn, fl, _ := runtime.Caller(skip) | ||||
| 	f := runtime.FuncForPC(pc) | ||||
| 	var fns string | ||||
| 	if f != nil { | ||||
| 		fns = f.Name() | ||||
| 		if x := strings.LastIndex(fns, "."); x > 0 { | ||||
| 			fns = fns[x+1:] | ||||
| 		} | ||||
| 		if strings.HasPrefix(fns, "func") { | ||||
| 			num := true | ||||
| 			for _, c := range fns[len("func"):] { | ||||
| 				if c < '0' || c > '9' { | ||||
| 					num = false | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 			if num { | ||||
| 				return origin(skip + 2) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return fmt.Sprintf("%s:%d:%s", filepath.Base(fn), fl, fns) | ||||
| } | ||||
| 
 | ||||
| // todo prints and returns caller's position and an optional message tagged with TODO. Output goes to stderr. | ||||
| // | ||||
| //lint:ignore U1000 whatever | ||||
| func todo(s string, args ...interface{}) string { | ||||
| 	switch { | ||||
| 	case s == "": | ||||
| 		s = fmt.Sprintf(strings.Repeat("%v ", len(args)), args...) | ||||
| 	default: | ||||
| 		s = fmt.Sprintf(s, args...) | ||||
| 	} | ||||
| 	r := fmt.Sprintf("%s\n\tTODO (%s)", origin(2), s) | ||||
| 	// fmt.Fprintf(os.Stderr, "%s\n", r) | ||||
| 	// os.Stdout.Sync() | ||||
| 	return r | ||||
| } | ||||
| 
 | ||||
| // trc prints and returns caller's position and an optional message tagged with TRC. Output goes to stderr. | ||||
| // | ||||
| //lint:ignore U1000 whatever | ||||
| func trc(s string, args ...interface{}) string { | ||||
| 	switch { | ||||
| 	case s == "": | ||||
| 		s = fmt.Sprintf(strings.Repeat("%v ", len(args)), args...) | ||||
| 	default: | ||||
| 		s = fmt.Sprintf(s, args...) | ||||
| 	} | ||||
| 	r := fmt.Sprintf("%s: TRC (%s)", origin(2), s) | ||||
| 	fmt.Fprintf(os.Stderr, "%s\n", r) | ||||
| 	os.Stderr.Sync() | ||||
| 	return r | ||||
| } | ||||
| 
 | ||||
| func extractPos(s string) (p token.Position, ok bool) { | ||||
| 	var prefix string | ||||
| 	if len(s) > 1 && s[1] == ':' { // c:\foo | ||||
| 		prefix = s[:2] | ||||
| 		s = s[2:] | ||||
| 	} | ||||
| 	// "testdata/parser/bug/001.c:1193: ..." | ||||
| 	a := strings.Split(s, ":") | ||||
| 	// ["testdata/parser/bug/001.c" "1193" "..."] | ||||
| 	if len(a) < 2 { | ||||
| 		return p, false | ||||
| 	} | ||||
| 
 | ||||
| 	line, err := strconv.Atoi(a[1]) | ||||
| 	if err != nil { | ||||
| 		return p, false | ||||
| 	} | ||||
| 
 | ||||
| 	col, err := strconv.Atoi(a[2]) | ||||
| 	if err != nil { | ||||
| 		col = 1 | ||||
| 	} | ||||
| 
 | ||||
| 	return token.Position{Filename: prefix + a[0], Line: line, Column: col}, true | ||||
| } | ||||
| 
 | ||||
| // errorf constructs an error value. If extendedErrors is true, the error will | ||||
| // contain its origin. | ||||
| func errorf(s string, args ...interface{}) error { | ||||
| 	switch { | ||||
| 	case s == "": | ||||
| 		s = fmt.Sprintf(strings.Repeat("%v ", len(args)), args...) | ||||
| 	default: | ||||
| 		s = fmt.Sprintf(s, args...) | ||||
| 	} | ||||
| 	if trcTODOs && strings.HasPrefix(s, "TODO") { | ||||
| 		fmt.Fprintf(os.Stderr, "%s (%v)\n", s, origin(2)) | ||||
| 		os.Stderr.Sync() | ||||
| 	} | ||||
| 	switch { | ||||
| 	case extendedErrors: | ||||
| 		return fmt.Errorf("%s (%v: %v: %v)", s, origin(4), origin(3), origin(2)) | ||||
| 	default: | ||||
| 		return fmt.Errorf("%s", s) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func tokSource(t token.Token) string { | ||||
| 	switch t { | ||||
| 	case ILLEGAL: | ||||
| 		return "ILLEGAL" | ||||
| 	case EOF: | ||||
| 		return "EOF" | ||||
| 	case COMMENT: | ||||
| 		return "COMMENT" | ||||
| 	case IDENT: | ||||
| 		return "IDENT" | ||||
| 	case INT: | ||||
| 		return "INT" | ||||
| 	case FLOAT: | ||||
| 		return "FLOAT" | ||||
| 	case IMAG: | ||||
| 		return "IMAG" | ||||
| 	case CHAR: | ||||
| 		return "CHAR" | ||||
| 	case STRING: | ||||
| 		return "STRING" | ||||
| 	case ADD: | ||||
| 		return "ADD" | ||||
| 	case SUB: | ||||
| 		return "SUB" | ||||
| 	case MUL: | ||||
| 		return "MUL" | ||||
| 	case QUO: | ||||
| 		return "QUO" | ||||
| 	case REM: | ||||
| 		return "REM" | ||||
| 	case AND: | ||||
| 		return "AND" | ||||
| 	case OR: | ||||
| 		return "OR" | ||||
| 	case XOR: | ||||
| 		return "XOR" | ||||
| 	case SHL: | ||||
| 		return "SHL" | ||||
| 	case SHR: | ||||
| 		return "SHR" | ||||
| 	case AND_NOT: | ||||
| 		return "AND_NOT" | ||||
| 	case ADD_ASSIGN: | ||||
| 		return "ADD_ASSIGN" | ||||
| 	case SUB_ASSIGN: | ||||
| 		return "SUB_ASSIGN" | ||||
| 	case MUL_ASSIGN: | ||||
| 		return "MUL_ASSIGN" | ||||
| 	case QUO_ASSIGN: | ||||
| 		return "QUO_ASSIGN" | ||||
| 	case REM_ASSIGN: | ||||
| 		return "REM_ASSIGN" | ||||
| 	case AND_ASSIGN: | ||||
| 		return "AND_ASSIGN" | ||||
| 	case OR_ASSIGN: | ||||
| 		return "OR_ASSIGN" | ||||
| 	case XOR_ASSIGN: | ||||
| 		return "XOR_ASSIGN" | ||||
| 	case SHL_ASSIGN: | ||||
| 		return "SHL_ASSIGN" | ||||
| 	case SHR_ASSIGN: | ||||
| 		return "SHR_ASSIGN" | ||||
| 	case AND_NOT_ASSIGN: | ||||
| 		return "AND_NOT_ASSIGN" | ||||
| 	case LAND: | ||||
| 		return "LAND" | ||||
| 	case LOR: | ||||
| 		return "LOR" | ||||
| 	case ARROW: | ||||
| 		return "ARROW" | ||||
| 	case INC: | ||||
| 		return "INC" | ||||
| 	case DEC: | ||||
| 		return "DEC" | ||||
| 	case EQL: | ||||
| 		return "EQL" | ||||
| 	case LSS: | ||||
| 		return "LSS" | ||||
| 	case GTR: | ||||
| 		return "GTR" | ||||
| 	case ASSIGN: | ||||
| 		return "ASSIGN" | ||||
| 	case NOT: | ||||
| 		return "NOT" | ||||
| 	case NEQ: | ||||
| 		return "NEQ" | ||||
| 	case LEQ: | ||||
| 		return "LEQ" | ||||
| 	case GEQ: | ||||
| 		return "GEQ" | ||||
| 	case DEFINE: | ||||
| 		return "DEFINE" | ||||
| 	case ELLIPSIS: | ||||
| 		return "ELLIPSIS" | ||||
| 	case LPAREN: | ||||
| 		return "LPAREN" | ||||
| 	case LBRACK: | ||||
| 		return "LBRACK" | ||||
| 	case LBRACE: | ||||
| 		return "LBRACE" | ||||
| 	case COMMA: | ||||
| 		return "COMMA" | ||||
| 	case PERIOD: | ||||
| 		return "PERIOD" | ||||
| 	case RPAREN: | ||||
| 		return "RPAREN" | ||||
| 	case RBRACK: | ||||
| 		return "RBRACK" | ||||
| 	case RBRACE: | ||||
| 		return "RBRACE" | ||||
| 	case SEMICOLON: | ||||
| 		return "SEMICOLON" | ||||
| 	case COLON: | ||||
| 		return "COLON" | ||||
| 	case BREAK: | ||||
| 		return "BREAK" | ||||
| 	case CASE: | ||||
| 		return "CASE" | ||||
| 	case CHAN: | ||||
| 		return "CHAN" | ||||
| 	case CONST: | ||||
| 		return "CONST" | ||||
| 	case CONTINUE: | ||||
| 		return "CONTINUE" | ||||
| 	case DEFAULT: | ||||
| 		return "DEFAULT" | ||||
| 	case DEFER: | ||||
| 		return "DEFER" | ||||
| 	case ELSE: | ||||
| 		return "ELSE" | ||||
| 	case FALLTHROUGH: | ||||
| 		return "FALLTHROUGH" | ||||
| 	case FOR: | ||||
| 		return "FOR" | ||||
| 	case FUNC: | ||||
| 		return "FUNC" | ||||
| 	case GO: | ||||
| 		return "GO" | ||||
| 	case GOTO: | ||||
| 		return "GOTO" | ||||
| 	case IF: | ||||
| 		return "IF" | ||||
| 	case IMPORT: | ||||
| 		return "IMPORT" | ||||
| 	case INTERFACE: | ||||
| 		return "INTERFACE" | ||||
| 	case MAP: | ||||
| 		return "MAP" | ||||
| 	case PACKAGE: | ||||
| 		return "PACKAGE" | ||||
| 	case RANGE: | ||||
| 		return "RANGE" | ||||
| 	case RETURN: | ||||
| 		return "RETURN" | ||||
| 	case SELECT: | ||||
| 		return "SELECT" | ||||
| 	case STRUCT: | ||||
| 		return "STRUCT" | ||||
| 	case SWITCH: | ||||
| 		return "SWITCH" | ||||
| 	case TYPE: | ||||
| 		return "TYPE" | ||||
| 	case VAR: | ||||
| 		return "VAR" | ||||
| 	case TILDE: | ||||
| 		return "TILDE" | ||||
| 	default: | ||||
| 		panic(todo("", int(t), t)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| type data struct { | ||||
| 	line  int | ||||
| 	cases int | ||||
| 	cnt   int | ||||
| } | ||||
| 
 | ||||
| type analyzer struct { | ||||
| 	sync.Mutex | ||||
| 	m map[int]*data // line: data | ||||
| } | ||||
| 
 | ||||
| func newAnalyzer() *analyzer { | ||||
| 	return &analyzer{m: map[int]*data{}} | ||||
| } | ||||
| 
 | ||||
| func (a *analyzer) record(line, cnt int) { | ||||
| 	d := a.m[line] | ||||
| 	if d == nil { | ||||
| 		d = &data{line: line} | ||||
| 		a.m[line] = d | ||||
| 	} | ||||
| 	d.cases++ | ||||
| 	d.cnt += cnt | ||||
| } | ||||
| 
 | ||||
| func (a *analyzer) merge(b *analyzer) { | ||||
| 	a.Lock() | ||||
| 	defer a.Unlock() | ||||
| 
 | ||||
| 	for k, v := range b.m { | ||||
| 		d := a.m[k] | ||||
| 		if d == nil { | ||||
| 			d = &data{line: k} | ||||
| 			a.m[k] = d | ||||
| 		} | ||||
| 		d.cases += v.cases | ||||
| 		d.cnt += v.cnt | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (a *analyzer) report() string { | ||||
| 	var rows []*data | ||||
| 	for _, v := range a.m { | ||||
| 		rows = append(rows, v) | ||||
| 	} | ||||
| 	sort.Slice(rows, func(i, j int) bool { | ||||
| 		a := rows[i] | ||||
| 		b := rows[j] | ||||
| 		if a.cases < b.cases { | ||||
| 			return true | ||||
| 		} | ||||
| 
 | ||||
| 		if a.cases > b.cases { | ||||
| 			return false | ||||
| 		} | ||||
| 
 | ||||
| 		// a.cases == b.cases | ||||
| 		if a.cnt < b.cnt { | ||||
| 			return true | ||||
| 		} | ||||
| 
 | ||||
| 		if a.cnt > b.cnt { | ||||
| 			return false | ||||
| 		} | ||||
| 
 | ||||
| 		// a.cnt == b.cnt | ||||
| 		return a.line < b.line | ||||
| 	}) | ||||
| 	var b strings.Builder | ||||
| 	var cases, cnt int | ||||
| 	for _, row := range rows { | ||||
| 		cases += row.cases | ||||
| 		cnt += row.cnt | ||||
| 		avg := float64(row.cnt) / float64(row.cases) | ||||
| 		fmt.Fprintf(&b, "parser.go:%d:\t%16s %16s %8.1f\n", row.line, h(row.cases), h(row.cnt), avg) | ||||
| 	} | ||||
| 	avg := float64(cnt) / float64(cases) | ||||
| 	fmt.Fprintf(&b, "<total>\t\t%16s %16s %8.1f\n", h(cases), h(cnt), avg) | ||||
| 	return b.String() | ||||
| } | ||||
| 
 | ||||
| func h(v interface{}) string { | ||||
| 	switch x := v.(type) { | ||||
| 	case int: | ||||
| 		return humanize.Comma(int64(x)) | ||||
| 	case int32: | ||||
| 		return humanize.Comma(int64(x)) | ||||
| 	case int64: | ||||
| 		return humanize.Comma(x) | ||||
| 	case uint32: | ||||
| 		return humanize.Comma(int64(x)) | ||||
| 	case uint64: | ||||
| 		if x <= math.MaxInt64 { | ||||
| 			return humanize.Comma(int64(x)) | ||||
| 		} | ||||
| 
 | ||||
| 		return "-" + humanize.Comma(-int64(x)) | ||||
| 	} | ||||
| 	return fmt.Sprint(v) | ||||
| } | ||||
| 
 | ||||
| type parallel struct { | ||||
| 	limiter chan struct{} | ||||
| } | ||||
| 
 | ||||
| func newParallel() *parallel { | ||||
| 	return ¶llel{ | ||||
| 		limiter: make(chan struct{}, runtime.GOMAXPROCS(0)), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (p *parallel) throttle(f func()) { | ||||
| 	p.limiter <- struct{}{} | ||||
| 
 | ||||
| 	defer func() { | ||||
| 		<-p.limiter | ||||
| 	}() | ||||
| 
 | ||||
| 	f() | ||||
| } | ||||
| 
 | ||||
| func extraTags(verMajor, verMinor int, goos, goarch string) (r []string) { | ||||
| 	// https://github.com/golang/go/commit/eeb7899137cda1c2cd60dab65ff41f627436db5b | ||||
| 	// | ||||
| 	// In Go 1.17 we added register ABI on AMD64 on Linux/macOS/Windows | ||||
| 	// as a GOEXPERIMENT, on by default. In Go 1.18, we commit to always | ||||
| 	// enabling register ABI on AMD64. | ||||
| 	// | ||||
| 	// Now "go build" for AMD64 always have goexperiment.regabi* tags | ||||
| 	// set. However, at bootstrapping cmd/dist does not set the tags | ||||
| 	// when building go_bootstrap. For this to work, unfortunately, we | ||||
| 	// need to hard-code AMD64 to use register ABI in runtime code. | ||||
| 	if verMajor == 1 { | ||||
| 		switch { | ||||
| 		case verMinor == 17: | ||||
| 			switch goos { | ||||
| 			case "linux", "darwin", "windows": | ||||
| 				if goarch == "amd64" { | ||||
| 					r = append(r, "goexperiment.regabiargs", "goexperiment.regabiwrappers") | ||||
| 				} | ||||
| 			} | ||||
| 		case verMinor >= 18: | ||||
| 			if goarch == "amd64" { | ||||
| 				r = append(r, "goexperiment.regabiargs", "goexperiment.regabiwrappers") | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return r | ||||
| } | ||||
							
								
								
									
										761
									
								
								vendor/modernc.org/gc/v3/gc.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										761
									
								
								vendor/modernc.org/gc/v3/gc.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,761 +0,0 @@ | |||
| // Copyright 2022 The Gc 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:generate stringer -output stringer.go -linecomment -type=Kind,ScopeKind,ChanDir,TypeCheck | ||||
| 
 | ||||
| package gc // modernc.org/gc/v3 | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"go/build" | ||||
| 	"go/build/constraint" | ||||
| 	"go/token" | ||||
| 	"io" | ||||
| 	"io/fs" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"runtime" | ||||
| 	"sort" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| 	"unicode" | ||||
| 
 | ||||
| 	"github.com/hashicorp/golang-lru/v2" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	trcErrors bool | ||||
| ) | ||||
| 
 | ||||
| type FileFilter func(cfg *Config, importPath string, matchedFSPaths []string, withTestFiles bool) (pkgFiles []string, err error) | ||||
| 
 | ||||
| type TypeCheck int | ||||
| 
 | ||||
| const ( | ||||
| 	TypeCheckNone TypeCheck = iota | ||||
| 	TypeCheckAll | ||||
| ) | ||||
| 
 | ||||
| type cacheKey struct { | ||||
| 	buildTagsKey string | ||||
| 	cfg          *Config | ||||
| 	fsPath       string | ||||
| 	goarch       string | ||||
| 	goos         string | ||||
| 	gopathKey    string | ||||
| 	goroot       string | ||||
| 	importPath   string | ||||
| 	typeCheck    TypeCheck | ||||
| 
 | ||||
| 	withTestFiles bool | ||||
| } | ||||
| 
 | ||||
| type cacheItem struct { | ||||
| 	pkg *Package | ||||
| 	ch  chan struct{} | ||||
| } | ||||
| 
 | ||||
| func newCacheItem() *cacheItem { return &cacheItem{ch: make(chan struct{})} } | ||||
| 
 | ||||
| func (c *cacheItem) set(pkg *Package) { | ||||
| 	c.pkg = pkg | ||||
| 	close(c.ch) | ||||
| } | ||||
| 
 | ||||
| func (c *cacheItem) wait() *Package { | ||||
| 	<-c.ch | ||||
| 	return c.pkg | ||||
| } | ||||
| 
 | ||||
| type Cache struct { | ||||
| 	sync.Mutex | ||||
| 	lru *lru.TwoQueueCache[cacheKey, *cacheItem] | ||||
| } | ||||
| 
 | ||||
| func NewCache(size int) (*Cache, error) { | ||||
| 	c, err := lru.New2Q[cacheKey, *cacheItem](size) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	return &Cache{lru: c}, nil | ||||
| } | ||||
| 
 | ||||
| func MustNewCache(size int) *Cache { | ||||
| 	c, err := NewCache(size) | ||||
| 	if err != nil { | ||||
| 		panic(todo("", err)) | ||||
| 	} | ||||
| 
 | ||||
| 	return c | ||||
| } | ||||
| 
 | ||||
| type ConfigOption func(*Config) error | ||||
| 
 | ||||
| // Config configures NewPackage | ||||
| // | ||||
| // Config instances can be shared, they are not mutated once created and | ||||
| // configured. | ||||
| type Config struct { | ||||
| 	abi           *ABI | ||||
| 	buildTagMap   map[string]bool | ||||
| 	buildTags     []string | ||||
| 	buildTagsKey  string // Zero byte separated | ||||
| 	builtin       *Package | ||||
| 	cache         *Cache | ||||
| 	cmp           *Package // Go 1.21 | ||||
| 	env           map[string]string | ||||
| 	fs            fs.FS | ||||
| 	goarch        string | ||||
| 	gocompiler    string // "gc", "gccgo" | ||||
| 	goos          string | ||||
| 	gopath        string | ||||
| 	gopathKey     string // Zero byte separated | ||||
| 	goroot        string | ||||
| 	goversion     string | ||||
| 	lookup        func(rel, importPath, version string) (fsPath string, err error) | ||||
| 	parallel      *parallel | ||||
| 	searchGoPaths []string | ||||
| 	searchGoroot  []string | ||||
| 
 | ||||
| 	int  Type // Set by NewConfig | ||||
| 	uint Type // Set by NewConfig | ||||
| 
 | ||||
| 	arch32bit  bool | ||||
| 	configured bool | ||||
| } | ||||
| 
 | ||||
| // NewConfig returns a newly created config or an error, if any. | ||||
| func NewConfig(opts ...ConfigOption) (r *Config, err error) { | ||||
| 	r = &Config{ | ||||
| 		buildTagMap: map[string]bool{}, | ||||
| 		env:         map[string]string{}, | ||||
| 		parallel:    newParallel(), | ||||
| 	} | ||||
| 
 | ||||
| 	defer func() { | ||||
| 		if r != nil { | ||||
| 			r.configured = true | ||||
| 		} | ||||
| 	}() | ||||
| 
 | ||||
| 	r.lookup = r.DefaultLookup | ||||
| 	ctx := build.Default | ||||
| 	r.goos = r.getenv("GOOS", ctx.GOOS) | ||||
| 	r.goarch = r.getenv("GOARCH", ctx.GOARCH) | ||||
| 	r.goroot = r.getenv("GOROOT", ctx.GOROOT) | ||||
| 	r.gopath = r.getenv("GOPATH", ctx.GOPATH) | ||||
| 	r.buildTags = append(r.buildTags, r.goos, r.goarch) | ||||
| 	r.gocompiler = runtime.Compiler | ||||
| 	for _, opt := range opts { | ||||
| 		if err := opt(r); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
| 	if r.abi, err = NewABI(r.goos, r.goarch); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	switch r.goarch { | ||||
| 	case "386", "arm": | ||||
| 		r.arch32bit = true | ||||
| 	} | ||||
| 
 | ||||
| 	//  During a particular build, the following build tags are satisfied: | ||||
| 	// | ||||
| 	//  the target operating system, as spelled by runtime.GOOS, set with the GOOS environment variable. | ||||
| 	//  the target architecture, as spelled by runtime.GOARCH, set with the GOARCH environment variable. | ||||
| 	//  "unix", if GOOS is a Unix or Unix-like system. | ||||
| 	//  the compiler being used, either "gc" or "gccgo" | ||||
| 	//  "cgo", if the cgo command is supported (see CGO_ENABLED in 'go help environment'). | ||||
| 	//  a term for each Go major release, through the current version: "go1.1" from Go version 1.1 onward, "go1.12" from Go 1.12, and so on. | ||||
| 	//  any additional tags given by the -tags flag (see 'go help build'). | ||||
| 	//  There are no separate build tags for beta or minor releases. | ||||
| 	if r.goversion == "" { | ||||
| 		r.goversion = runtime.Version() | ||||
| 	} | ||||
| 	if !strings.HasPrefix(r.goversion, "go") || !strings.Contains(r.goversion, ".") { | ||||
| 		return nil, fmt.Errorf("cannot parse Go version: %s", r.goversion) | ||||
| 	} | ||||
| 
 | ||||
| 	ver := strings.SplitN(r.goversion[len("go"):], ".", 2) | ||||
| 	verMajor, err := strconv.Atoi(ver[0]) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("cannot parse Go version %s: %v", r.goversion, err) | ||||
| 	} | ||||
| 
 | ||||
| 	if verMajor != 1 { | ||||
| 		return nil, fmt.Errorf("unsupported Go version: %s", r.goversion) | ||||
| 	} | ||||
| 
 | ||||
| 	switch x, x2 := strings.IndexByte(ver[1], '.'), strings.Index(ver[1], "rc"); { | ||||
| 	case x >= 0: | ||||
| 		ver[1] = ver[1][:x] | ||||
| 	case x2 >= 0: | ||||
| 		ver[1] = ver[1][:x2] | ||||
| 	} | ||||
| 	verMinor, err := strconv.Atoi(ver[1]) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("cannot parse Go version %s: %v", r.goversion, err) | ||||
| 	} | ||||
| 
 | ||||
| 	for i := 1; i <= verMinor; i++ { | ||||
| 		r.buildTags = append(r.buildTags, fmt.Sprintf("go%d.%d", verMajor, i)) | ||||
| 	} | ||||
| 	r.buildTags = append(r.buildTags, r.gocompiler) | ||||
| 	r.buildTags = append(r.buildTags, extraTags(verMajor, verMinor, r.goos, r.goarch)...) | ||||
| 	if r.getenv("CGO_ENABLED", "1") == "1" { | ||||
| 		r.buildTags = append(r.buildTags, "cgo") | ||||
| 	} | ||||
| 	for i, v := range r.buildTags { | ||||
| 		tag := strings.TrimSpace(v) | ||||
| 		r.buildTags[i] = tag | ||||
| 		r.buildTagMap[tag] = true | ||||
| 	} | ||||
| 	sort.Strings(r.buildTags) | ||||
| 	r.buildTagsKey = strings.Join(r.buildTags, "\x00") | ||||
| 	r.searchGoroot = []string{filepath.Join(r.goroot, "src")} | ||||
| 	r.searchGoPaths = filepath.SplitList(r.gopath) | ||||
| 	r.gopathKey = strings.Join(r.searchGoPaths, "\x00") | ||||
| 	for i, v := range r.searchGoPaths { | ||||
| 		r.searchGoPaths[i] = filepath.Join(v, "src") | ||||
| 	} | ||||
| 
 | ||||
| 	switch r.cmp, err = r.NewPackage("", "cmp", "", nil, false, TypeCheckNone); { | ||||
| 	case err != nil: | ||||
| 		r.cmp = nil | ||||
| 	default: | ||||
| 		//TODO r.cmp.Scope.kind = UniverseScope | ||||
| 	} | ||||
| 	if r.builtin, err = r.NewPackage("", "builtin", "", nil, false, TypeCheckNone); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	r.builtin.Scope.kind = UniverseScope | ||||
| 	if err := r.builtin.check(newCtx(r)); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	return r, nil | ||||
| } | ||||
| 
 | ||||
| func (c *Config) universe() *Scope { | ||||
| 	if c.builtin != nil { | ||||
| 		return c.builtin.Scope | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (c *Config) stat(name string) (fs.FileInfo, error) { | ||||
| 	if c.fs == nil { | ||||
| 		return os.Stat(name) | ||||
| 	} | ||||
| 
 | ||||
| 	name = filepath.ToSlash(name) | ||||
| 	if x, ok := c.fs.(fs.StatFS); ok { | ||||
| 		return x.Stat(name) | ||||
| 	} | ||||
| 
 | ||||
| 	f, err := c.fs.Open(name) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	defer f.Close() | ||||
| 
 | ||||
| 	return f.Stat() | ||||
| } | ||||
| 
 | ||||
| func (c *Config) open(name string) (fs.File, error) { | ||||
| 	if c.fs == nil { | ||||
| 		return os.Open(name) | ||||
| 	} | ||||
| 
 | ||||
| 	name = filepath.ToSlash(name) | ||||
| 	return c.fs.Open(name) | ||||
| } | ||||
| 
 | ||||
| func (c *Config) glob(pattern string) (matches []string, err error) { | ||||
| 	if c.fs == nil { | ||||
| 		return filepath.Glob(pattern) | ||||
| 	} | ||||
| 
 | ||||
| 	pattern = filepath.ToSlash(pattern) | ||||
| 	return fs.Glob(c.fs, pattern) | ||||
| } | ||||
| 
 | ||||
| func (c *Config) checkConstraints(pos token.Position, sep string) (r bool) { | ||||
| 	if !strings.Contains(sep, "//go:build") && !strings.Contains(sep, "+build") { | ||||
| 		return true | ||||
| 	} | ||||
| 
 | ||||
| 	// defer func() { trc("", r) }() | ||||
| 
 | ||||
| 	lines := strings.Split(sep, "\n") | ||||
| 	var build, plusBuild []string | ||||
| 	for i, line := range lines { | ||||
| 		if constraint.IsGoBuild(line) && i < len(lines)-1 && lines[i+1] == "" { | ||||
| 			build = append(build, line) | ||||
| 		} | ||||
| 		if constraint.IsPlusBuild(line) { | ||||
| 			plusBuild = append(plusBuild, line) | ||||
| 		} | ||||
| 	} | ||||
| 	switch len(build) { | ||||
| 	case 0: | ||||
| 		// ok | ||||
| 	case 1: | ||||
| 		expr, err := constraint.Parse(build[0]) | ||||
| 		if err != nil { | ||||
| 			return true | ||||
| 		} | ||||
| 
 | ||||
| 		return expr.Eval(func(tag string) (r bool) { | ||||
| 			// defer func() { trc("%q: %v", tag, r) }() | ||||
| 			switch tag { | ||||
| 			case "unix": | ||||
| 				return unixOS[c.goos] | ||||
| 			default: | ||||
| 				return c.buildTagMap[tag] | ||||
| 			} | ||||
| 		}) | ||||
| 	default: | ||||
| 		panic(todo("%v: %q", pos, build)) | ||||
| 	} | ||||
| 
 | ||||
| 	for _, line := range plusBuild { | ||||
| 		expr, err := constraint.Parse(line) | ||||
| 		if err != nil { | ||||
| 			return true | ||||
| 		} | ||||
| 
 | ||||
| 		if !expr.Eval(func(tag string) (r bool) { | ||||
| 			// defer func() { trc("%q: %v", tag, r) }() | ||||
| 			switch tag { | ||||
| 			case "unix": | ||||
| 				return unixOS[c.goos] | ||||
| 			default: | ||||
| 				return c.buildTagMap[tag] | ||||
| 			} | ||||
| 		}) { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
| 
 | ||||
| // Default lookup translates import paths, possibly relative to rel, to file system paths. | ||||
| func (c *Config) DefaultLookup(rel, importPath, version string) (fsPath string, err error) { | ||||
| 	if importPath == "" { | ||||
| 		return "", fmt.Errorf("import path cannot be emtpy") | ||||
| 	} | ||||
| 
 | ||||
| 	// Implementation restriction: A compiler may restrict ImportPaths to non-empty | ||||
| 	// strings using only characters belonging to Unicode's L, M, N, P, and S | ||||
| 	// general categories (the Graphic characters without spaces) and may also | ||||
| 	// exclude the characters !"#$%&'()*,:;<=>?[\]^`{|} and the Unicode replacement | ||||
| 	// character U+FFFD. | ||||
| 	if strings.ContainsAny(importPath, "!\"#$%&'()*,:;<=>?[\\]^`{|}\ufffd") { | ||||
| 		return "", fmt.Errorf("invalid import path: %s", importPath) | ||||
| 	} | ||||
| 
 | ||||
| 	for _, r := range importPath { | ||||
| 		if !unicode.Is(unicode.L, r) && | ||||
| 			!unicode.Is(unicode.M, r) && | ||||
| 			!unicode.Is(unicode.N, r) && | ||||
| 			!unicode.Is(unicode.P, r) && | ||||
| 			!unicode.Is(unicode.S, r) { | ||||
| 			return "", fmt.Errorf("invalid import path: %s", importPath) | ||||
| 		} | ||||
| 	} | ||||
| 	var search []string | ||||
| 	ip0 := importPath | ||||
| 	switch slash := strings.IndexByte(importPath, '/'); { | ||||
| 	case strings.HasPrefix(importPath, "./"): | ||||
| 		if rel != "" { | ||||
| 			panic(todo("")) | ||||
| 		} | ||||
| 
 | ||||
| 		return "", fmt.Errorf("invalid import path: %s", importPath) | ||||
| 	case strings.HasPrefix(importPath, "/"): | ||||
| 		return importPath, nil | ||||
| 	case slash > 0: | ||||
| 		ip0 = importPath[:slash] | ||||
| 	default: | ||||
| 		ip0 = importPath | ||||
| 	} | ||||
| 	if ip0 != "" { | ||||
| 		switch { | ||||
| 		case strings.Contains(ip0, "."): | ||||
| 			search = c.searchGoPaths | ||||
| 		default: | ||||
| 			search = c.searchGoroot | ||||
| 		} | ||||
| 	} | ||||
| 	for _, v := range search { | ||||
| 		fsPath = filepath.Join(v, importPath) | ||||
| 		dir, err := c.open(fsPath) | ||||
| 		if err != nil { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		fi, err := dir.Stat() | ||||
| 		dir.Close() | ||||
| 		if err != nil { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		if fi.IsDir() { | ||||
| 			return fsPath, nil | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return "", fmt.Errorf("cannot find package %s, searched %v", importPath, search) | ||||
| } | ||||
| 
 | ||||
| func (c *Config) getenv(nm, deflt string) (r string) { | ||||
| 	if r = c.env[nm]; r != "" { | ||||
| 		return r | ||||
| 	} | ||||
| 
 | ||||
| 	if r = os.Getenv(nm); r != "" { | ||||
| 		return r | ||||
| 	} | ||||
| 
 | ||||
| 	return deflt | ||||
| } | ||||
| 
 | ||||
| func DefaultFileFilter(cfg *Config, importPath string, matchedFSPaths []string, withTestFiles bool) (pkgFiles []string, err error) { | ||||
| 	w := 0 | ||||
| 	for _, v := range matchedFSPaths { | ||||
| 		base := filepath.Base(v) | ||||
| 		base = base[:len(base)-len(filepath.Ext(base))] | ||||
| 		const testSuffix = "_test" | ||||
| 		if strings.HasSuffix(base, testSuffix) { | ||||
| 			if !withTestFiles { | ||||
| 				continue | ||||
| 			} | ||||
| 
 | ||||
| 			base = base[:len(base)-len(testSuffix)] | ||||
| 		} | ||||
| 		if x := strings.LastIndexByte(base, '_'); x > 0 { | ||||
| 			last := base[x+1:] | ||||
| 			base = base[:x] | ||||
| 			var prevLast string | ||||
| 			if x := strings.LastIndexByte(base, '_'); x > 0 { | ||||
| 				prevLast = base[x+1:] | ||||
| 			} | ||||
| 			if last != "" && prevLast != "" { | ||||
| 				//  *_GOOS_GOARCH | ||||
| 				if knownOS[prevLast] && prevLast != cfg.goos { | ||||
| 					continue | ||||
| 				} | ||||
| 
 | ||||
| 				if knownArch[last] && last != cfg.goarch { | ||||
| 					continue | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			if last != "" { | ||||
| 				// *_GOOS or *_GOARCH | ||||
| 				if knownOS[last] && last != cfg.goos { | ||||
| 					continue | ||||
| 				} | ||||
| 
 | ||||
| 				if knownArch[last] && last != cfg.goarch { | ||||
| 					continue | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		matchedFSPaths[w] = v | ||||
| 		w++ | ||||
| 	} | ||||
| 	return matchedFSPaths[:w], nil | ||||
| } | ||||
| 
 | ||||
| // ConfigBuildTags configures build tags. | ||||
| func ConfigBuildTags(tags []string) ConfigOption { | ||||
| 	return func(cfg *Config) error { | ||||
| 		if cfg.configured { | ||||
| 			return fmt.Errorf("ConfigBuildTags: Config instance already configured") | ||||
| 		} | ||||
| 
 | ||||
| 		cfg.buildTags = append(cfg.buildTags, tags...) | ||||
| 		return nil | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // ConfigEnviron configures environment variables. | ||||
| func ConfigEnviron(env []string) ConfigOption { | ||||
| 	return func(cfg *Config) error { | ||||
| 		if cfg.configured { | ||||
| 			return fmt.Errorf("ConfigEnviron: Config instance already configured") | ||||
| 		} | ||||
| 
 | ||||
| 		for _, v := range env { | ||||
| 			switch x := strings.IndexByte(v, '='); { | ||||
| 			case x < 0: | ||||
| 				cfg.env[v] = "" | ||||
| 			default: | ||||
| 				cfg.env[v[:x]] = v[x+1:] | ||||
| 			} | ||||
| 		} | ||||
| 		return nil | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // ConfigFS configures a file system used for opening Go source files. If not | ||||
| // explicitly configured, a default os.DirFS("/") is used on Unix-like | ||||
| // operating systems. On Windows it will be rooted on the volume where | ||||
| // runtime.GOROOT() is. | ||||
| func ConfigFS(fs fs.FS) ConfigOption { | ||||
| 	return func(cfg *Config) error { | ||||
| 		if cfg.configured { | ||||
| 			return fmt.Errorf("ConfigFS: Config instance already configured") | ||||
| 		} | ||||
| 
 | ||||
| 		cfg.fs = fs | ||||
| 		return nil | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // ConfigLookup configures a lookup function. | ||||
| func ConfigLookup(f func(dir, importPath, version string) (fsPath string, err error)) ConfigOption { | ||||
| 	return func(cfg *Config) error { | ||||
| 		if cfg.configured { | ||||
| 			return fmt.Errorf("ConfigLookup: Config instance already configured") | ||||
| 		} | ||||
| 
 | ||||
| 		cfg.lookup = f | ||||
| 		return nil | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // ConfigCache configures a cache. | ||||
| func ConfigCache(c *Cache) ConfigOption { | ||||
| 	return func(cfg *Config) error { | ||||
| 		if cfg.configured { | ||||
| 			return fmt.Errorf("ConfigCache: Config instance already configured") | ||||
| 		} | ||||
| 
 | ||||
| 		cfg.cache = c | ||||
| 		return nil | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| type importGuard struct { | ||||
| 	m     map[string]struct{} | ||||
| 	stack []string | ||||
| } | ||||
| 
 | ||||
| func newImportGuard() *importGuard { return &importGuard{m: map[string]struct{}{}} } | ||||
| 
 | ||||
| // Package represents a Go package. The instance must not be mutated. | ||||
| type Package struct { | ||||
| 	AST            map[string]*AST // AST maps fsPaths of individual files to their respective ASTs | ||||
| 	FSPath         string | ||||
| 	GoFiles        []fs.FileInfo | ||||
| 	ImportPath     string | ||||
| 	InvalidGoFiles map[string]error // errors for particular files, if any | ||||
| 	Name           Token | ||||
| 	Scope          *Scope // Package scope. | ||||
| 	Version        string | ||||
| 	cfg            *Config | ||||
| 	guard          *importGuard | ||||
| 	mu             sync.Mutex | ||||
| 	typeCheck      TypeCheck | ||||
| 
 | ||||
| 	isUnsafe bool // ImportPath == "usnafe" | ||||
| 	// isChecked bool | ||||
| } | ||||
| 
 | ||||
| // NewPackage returns a Package, possibly cached, for importPath@version or an | ||||
| // error, if any. The fileFilter argument can be nil, in such case | ||||
| // DefaultFileFilter is used, which ignores Files with suffix _test.go unless | ||||
| // withTestFiles is true. | ||||
| // | ||||
| // NewPackage is safe for concurrent use by multiple goroutines. | ||||
| func (c *Config) NewPackage(dir, importPath, version string, fileFilter FileFilter, withTestFiles bool, typeCheck TypeCheck) (pkg *Package, err error) { | ||||
| 	return c.newPackage(dir, importPath, version, fileFilter, withTestFiles, typeCheck, newImportGuard()) | ||||
| } | ||||
| 
 | ||||
| func (c *Config) newPackage(dir, importPath, version string, fileFilter FileFilter, withTestFiles bool, typeCheck TypeCheck, guard *importGuard) (pkg *Package, err error) { | ||||
| 	if _, ok := guard.m[importPath]; ok { | ||||
| 		return nil, fmt.Errorf("import cycle %v", guard.stack) | ||||
| 	} | ||||
| 
 | ||||
| 	guard.stack = append(guard.stack, importPath) | ||||
| 	fsPath, err := c.lookup(dir, importPath, version) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("lookup %s: %v", importPath, err) | ||||
| 	} | ||||
| 
 | ||||
| 	pat := filepath.Join(fsPath, "*.go") | ||||
| 	matches, err := c.glob(pat) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("glob %s: %v", pat, err) | ||||
| 	} | ||||
| 
 | ||||
| 	if len(matches) == 0 { | ||||
| 		return nil, fmt.Errorf("no Go files in %s", fsPath) | ||||
| 	} | ||||
| 
 | ||||
| 	if fileFilter == nil { | ||||
| 		fileFilter = DefaultFileFilter | ||||
| 	} | ||||
| 	if matches, err = fileFilter(c, importPath, matches, withTestFiles); err != nil { | ||||
| 		return nil, fmt.Errorf("matching Go files in %s: %v", fsPath, err) | ||||
| 	} | ||||
| 
 | ||||
| 	var k cacheKey | ||||
| 	if c.cache != nil { | ||||
| 		k = cacheKey{ | ||||
| 			buildTagsKey:  c.buildTagsKey, | ||||
| 			cfg:           c, | ||||
| 			fsPath:        fsPath, | ||||
| 			goarch:        c.goarch, | ||||
| 			goos:          c.goos, | ||||
| 			gopathKey:     c.gopathKey, | ||||
| 			goroot:        c.goroot, | ||||
| 			importPath:    importPath, | ||||
| 			typeCheck:     typeCheck, | ||||
| 			withTestFiles: withTestFiles, | ||||
| 		} | ||||
| 
 | ||||
| 		c.cache.Lock() // ---------------------------------------- lock | ||||
| 		item, ok := c.cache.lru.Get(k) | ||||
| 		if ok { | ||||
| 			c.cache.Unlock() // ---------------------------- unlock | ||||
| 			if pkg = item.wait(); pkg != nil && pkg.matches(&k, matches) { | ||||
| 				return pkg, nil | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		item = newCacheItem() | ||||
| 		c.cache.lru.Add(k, item) | ||||
| 		c.cache.Unlock() // ------------------------------------ unlock | ||||
| 
 | ||||
| 		defer func() { | ||||
| 			if pkg != nil && err == nil { | ||||
| 				item.set(pkg) | ||||
| 			} | ||||
| 		}() | ||||
| 	} | ||||
| 
 | ||||
| 	r := &Package{ | ||||
| 		AST:        map[string]*AST{}, | ||||
| 		FSPath:     fsPath, | ||||
| 		ImportPath: importPath, | ||||
| 		Scope:      newScope(c.universe(), PackageScope), | ||||
| 		Version:    version, | ||||
| 		cfg:        c, | ||||
| 		guard:      guard, | ||||
| 		isUnsafe:   importPath == "unsafe", | ||||
| 		typeCheck:  typeCheck, | ||||
| 	} | ||||
| 
 | ||||
| 	defer func() { r.guard = nil }() | ||||
| 
 | ||||
| 	sort.Strings(matches) | ||||
| 
 | ||||
| 	defer func() { | ||||
| 		sort.Slice(r.GoFiles, func(i, j int) bool { return r.GoFiles[i].Name() < r.GoFiles[j].Name() }) | ||||
| 		if err != nil || len(r.InvalidGoFiles) != 0 || typeCheck == TypeCheckNone { | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		//TODO err = r.check(newCtx(c)) | ||||
| 	}() | ||||
| 
 | ||||
| 	c.parallel.throttle(func() { | ||||
| 		for _, path := range matches { | ||||
| 			if err = c.newPackageFile(r, path); err != nil { | ||||
| 				return | ||||
| 			} | ||||
| 		} | ||||
| 	}) | ||||
| 	return r, err | ||||
| } | ||||
| 
 | ||||
| func (c *Config) newPackageFile(pkg *Package, path string) (err error) { | ||||
| 	f, err := c.open(path) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("opening file %q: %v", path, err) | ||||
| 	} | ||||
| 
 | ||||
| 	defer func() { | ||||
| 		f.Close() | ||||
| 		if err != nil { | ||||
| 			if pkg.InvalidGoFiles == nil { | ||||
| 				pkg.InvalidGoFiles = map[string]error{} | ||||
| 			} | ||||
| 			pkg.InvalidGoFiles[path] = err | ||||
| 		} | ||||
| 	}() | ||||
| 
 | ||||
| 	var fi fs.FileInfo | ||||
| 	if fi, err = f.Stat(); err != nil { | ||||
| 		return fmt.Errorf("stat %s: %v", path, err) | ||||
| 	} | ||||
| 
 | ||||
| 	if !fi.Mode().IsRegular() { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	var b []byte | ||||
| 	if b, err = io.ReadAll(f); err != nil { | ||||
| 		return fmt.Errorf("reading %s: %v", path, err) | ||||
| 	} | ||||
| 
 | ||||
| 	p := newParser(pkg.Scope, path, b, false) | ||||
| 	if p.peek(0) == PACKAGE { | ||||
| 		tok := Token{p.s.source, p.s.toks[p.ix].ch, int32(p.ix)} | ||||
| 		if !c.checkConstraints(tok.Position(), tok.Sep()) { | ||||
| 			return nil | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	pkg.GoFiles = append(pkg.GoFiles, fi) | ||||
| 	var ast *AST | ||||
| 	if ast, err = p.parse(); err != nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	pkg.AST[path] = ast | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *Package) matches(k *cacheKey, matches []string) bool { | ||||
| 	matched := map[string]struct{}{} | ||||
| 	for _, match := range matches { | ||||
| 		matched[match] = struct{}{} | ||||
| 	} | ||||
| 	for _, cachedInfo := range p.GoFiles { | ||||
| 		name := cachedInfo.Name() | ||||
| 		path := filepath.Join(p.FSPath, name) | ||||
| 		if _, ok := matched[path]; !ok { | ||||
| 			return false | ||||
| 		} | ||||
| 
 | ||||
| 		info, err := k.cfg.stat(path) | ||||
| 		if err != nil { | ||||
| 			return false | ||||
| 		} | ||||
| 
 | ||||
| 		if info.IsDir() || | ||||
| 			info.Size() != cachedInfo.Size() || | ||||
| 			info.ModTime().After(cachedInfo.ModTime()) || | ||||
| 			info.Mode() != cachedInfo.Mode() { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
| 
 | ||||
| // ParseFile parses 'b', assuming it comes from 'path' and returns an AST or error, if any. | ||||
| func ParseFile(path string, b []byte) (*AST, error) { | ||||
| 	return newParser(newScope(nil, PackageScope), path, b, false).parse() | ||||
| } | ||||
							
								
								
									
										9415
									
								
								vendor/modernc.org/gc/v3/parser.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9415
									
								
								vendor/modernc.org/gc/v3/parser.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										1446
									
								
								vendor/modernc.org/gc/v3/scanner.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1446
									
								
								vendor/modernc.org/gc/v3/scanner.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										115
									
								
								vendor/modernc.org/gc/v3/stringer.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										115
									
								
								vendor/modernc.org/gc/v3/stringer.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,115 +0,0 @@ | |||
| // Code generated by "stringer -output stringer.go -linecomment -type=Kind,ScopeKind,ChanDir,TypeCheck"; DO NOT EDIT. | ||||
| 
 | ||||
| package gc | ||||
| 
 | ||||
| import "strconv" | ||||
| 
 | ||||
| func _() { | ||||
| 	// An "invalid array index" compiler error signifies that the constant values have changed. | ||||
| 	// Re-run the stringer command to generate them again. | ||||
| 	var x [1]struct{} | ||||
| 	_ = x[InvalidKind-0] | ||||
| 	_ = x[Array-1] | ||||
| 	_ = x[Bool-2] | ||||
| 	_ = x[Chan-3] | ||||
| 	_ = x[Complex128-4] | ||||
| 	_ = x[Complex64-5] | ||||
| 	_ = x[Float32-6] | ||||
| 	_ = x[Float64-7] | ||||
| 	_ = x[Function-8] | ||||
| 	_ = x[Int-9] | ||||
| 	_ = x[Int16-10] | ||||
| 	_ = x[Int32-11] | ||||
| 	_ = x[Int64-12] | ||||
| 	_ = x[Int8-13] | ||||
| 	_ = x[Interface-14] | ||||
| 	_ = x[Map-15] | ||||
| 	_ = x[Pointer-16] | ||||
| 	_ = x[Slice-17] | ||||
| 	_ = x[String-18] | ||||
| 	_ = x[Struct-19] | ||||
| 	_ = x[Tuple-20] | ||||
| 	_ = x[Uint-21] | ||||
| 	_ = x[Uint16-22] | ||||
| 	_ = x[Uint32-23] | ||||
| 	_ = x[Uint64-24] | ||||
| 	_ = x[Uint8-25] | ||||
| 	_ = x[Uintptr-26] | ||||
| 	_ = x[UnsafePointer-27] | ||||
| 	_ = x[UntypedBool-28] | ||||
| 	_ = x[UntypedComplex-29] | ||||
| 	_ = x[UntypedFloat-30] | ||||
| 	_ = x[UntypedInt-31] | ||||
| 	_ = x[UntypedNil-32] | ||||
| 	_ = x[UntypedRune-33] | ||||
| 	_ = x[UntypedString-34] | ||||
| } | ||||
| 
 | ||||
| const _Kind_name = "<invalid type>arrayboolchancomplex128complex64float32float64functionintint16int32int64int8interfacemappointerslicestringstructtupleuintuint16uint32uint64uint8uintptrunsafe.Pointeruntyped booluntyped complexuntyped floatuntyped intuntyped niluntyped runeuntyped string" | ||||
| 
 | ||||
| var _Kind_index = [...]uint16{0, 14, 19, 23, 27, 37, 46, 53, 60, 68, 71, 76, 81, 86, 90, 99, 102, 109, 114, 120, 126, 131, 135, 141, 147, 153, 158, 165, 179, 191, 206, 219, 230, 241, 253, 267} | ||||
| 
 | ||||
| func (i Kind) String() string { | ||||
| 	if i >= Kind(len(_Kind_index)-1) { | ||||
| 		return "Kind(" + strconv.FormatInt(int64(i), 10) + ")" | ||||
| 	} | ||||
| 	return _Kind_name[_Kind_index[i]:_Kind_index[i+1]] | ||||
| } | ||||
| func _() { | ||||
| 	// An "invalid array index" compiler error signifies that the constant values have changed. | ||||
| 	// Re-run the stringer command to generate them again. | ||||
| 	var x [1]struct{} | ||||
| 	_ = x[scZero-0] | ||||
| 	_ = x[UniverseScope-1] | ||||
| 	_ = x[PackageScope-2] | ||||
| 	_ = x[FileScope-3] | ||||
| 	_ = x[OtherScope-4] | ||||
| } | ||||
| 
 | ||||
| const _ScopeKind_name = "scZeroUniverseScopePackageScopeFileScopeOtherScope" | ||||
| 
 | ||||
| var _ScopeKind_index = [...]uint8{0, 6, 19, 31, 40, 50} | ||||
| 
 | ||||
| func (i ScopeKind) String() string { | ||||
| 	if i < 0 || i >= ScopeKind(len(_ScopeKind_index)-1) { | ||||
| 		return "ScopeKind(" + strconv.FormatInt(int64(i), 10) + ")" | ||||
| 	} | ||||
| 	return _ScopeKind_name[_ScopeKind_index[i]:_ScopeKind_index[i+1]] | ||||
| } | ||||
| func _() { | ||||
| 	// An "invalid array index" compiler error signifies that the constant values have changed. | ||||
| 	// Re-run the stringer command to generate them again. | ||||
| 	var x [1]struct{} | ||||
| 	_ = x[SendRecv-0] | ||||
| 	_ = x[SendOnly-1] | ||||
| 	_ = x[RecvOnly-2] | ||||
| } | ||||
| 
 | ||||
| const _ChanDir_name = "SendRecvSendOnlyRecvOnly" | ||||
| 
 | ||||
| var _ChanDir_index = [...]uint8{0, 8, 16, 24} | ||||
| 
 | ||||
| func (i ChanDir) String() string { | ||||
| 	if i < 0 || i >= ChanDir(len(_ChanDir_index)-1) { | ||||
| 		return "ChanDir(" + strconv.FormatInt(int64(i), 10) + ")" | ||||
| 	} | ||||
| 	return _ChanDir_name[_ChanDir_index[i]:_ChanDir_index[i+1]] | ||||
| } | ||||
| func _() { | ||||
| 	// An "invalid array index" compiler error signifies that the constant values have changed. | ||||
| 	// Re-run the stringer command to generate them again. | ||||
| 	var x [1]struct{} | ||||
| 	_ = x[TypeCheckNone-0] | ||||
| 	_ = x[TypeCheckAll-1] | ||||
| } | ||||
| 
 | ||||
| const _TypeCheck_name = "TypeCheckNoneTypeCheckAll" | ||||
| 
 | ||||
| var _TypeCheck_index = [...]uint8{0, 13, 25} | ||||
| 
 | ||||
| func (i TypeCheck) String() string { | ||||
| 	if i < 0 || i >= TypeCheck(len(_TypeCheck_index)-1) { | ||||
| 		return "TypeCheck(" + strconv.FormatInt(int64(i), 10) + ")" | ||||
| 	} | ||||
| 	return _TypeCheck_name[_TypeCheck_index[i]:_TypeCheck_index[i+1]] | ||||
| } | ||||
							
								
								
									
										90
									
								
								vendor/modernc.org/gc/v3/syslist.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										90
									
								
								vendor/modernc.org/gc/v3/syslist.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,90 +0,0 @@ | |||
| // Copyright 2011 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the GO-LICENSE file. | ||||
| 
 | ||||
| // Modifications | ||||
| // | ||||
| // Copyright 2022 The Gc Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| // package build // /usr/local/go/src/go/build/syslist.go | ||||
| 
 | ||||
| package gc // import "modernc.org/gc/v3" | ||||
| 
 | ||||
| // Go 1.19.3 | ||||
| 
 | ||||
| // Note that this file is read by internal/goarch/gengoarch.go and by | ||||
| // internal/goos/gengoos.go. If you change this file, look at those | ||||
| // files as well. | ||||
| 
 | ||||
| // knownOS is the list of past, present, and future known GOOS values. | ||||
| // Do not remove from this list, as it is used for filename matching. | ||||
| // If you add an entry to this list, look at unixOS, below. | ||||
| var knownOS = map[string]bool{ | ||||
| 	"aix":       true, | ||||
| 	"android":   true, | ||||
| 	"darwin":    true, | ||||
| 	"dragonfly": true, | ||||
| 	"freebsd":   true, | ||||
| 	"hurd":      true, | ||||
| 	"illumos":   true, | ||||
| 	"ios":       true, | ||||
| 	"js":        true, | ||||
| 	"linux":     true, | ||||
| 	"nacl":      true, | ||||
| 	"netbsd":    true, | ||||
| 	"openbsd":   true, | ||||
| 	"plan9":     true, | ||||
| 	"solaris":   true, | ||||
| 	"windows":   true, | ||||
| 	"zos":       true, | ||||
| } | ||||
| 
 | ||||
| // unixOS is the set of GOOS values matched by the "unix" build tag. | ||||
| // This is not used for filename matching. | ||||
| // This list also appears in cmd/dist/build.go and | ||||
| // cmd/go/internal/imports/build.go. | ||||
| var unixOS = map[string]bool{ | ||||
| 	"aix":       true, | ||||
| 	"android":   true, | ||||
| 	"darwin":    true, | ||||
| 	"dragonfly": true, | ||||
| 	"freebsd":   true, | ||||
| 	"hurd":      true, | ||||
| 	"illumos":   true, | ||||
| 	"ios":       true, | ||||
| 	"linux":     true, | ||||
| 	"netbsd":    true, | ||||
| 	"openbsd":   true, | ||||
| 	"solaris":   true, | ||||
| } | ||||
| 
 | ||||
| // knownArch is the list of past, present, and future known GOARCH values. | ||||
| // Do not remove from this list, as it is used for filename matching. | ||||
| var knownArch = map[string]bool{ | ||||
| 	"386":         true, | ||||
| 	"amd64":       true, | ||||
| 	"amd64p32":    true, | ||||
| 	"arm":         true, | ||||
| 	"armbe":       true, | ||||
| 	"arm64":       true, | ||||
| 	"arm64be":     true, | ||||
| 	"loong64":     true, | ||||
| 	"mips":        true, | ||||
| 	"mipsle":      true, | ||||
| 	"mips64":      true, | ||||
| 	"mips64le":    true, | ||||
| 	"mips64p32":   true, | ||||
| 	"mips64p32le": true, | ||||
| 	"ppc":         true, | ||||
| 	"ppc64":       true, | ||||
| 	"ppc64le":     true, | ||||
| 	"riscv":       true, | ||||
| 	"riscv64":     true, | ||||
| 	"s390":        true, | ||||
| 	"s390x":       true, | ||||
| 	"sparc":       true, | ||||
| 	"sparc64":     true, | ||||
| 	"wasm":        true, | ||||
| } | ||||
							
								
								
									
										813
									
								
								vendor/modernc.org/gc/v3/type.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										813
									
								
								vendor/modernc.org/gc/v3/type.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,813 +0,0 @@ | |||
| // Copyright 2022 The Gc Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| package gc // modernc.org/gc/v3 | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"go/token" | ||||
| 	"strings" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	Invalid = &InvalidType{} | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	_ Type = (*ArrayTypeNode)(nil) | ||||
| 	_ Type = (*ChannelTypeNode)(nil) | ||||
| 	_ Type = (*FunctionTypeNode)(nil) | ||||
| 	_ Type = (*InterfaceTypeNode)(nil) | ||||
| 	_ Type = (*InvalidType)(nil) | ||||
| 	_ Type = (*MapTypeNode)(nil) | ||||
| 	_ Type = (*ParenthesizedTypeNode)(nil) | ||||
| 	_ Type = (*PointerTypeNode)(nil) | ||||
| 	_ Type = (*PredeclaredType)(nil) | ||||
| 	_ Type = (*SliceTypeNode)(nil) | ||||
| 	_ Type = (*StructTypeNode)(nil) | ||||
| 	_ Type = (*TupleType)(nil) | ||||
| 	_ Type = (*TypeDefNode)(nil) | ||||
| 	_ Type = (*TypeNameNode)(nil) | ||||
| 	_ Type = (*TypeNode)(nil) | ||||
| 
 | ||||
| 	invalidRecursiveType = &InvalidType{} | ||||
| ) | ||||
| 
 | ||||
| // A Kind represents the specific kind of type that a Type represents. The zero | ||||
| // Kind is not a valid kind. | ||||
| type Kind byte | ||||
| 
 | ||||
| // Values of type Kind | ||||
| const ( | ||||
| 	InvalidKind Kind = iota // <invalid type> | ||||
| 
 | ||||
| 	Array          // array | ||||
| 	Bool           // bool | ||||
| 	Chan           // chan | ||||
| 	Complex128     // complex128 | ||||
| 	Complex64      // complex64 | ||||
| 	Float32        // float32 | ||||
| 	Float64        // float64 | ||||
| 	Function       // function | ||||
| 	Int            // int | ||||
| 	Int16          // int16 | ||||
| 	Int32          // int32 | ||||
| 	Int64          // int64 | ||||
| 	Int8           // int8 | ||||
| 	Interface      // interface | ||||
| 	Map            // map | ||||
| 	Pointer        // pointer | ||||
| 	Slice          // slice | ||||
| 	String         // string | ||||
| 	Struct         // struct | ||||
| 	Tuple          // tuple | ||||
| 	Uint           // uint | ||||
| 	Uint16         // uint16 | ||||
| 	Uint32         // uint32 | ||||
| 	Uint64         // uint64 | ||||
| 	Uint8          // uint8 | ||||
| 	Uintptr        // uintptr | ||||
| 	UnsafePointer  // unsafe.Pointer | ||||
| 	UntypedBool    // untyped bool | ||||
| 	UntypedComplex // untyped complex | ||||
| 	UntypedFloat   // untyped float | ||||
| 	UntypedInt     // untyped int | ||||
| 	UntypedNil     // untyped nil | ||||
| 	UntypedRune    // untyped rune | ||||
| 	UntypedString  // untyped string | ||||
| ) | ||||
| 
 | ||||
| type typeSetter interface { | ||||
| 	setType(t Type) Type | ||||
| } | ||||
| 
 | ||||
| type typeCache struct { | ||||
| 	t Type | ||||
| } | ||||
| 
 | ||||
| func (n *typeCache) Type() Type { | ||||
| 	if n.t != nil { | ||||
| 		return n.t | ||||
| 	} | ||||
| 
 | ||||
| 	n.t = Invalid | ||||
| 	return Invalid | ||||
| } | ||||
| 
 | ||||
| func (n *typeCache) setType(t Type) Type { | ||||
| 	n.t = t | ||||
| 	return t | ||||
| } | ||||
| 
 | ||||
| func (n *typeCache) enter(c *ctx, nd Node) bool { | ||||
| 	switch { | ||||
| 	case n.t == nil: | ||||
| 		n.t = invalidRecursiveType | ||||
| 		return true | ||||
| 	case n.t == invalidRecursiveType: | ||||
| 		n.t = Invalid | ||||
| 		c.err(nd, "invalid recursive type") | ||||
| 		return false | ||||
| 	default: | ||||
| 		return false | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| type typer interface { | ||||
| 	Type() Type | ||||
| } | ||||
| 
 | ||||
| type Type interface { | ||||
| 	Node | ||||
| 
 | ||||
| 	// Align returns the alignment in bytes of a value of this type when allocated | ||||
| 	// in memory. | ||||
| 	Align() int | ||||
| 
 | ||||
| 	// FieldAlign returns the alignment in bytes of a value of this type when used | ||||
| 	// as a field in a struct. | ||||
| 	FieldAlign() int | ||||
| 
 | ||||
| 	// Kind returns the specific kind of this type. | ||||
| 	Kind() Kind | ||||
| 
 | ||||
| 	// Size returns the number of bytes needed to store a value of the given type; | ||||
| 	// it is analogous to unsafe.Sizeof. | ||||
| 	Size() int64 | ||||
| 
 | ||||
| 	// String returns a string representation of the type.  The string | ||||
| 	// representation is not guaranteed to be unique among types. | ||||
| 	String() string | ||||
| 
 | ||||
| 	check(c *ctx) Type | ||||
| } | ||||
| 
 | ||||
| func (n *ArrayTypeNode) Align() int      { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *ArrayTypeNode) FieldAlign() int { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *ArrayTypeNode) Kind() Kind      { return Array } | ||||
| func (n *ArrayTypeNode) Size() int64     { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *ArrayTypeNode) String() string { | ||||
| 	return fmt.Sprintf("[%v]%v", n.ArrayLength.Value(), n.ElementType) | ||||
| } | ||||
| 
 | ||||
| func (n *ArrayTypeNode) check(c *ctx) Type { | ||||
| 	if n == nil { | ||||
| 		return Invalid | ||||
| 	} | ||||
| 
 | ||||
| 	n.ArrayLength = n.ArrayLength.checkExpr(c) | ||||
| 	v := c.convertValue(n.ArrayLength, n.ArrayLength.Value(), c.cfg.int) | ||||
| 	if !known(v) { | ||||
| 		return Invalid | ||||
| 	} | ||||
| 
 | ||||
| 	n.ElementType.check(c) | ||||
| 	return n | ||||
| } | ||||
| 
 | ||||
| // ChanDir represents a channel direction. | ||||
| type ChanDir int | ||||
| 
 | ||||
| // Values of type ChanDir. | ||||
| const ( | ||||
| 	SendRecv ChanDir = iota | ||||
| 	SendOnly | ||||
| 	RecvOnly | ||||
| ) | ||||
| 
 | ||||
| func (n *ChannelTypeNode) Align() int { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| 
 | ||||
| func (n *ChannelTypeNode) FieldAlign() int { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *ChannelTypeNode) Kind() Kind     { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *ChannelTypeNode) Size() int64    { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *ChannelTypeNode) String() string { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *ChannelTypeNode) check(c *ctx) Type { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *FunctionTypeNode) Align() int { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| 
 | ||||
| func (n *FunctionTypeNode) FieldAlign() int { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *FunctionTypeNode) Kind() Kind  { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *FunctionTypeNode) Size() int64 { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *FunctionTypeNode) String() string { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| func (n *FunctionTypeNode) check(c *ctx) Type { | ||||
| 	if !n.enter(c, n) { | ||||
| 		if n.guard == guardChecking { | ||||
| 			return Invalid | ||||
| 		} | ||||
| 
 | ||||
| 		return n | ||||
| 	} | ||||
| 
 | ||||
| 	defer func() { n.guard = guardChecked }() | ||||
| 
 | ||||
| 	n.Signature.check(c) | ||||
| 	return n | ||||
| } | ||||
| 
 | ||||
| func (n *InterfaceTypeNode) Align() int { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| 
 | ||||
| func (n *InterfaceTypeNode) FieldAlign() int { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *InterfaceTypeNode) Kind() Kind  { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *InterfaceTypeNode) Size() int64 { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *InterfaceTypeNode) String() string { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| func (n *InterfaceTypeNode) check(c *ctx) Type { | ||||
| 	if !n.enter(c, n) { | ||||
| 		if n.guard == guardChecking { | ||||
| 			return Invalid | ||||
| 		} | ||||
| 
 | ||||
| 		return n | ||||
| 	} | ||||
| 
 | ||||
| 	defer func() { n.guard = guardChecked }() | ||||
| 
 | ||||
| 	n.InterfaceElemList.check(c, n) | ||||
| 	return n | ||||
| } | ||||
| 
 | ||||
| func (n *InterfaceElemListNode) check(c *ctx, t *InterfaceTypeNode) { | ||||
| 	if n == nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	for l := n; l != nil; l = l.List { | ||||
| 		l.InterfaceElem.check(c, t) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (n *InterfaceElemNode) check(c *ctx, t *InterfaceTypeNode) { | ||||
| 	if n == nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	n.MethodElem.check(c, t) | ||||
| 	n.TypeElem.check(c) | ||||
| } | ||||
| 
 | ||||
| func (n *MethodElemNode) check(c *ctx, t *InterfaceTypeNode) { | ||||
| 	if n == nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	nm := n.MethodName.Src() | ||||
| 	if ex := t.methods[nm]; ex != nil { | ||||
| 		panic(todo("")) | ||||
| 	} | ||||
| 
 | ||||
| 	if t.methods == nil { | ||||
| 		t.methods = map[string]*MethodElemNode{} | ||||
| 	} | ||||
| 	t.methods[nm] = n | ||||
| 	n.typ = n.Signature.check(c) | ||||
| } | ||||
| 
 | ||||
| func (n *TypeElemListNode) check(c *ctx) { | ||||
| 	if n == nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| type InvalidType struct{} | ||||
| 
 | ||||
| func (n *InvalidType) Align() int                   { return 1 } | ||||
| func (n *InvalidType) FieldAlign() int              { return 1 } | ||||
| func (n *InvalidType) Kind() Kind                   { return InvalidKind } | ||||
| func (n *InvalidType) Position() (r token.Position) { return r } | ||||
| func (n *InvalidType) Size() int64                  { return 1 } | ||||
| func (n *InvalidType) Source(full bool) string      { return "<invalid type>" } | ||||
| func (n *InvalidType) String() string               { return "<invalid type>" } | ||||
| func (n *InvalidType) check(c *ctx) Type            { return n } | ||||
| 
 | ||||
| func (n *MapTypeNode) Align() int        { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *MapTypeNode) FieldAlign() int   { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *MapTypeNode) Kind() Kind        { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *MapTypeNode) Size() int64       { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *MapTypeNode) String() string    { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *MapTypeNode) check(c *ctx) Type { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| 
 | ||||
| func (n *ParenthesizedTypeNode) Align() int { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *ParenthesizedTypeNode) FieldAlign() int { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *ParenthesizedTypeNode) Kind() Kind { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *ParenthesizedTypeNode) Size() int64 { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *ParenthesizedTypeNode) String() string { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *ParenthesizedTypeNode) check(c *ctx) Type { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *PointerTypeNode) Align() int { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| 
 | ||||
| func (n *PointerTypeNode) FieldAlign() int { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *PointerTypeNode) Kind() Kind     { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *PointerTypeNode) Size() int64    { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *PointerTypeNode) String() string { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| 
 | ||||
| func (n *PointerTypeNode) check(c *ctx) Type { | ||||
| 	if !n.enter(c, n) { | ||||
| 		if n.guard == guardChecking { | ||||
| 			return Invalid | ||||
| 		} | ||||
| 
 | ||||
| 		return n | ||||
| 	} | ||||
| 
 | ||||
| 	defer func() { n.guard = guardChecked }() | ||||
| 
 | ||||
| 	switch x := n.BaseType.(type) { | ||||
| 	case *TypeNameNode: | ||||
| 		x.checkDefined(c) | ||||
| 	default: | ||||
| 		panic(todo("%v: %T %s", n.Position(), x, n.Source(false))) | ||||
| 	} | ||||
| 	return n | ||||
| } | ||||
| 
 | ||||
| type PredeclaredType struct { | ||||
| 	Node | ||||
| 	kind Kind | ||||
| 	t    ABIType | ||||
| } | ||||
| 
 | ||||
| func (c *ctx) newPredeclaredType(n Node, kind Kind) *PredeclaredType { | ||||
| 	t, ok := c.cfg.abi.Types[kind] | ||||
| 	if !ok && !isAnyUntypedKind(kind) { | ||||
| 		panic(todo("%v: internal error %s: %s", n.Position(), n.Source(false), kind)) | ||||
| 	} | ||||
| 
 | ||||
| 	return &PredeclaredType{ | ||||
| 		Node: n, | ||||
| 		kind: kind, | ||||
| 		t:    t, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (n *PredeclaredType) Align() int { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| 
 | ||||
| func (n *PredeclaredType) FieldAlign() int { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *PredeclaredType) Kind() Kind  { return n.kind } | ||||
| func (n *PredeclaredType) Size() int64 { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| 
 | ||||
| func (n *PredeclaredType) String() string { | ||||
| 	switch n.Kind() { | ||||
| 	case | ||||
| 		String, | ||||
| 		UntypedInt: | ||||
| 
 | ||||
| 		return n.Kind().String() | ||||
| 	default: | ||||
| 		panic(todo("%v: %s %s", n.Position(), n.Kind(), n.Source(false))) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (n *PredeclaredType) check(c *ctx) Type { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *SliceTypeNode) Align() int      { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *SliceTypeNode) FieldAlign() int { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *SliceTypeNode) Kind() Kind      { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *SliceTypeNode) Size() int64     { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *SliceTypeNode) String() string  { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| 
 | ||||
| func (n *SliceTypeNode) check(c *ctx) Type { | ||||
| 	if !n.enter(c, n) { | ||||
| 		if n.guard == guardChecking { | ||||
| 			return Invalid | ||||
| 		} | ||||
| 
 | ||||
| 		return n | ||||
| 	} | ||||
| 
 | ||||
| 	defer func() { n.guard = guardChecked }() | ||||
| 
 | ||||
| 	switch x := n.ElementType.(type) { | ||||
| 	case *TypeNameNode: | ||||
| 		x.checkDefined(c) | ||||
| 	default: | ||||
| 		panic(todo("%v: %T %s", n.Position(), x, n.Source(false))) | ||||
| 	} | ||||
| 	return n | ||||
| } | ||||
| 
 | ||||
| type Field struct { | ||||
| 	Declaration *FieldDeclNode | ||||
| 	Name        string | ||||
| } | ||||
| 
 | ||||
| func (n *StructTypeNode) Align() int      { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *StructTypeNode) FieldAlign() int { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *StructTypeNode) Kind() Kind      { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *StructTypeNode) Size() int64     { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *StructTypeNode) String() string  { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| 
 | ||||
| func (n *StructTypeNode) check(c *ctx) Type { | ||||
| 	if !n.enter(c, n) { | ||||
| 		if n.guard == guardChecking { | ||||
| 			return Invalid | ||||
| 		} | ||||
| 
 | ||||
| 		return n | ||||
| 	} | ||||
| 
 | ||||
| 	defer func() { n.guard = guardChecked }() | ||||
| 
 | ||||
| 	for l := n.FieldDeclList; l != nil; l = l.List { | ||||
| 		n.fields = append(n.fields, l.check(c)...) | ||||
| 	} | ||||
| 	return n | ||||
| } | ||||
| 
 | ||||
| func (n *FieldDeclListNode) check(c *ctx) []Field { | ||||
| 	return n.FieldDecl.check(c) | ||||
| } | ||||
| 
 | ||||
| func (n *FieldDeclNode) check(c *ctx) (r []Field) { | ||||
| 	switch { | ||||
| 	case n.EmbeddedField != nil: | ||||
| 		panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| 	default: | ||||
| 		n.TypeNode.check(c) | ||||
| 		for l := n.IdentifierList; l != nil; l = l.List { | ||||
| 			r = append(r, Field{n, l.IDENT.Src()}) | ||||
| 		} | ||||
| 	} | ||||
| 	return r | ||||
| } | ||||
| 
 | ||||
| type TupleType struct { | ||||
| 	Node | ||||
| 	Types []Type | ||||
| } | ||||
| 
 | ||||
| func newTupleType(n Node, types []Type) *TupleType { return &TupleType{n, types} } | ||||
| 
 | ||||
| func (n *TupleType) Align() int      { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *TupleType) FieldAlign() int { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *TupleType) Kind() Kind      { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| 
 | ||||
| func (n *TupleType) Size() int64 { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| 
 | ||||
| func (n *TupleType) Source(full bool) (r string) { | ||||
| 	if n.Node != nil { | ||||
| 		r = n.Node.Source(full) | ||||
| 	} | ||||
| 	return r | ||||
| } | ||||
| 
 | ||||
| func (n *TupleType) String() string { | ||||
| 	var a []string | ||||
| 	for _, v := range n.Types { | ||||
| 		a = append(a, v.String()) | ||||
| 	} | ||||
| 	return fmt.Sprintf("(%s)", strings.Join(a, ", ")) | ||||
| } | ||||
| 
 | ||||
| func (n *TupleType) check(c *ctx) Type { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *TypeDefNode) Align() int      { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *TypeDefNode) FieldAlign() int { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *TypeDefNode) Kind() Kind      { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *TypeDefNode) Size() int64     { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *TypeDefNode) String() string  { return fmt.Sprintf("%s.%s", n.pkg.ImportPath, n.IDENT.Src()) } | ||||
| 
 | ||||
| func (n *TypeDefNode) check(c *ctx) Type { | ||||
| 	if n == nil { | ||||
| 		return Invalid | ||||
| 	} | ||||
| 
 | ||||
| 	if n.pkg != nil { | ||||
| 		return n | ||||
| 	} | ||||
| 
 | ||||
| 	n.pkg = c.pkg | ||||
| 	if n.TypeParameters != nil { | ||||
| 		panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| 	} | ||||
| 
 | ||||
| 	switch x := n.TypeNode.check(c).(type) { | ||||
| 	case *PredeclaredType: | ||||
| 		n.TypeNode = x | ||||
| 	} | ||||
| 	return n | ||||
| } | ||||
| 
 | ||||
| func (n *TypeNameNode) Align() int      { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *TypeNameNode) FieldAlign() int { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *TypeNameNode) Kind() Kind      { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *TypeNameNode) Size() int64     { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *TypeNameNode) String() string  { return n.Name.Source(false) } | ||||
| 
 | ||||
| func (n *TypeNameNode) checkDefined(c *ctx) bool { | ||||
| 	switch x := n.Name.(type) { | ||||
| 	case Token: | ||||
| 		switch _, nmd := n.LexicalScope().lookup(x); y := nmd.n.(type) { | ||||
| 		case *TypeDefNode, *AliasDeclNode: | ||||
| 			return true | ||||
| 		default: | ||||
| 			panic(todo("%v: type=%T %s", y.Position(), y, y.Source(false))) | ||||
| 		} | ||||
| 	case *QualifiedIdentNode: | ||||
| 		if !token.IsExported(x.IDENT.Src()) { | ||||
| 			panic(todo("")) | ||||
| 		} | ||||
| 
 | ||||
| 		switch _, nmd := n.LexicalScope().lookup(x.PackageName); y := nmd.n.(type) { | ||||
| 		case *ImportSpecNode: | ||||
| 			if y.pkg == nil { | ||||
| 				panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| 			} | ||||
| 
 | ||||
| 			switch _, nmd := y.pkg.Scope.lookup(x.IDENT); z := nmd.n.(type) { | ||||
| 			case *TypeDefNode, *AliasDeclNode: | ||||
| 				return true | ||||
| 			default: | ||||
| 				panic(todo("%v: type=%T %s", z.Position(), z, z.Source(false))) | ||||
| 			} | ||||
| 		default: | ||||
| 			panic(todo("%v: type=%T %s", y.Position(), y, y.Source(false))) | ||||
| 		} | ||||
| 	default: | ||||
| 		panic(todo("%v: type=%T %s", n.Position(), x, n.Source(false))) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (n *TypeNameNode) check(c *ctx) Type { | ||||
| 	if n == nil { | ||||
| 		return Invalid | ||||
| 	} | ||||
| 
 | ||||
| 	switch x := n.Name.(type) { | ||||
| 	case Token: | ||||
| 		nm := x.Src() | ||||
| 		if c.isBuiltin() { | ||||
| 			switch nm { | ||||
| 			case "bool": | ||||
| 				return c.newPredeclaredType(n, Bool) | ||||
| 			case "uint8": | ||||
| 				return c.newPredeclaredType(n, Uint8) | ||||
| 			case "uint16": | ||||
| 				return c.newPredeclaredType(n, Uint16) | ||||
| 			case "uint32": | ||||
| 				return c.newPredeclaredType(n, Uint32) | ||||
| 			case "uint64": | ||||
| 				return c.newPredeclaredType(n, Uint64) | ||||
| 			case "int8": | ||||
| 				return c.newPredeclaredType(n, Int8) | ||||
| 			case "int16": | ||||
| 				return c.newPredeclaredType(n, Int16) | ||||
| 			case "int32": | ||||
| 				return c.newPredeclaredType(n, Int32) | ||||
| 			case "int64": | ||||
| 				return c.newPredeclaredType(n, Int64) | ||||
| 			case "float32": | ||||
| 				return c.newPredeclaredType(n, Float32) | ||||
| 			case "float64": | ||||
| 				return c.newPredeclaredType(n, Float64) | ||||
| 			case "complex64": | ||||
| 				return c.newPredeclaredType(n, Complex64) | ||||
| 			case "complex128": | ||||
| 				return c.newPredeclaredType(n, Complex128) | ||||
| 			case "string": | ||||
| 				return c.newPredeclaredType(n, String) | ||||
| 			case "int": | ||||
| 				return c.newPredeclaredType(n, Int) | ||||
| 			case "uint": | ||||
| 				return c.newPredeclaredType(n, Uint) | ||||
| 			case "uintptr": | ||||
| 				return c.newPredeclaredType(n, Uintptr) | ||||
| 			case "Type": | ||||
| 				// ok | ||||
| 			default: | ||||
| 				panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		pkg, _, nmd := c.lookup(n.LexicalScope(), x) | ||||
| 		switch y := nmd.n.(type) { | ||||
| 		case *TypeDefNode: | ||||
| 			if pkg != c.pkg { | ||||
| 				return y | ||||
| 			} | ||||
| 
 | ||||
| 			return y.check(c) | ||||
| 		case nil: | ||||
| 			panic(todo("%v: %T %s", x.Position(), y, x.Source(false))) | ||||
| 		default: | ||||
| 			panic(todo("%v: %T %s", y.Position(), y, y.Source(false))) | ||||
| 		} | ||||
| 	default: | ||||
| 		panic(todo("%v: %T %s", n.Position(), x, n.Source(false))) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (n *TypeNode) Align() int        { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *TypeNode) FieldAlign() int   { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *TypeNode) Kind() Kind        { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *TypeNode) Size() int64       { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *TypeNode) String() string    { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| func (n *TypeNode) check(c *ctx) Type { panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) } | ||||
| 
 | ||||
| func isAnyUntypedType(t Type) bool { return isAnyUntypedKind(t.Kind()) } | ||||
| 
 | ||||
| func isAnyUntypedKind(k Kind) bool { | ||||
| 	switch k { | ||||
| 	case UntypedBool, UntypedComplex, UntypedFloat, UntypedInt, UntypedNil, UntypedRune, UntypedString: | ||||
| 		return true | ||||
| 	} | ||||
| 
 | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| const ( | ||||
| 	guardUnchecked guard = iota | ||||
| 	guardChecking | ||||
| 	guardChecked | ||||
| ) | ||||
| 
 | ||||
| type guard byte | ||||
| 
 | ||||
| func (n *guard) enter(c *ctx, nd Node) bool { | ||||
| 	switch *n { | ||||
| 	case guardUnchecked: | ||||
| 		*n = guardChecking | ||||
| 		return true | ||||
| 	case guardChecking: | ||||
| 		c.err(nd, "invalid recursive type") | ||||
| 		return false | ||||
| 	default: | ||||
| 		return false | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func isAnyArithmeticType(t Type) bool { return isArithmeticType(t) || isUntypedArithmeticType(t) } | ||||
| 
 | ||||
| func isUntypedArithmeticType(t Type) bool { | ||||
| 	switch t.Kind() { | ||||
| 	case UntypedInt, UntypedFloat, UntypedComplex: | ||||
| 		return true | ||||
| 	default: | ||||
| 		return false | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func isArithmeticType(t Type) bool { | ||||
| 	return isIntegerType(t) || isFloatType(t) || isComplexType(t) | ||||
| } | ||||
| 
 | ||||
| func isComplexType(t Type) bool { | ||||
| 	switch t.Kind() { | ||||
| 	case Complex64, Complex128: | ||||
| 		return true | ||||
| 	default: | ||||
| 		return false | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func isFloatType(t Type) bool { | ||||
| 	switch t.Kind() { | ||||
| 	case Float32, Float64: | ||||
| 		return true | ||||
| 	default: | ||||
| 		return false | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func isIntegerType(t Type) bool { | ||||
| 	switch t.Kind() { | ||||
| 	case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr: | ||||
| 		return true | ||||
| 	default: | ||||
| 		return false | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (c *ctx) isIdentical(n Node, t, u Type) bool { | ||||
| 	tk := t.Kind() | ||||
| 	uk := u.Kind() | ||||
| 	if tk != uk { | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	if t == u { | ||||
| 		return true | ||||
| 	} | ||||
| 
 | ||||
| 	if isAnyUntypedKind(tk) && isAnyUntypedKind(uk) && tk == uk { | ||||
| 		return true | ||||
| 	} | ||||
| 
 | ||||
| 	switch x := t.(type) { | ||||
| 	// case *ArrayTypeNode: | ||||
| 	// 	switch y := u.(type) { | ||||
| 	// 	case *ArrayTypeNode: | ||||
| 	// 		return x.Len == y.Len && c.isIdentical(n, x.Elem, y.Elem) | ||||
| 	// 	} | ||||
| 	// case *StructType: | ||||
| 	// 	switch y := u.(type) { | ||||
| 	// 	case *StructType: | ||||
| 	// 		if len(x.Fields) != len(y.Fields) { | ||||
| 	// 			return false | ||||
| 	// 		} | ||||
| 
 | ||||
| 	// 		for i, v := range x.Fields { | ||||
| 	// 			w := y.Fields[i] | ||||
| 	// 			if v.Name != w.Name || !c.isIdentical(n, v.Type(), w.Type()) { | ||||
| 	// 				return false | ||||
| 	// 			} | ||||
| 	// 		} | ||||
| 
 | ||||
| 	// 		return true | ||||
| 	// 	} | ||||
| 	// case *FunctionType: | ||||
| 	// 	switch y := u.(type) { | ||||
| 	// 	case *FunctionType: | ||||
| 	// 		in, out := x.Parameters.Types, x.Result.Types | ||||
| 	// 		in2, out2 := y.Parameters.Types, y.Result.Types | ||||
| 	// 		if len(in) != len(in2) || len(out) != len(out2) { | ||||
| 	// 			return false | ||||
| 	// 		} | ||||
| 
 | ||||
| 	// 		for i, v := range in { | ||||
| 	// 			if !c.isIdentical(n, v, in2[i]) { | ||||
| 	// 				return false | ||||
| 	// 			} | ||||
| 	// 		} | ||||
| 
 | ||||
| 	// 		for i, v := range out { | ||||
| 	// 			if !c.isIdentical(n, v, out2[i]) { | ||||
| 	// 				return false | ||||
| 	// 			} | ||||
| 	// 		} | ||||
| 
 | ||||
| 	// 		return true | ||||
| 	// 	} | ||||
| 	// case *PointerType: | ||||
| 	// 	switch y := u.(type) { | ||||
| 	// 	case *PointerType: | ||||
| 	// 		return c.isIdentical(n, x.Elem, y.Elem) | ||||
| 	// 	} | ||||
| 	default: | ||||
| 		c.err(n, "TODO %v %v", x, u) | ||||
| 	} | ||||
| 
 | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| func (c *ctx) mustIdentical(n Node, t, u Type) bool { | ||||
| 	if !c.isIdentical(n, t, u) { | ||||
| 		c.err(n, "incompatible types: %v and %v", t, u) | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	return true | ||||
| } | ||||
| 
 | ||||
| func (c *ctx) checkType(n Node) Type { | ||||
| 	switch x := n.(type) { | ||||
| 	case *ArrayTypeNode: | ||||
| 		return x.check(c) | ||||
| 	default: | ||||
| 		c.err(n, "TODO %T", x) | ||||
| 		return Invalid | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										716
									
								
								vendor/modernc.org/gc/v3/value.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										716
									
								
								vendor/modernc.org/gc/v3/value.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,716 +0,0 @@ | |||
| // Copyright 2022 The Gc Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| package gc // modernc.org/gc/v3 | ||||
| 
 | ||||
| import ( | ||||
| 	"go/constant" | ||||
| 	"math" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	_ Expression = (*BasicLitNode)(nil) | ||||
| 	_ Expression = (*BinaryExpressionNode)(nil) | ||||
| 	_ Expression = (*CompositeLitNode)(nil) | ||||
| 	_ Expression = (*ConversionNode)(nil) | ||||
| 	_ Expression = (*FunctionLitNode)(nil) | ||||
| 	_ Expression = (*KeyedElementNode)(nil) | ||||
| 	_ Expression = (*LiteralValueNode)(nil) | ||||
| 	_ Expression = (*MethodExprNode)(nil) | ||||
| 	_ Expression = (*OperandNameNode)(nil) | ||||
| 	_ Expression = (*OperandNode)(nil) | ||||
| 	_ Expression = (*OperandQualifiedNameNode)(nil) | ||||
| 	_ Expression = (*ParenthesizedExpressionNode)(nil) | ||||
| 	_ Expression = (*PrimaryExprNode)(nil) | ||||
| 	_ Expression = (*UnaryExprNode)(nil) | ||||
| 	_ Expression = (*ValueExpression)(nil) | ||||
| 
 | ||||
| 	falseVal = constant.MakeBool(false) | ||||
| 	trueVal  = constant.MakeBool(true) | ||||
| 	unknown  = constant.MakeUnknown() | ||||
| ) | ||||
| 
 | ||||
| func known(v constant.Value) bool { return v != nil && v.Kind() != constant.Unknown } | ||||
| 
 | ||||
| type valueCache struct { | ||||
| 	v constant.Value | ||||
| } | ||||
| 
 | ||||
| func (n *valueCache) Value() constant.Value { | ||||
| 	if n.v != nil { | ||||
| 		return n.v | ||||
| 	} | ||||
| 
 | ||||
| 	return unknown | ||||
| } | ||||
| 
 | ||||
| func (n *valueCache) setValue(v constant.Value) constant.Value { | ||||
| 	n.v = v | ||||
| 	return v | ||||
| } | ||||
| 
 | ||||
| type valuer interface { | ||||
| 	Value() constant.Value | ||||
| } | ||||
| 
 | ||||
| type Expression interface { | ||||
| 	Node | ||||
| 	checkExpr(c *ctx) Expression | ||||
| 	clone() Expression | ||||
| 	typer | ||||
| 	valuer | ||||
| } | ||||
| 
 | ||||
| type ValueExpression struct { | ||||
| 	Node | ||||
| 	typeCache | ||||
| 	valueCache | ||||
| } | ||||
| 
 | ||||
| func (n *ValueExpression) checkExpr(c *ctx) Expression { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *ValueExpression) clone() Expression { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *BasicLitNode) Type() Type { | ||||
| 	switch n.Ch() { | ||||
| 	case CHAR: | ||||
| 		return n.ctx.int32 | ||||
| 	case INT: | ||||
| 		return n.ctx.untypedInt | ||||
| 	case FLOAT: | ||||
| 		return n.ctx.untypedFloat | ||||
| 	case STRING: | ||||
| 		return n.ctx.untypedString | ||||
| 	default: | ||||
| 		panic(todo("%v: %T %s %v", n.Position(), n, n.Source(false), n.Ch())) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (n *BasicLitNode) Value() constant.Value { | ||||
| 	return constant.MakeFromLiteral(n.Src(), n.Ch(), 0) | ||||
| } | ||||
| 
 | ||||
| func (n *BasicLitNode) checkExpr(c *ctx) Expression { | ||||
| 	n.ctx = c | ||||
| 	if !known(n.Value()) { | ||||
| 		c.err(n, "invalid literal: %s", n.Source(false)) | ||||
| 	} | ||||
| 	return n | ||||
| } | ||||
| 
 | ||||
| func (n *BasicLitNode) clone() Expression { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *OperandNameNode) Type() Type { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *OperandNameNode) Value() constant.Value { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *OperandNameNode) checkExpr(c *ctx) Expression { | ||||
| 	in, named := n.LexicalScope().lookup(n.Name) | ||||
| 	switch x := named.n.(type) { | ||||
| 	case *ConstSpecNode: | ||||
| 		switch in.kind { | ||||
| 		case UniverseScope: | ||||
| 			switch n.Name.Src() { | ||||
| 			case "iota": | ||||
| 				if c.iota < 0 { | ||||
| 					panic(todo("%v: %T %s", n.Position(), x, n.Source(false))) | ||||
| 				} | ||||
| 
 | ||||
| 				r := &ValueExpression{Node: x} | ||||
| 				r.t = c.untypedInt | ||||
| 				r.v = constant.MakeInt64(c.iota) | ||||
| 				return r | ||||
| 			default: | ||||
| 				panic(todo("%v: %T %s", n.Position(), x, n.Source(false))) | ||||
| 			} | ||||
| 		default: | ||||
| 			return x.Expression | ||||
| 		} | ||||
| 	default: | ||||
| 		panic(todo("%v: %T %s", n.Position(), x, n.Source(false))) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (n *OperandNameNode) clone() Expression { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *ParenthesizedExpressionNode) Type() Type { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *ParenthesizedExpressionNode) Value() constant.Value { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *ParenthesizedExpressionNode) checkExpr(c *ctx) Expression { | ||||
| 	return n.Expression.checkExpr(c) | ||||
| } | ||||
| 
 | ||||
| func (n *ParenthesizedExpressionNode) clone() Expression { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *LiteralValueNode) Type() Type { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *LiteralValueNode) Value() constant.Value { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *LiteralValueNode) checkExpr(c *ctx) Expression { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *LiteralValueNode) clone() Expression { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *KeyedElementNode) Type() Type { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *KeyedElementNode) Value() constant.Value { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *KeyedElementNode) checkExpr(c *ctx) Expression { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *KeyedElementNode) clone() Expression { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *CompositeLitNode) Type() Type { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *CompositeLitNode) Value() constant.Value { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *CompositeLitNode) checkExpr(c *ctx) Expression { | ||||
| 	if n == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	if !n.enter(c, n) { | ||||
| 		return n | ||||
| 	} | ||||
| 
 | ||||
| 	t := n.setType(c.checkType(n.LiteralType)) | ||||
| 	n.LiteralValue.check(c, t) | ||||
| 	return n | ||||
| } | ||||
| 
 | ||||
| func (n *CompositeLitNode) clone() Expression { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *LiteralValueNode) check(c *ctx, t Type) { | ||||
| 	if n == nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	switch t.Kind() { | ||||
| 	case Array: | ||||
| 		n.checkArray(c, t.(*ArrayTypeNode)) | ||||
| 	default: | ||||
| 		panic(todo("%v: %T %s %v", n.Position(), n, n.Source(false), t.Kind())) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (n *LiteralValueNode) checkArray(c *ctx, t *ArrayTypeNode) { | ||||
| 	panic(todo("%v: %T %s %s", n.Position(), n, t, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *FunctionLitNode) Type() Type { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *FunctionLitNode) Value() constant.Value { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *FunctionLitNode) checkExpr(c *ctx) Expression { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *FunctionLitNode) clone() Expression { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *OperandNode) Type() Type { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *OperandNode) Value() constant.Value { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *OperandNode) checkExpr(c *ctx) Expression { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *OperandNode) clone() Expression { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *OperandQualifiedNameNode) Type() Type { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *OperandQualifiedNameNode) Value() constant.Value { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *OperandQualifiedNameNode) checkExpr(c *ctx) Expression { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *OperandQualifiedNameNode) clone() Expression { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *ConversionNode) Type() Type { | ||||
| 	return n.TypeNode | ||||
| } | ||||
| 
 | ||||
| func (n *ConversionNode) checkExpr(c *ctx) Expression { | ||||
| 	t := n.TypeNode.check(c) | ||||
| 	n.Expression = n.Expression.checkExpr(c) | ||||
| 	v := n.Expression.Value() | ||||
| 	n.v = c.convertValue(n.Expression, v, t) | ||||
| 	return n | ||||
| } | ||||
| 
 | ||||
| func (n *ConversionNode) clone() Expression { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *MethodExprNode) Type() Type { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *MethodExprNode) Value() constant.Value { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *MethodExprNode) checkExpr(c *ctx) Expression { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *MethodExprNode) clone() Expression { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *PrimaryExprNode) Type() Type { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *PrimaryExprNode) Value() constant.Value { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *PrimaryExprNode) checkExpr(c *ctx) Expression { | ||||
| 	switch x := n.PrimaryExpr.(type) { | ||||
| 	case *OperandNameNode: | ||||
| 		_, named := x.LexicalScope().lookup(x.Name) | ||||
| 		switch y := named.n.(type) { | ||||
| 		case *TypeDefNode: | ||||
| 			switch z := n.Postfix.(type) { | ||||
| 			case *ArgumentsNode: | ||||
| 				cnv := &ConversionNode{ | ||||
| 					TypeNode: &TypeNameNode{ | ||||
| 						Name:          x.Name, | ||||
| 						lexicalScoper: x.lexicalScoper, | ||||
| 					}, | ||||
| 					LPAREN:     z.LPAREN, | ||||
| 					Expression: z.Expression, | ||||
| 					RPAREN:     z.RPAREN, | ||||
| 				} | ||||
| 				return cnv.checkExpr(c) | ||||
| 			default: | ||||
| 				panic(todo("%v: %T %s", n.Position(), z, n.Source(false))) | ||||
| 			} | ||||
| 		default: | ||||
| 			panic(todo("%v: %T %s", n.Position(), y, n.Source(false))) | ||||
| 		} | ||||
| 	default: | ||||
| 		panic(todo("%v: %T %s", n.Position(), x, n.Source(false))) | ||||
| 	} | ||||
| 
 | ||||
| 	n.PrimaryExpr = n.PrimaryExpr.checkExpr(c) | ||||
| 	switch x := n.Postfix.(type) { | ||||
| 	default: | ||||
| 		panic(todo("%v: %T %s", n.Position(), x, n.Source(false))) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (n *PrimaryExprNode) clone() Expression { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *BinaryExpressionNode) checkExpr(c *ctx) (r Expression) { | ||||
| 	if n == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	if n.typeCache.Type() != Invalid { | ||||
| 		return n | ||||
| 	} | ||||
| 
 | ||||
| 	n.LHS = n.LHS.checkExpr(c) | ||||
| 	n.RHS = n.RHS.checkExpr(c) | ||||
| 	lv := n.LHS.Value() | ||||
| 	lt := n.LHS.Type() | ||||
| 	rv := n.RHS.Value() | ||||
| 	rt := n.RHS.Type() | ||||
| 
 | ||||
| 	defer func() { | ||||
| 		if known(lv) && known(rv) && r != nil && !known(r.Value()) { | ||||
| 			c.err(n.Op, "operation value not determined: %v %s %v", lv, n.Op.Src(), rv) | ||||
| 		} | ||||
| 	}() | ||||
| 
 | ||||
| 	switch n.Op.Ch() { | ||||
| 	case SHL, SHR: | ||||
| 		var u uint64 | ||||
| 		var uOk bool | ||||
| 		n.t = lt | ||||
| 		// The right operand in a shift expression must have integer type or be an | ||||
| 		// untyped constant representable by a value of type uint. | ||||
| 		switch { | ||||
| 		case isIntegerType(rt): | ||||
| 			// ok | ||||
| 		case known(rv): | ||||
| 			if isAnyArithmeticType(rt) { | ||||
| 				rv = c.convertValue(n.RHS, rv, c.cfg.uint) | ||||
| 				if known(rv) { | ||||
| 					u, uOk = constant.Uint64Val(rv) | ||||
| 				} | ||||
| 				break | ||||
| 			} | ||||
| 
 | ||||
| 			c.err(n.Op, "TODO %v", n.Op.Src()) | ||||
| 			return n | ||||
| 		default: | ||||
| 			panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| 			return n | ||||
| 		} | ||||
| 
 | ||||
| 		// If the left operand of a non-constant shift expression is an untyped | ||||
| 		// constant, it is first implicitly converted to the type it would assume if | ||||
| 		// the shift expression were replaced by its left operand alone. | ||||
| 		switch { | ||||
| 		case known(lv) && !known(rv): | ||||
| 			panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| 			// c.err(n.Op, "TODO %v", n.Op.Ch.str()) | ||||
| 			// return n | ||||
| 		case known(lv) && known(rv): | ||||
| 			if !uOk { | ||||
| 				panic(todo("")) | ||||
| 			} | ||||
| 
 | ||||
| 			n.t = lt | ||||
| 			n.v = constant.Shift(lv, n.Op.Ch(), uint(u)) | ||||
| 		default: | ||||
| 			trc("", known(lv), known(rv), u, uOk) | ||||
| 			panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| 			// n.t = lt | ||||
| 			// n.v = constant.BinaryOp(lv, n.Op.Ch(), rv) | ||||
| 		} | ||||
| 	case ADD, SUB, MUL, QUO, REM: | ||||
| 		if !isAnyArithmeticType(lt) || !isAnyArithmeticType(rt) { | ||||
| 			c.err(n.Op, "TODO %v %v", lt, rt) | ||||
| 			break | ||||
| 		} | ||||
| 
 | ||||
| 		// For other binary operators, the operand types must be identical unless the | ||||
| 		// operation involves shifts or untyped constants. | ||||
| 		// | ||||
| 		// Except for shift operations, if one operand is an untyped constant and the | ||||
| 		// other operand is not, the constant is implicitly converted to the type of | ||||
| 		// the other operand. | ||||
| 		switch { | ||||
| 		case isAnyUntypedType(lt) && isAnyUntypedType(rt): | ||||
| 			n.v = constant.BinaryOp(lv, n.Op.Ch(), rv) | ||||
| 			switch n.v.Kind() { | ||||
| 			case constant.Int: | ||||
| 				n.t = c.untypedInt | ||||
| 			case constant.Float: | ||||
| 				n.t = c.untypedFloat | ||||
| 			default: | ||||
| 				c.err(n.Op, "TODO %v %v %q %v %v -> %v %v", lv, lt, n.Op.Src(), rv, rt, n.v, n.v.Kind()) | ||||
| 			} | ||||
| 		case isAnyUntypedType(lt) && !isAnyUntypedType(rt): | ||||
| 			c.err(n.Op, "TODO %v %v %q %v %v", lv, lt, n.Op.Src(), rv, rt) | ||||
| 		case !isAnyUntypedType(lt) && isAnyUntypedType(rt): | ||||
| 			c.err(n.Op, "TODO %v %v %q %v %v", lv, lt, n.Op.Src(), rv, rt) | ||||
| 		default: // case !isAnyUntypedType(lt) && !isAnyUntypedType(rt): | ||||
| 			c.err(n.Op, "TODO %v %v %q %v %v", lv, lt, n.Op.Src(), rv, rt) | ||||
| 		} | ||||
| 	default: | ||||
| 		c.err(n.Op, "TODO %v %v %q %v %v", lv, lt, n.Op.Src(), rv, rt) | ||||
| 	} | ||||
| 	return n | ||||
| } | ||||
| 
 | ||||
| func (n *BinaryExpressionNode) clone() Expression { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (n *UnaryExprNode) checkExpr(c *ctx) Expression { | ||||
| 	if n == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	if n.typeCache.Type() != Invalid { | ||||
| 		return n | ||||
| 	} | ||||
| 
 | ||||
| 	n.UnaryExpr = n.UnaryExpr.checkExpr(c) | ||||
| 	v := n.UnaryExpr.Value() | ||||
| 	t := n.UnaryExpr.Type() | ||||
| 	switch n.Op.Ch() { | ||||
| 	default: | ||||
| 		trc("", v, t) | ||||
| 		panic(todo("%v: %T %s", n.Op.Position(), n, n.Source(false))) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (n *UnaryExprNode) clone() Expression { | ||||
| 	panic(todo("%v: %T %s", n.Position(), n, n.Source(false))) | ||||
| } | ||||
| 
 | ||||
| func (c *ctx) convertValue(n Node, v constant.Value, to Type) (r constant.Value) { | ||||
| 	if !known(v) { | ||||
| 		return unknown | ||||
| 	} | ||||
| 
 | ||||
| 	switch to.Kind() { | ||||
| 	case | ||||
| 		Complex128, | ||||
| 		Complex64, | ||||
| 		Function, | ||||
| 		Interface, | ||||
| 		Map, | ||||
| 		Pointer, | ||||
| 		Slice, | ||||
| 		String, | ||||
| 		Struct, | ||||
| 		Tuple, | ||||
| 		UnsafePointer, | ||||
| 		UntypedBool, | ||||
| 		UntypedComplex, | ||||
| 		UntypedFloat, | ||||
| 		UntypedInt, | ||||
| 		UntypedNil, | ||||
| 		UntypedRune, | ||||
| 		UntypedString: | ||||
| 
 | ||||
| 		c.err(n, "TODO %v -> %v", v, to) | ||||
| 	case Int: | ||||
| 		w := constant.ToInt(v) | ||||
| 		if !known(w) { | ||||
| 			c.err(n, "cannot convert %s to %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		i64, ok := constant.Int64Val(w) | ||||
| 		if !ok { | ||||
| 			c.err(n, "value %s overflows %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		switch c.cfg.goarch { | ||||
| 		case "386", "arm": | ||||
| 			if i64 < math.MinInt32 || i64 > math.MaxInt32 { | ||||
| 				c.err(n, "value %s overflows %s", v, to) | ||||
| 				return unknown | ||||
| 			} | ||||
| 		} | ||||
| 		return w | ||||
| 	case Int8: | ||||
| 		w := constant.ToInt(v) | ||||
| 		if !known(w) { | ||||
| 			c.err(n, "cannot convert %s to %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		i64, ok := constant.Int64Val(w) | ||||
| 		if !ok { | ||||
| 			c.err(n, "value %s overflows %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		if i64 < math.MinInt8 || i64 > math.MaxInt8 { | ||||
| 			c.err(n, "value %s overflows %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		return w | ||||
| 	case Int16: | ||||
| 		w := constant.ToInt(v) | ||||
| 		if !known(w) { | ||||
| 			c.err(n, "cannot convert %s to %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		i64, ok := constant.Int64Val(w) | ||||
| 		if !ok { | ||||
| 			c.err(n, "value %s overflows %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		if i64 < math.MinInt16 || i64 > math.MaxInt16 { | ||||
| 			c.err(n, "value %s overflows %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		return w | ||||
| 	case Int32: | ||||
| 		w := constant.ToInt(v) | ||||
| 		if !known(w) { | ||||
| 			c.err(n, "cannot convert %s to %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		i64, ok := constant.Int64Val(w) | ||||
| 		if !ok { | ||||
| 			c.err(n, "value %s overflows %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		if i64 < math.MinInt32 || i64 > math.MaxInt32 { | ||||
| 			c.err(n, "value %s overflows %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		return w | ||||
| 	case Int64: | ||||
| 		w := constant.ToInt(v) | ||||
| 		if !known(w) { | ||||
| 			c.err(n, "cannot convert %s to %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		if _, ok := constant.Int64Val(w); !ok { | ||||
| 			c.err(n, "value %s overflows %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		return w | ||||
| 	case Uint, Uintptr: | ||||
| 		w := constant.ToInt(v) | ||||
| 		if !known(w) { | ||||
| 			c.err(n, "cannot convert %s to %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		u64, ok := constant.Uint64Val(w) | ||||
| 		if !ok { | ||||
| 			c.err(n, "value %s overflows %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		switch c.cfg.goarch { | ||||
| 		case "386", "arm": | ||||
| 			if u64 > math.MaxUint32 { | ||||
| 				c.err(n, "value %s overflows %s", v, to) | ||||
| 				return unknown | ||||
| 			} | ||||
| 		} | ||||
| 		return w | ||||
| 	case Uint8: | ||||
| 		w := constant.ToInt(v) | ||||
| 		if !known(w) { | ||||
| 			c.err(n, "cannot convert %s to %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		u64, ok := constant.Uint64Val(w) | ||||
| 		if !ok { | ||||
| 			c.err(n, "value %s overflows %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		if u64 > math.MaxUint8 { | ||||
| 			c.err(n, "value %s overflows %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		return w | ||||
| 	case Uint16: | ||||
| 		w := constant.ToInt(v) | ||||
| 		if !known(w) { | ||||
| 			c.err(n, "cannot convert %s to %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		u64, ok := constant.Uint64Val(w) | ||||
| 		if !ok { | ||||
| 			c.err(n, "value %s overflows %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		if u64 > math.MaxUint16 { | ||||
| 			c.err(n, "value %s overflows %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		return w | ||||
| 	case Uint32: | ||||
| 		w := constant.ToInt(v) | ||||
| 		if !known(w) { | ||||
| 			c.err(n, "cannot convert %s to %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		u64, ok := constant.Uint64Val(w) | ||||
| 		if !ok { | ||||
| 			c.err(n, "value %s overflows %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		if u64 > math.MaxUint32 { | ||||
| 			c.err(n, "value %s overflows %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		return w | ||||
| 	case Uint64: | ||||
| 		w := constant.ToInt(v) | ||||
| 		if !known(w) { | ||||
| 			c.err(n, "cannot convert %s to %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		if _, ok := constant.Uint64Val(w); !ok { | ||||
| 			c.err(n, "value %s overflows %s", v, to) | ||||
| 			return unknown | ||||
| 		} | ||||
| 
 | ||||
| 		return w | ||||
| 	case Float32, Float64: | ||||
| 		return constant.ToFloat(v) | ||||
| 	case Bool: | ||||
| 		if v.Kind() == constant.Bool { | ||||
| 			return v | ||||
| 		} | ||||
| 	} | ||||
| 	return unknown | ||||
| } | ||||
							
								
								
									
										9
									
								
								vendor/modernc.org/sqlite/Makefile
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/modernc.org/sqlite/Makefile
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -37,8 +37,8 @@ build_all_targets: | |||
| 	GOOS=linux GOARCH=riscv64 go build -v ./... | ||||
| 	GOOS=linux GOARCH=s390x go test -c -o /dev/null | ||||
| 	GOOS=linux GOARCH=s390x go build -v ./... | ||||
| 	GOOS=netbsd GOARCH=amd64 go test -c -o /dev/null | ||||
| 	GOOS=netbsd GOARCH=amd64 go build -v ./... | ||||
| 	# GOOS=netbsd GOARCH=amd64 go test -c -o /dev/null | ||||
| 	# GOOS=netbsd GOARCH=amd64 go build -v ./... | ||||
| 	GOOS=openbsd GOARCH=amd64 go test -c -o /dev/null | ||||
| 	GOOS=openbsd GOARCH=amd64 go build -v ./... | ||||
| 	GOOS=openbsd GOARCH=arm64 go test -c -o /dev/null | ||||
|  | @ -69,7 +69,10 @@ test: | |||
| 	go test -v -timeout 24h 2>&1 | tee log-test | ||||
| 	 | ||||
| vendor: | ||||
| 	go run vendor_libsqlite3.go && make build_all_targets | ||||
| 	cd vendor_libsqlite3 && go build -o ../vendor main.go | ||||
| 	./vendor | ||||
| 	rm -f vendor | ||||
| 	make build_all_targets | ||||
| 	make build_all_targets | ||||
| 
 | ||||
| work: | ||||
|  |  | |||
							
								
								
									
										6
									
								
								vendor/modernc.org/sqlite/lib/hooks.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/modernc.org/sqlite/lib/hooks.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -2,6 +2,8 @@ | |||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| //go:build !(linux && arm64) | ||||
| 
 | ||||
| package sqlite3 | ||||
| 
 | ||||
| import ( | ||||
|  | @ -12,3 +14,7 @@ import ( | |||
| func X__ccgo_sqlite3_log(t *libc.TLS, iErrCode int32, zFormat uintptr, va uintptr) { /* sqlite3.c:29405:17: */ | ||||
| 	libc.X__ccgo_sqlite3_log(t, iErrCode, zFormat, va) | ||||
| } | ||||
| 
 | ||||
| func PatchIssue199() { | ||||
| 	// nop | ||||
| } | ||||
|  |  | |||
							
								
								
									
										30
									
								
								vendor/modernc.org/sqlite/lib/hooks_linux_arm64.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								vendor/modernc.org/sqlite/lib/hooks_linux_arm64.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,30 @@ | |||
| // Copyright 2019 The Sqlite Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| package sqlite3 | ||||
| 
 | ||||
| import ( | ||||
| 	"syscall" | ||||
| 	"unsafe" | ||||
| 
 | ||||
| 	"modernc.org/libc" | ||||
| ) | ||||
| 
 | ||||
| // Format and write a message to the log if logging is enabled. | ||||
| func X__ccgo_sqlite3_log(t *libc.TLS, iErrCode int32, zFormat uintptr, va uintptr) { /* sqlite3.c:29405:17: */ | ||||
| 	libc.X__ccgo_sqlite3_log(t, iErrCode, zFormat, va) | ||||
| } | ||||
| 
 | ||||
| // https://gitlab.com/cznic/sqlite/-/issues/199 | ||||
| // | ||||
| // We are currently stuck on libc@v1.55.3. Until that is resolved - fix the | ||||
| // problem at runtime. | ||||
| func PatchIssue199() { | ||||
| 	p := unsafe.Pointer(&_aSyscall) | ||||
| 	*(*uintptr)(unsafe.Add(p, 608)) = __ccgo_fp(_unixGetpagesizeIssue199) | ||||
| } | ||||
| 
 | ||||
| func _unixGetpagesizeIssue199(tls *libc.TLS) (r int32) { | ||||
| 	return int32(syscall.Getpagesize()) | ||||
| } | ||||
							
								
								
									
										5
									
								
								vendor/modernc.org/sqlite/sqlite.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								vendor/modernc.org/sqlite/sqlite.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -55,6 +55,11 @@ const ( | |||
| 	sqliteLockedSharedcache = sqlite3.SQLITE_LOCKED | (1 << 8) | ||||
| ) | ||||
| 
 | ||||
| // https://gitlab.com/cznic/sqlite/-/issues/199 | ||||
| func init() { | ||||
| 	sqlite3.PatchIssue199() | ||||
| } | ||||
| 
 | ||||
| // Error represents sqlite library error code. | ||||
| type Error struct { | ||||
| 	msg  string | ||||
|  |  | |||
							
								
								
									
										126
									
								
								vendor/modernc.org/sqlite/vendor_libsqlite3.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										126
									
								
								vendor/modernc.org/sqlite/vendor_libsqlite3.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,126 +0,0 @@ | |||
| // Copyright 2024 The Sqlite 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 none | ||||
| // +build none | ||||
| 
 | ||||
| // Tool for 1.28+ -> 1.29+. Pulls adjusted libsqlite3 code to this repo. | ||||
| 
 | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"go/token" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"modernc.org/gc/v3" | ||||
| ) | ||||
| 
 | ||||
| func fail(rc int, msg string, args ...any) { | ||||
| 	fmt.Fprintln(os.Stderr, strings.TrimSpace(fmt.Sprintf(msg, args...))) | ||||
| 	os.Exit(rc) | ||||
| } | ||||
| 
 | ||||
| func main() { | ||||
| 	for _, v := range []struct{ goos, goarch string }{ | ||||
| 		{"darwin", "amd64"}, | ||||
| 		{"darwin", "arm64"}, | ||||
| 		{"freebsd", "amd64"}, | ||||
| 		{"freebsd", "arm64"}, | ||||
| 		{"linux", "386"}, | ||||
| 		{"linux", "amd64"}, | ||||
| 		{"linux", "arm"}, | ||||
| 		{"linux", "arm64"}, | ||||
| 		{"linux", "loong64"}, | ||||
| 		{"linux", "ppc64le"}, | ||||
| 		{"linux", "riscv64"}, | ||||
| 		{"linux", "s390x"}, | ||||
| 		{"windows", "386"}, | ||||
| 		{"windows", "amd64"}, | ||||
| 	} { | ||||
| 		base := fmt.Sprintf("ccgo_%s_%s.go", v.goos, v.goarch) | ||||
| 		if v.goos == "windows" && v.goarch == "amd64" { | ||||
| 			base = "ccgo_windows.go" | ||||
| 		} | ||||
| 		ifn := filepath.Join("..", "libsqlite3", base) | ||||
| 		fmt.Printf("%s/%s\t%s\n", v.goos, v.goarch, ifn) | ||||
| 		in, err := os.ReadFile(ifn) | ||||
| 		if err != nil { | ||||
| 			fail(1, "%s\n", err) | ||||
| 		} | ||||
| 
 | ||||
| 		ast, err := gc.ParseFile(ifn, in) | ||||
| 		if err != nil { | ||||
| 			fail(1, "%s\n", err) | ||||
| 		} | ||||
| 
 | ||||
| 		b := bytes.NewBuffer(nil) | ||||
| 		s := ast.SourceFile.PackageClause.Source(true) | ||||
| 		s = strings.Replace(s, "package libsqlite3", "package sqlite3", 1) | ||||
| 		fmt.Fprintln(b, s) | ||||
| 		fmt.Fprint(b, ast.SourceFile.ImportDeclList.Source(true)) | ||||
| 		taken := map[string]struct{}{} | ||||
| 		for n := ast.SourceFile.TopLevelDeclList; n != nil; n = n.List { | ||||
| 			switch x := n.TopLevelDecl.(type) { | ||||
| 			case *gc.TypeDeclNode: | ||||
| 				adn := x.TypeSpecList.TypeSpec.(*gc.AliasDeclNode) | ||||
| 				nm := adn.IDENT.Src() | ||||
| 				taken[nm] = struct{}{} | ||||
| 			} | ||||
| 		} | ||||
| 	loop: | ||||
| 		for n := ast.SourceFile.TopLevelDeclList; n != nil; n = n.List { | ||||
| 			switch x := n.TopLevelDecl.(type) { | ||||
| 			case *gc.ConstDeclNode: | ||||
| 				switch y := x.ConstSpec.(type) { | ||||
| 				case *gc.ConstSpecNode: | ||||
| 					if y.IDENT.Src() != "SQLITE_TRANSIENT" { | ||||
| 						fmt.Fprintln(b, x.Source(true)) | ||||
| 					} | ||||
| 				default: | ||||
| 					panic(fmt.Sprintf("%v: %T %q", x.Position(), y, x.Source(false))) | ||||
| 				} | ||||
| 
 | ||||
| 			case *gc.FunctionDeclNode: | ||||
| 				fmt.Fprintln(b, x.Source(true)) | ||||
| 			case *gc.TypeDeclNode: | ||||
| 				fmt.Fprintln(b, x.Source(true)) | ||||
| 				adn := x.TypeSpecList.TypeSpec.(*gc.AliasDeclNode) | ||||
| 				nm := adn.IDENT.Src() | ||||
| 				nm2 := nm[1:] | ||||
| 				if _, ok := taken[nm2]; ok { | ||||
| 					break | ||||
| 				} | ||||
| 
 | ||||
| 				if token.IsExported(nm) { | ||||
| 					fmt.Fprintf(b, "\ntype %s = %s\n", nm2, nm) | ||||
| 				} | ||||
| 			case *gc.VarDeclNode: | ||||
| 				fmt.Fprintln(b, x.Source(true)) | ||||
| 			default: | ||||
| 				fmt.Printf("%v: TODO %T\n", n.Position(), x) | ||||
| 				break loop | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		b.WriteString(` | ||||
| type Sqlite3_int64 = sqlite3_int64 | ||||
| type Sqlite3_mutex_methods = sqlite3_mutex_methods | ||||
| type Sqlite3_value = sqlite3_value | ||||
| 
 | ||||
| type Sqlite3_index_info = sqlite3_index_info | ||||
| type Sqlite3_module = sqlite3_module | ||||
| type Sqlite3_vtab = sqlite3_vtab | ||||
| type Sqlite3_vtab_cursor = sqlite3_vtab_cursor | ||||
| 
 | ||||
| `) | ||||
| 		base = strings.Replace(base, "ccgo_", "sqlite_", 1) | ||||
| 		if err := os.WriteFile(filepath.Join("lib", base), b.Bytes(), 0660); err != nil { | ||||
| 			fail(1, "%s\n", err) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										12
									
								
								vendor/modernc.org/strutil/AUTHORS
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								vendor/modernc.org/strutil/AUTHORS
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,12 +0,0 @@ | |||
| # This file lists authors for copyright purposes.  This file is distinct from | ||||
| # the CONTRIBUTORS files.  See the latter for an explanation. | ||||
| # | ||||
| # Names should be added to this file as: | ||||
| #     Name or Organization <email address> | ||||
| # | ||||
| # The email address is not required for organizations. | ||||
| # | ||||
| # Please keep the list sorted. | ||||
| 
 | ||||
| CZ.NIC z.s.p.o. <kontakt@nic.cz> | ||||
| Jan Mercl <0xjnml@gmail.com> | ||||
							
								
								
									
										9
									
								
								vendor/modernc.org/strutil/CONTRIBUTORS
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/modernc.org/strutil/CONTRIBUTORS
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,9 +0,0 @@ | |||
| # This file lists people who contributed code to this repository.  The AUTHORS | ||||
| # file lists the copyright holders; this file lists people. | ||||
| # | ||||
| # Names should be added to this file like so: | ||||
| #     Name <email address> | ||||
| # | ||||
| # Please keep the list sorted. | ||||
| 
 | ||||
| Jan Mercl <0xjnml@gmail.com> | ||||
							
								
								
									
										27
									
								
								vendor/modernc.org/strutil/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										27
									
								
								vendor/modernc.org/strutil/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,27 +0,0 @@ | |||
| Copyright (c) 2014 The strutil Authors. All rights reserved. | ||||
| 
 | ||||
| Redistribution and use in source and binary forms, with or without | ||||
| modification, are permitted provided that the following conditions are | ||||
| met: | ||||
| 
 | ||||
|    * Redistributions of source code must retain the above copyright | ||||
| notice, this list of conditions and the following disclaimer. | ||||
|    * Redistributions in binary form must reproduce the above | ||||
| copyright notice, this list of conditions and the following disclaimer | ||||
| in the documentation and/or other materials provided with the | ||||
| distribution. | ||||
|    * Neither the names of the authors nor the names of the | ||||
| contributors may be used to endorse or promote products derived from | ||||
| this software without specific prior written permission. | ||||
| 
 | ||||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||
| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||
| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
							
								
								
									
										59
									
								
								vendor/modernc.org/strutil/Makefile
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										59
									
								
								vendor/modernc.org/strutil/Makefile
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,59 +0,0 @@ | |||
| # Copyright (c) 2014 The sortutil Authors. All rights reserved.
 | ||||
| # Use of this source code is governed by a BSD-style
 | ||||
| # license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
| .PHONY:	all clean cover cpu editor internalError later mem nuke todo edit | ||||
| 
 | ||||
| grep=--include=*.go --include=*.l --include=*.y --include=*.yy | ||||
| ngrep='TODOOK\|parser\.go\|scanner\.go\|.*_string\.go' | ||||
| 
 | ||||
| all: editor | ||||
| 	go vet 2>&1 | grep -v $(ngrep) || true | ||||
| 	golint 2>&1 | grep -v $(ngrep) || true | ||||
| 	make todo | ||||
| 	unused . || true | ||||
| 	misspell *.go | ||||
| 	gosimple || true | ||||
| 	maligned || true | ||||
| 	unconvert -apply | ||||
| 
 | ||||
| clean: | ||||
| 	go clean | ||||
| 	rm -f *~ *.test *.out | ||||
| 
 | ||||
| cover: | ||||
| 	t=$(shell tempfile) ; go test -coverprofile $$t && go tool cover -html $$t && unlink $$t | ||||
| 
 | ||||
| cpu: clean | ||||
| 	go test -run @ -bench . -cpuprofile cpu.out | ||||
| 	go tool pprof -lines *.test cpu.out | ||||
| 
 | ||||
| edit: | ||||
| 	@ 1>/dev/null 2>/dev/null gvim -p Makefile *.go | ||||
| 
 | ||||
| editor: | ||||
| 	unconvert -apply || true | ||||
| 	gofmt -l -s -w *.go | ||||
| 	go test -i | ||||
| 	go test 2>&1 | tee log | ||||
| 	go install | ||||
| 
 | ||||
| internalError: | ||||
| 	egrep -ho '"internal error.*"' *.go | sort | cat -n | ||||
| 
 | ||||
| later: | ||||
| 	@grep -n $(grep) LATER * || true | ||||
| 	@grep -n $(grep) MAYBE * || true | ||||
| 
 | ||||
| mem: clean | ||||
| 	go test -run @ -bench . -memprofile mem.out -memprofilerate 1 -timeout 24h | ||||
| 	go tool pprof -lines -web -alloc_space *.test mem.out | ||||
| 
 | ||||
| nuke: clean | ||||
| 	go clean -i | ||||
| 
 | ||||
| todo: | ||||
| 	@grep -nr $(grep) ^[[:space:]]*_[[:space:]]*=[[:space:]][[:alpha:]][[:alnum:]]* * | grep -v $(ngrep) || true | ||||
| 	@grep -nr $(grep) TODO * | grep -v $(ngrep) || true | ||||
| 	@grep -nr $(grep) BUG * | grep -v $(ngrep) || true | ||||
| 	@grep -nr $(grep) [^[:alpha:]]println * | grep -v $(ngrep) || true | ||||
							
								
								
									
										8
									
								
								vendor/modernc.org/strutil/README
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/modernc.org/strutil/README
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,8 +0,0 @@ | |||
| modernc.orgall-able mirror of modified code already published at: | ||||
| http://git.nic.cz/redmine/projects/gostrutil/repository | ||||
| 
 | ||||
| Online godoc documentation for this package (should be) available at: | ||||
| http://gopkgdoc.appspot.com/pkg/modernc.org/strutil | ||||
| 
 | ||||
| Installation: | ||||
| $ go get modernc.org/strutil | ||||
							
								
								
									
										733
									
								
								vendor/modernc.org/strutil/strutil.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										733
									
								
								vendor/modernc.org/strutil/strutil.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,733 +0,0 @@ | |||
| // Copyright (c) 2014 The sortutil Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| // Package strutil collects utils supplemental to the standard strings package. | ||||
| package strutil // import "modernc.org/strutil" | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/base32" | ||||
| 	"encoding/base64" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"reflect" | ||||
| 	"runtime" | ||||
| 	"sort" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| ) | ||||
| 
 | ||||
| // Base32ExtDecode decodes base32 extended (RFC 4648) text to binary data. | ||||
| func Base32ExtDecode(text []byte) (data []byte, err error) { | ||||
| 	n := base32.HexEncoding.DecodedLen(len(text)) | ||||
| 	data = make([]byte, n) | ||||
| 	decoder := base32.NewDecoder(base32.HexEncoding, bytes.NewBuffer(text)) | ||||
| 	if n, err = decoder.Read(data); err != nil { | ||||
| 		n = 0 | ||||
| 	} | ||||
| 	data = data[:n] | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Base32ExtEncode encodes binary data to base32 extended (RFC 4648) encoded text. | ||||
| func Base32ExtEncode(data []byte) (text []byte) { | ||||
| 	n := base32.HexEncoding.EncodedLen(len(data)) | ||||
| 	buf := bytes.NewBuffer(make([]byte, 0, n)) | ||||
| 	encoder := base32.NewEncoder(base32.HexEncoding, buf) | ||||
| 	encoder.Write(data) | ||||
| 	encoder.Close() | ||||
| 	if buf.Len() != n { | ||||
| 		panic("internal error") | ||||
| 	} | ||||
| 	return buf.Bytes() | ||||
| } | ||||
| 
 | ||||
| // Base64Decode decodes base64 text to binary data. | ||||
| func Base64Decode(text []byte) (data []byte, err error) { | ||||
| 	n := base64.StdEncoding.DecodedLen(len(text)) | ||||
| 	data = make([]byte, n) | ||||
| 	decoder := base64.NewDecoder(base64.StdEncoding, bytes.NewBuffer(text)) | ||||
| 	if n, err = decoder.Read(data); err != nil { | ||||
| 		n = 0 | ||||
| 	} | ||||
| 	data = data[:n] | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Base64Encode encodes binary data to base64 encoded text. | ||||
| func Base64Encode(data []byte) (text []byte) { | ||||
| 	n := base64.StdEncoding.EncodedLen(len(data)) | ||||
| 	buf := bytes.NewBuffer(make([]byte, 0, n)) | ||||
| 	encoder := base64.NewEncoder(base64.StdEncoding, buf) | ||||
| 	encoder.Write(data) | ||||
| 	encoder.Close() | ||||
| 	if buf.Len() != n { | ||||
| 		panic("internal error") | ||||
| 	} | ||||
| 	return buf.Bytes() | ||||
| } | ||||
| 
 | ||||
| // Formatter is an io.Writer extended by a fmt.Printf like function Format | ||||
| type Formatter interface { | ||||
| 	io.Writer | ||||
| 	Format(format string, args ...interface{}) (n int, errno error) | ||||
| } | ||||
| 
 | ||||
| type indentFormatter struct { | ||||
| 	io.Writer | ||||
| 	indent      []byte | ||||
| 	indentLevel int | ||||
| 	state       int | ||||
| } | ||||
| 
 | ||||
| const ( | ||||
| 	st0 = iota | ||||
| 	stBOL | ||||
| 	stPERC | ||||
| 	stBOLPERC | ||||
| ) | ||||
| 
 | ||||
| // IndentFormatter returns a new Formatter which interprets %i and %u in the | ||||
| // Format() format string as indent and undent commands. The commands can | ||||
| // nest. The Formatter writes to io.Writer 'w' and inserts one 'indent' | ||||
| // string per current indent level value. | ||||
| // Behaviour of commands reaching negative indent levels is undefined. | ||||
| //	IndentFormatter(os.Stdout, "\t").Format("abc%d%%e%i\nx\ny\n%uz\n", 3) | ||||
| // output: | ||||
| //	abc3%e | ||||
| //		x | ||||
| //		y | ||||
| //	z | ||||
| // The Go quoted string literal form of the above is: | ||||
| //	"abc%%e\n\tx\n\tx\nz\n" | ||||
| // The commands can be scattered between separate invocations of Format(), | ||||
| // i.e. the formatter keeps track of the indent level and knows if it is | ||||
| // positioned on start of a line and should emit indentation(s). | ||||
| // The same output as above can be produced by e.g.: | ||||
| //	f := IndentFormatter(os.Stdout, " ") | ||||
| //	f.Format("abc%d%%e%i\nx\n", 3) | ||||
| //	f.Format("y\n%uz\n") | ||||
| func IndentFormatter(w io.Writer, indent string) Formatter { | ||||
| 	return &indentFormatter{w, []byte(indent), 0, stBOL} | ||||
| } | ||||
| 
 | ||||
| func (f *indentFormatter) format(flat bool, format string, args ...interface{}) (n int, errno error) { | ||||
| 	buf := []byte{} | ||||
| 	for i := 0; i < len(format); i++ { | ||||
| 		c := format[i] | ||||
| 		switch f.state { | ||||
| 		case st0: | ||||
| 			switch c { | ||||
| 			case '\n': | ||||
| 				cc := c | ||||
| 				if flat && f.indentLevel != 0 { | ||||
| 					cc = ' ' | ||||
| 				} | ||||
| 				buf = append(buf, cc) | ||||
| 				f.state = stBOL | ||||
| 			case '%': | ||||
| 				f.state = stPERC | ||||
| 			default: | ||||
| 				buf = append(buf, c) | ||||
| 			} | ||||
| 		case stBOL: | ||||
| 			switch c { | ||||
| 			case '\n': | ||||
| 				cc := c | ||||
| 				if flat && f.indentLevel != 0 { | ||||
| 					cc = ' ' | ||||
| 				} | ||||
| 				buf = append(buf, cc) | ||||
| 			case '%': | ||||
| 				f.state = stBOLPERC | ||||
| 			default: | ||||
| 				if !flat { | ||||
| 					for i := 0; i < f.indentLevel; i++ { | ||||
| 						buf = append(buf, f.indent...) | ||||
| 					} | ||||
| 				} | ||||
| 				buf = append(buf, c) | ||||
| 				f.state = st0 | ||||
| 			} | ||||
| 		case stBOLPERC: | ||||
| 			switch c { | ||||
| 			case 'i': | ||||
| 				f.indentLevel++ | ||||
| 				f.state = stBOL | ||||
| 			case 'u': | ||||
| 				f.indentLevel-- | ||||
| 				f.state = stBOL | ||||
| 			default: | ||||
| 				if !flat { | ||||
| 					for i := 0; i < f.indentLevel; i++ { | ||||
| 						buf = append(buf, f.indent...) | ||||
| 					} | ||||
| 				} | ||||
| 				buf = append(buf, '%', c) | ||||
| 				f.state = st0 | ||||
| 			} | ||||
| 		case stPERC: | ||||
| 			switch c { | ||||
| 			case 'i': | ||||
| 				f.indentLevel++ | ||||
| 				f.state = st0 | ||||
| 			case 'u': | ||||
| 				f.indentLevel-- | ||||
| 				f.state = st0 | ||||
| 			default: | ||||
| 				buf = append(buf, '%', c) | ||||
| 				f.state = st0 | ||||
| 			} | ||||
| 		default: | ||||
| 			panic("unexpected state") | ||||
| 		} | ||||
| 	} | ||||
| 	switch f.state { | ||||
| 	case stPERC, stBOLPERC: | ||||
| 		buf = append(buf, '%') | ||||
| 	} | ||||
| 	return f.Write([]byte(fmt.Sprintf(string(buf), args...))) | ||||
| } | ||||
| 
 | ||||
| func (f *indentFormatter) Format(format string, args ...interface{}) (n int, errno error) { | ||||
| 	return f.format(false, format, args...) | ||||
| } | ||||
| 
 | ||||
| type flatFormatter indentFormatter | ||||
| 
 | ||||
| // FlatFormatter returns a newly created Formatter with the same functionality as the one returned | ||||
| // by IndentFormatter except it allows a newline in the 'format' string argument of Format | ||||
| // to pass through iff indent level is currently zero. | ||||
| // | ||||
| // If indent level is non-zero then such new lines are changed to a space character. | ||||
| // There is no indent string, the %i and %u format verbs are used solely to determine the indent level. | ||||
| // | ||||
| // The FlatFormatter is intended for flattening of normally nested structure textual representation to | ||||
| // a one top level structure per line form. | ||||
| //	FlatFormatter(os.Stdout, " ").Format("abc%d%%e%i\nx\ny\n%uz\n", 3) | ||||
| // output in the form of a Go quoted string literal: | ||||
| //	"abc3%%e x y z\n" | ||||
| func FlatFormatter(w io.Writer) Formatter { | ||||
| 	return (*flatFormatter)(IndentFormatter(w, "").(*indentFormatter)) | ||||
| } | ||||
| 
 | ||||
| func (f *flatFormatter) Format(format string, args ...interface{}) (n int, errno error) { | ||||
| 	return (*indentFormatter)(f).format(true, format, args...) | ||||
| } | ||||
| 
 | ||||
| // Pool handles aligning of strings having equal values to the same string instance. | ||||
| // Intended use is to conserve some memory e.g. where a large number of identically valued strings | ||||
| // with non identical backing arrays may exists in several semantically distinct instances of some structs. | ||||
| // Pool is *not* concurrent access safe. It doesn't handle common prefix/suffix aligning, | ||||
| // e.g. having s1 == "abc" and s2 == "bc", s2 is not automatically aligned as s1[1:]. | ||||
| type Pool struct { | ||||
| 	pool map[string]string | ||||
| } | ||||
| 
 | ||||
| // NewPool returns a newly created Pool. | ||||
| func NewPool() *Pool { | ||||
| 	return &Pool{map[string]string{}} | ||||
| } | ||||
| 
 | ||||
| // Align returns a string with the same value as its argument. It guarantees that | ||||
| // all aligned strings share a single instance in memory. | ||||
| func (p *Pool) Align(s string) string { | ||||
| 	if a, ok := p.pool[s]; ok { | ||||
| 		return a | ||||
| 	} | ||||
| 
 | ||||
| 	s = StrPack(s) | ||||
| 	p.pool[s] = s | ||||
| 	return s | ||||
| } | ||||
| 
 | ||||
| // Count returns the number of items in the pool. | ||||
| func (p *Pool) Count() int { | ||||
| 	return len(p.pool) | ||||
| } | ||||
| 
 | ||||
| // GoPool is a concurrent access safe version of Pool. | ||||
| type GoPool struct { | ||||
| 	pool map[string]string | ||||
| 	rwm  *sync.RWMutex | ||||
| } | ||||
| 
 | ||||
| // NewGoPool returns a newly created GoPool. | ||||
| func NewGoPool() (p *GoPool) { | ||||
| 	return &GoPool{map[string]string{}, &sync.RWMutex{}} | ||||
| } | ||||
| 
 | ||||
| // Align returns a string with the same value as its argument. It guarantees that | ||||
| // all aligned strings share a single instance in memory. | ||||
| func (p *GoPool) Align(s string) (y string) { | ||||
| 	if s != "" { | ||||
| 		p.rwm.RLock()               // R++ | ||||
| 		if a, ok := p.pool[s]; ok { // found | ||||
| 			p.rwm.RUnlock() // R-- | ||||
| 			return a | ||||
| 		} | ||||
| 
 | ||||
| 		p.rwm.RUnlock() // R-- | ||||
| 		// not found but with a race condition, retry within a write lock | ||||
| 		p.rwm.Lock()                // W++ | ||||
| 		defer p.rwm.Unlock()        // W-- | ||||
| 		if a, ok := p.pool[s]; ok { // done in a race | ||||
| 			return a | ||||
| 		} | ||||
| 
 | ||||
| 		// we won | ||||
| 		s = StrPack(s) | ||||
| 		p.pool[s] = s | ||||
| 		return s | ||||
| 	} | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Count returns the number of items in the pool. | ||||
| func (p *GoPool) Count() int { | ||||
| 	return len(p.pool) | ||||
| } | ||||
| 
 | ||||
| // Dict is a string <-> id bijection. Dict is *not* concurrent access safe for assigning new ids | ||||
| // to strings not yet contained in the bijection. | ||||
| // Id for an empty string is guaranteed to be 0, | ||||
| // thus Id for any non empty string is guaranteed to be non zero. | ||||
| type Dict struct { | ||||
| 	si map[string]int | ||||
| 	is []string | ||||
| } | ||||
| 
 | ||||
| // NewDict returns a newly created Dict. | ||||
| func NewDict() (d *Dict) { | ||||
| 	d = &Dict{map[string]int{}, []string{}} | ||||
| 	d.Id("") | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Count returns the number of items in the dict. | ||||
| func (d *Dict) Count() int { | ||||
| 	return len(d.is) | ||||
| } | ||||
| 
 | ||||
| // Id maps string s to its numeric identificator. | ||||
| func (d *Dict) Id(s string) (y int) { | ||||
| 	if y, ok := d.si[s]; ok { | ||||
| 		return y | ||||
| 	} | ||||
| 
 | ||||
| 	s = StrPack(s) | ||||
| 	y = len(d.is) | ||||
| 	d.si[s] = y | ||||
| 	d.is = append(d.is, s) | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // S maps an id to its string value and ok == true. Id values not contained in the bijection | ||||
| // return "", false. | ||||
| func (d *Dict) S(id int) (s string, ok bool) { | ||||
| 	if id >= len(d.is) { | ||||
| 		return "", false | ||||
| 	} | ||||
| 	return d.is[id], true | ||||
| } | ||||
| 
 | ||||
| // GoDict is a concurrent access safe version of Dict. | ||||
| type GoDict struct { | ||||
| 	si  map[string]int | ||||
| 	is  []string | ||||
| 	rwm *sync.RWMutex | ||||
| } | ||||
| 
 | ||||
| // NewGoDict returns a newly created GoDict. | ||||
| func NewGoDict() (d *GoDict) { | ||||
| 	d = &GoDict{map[string]int{}, []string{}, &sync.RWMutex{}} | ||||
| 	d.Id("") | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Count returns the number of items in the dict. | ||||
| func (d *GoDict) Count() int { | ||||
| 	return len(d.is) | ||||
| } | ||||
| 
 | ||||
| // Id maps string s to its numeric identificator. The implementation honors getting | ||||
| // an existing id at the cost of assigning a new one. | ||||
| func (d *GoDict) Id(s string) (y int) { | ||||
| 	d.rwm.RLock()             // R++ | ||||
| 	if y, ok := d.si[s]; ok { // found | ||||
| 		d.rwm.RUnlock() // R-- | ||||
| 		return y | ||||
| 	} | ||||
| 
 | ||||
| 	d.rwm.RUnlock() // R-- | ||||
| 
 | ||||
| 	// not found but with a race condition | ||||
| 	d.rwm.Lock()              // W++ recheck with write lock | ||||
| 	defer d.rwm.Unlock()      // W-- | ||||
| 	if y, ok := d.si[s]; ok { // some other goroutine won already | ||||
| 		return y | ||||
| 	} | ||||
| 
 | ||||
| 	// a race free not found state => insert the string | ||||
| 	s = StrPack(s) | ||||
| 	y = len(d.is) | ||||
| 	d.si[s] = y | ||||
| 	d.is = append(d.is, s) | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // S maps an id to its string value and ok == true. Id values not contained in the bijection | ||||
| // return "", false. | ||||
| func (d *GoDict) S(id int) (s string, ok bool) { | ||||
| 	d.rwm.RLock()         // R++ | ||||
| 	defer d.rwm.RUnlock() // R-- | ||||
| 	if id >= len(d.is) { | ||||
| 		return "", false | ||||
| 	} | ||||
| 	return d.is[id], true | ||||
| } | ||||
| 
 | ||||
| // StrPack returns a new instance of s which is tightly packed in memory. | ||||
| // It is intended for avoiding the situation where having a live reference | ||||
| // to a string slice over an unreferenced biger underlying string keeps the biger one | ||||
| // in memory anyway - it can't be GCed. | ||||
| func StrPack(s string) string { | ||||
| 	return string([]byte(s)) // T(U(T)) intentional. | ||||
| } | ||||
| 
 | ||||
| // JoinFields returns strings in flds joined by sep. Flds may contain arbitrary | ||||
| // bytes, including the sep as they are safely escaped. JoinFields panics if | ||||
| // sep is the backslash character or if len(sep) != 1. | ||||
| func JoinFields(flds []string, sep string) string { | ||||
| 	if len(sep) != 1 || sep == "\\" { | ||||
| 		panic("invalid separator") | ||||
| 	} | ||||
| 
 | ||||
| 	a := make([]string, len(flds)) | ||||
| 	for i, v := range flds { | ||||
| 		v = strings.Replace(v, "\\", "\\0", -1) | ||||
| 		a[i] = strings.Replace(v, sep, "\\1", -1) | ||||
| 	} | ||||
| 	return strings.Join(a, sep) | ||||
| } | ||||
| 
 | ||||
| // SplitFields splits s, which must be produced by JoinFields using the same | ||||
| // sep, into flds.  SplitFields panics if sep is the backslash character or if | ||||
| // len(sep) != 1. | ||||
| func SplitFields(s, sep string) (flds []string) { | ||||
| 	if len(sep) != 1 || sep == "\\" { | ||||
| 		panic("invalid separator") | ||||
| 	} | ||||
| 
 | ||||
| 	a := strings.Split(s, sep) | ||||
| 	r := make([]string, len(a)) | ||||
| 	for i, v := range a { | ||||
| 		v = strings.Replace(v, "\\1", sep, -1) | ||||
| 		r[i] = strings.Replace(v, "\\0", "\\", -1) | ||||
| 	} | ||||
| 	return r | ||||
| } | ||||
| 
 | ||||
| // PrettyPrintHooks allow to customize the result of PrettyPrint for types | ||||
| // listed in the map value. | ||||
| type PrettyPrintHooks map[reflect.Type]func(f Formatter, v interface{}, prefix, suffix string) | ||||
| 
 | ||||
| // PrettyString returns the output of PrettyPrint as a string. | ||||
| func PrettyString(v interface{}, prefix, suffix string, hooks PrettyPrintHooks) string { | ||||
| 	var b bytes.Buffer | ||||
| 	PrettyPrint(&b, v, prefix, suffix, hooks) | ||||
| 	return b.String() | ||||
| } | ||||
| 
 | ||||
| // PrettyPrint pretty prints v to w. Zero values and unexported struct fields | ||||
| // are omitted. | ||||
| // | ||||
| // Force printing of zero values of struct fields by including in the field tag | ||||
| // PrettyPrint:"zero". | ||||
| // | ||||
| // Enable using a String method, if any, of a struct field type by including in | ||||
| // the field tag PrettyPrint:"stringer". | ||||
| // | ||||
| // The tags can be combined as in PrettyPrint:"zero,stringer". The order is not | ||||
| // important, so PrettyPrint:stringer,zero has the same effect. | ||||
| // | ||||
| // A hook attached to the field type has priority over the struct field tag | ||||
| // described above. | ||||
| func PrettyPrint(w io.Writer, v interface{}, prefix, suffix string, hooks PrettyPrintHooks) { | ||||
| 	if v == nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	f := IndentFormatter(w, "· ") | ||||
| 
 | ||||
| 	defer func() { | ||||
| 		if e := recover(); e != nil { | ||||
| 			f.Format("\npanic: %v", e) | ||||
| 		} | ||||
| 	}() | ||||
| 
 | ||||
| 	prettyPrint(nil, f, prefix, suffix, v, hooks, false, false) | ||||
| } | ||||
| 
 | ||||
| func prettyPrint(protect map[interface{}]struct{}, sf Formatter, prefix, suffix string, v interface{}, hooks PrettyPrintHooks, zero, stringer bool) { | ||||
| 	if v == nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	rt := reflect.TypeOf(v) | ||||
| 	if handler := hooks[rt]; handler != nil { | ||||
| 		handler(sf, v, prefix, suffix) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	rv := reflect.ValueOf(v) | ||||
| 	if stringer { | ||||
| 		if _, ok := v.(fmt.Stringer); ok { | ||||
| 			sf.Format("%s%s", prefix, v) | ||||
| 			sf.Format(suffix) | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	switch rt.Kind() { | ||||
| 	case reflect.Slice: | ||||
| 		if rv.Len() == 0 && !zero { | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		sf.Format("%s[]%T{ // len %d%i\n", prefix, rv.Index(0).Interface(), rv.Len()) | ||||
| 		for i := 0; i < rv.Len(); i++ { | ||||
| 			prettyPrint(protect, sf, fmt.Sprintf("%d: ", i), ",\n", rv.Index(i).Interface(), hooks, false, false) | ||||
| 		} | ||||
| 		suffix = strings.Replace(suffix, "%", "%%", -1) | ||||
| 		sf.Format("%u}" + suffix) | ||||
| 	case reflect.Array: | ||||
| 		if reflect.Zero(rt).Interface() == rv.Interface() && !zero { | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		sf.Format("%s[%d]%T{%i\n", prefix, rv.Len(), rv.Index(0).Interface()) | ||||
| 		for i := 0; i < rv.Len(); i++ { | ||||
| 			prettyPrint(protect, sf, fmt.Sprintf("%d: ", i), ",\n", rv.Index(i).Interface(), hooks, false, false) | ||||
| 		} | ||||
| 		suffix = strings.Replace(suffix, "%", "%%", -1) | ||||
| 		sf.Format("%u}" + suffix) | ||||
| 	case reflect.Struct: | ||||
| 		if rt.NumField() == 0 { | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		if reflect.DeepEqual(reflect.Zero(rt).Interface(), rv.Interface()) && !zero { | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		sf.Format("%s%T{%i\n", prefix, v) | ||||
| 		for i := 0; i < rt.NumField(); i++ { | ||||
| 			f := rv.Field(i) | ||||
| 			if !f.CanInterface() { | ||||
| 				continue | ||||
| 			} | ||||
| 
 | ||||
| 			var stringer, zero bool | ||||
| 			ft := rt.Field(i) | ||||
| 			if tag, ok := ft.Tag.Lookup("PrettyPrint"); ok { | ||||
| 				a := strings.Split(tag, ",") | ||||
| 				for _, v := range a { | ||||
| 					switch strings.TrimSpace(v) { | ||||
| 					case "stringer": | ||||
| 						stringer = true | ||||
| 					case "zero": | ||||
| 						zero = true | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			prettyPrint(protect, sf, fmt.Sprintf("%s: ", rt.Field(i).Name), ",\n", f.Interface(), hooks, zero, stringer) | ||||
| 		} | ||||
| 		suffix = strings.Replace(suffix, "%", "%%", -1) | ||||
| 		sf.Format("%u}" + suffix) | ||||
| 	case reflect.Ptr: | ||||
| 		if rv.IsNil() && !zero { | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		rvi := rv.Interface() | ||||
| 		if _, ok := protect[rvi]; ok { | ||||
| 			suffix = strings.Replace(suffix, "%", "%%", -1) | ||||
| 			sf.Format("%s&%T{ /* recursive/repetitive pointee not shown */ }"+suffix, prefix, rv.Elem().Interface()) | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		if protect == nil { | ||||
| 			protect = map[interface{}]struct{}{} | ||||
| 		} | ||||
| 		protect[rvi] = struct{}{} | ||||
| 		prettyPrint(protect, sf, prefix+"&", suffix, rv.Elem().Interface(), hooks, false, false) | ||||
| 	case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int8: | ||||
| 		if v := rv.Int(); v != 0 || zero { | ||||
| 			suffix = strings.Replace(suffix, "%", "%%", -1) | ||||
| 			sf.Format("%s%v"+suffix, prefix, v) | ||||
| 		} | ||||
| 	case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint8: | ||||
| 		if v := rv.Uint(); v != 0 || zero { | ||||
| 			suffix = strings.Replace(suffix, "%", "%%", -1) | ||||
| 			sf.Format("%s%v"+suffix, prefix, v) | ||||
| 		} | ||||
| 	case reflect.Float32, reflect.Float64: | ||||
| 		if v := rv.Float(); v != 0 || zero { | ||||
| 			suffix = strings.Replace(suffix, "%", "%%", -1) | ||||
| 			sf.Format("%s%v"+suffix, prefix, v) | ||||
| 		} | ||||
| 	case reflect.Complex64, reflect.Complex128: | ||||
| 		if v := rv.Complex(); v != 0 || zero { | ||||
| 			suffix = strings.Replace(suffix, "%", "%%", -1) | ||||
| 			sf.Format("%s%v"+suffix, prefix, v) | ||||
| 		} | ||||
| 	case reflect.Uintptr: | ||||
| 		if v := rv.Uint(); v != 0 || zero { | ||||
| 			suffix = strings.Replace(suffix, "%", "%%", -1) | ||||
| 			sf.Format("%s%v"+suffix, prefix, v) | ||||
| 		} | ||||
| 	case reflect.UnsafePointer: | ||||
| 		s := fmt.Sprintf("%p", rv.Interface()) | ||||
| 		if s == "0x0" && !zero { | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		suffix = strings.Replace(suffix, "%", "%%", -1) | ||||
| 		sf.Format("%s%s"+suffix, prefix, s) | ||||
| 	case reflect.Bool: | ||||
| 		if v := rv.Bool(); v || zero { | ||||
| 			suffix = strings.Replace(suffix, "%", "%%", -1) | ||||
| 			sf.Format("%s%v"+suffix, prefix, rv.Bool()) | ||||
| 		} | ||||
| 	case reflect.String: | ||||
| 		s := rv.Interface().(string) | ||||
| 		if s == "" && !zero { | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		suffix = strings.Replace(suffix, "%", "%%", -1) | ||||
| 		sf.Format("%s%q"+suffix, prefix, s) | ||||
| 	case reflect.Chan: | ||||
| 		if reflect.Zero(rt).Interface() == rv.Interface() && !zero { | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		c := rv.Cap() | ||||
| 		s := "" | ||||
| 		if c != 0 { | ||||
| 			s = fmt.Sprintf("// capacity: %d", c) | ||||
| 		} | ||||
| 		suffix = strings.Replace(suffix, "%", "%%", -1) | ||||
| 		sf.Format("%s%s %s%s"+suffix, prefix, rt.ChanDir(), rt.Elem().Name(), s) | ||||
| 	case reflect.Func: | ||||
| 		if rv.IsNil() && !zero { | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		var in, out []string | ||||
| 		for i := 0; i < rt.NumIn(); i++ { | ||||
| 			x := reflect.Zero(rt.In(i)) | ||||
| 			in = append(in, fmt.Sprintf("%T", x.Interface())) | ||||
| 		} | ||||
| 		if rt.IsVariadic() { | ||||
| 			i := len(in) - 1 | ||||
| 			in[i] = "..." + in[i][2:] | ||||
| 		} | ||||
| 		for i := 0; i < rt.NumOut(); i++ { | ||||
| 			out = append(out, rt.Out(i).Name()) | ||||
| 		} | ||||
| 		s := "(" + strings.Join(in, ", ") + ")" | ||||
| 		t := strings.Join(out, ", ") | ||||
| 		if len(out) > 1 { | ||||
| 			t = "(" + t + ")" | ||||
| 		} | ||||
| 		if t != "" { | ||||
| 			t = " " + t | ||||
| 		} | ||||
| 		suffix = strings.Replace(suffix, "%", "%%", -1) | ||||
| 		sf.Format("%sfunc%s%s { ... }"+suffix, prefix, s, t) | ||||
| 	case reflect.Map: | ||||
| 		keys := rv.MapKeys() | ||||
| 		if len(keys) == 0 && !zero { | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		var buf bytes.Buffer | ||||
| 		nf := IndentFormatter(&buf, "· ") | ||||
| 		var skeys []string | ||||
| 		for i, k := range keys { | ||||
| 			prettyPrint(protect, nf, "", "", k.Interface(), hooks, false, false) | ||||
| 			skeys = append(skeys, fmt.Sprintf("%s%10d", buf.Bytes(), i)) | ||||
| 			buf.Reset() | ||||
| 		} | ||||
| 		sort.Strings(skeys) | ||||
| 		sf.Format("%s%T{%i\n", prefix, v) | ||||
| 		for _, k := range skeys { | ||||
| 			si := strings.TrimSpace(k[len(k)-10:]) | ||||
| 			k = k[:len(k)-10] | ||||
| 			n, _ := strconv.ParseUint(si, 10, 64) | ||||
| 			mv := rv.MapIndex(keys[n]) | ||||
| 			prettyPrint(protect, sf, fmt.Sprintf("%s: ", k), ",\n", mv.Interface(), hooks, false, false) | ||||
| 		} | ||||
| 		suffix = strings.Replace(suffix, "%", "%%", -1) | ||||
| 		sf.Format("%u}" + suffix) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Gopath returns the value of the $GOPATH environment variable or its default | ||||
| // value if not set. | ||||
| func Gopath() string { | ||||
| 	if r := os.Getenv("GOPATH"); r != "" { | ||||
| 		return r | ||||
| 	} | ||||
| 
 | ||||
| 	// go1.8: https://github.com/golang/go/blob/74628a8b9f102bddd5078ee426efe0fd57033115/doc/code.html#L122 | ||||
| 	switch runtime.GOOS { | ||||
| 	case "plan9": | ||||
| 		return os.Getenv("home") | ||||
| 	case "windows": | ||||
| 		return filepath.Join(os.Getenv("USERPROFILE"), "go") | ||||
| 	default: | ||||
| 		return filepath.Join(os.Getenv("HOME"), "go") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Homepath returns the user's home directory path. | ||||
| func Homepath() string { | ||||
| 	// go1.8: https://github.com/golang/go/blob/74628a8b9f102bddd5078ee426efe0fd57033115/doc/code.html#L122 | ||||
| 	switch runtime.GOOS { | ||||
| 	case "plan9": | ||||
| 		return os.Getenv("home") | ||||
| 	case "windows": | ||||
| 		return os.Getenv("USERPROFILE") | ||||
| 	default: | ||||
| 		return os.Getenv("HOME") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // ImportPath returns the import path of the caller or an error, if any. | ||||
| func ImportPath() (string, error) { | ||||
| 	_, file, _, ok := runtime.Caller(1) | ||||
| 	if !ok { | ||||
| 		return "", fmt.Errorf("runtime.Caller failed") | ||||
| 	} | ||||
| 
 | ||||
| 	gopath := Gopath() | ||||
| 	for _, v := range filepath.SplitList(gopath) { | ||||
| 		gp := filepath.Join(v, "src") | ||||
| 		path, err := filepath.Rel(gp, file) | ||||
| 		if err != nil { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		return filepath.Dir(path), nil | ||||
| 	} | ||||
| 
 | ||||
| 	return "", fmt.Errorf("cannot determine import path using GOPATH=%s", gopath) | ||||
| } | ||||
							
								
								
									
										27
									
								
								vendor/modernc.org/token/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										27
									
								
								vendor/modernc.org/token/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,27 +0,0 @@ | |||
| Copyright (c) 2009 The Go Authors. All rights reserved. | ||||
| 
 | ||||
| Redistribution and use in source and binary forms, with or without | ||||
| modification, are permitted provided that the following conditions are | ||||
| met: | ||||
| 
 | ||||
|    * Redistributions of source code must retain the above copyright | ||||
| notice, this list of conditions and the following disclaimer. | ||||
|    * Redistributions in binary form must reproduce the above | ||||
| copyright notice, this list of conditions and the following disclaimer | ||||
| in the documentation and/or other materials provided with the | ||||
| distribution. | ||||
|    * Neither the name of Google Inc. nor the names of its | ||||
| contributors may be used to endorse or promote products derived from | ||||
| this software without specific prior written permission. | ||||
| 
 | ||||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||
| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||
| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
							
								
								
									
										56
									
								
								vendor/modernc.org/token/Makefile
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										56
									
								
								vendor/modernc.org/token/Makefile
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,56 +0,0 @@ | |||
| .PHONY:	all clean cover cpu editor internalError later mem nuke todo edit | ||||
| 
 | ||||
| grep=--include=*.go --include=*.l --include=*.y --include=*.yy | ||||
| ngrep='TODOOK\|parser\.go\|scanner\.go\|.*_string\.go' | ||||
| 
 | ||||
| all: editor | ||||
| 	go vet 2>&1 | grep -v $(ngrep) || true | ||||
| 	golint 2>&1 | grep -v $(ngrep) || true | ||||
| 	make todo | ||||
| 	unused . || true | ||||
| 	misspell *.go | ||||
| 	gosimple || true | ||||
| 	maligned || true | ||||
| 	unconvert -apply | ||||
| 
 | ||||
| clean: | ||||
| 	go clean | ||||
| 	rm -f *~ *.test *.out | ||||
| 
 | ||||
| cover: | ||||
| 	t=$(shell mktemp) ; go test -coverprofile $$t && go tool cover -html $$t && unlink $$t | ||||
| 
 | ||||
| cpu: clean | ||||
| 	go test -run @ -bench . -cpuprofile cpu.out | ||||
| 	go tool pprof -lines *.test cpu.out | ||||
| 
 | ||||
| 
 | ||||
| edit: | ||||
| 	@touch log | ||||
| 	@if [ -f "Session.vim" ]; then gvim -S & else gvim -p Makefile *.go & fi | ||||
| 
 | ||||
| editor: | ||||
| 	gofmt -l -s -w *.go | ||||
| 	go test -i | ||||
| 	go test 2>&1 | tee log | ||||
| 	go install | ||||
| 
 | ||||
| internalError: | ||||
| 	egrep -ho '"internal error.*"' *.go | sort | cat -n | ||||
| 
 | ||||
| later: | ||||
| 	@grep -n $(grep) LATER * || true | ||||
| 	@grep -n $(grep) MAYBE * || true | ||||
| 
 | ||||
| mem: clean | ||||
| 	go test -run @ -bench . -memprofile mem.out -memprofilerate 1 -timeout 24h | ||||
| 	go tool pprof -lines -web -alloc_space *.test mem.out | ||||
| 
 | ||||
| nuke: clean | ||||
| 	go clean -i | ||||
| 
 | ||||
| todo: | ||||
| 	@grep -nr $(grep) ^[[:space:]]*_[[:space:]]*=[[:space:]][[:alpha:]][[:alnum:]]* * | grep -v $(ngrep) || true | ||||
| 	@grep -nr $(grep) TODO * | grep -v $(ngrep) || true | ||||
| 	@grep -nr $(grep) BUG * | grep -v $(ngrep) || true | ||||
| 	@grep -nr $(grep) [^[:alpha:]]println * | grep -v $(ngrep) || true | ||||
							
								
								
									
										9
									
								
								vendor/modernc.org/token/README.md
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/modernc.org/token/README.md
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,9 +0,0 @@ | |||
| # token | ||||
| 
 | ||||
| Package token is a variant of the stdlib package token with types FileSet and Token removed | ||||
| 
 | ||||
| Installation | ||||
| 
 | ||||
|     $ go get [-u] modernc.org/token | ||||
| 
 | ||||
| Documentation: [godoc.org/modernc.org/token](http://godoc.org/modernc.org/token) | ||||
							
								
								
									
										359
									
								
								vendor/modernc.org/token/position.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										359
									
								
								vendor/modernc.org/token/position.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,359 +0,0 @@ | |||
| // Copyright 2010 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. | ||||
| 
 | ||||
| // Package token is variant of the stdlib package token with types FileSet and | ||||
| // Token removed. | ||||
| package token // import "modernc.org/token" | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"sort" | ||||
| ) | ||||
| 
 | ||||
| // ----------------------------------------------------------------------------- | ||||
| // Positions | ||||
| 
 | ||||
| // Position describes an arbitrary source position | ||||
| // including the file, line, and column location. | ||||
| // A Position is valid if the line number is > 0. | ||||
| type Position struct { | ||||
| 	Filename string // filename, if any | ||||
| 	Offset   int    // offset, starting at 0 | ||||
| 	Line     int    // line number, starting at 1 | ||||
| 	Column   int    // column number, starting at 1 (byte count) | ||||
| } | ||||
| 
 | ||||
| // IsValid reports whether the position is valid. | ||||
| func (pos *Position) IsValid() bool { return pos.Line > 0 } | ||||
| 
 | ||||
| // String returns a string in one of several forms: | ||||
| // | ||||
| //	file:line:column    valid position with file name | ||||
| //	file:line           valid position with file name but no column (column == 0) | ||||
| //	line:column         valid position without file name | ||||
| //	line                valid position without file name and no column (column == 0) | ||||
| //	file                invalid position with file name | ||||
| //	-                   invalid position without file name | ||||
| func (pos Position) String() string { | ||||
| 	s := pos.Filename | ||||
| 	if pos.IsValid() { | ||||
| 		if s != "" { | ||||
| 			s += ":" | ||||
| 		} | ||||
| 		s += fmt.Sprintf("%d", pos.Line) | ||||
| 		if pos.Column != 0 { | ||||
| 			s += fmt.Sprintf(":%d", pos.Column) | ||||
| 		} | ||||
| 	} | ||||
| 	if s == "" { | ||||
| 		s = "-" | ||||
| 	} | ||||
| 	return s | ||||
| } | ||||
| 
 | ||||
| // Pos is a compact encoding of a source position within a file set. | ||||
| // It can be converted into a Position for a more convenient, but much | ||||
| // larger, representation. | ||||
| // | ||||
| // The Pos value for a given file is a number in the range [base, base+size], | ||||
| // where base and size are specified when a file is added to the file set. | ||||
| // The difference between a Pos value and the corresponding file base | ||||
| // corresponds to the byte offset of that position (represented by the Pos value) | ||||
| // from the beginning of the file. Thus, the file base offset is the Pos value | ||||
| // representing the first byte in the file. | ||||
| // | ||||
| // To create the Pos value for a specific source offset (measured in bytes), | ||||
| // first add the respective file to the current file set using FileSet.AddFile | ||||
| // and then call File.Pos(offset) for that file. Given a Pos value p | ||||
| // for a specific file set fset, the corresponding Position value is | ||||
| // obtained by calling fset.Position(p). | ||||
| // | ||||
| // Pos values can be compared directly with the usual comparison operators: | ||||
| // If two Pos values p and q are in the same file, comparing p and q is | ||||
| // equivalent to comparing the respective source file offsets. If p and q | ||||
| // are in different files, p < q is true if the file implied by p was added | ||||
| // to the respective file set before the file implied by q. | ||||
| type Pos int | ||||
| 
 | ||||
| // The zero value for Pos is NoPos; there is no file and line information | ||||
| // associated with it, and NoPos.IsValid() is false. NoPos is always | ||||
| // smaller than any other Pos value. The corresponding Position value | ||||
| // for NoPos is the zero value for Position. | ||||
| const NoPos Pos = 0 | ||||
| 
 | ||||
| // IsValid reports whether the position is valid. | ||||
| func (p Pos) IsValid() bool { | ||||
| 	return p != NoPos | ||||
| } | ||||
| 
 | ||||
| // ----------------------------------------------------------------------------- | ||||
| // File | ||||
| 
 | ||||
| // A File is a handle for a file belonging to a FileSet. | ||||
| // A File has a name, size, and line offset table. | ||||
| type File struct { | ||||
| 	name string // file name as provided to AddFile | ||||
| 	base int    // Pos value range for this file is [base...base+size] | ||||
| 	size int    // file size as provided to AddFile | ||||
| 
 | ||||
| 	lines []int // lines contains the offset of the first character for each line (the first entry is always 0) | ||||
| 	infos []lineInfo | ||||
| } | ||||
| 
 | ||||
| // NewFile returns  a new file with a given filename and file size. | ||||
| // | ||||
| func NewFile(filename string, size int) *File { | ||||
| 	return &File{name: filename, base: 1, size: size, lines: []int{0}} | ||||
| } | ||||
| 
 | ||||
| // Name returns the file name of file f as registered with AddFile. | ||||
| func (f *File) Name() string { | ||||
| 	return f.name | ||||
| } | ||||
| 
 | ||||
| // Base returns the base offset of file f as registered with AddFile. | ||||
| func (f *File) Base() int { | ||||
| 	return f.base | ||||
| } | ||||
| 
 | ||||
| // Size returns the size of file f as registered with AddFile. | ||||
| func (f *File) Size() int { | ||||
| 	return f.size | ||||
| } | ||||
| 
 | ||||
| // LineCount returns the number of lines in file f. | ||||
| func (f *File) LineCount() int { | ||||
| 	n := len(f.lines) | ||||
| 	return n | ||||
| } | ||||
| 
 | ||||
| // AddLine adds the line offset for a new line. | ||||
| // The line offset must be larger than the offset for the previous line | ||||
| // and smaller than the file size; otherwise the line offset is ignored. | ||||
| func (f *File) AddLine(offset int) { | ||||
| 	if i := len(f.lines); (i == 0 || f.lines[i-1] < offset) && offset < f.size { | ||||
| 		f.lines = append(f.lines, offset) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // MergeLine merges a line with the following line. It is akin to replacing | ||||
| // the newline character at the end of the line with a space (to not change the | ||||
| // remaining offsets). To obtain the line number, consult e.g. Position.Line. | ||||
| // MergeLine will panic if given an invalid line number. | ||||
| func (f *File) MergeLine(line int) { | ||||
| 	if line < 1 { | ||||
| 		panic(fmt.Sprintf("invalid line number %d (should be >= 1)", line)) | ||||
| 	} | ||||
| 	if line >= len(f.lines) { | ||||
| 		panic(fmt.Sprintf("invalid line number %d (should be < %d)", line, len(f.lines))) | ||||
| 	} | ||||
| 	// To merge the line numbered <line> with the line numbered <line+1>, | ||||
| 	// we need to remove the entry in lines corresponding to the line | ||||
| 	// numbered <line+1>. The entry in lines corresponding to the line | ||||
| 	// numbered <line+1> is located at index <line>, since indices in lines | ||||
| 	// are 0-based and line numbers are 1-based. | ||||
| 	copy(f.lines[line:], f.lines[line+1:]) | ||||
| 	f.lines = f.lines[:len(f.lines)-1] | ||||
| } | ||||
| 
 | ||||
| // SetLines sets the line offsets for a file and reports whether it succeeded. | ||||
| // The line offsets are the offsets of the first character of each line; | ||||
| // for instance for the content "ab\nc\n" the line offsets are {0, 3}. | ||||
| // An empty file has an empty line offset table. | ||||
| // Each line offset must be larger than the offset for the previous line | ||||
| // and smaller than the file size; otherwise SetLines fails and returns | ||||
| // false. | ||||
| // Callers must not mutate the provided slice after SetLines returns. | ||||
| func (f *File) SetLines(lines []int) bool { | ||||
| 	// verify validity of lines table | ||||
| 	size := f.size | ||||
| 	for i, offset := range lines { | ||||
| 		if i > 0 && offset <= lines[i-1] || size <= offset { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// set lines table | ||||
| 	f.lines = lines | ||||
| 	return true | ||||
| } | ||||
| 
 | ||||
| // SetLinesForContent sets the line offsets for the given file content. | ||||
| // It ignores position-altering //line comments. | ||||
| func (f *File) SetLinesForContent(content []byte) { | ||||
| 	var lines []int | ||||
| 	line := 0 | ||||
| 	for offset, b := range content { | ||||
| 		if line >= 0 { | ||||
| 			lines = append(lines, line) | ||||
| 		} | ||||
| 		line = -1 | ||||
| 		if b == '\n' { | ||||
| 			line = offset + 1 | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// set lines table | ||||
| 	f.lines = lines | ||||
| } | ||||
| 
 | ||||
| // LineStart returns the Pos value of the start of the specified line. | ||||
| // It ignores any alternative positions set using AddLineColumnInfo. | ||||
| // LineStart panics if the 1-based line number is invalid. | ||||
| func (f *File) LineStart(line int) Pos { | ||||
| 	if line < 1 { | ||||
| 		panic(fmt.Sprintf("invalid line number %d (should be >= 1)", line)) | ||||
| 	} | ||||
| 	if line > len(f.lines) { | ||||
| 		panic(fmt.Sprintf("invalid line number %d (should be < %d)", line, len(f.lines))) | ||||
| 	} | ||||
| 	return Pos(f.base + f.lines[line-1]) | ||||
| } | ||||
| 
 | ||||
| // A lineInfo object describes alternative file, line, and column | ||||
| // number information (such as provided via a //line directive) | ||||
| // for a given file offset. | ||||
| type lineInfo struct { | ||||
| 	// fields are exported to make them accessible to gob | ||||
| 	Offset       int | ||||
| 	Filename     string | ||||
| 	Line, Column int | ||||
| } | ||||
| 
 | ||||
| // AddLineInfo is like AddLineColumnInfo with a column = 1 argument. | ||||
| // It is here for backward-compatibility for code prior to Go 1.11. | ||||
| func (f *File) AddLineInfo(offset int, filename string, line int) { | ||||
| 	f.AddLineColumnInfo(offset, filename, line, 1) | ||||
| } | ||||
| 
 | ||||
| // AddLineColumnInfo adds alternative file, line, and column number | ||||
| // information for a given file offset. The offset must be larger | ||||
| // than the offset for the previously added alternative line info | ||||
| // and smaller than the file size; otherwise the information is | ||||
| // ignored. | ||||
| // | ||||
| // AddLineColumnInfo is typically used to register alternative position | ||||
| // information for line directives such as //line filename:line:column. | ||||
| func (f *File) AddLineColumnInfo(offset int, filename string, line, column int) { | ||||
| 	if i := len(f.infos); i == 0 || f.infos[i-1].Offset < offset && offset < f.size { | ||||
| 		f.infos = append(f.infos, lineInfo{offset, filename, line, column}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Pos returns the Pos value for the given file offset; | ||||
| // the offset must be <= f.Size(). | ||||
| // f.Pos(f.Offset(p)) == p. | ||||
| func (f *File) Pos(offset int) Pos { | ||||
| 	if offset > f.size { | ||||
| 		panic(fmt.Sprintf("invalid file offset %d (should be <= %d)", offset, f.size)) | ||||
| 	} | ||||
| 	return Pos(f.base + offset) | ||||
| } | ||||
| 
 | ||||
| // Offset returns the offset for the given file position p; | ||||
| // p must be a valid Pos value in that file. | ||||
| // f.Offset(f.Pos(offset)) == offset. | ||||
| func (f *File) Offset(p Pos) int { | ||||
| 	if int(p) < f.base || int(p) > f.base+f.size { | ||||
| 		panic(fmt.Sprintf("invalid Pos value %d (should be in [%d, %d])", p, f.base, f.base+f.size)) | ||||
| 	} | ||||
| 	return int(p) - f.base | ||||
| } | ||||
| 
 | ||||
| // Line returns the line number for the given file position p; | ||||
| // p must be a Pos value in that file or NoPos. | ||||
| func (f *File) Line(p Pos) int { | ||||
| 	return f.Position(p).Line | ||||
| } | ||||
| 
 | ||||
| func searchLineInfos(a []lineInfo, x int) int { | ||||
| 	return sort.Search(len(a), func(i int) bool { return a[i].Offset > x }) - 1 | ||||
| } | ||||
| 
 | ||||
| // unpack returns the filename and line and column number for a file offset. | ||||
| // If adjusted is set, unpack will return the filename and line information | ||||
| // possibly adjusted by //line comments; otherwise those comments are ignored. | ||||
| func (f *File) unpack(offset int, adjusted bool) (filename string, line, column int) { | ||||
| 	filename = f.name | ||||
| 	if i := searchInts(f.lines, offset); i >= 0 { | ||||
| 		line, column = i+1, offset-f.lines[i]+1 | ||||
| 	} | ||||
| 	if adjusted && len(f.infos) > 0 { | ||||
| 		// few files have extra line infos | ||||
| 		if i := searchLineInfos(f.infos, offset); i >= 0 { | ||||
| 			alt := &f.infos[i] | ||||
| 			filename = alt.Filename | ||||
| 			if i := searchInts(f.lines, alt.Offset); i >= 0 { | ||||
| 				// i+1 is the line at which the alternative position was recorded | ||||
| 				d := line - (i + 1) // line distance from alternative position base | ||||
| 				line = alt.Line + d | ||||
| 				if alt.Column == 0 { | ||||
| 					// alternative column is unknown => relative column is unknown | ||||
| 					// (the current specification for line directives requires | ||||
| 					// this to apply until the next PosBase/line directive, | ||||
| 					// not just until the new newline) | ||||
| 					column = 0 | ||||
| 				} else if d == 0 { | ||||
| 					// the alternative position base is on the current line | ||||
| 					// => column is relative to alternative column | ||||
| 					column = alt.Column + (offset - alt.Offset) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (f *File) position(p Pos, adjusted bool) (pos Position) { | ||||
| 	offset := int(p) - f.base | ||||
| 	pos.Offset = offset | ||||
| 	pos.Filename, pos.Line, pos.Column = f.unpack(offset, adjusted) | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // PositionFor returns the Position value for the given file position p. | ||||
| // If adjusted is set, the position may be adjusted by position-altering | ||||
| // //line comments; otherwise those comments are ignored. | ||||
| // p must be a Pos value in f or NoPos. | ||||
| func (f *File) PositionFor(p Pos, adjusted bool) (pos Position) { | ||||
| 	if p != NoPos { | ||||
| 		if int(p) < f.base || int(p) > f.base+f.size { | ||||
| 			panic(fmt.Sprintf("invalid Pos value %d (should be in [%d, %d])", p, f.base, f.base+f.size)) | ||||
| 		} | ||||
| 		pos = f.position(p, adjusted) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Position returns the Position value for the given file position p. | ||||
| // Calling f.Position(p) is equivalent to calling f.PositionFor(p, true). | ||||
| func (f *File) Position(p Pos) (pos Position) { | ||||
| 	return f.PositionFor(p, true) | ||||
| } | ||||
| 
 | ||||
| // ----------------------------------------------------------------------------- | ||||
| // Helper functions | ||||
| 
 | ||||
| func searchInts(a []int, x int) int { | ||||
| 	// This function body is a manually inlined version of: | ||||
| 	// | ||||
| 	//   return sort.Search(len(a), func(i int) bool { return a[i] > x }) - 1 | ||||
| 	// | ||||
| 	// With better compiler optimizations, this may not be needed in the | ||||
| 	// future, but at the moment this change improves the go/printer | ||||
| 	// benchmark performance by ~30%. This has a direct impact on the | ||||
| 	// speed of gofmt and thus seems worthwhile (2011-04-29). | ||||
| 	// TODO(gri): Remove this when compilers have caught up. | ||||
| 	i, j := 0, len(a) | ||||
| 	for i < j { | ||||
| 		h := int(uint(i+j) >> 1) // avoid overflow when computing h | ||||
| 		// i ≤ h < j | ||||
| 		if a[h] <= x { | ||||
| 			i = h + 1 | ||||
| 		} else { | ||||
| 			j = h | ||||
| 		} | ||||
| 	} | ||||
| 	return i - 1 | ||||
| } | ||||
							
								
								
									
										18
									
								
								vendor/modules.txt
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								vendor/modules.txt
									
										
									
									
										vendored
									
									
								
							|  | @ -364,11 +364,6 @@ github.com/gorilla/websocket | |||
| github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule | ||||
| github.com/grpc-ecosystem/grpc-gateway/v2/runtime | ||||
| github.com/grpc-ecosystem/grpc-gateway/v2/utilities | ||||
| # github.com/hashicorp/golang-lru/v2 v2.0.7 | ||||
| ## explicit; go 1.18 | ||||
| github.com/hashicorp/golang-lru/v2 | ||||
| github.com/hashicorp/golang-lru/v2/internal | ||||
| github.com/hashicorp/golang-lru/v2/simplelru | ||||
| # github.com/hashicorp/hcl v1.0.0 | ||||
| ## explicit | ||||
| github.com/hashicorp/hcl | ||||
|  | @ -1289,9 +1284,6 @@ gopkg.in/yaml.v2 | |||
| # gopkg.in/yaml.v3 v3.0.1 | ||||
| ## explicit | ||||
| gopkg.in/yaml.v3 | ||||
| # modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 | ||||
| ## explicit; go 1.20 | ||||
| modernc.org/gc/v3 | ||||
| # modernc.org/libc v1.55.3 | ||||
| ## explicit; go 1.20 | ||||
| modernc.org/libc | ||||
|  | @ -1326,21 +1318,15 @@ modernc.org/mathutil | |||
| # modernc.org/memory v1.8.0 | ||||
| ## explicit; go 1.18 | ||||
| modernc.org/memory | ||||
| # modernc.org/sqlite v0.0.0-00010101000000-000000000000 => gitlab.com/NyaaaWhatsUpDoc/sqlite v1.34.2-concurrency-workaround | ||||
| # modernc.org/sqlite v0.0.0-00010101000000-000000000000 => gitlab.com/NyaaaWhatsUpDoc/sqlite v1.34.5-concurrency-workaround | ||||
| ## explicit; go 1.21 | ||||
| modernc.org/sqlite | ||||
| modernc.org/sqlite/lib | ||||
| # modernc.org/strutil v1.2.0 | ||||
| ## explicit; go 1.18 | ||||
| modernc.org/strutil | ||||
| # modernc.org/token v1.1.0 | ||||
| ## explicit | ||||
| modernc.org/token | ||||
| # mvdan.cc/xurls/v2 v2.6.0 | ||||
| ## explicit; go 1.22.0 | ||||
| mvdan.cc/xurls/v2 | ||||
| # github.com/go-swagger/go-swagger => github.com/superseriousbusiness/go-swagger v0.31.0-gts-go1.23-fix | ||||
| # modernc.org/sqlite => gitlab.com/NyaaaWhatsUpDoc/sqlite v1.34.2-concurrency-workaround | ||||
| # modernc.org/sqlite => gitlab.com/NyaaaWhatsUpDoc/sqlite v1.34.5-concurrency-workaround | ||||
| # go.opentelemetry.io/otel => go.opentelemetry.io/otel v1.29.0 | ||||
| # go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc => go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 | ||||
| # go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp => go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.29.0 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue