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 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/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 | // 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 | 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/securecookie v1.1.2 // indirect | ||||||
| 	github.com/gorilla/sessions v1.2.2 // indirect | 	github.com/gorilla/sessions v1.2.2 // indirect | ||||||
| 	github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // 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/hashicorp/hcl v1.0.0 // indirect | ||||||
| 	github.com/huandu/xstrings v1.4.0 // indirect | 	github.com/huandu/xstrings v1.4.0 // indirect | ||||||
| 	github.com/imdario/mergo v0.3.16 // indirect | 	github.com/imdario/mergo v0.3.16 // indirect | ||||||
|  | @ -235,10 +234,7 @@ require ( | ||||||
| 	google.golang.org/protobuf v1.36.2 // indirect | 	google.golang.org/protobuf v1.36.2 // indirect | ||||||
| 	gopkg.in/ini.v1 v1.67.0 // indirect | 	gopkg.in/ini.v1 v1.67.0 // indirect | ||||||
| 	gopkg.in/yaml.v2 v2.4.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/libc v1.55.3 // indirect | ||||||
| 	modernc.org/mathutil v1.6.0 // indirect | 	modernc.org/mathutil v1.6.0 // indirect | ||||||
| 	modernc.org/memory v1.8.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/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.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 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 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= | ||||||
| github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= | 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= | 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.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 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= | ||||||
| github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= | 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.5-concurrency-workaround h1:BLmmUkkZ2KiS8k2lePZRQo7Z5puFrfxuFq9BrJQmS9o= | ||||||
| gitlab.com/NyaaaWhatsUpDoc/sqlite v1.34.2-concurrency-workaround/go.mod h1:dnR723UrTtjKpoHCAMN0Q/gZ9MT4r+iRvIBb9umWFkU= | 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 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= | ||||||
| go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= | 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= | 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/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 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw= | ||||||
| modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= | 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 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U= | ||||||
| modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w= | 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= | 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=riscv64 go build -v ./... | ||||||
| 	GOOS=linux GOARCH=s390x go test -c -o /dev/null | 	GOOS=linux GOARCH=s390x go test -c -o /dev/null | ||||||
| 	GOOS=linux GOARCH=s390x go build -v ./... | 	GOOS=linux GOARCH=s390x go build -v ./... | ||||||
| 	GOOS=netbsd GOARCH=amd64 go test -c -o /dev/null | 	# GOOS=netbsd GOARCH=amd64 go test -c -o /dev/null | ||||||
| 	GOOS=netbsd GOARCH=amd64 go build -v ./... | 	# GOOS=netbsd GOARCH=amd64 go build -v ./... | ||||||
| 	GOOS=openbsd GOARCH=amd64 go test -c -o /dev/null | 	GOOS=openbsd GOARCH=amd64 go test -c -o /dev/null | ||||||
| 	GOOS=openbsd GOARCH=amd64 go build -v ./... | 	GOOS=openbsd GOARCH=amd64 go build -v ./... | ||||||
| 	GOOS=openbsd GOARCH=arm64 go test -c -o /dev/null | 	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 | 	go test -v -timeout 24h 2>&1 | tee log-test | ||||||
| 	 | 	 | ||||||
| vendor: | 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 | 	make build_all_targets | ||||||
| 
 | 
 | ||||||
| work: | 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 | // Use of this source code is governed by a BSD-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
| 
 | 
 | ||||||
|  | //go:build !(linux && arm64) | ||||||
|  | 
 | ||||||
| package sqlite3 | package sqlite3 | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | @ -12,3 +14,7 @@ import ( | ||||||
| func X__ccgo_sqlite3_log(t *libc.TLS, iErrCode int32, zFormat uintptr, va uintptr) { /* sqlite3.c:29405:17: */ | 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) | 	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) | 	sqliteLockedSharedcache = sqlite3.SQLITE_LOCKED | (1 << 8) | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | // https://gitlab.com/cznic/sqlite/-/issues/199 | ||||||
|  | func init() { | ||||||
|  | 	sqlite3.PatchIssue199() | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Error represents sqlite library error code. | // Error represents sqlite library error code. | ||||||
| type Error struct { | type Error struct { | ||||||
| 	msg  string | 	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/internal/httprule | ||||||
| github.com/grpc-ecosystem/grpc-gateway/v2/runtime | github.com/grpc-ecosystem/grpc-gateway/v2/runtime | ||||||
| github.com/grpc-ecosystem/grpc-gateway/v2/utilities | 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 | # github.com/hashicorp/hcl v1.0.0 | ||||||
| ## explicit | ## explicit | ||||||
| github.com/hashicorp/hcl | github.com/hashicorp/hcl | ||||||
|  | @ -1289,9 +1284,6 @@ gopkg.in/yaml.v2 | ||||||
| # gopkg.in/yaml.v3 v3.0.1 | # gopkg.in/yaml.v3 v3.0.1 | ||||||
| ## explicit | ## explicit | ||||||
| gopkg.in/yaml.v3 | 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 | # modernc.org/libc v1.55.3 | ||||||
| ## explicit; go 1.20 | ## explicit; go 1.20 | ||||||
| modernc.org/libc | modernc.org/libc | ||||||
|  | @ -1326,21 +1318,15 @@ modernc.org/mathutil | ||||||
| # modernc.org/memory v1.8.0 | # modernc.org/memory v1.8.0 | ||||||
| ## explicit; go 1.18 | ## explicit; go 1.18 | ||||||
| modernc.org/memory | 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 | ## explicit; go 1.21 | ||||||
| modernc.org/sqlite | modernc.org/sqlite | ||||||
| modernc.org/sqlite/lib | 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 | # mvdan.cc/xurls/v2 v2.6.0 | ||||||
| ## explicit; go 1.22.0 | ## explicit; go 1.22.0 | ||||||
| mvdan.cc/xurls/v2 | mvdan.cc/xurls/v2 | ||||||
| # github.com/go-swagger/go-swagger => github.com/superseriousbusiness/go-swagger v0.31.0-gts-go1.23-fix | # 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 => 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/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 | # 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