| 1010 | } |
| 1011 | |
| 1012 | function maybeTagAsGeneric(fn) { |
| 1013 | var target = fn.retval; |
| 1014 | if (target == ANull || fn.isArrowFn()) return; |
| 1015 | var targetInner, asArray; |
| 1016 | if (!target.isEmpty() && (targetInner = target.getType()) instanceof Arr) |
| 1017 | target = asArray = targetInner.getProp("<i>"); |
| 1018 | |
| 1019 | function explore(aval, path, depth) { |
| 1020 | if (depth > 3 || !aval.forward) return; |
| 1021 | for (var i = 0; i < aval.forward.length; ++i) { |
| 1022 | var prop = aval.forward[i].propagatesTo(); |
| 1023 | if (!prop) continue; |
| 1024 | var newPath = path, dest; |
| 1025 | if (prop instanceof AVal) { |
| 1026 | dest = prop; |
| 1027 | } else if (prop.target instanceof AVal) { |
| 1028 | newPath += prop.pathExt; |
| 1029 | dest = prop.target; |
| 1030 | } else continue; |
| 1031 | if (dest == target) return newPath; |
| 1032 | var found = explore(dest, newPath, depth + 1); |
| 1033 | if (found) return found; |
| 1034 | } |
| 1035 | } |
| 1036 | |
| 1037 | var foundPath = explore(fn.self, "!this", 0); |
| 1038 | for (var i = 0; !foundPath && i < fn.args.length; ++i) |
| 1039 | foundPath = explore(fn.args[i], "!" + i, 0); |
| 1040 | |
| 1041 | if (foundPath) { |
| 1042 | if (asArray) foundPath = "[" + foundPath + "]"; |
| 1043 | var p = new def.TypeParser(foundPath); |
| 1044 | var parsed = p.parseType(true); |
| 1045 | fn.computeRet = parsed.apply ? parsed : function() { return parsed; }; |
| 1046 | fn.computeRetSource = foundPath; |
| 1047 | return true; |
| 1048 | } |
| 1049 | } |
| 1050 | |
| 1051 | // SCOPE GATHERING PASS |
| 1052 | |