forked from mirrors/gecko-dev
Differential Revision: https://phabricator.services.mozilla.com/D19641 --HG-- rename : devtools/client/sourceeditor/.eslintrc.js => devtools/client/shared/sourceeditor/.eslintrc.js rename : devtools/client/sourceeditor/README => devtools/client/shared/sourceeditor/README rename : devtools/client/sourceeditor/autocomplete.js => devtools/client/shared/sourceeditor/autocomplete.js rename : devtools/client/sourceeditor/codemirror/LICENSE => devtools/client/shared/sourceeditor/codemirror/LICENSE rename : devtools/client/sourceeditor/codemirror/addon/comment/comment.js => devtools/client/shared/sourceeditor/codemirror/addon/comment/comment.js rename : devtools/client/sourceeditor/codemirror/addon/comment/continuecomment.js => devtools/client/shared/sourceeditor/codemirror/addon/comment/continuecomment.js rename : devtools/client/sourceeditor/codemirror/addon/dialog/dialog.css => devtools/client/shared/sourceeditor/codemirror/addon/dialog/dialog.css rename : devtools/client/sourceeditor/codemirror/addon/dialog/dialog.js => devtools/client/shared/sourceeditor/codemirror/addon/dialog/dialog.js rename : devtools/client/sourceeditor/codemirror/addon/edit/closebrackets.js => devtools/client/shared/sourceeditor/codemirror/addon/edit/closebrackets.js rename : devtools/client/sourceeditor/codemirror/addon/edit/closetag.js => devtools/client/shared/sourceeditor/codemirror/addon/edit/closetag.js rename : devtools/client/sourceeditor/codemirror/addon/edit/continuelist.js => devtools/client/shared/sourceeditor/codemirror/addon/edit/continuelist.js rename : devtools/client/sourceeditor/codemirror/addon/edit/matchbrackets.js => devtools/client/shared/sourceeditor/codemirror/addon/edit/matchbrackets.js rename : devtools/client/sourceeditor/codemirror/addon/edit/matchtags.js => devtools/client/shared/sourceeditor/codemirror/addon/edit/matchtags.js rename : devtools/client/sourceeditor/codemirror/addon/edit/trailingspace.js => devtools/client/shared/sourceeditor/codemirror/addon/edit/trailingspace.js rename : devtools/client/sourceeditor/codemirror/addon/fold/brace-fold.js => devtools/client/shared/sourceeditor/codemirror/addon/fold/brace-fold.js rename : devtools/client/sourceeditor/codemirror/addon/fold/comment-fold.js => devtools/client/shared/sourceeditor/codemirror/addon/fold/comment-fold.js rename : devtools/client/sourceeditor/codemirror/addon/fold/foldcode.js => devtools/client/shared/sourceeditor/codemirror/addon/fold/foldcode.js rename : devtools/client/sourceeditor/codemirror/addon/fold/foldgutter.css => devtools/client/shared/sourceeditor/codemirror/addon/fold/foldgutter.css rename : devtools/client/sourceeditor/codemirror/addon/fold/foldgutter.js => devtools/client/shared/sourceeditor/codemirror/addon/fold/foldgutter.js rename : devtools/client/sourceeditor/codemirror/addon/fold/indent-fold.js => devtools/client/shared/sourceeditor/codemirror/addon/fold/indent-fold.js rename : devtools/client/sourceeditor/codemirror/addon/fold/markdown-fold.js => devtools/client/shared/sourceeditor/codemirror/addon/fold/markdown-fold.js rename : devtools/client/sourceeditor/codemirror/addon/fold/xml-fold.js => devtools/client/shared/sourceeditor/codemirror/addon/fold/xml-fold.js rename : devtools/client/sourceeditor/codemirror/addon/hint/show-hint.js => devtools/client/shared/sourceeditor/codemirror/addon/hint/show-hint.js rename : devtools/client/sourceeditor/codemirror/addon/runmode/runmode.js => devtools/client/shared/sourceeditor/codemirror/addon/runmode/runmode.js rename : devtools/client/sourceeditor/codemirror/addon/search/match-highlighter.js => devtools/client/shared/sourceeditor/codemirror/addon/search/match-highlighter.js rename : devtools/client/sourceeditor/codemirror/addon/search/search.js => devtools/client/shared/sourceeditor/codemirror/addon/search/search.js rename : devtools/client/sourceeditor/codemirror/addon/search/searchcursor.js => devtools/client/shared/sourceeditor/codemirror/addon/search/searchcursor.js rename : devtools/client/sourceeditor/codemirror/addon/selection/active-line.js => devtools/client/shared/sourceeditor/codemirror/addon/selection/active-line.js rename : devtools/client/sourceeditor/codemirror/addon/selection/mark-selection.js => devtools/client/shared/sourceeditor/codemirror/addon/selection/mark-selection.js rename : devtools/client/sourceeditor/codemirror/addon/tern/tern.css => devtools/client/shared/sourceeditor/codemirror/addon/tern/tern.css rename : devtools/client/sourceeditor/codemirror/addon/tern/tern.js => devtools/client/shared/sourceeditor/codemirror/addon/tern/tern.js rename : devtools/client/sourceeditor/codemirror/cmiframe.html => devtools/client/shared/sourceeditor/codemirror/cmiframe.html rename : devtools/client/sourceeditor/codemirror/codemirror.bundle.js => devtools/client/shared/sourceeditor/codemirror/codemirror.bundle.js rename : devtools/client/sourceeditor/codemirror/keymap/emacs.js => devtools/client/shared/sourceeditor/codemirror/keymap/emacs.js rename : devtools/client/sourceeditor/codemirror/keymap/sublime.js => devtools/client/shared/sourceeditor/codemirror/keymap/sublime.js rename : devtools/client/sourceeditor/codemirror/keymap/vim.js => devtools/client/shared/sourceeditor/codemirror/keymap/vim.js rename : devtools/client/sourceeditor/codemirror/lib/codemirror.css => devtools/client/shared/sourceeditor/codemirror/lib/codemirror.css rename : devtools/client/sourceeditor/codemirror/lib/codemirror.js => devtools/client/shared/sourceeditor/codemirror/lib/codemirror.js rename : devtools/client/sourceeditor/codemirror/mode/clike/clike.js => devtools/client/shared/sourceeditor/codemirror/mode/clike/clike.js rename : devtools/client/sourceeditor/codemirror/mode/clojure/clojure.js => devtools/client/shared/sourceeditor/codemirror/mode/clojure/clojure.js rename : devtools/client/sourceeditor/codemirror/mode/coffeescript/coffeescript.js => devtools/client/shared/sourceeditor/codemirror/mode/coffeescript/coffeescript.js rename : devtools/client/sourceeditor/codemirror/mode/css/css.js => devtools/client/shared/sourceeditor/codemirror/mode/css/css.js rename : devtools/client/sourceeditor/codemirror/mode/elm/elm.js => devtools/client/shared/sourceeditor/codemirror/mode/elm/elm.js rename : devtools/client/sourceeditor/codemirror/mode/haxe/haxe.js => devtools/client/shared/sourceeditor/codemirror/mode/haxe/haxe.js rename : devtools/client/sourceeditor/codemirror/mode/htmlmixed/htmlmixed.js => devtools/client/shared/sourceeditor/codemirror/mode/htmlmixed/htmlmixed.js rename : devtools/client/sourceeditor/codemirror/mode/javascript/javascript.js => devtools/client/shared/sourceeditor/codemirror/mode/javascript/javascript.js rename : devtools/client/sourceeditor/codemirror/mode/jsx/jsx.js => devtools/client/shared/sourceeditor/codemirror/mode/jsx/jsx.js rename : devtools/client/sourceeditor/codemirror/mode/wasm/wasm.js => devtools/client/shared/sourceeditor/codemirror/mode/wasm/wasm.js rename : devtools/client/sourceeditor/codemirror/mode/xml/xml.js => devtools/client/shared/sourceeditor/codemirror/mode/xml/xml.js rename : devtools/client/sourceeditor/codemirror/mozilla.css => devtools/client/shared/sourceeditor/codemirror/mozilla.css rename : devtools/client/sourceeditor/css-autocompleter.js => devtools/client/shared/sourceeditor/css-autocompleter.js rename : devtools/client/sourceeditor/debugger.js => devtools/client/shared/sourceeditor/debugger.js rename : devtools/client/sourceeditor/editor-commands-controller.js => devtools/client/shared/sourceeditor/editor-commands-controller.js rename : devtools/client/sourceeditor/editor.js => devtools/client/shared/sourceeditor/editor.js rename : devtools/client/sourceeditor/moz.build => devtools/client/shared/sourceeditor/moz.build rename : devtools/client/sourceeditor/package.json => devtools/client/shared/sourceeditor/package.json rename : devtools/client/sourceeditor/tern/README => devtools/client/shared/sourceeditor/tern/README rename : devtools/client/sourceeditor/tern/browser.js => devtools/client/shared/sourceeditor/tern/browser.js rename : devtools/client/sourceeditor/tern/comment.js => devtools/client/shared/sourceeditor/tern/comment.js rename : devtools/client/sourceeditor/tern/condense.js => devtools/client/shared/sourceeditor/tern/condense.js rename : devtools/client/sourceeditor/tern/def.js => devtools/client/shared/sourceeditor/tern/def.js rename : devtools/client/sourceeditor/tern/ecma5.js => devtools/client/shared/sourceeditor/tern/ecma5.js rename : devtools/client/sourceeditor/tern/infer.js => devtools/client/shared/sourceeditor/tern/infer.js rename : devtools/client/sourceeditor/tern/moz.build => devtools/client/shared/sourceeditor/tern/moz.build rename : devtools/client/sourceeditor/tern/signal.js => devtools/client/shared/sourceeditor/tern/signal.js rename : devtools/client/sourceeditor/tern/tern.js => devtools/client/shared/sourceeditor/tern/tern.js rename : devtools/client/sourceeditor/tern/tests/unit/head_tern.js => devtools/client/shared/sourceeditor/tern/tests/unit/head_tern.js rename : devtools/client/sourceeditor/tern/tests/unit/test_autocompletion.js => devtools/client/shared/sourceeditor/tern/tests/unit/test_autocompletion.js rename : devtools/client/sourceeditor/tern/tests/unit/test_import_tern.js => devtools/client/shared/sourceeditor/tern/tests/unit/test_import_tern.js rename : devtools/client/sourceeditor/tern/tests/unit/xpcshell.ini => devtools/client/shared/sourceeditor/tern/tests/unit/xpcshell.ini rename : devtools/client/sourceeditor/test/.eslintrc.js => devtools/client/shared/sourceeditor/test/.eslintrc.js rename : devtools/client/sourceeditor/test/browser.ini => devtools/client/shared/sourceeditor/test/browser.ini rename : devtools/client/sourceeditor/test/browser_codemirror.js => devtools/client/shared/sourceeditor/test/browser_codemirror.js rename : devtools/client/sourceeditor/test/browser_css_autocompletion.js => devtools/client/shared/sourceeditor/test/browser_css_autocompletion.js rename : devtools/client/sourceeditor/test/browser_css_getInfo.js => devtools/client/shared/sourceeditor/test/browser_css_getInfo.js rename : devtools/client/sourceeditor/test/browser_css_statemachine.js => devtools/client/shared/sourceeditor/test/browser_css_statemachine.js rename : devtools/client/sourceeditor/test/browser_detectindent.js => devtools/client/shared/sourceeditor/test/browser_detectindent.js rename : devtools/client/sourceeditor/test/browser_editor_addons.js => devtools/client/shared/sourceeditor/test/browser_editor_addons.js rename : devtools/client/sourceeditor/test/browser_editor_alt_b_f.js => devtools/client/shared/sourceeditor/test/browser_editor_alt_b_f.js rename : devtools/client/sourceeditor/test/browser_editor_autocomplete_basic.js => devtools/client/shared/sourceeditor/test/browser_editor_autocomplete_basic.js rename : devtools/client/sourceeditor/test/browser_editor_autocomplete_events.js => devtools/client/shared/sourceeditor/test/browser_editor_autocomplete_events.js rename : devtools/client/sourceeditor/test/browser_editor_autocomplete_js.js => devtools/client/shared/sourceeditor/test/browser_editor_autocomplete_js.js rename : devtools/client/sourceeditor/test/browser_editor_basic.js => devtools/client/shared/sourceeditor/test/browser_editor_basic.js rename : devtools/client/sourceeditor/test/browser_editor_cursor.js => devtools/client/shared/sourceeditor/test/browser_editor_cursor.js rename : devtools/client/sourceeditor/test/browser_editor_find_again.js => devtools/client/shared/sourceeditor/test/browser_editor_find_again.js rename : devtools/client/sourceeditor/test/browser_editor_goto_line.js => devtools/client/shared/sourceeditor/test/browser_editor_goto_line.js rename : devtools/client/sourceeditor/test/browser_editor_history.js => devtools/client/shared/sourceeditor/test/browser_editor_history.js rename : devtools/client/sourceeditor/test/browser_editor_markers.js => devtools/client/shared/sourceeditor/test/browser_editor_markers.js rename : devtools/client/sourceeditor/test/browser_editor_movelines.js => devtools/client/shared/sourceeditor/test/browser_editor_movelines.js rename : devtools/client/sourceeditor/test/browser_editor_prefs.js => devtools/client/shared/sourceeditor/test/browser_editor_prefs.js rename : devtools/client/sourceeditor/test/browser_editor_script_injection.js => devtools/client/shared/sourceeditor/test/browser_editor_script_injection.js rename : devtools/client/sourceeditor/test/browser_vimemacs.js => devtools/client/shared/sourceeditor/test/browser_vimemacs.js rename : devtools/client/sourceeditor/test/cm_mode_ruby.js => devtools/client/shared/sourceeditor/test/cm_mode_ruby.js rename : devtools/client/sourceeditor/test/cm_script_injection_test.js => devtools/client/shared/sourceeditor/test/cm_script_injection_test.js rename : devtools/client/sourceeditor/test/codemirror/codemirror.html => devtools/client/shared/sourceeditor/test/codemirror/codemirror.html rename : devtools/client/sourceeditor/test/codemirror/comment_test.js => devtools/client/shared/sourceeditor/test/codemirror/comment_test.js rename : devtools/client/sourceeditor/test/codemirror/doc_test.js => devtools/client/shared/sourceeditor/test/codemirror/doc_test.js rename : devtools/client/sourceeditor/test/codemirror/driver.js => devtools/client/shared/sourceeditor/test/codemirror/driver.js rename : devtools/client/sourceeditor/test/codemirror/emacs_test.js => devtools/client/shared/sourceeditor/test/codemirror/emacs_test.js rename : devtools/client/sourceeditor/test/codemirror/mode/javascript/test.js => devtools/client/shared/sourceeditor/test/codemirror/mode/javascript/test.js rename : devtools/client/sourceeditor/test/codemirror/mode_test.css => devtools/client/shared/sourceeditor/test/codemirror/mode_test.css rename : devtools/client/sourceeditor/test/codemirror/mode_test.js => devtools/client/shared/sourceeditor/test/codemirror/mode_test.js rename : devtools/client/sourceeditor/test/codemirror/multi_test.js => devtools/client/shared/sourceeditor/test/codemirror/multi_test.js rename : devtools/client/sourceeditor/test/codemirror/search_test.js => devtools/client/shared/sourceeditor/test/codemirror/search_test.js rename : devtools/client/sourceeditor/test/codemirror/sublime_test.js => devtools/client/shared/sourceeditor/test/codemirror/sublime_test.js rename : devtools/client/sourceeditor/test/codemirror/test.js => devtools/client/shared/sourceeditor/test/codemirror/test.js rename : devtools/client/sourceeditor/test/codemirror/vim_test.js => devtools/client/shared/sourceeditor/test/codemirror/vim_test.js rename : devtools/client/sourceeditor/test/codemirror/vimemacs.html => devtools/client/shared/sourceeditor/test/codemirror/vimemacs.html rename : devtools/client/sourceeditor/test/css_autocompletion_tests.json => devtools/client/shared/sourceeditor/test/css_autocompletion_tests.json rename : devtools/client/sourceeditor/test/css_statemachine_testcases.css => devtools/client/shared/sourceeditor/test/css_statemachine_testcases.css rename : devtools/client/sourceeditor/test/css_statemachine_tests.json => devtools/client/shared/sourceeditor/test/css_statemachine_tests.json rename : devtools/client/sourceeditor/test/head.js => devtools/client/shared/sourceeditor/test/head.js rename : devtools/client/sourceeditor/test/head.xul => devtools/client/shared/sourceeditor/test/head.xul rename : devtools/client/sourceeditor/test/helper_codemirror_runner.js => devtools/client/shared/sourceeditor/test/helper_codemirror_runner.js rename : devtools/client/sourceeditor/wasm.js => devtools/client/shared/sourceeditor/wasm.js rename : devtools/client/sourceeditor/webpack.config.js => devtools/client/shared/sourceeditor/webpack.config.js extra : moz-landing-system : lando
304 lines
10 KiB
JavaScript
Executable file
304 lines
10 KiB
JavaScript
Executable file
// Condensing an inferred set of types to a JSON description document.
|
|
|
|
// This code can be used to, after a library has been analyzed,
|
|
// extract the types defined in that library and dump them as a JSON
|
|
// structure (as parsed by def.js).
|
|
|
|
// The idea being that big libraries can be analyzed once, dumped, and
|
|
// then cheaply included in later analysis.
|
|
|
|
(function(root, mod) {
|
|
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
|
return mod(exports, require("./infer"));
|
|
if (typeof define == "function" && define.amd) // AMD
|
|
return define(["exports", "./infer"], mod);
|
|
mod(root.tern || (root.tern = {}), tern); // Plain browser env
|
|
})(this, function(exports, infer) {
|
|
"use strict";
|
|
|
|
exports.condense = function(origins, name, options) {
|
|
if (typeof origins == "string") origins = [origins];
|
|
var state = new State(origins, name || origins[0], options || {});
|
|
|
|
state.server.signal("preCondenseReach", state)
|
|
|
|
state.cx.topScope.path = "<top>";
|
|
state.cx.topScope.reached("", state);
|
|
for (var path in state.roots)
|
|
reach(state.roots[path], null, path, state);
|
|
for (var i = 0; i < state.patchUp.length; ++i)
|
|
patchUpSimpleInstance(state.patchUp[i], state);
|
|
|
|
state.server.signal("postCondenseReach", state)
|
|
|
|
for (var path in state.types)
|
|
store(createPath(path.split("."), state), state.types[path], state);
|
|
for (var path in state.altPaths)
|
|
storeAlt(path, state.altPaths[path], state);
|
|
var hasDef = false;
|
|
for (var _def in state.output["!define"]) { hasDef = true; break; }
|
|
if (!hasDef) delete state.output["!define"];
|
|
|
|
state.server.signal("postCondense", state)
|
|
|
|
return simplify(state.output, state.options.sortOutput);
|
|
};
|
|
|
|
function State(origins, name, options) {
|
|
this.origins = origins;
|
|
this.cx = infer.cx();
|
|
this.server = options.server || this.cx.parent || {signal: function() {}}
|
|
this.maxOrigin = -Infinity;
|
|
for (var i = 0; i < origins.length; ++i)
|
|
this.maxOrigin = Math.max(this.maxOrigin, this.cx.origins.indexOf(origins[i]));
|
|
this.output = {"!name": name, "!define": {}};
|
|
this.options = options;
|
|
this.types = Object.create(null);
|
|
this.altPaths = Object.create(null);
|
|
this.patchUp = [];
|
|
this.roots = Object.create(null);
|
|
}
|
|
|
|
State.prototype.isTarget = function(origin) {
|
|
return this.origins.indexOf(origin) > -1;
|
|
};
|
|
|
|
State.prototype.getSpan = function(node) {
|
|
if (this.options.spans == false || !this.isTarget(node.origin)) return null;
|
|
if (node.span) return node.span;
|
|
var srv = this.cx.parent, file;
|
|
if (!srv || !node.originNode || !(file = srv.findFile(node.origin))) return null;
|
|
var start = node.originNode.start, end = node.originNode.end;
|
|
var pStart = file.asLineChar(start), pEnd = file.asLineChar(end);
|
|
return start + "[" + pStart.line + ":" + pStart.ch + "]-" +
|
|
end + "[" + pEnd.line + ":" + pEnd.ch + "]";
|
|
};
|
|
|
|
function pathLen(path) {
|
|
var len = 1, pos = 0, dot;
|
|
while ((dot = path.indexOf(".", pos)) != -1) {
|
|
pos = dot + 1;
|
|
len += path.charAt(pos) == "!" ? 10 : 1;
|
|
}
|
|
return len;
|
|
}
|
|
|
|
function hop(obj, prop) {
|
|
return Object.prototype.hasOwnProperty.call(obj, prop);
|
|
}
|
|
|
|
function isSimpleInstance(o) {
|
|
return o.proto && !(o instanceof infer.Fn) && o.proto != infer.cx().protos.Object &&
|
|
o.proto.hasCtor && !o.hasCtor;
|
|
}
|
|
|
|
function reach(type, path, id, state, byName) {
|
|
var actual = type.getType(false);
|
|
if (!actual) return;
|
|
var orig = type.origin || actual.origin, relevant = false;
|
|
if (orig) {
|
|
var origPos = state.cx.origins.indexOf(orig);
|
|
// This is a path that is newer than the code we are interested in.
|
|
if (origPos > state.maxOrigin) return;
|
|
relevant = state.isTarget(orig);
|
|
}
|
|
var newPath = path ? path + "." + id : id, oldPath = actual.path;
|
|
var shorter = !oldPath || pathLen(oldPath) > pathLen(newPath);
|
|
if (shorter) {
|
|
if (!(actual instanceof infer.Prim)) actual.path = newPath;
|
|
if (actual.reached(newPath, state, !relevant) && relevant) {
|
|
var data = state.types[oldPath];
|
|
if (data) {
|
|
delete state.types[oldPath];
|
|
state.altPaths[oldPath] = actual;
|
|
} else data = {type: actual};
|
|
data.span = state.getSpan(type) || (actual != type && state.isTarget(actual.origin) && state.getSpan(actual)) || data.span;
|
|
data.doc = type.doc || (actual != type && state.isTarget(actual.origin) && actual.doc) || data.doc;
|
|
data.data = actual.metaData;
|
|
data.byName = data.byName == null ? !!byName : data.byName && byName;
|
|
state.types[newPath] = data;
|
|
}
|
|
} else {
|
|
if (relevant) state.altPaths[newPath] = actual;
|
|
}
|
|
}
|
|
function reachByName(aval, path, id, state) {
|
|
var type = aval.getType();
|
|
if (type) reach(type, path, id, state, true);
|
|
}
|
|
|
|
infer.Prim.prototype.reached = function() {return true;};
|
|
|
|
infer.Arr.prototype.reached = function(path, state, concrete) {
|
|
if (concrete) return true
|
|
if (this.tuple) {
|
|
for (var i = 0; i < this.tuple; i++)
|
|
reachByName(this.getProp(String(i)), path, String(i), state)
|
|
} else {
|
|
reachByName(this.getProp("<i>"), path, "<i>", state)
|
|
}
|
|
return true;
|
|
};
|
|
|
|
infer.Fn.prototype.reached = function(path, state, concrete) {
|
|
infer.Obj.prototype.reached.call(this, path, state, concrete);
|
|
if (!concrete) {
|
|
for (var i = 0; i < this.args.length; ++i)
|
|
reachByName(this.args[i], path, "!" + i, state);
|
|
reachByName(this.retval, path, "!ret", state);
|
|
}
|
|
return true;
|
|
};
|
|
|
|
infer.Obj.prototype.reached = function(path, state, concrete) {
|
|
if (isSimpleInstance(this) && !this.condenseForceInclude) {
|
|
if (!state.patchUp.includes(this)) state.patchUp.push(this);
|
|
return true;
|
|
} else if (this.proto && !concrete) {
|
|
reach(this.proto, path, "!proto", state);
|
|
}
|
|
var hasProps = false;
|
|
for (var prop in this.props) {
|
|
reach(this.props[prop], path, prop, state);
|
|
hasProps = true;
|
|
}
|
|
if (!hasProps && !this.condenseForceInclude && !(this instanceof infer.Fn)) {
|
|
this.nameOverride = "?";
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
|
|
function patchUpSimpleInstance(obj, state) {
|
|
var path = obj.proto.hasCtor.path;
|
|
if (path) {
|
|
obj.nameOverride = "+" + path;
|
|
} else {
|
|
path = obj.path;
|
|
}
|
|
for (var prop in obj.props)
|
|
reach(obj.props[prop], path, prop, state);
|
|
}
|
|
|
|
function createPath(parts, state) {
|
|
var base = state.output, defs = state.output["!define"];
|
|
for (var i = 0, path; i < parts.length; ++i) {
|
|
var part = parts[i];
|
|
path = path ? path + "." + part : part;
|
|
var me = state.types[path];
|
|
if (part.charAt(0) == "!" || me && me.byName) {
|
|
if (hop(defs, path)) base = defs[path];
|
|
else defs[path] = base = {};
|
|
} else {
|
|
if (hop(base, parts[i])) base = base[part];
|
|
else base = base[part] = {};
|
|
}
|
|
}
|
|
return base;
|
|
}
|
|
|
|
function store(out, info, state) {
|
|
var name = typeName(info.type);
|
|
if (name != info.type.path && name != "?") {
|
|
out["!type"] = name;
|
|
} else if (info.type.proto && info.type.proto != state.cx.protos.Object) {
|
|
var protoName = typeName(info.type.proto);
|
|
if (protoName != "?") out["!proto"] = protoName;
|
|
}
|
|
if (info.span) out["!span"] = info.span;
|
|
if (info.doc) out["!doc"] = info.doc;
|
|
if (info.data) out["!data"] = info.data;
|
|
}
|
|
|
|
function storeAlt(path, type, state) {
|
|
var parts = path.split("."), last = parts.pop();
|
|
if (last[0] == "!") return;
|
|
var known = state.types[parts.join(".")];
|
|
var base = createPath(parts, state);
|
|
if (known && known.type.constructor != infer.Obj) return;
|
|
if (!hop(base, last)) base[last] = type.nameOverride || type.path;
|
|
}
|
|
|
|
var typeNameStack = [];
|
|
function typeName(value) {
|
|
var isType = value instanceof infer.Type;
|
|
if (isType) {
|
|
if (typeNameStack.indexOf(value) > -1)
|
|
return value.path || "?";
|
|
typeNameStack.push(value);
|
|
}
|
|
var name = value.typeName();
|
|
if (isType) typeNameStack.pop();
|
|
return name;
|
|
}
|
|
|
|
infer.AVal.prototype.typeName = function() {
|
|
if (this.types.length == 0) return "?";
|
|
if (this.types.length == 1) return typeName(this.types[0]);
|
|
var simplified = infer.simplifyTypes(this.types);
|
|
if (simplified.length > 2) return "?";
|
|
for (var strs = [], i = 0; i < simplified.length; i++)
|
|
strs.push(typeName(simplified[i]));
|
|
return strs.join("|");
|
|
};
|
|
|
|
infer.ANull.typeName = function() { return "?"; };
|
|
|
|
infer.Prim.prototype.typeName = function() { return this.name; };
|
|
|
|
infer.Sym.prototype.typeName = function() { return this.asPropName }
|
|
|
|
infer.Arr.prototype.typeName = function() {
|
|
if (!this.tuple) return "[" + typeName(this.getProp("<i>")) + "]"
|
|
var content = []
|
|
for (var i = 0; i < this.tuple; i++)
|
|
content.push(typeName(this.getProp(String(i))))
|
|
return "[" + content.join(", ") + "]"
|
|
};
|
|
|
|
infer.Fn.prototype.typeName = function() {
|
|
var out = this.generator ? "fn*(" : "fn(";
|
|
for (var i = 0; i < this.args.length; ++i) {
|
|
if (i) out += ", ";
|
|
var name = this.argNames[i];
|
|
if (name && name != "?") out += name + ": ";
|
|
out += typeName(this.args[i]);
|
|
}
|
|
out += ")";
|
|
if (this.computeRetSource)
|
|
out += " -> " + this.computeRetSource;
|
|
else if (!this.retval.isEmpty())
|
|
out += " -> " + typeName(this.retval);
|
|
return out;
|
|
};
|
|
|
|
infer.Obj.prototype.typeName = function() {
|
|
if (this.nameOverride) return this.nameOverride;
|
|
if (!this.path) return "?";
|
|
return this.path;
|
|
};
|
|
|
|
function simplify(data, sort) {
|
|
if (typeof data != "object") return data;
|
|
var sawType = false, sawOther = false;
|
|
for (var prop in data) {
|
|
if (prop == "!type") sawType = true;
|
|
else sawOther = true;
|
|
if (prop != "!data")
|
|
data[prop] = simplify(data[prop], sort);
|
|
}
|
|
if (sawType && !sawOther) return data["!type"];
|
|
return sort ? sortObject(data) : data;
|
|
}
|
|
|
|
function sortObject(obj) {
|
|
var props = [], out = {};
|
|
for (var prop in obj) props.push(prop);
|
|
props.sort();
|
|
for (var i = 0; i < props.length; ++i) {
|
|
var prop = props[i];
|
|
out[prop] = obj[prop];
|
|
}
|
|
return out;
|
|
}
|
|
});
|