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  ```