Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for indexers and "callable" objects #132

Merged
merged 10 commits into from
Feb 1, 2021

Conversation

cannorin
Copy link
Contributor

@cannorin cannorin commented Jan 30, 2021

This PR adds three attributes for value binding: [@@js.index_get], [@@js.index_set], and [@@js.apply].

Indexers

[@@js.index_get] and [@@js.index_set] can be used to bind to indexer in a JS object. For example, the binding for getter and setter of JS Buffer can now be written as

val get: t -> int -> int option [@@js.index_get]
val set: t -> int -> int -> unit [@@js.index_set]

instead of

val get: t -> int -> int option[@@js.custom
  let get buf index = [%js.to:int option](Ojs.array_get buf index)
    ]
val set: t -> int -> int -> unit[@@js.custom
  let set buf index value =
    Ojs.array_set buf index ([%js.of:int] value)
  ]

Function Objects

Sometimes a JS object can also be a function (so-called "callable object").

var foo = function() { .. }
foo.bar = 42

We can now bind this kind of object with the following:

module Foo : sig
  type t = private Ojs.t

  val foo: t -> int [@@js.get "foo"]
  val apply: t -> unit -> unit [@@js.apply]
end

Compatibility with TypeScript

This complements gen_js_api's ability to bind to TypeScript interfaces. With this PR merged, we now support Function Types and Indexable Types (which were very hard to bind).

interface MapLike<T> {
    [index: string]: T
}
interface SearchFunc {
    (source: string, subString: string): boolean;
}
module MapLike : sig
  type 'a t = private Ojs.t
  val get: 'a t -> string -> 'a option [@@js.index_get]
  val set: 'a t -> string -> 'a -> unit [@@js.index_set]
end
module SearchFunc : sig
  type t = private Ojs.t
  val apply: t -> string -> string -> bool [@@js.apply]
end

lib/ojs.mli Outdated Show resolved Hide resolved
VALUES.md Outdated Show resolved Hide resolved
mkfun
(fun this ->
match ty_args, ty_vararg, unit_arg with
| [], None, false -> js2ml_unit [] ty_res (res this)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know you were not responsible for that; but this pattern matching was not making a lot of sense:
ty_vars, ty_avarg = [], None implies formal_args = [] implies func formal_args false x = x

@mlasson mlasson force-pushed the index-and-function-signature-binding branch from 0ac7508 to e6154ee Compare February 1, 2021 17:11
@mlasson
Copy link
Member

mlasson commented Feb 1, 2021

Nice PR thanks !

@mlasson mlasson merged commit fe46e29 into LexiFi:master Feb 1, 2021
@cannorin cannorin deleted the index-and-function-signature-binding branch February 2, 2021 10:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants