(scope, str, pos)
| 266 | } |
| 267 | |
| 268 | function parseTypeInner(scope, str, pos) { |
| 269 | pos = skipSpace(str, pos); |
| 270 | if (/[?!]/.test(str.charAt(pos))) pos++; |
| 271 | var type, madeUp = false; |
| 272 | |
| 273 | if (str.indexOf("function(", pos) == pos) { |
| 274 | var args = parseLabelList(scope, str, pos + 9, ")"), ret = infer.ANull; |
| 275 | if (!args) return null; |
| 276 | pos = skipSpace(str, args.end); |
| 277 | if (str.charAt(pos) == ":") { |
| 278 | ++pos; |
| 279 | var retType = parseType(scope, str, pos + 1); |
| 280 | if (!retType) return null; |
| 281 | pos = retType.end; |
| 282 | ret = retType.type; |
| 283 | madeUp = retType.madeUp; |
| 284 | } |
| 285 | type = new infer.Fn(null, infer.ANull, args.types, args.labels, ret); |
| 286 | } else if (str.charAt(pos) == "[") { |
| 287 | var inner = parseType(scope, str, pos + 1); |
| 288 | if (!inner) return null; |
| 289 | pos = skipSpace(str, inner.end); |
| 290 | madeUp = inner.madeUp; |
| 291 | if (str.charAt(pos) != "]") return null; |
| 292 | ++pos; |
| 293 | type = new infer.Arr(inner.type); |
| 294 | } else if (str.charAt(pos) == "{") { |
| 295 | var fields = parseLabelList(scope, str, pos + 1, "}"); |
| 296 | if (!fields) return null; |
| 297 | type = new infer.Obj(true); |
| 298 | for (var i = 0; i < fields.types.length; ++i) { |
| 299 | var field = type.defProp(fields.labels[i]); |
| 300 | field.initializer = true; |
| 301 | fields.types[i].propagate(field); |
| 302 | } |
| 303 | pos = fields.end; |
| 304 | madeUp = fields.madeUp; |
| 305 | } else if (str.charAt(pos) == "(") { |
| 306 | var inner = parseType(scope, str, pos + 1); |
| 307 | if (!inner) return null; |
| 308 | pos = skipSpace(str, inner.end); |
| 309 | if (str.charAt(pos) != ")") return null; |
| 310 | ++pos; |
| 311 | type = inner.type; |
| 312 | } else { |
| 313 | var start = pos; |
| 314 | if (!acorn.isIdentifierStart(str.charCodeAt(pos))) return null; |
| 315 | while (acorn.isIdentifierChar(str.charCodeAt(pos))) ++pos; |
| 316 | if (start == pos) return null; |
| 317 | var word = str.slice(start, pos); |
| 318 | if (/^(number|integer)$/i.test(word)) type = infer.cx().num; |
| 319 | else if (/^bool(ean)?$/i.test(word)) type = infer.cx().bool; |
| 320 | else if (/^string$/i.test(word)) type = infer.cx().str; |
| 321 | else if (/^(null|undefined)$/i.test(word)) type = infer.ANull; |
| 322 | else if (/^array$/i.test(word)) { |
| 323 | var inner = null; |
| 324 | if (str.charAt(pos) == "." && str.charAt(pos + 1) == "<") { |
| 325 | var inAngles = parseType(scope, str, pos + 2); |
no test coverage detected
searching dependent graphs…