| 417 | } |
| 418 | |
| 419 | function passTwo(base, spec, path) { |
| 420 | if (base.isShell) { |
| 421 | delete base.isShell; |
| 422 | var tp = spec["!type"]; |
| 423 | if (tp) { |
| 424 | parseType(tp, path, base); |
| 425 | } else { |
| 426 | var proto = spec["!proto"] && parseType(spec["!proto"]); |
| 427 | infer.Obj.call(base, proto instanceof infer.Obj ? proto : true, path); |
| 428 | } |
| 429 | } |
| 430 | |
| 431 | var effects = spec["!effects"]; |
| 432 | if (effects && base instanceof infer.Fn) for (var i = 0; i < effects.length; ++i) |
| 433 | parseEffect(effects[i], base); |
| 434 | copyInfo(spec, base); |
| 435 | |
| 436 | for (var name in spec) if (hop(spec, name) && name.charCodeAt(0) != 33) { |
| 437 | var inner = spec[name], known = base.defProp(name), innerPath = path ? path + "." + name : name; |
| 438 | if (typeof inner == "string") { |
| 439 | if (known.isEmpty()) parseType(inner, innerPath).propagate(known); |
| 440 | } else { |
| 441 | if (!isSimpleAnnotation(inner)) |
| 442 | passTwo(known.getObjType(), inner, innerPath); |
| 443 | else if (known.isEmpty()) |
| 444 | parseType(inner["!type"], innerPath, null, true).propagate(known); |
| 445 | else |
| 446 | continue; |
| 447 | if (inner["!doc"]) known.doc = inner["!doc"]; |
| 448 | if (inner["!url"]) known.url = inner["!url"]; |
| 449 | if (inner["!span"]) known.span = inner["!span"]; |
| 450 | } |
| 451 | } |
| 452 | return base; |
| 453 | } |
| 454 | |
| 455 | function copyInfo(spec, type) { |
| 456 | if (spec["!doc"]) type.doc = spec["!doc"]; |