github.com/gopherjs/gopherjs@v1.19.0-beta1.0.20240506212314-27071a8796e4/doc/pargma.md (about) 1 # Compiler directives 2 3 Compiler directives allow to provide low-level instructions to the GopherJS 4 compiler, which are outside of the Go language itself. Compiler directives are 5 specific to each Go compiler implementation and may be a source of portability 6 issues, so it is recommended to avoid using them if possible. 7 8 GopherJS compiler supports the following directives: 9 10 - [go:linkname](#golinkname) 11 - [go:embed](#goembed) 12 - [gopherjs:keep-original](#gopherjskeep-original) 13 - [gopherjs:purge](#gopherjspurge) 14 - [gopherjs:override-signature](#gopherjsoverride-signature) 15 16 ## `go:linkname` 17 18 This is a limited version of the `go:linkname` directive the upstream Go 19 compiler implements. Usage: 20 21 ```go 22 import _ "unsafe" // for go:linkname 23 24 //go:linkname localname import/path.remotename 25 func localname(arg1 type1, arg2 type2) (returnType, error) 26 ``` 27 28 This directive has an effect of making a `remotename` function from 29 `import/path` package available to the current package as `localname`. 30 Signatures of `remotename` and `localname` must be identical. Since this 31 directive can subvert package incapsulation, the source file that uses the 32 directive must also import `unsafe`. 33 34 The following directive formats are supported: 35 36 - `//go:linkname <localname> <importpath>.<name>` 37 - `//go:linkname <localname> <importpath>.<type>.<name>` 38 - `//go:linkname <localname> <importpath>.<(*type)>.<name>` 39 40 Compared to the upstream Go, the following limitations exist in GopherJS: 41 42 - The directive only works on package-level functions or methods (variables 43 are not supported). 44 - The directive can only be used to "import" implementation from another 45 package, and not to "provide" local implementation to another package. 46 47 See [gopherjs/issues/1000](https://github.com/gopherjs/gopherjs/issues/1000) 48 for details. 49 50 ## `go:embed` 51 52 This is a very similar version of the `go:embed` directive the upstream Go 53 compiler implements. 54 GopherJS leverages [goembed](https://github.com/visualfc/goembed) 55 to parse this directive and provide support reading embedded content. Usage: 56 57 ```go 58 import _ "embed" // for go:embed 59 60 //go:embed externalText 61 var embeddedText string 62 63 //go:embed externalContent 64 var embeddedContent []byte 65 66 //go:embed file1 67 //go:embed file2 68 // ... 69 //go:embed image/* blobs/* 70 var embeddedFiles embed.FS 71 ``` 72 73 This directive affects the variable specification (e.g. `embeddedText`) 74 that the comment containing the directive is associated with. 75 There may be one embed directives associated with `string` or `[]byte` 76 variables. There may be one or more embed directives associated with 77 `embed.FS` variables and each directive may contain one or more 78 file matching patterns. The effect is that the variable will be assigned to 79 the content (e.g. `externalText`) given in the directive. In the case 80 of `embed.FS`, several embedded files will be accessible. 81 82 See [pkg.go.dev/embed](https://pkg.go.dev/embed#hdr-Directives) 83 for more information. 84 85 ## `gopherjs:keep-original` 86 87 This directive is custom to GopherJS. This directive can be added to a 88 function declaration in the native file overrides as part of the build step. 89 90 This will keep the original function by the same name as the function 91 in the overrides, however it will prepend `_gopherjs_original_` to the original 92 function's name. This allows the original function to be called by functions 93 in the overrides and the overridden function to be called instead of the 94 original. This is useful when wanting to augment the original behavior without 95 having to rewrite the entire original function. Usage: 96 97 ```go 98 //gopherjs:keep-original 99 func foo(a, b int) int { 100 return _gopherjs_original_foo(a+1, b+1) - 1 101 } 102 ``` 103 104 ## `gopherjs:purge` 105 106 This directive is custom to GopherJS. This directive can be added 107 to most declarations and specification in the native file overrides as 108 part of the build step. 109 This can be added to structures, interfaces, methods, functions, 110 variables, or constants, but are not supported for imports, structure fields, 111 nor interface function signatures. 112 113 This will remove the original structure, interface, etc from both the override 114 files and the original files. 115 If this is added to a structure, then all functions in the original files 116 that use that structure as a receiver will also be removed. 117 This is useful for removing all the code that is invalid in GopherJS, 118 such as code using unsupported features (e.g. generic interfaces before 119 generics were fully supported). In many cases the overrides to replace 120 the original code may not have use of all the original functions and 121 variables or the original code is not intended to be replaced yet. 122 Usage: 123 124 ```go 125 //gopherjs:purge 126 var data string 127 128 //gopherjs:purge 129 // This will also purge any function starting with `dataType` as the receiver. 130 type dataType struct {} 131 132 //gopherjs:purge 133 type interfaceType interface{} 134 135 //gopherjs:purge 136 func doThing[T ~string](value T) 137 ``` 138 139 ## `gopherjs:override-signature` 140 141 This directive is custom to GopherJS. This directive can be added to a 142 function declaration in the native file overrides as part of the build step. 143 144 This will remove the function from the overrides but record the signature 145 used in the overrides, then update the original function with that signature 146 provided in the overrides. 147 The affect is to change the receiver, type parameters, 148 parameters, or return types of the original function. The original function 149 and override function must have the same function key name so that they can 150 be associated, meaning the identifier of the receiver, if there is one, must 151 match and the identifier of the function must match. 152 153 This allows the signature to be modified without modifying the body of a 154 function thus allowing the types to be adjusted to work in GopherJS. 155 The signature may need to be replaced because it uses a parameter type 156 that is invalid in GopherJS or the signature uses unsupported features 157 (e.g. generic interfaces before generics were fully supported). 158 Usage: 159 160 ```go 161 // -- in original file -- 162 func Foo[T comparable](a, b T) (T, bool) { 163 if a == b { 164 return a, true 165 } 166 return b, false 167 } 168 169 // -- in override file -- 170 //gopherjs:override-signature 171 func Foo(a, b any) (any, bool) 172 173 // -- result in augmented original -- 174 func Foo(a, b any) (any, bool) { 175 if a == b { 176 return a, true 177 } 178 return b, false 179 } 180 ``` 181 182 ```go 183 // -- in original file -- 184 func (f *Foo[A, B, C]) Bar(a int, b *A) (*A, error) { 185 //... 186 } 187 188 // -- in override file -- 189 //gopherjs:override-signature 190 func (f *Foo) Bar(a int, b jsTypeA) (jsTypeA, error) 191 192 // -- result in augmented original -- 193 func (f *Foo) Bar(a int, b jsTypeA) (jsTypeA, error) { 194 //... 195 } 196 ```