Skip to content

Commit b98d5f8

Browse files
committed
structured annotations #10: docs and namespace
1 parent 804e670 commit b98d5f8

2 files changed

Lines changed: 138 additions & 2 deletions

File tree

compiler/test/fixtures/gen-hs2/HsTest/Types.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,11 @@ import qualified Data.Text as Text
5353
import qualified Data.Text.Encoding as Text
5454
import qualified Data.Vector as Vector
5555
import qualified Data.Vector.Storable as VectorStorable
56+
import qualified Facebook.Thrift.Annotation.Haskell.Haskell.Types
57+
as Facebook.Thrift.Annotation.Haskell.Haskell
5658
import qualified Facebook.Thrift.Annotation.Thrift.Thrift.Types
5759
as Facebook.Thrift.Annotation.Thrift.Thrift
5860
import qualified GHC.Magic as GHC
59-
import qualified Haskell.Types as Haskell
6061
import qualified Prelude as Prelude
6162
import qualified Thrift.Binary.Parser as Parser
6263
import qualified Thrift.CodegenTypesOnly as Thrift
@@ -75,7 +76,7 @@ import qualified Data.Vector as Vector
7576
import qualified Data.Vector.Storable as VectorStorable
7677
{-# LINE 7 "if/hs_test_instances.hs" #-}
7778
import Prelude ((/=), ($))
78-
{-# LINE 79 "test/fixtures/gen-hs2/HsTest/Types.hs" #-}
79+
{-# LINE 80 "test/fixtures/gen-hs2/HsTest/Types.hs" #-}
7980

8081
newtype X = X{unX :: Int.Int64}
8182
deriving (Prelude.Eq, Prelude.Show, DeepSeq.NFData, Prelude.Ord)

thrift/annotation/haskell.thrift

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,38 +19,173 @@ include "thrift/annotation/thrift.thrift"
1919

2020
package "facebook.com/thrift/annotation/haskell"
2121

22+
namespace hs Facebook.Thrift.Annotation.Haskell
23+
24+
/**
25+
* Overrides the Haskell type used for a typedef, field, or function parameter.
26+
*
27+
* The `name` field specifies the target Haskell type. Supported values:
28+
*
29+
* * `"Int"` — use `Int` instead of `Int64` for `i64`
30+
* * `"String"` — use `String` instead of `Text` for `string`
31+
* * `"ByteString"` — use `ByteString` instead of `Text` for `string`
32+
* * `"HashMap"` — use `HashMap` instead of `Map` for `map`
33+
* * `"HashSet"` — use `HashSet` instead of `Set` for `set`
34+
* * `"Vector"` — use `Vector` instead of `[]` for `list`
35+
* * `"VectorStorable"` — use `Storable Vector` instead of `[]` for `list`
36+
*
37+
* For example:
38+
*
39+
* @haskell.Type{name = "HashMap"}
40+
* typedef map<string, string> MyMap;
41+
*/
2242
@scope.Typedef
2343
@scope.Field
2444
@scope.FunctionParameter
2545
struct Type {
2646
1: string name;
2747
}
2848

49+
/**
50+
* Makes struct fields lazy (non-strict). Can be applied to an entire struct
51+
* to set the default laziness for all fields, or to individual fields.
52+
* Field-level annotations override struct-level ones.
53+
*
54+
* For example:
55+
*
56+
* @haskell.Lazy
57+
* struct Foo {
58+
* @haskell.Strict
59+
* 1: i32 strictField; // strict despite struct-level @Lazy
60+
* 2: i32 lazyField; // lazy from struct-level @Lazy
61+
* }
62+
*/
2963
@scope.Struct
3064
@scope.Field
3165
struct Lazy {}
3266

67+
/**
68+
* Makes struct fields strict (eagerly evaluated). Can be applied to an
69+
* entire struct to set the default strictness for all fields, or to
70+
* individual fields. Field-level annotations override struct-level ones.
71+
*
72+
* For example:
73+
*
74+
* struct Foo {
75+
* @haskell.Strict
76+
* 1: i32 strictField;
77+
* 2: i32 defaultField;
78+
* }
79+
*/
3380
@scope.Struct
3481
@scope.Field
3582
struct Strict {}
3683

84+
/**
85+
* Excludes a field from the generated Haskell record. The field will not
86+
* appear in the generated data type or serialization code.
87+
*
88+
* For example:
89+
*
90+
* struct Foo {
91+
* @haskell.Hidden
92+
* 1: i64 internalField;
93+
* 2: i32 visibleField;
94+
* }
95+
*/
3796
@scope.Field
3897
struct Hidden {}
3998

99+
/**
100+
* Generates a Haskell `newtype` wrapper instead of a `type` alias for a
101+
* typedef. This creates a distinct type that is not automatically
102+
* interchangeable with its underlying type.
103+
*
104+
* For example:
105+
*
106+
* @haskell.Newtype
107+
* typedef i64 UserId;
108+
*
109+
* Generates `newtype UserId = UserId Int64` instead of `type UserId = Int64`.
110+
*/
40111
@scope.Typedef
41112
struct Newtype {}
42113

114+
/**
115+
* Indicates that a union type has no empty variant. By default, unions
116+
* generate an empty constructor (for the case where no field is set).
117+
* This annotation removes it, making the union non-empty.
118+
*
119+
* For example:
120+
*
121+
* @haskell.NonEmpty
122+
* union Result {
123+
* 1: string success;
124+
* 2: string error;
125+
* }
126+
*/
43127
@scope.Union
44128
struct NonEmpty {}
45129

130+
/**
131+
* Generates an enum without an unknown/catch-all variant. By default,
132+
* enums include a catch-all constructor for unrecognised values. This
133+
* annotation removes it, treating the enum as a closed sum type.
134+
*
135+
* For example:
136+
*
137+
* @haskell.NoUnknown
138+
* enum Color {
139+
* RED = 1,
140+
* GREEN = 2,
141+
* BLUE = 3,
142+
* }
143+
*/
46144
@scope.Enum
47145
struct NoUnknown {}
48146

147+
/**
148+
* Generates an enum as a newtype wrapper around an integer instead of a
149+
* Haskell sum type. This can be more efficient for enums with many
150+
* alternatives.
151+
*
152+
* The optional `value` field controls the representation:
153+
* * omitted — uses a plain integer newtype
154+
* * `"thriftenum"` — uses a Thrift-compatible enum encoding
155+
*
156+
* For example:
157+
*
158+
* @haskell.PseudoEnum
159+
* enum Status {
160+
* ACTIVE = 1,
161+
* INACTIVE = 2,
162+
* }
163+
*
164+
* @haskell.PseudoEnum{value = "thriftenum"}
165+
* enum Priority {
166+
* LOW = 1,
167+
* HIGH = 2,
168+
* }
169+
*/
49170
@scope.Enum
50171
struct PseudoEnum {
51172
1: string value;
52173
}
53174

175+
/**
176+
* Overrides the default prefix used for generated field names, enum
177+
* alternatives, union alternatives, or function names. By default, the
178+
* Thrift compiler generates prefixes based on the parent type name to
179+
* avoid name collisions.
180+
*
181+
* For example:
182+
*
183+
* @haskell.Prefix{name = "ps_"}
184+
* struct PrefixedStruct {
185+
* 1: i64 foo; // generates ps_foo
186+
* 2: i32 bar; // generates ps_bar
187+
* }
188+
*/
54189
@scope.Struct
55190
@scope.Union
56191
@scope.Enum

0 commit comments

Comments
 (0)