1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
* Copyright 2019 The Starlark in Rust Authors.
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//! A proc-macro for writing functions in Rust that can be called from Starlark.
// proc_macro is very special
extern crate proc_macro;
use TokenStream;
use *;
/// Write Starlark modules concisely in Rust syntax.
///
/// For example:
///
/// ```ignore
/// #[starlark_module]
/// fn global(registry: &mut GlobalsBuilder) {
/// fn cc_binary(name: &str, srcs: Vec<&str>) -> String {
/// Ok(format!("{:?} {:?}", name, srcs))
/// }
/// }
/// ```
///
/// Parameters operate as named parameters of a given type, with six possible tweaks:
///
/// * `this` (or `_this`) as the first argument means the argument is passed as a
/// bound method value, e.g. in `a.f(...)` the `a` would be `this`.
/// * `args` means the argument is the `*args`.
/// * `kwargs` means the argument is the `**kwargs`.
/// * `ref name` means the argument must be passed by position, not by name.
/// * A type of `Option` means the argument is optional.
/// * A pattern `x @ foo : bool` means the argument defaults to `foo` if not
/// specified.
///
/// During execution there are two local variables injected into scope:
///
/// * `eval` is the `Evaluator`.
/// * `heap` is the `Heap`, obtained from `eval.heap()`.
///
/// A function with the `#[starlark_module]` attribute can be added to a `GlobalsBuilder` value
/// using the `with` function. Those `Globals` can be passed to `Evaluator` to provide global functions.
/// Alternatively, you can return `Globals` from `get_methods` to _attach_ functions to
/// a specific type (e.g. the `string` type).
///
/// * When unattached, you can define constants with `const`. We define `True`, `False` and
/// `None` that way.
/// * When attached, you can annotate the functions with `#[starlark(attribute)]` to turn the name into
/// an attribute on the value. Such a function must take exactly one argument, namely a value
/// of the type you have attached it to.
/// * The attribute `#[starlark(type("test"))]` causes `f.type` to return `"test"`.
/// * If a member is annotated with `#[starlark(speculative_exec_safe)]`, then a function
/// is considered safe to execute speculatively: the function should have
/// no global side effects, should not panic, and should finish in reasonable time.
/// The evaluator may invoke such functions early to generate more efficient code.
///
/// All these functions interoperate properly with `dir()`, `getattr()` and `hasattr()`.
///
/// If a desired function name is also a Rust keyword, use the `r#` prefix, e.g. `r#type`.
/// Stubs for Starlark bytecode interpreter.
/// Derive the `Trace` trait.
/// Derive the `Freeze` trait.
/// Derive accessor methods that are designed to be used from {has,get,dir}_attr
/// in an `impl StarlarkValue` block. All fields in the struct that are not
/// marked with #[starlark(skip)] are exported to Starlark code as attributes.
/// NOTE: Any usage must also call `starlark_attrs!()` in the impl block for
/// `StarlarkValue`, otherwise the generated attr methods will not be used.
/// Generate `{has,get,dir}_attr` in the `StarlarkValue` impl block that proxy
/// to the ones generated by `derive(StarlarkAttrs)`