UNPKG

5.04 kBJavaScriptView Raw
1// Generated by LiveScript 1.6.0
2(function(){
3 var identifierRegex, tokenRegex;
4 identifierRegex = /[\$\w]+/;
5 function peek(tokens){
6 var token;
7 token = tokens[0];
8 if (token == null) {
9 throw new Error('Unexpected end of input.');
10 }
11 return token;
12 }
13 function consumeIdent(tokens){
14 var token;
15 token = peek(tokens);
16 if (!identifierRegex.test(token)) {
17 throw new Error("Expected text, got '" + token + "' instead.");
18 }
19 return tokens.shift();
20 }
21 function consumeOp(tokens, op){
22 var token;
23 token = peek(tokens);
24 if (token !== op) {
25 throw new Error("Expected '" + op + "', got '" + token + "' instead.");
26 }
27 return tokens.shift();
28 }
29 function maybeConsumeOp(tokens, op){
30 var token;
31 token = tokens[0];
32 if (token === op) {
33 return tokens.shift();
34 } else {
35 return null;
36 }
37 }
38 function consumeArray(tokens){
39 var types;
40 consumeOp(tokens, '[');
41 if (peek(tokens) === ']') {
42 throw new Error("Must specify type of Array - eg. [Type], got [] instead.");
43 }
44 types = consumeTypes(tokens);
45 consumeOp(tokens, ']');
46 return {
47 structure: 'array',
48 of: types
49 };
50 }
51 function consumeTuple(tokens){
52 var components;
53 components = [];
54 consumeOp(tokens, '(');
55 if (peek(tokens) === ')') {
56 throw new Error("Tuple must be of at least length 1 - eg. (Type), got () instead.");
57 }
58 for (;;) {
59 components.push(consumeTypes(tokens));
60 maybeConsumeOp(tokens, ',');
61 if (')' === peek(tokens)) {
62 break;
63 }
64 }
65 consumeOp(tokens, ')');
66 return {
67 structure: 'tuple',
68 of: components
69 };
70 }
71 function consumeFields(tokens){
72 var fields, subset, ref$, key, types;
73 fields = {};
74 consumeOp(tokens, '{');
75 subset = false;
76 for (;;) {
77 if (maybeConsumeOp(tokens, '...')) {
78 subset = true;
79 break;
80 }
81 ref$ = consumeField(tokens), key = ref$[0], types = ref$[1];
82 fields[key] = types;
83 maybeConsumeOp(tokens, ',');
84 if ('}' === peek(tokens)) {
85 break;
86 }
87 }
88 consumeOp(tokens, '}');
89 return {
90 structure: 'fields',
91 of: fields,
92 subset: subset
93 };
94 }
95 function consumeField(tokens){
96 var key, types;
97 key = consumeIdent(tokens);
98 consumeOp(tokens, ':');
99 types = consumeTypes(tokens);
100 return [key, types];
101 }
102 function maybeConsumeStructure(tokens){
103 switch (tokens[0]) {
104 case '[':
105 return consumeArray(tokens);
106 case '(':
107 return consumeTuple(tokens);
108 case '{':
109 return consumeFields(tokens);
110 }
111 }
112 function consumeType(tokens){
113 var token, wildcard, type, structure;
114 token = peek(tokens);
115 wildcard = token === '*';
116 if (wildcard || identifierRegex.test(token)) {
117 type = wildcard
118 ? consumeOp(tokens, '*')
119 : consumeIdent(tokens);
120 structure = maybeConsumeStructure(tokens);
121 if (structure) {
122 return structure.type = type, structure;
123 } else {
124 return {
125 type: type
126 };
127 }
128 } else {
129 structure = maybeConsumeStructure(tokens);
130 if (!structure) {
131 throw new Error("Unexpected character: " + token);
132 }
133 return structure;
134 }
135 }
136 function consumeTypes(tokens){
137 var lookahead, types, typesSoFar, typeObj, type, structure;
138 if ('::' === peek(tokens)) {
139 throw new Error("No comment before comment separator '::' found.");
140 }
141 lookahead = tokens[1];
142 if (lookahead != null && lookahead === '::') {
143 tokens.shift();
144 tokens.shift();
145 }
146 types = [];
147 typesSoFar = {};
148 if ('Maybe' === peek(tokens)) {
149 tokens.shift();
150 types = [
151 {
152 type: 'Undefined'
153 }, {
154 type: 'Null'
155 }
156 ];
157 typesSoFar = {
158 Undefined: true,
159 Null: true
160 };
161 }
162 for (;;) {
163 typeObj = consumeType(tokens), type = typeObj.type, structure = typeObj.structure;
164 if (!typesSoFar[type]) {
165 types.push(typeObj);
166 }
167 if (structure == null) {
168 typesSoFar[type] = true;
169 }
170 if (!maybeConsumeOp(tokens, '|')) {
171 break;
172 }
173 }
174 return types;
175 }
176 tokenRegex = RegExp('\\.\\.\\.|::|->|' + identifierRegex.source + '|\\S', 'g');
177 module.exports = function(input){
178 var tokens, e;
179 if (!input.length) {
180 throw new Error('No type specified.');
181 }
182 tokens = input.match(tokenRegex) || [];
183 if (in$('->', tokens)) {
184 throw new Error("Function types are not supported.\ To validate that something is a function, you may use 'Function'.");
185 }
186 try {
187 return consumeTypes(tokens);
188 } catch (e$) {
189 e = e$;
190 throw new Error(e.message + " - Remaining tokens: " + JSON.stringify(tokens) + " - Initial input: '" + input + "'");
191 }
192 };
193 function in$(x, xs){
194 var i = -1, l = xs.length >>> 0;
195 while (++i < l) if (x === xs[i]) return true;
196 return false;
197 }
198}).call(this);