mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-09-06 12:58:03 +00:00
Remove the old parser code
Thus introducing a few functional regressions, but it's going to be easier to fix things up without the old code knocking around and getting in the way.
This commit is contained in:
1
node_modules/.bin/esparse
generated
vendored
1
node_modules/.bin/esparse
generated
vendored
@@ -1 +0,0 @@
|
||||
../esprima/bin/esparse.js
|
5
node_modules/esprima/.travis.yml
generated
vendored
5
node_modules/esprima/.travis.yml
generated
vendored
@@ -1,5 +0,0 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 0.4
|
||||
- 0.6
|
||||
|
19
node_modules/esprima/LICENSE.BSD
generated
vendored
19
node_modules/esprima/LICENSE.BSD
generated
vendored
@@ -1,19 +0,0 @@
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
74
node_modules/esprima/README.md
generated
vendored
74
node_modules/esprima/README.md
generated
vendored
@@ -1,74 +0,0 @@
|
||||
Esprima ([esprima.org](http://esprima.org)) is an educational
|
||||
[ECMAScript](http://www.ecma-international.org/publications/standards/Ecma-262.htm)
|
||||
(also popularly known as [JavaScript](http://en.wikipedia.org/wiki/JavaScript>JavaScript))
|
||||
parsing infrastructure for multipurpose analysis. It is also written in ECMAScript.
|
||||
|
||||
Esprima serves as a good basis for various tools such as source
|
||||
modification ([Esmorph](https://github.com/ariya/esmorph)), coverage analyzer
|
||||
([node-cover](https://github.com/itay/node-cover) and
|
||||
[coveraje](https://github.com/coveraje/coveraje)),
|
||||
source-to-source compiler ([Marv](https://github.com/Yoric/Marv-the-Tinker)),
|
||||
syntax formatter ([Code Painter](https://github.com/fawek/codepainter)),
|
||||
and code generator ([escodegen](https://github.com/Constellation/escodegen)).
|
||||
|
||||
Esprima can be used in a web browser:
|
||||
|
||||
<script src="esprima.js"></script>
|
||||
|
||||
or in a Node.js application via the package manager:
|
||||
|
||||
npm install esprima
|
||||
|
||||
Esprima parser output is compatible with Mozilla (SpiderMonkey)
|
||||
[Parser API](https://developer.mozilla.org/en/SpiderMonkey/Parser_API).
|
||||
|
||||
A very simple example:
|
||||
|
||||
esprima.parse('var answer=42').body[0].declarations[0].init
|
||||
|
||||
produces the following object:
|
||||
|
||||
{ type: 'Literal', value: 42 }
|
||||
|
||||
Esprima is still in the development, for now please check
|
||||
[the wiki documentation](http://wiki.esprima.org).
|
||||
|
||||
Since it is not comprehensive nor complete, refer to the
|
||||
[issue tracker](http://issues.esprima.org) for
|
||||
[known problems](http://code.google.com/p/esprima/issues/list?q=Defect)
|
||||
and [future plans](http://code.google.com/p/esprima/issues/list?q=Enhancement).
|
||||
Esprima is supported on [many browsers](http://code.google.com/p/esprima/wiki/BrowserCompatibility):
|
||||
IE 6+, Firefox 1+, Safari 3+, Chrome 1+, and Opera 8+.
|
||||
|
||||
Feedback and contribution are welcomed! Please join the
|
||||
[mailing list](http://groups.google.com/group/esprima) and read the
|
||||
[contribution guide](http://code.google.com/p/esprima/wiki/ContributionGuide)
|
||||
for further info.
|
||||
|
||||
|
||||
### License
|
||||
|
||||
Copyright (C) 2012, 2011 [Ariya Hidayat](http://ariya.ofilabs.com/about)
|
||||
(twitter: [@ariyahidayat](http://twitter.com/ariyahidayat)) and other contributors.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
112
node_modules/esprima/assets/codemirror/codemirror.css
generated
vendored
112
node_modules/esprima/assets/codemirror/codemirror.css
generated
vendored
@@ -1,112 +0,0 @@
|
||||
.CodeMirror {
|
||||
line-height: 1em;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.CodeMirror-scroll {
|
||||
overflow: auto;
|
||||
height: 300px;
|
||||
/* This is needed to prevent an IE[67] bug where the scrolled content
|
||||
is visible outside of the scrolling box. */
|
||||
position: relative;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.CodeMirror-gutter {
|
||||
position: absolute; left: 0; top: 0;
|
||||
z-index: 10;
|
||||
background-color: #f7f7f7;
|
||||
border-right: 1px solid #eee;
|
||||
min-width: 2em;
|
||||
height: 100%;
|
||||
}
|
||||
.CodeMirror-gutter-text {
|
||||
color: #aaa;
|
||||
text-align: right;
|
||||
padding: .4em .2em .4em .4em;
|
||||
white-space: pre !important;
|
||||
}
|
||||
.CodeMirror-lines {
|
||||
padding: .4em;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.CodeMirror pre {
|
||||
-moz-border-radius: 0;
|
||||
-webkit-border-radius: 0;
|
||||
-o-border-radius: 0;
|
||||
border-radius: 0;
|
||||
border-width: 0; margin: 0; padding: 0; background: transparent;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
padding: 0; margin: 0;
|
||||
white-space: pre;
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
.CodeMirror-wrap pre {
|
||||
word-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.CodeMirror-wrap .CodeMirror-scroll {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.CodeMirror textarea {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.CodeMirror pre.CodeMirror-cursor {
|
||||
z-index: 10;
|
||||
position: absolute;
|
||||
visibility: hidden;
|
||||
border-left: 1px solid black;
|
||||
border-right:none;
|
||||
width:0;
|
||||
}
|
||||
.CodeMirror pre.CodeMirror-cursor.CodeMirror-overwrite {}
|
||||
.CodeMirror-focused pre.CodeMirror-cursor {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
div.CodeMirror-selected { background: #d9d9d9; }
|
||||
.CodeMirror-focused div.CodeMirror-selected { background: #d7d4f0; }
|
||||
|
||||
.CodeMirror-searching {
|
||||
background: #ffa;
|
||||
background: rgba(255, 255, 0, .4);
|
||||
}
|
||||
|
||||
/* Default theme */
|
||||
|
||||
.cm-s-default span.cm-keyword {color: #708;}
|
||||
.cm-s-default span.cm-atom {color: #219;}
|
||||
.cm-s-default span.cm-number {color: #164;}
|
||||
.cm-s-default span.cm-def {color: #00f;}
|
||||
.cm-s-default span.cm-variable {color: black;}
|
||||
.cm-s-default span.cm-variable-2 {color: #05a;}
|
||||
.cm-s-default span.cm-variable-3 {color: #085;}
|
||||
.cm-s-default span.cm-property {color: black;}
|
||||
.cm-s-default span.cm-operator {color: black;}
|
||||
.cm-s-default span.cm-comment {color: #a50;}
|
||||
.cm-s-default span.cm-string {color: #a11;}
|
||||
.cm-s-default span.cm-string-2 {color: #f50;}
|
||||
.cm-s-default span.cm-meta {color: #555;}
|
||||
.cm-s-default span.cm-error {color: #f00;}
|
||||
.cm-s-default span.cm-qualifier {color: #555;}
|
||||
.cm-s-default span.cm-builtin {color: #30a;}
|
||||
.cm-s-default span.cm-bracket {color: #cc7;}
|
||||
.cm-s-default span.cm-tag {color: #170;}
|
||||
.cm-s-default span.cm-attribute {color: #00c;}
|
||||
.cm-s-default span.cm-header {color: #a0a;}
|
||||
.cm-s-default span.cm-quote {color: #090;}
|
||||
.cm-s-default span.cm-hr {color: #999;}
|
||||
.cm-s-default span.cm-link {color: #00c;}
|
||||
|
||||
span.cm-header, span.cm-strong {font-weight: bold;}
|
||||
span.cm-em {font-style: italic;}
|
||||
span.cm-emstrong {font-style: italic; font-weight: bold;}
|
||||
span.cm-link {text-decoration: underline;}
|
||||
|
||||
div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
|
||||
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
|
2972
node_modules/esprima/assets/codemirror/codemirror.js
generated
vendored
2972
node_modules/esprima/assets/codemirror/codemirror.js
generated
vendored
File diff suppressed because it is too large
Load Diff
360
node_modules/esprima/assets/codemirror/javascript.js
generated
vendored
360
node_modules/esprima/assets/codemirror/javascript.js
generated
vendored
@@ -1,360 +0,0 @@
|
||||
CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
var indentUnit = config.indentUnit;
|
||||
var jsonMode = parserConfig.json;
|
||||
|
||||
// Tokenizer
|
||||
|
||||
var keywords = function(){
|
||||
function kw(type) {return {type: type, style: "keyword"};}
|
||||
var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
|
||||
var operator = kw("operator"), atom = {type: "atom", style: "atom"};
|
||||
return {
|
||||
"if": A, "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
|
||||
"return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C,
|
||||
"var": kw("var"), "const": kw("var"), "let": kw("var"),
|
||||
"function": kw("function"), "catch": kw("catch"),
|
||||
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
|
||||
"in": operator, "typeof": operator, "instanceof": operator,
|
||||
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom
|
||||
};
|
||||
}();
|
||||
|
||||
var isOperatorChar = /[+\-*&%=<>!?|]/;
|
||||
|
||||
function chain(stream, state, f) {
|
||||
state.tokenize = f;
|
||||
return f(stream, state);
|
||||
}
|
||||
|
||||
function nextUntilUnescaped(stream, end) {
|
||||
var escaped = false, next;
|
||||
while ((next = stream.next()) != null) {
|
||||
if (next == end && !escaped)
|
||||
return false;
|
||||
escaped = !escaped && next == "\\";
|
||||
}
|
||||
return escaped;
|
||||
}
|
||||
|
||||
// Used as scratch variables to communicate multiple values without
|
||||
// consing up tons of objects.
|
||||
var type, content;
|
||||
function ret(tp, style, cont) {
|
||||
type = tp; content = cont;
|
||||
return style;
|
||||
}
|
||||
|
||||
function jsTokenBase(stream, state) {
|
||||
var ch = stream.next();
|
||||
if (ch == '"' || ch == "'")
|
||||
return chain(stream, state, jsTokenString(ch));
|
||||
else if (/[\[\]{}\(\),;\:\.]/.test(ch))
|
||||
return ret(ch);
|
||||
else if (ch == "0" && stream.eat(/x/i)) {
|
||||
stream.eatWhile(/[\da-f]/i);
|
||||
return ret("number", "number");
|
||||
}
|
||||
else if (/\d/.test(ch)) {
|
||||
stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
|
||||
return ret("number", "number");
|
||||
}
|
||||
else if (ch == "/") {
|
||||
if (stream.eat("*")) {
|
||||
return chain(stream, state, jsTokenComment);
|
||||
}
|
||||
else if (stream.eat("/")) {
|
||||
stream.skipToEnd();
|
||||
return ret("comment", "comment");
|
||||
}
|
||||
else if (state.reAllowed) {
|
||||
nextUntilUnescaped(stream, "/");
|
||||
stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
|
||||
return ret("regexp", "string-2");
|
||||
}
|
||||
else {
|
||||
stream.eatWhile(isOperatorChar);
|
||||
return ret("operator", null, stream.current());
|
||||
}
|
||||
}
|
||||
else if (ch == "#") {
|
||||
stream.skipToEnd();
|
||||
return ret("error", "error");
|
||||
}
|
||||
else if (isOperatorChar.test(ch)) {
|
||||
stream.eatWhile(isOperatorChar);
|
||||
return ret("operator", null, stream.current());
|
||||
}
|
||||
else {
|
||||
stream.eatWhile(/[\w\$_]/);
|
||||
var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
|
||||
return (known && state.kwAllowed) ? ret(known.type, known.style, word) :
|
||||
ret("variable", "variable", word);
|
||||
}
|
||||
}
|
||||
|
||||
function jsTokenString(quote) {
|
||||
return function(stream, state) {
|
||||
if (!nextUntilUnescaped(stream, quote))
|
||||
state.tokenize = jsTokenBase;
|
||||
return ret("string", "string");
|
||||
};
|
||||
}
|
||||
|
||||
function jsTokenComment(stream, state) {
|
||||
var maybeEnd = false, ch;
|
||||
while (ch = stream.next()) {
|
||||
if (ch == "/" && maybeEnd) {
|
||||
state.tokenize = jsTokenBase;
|
||||
break;
|
||||
}
|
||||
maybeEnd = (ch == "*");
|
||||
}
|
||||
return ret("comment", "comment");
|
||||
}
|
||||
|
||||
// Parser
|
||||
|
||||
var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true};
|
||||
|
||||
function JSLexical(indented, column, type, align, prev, info) {
|
||||
this.indented = indented;
|
||||
this.column = column;
|
||||
this.type = type;
|
||||
this.prev = prev;
|
||||
this.info = info;
|
||||
if (align != null) this.align = align;
|
||||
}
|
||||
|
||||
function inScope(state, varname) {
|
||||
for (var v = state.localVars; v; v = v.next)
|
||||
if (v.name == varname) return true;
|
||||
}
|
||||
|
||||
function parseJS(state, style, type, content, stream) {
|
||||
var cc = state.cc;
|
||||
// Communicate our context to the combinators.
|
||||
// (Less wasteful than consing up a hundred closures on every call.)
|
||||
cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
|
||||
|
||||
if (!state.lexical.hasOwnProperty("align"))
|
||||
state.lexical.align = true;
|
||||
|
||||
while(true) {
|
||||
var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
|
||||
if (combinator(type, content)) {
|
||||
while(cc.length && cc[cc.length - 1].lex)
|
||||
cc.pop()();
|
||||
if (cx.marked) return cx.marked;
|
||||
if (type == "variable" && inScope(state, content)) return "variable-2";
|
||||
return style;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Combinator utils
|
||||
|
||||
var cx = {state: null, column: null, marked: null, cc: null};
|
||||
function pass() {
|
||||
for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
|
||||
}
|
||||
function cont() {
|
||||
pass.apply(null, arguments);
|
||||
return true;
|
||||
}
|
||||
function register(varname) {
|
||||
var state = cx.state;
|
||||
if (state.context) {
|
||||
cx.marked = "def";
|
||||
for (var v = state.localVars; v; v = v.next)
|
||||
if (v.name == varname) return;
|
||||
state.localVars = {name: varname, next: state.localVars};
|
||||
}
|
||||
}
|
||||
|
||||
// Combinators
|
||||
|
||||
var defaultVars = {name: "this", next: {name: "arguments"}};
|
||||
function pushcontext() {
|
||||
if (!cx.state.context) cx.state.localVars = defaultVars;
|
||||
cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
|
||||
}
|
||||
function popcontext() {
|
||||
cx.state.localVars = cx.state.context.vars;
|
||||
cx.state.context = cx.state.context.prev;
|
||||
}
|
||||
function pushlex(type, info) {
|
||||
var result = function() {
|
||||
var state = cx.state;
|
||||
state.lexical = new JSLexical(state.indented, cx.stream.column(), type, null, state.lexical, info)
|
||||
};
|
||||
result.lex = true;
|
||||
return result;
|
||||
}
|
||||
function poplex() {
|
||||
var state = cx.state;
|
||||
if (state.lexical.prev) {
|
||||
if (state.lexical.type == ")")
|
||||
state.indented = state.lexical.indented;
|
||||
state.lexical = state.lexical.prev;
|
||||
}
|
||||
}
|
||||
poplex.lex = true;
|
||||
|
||||
function expect(wanted) {
|
||||
return function expecting(type) {
|
||||
if (type == wanted) return cont();
|
||||
else if (wanted == ";") return pass();
|
||||
else return cont(arguments.callee);
|
||||
};
|
||||
}
|
||||
|
||||
function statement(type) {
|
||||
if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex);
|
||||
if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
|
||||
if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
|
||||
if (type == "{") return cont(pushlex("}"), block, poplex);
|
||||
if (type == ";") return cont();
|
||||
if (type == "function") return cont(functiondef);
|
||||
if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
|
||||
poplex, statement, poplex);
|
||||
if (type == "variable") return cont(pushlex("stat"), maybelabel);
|
||||
if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
|
||||
block, poplex, poplex);
|
||||
if (type == "case") return cont(expression, expect(":"));
|
||||
if (type == "default") return cont(expect(":"));
|
||||
if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
|
||||
statement, poplex, popcontext);
|
||||
return pass(pushlex("stat"), expression, expect(";"), poplex);
|
||||
}
|
||||
function expression(type) {
|
||||
if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator);
|
||||
if (type == "function") return cont(functiondef);
|
||||
if (type == "keyword c") return cont(maybeexpression);
|
||||
if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeoperator);
|
||||
if (type == "operator") return cont(expression);
|
||||
if (type == "[") return cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator);
|
||||
if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);
|
||||
return cont();
|
||||
}
|
||||
function maybeexpression(type) {
|
||||
if (type.match(/[;\}\)\],]/)) return pass();
|
||||
return pass(expression);
|
||||
}
|
||||
|
||||
function maybeoperator(type, value) {
|
||||
if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator);
|
||||
if (type == "operator") return cont(expression);
|
||||
if (type == ";") return;
|
||||
if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator);
|
||||
if (type == ".") return cont(property, maybeoperator);
|
||||
if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator);
|
||||
}
|
||||
function maybelabel(type) {
|
||||
if (type == ":") return cont(poplex, statement);
|
||||
return pass(maybeoperator, expect(";"), poplex);
|
||||
}
|
||||
function property(type) {
|
||||
if (type == "variable") {cx.marked = "property"; return cont();}
|
||||
}
|
||||
function objprop(type) {
|
||||
if (type == "variable") cx.marked = "property";
|
||||
if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expression);
|
||||
}
|
||||
function commasep(what, end) {
|
||||
function proceed(type) {
|
||||
if (type == ",") return cont(what, proceed);
|
||||
if (type == end) return cont();
|
||||
return cont(expect(end));
|
||||
}
|
||||
return function commaSeparated(type) {
|
||||
if (type == end) return cont();
|
||||
else return pass(what, proceed);
|
||||
};
|
||||
}
|
||||
function block(type) {
|
||||
if (type == "}") return cont();
|
||||
return pass(statement, block);
|
||||
}
|
||||
function vardef1(type, value) {
|
||||
if (type == "variable"){register(value); return cont(vardef2);}
|
||||
return cont();
|
||||
}
|
||||
function vardef2(type, value) {
|
||||
if (value == "=") return cont(expression, vardef2);
|
||||
if (type == ",") return cont(vardef1);
|
||||
}
|
||||
function forspec1(type) {
|
||||
if (type == "var") return cont(vardef1, forspec2);
|
||||
if (type == ";") return pass(forspec2);
|
||||
if (type == "variable") return cont(formaybein);
|
||||
return pass(forspec2);
|
||||
}
|
||||
function formaybein(type, value) {
|
||||
if (value == "in") return cont(expression);
|
||||
return cont(maybeoperator, forspec2);
|
||||
}
|
||||
function forspec2(type, value) {
|
||||
if (type == ";") return cont(forspec3);
|
||||
if (value == "in") return cont(expression);
|
||||
return cont(expression, expect(";"), forspec3);
|
||||
}
|
||||
function forspec3(type) {
|
||||
if (type != ")") cont(expression);
|
||||
}
|
||||
function functiondef(type, value) {
|
||||
if (type == "variable") {register(value); return cont(functiondef);}
|
||||
if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext);
|
||||
}
|
||||
function funarg(type, value) {
|
||||
if (type == "variable") {register(value); return cont();}
|
||||
}
|
||||
|
||||
// Interface
|
||||
|
||||
return {
|
||||
startState: function(basecolumn) {
|
||||
return {
|
||||
tokenize: jsTokenBase,
|
||||
reAllowed: true,
|
||||
kwAllowed: true,
|
||||
cc: [],
|
||||
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
|
||||
localVars: parserConfig.localVars,
|
||||
context: parserConfig.localVars && {vars: parserConfig.localVars},
|
||||
indented: 0
|
||||
};
|
||||
},
|
||||
|
||||
token: function(stream, state) {
|
||||
if (stream.sol()) {
|
||||
if (!state.lexical.hasOwnProperty("align"))
|
||||
state.lexical.align = false;
|
||||
state.indented = stream.indentation();
|
||||
}
|
||||
if (stream.eatSpace()) return null;
|
||||
var style = state.tokenize(stream, state);
|
||||
if (type == "comment") return style;
|
||||
state.reAllowed = !!(type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/));
|
||||
state.kwAllowed = type != '.';
|
||||
return parseJS(state, style, type, content, stream);
|
||||
},
|
||||
|
||||
indent: function(state, textAfter) {
|
||||
if (state.tokenize != jsTokenBase) return 0;
|
||||
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical,
|
||||
type = lexical.type, closing = firstChar == type;
|
||||
if (type == "vardef") return lexical.indented + 4;
|
||||
else if (type == "form" && firstChar == "{") return lexical.indented;
|
||||
else if (type == "stat" || type == "form") return lexical.indented + indentUnit;
|
||||
else if (lexical.info == "switch" && !closing)
|
||||
return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
|
||||
else if (lexical.align) return lexical.column + (closing ? 0 : 1);
|
||||
else return lexical.indented + (closing ? 0 : indentUnit);
|
||||
},
|
||||
|
||||
electricChars: ":{}"
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/javascript", "javascript");
|
||||
CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
|
487
node_modules/esprima/assets/json2.js
generated
vendored
487
node_modules/esprima/assets/json2.js
generated
vendored
@@ -1,487 +0,0 @@
|
||||
/*
|
||||
http://www.JSON.org/json2.js
|
||||
2011-10-19
|
||||
|
||||
Public Domain.
|
||||
|
||||
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
||||
|
||||
See http://www.JSON.org/js.html
|
||||
|
||||
|
||||
This code should be minified before deployment.
|
||||
See http://javascript.crockford.com/jsmin.html
|
||||
|
||||
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
|
||||
NOT CONTROL.
|
||||
|
||||
|
||||
This file creates a global JSON object containing two methods: stringify
|
||||
and parse.
|
||||
|
||||
JSON.stringify(value, replacer, space)
|
||||
value any JavaScript value, usually an object or array.
|
||||
|
||||
replacer an optional parameter that determines how object
|
||||
values are stringified for objects. It can be a
|
||||
function or an array of strings.
|
||||
|
||||
space an optional parameter that specifies the indentation
|
||||
of nested structures. If it is omitted, the text will
|
||||
be packed without extra whitespace. If it is a number,
|
||||
it will specify the number of spaces to indent at each
|
||||
level. If it is a string (such as '\t' or ' '),
|
||||
it contains the characters used to indent at each level.
|
||||
|
||||
This method produces a JSON text from a JavaScript value.
|
||||
|
||||
When an object value is found, if the object contains a toJSON
|
||||
method, its toJSON method will be called and the result will be
|
||||
stringified. A toJSON method does not serialize: it returns the
|
||||
value represented by the name/value pair that should be serialized,
|
||||
or undefined if nothing should be serialized. The toJSON method
|
||||
will be passed the key associated with the value, and this will be
|
||||
bound to the value
|
||||
|
||||
For example, this would serialize Dates as ISO strings.
|
||||
|
||||
Date.prototype.toJSON = function (key) {
|
||||
function f(n) {
|
||||
// Format integers to have at least two digits.
|
||||
return n < 10 ? '0' + n : n;
|
||||
}
|
||||
|
||||
return this.getUTCFullYear() + '-' +
|
||||
f(this.getUTCMonth() + 1) + '-' +
|
||||
f(this.getUTCDate()) + 'T' +
|
||||
f(this.getUTCHours()) + ':' +
|
||||
f(this.getUTCMinutes()) + ':' +
|
||||
f(this.getUTCSeconds()) + 'Z';
|
||||
};
|
||||
|
||||
You can provide an optional replacer method. It will be passed the
|
||||
key and value of each member, with this bound to the containing
|
||||
object. The value that is returned from your method will be
|
||||
serialized. If your method returns undefined, then the member will
|
||||
be excluded from the serialization.
|
||||
|
||||
If the replacer parameter is an array of strings, then it will be
|
||||
used to select the members to be serialized. It filters the results
|
||||
such that only members with keys listed in the replacer array are
|
||||
stringified.
|
||||
|
||||
Values that do not have JSON representations, such as undefined or
|
||||
functions, will not be serialized. Such values in objects will be
|
||||
dropped; in arrays they will be replaced with null. You can use
|
||||
a replacer function to replace those with JSON values.
|
||||
JSON.stringify(undefined) returns undefined.
|
||||
|
||||
The optional space parameter produces a stringification of the
|
||||
value that is filled with line breaks and indentation to make it
|
||||
easier to read.
|
||||
|
||||
If the space parameter is a non-empty string, then that string will
|
||||
be used for indentation. If the space parameter is a number, then
|
||||
the indentation will be that many spaces.
|
||||
|
||||
Example:
|
||||
|
||||
text = JSON.stringify(['e', {pluribus: 'unum'}]);
|
||||
// text is '["e",{"pluribus":"unum"}]'
|
||||
|
||||
|
||||
text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
|
||||
// text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
|
||||
|
||||
text = JSON.stringify([new Date()], function (key, value) {
|
||||
return this[key] instanceof Date ?
|
||||
'Date(' + this[key] + ')' : value;
|
||||
});
|
||||
// text is '["Date(---current time---)"]'
|
||||
|
||||
|
||||
JSON.parse(text, reviver)
|
||||
This method parses a JSON text to produce an object or array.
|
||||
It can throw a SyntaxError exception.
|
||||
|
||||
The optional reviver parameter is a function that can filter and
|
||||
transform the results. It receives each of the keys and values,
|
||||
and its return value is used instead of the original value.
|
||||
If it returns what it received, then the structure is not modified.
|
||||
If it returns undefined then the member is deleted.
|
||||
|
||||
Example:
|
||||
|
||||
// Parse the text. Values that look like ISO date strings will
|
||||
// be converted to Date objects.
|
||||
|
||||
myData = JSON.parse(text, function (key, value) {
|
||||
var a;
|
||||
if (typeof value === 'string') {
|
||||
a =
|
||||
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
|
||||
if (a) {
|
||||
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
|
||||
+a[5], +a[6]));
|
||||
}
|
||||
}
|
||||
return value;
|
||||
});
|
||||
|
||||
myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
|
||||
var d;
|
||||
if (typeof value === 'string' &&
|
||||
value.slice(0, 5) === 'Date(' &&
|
||||
value.slice(-1) === ')') {
|
||||
d = new Date(value.slice(5, -1));
|
||||
if (d) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
});
|
||||
|
||||
|
||||
This is a reference implementation. You are free to copy, modify, or
|
||||
redistribute.
|
||||
*/
|
||||
|
||||
/*jslint evil: true, regexp: true */
|
||||
|
||||
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
|
||||
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
|
||||
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
|
||||
lastIndex, length, parse, prototype, push, replace, slice, stringify,
|
||||
test, toJSON, toString, valueOf
|
||||
*/
|
||||
|
||||
|
||||
// Create a JSON object only if one does not already exist. We create the
|
||||
// methods in a closure to avoid creating global variables.
|
||||
|
||||
var JSON;
|
||||
if (!JSON) {
|
||||
JSON = {};
|
||||
}
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function f(n) {
|
||||
// Format integers to have at least two digits.
|
||||
return n < 10 ? '0' + n : n;
|
||||
}
|
||||
|
||||
if (typeof Date.prototype.toJSON !== 'function') {
|
||||
|
||||
Date.prototype.toJSON = function (key) {
|
||||
|
||||
return isFinite(this.valueOf())
|
||||
? this.getUTCFullYear() + '-' +
|
||||
f(this.getUTCMonth() + 1) + '-' +
|
||||
f(this.getUTCDate()) + 'T' +
|
||||
f(this.getUTCHours()) + ':' +
|
||||
f(this.getUTCMinutes()) + ':' +
|
||||
f(this.getUTCSeconds()) + 'Z'
|
||||
: null;
|
||||
};
|
||||
|
||||
String.prototype.toJSON =
|
||||
Number.prototype.toJSON =
|
||||
Boolean.prototype.toJSON = function (key) {
|
||||
return this.valueOf();
|
||||
};
|
||||
}
|
||||
|
||||
var cx = new RegExp('[\u0000\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]', 'g'),
|
||||
escapable = new RegExp('[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]', 'g'),
|
||||
gap,
|
||||
indent,
|
||||
meta = { // table of character substitutions
|
||||
'\b': '\\b',
|
||||
'\t': '\\t',
|
||||
'\n': '\\n',
|
||||
'\f': '\\f',
|
||||
'\r': '\\r',
|
||||
'"' : '\\"',
|
||||
'\\': '\\\\'
|
||||
},
|
||||
rep;
|
||||
|
||||
|
||||
function quote(string) {
|
||||
|
||||
// If the string contains no control characters, no quote characters, and no
|
||||
// backslash characters, then we can safely slap some quotes around it.
|
||||
// Otherwise we must also replace the offending characters with safe escape
|
||||
// sequences.
|
||||
|
||||
escapable.lastIndex = 0;
|
||||
return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
|
||||
var c = meta[a];
|
||||
return typeof c === 'string'
|
||||
? c
|
||||
: '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
||||
}) + '"' : '"' + string + '"';
|
||||
}
|
||||
|
||||
|
||||
function str(key, holder) {
|
||||
|
||||
// Produce a string from holder[key].
|
||||
|
||||
var i, // The loop counter.
|
||||
k, // The member key.
|
||||
v, // The member value.
|
||||
length,
|
||||
mind = gap,
|
||||
partial,
|
||||
value = holder[key];
|
||||
|
||||
// If the value has a toJSON method, call it to obtain a replacement value.
|
||||
|
||||
if (value && typeof value === 'object' &&
|
||||
typeof value.toJSON === 'function') {
|
||||
value = value.toJSON(key);
|
||||
}
|
||||
|
||||
// If we were called with a replacer function, then call the replacer to
|
||||
// obtain a replacement value.
|
||||
|
||||
if (typeof rep === 'function') {
|
||||
value = rep.call(holder, key, value);
|
||||
}
|
||||
|
||||
// What happens next depends on the value's type.
|
||||
|
||||
switch (typeof value) {
|
||||
case 'string':
|
||||
return quote(value);
|
||||
|
||||
case 'number':
|
||||
|
||||
// JSON numbers must be finite. Encode non-finite numbers as null.
|
||||
|
||||
return isFinite(value) ? String(value) : 'null';
|
||||
|
||||
case 'boolean':
|
||||
case 'null':
|
||||
|
||||
// If the value is a boolean or null, convert it to a string. Note:
|
||||
// typeof null does not produce 'null'. The case is included here in
|
||||
// the remote chance that this gets fixed someday.
|
||||
|
||||
return String(value);
|
||||
|
||||
// If the type is 'object', we might be dealing with an object or an array or
|
||||
// null.
|
||||
|
||||
case 'object':
|
||||
|
||||
// Due to a specification blunder in ECMAScript, typeof null is 'object',
|
||||
// so watch out for that case.
|
||||
|
||||
if (!value) {
|
||||
return 'null';
|
||||
}
|
||||
|
||||
// Make an array to hold the partial results of stringifying this object value.
|
||||
|
||||
gap += indent;
|
||||
partial = [];
|
||||
|
||||
// Is the value an array?
|
||||
|
||||
if (Object.prototype.toString.apply(value) === '[object Array]') {
|
||||
|
||||
// The value is an array. Stringify every element. Use null as a placeholder
|
||||
// for non-JSON values.
|
||||
|
||||
length = value.length;
|
||||
for (i = 0; i < length; i += 1) {
|
||||
partial[i] = str(i, value) || 'null';
|
||||
}
|
||||
|
||||
// Join all of the elements together, separated with commas, and wrap them in
|
||||
// brackets.
|
||||
|
||||
v = partial.length === 0
|
||||
? '[]'
|
||||
: gap
|
||||
? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
|
||||
: '[' + partial.join(',') + ']';
|
||||
gap = mind;
|
||||
return v;
|
||||
}
|
||||
|
||||
// If the replacer is an array, use it to select the members to be stringified.
|
||||
|
||||
if (rep && typeof rep === 'object') {
|
||||
length = rep.length;
|
||||
for (i = 0; i < length; i += 1) {
|
||||
if (typeof rep[i] === 'string') {
|
||||
k = rep[i];
|
||||
v = str(k, value);
|
||||
if (v) {
|
||||
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// Otherwise, iterate through all of the keys in the object.
|
||||
|
||||
for (k in value) {
|
||||
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
||||
v = str(k, value);
|
||||
if (v) {
|
||||
partial.push(quote(k) + (gap ? ': ' : ':') + v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Join all of the member texts together, separated with commas,
|
||||
// and wrap them in braces.
|
||||
|
||||
v = partial.length === 0
|
||||
? '{}'
|
||||
: gap
|
||||
? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
|
||||
: '{' + partial.join(',') + '}';
|
||||
gap = mind;
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
// If the JSON object does not yet have a stringify method, give it one.
|
||||
|
||||
if (typeof JSON.stringify !== 'function') {
|
||||
JSON.stringify = function (value, replacer, space) {
|
||||
|
||||
// The stringify method takes a value and an optional replacer, and an optional
|
||||
// space parameter, and returns a JSON text. The replacer can be a function
|
||||
// that can replace values, or an array of strings that will select the keys.
|
||||
// A default replacer method can be provided. Use of the space parameter can
|
||||
// produce text that is more easily readable.
|
||||
|
||||
var i;
|
||||
gap = '';
|
||||
indent = '';
|
||||
|
||||
// If the space parameter is a number, make an indent string containing that
|
||||
// many spaces.
|
||||
|
||||
if (typeof space === 'number') {
|
||||
for (i = 0; i < space; i += 1) {
|
||||
indent += ' ';
|
||||
}
|
||||
|
||||
// If the space parameter is a string, it will be used as the indent string.
|
||||
|
||||
} else if (typeof space === 'string') {
|
||||
indent = space;
|
||||
}
|
||||
|
||||
// If there is a replacer, it must be a function or an array.
|
||||
// Otherwise, throw an error.
|
||||
|
||||
rep = replacer;
|
||||
if (replacer && typeof replacer !== 'function' &&
|
||||
(typeof replacer !== 'object' ||
|
||||
typeof replacer.length !== 'number')) {
|
||||
throw new Error('JSON.stringify');
|
||||
}
|
||||
|
||||
// Make a fake root object containing our value under the key of ''.
|
||||
// Return the result of stringifying the value.
|
||||
|
||||
return str('', {'': value});
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// If the JSON object does not yet have a parse method, give it one.
|
||||
|
||||
if (typeof JSON.parse !== 'function') {
|
||||
JSON.parse = function (text, reviver) {
|
||||
|
||||
// The parse method takes a text and an optional reviver function, and returns
|
||||
// a JavaScript value if the text is a valid JSON text.
|
||||
|
||||
var j;
|
||||
|
||||
function walk(holder, key) {
|
||||
|
||||
// The walk method is used to recursively walk the resulting structure so
|
||||
// that modifications can be made.
|
||||
|
||||
var k, v, value = holder[key];
|
||||
if (value && typeof value === 'object') {
|
||||
for (k in value) {
|
||||
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
||||
v = walk(value, k);
|
||||
if (v !== undefined) {
|
||||
value[k] = v;
|
||||
} else {
|
||||
delete value[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return reviver.call(holder, key, value);
|
||||
}
|
||||
|
||||
|
||||
// Parsing happens in four stages. In the first stage, we replace certain
|
||||
// Unicode characters with escape sequences. JavaScript handles many characters
|
||||
// incorrectly, either silently deleting them, or treating them as line endings.
|
||||
|
||||
text = String(text);
|
||||
cx.lastIndex = 0;
|
||||
if (cx.test(text)) {
|
||||
text = text.replace(cx, function (a) {
|
||||
return '\\u' +
|
||||
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
||||
});
|
||||
}
|
||||
|
||||
// In the second stage, we run the text against regular expressions that look
|
||||
// for non-JSON patterns. We are especially concerned with '()' and 'new'
|
||||
// because they can cause invocation, and '=' because it can cause mutation.
|
||||
// But just to be safe, we want to reject all unexpected forms.
|
||||
|
||||
// We split the second stage into 4 regexp operations in order to work around
|
||||
// crippling inefficiencies in IE's and Safari's regexp engines. First we
|
||||
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
|
||||
// replace all simple value tokens with ']' characters. Third, we delete all
|
||||
// open brackets that follow a colon or comma or that begin the text. Finally,
|
||||
// we look to see that the remaining characters are only whitespace or ']' or
|
||||
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
|
||||
|
||||
if (/^[\],:{}\s]*$/
|
||||
.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
|
||||
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
|
||||
.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
|
||||
|
||||
// In the third stage we use the eval function to compile the text into a
|
||||
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
|
||||
// in JavaScript: it can begin a block or an object literal. We wrap the text
|
||||
// in parens to eliminate the ambiguity.
|
||||
|
||||
j = eval('(' + text + ')');
|
||||
|
||||
// In the optional fourth stage, we recursively walk the new structure, passing
|
||||
// each name/value pair to a reviver function for possible transformation.
|
||||
|
||||
return typeof reviver === 'function'
|
||||
? walk({'': j}, '')
|
||||
: j;
|
||||
}
|
||||
|
||||
// If the text is not JSON parseable, then a SyntaxError is thrown.
|
||||
|
||||
throw new SyntaxError('JSON.parse');
|
||||
};
|
||||
}
|
||||
}());
|
164
node_modules/esprima/assets/style.css
generated
vendored
164
node_modules/esprima/assets/style.css
generated
vendored
@@ -1,164 +0,0 @@
|
||||
body {
|
||||
background-color: #ffffff;
|
||||
min-width: 960px;
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
line-height: 18px;
|
||||
color: #444;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
line-height: 18px;
|
||||
margin-bottom: 9px;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
li {
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
line-height: 18px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin-left: 15px;
|
||||
font-family: Inconsolata, Menlo, 'Courier New', monospace;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-top: 2px;
|
||||
margin-bottom: 18px;
|
||||
font-size: 30px;
|
||||
line-height: 36px;
|
||||
font-weight: bold;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
h1 small {
|
||||
font-size: 18px;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
h3, h4 {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.code {
|
||||
border-left: 3px solid #ddd;
|
||||
margin: 5px 3px 8px 15px;
|
||||
padding: 0 0 0 8px;
|
||||
}
|
||||
|
||||
.CodeMirror {
|
||||
padding: 0;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.CodeMirror-scroll {
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.container {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: 960px;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
top: 0;
|
||||
margin: 0 0 0 480px;
|
||||
padding: 0;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.topbar ul {
|
||||
padding: 5px 20px 5px 10px;
|
||||
background-color: #222;
|
||||
margin: 0 10px 0 0;
|
||||
}
|
||||
|
||||
.topbar a {
|
||||
color: #ddd;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.topbar a:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.topbar .nav li {
|
||||
background-color: #222;
|
||||
display: inline;
|
||||
padding: 4px 10px 4px 0px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.container .main {
|
||||
width: 540px;
|
||||
display: inline;
|
||||
float: left;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.container .sidebar {
|
||||
width: 350px;
|
||||
display: inline;
|
||||
float: left;
|
||||
margin-left: 30px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 25px;
|
||||
margin-bottom: 25px;
|
||||
color: #555;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
font-family: Inconsolata, Monaco, Consolas, "Lucida Console", monospace;
|
||||
font-size: 13px;
|
||||
color: #555;
|
||||
width: 80%;
|
||||
padding: 7px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 80%;
|
||||
border: 1px solid #ccc;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
thead {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
table th, table td {
|
||||
border-left: 1px solid #ccc;
|
||||
padding: 3px 3px 10px 3px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table td {
|
||||
border-top: 1px solid #ccc;
|
||||
}
|
||||
|
||||
tbody tr:nth-child(odd) td {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
12
node_modules/esprima/assets/yui/treeview-min.js
generated
vendored
12
node_modules/esprima/assets/yui/treeview-min.js
generated
vendored
File diff suppressed because one or more lines are too long
BIN
node_modules/esprima/assets/yui/treeview-sprite.gif
generated
vendored
BIN
node_modules/esprima/assets/yui/treeview-sprite.gif
generated
vendored
Binary file not shown.
Before Width: | Height: | Size: 4.2 KiB |
7
node_modules/esprima/assets/yui/treeview.css
generated
vendored
7
node_modules/esprima/assets/yui/treeview.css
generated
vendored
@@ -1,7 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2011, Yahoo! Inc. All rights reserved.
|
||||
Code licensed under the BSD License:
|
||||
http://developer.yahoo.com/yui/license.html
|
||||
version: 2.9.0
|
||||
*/
|
||||
table.ygtvtable{margin-bottom:0;border:0;border-collapse:collapse}td.ygtvcell{border:0;padding:0}a.ygtvspacer{text-decoration:none;outline-style:none;display:block}.ygtvtn{width:18px;height:22px;background:url(treeview-sprite.gif) 0 -5600px no-repeat;cursor:pointer}.ygtvtm{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -4000px no-repeat}.ygtvtmh,.ygtvtmhh{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -4800px no-repeat}.ygtvtp{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -6400px no-repeat}.ygtvtph,.ygtvtphh{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -7200px no-repeat}.ygtvln{width:18px;height:22px;background:url(treeview-sprite.gif) 0 -1600px no-repeat;cursor:pointer}.ygtvlm{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 0 no-repeat}.ygtvlmh,.ygtvlmhh{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -800px no-repeat}.ygtvlp{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -2400px no-repeat}.ygtvlph,.ygtvlphh{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -3200px no-repeat;cursor:pointer}.ygtvloading{width:18px;height:22px;background:url(treeview-loading.gif) 0 0 no-repeat}.ygtvdepthcell{width:18px;height:22px;background:url(treeview-sprite.gif) 0 -8000px no-repeat}.ygtvblankdepthcell{width:18px;height:22px}* html .ygtvchildren{height:2%}.ygtvlabel,.ygtvlabel:link,.ygtvlabel:visited,.ygtvlabel:hover{margin-left:2px;text-decoration:none;background-color:white;cursor:pointer}.ygtvcontent{cursor:default}.ygtvspacer{height:22px;width:18px}.ygtvfocus{background-color:#c0e0e0;border:0}.ygtvfocus .ygtvlabel,.ygtvfocus .ygtvlabel:link,.ygtvfocus .ygtvlabel:visited,.ygtvfocus .ygtvlabel:hover{background-color:#c0e0e0}.ygtvfocus a{outline-style:none}.ygtvok{width:18px;height:22px;background:url(treeview-sprite.gif) 0 -8800px no-repeat}.ygtvok:hover{background:url(treeview-sprite.gif) 0 -8844px no-repeat}.ygtvcancel{width:18px;height:22px;background:url(treeview-sprite.gif) 0 -8822px no-repeat}.ygtvcancel:hover{background:url(treeview-sprite.gif) 0 -8866px no-repeat}.ygtv-label-editor{background-color:#f2f2f2;border:1px solid silver;position:absolute;display:none;overflow:hidden;margin:auto;z-index:9000}.ygtv-edit-TextNode{width:190px}.ygtv-edit-TextNode .ygtvcancel,.ygtv-edit-TextNode .ygtvok{border:0}.ygtv-edit-TextNode .ygtv-button-container{float:right}.ygtv-edit-TextNode .ygtv-input input{width:140px}.ygtv-edit-DateNode .ygtvcancel{border:0}.ygtv-edit-DateNode .ygtvok{display:none}.ygtv-edit-DateNode .ygtv-button-container{text-align:right;margin:auto}.ygtv-highlight .ygtv-highlight1,.ygtv-highlight .ygtv-highlight1 .ygtvlabel{background-color:blue;color:white}.ygtv-highlight .ygtv-highlight2,.ygtv-highlight .ygtv-highlight2 .ygtvlabel{background-color:silver}.ygtv-highlight .ygtv-highlight0 .ygtvfocus .ygtvlabel,.ygtv-highlight .ygtv-highlight1 .ygtvfocus .ygtvlabel,.ygtv-highlight .ygtv-highlight2 .ygtvfocus .ygtvlabel{background-color:#c0e0e0}.ygtv-highlight .ygtvcontent{padding-right:1em}.ygtv-checkbox .ygtv-highlight0 .ygtvcontent{padding-left:1em;background:url(check0.gif) no-repeat}.ygtv-checkbox .ygtv-highlight0 .ygtvfocus.ygtvcontent,.ygtv-checkbox .ygtv-highlight1 .ygtvfocus.ygtvcontent,.ygtv-checkbox .ygtv-highlight2 .ygtvfocus.ygtvcontent{background-color:#c0e0e0}.ygtv-checkbox .ygtv-highlight1 .ygtvcontent{padding-left:1em;background:url(check1.gif) no-repeat}.ygtv-checkbox .ygtv-highlight2 .ygtvcontent{padding-left:1em;background:url(check2.gif) no-repeat}
|
14
node_modules/esprima/assets/yui/yahoo-dom-event.js
generated
vendored
14
node_modules/esprima/assets/yui/yahoo-dom-event.js
generated
vendored
File diff suppressed because one or more lines are too long
42
node_modules/esprima/bin/esparse.js
generated
vendored
42
node_modules/esprima/bin/esparse.js
generated
vendored
@@ -1,42 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
/*
|
||||
Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*jslint sloppy:true node:true */
|
||||
|
||||
var fs = require('fs'),
|
||||
esprima = require('esprima'),
|
||||
files = process.argv.splice(2);
|
||||
|
||||
if (files.length === 0) {
|
||||
console.log('Usage:');
|
||||
console.log(' esparse file.js');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
files.forEach(function (filename) {
|
||||
var content = fs.readFileSync(filename, 'utf-8');
|
||||
console.log(JSON.stringify(esprima.parse(content), null, 4));
|
||||
});
|
||||
/* vim: set sw=4 ts=4 et tw=80 : */
|
92
node_modules/esprima/changes
generated
vendored
92
node_modules/esprima/changes
generated
vendored
@@ -1,92 +0,0 @@
|
||||
Update escodegen for the rewrite demo.
|
||||
Update CodeMirror to version 2.23.
|
||||
Collect the last line comment.
|
||||
Dynamically loading Narcissus in the speed comparison page.
|
||||
Show an exemplary coverage analysis result.
|
||||
Generate coverage analysis report.
|
||||
Tree interface for the parse demo.
|
||||
Use increment operator in various scanning functions.
|
||||
Use increment operator in comment handling functions.
|
||||
Unbreak the test suite on older web browsers.
|
||||
Reenable testing with Node.js 0.4.
|
||||
Compensate if invalid regular expression flag is not handled correctly.
|
||||
Mention github.com/Yoric/Marv-the-Tinker.
|
||||
Preserve line terminators in block comments
|
||||
Tolerant mode: ignore with restriction
|
||||
Do not use Object.freeze for various hash tables.
|
||||
Simplify nextChar() function with increment operator.
|
||||
Tolerant mode: ignore return not within a function
|
||||
Import Esmorph code for the Function Trace demo.
|
||||
Remove source modification feature.
|
||||
Reorganize binary node tracking routines.
|
||||
Vary parsing options while testing for invalid syntax.
|
||||
Fix wrong location info when comments are present.
|
||||
Add a test case for do while ended with a semicolon.
|
||||
Add a test case for continue statement with a semicolon.
|
||||
Shuffle the code in wrapTrackingFunction() function.
|
||||
Import escodegen for the Source Rewrite demo.
|
||||
Split code generator from esprima core
|
||||
Add test cases for reserved words as function argument name.
|
||||
Add a test case for using future reserved word as function name.
|
||||
Shuffle the code in parseSourceElement() function.
|
||||
Add a test case for computed member in left hand-side expression.
|
||||
Make note of unreachable case when parsing object property key.
|
||||
Update CodeMirror to version 2.22.
|
||||
Update platform.js to v1.0.0-pre.
|
||||
Temporarily disable Travis CI test on Node.js 0.4.
|
||||
Add a test case to trigger an error due to expecting a keyword.
|
||||
No need to shorten the token value for unexpected token error.
|
||||
Add a test case for (invalid) Unicode escape in regular expression flag.
|
||||
Add a test case for octal directive restriction before strict directive in Program
|
||||
Strict mode: duplicate identifier in function parameter list
|
||||
Add a test case for an error of non-identifier after non-computed property.
|
||||
Syntax errors for duplicate object properties.
|
||||
Fixed property name error message identifiers.
|
||||
Add test cases to capture some escaping in the string literals.
|
||||
Add test cases for invalid octal literals.
|
||||
Add a test case for semicolon after a comment.
|
||||
Add a test case to provoke an error in the object property setter.
|
||||
Add test cases for break and continue followed by a line break.
|
||||
Add a test case for empty source elements.
|
||||
Use assert for better semantics of contract.
|
||||
Reject illegal numeric literal like '10E+'
|
||||
ArrayInitialiser / ObjectInitialiser don't handle end-of-input correctly
|
||||
Add tests to catch various corner cases when handling Unicode literals.
|
||||
Static mapping of token value and its name.
|
||||
Incomplete statement should trigger an error.
|
||||
Remove unused function unpatching after the refactoring.
|
||||
Support space separator as white space
|
||||
Add comment about following V8 error messages.
|
||||
Fix syntax error message strings.
|
||||
Handle LHS in for-in and assignment correctly
|
||||
SyntaxError for 'return' outside function body
|
||||
Mention related projects based on Esprima.
|
||||
IE6 fix for parser demo error reporting.
|
||||
IE6 fixes for labelSet.
|
||||
Fix coding style violations in the new isKeyword() function.
|
||||
Syntax errors for invalid continue/break and label references
|
||||
Faster isKeyword() implementation.
|
||||
Add generator identity test
|
||||
Freeze constant values
|
||||
Remove some invalid Precedence
|
||||
generate() fails on consecutive unary expressions.
|
||||
Optimize moving the index forward instead of calling nextChar().
|
||||
Add API test cases for Mozilla Reflect compatibility.
|
||||
Add support for indentation option in the rewriter demo.
|
||||
New demo to showcase source code rewrite.
|
||||
Simplify nextChar() function.
|
||||
Unterminated block comment should trigger an error.
|
||||
Make the regular expressions for `IdentifierStart` and `IdentifierPart` more compact
|
||||
Strict Mode: restrict with statement
|
||||
Duplicated property check should be robust against special name.
|
||||
Fix code generator with an empty program.
|
||||
Fix generator indentation bug in double nested If statements.
|
||||
Allow some future reserved word in non-strict code.
|
||||
Unnecessary forward slash in json2.js Opera fix.
|
||||
Strict mode: do not allow octal literals.
|
||||
Fixed null literal value property.
|
||||
Clean-up unused variables.
|
||||
Strict mode: trigger an error when using eval and arguments.
|
||||
Mark numeric literal specified as an octal number.
|
||||
Fix Unicode bug with Letter number (Nl) and `\u200C` or `\u200D`.
|
||||
Include the forgotten Python script to generated Unicode regex.
|
696
node_modules/esprima/cm
generated
vendored
696
node_modules/esprima/cm
generated
vendored
@@ -1,696 +0,0 @@
|
||||
commit f2dd82b0d3defdedb01c5222e802d56ba47bd93f
|
||||
Author: Ariya Hidayat <ariya.hidayat@gmail.com>
|
||||
Date: Tue Mar 27 17:56:26 2012 -0700
|
||||
|
||||
CodeMirror version 2.23.
|
||||
|
||||
diff --git a/assets/codemirror/codemirror.css b/assets/codemirror/codemirror.css
|
||||
index 5eadb24..2d79f4a 100644
|
||||
--- a/assets/codemirror/codemirror.css
|
||||
+++ b/assets/codemirror/codemirror.css
|
||||
@@ -9,6 +9,7 @@
|
||||
/* This is needed to prevent an IE[67] bug where the scrolled content
|
||||
is visible outside of the scrolling box. */
|
||||
position: relative;
|
||||
+ outline: none;
|
||||
}
|
||||
|
||||
.CodeMirror-gutter {
|
||||
@@ -27,6 +28,7 @@
|
||||
}
|
||||
.CodeMirror-lines {
|
||||
padding: .4em;
|
||||
+ white-space: pre;
|
||||
}
|
||||
|
||||
.CodeMirror pre {
|
||||
diff --git a/assets/codemirror/codemirror.js b/assets/codemirror/codemirror.js
|
||||
index 9c6e65e..5434a8d 100644
|
||||
--- a/assets/codemirror/codemirror.js
|
||||
+++ b/assets/codemirror/codemirror.js
|
||||
@@ -1,4 +1,4 @@
|
||||
-// CodeMirror version 2.22
|
||||
+// CodeMirror version 2.23
|
||||
//
|
||||
// All functions that need access to the editor's state live inside
|
||||
// the CodeMirror function. Below that, at the bottom of the file,
|
||||
@@ -15,9 +15,8 @@ var CodeMirror = (function() {
|
||||
if (defaults.hasOwnProperty(opt))
|
||||
options[opt] = (givenOptions && givenOptions.hasOwnProperty(opt) ? givenOptions : defaults)[opt];
|
||||
|
||||
- var targetDocument = options["document"];
|
||||
// The element in which the editor lives.
|
||||
- var wrapper = targetDocument.createElement("div");
|
||||
+ var wrapper = document.createElement("div");
|
||||
wrapper.className = "CodeMirror" + (options.lineWrapping ? " CodeMirror-wrap" : "");
|
||||
// This mess creates the base DOM structure for the editor.
|
||||
wrapper.innerHTML =
|
||||
@@ -48,7 +47,10 @@ var CodeMirror = (function() {
|
||||
if (!webkit) lineSpace.draggable = true;
|
||||
lineSpace.style.outline = "none";
|
||||
if (options.tabindex != null) input.tabIndex = options.tabindex;
|
||||
+ if (options.autofocus) focusInput();
|
||||
if (!options.gutter && !options.lineNumbers) gutter.style.display = "none";
|
||||
+ // Needed to handle Tab key in KHTML
|
||||
+ if (khtml) inputDiv.style.height = "1px", inputDiv.style.position = "absolute";
|
||||
|
||||
// Check for problem with IE innerHTML not working when we have a
|
||||
// P (or similar) parent node.
|
||||
@@ -81,12 +83,13 @@ var CodeMirror = (function() {
|
||||
gutterDirty, callbacks;
|
||||
// Current visible range (may be bigger than the view window).
|
||||
var displayOffset = 0, showingFrom = 0, showingTo = 0, lastSizeC = 0;
|
||||
- // bracketHighlighted is used to remember that a backet has been
|
||||
+ // bracketHighlighted is used to remember that a bracket has been
|
||||
// marked.
|
||||
var bracketHighlighted;
|
||||
// Tracks the maximum line length so that the horizontal scrollbar
|
||||
// can be kept static when scrolling.
|
||||
var maxLine = "", maxWidth;
|
||||
+ var tabCache = {};
|
||||
|
||||
// Initialize the content.
|
||||
operation(function(){setValue(options.value || ""); updateInput = false;})();
|
||||
@@ -124,10 +127,16 @@ var CodeMirror = (function() {
|
||||
if (!options.readOnly) replaceSelection("");
|
||||
}));
|
||||
|
||||
+ // Needed to handle Tab key in KHTML
|
||||
+ if (khtml) connect(code, "mouseup", function() {
|
||||
+ if (document.activeElement == input) input.blur();
|
||||
+ focusInput();
|
||||
+ });
|
||||
+
|
||||
// IE throws unspecified error in certain cases, when
|
||||
// trying to access activeElement before onload
|
||||
- var hasFocus; try { hasFocus = (targetDocument.activeElement == input); } catch(e) { }
|
||||
- if (hasFocus) setTimeout(onFocus, 20);
|
||||
+ var hasFocus; try { hasFocus = (document.activeElement == input); } catch(e) { }
|
||||
+ if (hasFocus || options.autofocus) setTimeout(onFocus, 20);
|
||||
else onBlur();
|
||||
|
||||
function isLine(l) {return l >= 0 && l < doc.size;}
|
||||
@@ -178,17 +187,23 @@ var CodeMirror = (function() {
|
||||
line = clipLine(line == null ? doc.size - 1: line);
|
||||
return getStateBefore(line + 1);
|
||||
},
|
||||
- cursorCoords: function(start){
|
||||
+ cursorCoords: function(start, mode) {
|
||||
if (start == null) start = sel.inverted;
|
||||
- return pageCoords(start ? sel.from : sel.to);
|
||||
+ return this.charCoords(start ? sel.from : sel.to, mode);
|
||||
+ },
|
||||
+ charCoords: function(pos, mode) {
|
||||
+ pos = clipPos(pos);
|
||||
+ if (mode == "local") return localCoords(pos, false);
|
||||
+ if (mode == "div") return localCoords(pos, true);
|
||||
+ return pageCoords(pos);
|
||||
},
|
||||
- charCoords: function(pos){return pageCoords(clipPos(pos));},
|
||||
coordsChar: function(coords) {
|
||||
var off = eltOffset(lineSpace);
|
||||
return coordsChar(coords.x - off.left, coords.y - off.top);
|
||||
},
|
||||
markText: operation(markText),
|
||||
setBookmark: setBookmark,
|
||||
+ findMarksAt: findMarksAt,
|
||||
setMarker: operation(addGutterMarker),
|
||||
clearMarker: operation(removeGutterMarker),
|
||||
setLineClass: operation(setLineClass),
|
||||
@@ -256,6 +271,7 @@ var CodeMirror = (function() {
|
||||
replaceRange: operation(replaceRange),
|
||||
getRange: function(from, to) {return getRange(clipPos(from), clipPos(to));},
|
||||
|
||||
+ triggerOnKeyDown: operation(onKeyDown),
|
||||
execCommand: function(cmd) {return commands[cmd](instance);},
|
||||
// Stuff used by commands, probably not much use to outside code.
|
||||
moveH: operation(moveH),
|
||||
@@ -373,7 +389,7 @@ var CodeMirror = (function() {
|
||||
!posLess(start, sel.from) && !posLess(sel.to, start)) {
|
||||
// Let the drag handler handle this.
|
||||
if (webkit) lineSpace.draggable = true;
|
||||
- var up = connect(targetDocument, "mouseup", operation(function(e2) {
|
||||
+ var up = connect(document, "mouseup", operation(function(e2) {
|
||||
if (webkit) lineSpace.draggable = false;
|
||||
draggingText = false;
|
||||
up();
|
||||
@@ -384,6 +400,8 @@ var CodeMirror = (function() {
|
||||
}
|
||||
}), true);
|
||||
draggingText = true;
|
||||
+ // IE's approach to draggable
|
||||
+ if (lineSpace.dragDrop) lineSpace.dragDrop();
|
||||
return;
|
||||
}
|
||||
e_preventDefault(e);
|
||||
@@ -402,12 +420,7 @@ var CodeMirror = (function() {
|
||||
}
|
||||
}
|
||||
|
||||
- var move = connect(targetDocument, "mousemove", operation(function(e) {
|
||||
- clearTimeout(going);
|
||||
- e_preventDefault(e);
|
||||
- extend(e);
|
||||
- }), true);
|
||||
- var up = connect(targetDocument, "mouseup", operation(function(e) {
|
||||
+ function done(e) {
|
||||
clearTimeout(going);
|
||||
var cur = posFromMouse(e);
|
||||
if (cur) setSelectionUser(start, cur);
|
||||
@@ -415,7 +428,14 @@ var CodeMirror = (function() {
|
||||
focusInput();
|
||||
updateInput = true;
|
||||
move(); up();
|
||||
+ }
|
||||
+ var move = connect(document, "mousemove", operation(function(e) {
|
||||
+ clearTimeout(going);
|
||||
+ e_preventDefault(e);
|
||||
+ if (!ie && !e_button(e)) done(e);
|
||||
+ else extend(e);
|
||||
}), true);
|
||||
+ var up = connect(document, "mouseup", operation(done), true);
|
||||
}
|
||||
function onDoubleClick(e) {
|
||||
for (var n = e_target(e); n != wrapper; n = n.parentNode)
|
||||
@@ -464,11 +484,14 @@ var CodeMirror = (function() {
|
||||
}
|
||||
function onDragStart(e) {
|
||||
var txt = getSelection();
|
||||
- // Disabled until further notice. Doesn't work on most browsers,
|
||||
- // and crashes Safari (issue #332).
|
||||
- //htmlEscape(txt);
|
||||
- //e.dataTransfer.setDragImage(escapeElement, 0, 0);
|
||||
e.dataTransfer.setData("Text", txt);
|
||||
+
|
||||
+ // Use dummy image instead of default browsers image.
|
||||
+ if (gecko || chrome) {
|
||||
+ var img = document.createElement('img');
|
||||
+ img.scr = 'data:image/gif;base64,R0lGODdhAgACAIAAAAAAAP///ywAAAAAAgACAAACAoRRADs='; //1x1 image
|
||||
+ e.dataTransfer.setDragImage(img, 0, 0);
|
||||
+ }
|
||||
}
|
||||
|
||||
function doHandleBinding(bound, dropShift) {
|
||||
@@ -506,13 +529,19 @@ var CodeMirror = (function() {
|
||||
if (e_prop(e, "ctrlKey")) name = "Ctrl-" + name;
|
||||
if (e_prop(e, "metaKey")) name = "Cmd-" + name;
|
||||
|
||||
- if (e_prop(e, "shiftKey"))
|
||||
+ if (e_prop(e, "shiftKey")) {
|
||||
handled = lookupKey("Shift-" + name, options.extraKeys, options.keyMap,
|
||||
- function(b) {return doHandleBinding(b, true);});
|
||||
- if (!handled)
|
||||
+ function(b) {return doHandleBinding(b, true);})
|
||||
+ || lookupKey(name, options.extraKeys, options.keyMap, function(b) {
|
||||
+ if (typeof b == "string" && /^go[A-Z]/.test(b)) return doHandleBinding(b);
|
||||
+ });
|
||||
+ } else {
|
||||
handled = lookupKey(name, options.extraKeys, options.keyMap, doHandleBinding);
|
||||
-
|
||||
- if (handled) e_preventDefault(e);
|
||||
+ }
|
||||
+ if (handled) {
|
||||
+ e_preventDefault(e);
|
||||
+ if (ie) { e.oldKeyCode = e.keyCode; e.keyCode = 0; }
|
||||
+ }
|
||||
return handled;
|
||||
}
|
||||
function handleCharBinding(e, ch) {
|
||||
@@ -545,7 +574,7 @@ var CodeMirror = (function() {
|
||||
if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
|
||||
var keyCode = e_prop(e, "keyCode"), charCode = e_prop(e, "charCode");
|
||||
if (window.opera && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
|
||||
- if (window.opera && !e.which && handleKeyBinding(e)) return;
|
||||
+ if (((window.opera && !e.which) || khtml) && handleKeyBinding(e)) return;
|
||||
var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
|
||||
if (options.electricChars && mode.electricChars && options.smartIndent && !options.readOnly) {
|
||||
if (mode.electricChars.indexOf(ch) > -1)
|
||||
@@ -837,11 +866,11 @@ var CodeMirror = (function() {
|
||||
return scrollIntoView(x, cursor.y, x, cursor.yBot);
|
||||
}
|
||||
function scrollIntoView(x1, y1, x2, y2) {
|
||||
- var pl = paddingLeft(), pt = paddingTop(), lh = textHeight();
|
||||
+ var pl = paddingLeft(), pt = paddingTop();
|
||||
y1 += pt; y2 += pt; x1 += pl; x2 += pl;
|
||||
var screen = scroller.clientHeight, screentop = scroller.scrollTop, scrolled = false, result = true;
|
||||
- if (y1 < screentop) {scroller.scrollTop = Math.max(0, y1 - 2*lh); scrolled = true;}
|
||||
- else if (y2 > screentop + screen) {scroller.scrollTop = y2 + lh - screen; scrolled = true;}
|
||||
+ if (y1 < screentop) {scroller.scrollTop = Math.max(0, y1); scrolled = true;}
|
||||
+ else if (y2 > screentop + screen) {scroller.scrollTop = y2 - screen; scrolled = true;}
|
||||
|
||||
var screenw = scroller.clientWidth, screenleft = scroller.scrollLeft;
|
||||
var gutterw = options.fixedGutter ? gutter.clientWidth : 0;
|
||||
@@ -921,7 +950,7 @@ var CodeMirror = (function() {
|
||||
throw new Error("BAD PATCH! " + JSON.stringify(intact) + " size=" + (showingTo - showingFrom) +
|
||||
" nodes=" + lineDiv.childNodes.length);
|
||||
|
||||
- if (options.lineWrapping) {
|
||||
+ function checkHeights() {
|
||||
maxWidth = scroller.clientWidth;
|
||||
var curNode = lineDiv.firstChild, heightChanged = false;
|
||||
doc.iter(showingFrom, showingTo, function(line) {
|
||||
@@ -936,6 +965,11 @@ var CodeMirror = (function() {
|
||||
});
|
||||
if (heightChanged)
|
||||
code.style.height = (doc.height * th + 2 * paddingTop()) + "px";
|
||||
+ return heightChanged;
|
||||
+ }
|
||||
+
|
||||
+ if (options.lineWrapping) {
|
||||
+ checkHeights();
|
||||
} else {
|
||||
if (maxWidth == null) maxWidth = stringWidth(maxLine);
|
||||
if (maxWidth > scroller.clientWidth) {
|
||||
@@ -947,8 +981,12 @@ var CodeMirror = (function() {
|
||||
lineSpace.style.width = code.style.width = "";
|
||||
}
|
||||
}
|
||||
+
|
||||
gutter.style.display = gutterDisplay;
|
||||
- if (different || gutterDirty) updateGutter();
|
||||
+ if (different || gutterDirty) {
|
||||
+ // If the gutter grew in size, re-check heights. If those changed, re-draw gutter.
|
||||
+ updateGutter() && options.lineWrapping && checkHeights() && updateGutter();
|
||||
+ }
|
||||
updateSelection();
|
||||
if (!suppressCallback && options.onUpdate) options.onUpdate(instance);
|
||||
return true;
|
||||
@@ -996,16 +1034,17 @@ var CodeMirror = (function() {
|
||||
}
|
||||
// This pass fills in the lines that actually changed.
|
||||
var nextIntact = intact.shift(), curNode = lineDiv.firstChild, j = from;
|
||||
- var scratch = targetDocument.createElement("div"), newElt;
|
||||
+ var scratch = document.createElement("div");
|
||||
doc.iter(from, to, function(line) {
|
||||
if (nextIntact && nextIntact.to == j) nextIntact = intact.shift();
|
||||
if (!nextIntact || nextIntact.from > j) {
|
||||
if (line.hidden) var html = scratch.innerHTML = "<pre></pre>";
|
||||
else {
|
||||
- var html = '<pre>' + line.getHTML(makeTab) + '</pre>';
|
||||
+ var html = '<pre' + (line.className ? ' class="' + line.className + '"' : '') + '>'
|
||||
+ + line.getHTML(makeTab) + '</pre>';
|
||||
// Kludge to make sure the styled element lies behind the selection (by z-index)
|
||||
- if (line.className)
|
||||
- html = '<div style="position: relative"><pre class="' + line.className +
|
||||
+ if (line.bgClassName)
|
||||
+ html = '<div style="position: relative"><pre class="' + line.bgClassName +
|
||||
'" style="position: absolute; left: 0; right: 0; top: 0; bottom: 0; z-index: -2"> </pre>' + html + "</div>";
|
||||
}
|
||||
scratch.innerHTML = html;
|
||||
@@ -1021,7 +1060,7 @@ var CodeMirror = (function() {
|
||||
if (!options.gutter && !options.lineNumbers) return;
|
||||
var hText = mover.offsetHeight, hEditor = scroller.clientHeight;
|
||||
gutter.style.height = (hText - hEditor < 2 ? hEditor : hText) + "px";
|
||||
- var html = [], i = showingFrom;
|
||||
+ var html = [], i = showingFrom, normalNode;
|
||||
doc.iter(showingFrom, Math.max(showingTo, showingFrom + 1), function(line) {
|
||||
if (line.hidden) {
|
||||
html.push("<pre></pre>");
|
||||
@@ -1035,17 +1074,24 @@ var CodeMirror = (function() {
|
||||
html.push((marker && marker.style ? '<pre class="' + marker.style + '">' : "<pre>"), text);
|
||||
for (var j = 1; j < line.height; ++j) html.push("<br/> ");
|
||||
html.push("</pre>");
|
||||
+ if (!marker) normalNode = i;
|
||||
}
|
||||
++i;
|
||||
});
|
||||
gutter.style.display = "none";
|
||||
gutterText.innerHTML = html.join("");
|
||||
- var minwidth = String(doc.size).length, firstNode = gutterText.firstChild, val = eltText(firstNode), pad = "";
|
||||
- while (val.length + pad.length < minwidth) pad += "\u00a0";
|
||||
- if (pad) firstNode.insertBefore(targetDocument.createTextNode(pad), firstNode.firstChild);
|
||||
+ // Make sure scrolling doesn't cause number gutter size to pop
|
||||
+ if (normalNode != null) {
|
||||
+ var node = gutterText.childNodes[normalNode - showingFrom];
|
||||
+ var minwidth = String(doc.size).length, val = eltText(node), pad = "";
|
||||
+ while (val.length + pad.length < minwidth) pad += "\u00a0";
|
||||
+ if (pad) node.insertBefore(document.createTextNode(pad), node.firstChild);
|
||||
+ }
|
||||
gutter.style.display = "";
|
||||
+ var resized = Math.abs((parseInt(lineSpace.style.marginLeft) || 0) - gutter.offsetWidth) > 2;
|
||||
lineSpace.style.marginLeft = gutter.offsetWidth + "px";
|
||||
gutterDirty = false;
|
||||
+ return resized;
|
||||
}
|
||||
function updateSelection() {
|
||||
var collapsed = posEq(sel.from, sel.to);
|
||||
@@ -1066,16 +1112,18 @@ var CodeMirror = (function() {
|
||||
html += '<div class="CodeMirror-selected" style="position: absolute; left: ' + left +
|
||||
'px; top: ' + top + 'px; right: ' + right + 'px; height: ' + height + 'px"></div>';
|
||||
}
|
||||
+ var clientWidth = lineSpace.clientWidth || lineSpace.offsetWidth;
|
||||
+ var clientHeight = lineSpace.clientHeight || lineSpace.offsetHeight;
|
||||
if (sel.from.ch && fromPos.y >= 0) {
|
||||
- var right = sameLine ? lineSpace.clientWidth - toPos.x : 0;
|
||||
+ var right = sameLine ? clientWidth - toPos.x : 0;
|
||||
add(fromPos.x, fromPos.y, right, th);
|
||||
}
|
||||
var middleStart = Math.max(0, fromPos.y + (sel.from.ch ? th : 0));
|
||||
- var middleHeight = Math.min(toPos.y, lineSpace.clientHeight) - middleStart;
|
||||
+ var middleHeight = Math.min(toPos.y, clientHeight) - middleStart;
|
||||
if (middleHeight > 0.2 * th)
|
||||
add(0, middleStart, 0, middleHeight);
|
||||
- if ((!sameLine || !sel.from.ch) && toPos.y < lineSpace.clientHeight - .5 * th)
|
||||
- add(0, toPos.y, lineSpace.clientWidth - toPos.x, th);
|
||||
+ if ((!sameLine || !sel.from.ch) && toPos.y < clientHeight - .5 * th)
|
||||
+ add(0, toPos.y, clientWidth - toPos.x, th);
|
||||
selectionDiv.innerHTML = html;
|
||||
cursor.style.display = "none";
|
||||
selectionDiv.style.display = "";
|
||||
@@ -1105,7 +1153,12 @@ var CodeMirror = (function() {
|
||||
if (posLess(to, from)) {var tmp = to; to = from; from = tmp;}
|
||||
|
||||
// Skip over hidden lines.
|
||||
- if (from.line != oldFrom) from = skipHidden(from, oldFrom, sel.from.ch);
|
||||
+ if (from.line != oldFrom) {
|
||||
+ var from1 = skipHidden(from, oldFrom, sel.from.ch);
|
||||
+ // If there is no non-hidden line left, force visibility on current line
|
||||
+ if (!from1) setLineHidden(from.line, false);
|
||||
+ else from = from1;
|
||||
+ }
|
||||
if (to.line != oldTo) to = skipHidden(to, oldTo, sel.to.ch);
|
||||
|
||||
if (posEq(from, to)) sel.inverted = false;
|
||||
@@ -1114,7 +1167,7 @@ var CodeMirror = (function() {
|
||||
|
||||
if (options.autoClearEmptyLines && posEq(sel.from, sel.to)) {
|
||||
var head = sel.inverted ? from : to;
|
||||
- if (head.line != sel.from.line) {
|
||||
+ if (head.line != sel.from.line && sel.from.line < doc.size) {
|
||||
var oldLine = getLine(sel.from.line);
|
||||
if (/^\s+$/.test(oldLine.text))
|
||||
setTimeout(operation(function() {
|
||||
@@ -1209,6 +1262,7 @@ var CodeMirror = (function() {
|
||||
if (unit == "page") dist = Math.min(scroller.clientHeight, window.innerHeight || document.documentElement.clientHeight);
|
||||
else if (unit == "line") dist = textHeight();
|
||||
var target = coordsChar(pos.x, pos.y + dist * dir + 2);
|
||||
+ if (unit == "page") scroller.scrollTop += localCoords(target, true).y - pos.y;
|
||||
setCursor(target.line, target.ch, true);
|
||||
goalColumn = pos.x;
|
||||
}
|
||||
@@ -1295,9 +1349,10 @@ var CodeMirror = (function() {
|
||||
changes.push({from: 0, to: doc.size});
|
||||
}
|
||||
function makeTab(col) {
|
||||
- var w = options.tabSize - col % options.tabSize;
|
||||
+ var w = options.tabSize - col % options.tabSize, cached = tabCache[w];
|
||||
+ if (cached) return cached;
|
||||
for (var str = '<span class="cm-tab">', i = 0; i < w; ++i) str += " ";
|
||||
- return {html: str + "</span>", width: w};
|
||||
+ return (tabCache[w] = {html: str + "</span>", width: w});
|
||||
}
|
||||
function themeChanged() {
|
||||
scroller.className = scroller.className.replace(/\s*cm-s-\w+/g, "") +
|
||||
@@ -1313,7 +1368,7 @@ var CodeMirror = (function() {
|
||||
var lineN = lineNo(line);
|
||||
min = Math.min(min, lineN); max = Math.max(max, lineN);
|
||||
for (var j = 0; j < mk.length; ++j)
|
||||
- if (mk[j].set == this.set) mk.splice(j--, 1);
|
||||
+ if (mk[j].marker == this) mk.splice(j--, 1);
|
||||
}
|
||||
if (min != Infinity)
|
||||
changes.push({from: min, to: max + 1});
|
||||
@@ -1324,7 +1379,7 @@ var CodeMirror = (function() {
|
||||
var line = this.set[i], mk = line.marked;
|
||||
for (var j = 0; j < mk.length; ++j) {
|
||||
var mark = mk[j];
|
||||
- if (mark.set == this.set) {
|
||||
+ if (mark.marker == this) {
|
||||
if (mark.from != null || mark.to != null) {
|
||||
var found = lineNo(line);
|
||||
if (found != null) {
|
||||
@@ -1341,8 +1396,9 @@ var CodeMirror = (function() {
|
||||
function markText(from, to, className) {
|
||||
from = clipPos(from); to = clipPos(to);
|
||||
var tm = new TextMarker();
|
||||
+ if (!posLess(from, to)) return tm;
|
||||
function add(line, from, to, className) {
|
||||
- getLine(line).addMark(new MarkedText(from, to, className, tm.set));
|
||||
+ getLine(line).addMark(new MarkedText(from, to, className, tm));
|
||||
}
|
||||
if (from.line == to.line) add(from.line, from.ch, to.ch, className);
|
||||
else {
|
||||
@@ -1362,6 +1418,19 @@ var CodeMirror = (function() {
|
||||
return bm;
|
||||
}
|
||||
|
||||
+ function findMarksAt(pos) {
|
||||
+ pos = clipPos(pos);
|
||||
+ var markers = [], marked = getLine(pos.line).marked;
|
||||
+ if (!marked) return markers;
|
||||
+ for (var i = 0, e = marked.length; i < e; ++i) {
|
||||
+ var m = marked[i];
|
||||
+ if ((m.from == null || m.from <= pos.ch) &&
|
||||
+ (m.to == null || m.to >= pos.ch))
|
||||
+ markers.push(m.marker || m);
|
||||
+ }
|
||||
+ return markers;
|
||||
+ }
|
||||
+
|
||||
function addGutterMarker(line, text, className) {
|
||||
if (typeof line == "number") line = getLine(clipLine(line));
|
||||
line.gutterMarker = {text: text, style: className};
|
||||
@@ -1383,10 +1452,11 @@ var CodeMirror = (function() {
|
||||
else return null;
|
||||
return line;
|
||||
}
|
||||
- function setLineClass(handle, className) {
|
||||
+ function setLineClass(handle, className, bgClassName) {
|
||||
return changeLine(handle, function(line) {
|
||||
- if (line.className != className) {
|
||||
+ if (line.className != className || line.bgClassName != bgClassName) {
|
||||
line.className = className;
|
||||
+ line.bgClassName = bgClassName;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@@ -1400,6 +1470,8 @@ var CodeMirror = (function() {
|
||||
if (hidden && (fline == no || tline == no)) {
|
||||
var from = fline == no ? skipHidden({line: fline, ch: 0}, fline, 0) : sel.from;
|
||||
var to = tline == no ? skipHidden({line: tline, ch: 0}, tline, 0) : sel.to;
|
||||
+ // Can't hide the last visible line, we'd have no place to put the cursor
|
||||
+ if (!to) return;
|
||||
setSelection(from, to);
|
||||
}
|
||||
return (gutterDirty = true);
|
||||
@@ -1420,7 +1492,7 @@ var CodeMirror = (function() {
|
||||
}
|
||||
var marker = line.gutterMarker;
|
||||
return {line: n, handle: line, text: line.text, markerText: marker && marker.text,
|
||||
- markerClass: marker && marker.style, lineClass: line.className};
|
||||
+ markerClass: marker && marker.style, lineClass: line.className, bgClass: line.bgClassName};
|
||||
}
|
||||
|
||||
function stringWidth(str) {
|
||||
@@ -1464,7 +1536,7 @@ var CodeMirror = (function() {
|
||||
var extra = "";
|
||||
// Include extra text at the end to make sure the measured line is wrapped in the right way.
|
||||
if (options.lineWrapping) {
|
||||
- var end = line.text.indexOf(" ", ch + 2);
|
||||
+ var end = line.text.indexOf(" ", ch + 6);
|
||||
extra = htmlEscape(line.text.slice(ch + 1, end < 0 ? line.text.length : end + (ie ? 5 : 0)));
|
||||
}
|
||||
measure.innerHTML = "<pre>" + line.getHTML(makeTab, ch) +
|
||||
@@ -1823,7 +1895,7 @@ var CodeMirror = (function() {
|
||||
pollInterval: 100,
|
||||
undoDepth: 40,
|
||||
tabindex: null,
|
||||
- document: window.document
|
||||
+ autofocus: null
|
||||
};
|
||||
|
||||
var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
|
||||
@@ -1831,7 +1903,7 @@ var CodeMirror = (function() {
|
||||
var win = /Win/.test(navigator.platform);
|
||||
|
||||
// Known modes, by name and by MIME
|
||||
- var modes = {}, mimeModes = {};
|
||||
+ var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
|
||||
CodeMirror.defineMode = function(name, mode) {
|
||||
if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
|
||||
modes[name] = mode;
|
||||
@@ -1842,6 +1914,8 @@ var CodeMirror = (function() {
|
||||
CodeMirror.resolveMode = function(spec) {
|
||||
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec))
|
||||
spec = mimeModes[spec];
|
||||
+ else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec))
|
||||
+ return CodeMirror.resolveMode("application/xml");
|
||||
if (typeof spec == "string") return {name: spec};
|
||||
else return spec || {name: "null"};
|
||||
};
|
||||
@@ -1926,7 +2000,7 @@ var CodeMirror = (function() {
|
||||
keyMap.basic = {
|
||||
"Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
|
||||
"End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
|
||||
- "Delete": "delCharRight", "Backspace": "delCharLeft", "Tab": "indentMore", "Shift-Tab": "indentLess",
|
||||
+ "Delete": "delCharRight", "Backspace": "delCharLeft", "Tab": "insertTab", "Shift-Tab": "indentAuto",
|
||||
"Enter": "newlineAndIndent", "Insert": "toggleOverwrite"
|
||||
};
|
||||
// Note that the save and find-related commands aren't defined by
|
||||
@@ -1937,6 +2011,7 @@ var CodeMirror = (function() {
|
||||
"Ctrl-Left": "goWordLeft", "Ctrl-Right": "goWordRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
|
||||
"Ctrl-Backspace": "delWordLeft", "Ctrl-Delete": "delWordRight", "Ctrl-S": "save", "Ctrl-F": "find",
|
||||
"Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
|
||||
+ "Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
|
||||
fallthrough: "basic"
|
||||
};
|
||||
keyMap.macDefault = {
|
||||
@@ -1945,6 +2020,7 @@ var CodeMirror = (function() {
|
||||
"Alt-Right": "goWordRight", "Cmd-Left": "goLineStart", "Cmd-Right": "goLineEnd", "Alt-Backspace": "delWordLeft",
|
||||
"Ctrl-Alt-Backspace": "delWordRight", "Alt-Delete": "delWordRight", "Cmd-S": "save", "Cmd-F": "find",
|
||||
"Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
|
||||
+ "Cmd-[": "indentLess", "Cmd-]": "indentMore",
|
||||
fallthrough: ["basic", "emacsy"]
|
||||
};
|
||||
keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
|
||||
@@ -1987,6 +2063,8 @@ var CodeMirror = (function() {
|
||||
options.value = textarea.value;
|
||||
if (!options.tabindex && textarea.tabindex)
|
||||
options.tabindex = textarea.tabindex;
|
||||
+ if (options.autofocus == null && textarea.getAttribute("autofocus") != null)
|
||||
+ options.autofocus = true;
|
||||
|
||||
function save() {textarea.value = instance.getValue();}
|
||||
if (textarea.form) {
|
||||
@@ -2098,34 +2176,34 @@ var CodeMirror = (function() {
|
||||
};
|
||||
CodeMirror.StringStream = StringStream;
|
||||
|
||||
- function MarkedText(from, to, className, set) {
|
||||
- this.from = from; this.to = to; this.style = className; this.set = set;
|
||||
+ function MarkedText(from, to, className, marker) {
|
||||
+ this.from = from; this.to = to; this.style = className; this.marker = marker;
|
||||
}
|
||||
MarkedText.prototype = {
|
||||
- attach: function(line) { this.set.push(line); },
|
||||
+ attach: function(line) { this.marker.set.push(line); },
|
||||
detach: function(line) {
|
||||
- var ix = indexOf(this.set, line);
|
||||
- if (ix > -1) this.set.splice(ix, 1);
|
||||
+ var ix = indexOf(this.marker.set, line);
|
||||
+ if (ix > -1) this.marker.set.splice(ix, 1);
|
||||
},
|
||||
split: function(pos, lenBefore) {
|
||||
if (this.to <= pos && this.to != null) return null;
|
||||
var from = this.from < pos || this.from == null ? null : this.from - pos + lenBefore;
|
||||
var to = this.to == null ? null : this.to - pos + lenBefore;
|
||||
- return new MarkedText(from, to, this.style, this.set);
|
||||
+ return new MarkedText(from, to, this.style, this.marker);
|
||||
},
|
||||
- dup: function() { return new MarkedText(null, null, this.style, this.set); },
|
||||
+ dup: function() { return new MarkedText(null, null, this.style, this.marker); },
|
||||
clipTo: function(fromOpen, from, toOpen, to, diff) {
|
||||
- if (this.from != null && this.from >= from)
|
||||
- this.from = Math.max(to, this.from) + diff;
|
||||
- if (this.to != null && this.to > from)
|
||||
- this.to = to < this.to ? this.to + diff : from;
|
||||
if (fromOpen && to > this.from && (to < this.to || this.to == null))
|
||||
this.from = null;
|
||||
+ else if (this.from != null && this.from >= from)
|
||||
+ this.from = Math.max(to, this.from) + diff;
|
||||
if (toOpen && (from < this.to || this.to == null) && (from > this.from || this.from == null))
|
||||
this.to = null;
|
||||
+ else if (this.to != null && this.to > from)
|
||||
+ this.to = to < this.to ? this.to + diff : from;
|
||||
},
|
||||
isDead: function() { return this.from != null && this.to != null && this.from >= this.to; },
|
||||
- sameSet: function(x) { return this.set == x.set; }
|
||||
+ sameSet: function(x) { return this.marker == x.marker; }
|
||||
};
|
||||
|
||||
function Bookmark(pos) {
|
||||
@@ -2168,7 +2246,7 @@ var CodeMirror = (function() {
|
||||
this.styles = styles || [text, null];
|
||||
this.text = text;
|
||||
this.height = 1;
|
||||
- this.marked = this.gutterMarker = this.className = this.handlers = null;
|
||||
+ this.marked = this.gutterMarker = this.className = this.bgClassName = this.handlers = null;
|
||||
this.stateAfter = this.parent = this.hidden = null;
|
||||
}
|
||||
Line.inheritMarks = function(text, orig) {
|
||||
@@ -2214,6 +2292,7 @@ var CodeMirror = (function() {
|
||||
if (newmark) {
|
||||
if (!taken.marked) taken.marked = [];
|
||||
taken.marked.push(newmark); newmark.attach(taken);
|
||||
+ if (newmark == mark) mk.splice(i--, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2637,10 +2716,10 @@ var CodeMirror = (function() {
|
||||
if (start < last.start) {
|
||||
for (var i = last.start - start - 1; i >= 0; --i)
|
||||
last.old.unshift(old[i]);
|
||||
- last.added += last.start - start;
|
||||
+ oldoff = Math.min(0, added - old.length);
|
||||
+ last.added += last.start - start + oldoff;
|
||||
last.start = start;
|
||||
- }
|
||||
- else if (last.start < start) {
|
||||
+ } else if (last.start < start) {
|
||||
oldoff = start - last.start;
|
||||
added += oldoff;
|
||||
}
|
||||
@@ -2707,19 +2786,21 @@ var CodeMirror = (function() {
|
||||
|
||||
var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}};
|
||||
|
||||
- // Detect drag-and-drop
|
||||
- var dragAndDrop = function() {
|
||||
- // IE8 has ondragstart and ondrop properties, but doesn't seem to
|
||||
- // actually support ondragstart the way it's supposed to work.
|
||||
- if (/MSIE [1-8]\b/.test(navigator.userAgent)) return false;
|
||||
- var div = document.createElement('div');
|
||||
- return "draggable" in div;
|
||||
- }();
|
||||
-
|
||||
var gecko = /gecko\/\d{7}/i.test(navigator.userAgent);
|
||||
var ie = /MSIE \d/.test(navigator.userAgent);
|
||||
var ie_lt9 = /MSIE [1-8]\b/.test(navigator.userAgent);
|
||||
var webkit = /WebKit\//.test(navigator.userAgent);
|
||||
+ var chrome = /Chrome\//.test(navigator.userAgent);
|
||||
+ var khtml = /KHTML\//.test(navigator.userAgent);
|
||||
+
|
||||
+ // Detect drag-and-drop
|
||||
+ var dragAndDrop = function() {
|
||||
+ // There is *some* kind of drag-and-drop support in IE6-8, but I
|
||||
+ // couldn't get it to work yet.
|
||||
+ if (ie_lt9) return false;
|
||||
+ var div = document.createElement('div');
|
||||
+ return "draggable" in div || "dragDrop" in div;
|
||||
+ }();
|
||||
|
||||
var lineSep = "\n";
|
||||
// Feature-detect whether newlines in textareas are converted to \r\n
|
||||
@@ -2873,7 +2954,7 @@ var CodeMirror = (function() {
|
||||
var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
|
||||
19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
|
||||
36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
|
||||
- 46: "Delete", 59: ";", 91: "Mod", 92: "Mod", 93: "Mod", 186: ";", 187: "=", 188: ",",
|
||||
+ 46: "Delete", 59: ";", 91: "Mod", 92: "Mod", 93: "Mod", 127: "Delete", 186: ";", 187: "=", 188: ",",
|
||||
189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", 221: "]", 222: "'", 63276: "PageUp",
|
||||
63277: "PageDown", 63275: "End", 63273: "Home", 63234: "Left", 63232: "Up", 63235: "Right",
|
||||
63233: "Down", 63302: "Insert", 63272: "Delete"};
|
||||
diff --git a/assets/codemirror/javascript.js b/assets/codemirror/javascript.js
|
||||
index b9388bc..462f486 100644
|
||||
--- a/assets/codemirror/javascript.js
|
||||
+++ b/assets/codemirror/javascript.js
|
||||
@@ -319,8 +319,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
kwAllowed: true,
|
||||
cc: [],
|
||||
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
|
||||
- localVars: null,
|
||||
- context: null,
|
||||
+ localVars: parserConfig.localVars,
|
||||
+ context: parserConfig.localVars && {vars: parserConfig.localVars},
|
||||
indented: 0
|
||||
};
|
||||
},
|
||||
@@ -334,7 +334,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
||||
if (stream.eatSpace()) return null;
|
||||
var style = state.tokenize(stream, state);
|
||||
if (type == "comment") return style;
|
||||
- state.reAllowed = type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/);
|
||||
+ state.reAllowed = !!(type == "operator" || type == "keyword c" || type.match(/^[\[{}\(,;:]$/));
|
||||
state.kwAllowed = type != '.';
|
||||
return parseJS(state, style, type, content, stream);
|
||||
},
|
42
node_modules/esprima/demo/checkenv.js
generated
vendored
42
node_modules/esprima/demo/checkenv.js
generated
vendored
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// Unfortunately we have to use User Agent detection to blacklist the browsers.
|
||||
/*jslint browser:true */
|
||||
(function (window) {
|
||||
'use strict';
|
||||
|
||||
var majorVersion = parseInt(window.platform.version.split('.')[0], 10);
|
||||
|
||||
window.checkEnv = function () {
|
||||
if (window.platform.name === 'Safari' && majorVersion <= 3) {
|
||||
throw new Error('CodeMirror does not support Safari <= 3');
|
||||
}
|
||||
if (window.platform.name === 'Opera' && majorVersion <= 8) {
|
||||
throw new Error('CodeMirror does not support Opera <= 8');
|
||||
}
|
||||
};
|
||||
|
||||
}(window));
|
||||
/* vim: set sw=4 ts=4 et tw=80 : */
|
82
node_modules/esprima/demo/collector.html
generated
vendored
82
node_modules/esprima/demo/collector.html
generated
vendored
@@ -1,82 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Esprima: Regex Collector Demo</title>
|
||||
<script src="../test/3rdparty/platform.js"></script>
|
||||
<script src="checkenv.js"></script>
|
||||
<script src="collector.js"></script>
|
||||
<script src="../esprima.js"></script>
|
||||
<script src="../assets/codemirror/codemirror.js"></script>
|
||||
<script src="../assets/codemirror/javascript.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../assets/codemirror/codemirror.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="../assets/style.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
||||
<div class="topbar">
|
||||
<ul class="nav">
|
||||
<li><a href="../index.html">← Home</a></li>
|
||||
<li><a href="http://github.com/ariya/esprima">Code</a></li>
|
||||
<li><a href="http://wiki.esprima.org">Documentation</a></li>
|
||||
<li><a href="http://issues.esprima.org">Issues</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h1>Regular Expression Collector <small>uncovers all your secrets</small></h1>
|
||||
|
||||
<p><strong>Note</strong>: Only regular expression literals and objects created with <code>RegExp</code> are considered.</p>
|
||||
<p>Type ECMAScript code:</p>
|
||||
<p><textarea id="code" autofocus="autofocus" cols="70" rows="15" spellcheck="false">
|
||||
var letterRE = new RegExp('[a-zA-Z]', 'g'),
|
||||
digitRE = RegExp('[0-9]');
|
||||
|
||||
|
||||
// This is from json2.js.
|
||||
|
||||
if (/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
|
||||
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
|
||||
.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
|
||||
}
|
||||
</textarea></p>
|
||||
<p id="codemirror" align="right"><small>The above code editor is based on <a href="http://codemirror.net" target="_blank">CodeMirror</a>.</small></p>
|
||||
|
||||
<p>Using Esprima version <span id="version"></span>.</p>
|
||||
|
||||
<div id="result">
|
||||
</div>
|
||||
|
||||
<div class="footer"><strong>Esprima</strong> is created by
|
||||
<a href="http://ariya.ofilabs.com/about" target="_blank">Ariya Hidayat</a>. Follow <a href="http://twitter.com/ariyahidayat">@ariyahidayat</a> on Twitter.
|
||||
</div>
|
||||
|
||||
<p id="testbox" style="visibility: hidden;"><textarea id="test"></textarea></p>
|
||||
</div>
|
||||
<script>
|
||||
/*jslint sloppy:true browser:true */
|
||||
/*global collectRegex:true, CodeMirror:true */
|
||||
window.onload = collectRegex;
|
||||
|
||||
try {
|
||||
window.checkEnv();
|
||||
|
||||
// This is just testing, to detect whether CodeMirror would fail or not
|
||||
window.editor = CodeMirror.fromTextArea(document.getElementById("test"));
|
||||
|
||||
window.editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
onChange: collectRegex
|
||||
});
|
||||
} catch (e) {
|
||||
// CodeMirror failed to initialize, possible in e.g. old IE.
|
||||
document.getElementById('codemirror').innerHTML = '';
|
||||
document.getElementById('code').onchange = collectRegex;
|
||||
document.getElementById('code').onkeydown = collectRegex;
|
||||
} finally {
|
||||
document.getElementById('testbox').parentNode.removeChild(document.getElementById('testbox'));
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
170
node_modules/esprima/demo/collector.js
generated
vendored
170
node_modules/esprima/demo/collector.js
generated
vendored
@@ -1,170 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*jslint browser:true */
|
||||
|
||||
var timerId;
|
||||
|
||||
function collectRegex() {
|
||||
'use strict';
|
||||
|
||||
function id(i) {
|
||||
return document.getElementById(i);
|
||||
}
|
||||
|
||||
function escaped(str) {
|
||||
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
||||
}
|
||||
|
||||
function setText(id, str) {
|
||||
var el = document.getElementById(id);
|
||||
if (typeof el.innerText === 'string') {
|
||||
el.innerText = str;
|
||||
} else {
|
||||
el.textContent = str;
|
||||
}
|
||||
}
|
||||
|
||||
function isLineTerminator(ch) {
|
||||
return (ch === '\n' || ch === '\r' || ch === '\u2028' || ch === '\u2029');
|
||||
}
|
||||
|
||||
function process(delay) {
|
||||
if (timerId) {
|
||||
window.clearTimeout(timerId);
|
||||
}
|
||||
|
||||
timerId = window.setTimeout(function () {
|
||||
var code, result, i, str;
|
||||
|
||||
if (typeof window.editor === 'undefined') {
|
||||
code = document.getElementById('code').value;
|
||||
} else {
|
||||
code = window.editor.getValue();
|
||||
}
|
||||
|
||||
// Executes f on the object and its children (recursively).
|
||||
function visit(object, f) {
|
||||
var key, child;
|
||||
|
||||
if (f.call(null, object) === false) {
|
||||
return;
|
||||
}
|
||||
for (key in object) {
|
||||
if (object.hasOwnProperty(key)) {
|
||||
child = object[key];
|
||||
if (typeof child === 'object' && child !== null) {
|
||||
visit(child, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createRegex(pattern, mode) {
|
||||
var literal;
|
||||
try {
|
||||
literal = new RegExp(pattern, mode);
|
||||
} catch (e) {
|
||||
// Invalid regular expression.
|
||||
return;
|
||||
}
|
||||
return literal;
|
||||
}
|
||||
|
||||
function collect(node) {
|
||||
var str, arg, value;
|
||||
if (node.type === 'Literal') {
|
||||
if (node.value instanceof RegExp) {
|
||||
str = node.value.toString();
|
||||
if (str[0] === '/') {
|
||||
result.push({
|
||||
type: 'Literal',
|
||||
value: node.value,
|
||||
line: node.loc.start.line,
|
||||
column: node.loc.start.column
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node.type === 'NewExpression' || node.type === 'CallExpression') {
|
||||
if (node.callee.type === 'Identifier' && node.callee.name === 'RegExp') {
|
||||
arg = node['arguments'];
|
||||
if (arg.length === 1 && arg[0].type === 'Literal') {
|
||||
if (typeof arg[0].value === 'string') {
|
||||
value = createRegex(arg[0].value);
|
||||
if (value) {
|
||||
result.push({
|
||||
type: 'Literal',
|
||||
value: value,
|
||||
line: node.loc.start.line,
|
||||
column: node.loc.start.column
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (arg.length === 2 && arg[0].type === 'Literal' && arg[1].type === 'Literal') {
|
||||
if (typeof arg[0].value === 'string' && typeof arg[1].value === 'string') {
|
||||
value = createRegex(arg[0].value, arg[1].value);
|
||||
if (value) {
|
||||
result.push({
|
||||
type: 'Literal',
|
||||
value: value,
|
||||
line: node.loc.start.line,
|
||||
column: node.loc.start.column
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
result = [];
|
||||
visit(window.esprima.parse(code, { loc: true }), collect);
|
||||
|
||||
if (result.length > 0) {
|
||||
str = '<p>Found <b>' + result.length + '</b> regex(s):</p>';
|
||||
for (i = 0; i < result.length; i += 1) {
|
||||
str += '<p>' + 'Line ' + result[i].line;
|
||||
str += ' column ' + (1 + result[i].column);
|
||||
str += ': <code>'; str += escaped(result[i].value.toString()) + '</code>';
|
||||
str += '</p>';
|
||||
}
|
||||
id('result').innerHTML = str;
|
||||
} else {
|
||||
setText('result', 'No regex.');
|
||||
}
|
||||
} catch (e) {
|
||||
setText('result', e.toString());
|
||||
}
|
||||
|
||||
timerId = undefined;
|
||||
}, delay || 811);
|
||||
}
|
||||
|
||||
setText('version', window.esprima.version);
|
||||
process(1);
|
||||
}
|
||||
/* vim: set sw=4 ts=4 et tw=80 : */
|
106
node_modules/esprima/demo/functiontrace.html
generated
vendored
106
node_modules/esprima/demo/functiontrace.html
generated
vendored
@@ -1,106 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Esprima: Function Trace Demo</title>
|
||||
<script src="../test/3rdparty/platform.js"></script>
|
||||
<script src="checkenv.js"></script>
|
||||
<script src="functiontrace.js"></script>
|
||||
<script src="../esprima.js"></script>
|
||||
<script src="../test/3rdparty/esmorph.js"></script>
|
||||
<script src="../assets/codemirror/codemirror.js"></script>
|
||||
<script src="../assets/codemirror/javascript.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../assets/codemirror/codemirror.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="../assets/style.css"/>
|
||||
<style>
|
||||
.CodeMirror-scroll {
|
||||
height: 300px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
||||
<div class="topbar">
|
||||
<ul class="nav">
|
||||
<li><a href="../index.html">← Home</a></li>
|
||||
<li><a href="http://github.com/ariya/esprima">Code</a></li>
|
||||
<li><a href="http://wiki.esprima.org">Documentation</a></li>
|
||||
<li><a href="http://issues.esprima.org">Issues</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h1>Function Trace <small>reveals what is being called</small></h1>
|
||||
|
||||
<p>Type ECMAScript code:</p>
|
||||
<p><textarea id="code" autofocus="autofocus" cols="70" rows="25" spellcheck="false">
|
||||
Array.prototype.swap = function (i, j) {
|
||||
var k = this[i]; this[i] = this[j]; this[j] = k;
|
||||
}
|
||||
|
||||
function bubbleSort(list) {
|
||||
var items = list.slice(0), swapped = false, p, q;
|
||||
for (p = 1; p < items.length; ++p) {
|
||||
for (q = 0; q < items.length - p; ++q) {
|
||||
if (items[q + 1] < items[q]) {
|
||||
items.swap(q, q + 1);
|
||||
swapped =true;
|
||||
}
|
||||
}
|
||||
if (!swapped) break;
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
var N = 100, data = []; while (N > 0) data.push(N--);
|
||||
|
||||
bubbleSort(data);
|
||||
</textarea></p>
|
||||
<p id="codemirror" align="right"><small>The above code editor is based on <a href="http://codemirror.net" target="_blank">CodeMirror</a>.</small></p>
|
||||
|
||||
<p><input type="button" value="Run" id="run"></p>
|
||||
|
||||
<div id="result"><p>No result yet.</p></div>
|
||||
|
||||
<p style="margin-top: 50px;">Using Esprima version <span id="version"></span>.</p>
|
||||
<div class="footer"><strong>Esprima</strong> is created by
|
||||
<a href="http://ariya.ofilabs.com/about" target="_blank">Ariya Hidayat</a>. Follow <a href="http://twitter.com/ariyahidayat">@ariyahidayat</a> on Twitter.
|
||||
</div>
|
||||
|
||||
<p id="testbox" style="visibility: hidden;"><textarea id="test"></textarea></p>
|
||||
</div>
|
||||
<script>
|
||||
/*jslint sloppy:true browser:true */
|
||||
/*global traceRun:true, CodeMirror:true */
|
||||
window.onload = function () {
|
||||
var el;
|
||||
|
||||
el = document.getElementById('version');
|
||||
if (typeof el.innerText === 'string') {
|
||||
el.innerText = window.esprima.version;
|
||||
} else {
|
||||
el.textContent = window.esprima.version;
|
||||
}
|
||||
|
||||
document.getElementById('run').onclick = traceRun;
|
||||
};
|
||||
|
||||
try {
|
||||
window.checkEnv();
|
||||
|
||||
// This is just testing, to detect whether CodeMirror would fail or not
|
||||
window.editor = CodeMirror.fromTextArea(document.getElementById("test"));
|
||||
|
||||
window.editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true
|
||||
});
|
||||
} catch (e) {
|
||||
// CodeMirror failed to initialize, possible in e.g. old IE.
|
||||
document.getElementById('codemirror').innerHTML = '';
|
||||
} finally {
|
||||
document.getElementById('testbox').parentNode.removeChild(document.getElementById('testbox'));
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
123
node_modules/esprima/demo/functiontrace.js
generated
vendored
123
node_modules/esprima/demo/functiontrace.js
generated
vendored
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*jslint browser:true evil:true */
|
||||
|
||||
var timerId;
|
||||
|
||||
function traceRun() {
|
||||
'use strict';
|
||||
|
||||
var lookup;
|
||||
|
||||
function id(i) {
|
||||
return document.getElementById(i);
|
||||
}
|
||||
|
||||
function escaped(str) {
|
||||
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
||||
}
|
||||
|
||||
function setText(id, str) {
|
||||
var el = document.getElementById(id);
|
||||
if (typeof el.innerText === 'string') {
|
||||
el.innerText = str;
|
||||
} else {
|
||||
el.textContent = str;
|
||||
}
|
||||
}
|
||||
|
||||
function isLineTerminator(ch) {
|
||||
return (ch === '\n' || ch === '\r' || ch === '\u2028' || ch === '\u2029');
|
||||
}
|
||||
|
||||
function insertTracer() {
|
||||
var tracer, code, i, functionList, signature, pos;
|
||||
|
||||
if (typeof window.editor === 'undefined') {
|
||||
code = document.getElementById('code').value;
|
||||
} else {
|
||||
code = window.editor.getValue();
|
||||
}
|
||||
|
||||
tracer = window.esmorph.Tracer.FunctionEntrance('window.TRACE.enterFunction');
|
||||
code = window.esmorph.modify(code, tracer);
|
||||
|
||||
// Enclose in IIFE.
|
||||
code = '(function() {\n' + code + '\n}())';
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
function showResult() {
|
||||
var i, str, histogram, entry;
|
||||
|
||||
histogram = window.TRACE.getHistogram();
|
||||
|
||||
str = '<table><thead><tr><td>Function</td><td>Hits</td></tr></thead>';
|
||||
for (i = 0; i < histogram.length; i += 1) {
|
||||
entry = histogram[i];
|
||||
str += '<tr>';
|
||||
str += '<td>' + entry.name + '</td>';
|
||||
str += '<td>' + entry.count + '</td>';
|
||||
str += '</tr>';
|
||||
}
|
||||
str += '</table>';
|
||||
|
||||
id('result').innerHTML = str;
|
||||
}
|
||||
|
||||
window.TRACE = {
|
||||
hits: {},
|
||||
enterFunction: function (info) {
|
||||
var key = info.name + ' at line ' + info.lineNumber;
|
||||
if (this.hits.hasOwnProperty(key)) {
|
||||
this.hits[key] = this.hits[key] + 1;
|
||||
} else {
|
||||
this.hits[key] = 1;
|
||||
}
|
||||
},
|
||||
getHistogram: function () {
|
||||
var entry,
|
||||
sorted = [];
|
||||
for (entry in this.hits) {
|
||||
if (this.hits.hasOwnProperty(entry)) {
|
||||
sorted.push({ name: entry, count: this.hits[entry]});
|
||||
}
|
||||
}
|
||||
sorted.sort(function (a, b) {
|
||||
return b.count - a.count;
|
||||
});
|
||||
return sorted;
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
eval(insertTracer());
|
||||
showResult();
|
||||
} catch (e) {
|
||||
id('result').innerText = e.toString();
|
||||
}
|
||||
}
|
||||
/* vim: set sw=4 ts=4 et tw=80 : */
|
82
node_modules/esprima/demo/parse.css
generated
vendored
82
node_modules/esprima/demo/parse.css
generated
vendored
@@ -1,82 +0,0 @@
|
||||
.tabs textarea {
|
||||
padding: 7px 0px 7px 7px;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
position: relative;
|
||||
display: block;
|
||||
margin-top: 30px;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
.tabs ul, .tabs li {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
line-height: 0px;
|
||||
}
|
||||
|
||||
.tabs h3 {
|
||||
float: left;
|
||||
position: relative;
|
||||
margin: 0 6px 0 0;
|
||||
border: 1px solid #bbb;
|
||||
background-color: #eee;
|
||||
border-bottom: none;
|
||||
cursor: pointer;
|
||||
z-index: 0;
|
||||
-moz-border-radius-topleft: 6px;
|
||||
-webkit-border-top-left-radius: 6px;
|
||||
-ms-border-top-left-radius: 6px;
|
||||
-o-border-top-left-radius: 6px;
|
||||
border-top-left-radius: 6px;
|
||||
-moz-border-radius-topright: 6px;
|
||||
-webkit-border-top-right-radius: 6px;
|
||||
-ms-border-top-right-radius: 6px;
|
||||
-o-border-top-right-radius: 6px;
|
||||
border-top-right-radius: 6px
|
||||
}
|
||||
|
||||
.tabs .active h3 {
|
||||
background-color: #fff;
|
||||
border-bottom-color: #fff;
|
||||
z-index: 2
|
||||
}
|
||||
|
||||
.tabs h3 a {
|
||||
padding: 0 10px;
|
||||
line-height: 29px;
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.tabs a {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.tabs a:visited {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.tabs .tab {
|
||||
position: absolute;
|
||||
display: none;
|
||||
left: 0;
|
||||
top: 29px;
|
||||
right: 0;
|
||||
border-top: 1px solid #bbb;
|
||||
z-index: 1;
|
||||
padding: 25px 60px 50px 5px;
|
||||
}
|
||||
|
||||
.pages div {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pages div.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tabs .active .tab {
|
||||
display: block;
|
||||
}
|
352
node_modules/esprima/demo/parse.html
generated
vendored
352
node_modules/esprima/demo/parse.html
generated
vendored
@@ -1,352 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Esprima: Parsing Demo</title>
|
||||
<script src="../test/3rdparty/platform.js"></script>
|
||||
<script src="checkenv.js"></script>
|
||||
<script src="../esprima.js"></script>
|
||||
<script src="../assets/json2.js"></script>
|
||||
<script src="../assets/codemirror/codemirror.js"></script>
|
||||
<script src="../assets/codemirror/javascript.js"></script>
|
||||
<script src="../assets/yui/yahoo-dom-event.js"></script>
|
||||
<script src="../assets/yui/treeview-min.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../assets/codemirror/codemirror.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="../assets/yui/treeview.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="../assets/style.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="parse.css"/>
|
||||
<style>
|
||||
.ygtvfocus .ygtvlabel,
|
||||
.ygtvfocus .ygtvlabel:link,
|
||||
.ygtvfocus .ygtvlabel:visited,
|
||||
.ygtvfocus .ygtvlabel:hover {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
table th, table td {
|
||||
text-align: left;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
tbody tr:nth-child(odd) td {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
tbody td {
|
||||
background-color: white;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
/*jslint sloppy:true browser:true */
|
||||
/*global esprima:true, YAHOO:true */
|
||||
var parseId;
|
||||
|
||||
function updateTree(syntax) {
|
||||
|
||||
if (window.tree) {
|
||||
window.tree.destroy();
|
||||
window.tree = null;
|
||||
}
|
||||
|
||||
if (typeof syntax === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (document.getElementById('tab_tree').className !== 'active') {
|
||||
return;
|
||||
}
|
||||
|
||||
window.tree = new YAHOO.widget.TreeView("treeview");
|
||||
document.getElementById('collapse').onclick = function () { window.tree.collapseAll(); };
|
||||
document.getElementById('expand').onclick = function () { window.tree.expandAll(); };
|
||||
|
||||
function isArray(o) {
|
||||
return (typeof Array.isArray === 'function') ? Array.isArray(o) :
|
||||
Object.prototype.toString.apply(o) === '[object Array]';
|
||||
}
|
||||
|
||||
function convert(name, node) {
|
||||
var result, i, key, value, child;
|
||||
|
||||
switch (typeof node) {
|
||||
case 'string':
|
||||
return {
|
||||
type: 'Text',
|
||||
label: name + ': ' + node
|
||||
};
|
||||
|
||||
case 'number':
|
||||
case 'boolean':
|
||||
return {
|
||||
type: 'Text',
|
||||
label: name + ': ' + String(node)
|
||||
};
|
||||
|
||||
case 'object':
|
||||
if (!node) {
|
||||
return {
|
||||
type: 'Text',
|
||||
label: name + ': null'
|
||||
};
|
||||
}
|
||||
if (node instanceof RegExp) {
|
||||
return {
|
||||
type: 'Text',
|
||||
label: name + ': ' + node.toString()
|
||||
};
|
||||
}
|
||||
result = {
|
||||
type: 'Text',
|
||||
label: name,
|
||||
expanded: true,
|
||||
children: []
|
||||
};
|
||||
if (isArray(node)) {
|
||||
if (node.length === 2 && name === 'range') {
|
||||
result.label = name + ': [' + node[0] + ', ' + node[1] + ']';
|
||||
} else {
|
||||
result.label = result.label + ' [' + node.length + ']';
|
||||
for (i = 0; i < node.length; i += 1) {
|
||||
key = String(i);
|
||||
value = node[i];
|
||||
child = convert(key, value);
|
||||
if (isArray(child.children) && child.children.length === 1) {
|
||||
result.children.push(child.children[0]);
|
||||
} else {
|
||||
result.children.push(convert(key, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (typeof node.type !== 'undefined') {
|
||||
result.children.push({
|
||||
type: 'Text',
|
||||
label: node.type,
|
||||
expanded: true,
|
||||
children: []
|
||||
});
|
||||
for (key in node) {
|
||||
if (Object.prototype.hasOwnProperty.call(node, key)) {
|
||||
if (key !== 'type') {
|
||||
value = node[key];
|
||||
result.children[0].children.push(convert(key, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (key in node) {
|
||||
if (Object.prototype.hasOwnProperty.call(node, key)) {
|
||||
value = node[key];
|
||||
result.children.push(convert(key, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'Text',
|
||||
label: '?'
|
||||
};
|
||||
}
|
||||
|
||||
window.tree.buildTreeFromObject(convert('Program body', syntax.body));
|
||||
window.tree.render();
|
||||
}
|
||||
|
||||
function parse(delay) {
|
||||
if (parseId) {
|
||||
window.clearTimeout(parseId);
|
||||
}
|
||||
|
||||
parseId = window.setTimeout(function () {
|
||||
var code, options, result, el, str;
|
||||
|
||||
// Special handling for regular expression literal since we need to
|
||||
// convert it to a string literal, otherwise it will be decoded
|
||||
// as object "{}" and the regular expression would be lost.
|
||||
function adjustRegexLiteral(key, value) {
|
||||
if (key === 'value' && value instanceof RegExp) {
|
||||
value = value.toString();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
if (typeof window.editor === 'undefined') {
|
||||
code = document.getElementById('code').value;
|
||||
} else {
|
||||
code = window.editor.getValue();
|
||||
}
|
||||
options = {
|
||||
comment: document.getElementById('comment').checked,
|
||||
raw: document.getElementById('raw').checked,
|
||||
range: document.getElementById('range').checked,
|
||||
loc: document.getElementById('loc').checked
|
||||
};
|
||||
|
||||
document.getElementById('tokens').value = '';
|
||||
|
||||
try {
|
||||
|
||||
result = esprima.parse(code, options);
|
||||
str = JSON.stringify(result, adjustRegexLiteral, 4);
|
||||
document.getElementById('tokens').value = JSON.stringify(esprima.parse(code,
|
||||
{ tokens : true }).tokens, adjustRegexLiteral, 4);
|
||||
updateTree(result);
|
||||
} catch (e) {
|
||||
updateTree();
|
||||
str = e.name + ': ' + e.message;
|
||||
}
|
||||
|
||||
el = document.getElementById('syntax');
|
||||
el.value = str;
|
||||
|
||||
parseId = undefined;
|
||||
}, delay || 811);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body class="yui-skin-sam">
|
||||
<div class="container">
|
||||
|
||||
<div class="topbar">
|
||||
<ul class="nav">
|
||||
<li><a href="../index.html">← Home</a></li>
|
||||
<li><a href="http://github.com/ariya/esprima">Code</a></li>
|
||||
<li><a href="http://wiki.esprima.org">Documentation</a></li>
|
||||
<li><a href="http://issues.esprima.org">Issues</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h1>Parser <small>produces syntax tree</small></h1>
|
||||
|
||||
<p>Esprima version <span id="version"></span>.</p>
|
||||
|
||||
<p>Type ECMAScript code:</p>
|
||||
<p><textarea id="code" autofocus="autofocus" cols="70" rows="15" spellcheck="false">
|
||||
// Life, Universe, and Everything
|
||||
var answer = 6 * 7;</textarea></p>
|
||||
<p id="codemirror" align="right"><small>The above code editor is based on <a href="http://codemirror.net" target="_blank">CodeMirror</a>.</small></p>
|
||||
<p><label><input type="checkbox" id="raw"> Preserve raw value of literals</label></p>
|
||||
<p><label><input type="checkbox" id="comment"> Include comments</label></p>
|
||||
<p> Syntax node location info (start, end)</p>
|
||||
<div style="margin-left: 20px;">
|
||||
<p><label><input type="checkbox" id="range">Index-based range</label></p>
|
||||
<p><label><input type="checkbox" id="loc">Line and column-based</label></p>
|
||||
</div>
|
||||
<div class="tabs">
|
||||
<ul>
|
||||
<li id="tab_syntax" class="active">
|
||||
<h3><a id="show_syntax">Syntax</a></h3>
|
||||
<div class="tab">
|
||||
<textarea id="syntax" rows="20" readonly></textarea>
|
||||
</div>
|
||||
</li>
|
||||
<li id="tab_tokens">
|
||||
<h3><a id="show_tokens">Tokens</a></h3>
|
||||
<div class="tab">
|
||||
<textarea id="tokens" rows="20" readonly></textarea>
|
||||
</div>
|
||||
</li>
|
||||
<li id="tab_tree">
|
||||
<h3><a id="show_tree">Tree</a></h3>
|
||||
<div class="tab">
|
||||
<span style="margin-left: 500px;"><input type="button" id="expand" value="Expand All">
|
||||
<input type="button" id="collapse" value="Collapse All"></span>
|
||||
<div id="treeview">
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<!--
|
||||
<div class="footer"><strong>Esprima</strong> is created by
|
||||
<a href="http://ariya.ofilabs.com/about" target="_blank">Ariya Hidayat</a>. Follow <a href="http://twitter.com/ariyahidayat">@ariyahidayat</a> on Twitter.
|
||||
</div>
|
||||
-->
|
||||
|
||||
<p id="testbox"><textarea id="test"></textarea></p>
|
||||
</div>
|
||||
<script>
|
||||
window.onload = function () {
|
||||
var id, el;
|
||||
|
||||
id = function (i) {
|
||||
return document.getElementById(i);
|
||||
};
|
||||
|
||||
el = id('version');
|
||||
if (typeof el.innerText === 'string') {
|
||||
el.innerText = esprima.version;
|
||||
} else {
|
||||
el.textContent = esprima.version;
|
||||
}
|
||||
try {
|
||||
parse(1);
|
||||
} catch (e) { }
|
||||
|
||||
id('show_tree').onclick = function () {
|
||||
id('tab_tree').className = 'active';
|
||||
id('tab_syntax').className = '';
|
||||
id('tab_tokens').className = '';
|
||||
parse(1);
|
||||
};
|
||||
|
||||
id('show_syntax').onclick = function () {
|
||||
id('tab_tree').className = '';
|
||||
id('tab_syntax').className = 'active';
|
||||
id('tab_tokens').className = '';
|
||||
};
|
||||
|
||||
id('show_tokens').onclick = function () {
|
||||
id('tab_tree').className = '';
|
||||
id('tab_syntax').className = '';
|
||||
id('tab_tokens').className = 'active';
|
||||
};
|
||||
};
|
||||
</script>
|
||||
<script>
|
||||
/*jslint sloppy:true browser:true */
|
||||
/*global CodeMirror:true */
|
||||
try {
|
||||
function quickParse() { parse(1); }
|
||||
document.getElementById('comment').onchange = quickParse;
|
||||
document.getElementById('raw').onchange = quickParse;
|
||||
document.getElementById('range').onchange = quickParse;
|
||||
document.getElementById('loc').onchange = quickParse;
|
||||
document.getElementById('tokens').onchange = quickParse;
|
||||
|
||||
// Special handling for IE.
|
||||
document.getElementById('comment').onclick = quickParse;
|
||||
document.getElementById('raw').onclick = quickParse;
|
||||
document.getElementById('range').onclick = quickParse;
|
||||
document.getElementById('loc').onclick = quickParse;
|
||||
document.getElementById('tokens').onclick = quickParse;
|
||||
|
||||
window.checkEnv();
|
||||
|
||||
// This is just testing, to detect whether CodeMirror would fail or not
|
||||
window.editor = CodeMirror.fromTextArea(document.getElementById("test"));
|
||||
|
||||
window.editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true,
|
||||
onChange: parse
|
||||
});
|
||||
} catch (e) {
|
||||
// CodeMirror failed to initialize, possible in e.g. old IE.
|
||||
document.getElementById('codemirror').innerHTML = '';
|
||||
document.getElementById('code').onchange = parse;
|
||||
document.getElementById('code').onkeydown = parse;
|
||||
} finally {
|
||||
document.getElementById('testbox').parentNode.removeChild(document.getElementById('testbox'));
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
225
node_modules/esprima/demo/precedence.html
generated
vendored
225
node_modules/esprima/demo/precedence.html
generated
vendored
@@ -1,225 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Esprima: Operator Precedence Demo</title>
|
||||
<script src="../esprima.js"></script>
|
||||
<script src="../assets/json2.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../assets/style.css"/>
|
||||
<style>
|
||||
#a, #b, #expr {
|
||||
font-size: 16px;
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
#expr {
|
||||
border: none;
|
||||
}
|
||||
|
||||
#answer {
|
||||
color: white;
|
||||
padding: 5px;
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.yes {
|
||||
background-color: #228B22;
|
||||
}
|
||||
|
||||
.no {
|
||||
background-color: #8B2500;
|
||||
}
|
||||
|
||||
.lightred {
|
||||
background-color: #FFC0CB;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
/*jslint sloppy:true browser:true */
|
||||
/*global esprima:true */
|
||||
var compareId;
|
||||
function compare() {
|
||||
if (compareId) {
|
||||
window.clearTimeout(compareId);
|
||||
}
|
||||
|
||||
function stringify(node) {
|
||||
var result;
|
||||
|
||||
if (typeof node !== 'object') {
|
||||
throw new Error('Node is not valid');
|
||||
}
|
||||
if (typeof node.type !== 'string') {
|
||||
throw new Error('Node does not have type property');
|
||||
}
|
||||
|
||||
switch (node.type) {
|
||||
|
||||
case 'Program':
|
||||
if (node.body.length !== 1) {
|
||||
throw new Error('Expression is too complex');
|
||||
}
|
||||
result = stringify(node.body[0]);
|
||||
if (result[0] === '(' && result[result.length - 1] === ')') {
|
||||
result = result.substr(1, result.length - 2);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'ExpressionStatement':
|
||||
result = stringify(node.expression);
|
||||
break;
|
||||
|
||||
case 'BinaryExpression':
|
||||
case 'LogicalExpression':
|
||||
result = '(' + stringify(node.left) + ' ' + node.operator + ' ' + stringify(node.right) + ')';
|
||||
break;
|
||||
|
||||
case 'UnaryExpression':
|
||||
result = '(' + node.operator;
|
||||
if (node.operator.length > 2) {
|
||||
// delete void typeof
|
||||
result += ' ';
|
||||
}
|
||||
result += stringify(node.argument) + ')';
|
||||
break;
|
||||
|
||||
case 'UpdateExpression':
|
||||
result = stringify(node.argument);
|
||||
if (node.prefix) {
|
||||
result = node.operator + result;
|
||||
} else {
|
||||
result = result + node.operator;
|
||||
}
|
||||
result = '(' + result + ')';
|
||||
break;
|
||||
|
||||
case 'Literal':
|
||||
result = node.value.toString();
|
||||
if (typeof node.value === 'string') {
|
||||
result = '"' + node.value + '"';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Identifier':
|
||||
result = node.name;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Unknown node type: ' + node.type);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function setText(el, str) {
|
||||
if (typeof el.innerText === 'string') {
|
||||
el.innerText = str;
|
||||
} else {
|
||||
el.textContent = str;
|
||||
}
|
||||
}
|
||||
|
||||
compareId = window.setTimeout(function () {
|
||||
var a, b, answer, status, expr, left, right, suggest;
|
||||
|
||||
a = document.getElementById('a');
|
||||
b = document.getElementById('b');
|
||||
answer = document.getElementById('answer');
|
||||
status = document.getElementById('status');
|
||||
expr = document.getElementById('expr');
|
||||
|
||||
a.setAttribute('class', '');
|
||||
b.setAttribute('class', '');
|
||||
answer.setAttribute('class', '');
|
||||
|
||||
setText(answer, '');
|
||||
setText(status, '');
|
||||
setText(expr, '');
|
||||
|
||||
try {
|
||||
left = esprima.parse((typeof a.innerText === 'string') ? a.innerText : a.textContent);
|
||||
} catch (e_left) {
|
||||
a.setAttribute('class', 'lightred');
|
||||
}
|
||||
|
||||
try {
|
||||
right = esprima.parse((typeof b.innerText === 'string') ? b.innerText : b.textContent);
|
||||
} catch (e_right) {
|
||||
b.setAttribute('class', 'lightred');
|
||||
}
|
||||
|
||||
try {
|
||||
suggest = stringify(left);
|
||||
} catch (e_suggest) {
|
||||
a.setAttribute('class', 'lightred');
|
||||
}
|
||||
|
||||
if (left && right) {
|
||||
if (JSON.stringify(left) === JSON.stringify(right)) {
|
||||
setText(answer, 'Yes');
|
||||
answer.setAttribute('class', 'yes');
|
||||
} else {
|
||||
setText(answer, 'No');
|
||||
answer.setAttribute('class', 'no');
|
||||
setText(status, suggest ? 'It is more like ' : '');
|
||||
setText(expr, suggest || '');
|
||||
}
|
||||
} else {
|
||||
answer.setAttribute('class', '');
|
||||
}
|
||||
|
||||
compareId = undefined;
|
||||
}, 57);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
||||
<div class="topbar">
|
||||
<ul class="nav">
|
||||
<li><a href="../index.html">← Home</a></li>
|
||||
<li><a href="http://github.com/ariya/esprima">Code</a></li>
|
||||
<li><a href="http://wiki.esprima.org">Documentation</a></li>
|
||||
<li><a href="http://issues.esprima.org">Issues</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h1>Operator precedence <small>is not always easy</small></h1>
|
||||
<p>Is <code id="a" contenteditable="true">1 << 2 * 3</code> semantically equivalent to
|
||||
<code id="b" contenteditable="true">(1 << 2) * 3</code>? <span id="answer"></span></p>
|
||||
<p style="margin-top: 40px;"><span id="status"></span> <code id="expr"></code></p>
|
||||
<p style="margin-top: 60px;">This demo is inspired by <a href="http://mothereff.in/operator-precedence">mothereff.in/operator-precedence</a>.</p>
|
||||
<div class="footer"><strong>Esprima</strong> is created by
|
||||
<a href="http://ariya.ofilabs.com/about" target="_blank">Ariya Hidayat</a>. Follow <a href="http://twitter.com/ariyahidayat">@ariyahidayat</a> on Twitter.
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
if (typeof document.body.attachEvent === 'object') {
|
||||
// Workaround for old Internet Explorer.
|
||||
// Until there is a reliable way to track the modification to the editable
|
||||
// inputs, manually track the change periodically.
|
||||
window.setInterval(compare, 500);
|
||||
}
|
||||
|
||||
// See http://mathiasbynens.be/notes/oninput for details.
|
||||
document.getElementById('a').onkeyup = compare;
|
||||
document.getElementById('a').oninput = function () {
|
||||
this.onkeyup = null;
|
||||
compare();
|
||||
};
|
||||
document.getElementById('b').onkeyup = compare;
|
||||
document.getElementById('b').oninput = function () {
|
||||
this.onkeyup = null;
|
||||
compare();
|
||||
};
|
||||
compare();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
120
node_modules/esprima/demo/rewrite.html
generated
vendored
120
node_modules/esprima/demo/rewrite.html
generated
vendored
@@ -1,120 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Esprima: Full Source Rewrite Demo</title>
|
||||
<script src="../test/3rdparty/platform.js"></script>
|
||||
<script src="../test/3rdparty/escodegen.js"></script>
|
||||
<script src="checkenv.js"></script>
|
||||
<script src="rewrite.js"></script>
|
||||
<script src="../esprima.js"></script>
|
||||
<script src="../assets/codemirror/codemirror.js"></script>
|
||||
<script src="../assets/codemirror/javascript.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../assets/codemirror/codemirror.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="../assets/style.css"/>
|
||||
<style>
|
||||
.CodeMirror-scroll {
|
||||
height: 300px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
||||
<div class="topbar">
|
||||
<ul class="nav">
|
||||
<li><a href="../index.html">← Home</a></li>
|
||||
<li><a href="http://github.com/ariya/esprima">Code</a></li>
|
||||
<li><a href="http://wiki.esprima.org">Documentation</a></li>
|
||||
<li><a href="http://issues.esprima.org">Issues</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h1>Source Rewrite <small>cleans up and reformats everything</small></h1>
|
||||
|
||||
<p>Type ECMAScript code in the editor. Press <b>Rewrite</b> button to get the code
|
||||
parsed and reconstructed.</p>
|
||||
|
||||
<p><textarea id="code" autofocus="autofocus" cols="70" rows="25" spellcheck="false">
|
||||
// Example of messy code with confusing and inconsistent indentations
|
||||
|
||||
function bubbleSort (list) {
|
||||
var items = list.slice(0), swapped =false,
|
||||
p, q;
|
||||
for ( p= 1;p < items.length; ++p) {
|
||||
for (q=0; q < items.length - p; ++q) {
|
||||
if (items[q + 1 ] < items[q]) {
|
||||
swapped =true;
|
||||
let temp = items[q];
|
||||
items[q] = items[ q+1]; items[q+1] = temp;
|
||||
}
|
||||
}
|
||||
if (!swapped)
|
||||
break;
|
||||
}
|
||||
return items;
|
||||
}
|
||||
</textarea></p>
|
||||
|
||||
<p>Indent with:
|
||||
<label><input type="radio" name="indent" id="onetab" value="onetab"> tab</label>
|
||||
<label><input type="radio" name="indent" id="twospaces" value="twospaces"> 2 spaces</label>
|
||||
<label><input checked type="radio" name="indent" id="fourspaces" value="fourspaces"> 4 spaces</label>
|
||||
</p>
|
||||
|
||||
<p><input type="button" value="Rewrite" id="rewrite"></p>
|
||||
|
||||
<p id="codemirror" align="right"><small>The above code editor is based on <a href="http://codemirror.net" target="_blank">CodeMirror</a>.</small></p>
|
||||
|
||||
<p id="error"></p>
|
||||
|
||||
<p><b>Notes</b>:</p>
|
||||
<ul>
|
||||
<li>Only valid syntax is accepted.</li>
|
||||
<li>Comments are <em>not</em> preserved.</li>
|
||||
<li>It is still experimental (see the <a href="https://github.com/Constellation/escodegen">escodegen project</a>).</li>
|
||||
</ul>
|
||||
|
||||
<p style="margin-top: 50px;">Using Esprima version <span id="version"></span>.</p>
|
||||
|
||||
<div class="footer"><strong>Esprima</strong> is created by
|
||||
<a href="http://ariya.ofilabs.com/about" target="_blank">Ariya Hidayat</a>. Follow <a href="http://twitter.com/ariyahidayat">@ariyahidayat</a> on Twitter.
|
||||
</div>
|
||||
|
||||
<p id="testbox" style="visibility: hidden;"><textarea id="test"></textarea></p>
|
||||
</div>
|
||||
<script>
|
||||
/*jslint sloppy:true browser:true */
|
||||
/*global sourceRewrite:true, CodeMirror:true */
|
||||
window.onload = function () {
|
||||
var el;
|
||||
|
||||
el = document.getElementById('version');
|
||||
if (typeof el.innerText === 'string') {
|
||||
el.innerText = window.esprima.version;
|
||||
} else {
|
||||
el.textContent = window.esprima.version;
|
||||
}
|
||||
|
||||
document.getElementById('rewrite').onclick = sourceRewrite;
|
||||
};
|
||||
|
||||
try {
|
||||
window.checkEnv();
|
||||
|
||||
// This is just testing, to detect whether CodeMirror would fail or not
|
||||
window.editor = CodeMirror.fromTextArea(document.getElementById("test"));
|
||||
|
||||
window.editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
matchBrackets: true
|
||||
});
|
||||
} catch (e) {
|
||||
// CodeMirror failed to initialize, possible in e.g. old IE.
|
||||
document.getElementById('codemirror').innerHTML = '';
|
||||
} finally {
|
||||
document.getElementById('testbox').parentNode.removeChild(document.getElementById('testbox'));
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
71
node_modules/esprima/demo/rewrite.js
generated
vendored
71
node_modules/esprima/demo/rewrite.js
generated
vendored
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*jslint browser:true evil:true */
|
||||
|
||||
function sourceRewrite() {
|
||||
'use strict';
|
||||
|
||||
var code, syntax, indent;
|
||||
|
||||
function setText(id, str) {
|
||||
var el = document.getElementById(id);
|
||||
if (typeof el.innerText === 'string') {
|
||||
el.innerText = str;
|
||||
} else {
|
||||
el.textContent = str;
|
||||
}
|
||||
}
|
||||
|
||||
setText('error', '');
|
||||
if (typeof window.editor !== 'undefined') {
|
||||
// Using CodeMirror.
|
||||
code = window.editor.getValue();
|
||||
} else {
|
||||
// Plain textarea, likely in a situation where CodeMirror does not work.
|
||||
code = document.getElementById('code').value;
|
||||
}
|
||||
|
||||
indent = '';
|
||||
if (document.getElementById('onetab').checked) {
|
||||
indent = '\t';
|
||||
} else if (document.getElementById('twospaces').checked) {
|
||||
indent = ' ';
|
||||
} else if (document.getElementById('fourspaces').checked) {
|
||||
indent = ' ';
|
||||
}
|
||||
|
||||
try {
|
||||
syntax = window.esprima.parse(code, { raw: true });
|
||||
code = window.escodegen.generate(syntax, { indent: indent });
|
||||
} catch (e) {
|
||||
setText('error', e.toString());
|
||||
} finally {
|
||||
if (typeof window.editor !== 'undefined') {
|
||||
window.editor.setValue(code);
|
||||
} else {
|
||||
document.getElementById('code').value = code;
|
||||
}
|
||||
}
|
||||
}
|
3577
node_modules/esprima/esprima.js
generated
vendored
3577
node_modules/esprima/esprima.js
generated
vendored
File diff suppressed because one or more lines are too long
103
node_modules/esprima/index.html
generated
vendored
103
node_modules/esprima/index.html
generated
vendored
@@ -1,103 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Esprima</title>
|
||||
<link rel="stylesheet" type="text/css" href="assets/style.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
||||
<div class="topbar">
|
||||
<ul class="nav">
|
||||
<li><a href="index.html">← Home</a></li>
|
||||
<li><a href="http://github.com/ariya/esprima">Code</a></li>
|
||||
<li><a href="http://wiki.esprima.org">Documentation</a></li>
|
||||
<li><a href="http://issues.esprima.org">Issues</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h1>Esprima <small>ECMAScript parsing infrastructure for multipurpose analysis</small></h1>
|
||||
|
||||
<div class="main">
|
||||
<p>Esprima (<a href="http://esprima.org">esprima.org</a>) is an educational
|
||||
<a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">ECMAScript</a>
|
||||
(also popularly known as <a href="http://en.wikipedia.org/wiki/JavaScript">JavaScript</a>)
|
||||
parsing infrastructure for multipurpose analysis. It is also written in ECMAScript.</p>
|
||||
|
||||
<p>Esprima serves as a good basis for various tools such as source modification
|
||||
(<a href="https://github.com/ariya/esmorph">Esmorph</a>), coverage analyzer
|
||||
(<a href="https://github.com/itay/node-cover">node-cover</a> and
|
||||
<a href="https://github.com/coveraje/coveraje">coveraje</a>),
|
||||
source-to-source compiler (<a href="https://github.com/Yoric/Marv-the-Tinker">Marv</a>),
|
||||
syntax formatter (<a href="https://github.com/fawek/codepainter">Code Painter</a>),
|
||||
and code generator (<a href="https://github.com/Constellation/escodegen">escodegen</a>).
|
||||
</p>
|
||||
|
||||
<p>Esprima can be used in a web browser:</p>
|
||||
|
||||
<pre><script src="esprima.js"><script></pre>
|
||||
|
||||
<p>or in a Node.js application via the package manager:</p>
|
||||
|
||||
<pre>npm install esprima</pre>
|
||||
|
||||
<p>Esprima parser output is compatible with Mozilla (SpiderMonkey)
|
||||
<a href="https://developer.mozilla.org/en/SpiderMonkey/Parser_API">Parser API</a>.</p>
|
||||
|
||||
<p>A very simple example:</p>
|
||||
|
||||
<pre>esprima.parse('var answer=42').body[0].declarations[0].init</pre>
|
||||
|
||||
<p>produces the following object:</p>
|
||||
|
||||
<pre>{ type: 'Literal', value: 42 }</pre>
|
||||
|
||||
<p>Esprima is still in the development, for now please check
|
||||
<a href="http://wiki.esprima.org">the wiki documentation</a>.</p>
|
||||
|
||||
<p>Since it is not comprehensive nor complete, refer to the
|
||||
<a href="http://issues.esprima.org">issue tracker</a> for
|
||||
<a href="http://code.google.com/p/esprima/issues/list?q=Defect">known problems</a>
|
||||
and <a href="http://code.google.com/p/esprima/issues/list?q=Enhancement">future plans</a>.
|
||||
Esprima is supported on <a href="http://code.google.com/p/esprima/wiki/BrowserCompatibility">many browsers</a>:
|
||||
IE 6+, Firefox 1+, Safari 3+, Chrome 1+, and Opera 8+.</p>
|
||||
|
||||
<p>Feedback and contribution are welcomed! Please join the
|
||||
<a href="http://groups.google.com/group/esprima">mailing list</a> and read the
|
||||
<a href="http://code.google.com/p/esprima/wiki/ContributionGuide">contribution guide</a>
|
||||
for further info.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="sidebar">
|
||||
<h3>Useful demos</h3>
|
||||
<ul>
|
||||
<li><a href="demo/parse.html">Code parser</a></li>
|
||||
<li><a href="demo/precedence.html">Operator precedence</a></li>
|
||||
<li><a href="demo/collector.html">Regex collector</a></li>
|
||||
<li><a href="demo/functiontrace.html">Function tracing</a></li>
|
||||
<li><a href="demo/rewrite.html">Source rewrite</a></li>
|
||||
</ul>
|
||||
<h3>Harness tests</h3>
|
||||
<ul>
|
||||
<li><a href="test/index.html">Unit tests</a></li>
|
||||
<li><a href="test/compat.html">Compatibility tests</a></li>
|
||||
<li><a href="test/coverage.html">Coverage analysis</a></li>
|
||||
</ul>
|
||||
<h3>Need for speed</h3>
|
||||
<ul>
|
||||
<li><a href="test/benchmarks.html">Benchmarks suite</a></li>
|
||||
<li><a href="test/compare.html">Speed comparison</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<br clear="all"/>
|
||||
|
||||
<div class="footer"><strong>Esprima</strong> is created by
|
||||
<a href="http://ariya.ofilabs.com/about" target="_blank">Ariya Hidayat</a>. Follow <a href="http://twitter.com/ariyahidayat">@ariyahidayat</a> on Twitter.
|
||||
</div>
|
||||
</div>
|
||||
<a href="http://github.com/ariya/esprima"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://a248.e.akamai.net/assets.github.com/img/e6bef7a091f5f3138b8cd40bc3e114258dd68ddf/687474703a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f7265645f6161303030302e706e67" alt="Fork me on GitHub"></a>
|
||||
</body>
|
||||
</html>
|
47
node_modules/esprima/package.json
generated
vendored
47
node_modules/esprima/package.json
generated
vendored
@@ -1,47 +0,0 @@
|
||||
{
|
||||
"name": "esprima",
|
||||
"description": "ECMAScript parsing infrastructure for multipurpose analysis",
|
||||
"homepage": "http://esprima.org",
|
||||
"main": "esprima.js",
|
||||
"bin": {
|
||||
"esparse": "./bin/esparse.js"
|
||||
},
|
||||
"version": "0.9.9",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "Ariya Hidayat",
|
||||
"email": "ariya.hidayat@gmail.com",
|
||||
"url": "http://ariya.ofilabs.com"
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/ariya/esprima.git"
|
||||
},
|
||||
"licenses": [
|
||||
{
|
||||
"type": "BSD",
|
||||
"url": "http://github.com/ariya/esprima/raw/master/LICENSE.BSD"
|
||||
}
|
||||
],
|
||||
"scripts": {
|
||||
"test": "node test/run.js",
|
||||
"benchmark": "node test/benchmarks.js",
|
||||
"benchmark-quick": "node test/benchmarks.js quick"
|
||||
},
|
||||
"_id": "esprima@0.9.9",
|
||||
"dependencies": {},
|
||||
"devDependencies": {},
|
||||
"optionalDependencies": {},
|
||||
"_engineSupported": true,
|
||||
"_npmVersion": "1.1.16",
|
||||
"_nodeVersion": "v0.6.15",
|
||||
"_defaultsLoaded": true,
|
||||
"dist": {
|
||||
"shasum": "cd61f7ed84ab17ed4c34e7bb93765d6e813188ec"
|
||||
},
|
||||
"_from": "esprima@0.9.9"
|
||||
}
|
646
node_modules/esprima/test/3rdparty/Tokenizer.js
generated
vendored
646
node_modules/esprima/test/3rdparty/Tokenizer.js
generated
vendored
@@ -1,646 +0,0 @@
|
||||
if (typeof exports !== 'undefined') {
|
||||
var window = {Unicode: require('./unicodecategories').Unicode};
|
||||
exports.Tokenizer = Tokenizer;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Tokenizer for JavaScript / ECMAScript 5
|
||||
* (c) Peter van der Zee, qfox.nl
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {Object} inp
|
||||
*/
|
||||
function Tokenizer(inp){
|
||||
this.inp = inp||'';
|
||||
// replace all other line terminators with \n (leave \r\n in tact though). we should probably remove the shadowInp when finished...
|
||||
// only replace \r if it is not followed by a \n else \r\n would become \n\n causing a double newline where it is just a single
|
||||
this.shadowInp = (inp||'').replace(Tokenizer.regexNormalizeNewlines, '\n');
|
||||
this.pos = 0;
|
||||
this.line = 0;
|
||||
this.column = 0;
|
||||
this.cache = {};
|
||||
|
||||
this.errorStack = [];
|
||||
|
||||
this.wtree = [];
|
||||
this.btree = [];
|
||||
|
||||
// this.regexWhiteSpace = Tokenizer.regexWhiteSpace;
|
||||
this.regexLineTerminator = Tokenizer.regexLineTerminator; // used in fallback
|
||||
this.regexAsciiIdentifier = Tokenizer.regexAsciiIdentifier;
|
||||
this.hashAsciiIdentifier = Tokenizer.hashAsciiIdentifier;
|
||||
// this.regexHex = Tokenizer.regexHex;
|
||||
this.hashHex = Tokenizer.hashHex
|
||||
this.regexUnicodeEscape = Tokenizer.regexUnicodeEscape;
|
||||
this.regexIdentifierStop = Tokenizer.regexIdentifierStop;
|
||||
this.hashIdentifierStop = Tokenizer.hashIdentifierStop;
|
||||
// this.regexPunctuators = Tokenizer.regexPunctuators;
|
||||
this.regexNumber = Tokenizer.regexNumber;
|
||||
this.regexNewline = Tokenizer.regexNewline;
|
||||
|
||||
this.regexBig = Tokenizer.regexBig;
|
||||
this.regexBigAlt = Tokenizer.regexBigAlt;
|
||||
|
||||
this.tokenCount = 0;
|
||||
this.tokenCountNoWhite = 0;
|
||||
|
||||
this.Unicode = window.Unicode;
|
||||
|
||||
// if the Parser throws an error. it will set this property to the next match
|
||||
// at the time of the error (which was not what it was expecting at that point)
|
||||
// and pass on an "error" match. the error should be scooped on the stack and
|
||||
// this property should be returned, without looking at the input...
|
||||
this.errorEscape = null;
|
||||
};
|
||||
|
||||
Tokenizer.prototype = {
|
||||
inp:null,
|
||||
shadowInp:null,
|
||||
pos:null,
|
||||
line:null,
|
||||
column:null,
|
||||
cache:null,
|
||||
errorStack:null,
|
||||
|
||||
wtree: null, // contains whitespace (spaces, comments, newlines)
|
||||
btree: null, // does not contain any whitespace tokens.
|
||||
|
||||
regexLineTerminator:null,
|
||||
regexAsciiIdentifier:null,
|
||||
hashAsciiIdentifier:null,
|
||||
hashHex:null,
|
||||
regexUnicodeEscape:null,
|
||||
regexIdentifierStop:null,
|
||||
hashIdentifierStop:null,
|
||||
regexNumber:null,
|
||||
regexNewline:null,
|
||||
regexBig:null,
|
||||
regexBigAlt:null,
|
||||
tokenCount:null,
|
||||
tokenCountNoWhite:null,
|
||||
|
||||
Unicode:null,
|
||||
|
||||
// storeCurrentAndFetchNextToken(bool, false, false true) to get just one token
|
||||
storeCurrentAndFetchNextToken: function(noRegex, returnValue, stack, _dontStore){
|
||||
var regex = !noRegex; // TOFIX :)
|
||||
var pos = this.pos;
|
||||
var inp = this.inp;
|
||||
var shadowInp = this.shadowInp;
|
||||
var matchedNewline = false;
|
||||
do {
|
||||
if (!_dontStore) {
|
||||
++this.tokenCount;
|
||||
stack.push(returnValue);
|
||||
// did the parent Parser throw up?
|
||||
if (this.errorEscape) {
|
||||
returnValue = this.errorEscape;
|
||||
this.errorEscape = null;
|
||||
return returnValue;
|
||||
}
|
||||
}
|
||||
_dontStore = false;
|
||||
|
||||
if (pos >= inp.length) {
|
||||
returnValue = {start:inp.length,stop:inp.length,name:12/*EOF*/};
|
||||
break;
|
||||
}
|
||||
var returnValue = null;
|
||||
|
||||
var start = pos;
|
||||
var chr = inp[pos];
|
||||
|
||||
// 1 ws 2 lt 3 scmt 4 mcmt 5/6 str 7 nr 8 rx 9 punc
|
||||
//if (true) {
|
||||
// substring method (I think this is faster..)
|
||||
var part2 = inp.substring(pos,pos+4);
|
||||
var part = this.regexBig.exec(part2);
|
||||
//} else {
|
||||
// // non-substring method (lastIndex)
|
||||
// // this method does not need a substring to apply it
|
||||
// this.regexBigAlt.lastIndex = pos;
|
||||
// var part = this.regexBigAlt.exec(inp);
|
||||
//}
|
||||
|
||||
if (part[1]) { //this.regexWhiteSpace.test(chr)) { // SP, TAB, VT, FF, NBSP, BOM (, TOFIX: USP)
|
||||
++pos;
|
||||
returnValue = {start:start,stop:pos,name:9/*WHITE_SPACE*/,line:this.line,col:this.column,isWhite:true};
|
||||
++this.column;
|
||||
} else if (part[2]) { //this.regexLineTerminator.test(chr)) { // LF, CR, LS, PS
|
||||
var end = pos+1;
|
||||
if (chr=='\r' && inp[pos+1] == '\n') ++end; // support crlf=>lf
|
||||
returnValue = {start:pos,stop:end,name:10/*LINETERMINATOR*/,line:this.line,col:this.column,isWhite:true};
|
||||
pos = end;
|
||||
// mark newlines for ASI
|
||||
matchedNewline = true;
|
||||
++this.line;
|
||||
this.column = 0;
|
||||
returnValue.hasNewline = 1;
|
||||
} else if (part[3]) { //chr == '/' && inp[pos+1] == '/') {
|
||||
pos = shadowInp.indexOf('\n',pos);
|
||||
if (pos == -1) pos = inp.length;
|
||||
returnValue = {start:start,stop:pos,name:7/*COMMENT_SINGLE*/,line:this.line,col:this.column,isComment:true,isWhite:true};
|
||||
this.column = returnValue.stop;
|
||||
} else if (part[4]) { //chr == '/' && inp[pos+1] == '*') {
|
||||
var newpos = inp.indexOf('*/',pos);
|
||||
if (newpos == -1) {
|
||||
newpos = shadowInp.indexOf('\n', pos);
|
||||
if (newpos < 0) pos += 2;
|
||||
else pos = newpos;
|
||||
returnValue = {start:start,stop:pos,name:14/*error*/,value:inp.substring(start, pos),line:this.line,col:this.column,isComment:true,isWhite:true,tokenError:true,error:Tokenizer.Error.UnterminatedMultiLineComment};
|
||||
this.errorStack.push(returnValue);
|
||||
} else {
|
||||
pos = newpos+2;
|
||||
returnValue = {start:start,stop:pos,name:8/*COMMENT_MULTI*/,value:inp.substring(start, pos),line:this.line,col:this.column,isComment:true,isWhite:true};
|
||||
|
||||
// multi line comments are also reason for asi, but only if they contain at least one newline (use shadow input, because all line terminators would be valid...)
|
||||
var shadowValue = shadowInp.substring(start, pos);
|
||||
var i = 0, hasNewline = 0;
|
||||
while (i < (i = shadowValue.indexOf('\n', i+1))) {
|
||||
++hasNewline;
|
||||
}
|
||||
if (hasNewline) {
|
||||
matchedNewline = true;
|
||||
returnValue.hasNewline = hasNewline;
|
||||
this.line += hasNewline;
|
||||
this.column = 0;
|
||||
} else {
|
||||
this.column = returnValue.stop;
|
||||
}
|
||||
}
|
||||
} else if (part[5]) { //chr == "'") {
|
||||
// old method
|
||||
//console.log("old method");
|
||||
|
||||
var hasNewline = 0;
|
||||
do {
|
||||
// process escaped characters
|
||||
while (pos < inp.length && inp[++pos] == '\\') {
|
||||
if (shadowInp[pos+1] == '\n') ++hasNewline;
|
||||
++pos;
|
||||
}
|
||||
if (this.regexLineTerminator.test(inp[pos])) {
|
||||
returnValue = {start:start,stop:pos,name:14/*error*/,value:inp.substring(start, pos),isString:true,tokenError:true,error:Tokenizer.Error.UnterminatedDoubleStringNewline};
|
||||
this.errorStack.push(returnValue);
|
||||
break;
|
||||
}
|
||||
} while (pos < inp.length && inp[pos] != "'");
|
||||
if (returnValue) {} // error
|
||||
else if (inp[pos] != "'") {
|
||||
returnValue = {start:start,stop:pos,name:14/*error*/,value:inp.substring(start, pos),isString:true,tokenError:true,error:Tokenizer.Error.UnterminatedDoubleStringOther};
|
||||
this.errorStack.push(returnValue);
|
||||
} else {
|
||||
++pos;
|
||||
returnValue = {start:start,stop:pos,name:5/*STRING_SINGLE*/,isPrimitive:true,isString:true};
|
||||
if (hasNewline) {
|
||||
returnValue.hasNewline = hasNewline;
|
||||
this.line += hasNewline;
|
||||
this.column = 0;
|
||||
} else {
|
||||
this.column += (pos-start);
|
||||
}
|
||||
}
|
||||
} else if (part[6]) { //chr == '"') {
|
||||
var hasNewline = 0;
|
||||
// TODO: something like this: var regexmatch = /([^\']|$)+/.match();
|
||||
do {
|
||||
// process escaped chars
|
||||
while (pos < inp.length && inp[++pos] == '\\') {
|
||||
if (shadowInp[pos+1] == '\n') ++hasNewline;
|
||||
++pos;
|
||||
}
|
||||
if (this.regexLineTerminator.test(inp[pos])) {
|
||||
returnValue = {start:start,stop:pos,name:14/*error*/,value:inp.substring(start, pos),isString:true,tokenError:true,error:Tokenizer.Error.UnterminatedSingleStringNewline};
|
||||
this.errorStack.push(returnValue);
|
||||
break;
|
||||
}
|
||||
} while (pos < inp.length && inp[pos] != '"');
|
||||
if (returnValue) {}
|
||||
else if (inp[pos] != '"') {
|
||||
returnValue = {start:start,stop:pos,name:14/*error*/,value:inp.substring(start, pos),isString:true,tokenError:true,error:Tokenizer.Error.UnterminatedSingleStringOther};
|
||||
this.errorStack.push(returnValue);
|
||||
} else {
|
||||
++pos;
|
||||
returnValue = {start:start,stop:pos,name:6/*STRING_DOUBLE*/,isPrimitive:true,isString:true};
|
||||
if (hasNewline) {
|
||||
returnValue.hasNewline = hasNewline;
|
||||
this.line += hasNewline;
|
||||
this.column = 0;
|
||||
} else {
|
||||
this.column += (pos-start);
|
||||
}
|
||||
}
|
||||
} else if (part[7]) { //(chr >= '0' && chr <= '9') || (chr == '.' && inp[pos+1] >= '0' && inp[pos+1] <= '9')) {
|
||||
var nextPart = inp.substring(pos, pos+30);
|
||||
var match = nextPart.match(this.regexNumber);
|
||||
if (match[2]) { // decimal
|
||||
var value = match[2];
|
||||
var parsingOctal = value[0] == '0' && value[1] && value[1] != 'e' && value[1] != 'E' && value[1] != '.';
|
||||
if (parsingOctal) {
|
||||
returnValue = {start:start,stop:pos,name:14/*error*/,isNumber:true,isOctal:true,tokenError:true,error:Tokenizer.Error.IllegalOctalEscape,value:value};
|
||||
this.errorStack.push(returnValue);
|
||||
} else {
|
||||
returnValue = {start:start,stop:start+value.length,name:4/*NUMERIC_DEC*/,isPrimitive:true,isNumber:true,value:value};
|
||||
}
|
||||
} else if (match[1]) { // hex
|
||||
var value = match[1];
|
||||
returnValue = {start:start,stop:start+value.length,name:3/*NUMERIC_HEX*/,isPrimitive:true,isNumber:true,value:value};
|
||||
} else {
|
||||
throw 'unexpected parser errror... regex fail :(';
|
||||
}
|
||||
|
||||
if (value.length < 300) {
|
||||
pos += value.length;
|
||||
} else {
|
||||
// old method of parsing numbers. only used for extremely long number literals (300+ chars).
|
||||
// this method does not require substringing... just memory :)
|
||||
var tmpReturnValue = this.oldNumberParser(pos, chr, inp, returnValue, start, Tokenizer);
|
||||
pos = tmpReturnValue[0];
|
||||
returnValue = tmpReturnValue[1];
|
||||
}
|
||||
} else if (regex && part[8]) { //chr == '/') { // regex cannot start with /* (would be multiline comment, and not make sense anyways). but if it was /* then an earlier if would have eated it. so we only check for /
|
||||
var twinfo = []; // matching {[( info
|
||||
var found = false;
|
||||
var parens = [];
|
||||
var nonLethalError = null;
|
||||
while (++pos < inp.length) {
|
||||
chr = shadowInp[pos];
|
||||
// parse RegularExpressionChar
|
||||
if (chr == '\n') {
|
||||
returnValue = {start:start,stop:pos,name:14/*error*/,tokenError:true,errorHasContent:true,error:Tokenizer.Error.UnterminatedRegularExpressionNewline};
|
||||
this.errorStack.push(returnValue);
|
||||
break; // fail
|
||||
} else if (chr == '/') {
|
||||
found = true;
|
||||
break;
|
||||
} else if (chr == '?' || chr == '*' || chr == '+') {
|
||||
nonLethalError = Tokenizer.Error.NothingToRepeat;
|
||||
} else if (chr == '^') {
|
||||
if (
|
||||
inp[pos-1] != '/' &&
|
||||
inp[pos-1] != '|' &&
|
||||
inp[pos-1] != '(' &&
|
||||
!(inp[pos-3] == '(' && inp[pos-2] == '?' && (inp[pos-1] == ':' || inp[pos-1] == '!' || inp[pos-1] == '='))
|
||||
) {
|
||||
nonLethalError = Tokenizer.Error.StartOfMatchShouldBeAtStart;
|
||||
}
|
||||
} else if (chr == '$') {
|
||||
if (inp[pos+1] != '/' && inp[pos+1] != '|' && inp[pos+1] != ')') nonLethalError = Tokenizer.Error.DollarShouldBeEnd;
|
||||
} else if (chr == '}') {
|
||||
nonLethalError = Tokenizer.Error.MissingOpeningCurly;
|
||||
} else { // it's a "character" (can be group or class), something to match
|
||||
// match parenthesis
|
||||
if (chr == '(') {
|
||||
parens.push(pos-start);
|
||||
} else if (chr == ')') {
|
||||
if (parens.length == 0) {
|
||||
nonLethalError = {start:start,stop:pos,name:14/*error*/,tokenError:true,error:Tokenizer.Error.RegexNoOpenGroups};
|
||||
} else {
|
||||
var twin = parens.pop();
|
||||
var now = pos-start;
|
||||
twinfo[twin] = now;
|
||||
twinfo[now] = twin;
|
||||
}
|
||||
}
|
||||
// first process character class
|
||||
if (chr == '[') {
|
||||
var before = pos-start;
|
||||
while (++pos < inp.length && shadowInp[pos] != '\n' && inp[pos] != ']') {
|
||||
// only newline is not allowed in class range
|
||||
// anything else can be escaped, most of it does not have to be escaped...
|
||||
if (inp[pos] == '\\') {
|
||||
if (shadowInp[pos+1] == '\n') break;
|
||||
else ++pos; // skip next char. (mainly prohibits ] to be picked up as closing the group...)
|
||||
}
|
||||
}
|
||||
if (inp[pos] != ']') {
|
||||
returnValue = {start:start,stop:pos,name:14/*error*/,tokenError:true,error:Tokenizer.Error.ClosingClassRangeNotFound};
|
||||
this.errorStack.push(returnValue);
|
||||
break;
|
||||
} else {
|
||||
var after = pos-start;
|
||||
twinfo[before] = after;
|
||||
twinfo[after] = before;
|
||||
}
|
||||
} else if (chr == '\\' && shadowInp[pos+1] != '\n') {
|
||||
// is ok anywhere in the regex (match next char literally, regardless of its otherwise special meaning)
|
||||
++pos;
|
||||
}
|
||||
|
||||
// now process repeaters (+, ? and *)
|
||||
|
||||
// non-collecting group (?:...) and positive (?=...) or negative (?!...) lookahead
|
||||
if (chr == '(') {
|
||||
if (inp[pos+1] == '?' && (inp[pos+2] == ':' || inp[pos+2] == '=' || inp[pos+2] == '!')) {
|
||||
pos += 2;
|
||||
}
|
||||
}
|
||||
// matching "char"
|
||||
else if (inp[pos+1] == '?') ++pos;
|
||||
else if (inp[pos+1] == '*' || inp[pos+1] == '+') {
|
||||
++pos;
|
||||
if (inp[pos+1] == '?') ++pos; // non-greedy match
|
||||
} else if (inp[pos+1] == '{') {
|
||||
pos += 1;
|
||||
var before = pos-start;
|
||||
// quantifier:
|
||||
// - {n}
|
||||
// - {n,}
|
||||
// - {n,m}
|
||||
if (!/[0-9]/.test(inp[pos+1])) {
|
||||
nonLethalError = Tokenizer.Error.QuantifierRequiresNumber;
|
||||
}
|
||||
while (++pos < inp.length && /[0-9]/.test(inp[pos+1]));
|
||||
if (inp[pos+1] == ',') {
|
||||
++pos;
|
||||
while (pos < inp.length && /[0-9]/.test(inp[pos+1])) ++pos;
|
||||
}
|
||||
if (inp[pos+1] != '}') {
|
||||
nonLethalError = Tokenizer.Error.QuantifierRequiresClosingCurly;
|
||||
} else {
|
||||
++pos;
|
||||
var after = pos-start;
|
||||
twinfo[before] = after;
|
||||
twinfo[after] = before;
|
||||
if (inp[pos+1] == '?') ++pos; // non-greedy match
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// if found=false, fail right now. otherwise try to parse an identifiername (that's all RegularExpressionFlags is..., but it's constructed in a stupid fashion)
|
||||
if (!found || returnValue) {
|
||||
if (!returnValue) {
|
||||
returnValue = {start:start,stop:pos,name:14/*error*/,tokenError:true,error:Tokenizer.Error.UnterminatedRegularExpressionOther};
|
||||
this.errorStack.push(returnValue);
|
||||
}
|
||||
} else {
|
||||
// this is the identifier scanner, for now
|
||||
do ++pos;
|
||||
while (pos < inp.length && this.hashAsciiIdentifier[inp[pos]]); /*this.regexAsciiIdentifier.test(inp[pos])*/
|
||||
|
||||
if (parens.length) {
|
||||
// nope, this is still an error, there was at least one paren that did not have a matching twin
|
||||
if (parens.length > 0) returnValue = {start:start,stop:pos,name:14/*error*/,tokenError:true,error:Tokenizer.Error.RegexOpenGroup};
|
||||
this.errorStack.push(returnValue);
|
||||
} else if (nonLethalError) {
|
||||
returnValue = {start:start,stop:pos,name:14/*error*/,errorHasContent:true,tokenError:true,error:nonLethalError};
|
||||
this.errorStack.push(returnValue);
|
||||
} else {
|
||||
returnValue = {start:start,stop:pos,name:1/*REG_EX*/,isPrimitive:true};
|
||||
}
|
||||
}
|
||||
returnValue.twinfo = twinfo;
|
||||
} else {
|
||||
// note: operators need to be ordered from longest to smallest. regex will take care of the rest.
|
||||
// no need to worry about div vs regex. if looking for regex, earlier if will have eaten it
|
||||
//var result = this.regexPunctuators.exec(inp.substring(pos,pos+4));
|
||||
|
||||
// note: due to the regex, the single forward slash might be caught by an earlier part of the regex. so check for that.
|
||||
var result = part[8] || part[9];
|
||||
if (result) {
|
||||
//result = result[1];
|
||||
returnValue = {start:pos,stop:pos+=result.length,name:11/*PUNCTUATOR*/,value:result};
|
||||
} else {
|
||||
var found = false;
|
||||
// identifiers cannot start with a number. but if the leading string would be a number, another if would have eaten it already for numeric literal :)
|
||||
while (pos < inp.length) {
|
||||
var c = inp[pos];
|
||||
|
||||
if (this.hashAsciiIdentifier[c]) ++pos; //if (this.regexAsciiIdentifier.test(c)) ++pos;
|
||||
else if (c == '\\' && this.regexUnicodeEscape.test(inp.substring(pos,pos+6))) pos += 6; // this is like a \uxxxx
|
||||
// ok, now test unicode ranges...
|
||||
// basically this hardly ever happens so there's little risk of this hitting performance
|
||||
// however, if you do happen to have used them, it's not a problem. the parser will support it :)
|
||||
else if (this.Unicode) { // the unicode is optional.
|
||||
// these chars may not be part of identifier. i want to try to prevent running the unicode regexes here...
|
||||
if (this.hashIdentifierStop[c] /*this.regexIdentifierStop.test(c)*/) break;
|
||||
// for most scripts, the code wont reach here. which is good, because this is going to be relatively slow :)
|
||||
var Unicode = this.Unicode; // cache
|
||||
if (!(
|
||||
// these may all occur in an identifier... (pure a specification compliance thing :)
|
||||
Unicode.Lu.test(c) || Unicode.Ll.test(c) || Unicode.Lt.test(c) || Unicode.Lm.test(c) ||
|
||||
Unicode.Lo.test(c) || Unicode.Nl.test(c) || Unicode.Mn.test(c) || Unicode.Mc.test(c) ||
|
||||
Unicode.Nd.test(c) || Unicode.Pc.test(c) || Unicode.sp.test(c)
|
||||
)) break; // end of match.
|
||||
// passed, next char
|
||||
++pos;
|
||||
} else break; // end of match.
|
||||
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (found) {
|
||||
returnValue = {start:start,stop:pos,name:2/*IDENTIFIER*/,value:inp.substring(start,pos)};
|
||||
if (returnValue.value == 'undefined' || returnValue.value == 'null' || returnValue.value == 'true' || returnValue.value == 'false') returnValue.isPrimitive = true;
|
||||
} else {
|
||||
if (inp[pos] == '`') {
|
||||
returnValue = {start:start,stop:pos+1,name:14/*error*/,tokenError:true,error:Tokenizer.Error.BacktickNotSupported};
|
||||
this.errorStack.push(returnValue);
|
||||
} else if (inp[pos] == '\\') {
|
||||
if (inp[pos+1] == 'u') {
|
||||
returnValue = {start:start,stop:pos+1,name:14/*error*/,tokenError:true,error:Tokenizer.Error.InvalidUnicodeEscape};
|
||||
this.errorStack.push(returnValue);
|
||||
} else {
|
||||
returnValue = {start:start,stop:pos+1,name:14/*error*/,tokenError:true,error:Tokenizer.Error.InvalidBackslash};
|
||||
this.errorStack.push(returnValue);
|
||||
}
|
||||
} else {
|
||||
returnValue = {start:start,stop:pos+1,name:14/*error*/,tokenError:true,error:Tokenizer.Error.Unknown,value:c};
|
||||
this.errorStack.push(returnValue);
|
||||
// try to skip this char. it's not going anywhere.
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (returnValue) {
|
||||
// note that ASI's are slipstreamed in here from the parser since the tokenizer cant determine that
|
||||
// if this part ever changes, make sure you change that too :)
|
||||
returnValue.tokposw = this.wtree.length;
|
||||
this.wtree.push(returnValue);
|
||||
if (!returnValue.isWhite) {
|
||||
returnValue.tokposb = this.btree.length;
|
||||
this.btree.push(returnValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} while (stack && returnValue && returnValue.isWhite); // WHITE_SPACE LINETERMINATOR COMMENT_SINGLE COMMENT_MULTI
|
||||
++this.tokenCountNoWhite;
|
||||
|
||||
this.pos = pos;
|
||||
|
||||
if (matchedNewline) returnValue.newline = true;
|
||||
return returnValue;
|
||||
},
|
||||
addTokenToStreamBefore: function(token, match){
|
||||
var wtree = this.wtree;
|
||||
var btree = this.btree;
|
||||
if (match.name == 12/*asi*/) {
|
||||
token.tokposw = wtree.length;
|
||||
wtree.push(token);
|
||||
token.tokposb = btree.length;
|
||||
btree.push(token);
|
||||
} else {
|
||||
token.tokposw = match.tokposw;
|
||||
wtree[token.tokposw] = token;
|
||||
match.tokposw += 1;
|
||||
wtree[match.tokposw] = match;
|
||||
|
||||
if (match.tokposb) {
|
||||
token.tokposb = match.tokposb;
|
||||
btree[token.tokposb] = token;
|
||||
match.tokposb += 1;
|
||||
btree[match.tokposb] = match;
|
||||
}
|
||||
}
|
||||
},
|
||||
oldNumberParser: function(pos, chr, inp, returnValue, start, Tokenizer){
|
||||
++pos;
|
||||
// either: 0x 0X 0 .3
|
||||
if (chr == '0' && (inp[pos] == 'x' || inp[pos] == 'X')) {
|
||||
// parsing hex
|
||||
while (++pos < inp.length && this.hashHex[inp[pos]]); // this.regexHex.test(inp[pos]));
|
||||
returnValue = {start:start,stop:pos,name:3/*NUMERIC_HEX*/,isPrimitive:true,isNumber:true};
|
||||
} else {
|
||||
var parsingOctal = chr == '0' && inp[pos] >= '0' && inp[pos] <= '9';
|
||||
// parsing dec
|
||||
if (chr != '.') { // integer part
|
||||
while (pos < inp.length && inp[pos] >= '0' && inp[pos] <= '9') ++pos;
|
||||
if (inp[pos] == '.') ++pos;
|
||||
}
|
||||
// decimal part
|
||||
while (pos < inp.length && inp[pos] >= '0' && inp[pos] <= '9') ++pos;
|
||||
// exponent part
|
||||
if (inp[pos] == 'e' || inp[pos] == 'E') {
|
||||
if (inp[++pos] == '+' || inp[pos] == '-') ++pos;
|
||||
var expPosBak = pos;
|
||||
while (pos < inp.length && inp[pos] >= '0' && inp[pos] <= '9') ++pos;
|
||||
if (expPosBak == pos) {
|
||||
returnValue = {start:start,stop:pos,name:14/*error*/,tokenError:true,error:Tokenizer.Error.NumberExponentRequiresDigits};
|
||||
this.errorStack.push(returnValue);
|
||||
}
|
||||
}
|
||||
if (returnValue.name != 14/*error*/) {
|
||||
if (parsingOctal) {
|
||||
returnValue = {start:start,stop:pos,name:14/*error*/,isNumber:true,isOctal:true,tokenError:true,error:Tokenizer.Error.IllegalOctalEscape};
|
||||
this.errorStack.push(returnValue);
|
||||
console.log("foo")
|
||||
} else {
|
||||
returnValue = {start:start,stop:pos,name:4/*NUMERIC_DEC*/,isPrimitive:true,isNumber:true};
|
||||
}
|
||||
}
|
||||
}
|
||||
return [pos, returnValue];
|
||||
},
|
||||
tokens: function(arrx){
|
||||
arrx = arrx || [];
|
||||
var n = 0;
|
||||
var last;
|
||||
var stack = [];
|
||||
while ((last = this.storeCurrentAndFetchNextToken(!arrx[n++], false, false, true)) && last.name != 12/*EOF*/) stack.push(last);
|
||||
return stack;
|
||||
},
|
||||
fixValues: function(){
|
||||
this.wtree.forEach(function(t){
|
||||
if (!t.value) t.value = this.inp.substring(t.start, t.stop);
|
||||
},this);
|
||||
}
|
||||
};
|
||||
|
||||
//#ifdef TEST_SUITE
|
||||
Tokenizer.escape = function(s){
|
||||
return s.replace(/\n/g,'\\n').replace(/\t/g,'\\t').replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/\uFFFF/g, '\\uFFFF').replace(/\s/g, function(s){
|
||||
// replace whitespace as is...
|
||||
var ord = s.charCodeAt(0).toString(16);
|
||||
switch (ord.length) {
|
||||
case 1: ord = '000'+ord; break;
|
||||
case 2: ord = '00'+ord; break;
|
||||
case 3: ord = '0'+ord; break;
|
||||
}
|
||||
return '\\u'+ord;
|
||||
});
|
||||
};
|
||||
Tokenizer.testSuite = function(arr){
|
||||
var out = document.createElement('pre');
|
||||
document.body.appendChild(out);
|
||||
var debug = function(){
|
||||
var f = document.createElement('div');
|
||||
f.innerHTML = Array.prototype.slice.call(arguments).join(' ');
|
||||
out.appendChild(f);
|
||||
return arguments[0];
|
||||
};
|
||||
|
||||
debug("Running test suite...",arr.length,"tests");
|
||||
debug(' ');
|
||||
var start = +new Date;
|
||||
var ok = 0;
|
||||
var fail = 0;
|
||||
for (var i=0; i<arr.length; ++i) {
|
||||
var test = arr[i], result;
|
||||
var input = test[0];
|
||||
var outputLen = test[1].length ? test[1][0] : test[1];
|
||||
var regexHints = test[3] ? test[2] : null; // if flags, then len=4
|
||||
var desc = test[3] || test[2];
|
||||
|
||||
var result = new Tokenizer(input).tokens(regexHints); // regexHints can be null, that's ok
|
||||
if (result.length == outputLen) {
|
||||
debug('<span class="green">Test '+i+' ok:</span>',desc);
|
||||
++ok;
|
||||
} else {
|
||||
debug('<b class="red">Test failed:</span>',desc,'(found',result.length,'expected',outputLen+')'),console.log(desc, result);
|
||||
++fail;
|
||||
}
|
||||
debug('<b>'+Tokenizer.escape(input)+'</b>');
|
||||
debug('<br/>');
|
||||
}
|
||||
debug("Tokenizer test suite finished ("+(+new Date - start)+' ms). ok:'+ok+', fail:'+fail);
|
||||
};
|
||||
//#endif
|
||||
|
||||
Tokenizer.regexWhiteSpace = /[ \t\u000B\u000C\u00A0\uFFFF]/;
|
||||
Tokenizer.regexLineTerminator = /[\u000A\u000D\u2028\u2029]/;
|
||||
Tokenizer.regexAsciiIdentifier = /[a-zA-Z0-9\$_]/;
|
||||
Tokenizer.hashAsciiIdentifier = {_:1,$:1,a:1,b:1,c:1,d:1,e:1,f:1,g:1,h:1,i:1,j:1,k:1,l:1,m:1,n:1,o:1,p:1,q:1,r:1,s:1,t:1,u:1,v:1,w:1,x:1,y:1,z:1,A:1,B:1,C:1,D:1,E:1,F:1,G:1,H:1,I:1,J:1,K:1,L:1,M:1,N:1,O:1,P:1,Q:1,R:1,S:1,T:1,U:1,V:1,W:1,X:1,Y:1,Z:1,0:1,1:1,2:1,3:1,4:1,5:1,6:1,7:1,8:1,9:1};
|
||||
Tokenizer.regexHex = /[0-9A-Fa-f]/;
|
||||
Tokenizer.hashHex = {0:1,1:1,2:1,3:1,4:1,5:1,6:1,7:1,8:1,9:1,a:1,b:1,c:1,d:1,e:1,f:1,A:1,B:1,C:1,D:1,E:1,F:1};
|
||||
Tokenizer.regexUnicodeEscape = /u[0-9A-Fa-f]{4}/; // the \ is already checked at usage...
|
||||
Tokenizer.regexIdentifierStop = /[\>\=\!\|\<\+\-\&\*\%\^\/\{\}\(\)\[\]\.\;\,\~\?\:\ \t\n\\\'\"]/;
|
||||
Tokenizer.hashIdentifierStop = {'>':1,'=':1,'!':1,'|':1,'<':1,'+':1,'-':1,'&':1,'*':1,'%':1,'^':1,'/':1,'{':1,'}':1,'(':1,')':1,'[':1,']':1,'.':1,';':1,',':1,'~':1,'?':1,':':1,'\\':1,'\'':1,'"':1,' ':1,'\t':1,'\n':1};
|
||||
Tokenizer.regexNewline = /\n/g;
|
||||
//Tokenizer.regexPunctuators = /^(>>>=|===|!==|>>>|<<=|>>=|<=|>=|==|!=|\+\+|--|<<|>>|\&\&|\|\||\+=|-=|\*=|%=|\&=|\|=|\^=|\/=|\{|\}|\(|\)|\[|\]|\.|;|,|<|>|\+|-|\*|%|\||\&|\||\^|!|~|\?|:|=|\/)/;
|
||||
Tokenizer.Unidocde = window.Unicode;
|
||||
Tokenizer.regexNumber = /^(?:(0[xX][0-9A-Fa-f]+)|((?:(?:(?:(?:[0-9]+)(?:\.[0-9]*)?))|(?:\.[0-9]+))(?:[eE][-+]?[0-9]{1,})?))/;
|
||||
Tokenizer.regexNormalizeNewlines = /(\u000D[^\u000A])|[\u2028\u2029]/;
|
||||
|
||||
// 1 ws 2 lt 3 scmt 4 mcmt 5/6 str 7 nr 8 rx 9 punc
|
||||
Tokenizer.regexBig = /^([ \t\u000B\u000C\u00A0\uFFFF])?([\u000A\u000D\u2028\u2029])?(\/\/)?(\/\*)?(')?(")?(\.?[0-9])?(?:(\/)[^=])?(>>>=|===|!==|>>>|<<=|>>=|<=|>=|==|!=|\+\+|--|<<|>>|\&\&|\|\||\+=|-=|\*=|%=|\&=|\|=|\^=|\/=|\{|\}|\(|\)|\[|\]|\.|;|,|<|>|\+|-|\*|%|\||\&|\||\^|!|~|\?|:|=|\/)?/;
|
||||
Tokenizer.regexBigAlt = /([ \t\u000B\u000C\u00A0\uFFFF])?([\u000A\u000D\u2028\u2029])?(\/\/)?(\/\*)?(')?(")?(\.?[0-9])?(?:(\/)[^=])?(>>>=|===|!==|>>>|<<=|>>=|<=|>=|==|!=|\+\+|--|<<|>>|\&\&|\|\||\+=|-=|\*=|%=|\&=|\|=|\^=|\/=|\{|\}|\(|\)|\[|\]|\.|;|,|<|>|\+|-|\*|%|\||\&|\||\^|!|~|\?|:|=|\/)?/g;
|
||||
|
||||
Tokenizer.Error = {
|
||||
UnterminatedSingleStringNewline: {msg:'Newlines are not allowed in string literals'},
|
||||
UnterminatedSingleStringOther: {msg:'Unterminated single string'},
|
||||
UnterminatedDoubleStringNewline: {msg:'Newlines are not allowed in string literals'},
|
||||
UnterminatedDoubleStringOther: {msg:'Unterminated double string'},
|
||||
UnterminatedRegularExpressionNewline: {msg:'Newlines are not allowed in regular expressions'},
|
||||
NothingToRepeat: {msg:'Used a repeat character (*?+) in a regex without something prior to it to match'},
|
||||
ClosingClassRangeNotFound: {msg: 'Unable to find ] for class range'},
|
||||
RegexOpenGroup: {msg: 'Open group did not find closing parenthesis'},
|
||||
RegexNoOpenGroups: {msg: 'Closing parenthesis found but no group open'},
|
||||
UnterminatedRegularExpressionOther: {msg:'Unterminated regular expression'},
|
||||
UnterminatedMultiLineComment: {msg:'Unterminated multi line comment'},
|
||||
UnexpectedIdentifier: {msg:'Unexpected identifier'},
|
||||
IllegalOctalEscape: {msg:'Octal escapes are not valid'},
|
||||
Unknown: {msg:'Unknown input'}, // if this happens, my parser is bad :(
|
||||
NumberExponentRequiresDigits: {msg:'Numbers with exponents require at least one digit after the `e`'},
|
||||
BacktickNotSupported: {msg:'The backtick is not used in js, maybe you copy/pasted from a fancy site/doc?'},
|
||||
InvalidUnicodeEscape: {msg:'Encountered an invalid unicode escape, must be followed by exactly four hex numbers'},
|
||||
InvalidBackslash: {msg:'Encountered a backslash where it not allowed'},
|
||||
StartOfMatchShouldBeAtStart: {msg: 'The ^ signifies the start of match but was not found at a start'},
|
||||
DollarShouldBeEnd: {msg: 'The $ signifies the stop of match but was not found at a stop'},
|
||||
QuantifierRequiresNumber: {msg:'Quantifier curly requires at least one digit before the comma'},
|
||||
QuantifierRequiresClosingCurly: {msg:'Quantifier curly requires to be closed'},
|
||||
MissingOpeningCurly: {msg:'Encountered closing quantifier curly without seeing an opening curly'}
|
||||
};
|
509
node_modules/esprima/test/3rdparty/XMLHttpRequest.js
generated
vendored
509
node_modules/esprima/test/3rdparty/XMLHttpRequest.js
generated
vendored
@@ -1,509 +0,0 @@
|
||||
/**
|
||||
* XMLHttpRequest.js Copyright (C) 2011 Sergey Ilinsky (http://www.ilinsky.com)
|
||||
*
|
||||
* This work is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This work is distributed in the hope that it will be useful,
|
||||
* but without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
(function () {
|
||||
|
||||
// Save reference to earlier defined object implementation (if any)
|
||||
var oXMLHttpRequest = window.XMLHttpRequest;
|
||||
|
||||
// Define on browser type
|
||||
var bGecko = !!window.controllers;
|
||||
var bIE = window.document.all && !window.opera;
|
||||
var bIE7 = bIE && window.navigator.userAgent.match(/MSIE 7.0/);
|
||||
|
||||
// Enables "XMLHttpRequest()" call next to "new XMLHttpReques()"
|
||||
function fXMLHttpRequest() {
|
||||
this._object = oXMLHttpRequest && !bIE7 ? new oXMLHttpRequest : new window.ActiveXObject("Microsoft.XMLHTTP");
|
||||
this._listeners = [];
|
||||
}
|
||||
|
||||
// Constructor
|
||||
function cXMLHttpRequest() {
|
||||
return new fXMLHttpRequest;
|
||||
}
|
||||
cXMLHttpRequest.prototype = fXMLHttpRequest.prototype;
|
||||
|
||||
// BUGFIX: Firefox with Firebug installed would break pages if not executed
|
||||
if (bGecko && oXMLHttpRequest.wrapped) {
|
||||
cXMLHttpRequest.wrapped = oXMLHttpRequest.wrapped;
|
||||
}
|
||||
|
||||
// Constants
|
||||
cXMLHttpRequest.UNSENT = 0;
|
||||
cXMLHttpRequest.OPENED = 1;
|
||||
cXMLHttpRequest.HEADERS_RECEIVED = 2;
|
||||
cXMLHttpRequest.LOADING = 3;
|
||||
cXMLHttpRequest.DONE = 4;
|
||||
|
||||
// Public Properties
|
||||
cXMLHttpRequest.prototype.readyState = cXMLHttpRequest.UNSENT;
|
||||
cXMLHttpRequest.prototype.responseText = '';
|
||||
cXMLHttpRequest.prototype.responseXML = null;
|
||||
cXMLHttpRequest.prototype.status = 0;
|
||||
cXMLHttpRequest.prototype.statusText = '';
|
||||
|
||||
// Priority proposal
|
||||
cXMLHttpRequest.prototype.priority = "NORMAL";
|
||||
|
||||
// Instance-level Events Handlers
|
||||
cXMLHttpRequest.prototype.onreadystatechange = null;
|
||||
|
||||
// Class-level Events Handlers
|
||||
cXMLHttpRequest.onreadystatechange = null;
|
||||
cXMLHttpRequest.onopen = null;
|
||||
cXMLHttpRequest.onsend = null;
|
||||
cXMLHttpRequest.onabort = null;
|
||||
|
||||
// Public Methods
|
||||
cXMLHttpRequest.prototype.open = function(sMethod, sUrl, bAsync, sUser, sPassword) {
|
||||
// Delete headers, required when object is reused
|
||||
delete this._headers;
|
||||
|
||||
// When bAsync parameter value is omitted, use true as default
|
||||
if (arguments.length < 3) {
|
||||
bAsync = true;
|
||||
}
|
||||
|
||||
// Save async parameter for fixing Gecko bug with missing readystatechange in synchronous requests
|
||||
this._async = bAsync;
|
||||
|
||||
// Set the onreadystatechange handler
|
||||
var oRequest = this;
|
||||
var nState = this.readyState;
|
||||
var fOnUnload = null;
|
||||
|
||||
// BUGFIX: IE - memory leak on page unload (inter-page leak)
|
||||
if (bIE && bAsync) {
|
||||
fOnUnload = function() {
|
||||
if (nState != cXMLHttpRequest.DONE) {
|
||||
fCleanTransport(oRequest);
|
||||
// Safe to abort here since onreadystatechange handler removed
|
||||
oRequest.abort();
|
||||
}
|
||||
};
|
||||
window.attachEvent("onunload", fOnUnload);
|
||||
}
|
||||
|
||||
// Add method sniffer
|
||||
if (cXMLHttpRequest.onopen) {
|
||||
cXMLHttpRequest.onopen.apply(this, arguments);
|
||||
}
|
||||
|
||||
if (arguments.length > 4) {
|
||||
this._object.open(sMethod, sUrl, bAsync, sUser, sPassword);
|
||||
} else if (arguments.length > 3) {
|
||||
this._object.open(sMethod, sUrl, bAsync, sUser);
|
||||
} else {
|
||||
this._object.open(sMethod, sUrl, bAsync);
|
||||
}
|
||||
|
||||
this.readyState = cXMLHttpRequest.OPENED;
|
||||
fReadyStateChange(this);
|
||||
|
||||
this._object.onreadystatechange = function() {
|
||||
if (bGecko && !bAsync) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Synchronize state
|
||||
oRequest.readyState = oRequest._object.readyState;
|
||||
fSynchronizeValues(oRequest);
|
||||
|
||||
// BUGFIX: Firefox fires unnecessary DONE when aborting
|
||||
if (oRequest._aborted) {
|
||||
// Reset readyState to UNSENT
|
||||
oRequest.readyState = cXMLHttpRequest.UNSENT;
|
||||
|
||||
// Return now
|
||||
return;
|
||||
}
|
||||
|
||||
if (oRequest.readyState == cXMLHttpRequest.DONE) {
|
||||
// Free up queue
|
||||
delete oRequest._data;
|
||||
|
||||
// Uncomment these lines for bAsync
|
||||
/**
|
||||
* if (bAsync) {
|
||||
* fQueue_remove(oRequest);
|
||||
* }
|
||||
*/
|
||||
|
||||
fCleanTransport(oRequest);
|
||||
|
||||
// Uncomment this block if you need a fix for IE cache
|
||||
/**
|
||||
* // BUGFIX: IE - cache issue
|
||||
* if (!oRequest._object.getResponseHeader("Date")) {
|
||||
* // Save object to cache
|
||||
* oRequest._cached = oRequest._object;
|
||||
*
|
||||
* // Instantiate a new transport object
|
||||
* cXMLHttpRequest.call(oRequest);
|
||||
*
|
||||
* // Re-send request
|
||||
* if (sUser) {
|
||||
* if (sPassword) {
|
||||
* oRequest._object.open(sMethod, sUrl, bAsync, sUser, sPassword);
|
||||
* } else {
|
||||
* oRequest._object.open(sMethod, sUrl, bAsync);
|
||||
* }
|
||||
*
|
||||
* oRequest._object.setRequestHeader("If-Modified-Since", oRequest._cached.getResponseHeader("Last-Modified") || new window.Date(0));
|
||||
* // Copy headers set
|
||||
* if (oRequest._headers) {
|
||||
* for (var sHeader in oRequest._headers) {
|
||||
* // Some frameworks prototype objects with functions
|
||||
* if (typeof oRequest._headers[sHeader] == "string") {
|
||||
* oRequest._object.setRequestHeader(sHeader, oRequest._headers[sHeader]);
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* oRequest._object.onreadystatechange = function() {
|
||||
* // Synchronize state
|
||||
* oRequest.readyState = oRequest._object.readyState;
|
||||
*
|
||||
* if (oRequest._aborted) {
|
||||
* //
|
||||
* oRequest.readyState = cXMLHttpRequest.UNSENT;
|
||||
*
|
||||
* // Return
|
||||
* return;
|
||||
* }
|
||||
*
|
||||
* if (oRequest.readyState == cXMLHttpRequest.DONE) {
|
||||
* // Clean Object
|
||||
* fCleanTransport(oRequest);
|
||||
*
|
||||
* // get cached request
|
||||
* if (oRequest.status == 304) {
|
||||
* oRequest._object = oRequest._cached;
|
||||
* }
|
||||
*
|
||||
* //
|
||||
* delete oRequest._cached;
|
||||
*
|
||||
* //
|
||||
* fSynchronizeValues(oRequest);
|
||||
*
|
||||
* //
|
||||
* fReadyStateChange(oRequest);
|
||||
*
|
||||
* // BUGFIX: IE - memory leak in interrupted
|
||||
* if (bIE && bAsync) {
|
||||
* window.detachEvent("onunload", fOnUnload);
|
||||
* }
|
||||
*
|
||||
* }
|
||||
* };
|
||||
* oRequest._object.send(null);
|
||||
*
|
||||
* // Return now - wait until re-sent request is finished
|
||||
* return;
|
||||
* };
|
||||
*/
|
||||
|
||||
// BUGFIX: IE - memory leak in interrupted
|
||||
if (bIE && bAsync) {
|
||||
window.detachEvent("onunload", fOnUnload);
|
||||
}
|
||||
|
||||
// BUGFIX: Some browsers (Internet Explorer, Gecko) fire OPEN readystate twice
|
||||
if (nState != oRequest.readyState) {
|
||||
fReadyStateChange(oRequest);
|
||||
}
|
||||
|
||||
nState = oRequest.readyState;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
cXMLHttpRequest.prototype.send = function(vData) {
|
||||
// Add method sniffer
|
||||
if (cXMLHttpRequest.onsend) {
|
||||
cXMLHttpRequest.onsend.apply(this, arguments);
|
||||
}
|
||||
|
||||
if (!arguments.length) {
|
||||
vData = null;
|
||||
}
|
||||
|
||||
// BUGFIX: Safari - fails sending documents created/modified dynamically, so an explicit serialization required
|
||||
// BUGFIX: IE - rewrites any custom mime-type to "text/xml" in case an XMLNode is sent
|
||||
// BUGFIX: Gecko - fails sending Element (this is up to the implementation either to standard)
|
||||
if (vData && vData.nodeType) {
|
||||
vData = window.XMLSerializer ? new window.XMLSerializer().serializeToString(vData) : vData.xml;
|
||||
if (!this._headers["Content-Type"]) {
|
||||
this._object.setRequestHeader("Content-Type", "application/xml");
|
||||
}
|
||||
}
|
||||
|
||||
this._data = vData;
|
||||
|
||||
/**
|
||||
* // Add to queue
|
||||
* if (this._async) {
|
||||
* fQueue_add(this);
|
||||
* } else { */
|
||||
fXMLHttpRequest_send(this);
|
||||
/**
|
||||
* }
|
||||
*/
|
||||
};
|
||||
|
||||
cXMLHttpRequest.prototype.abort = function() {
|
||||
// Add method sniffer
|
||||
if (cXMLHttpRequest.onabort) {
|
||||
cXMLHttpRequest.onabort.apply(this, arguments);
|
||||
}
|
||||
|
||||
// BUGFIX: Gecko - unnecessary DONE when aborting
|
||||
if (this.readyState > cXMLHttpRequest.UNSENT) {
|
||||
this._aborted = true;
|
||||
}
|
||||
|
||||
this._object.abort();
|
||||
|
||||
// BUGFIX: IE - memory leak
|
||||
fCleanTransport(this);
|
||||
|
||||
this.readyState = cXMLHttpRequest.UNSENT;
|
||||
|
||||
delete this._data;
|
||||
|
||||
/* if (this._async) {
|
||||
* fQueue_remove(this);
|
||||
* }
|
||||
*/
|
||||
};
|
||||
|
||||
cXMLHttpRequest.prototype.getAllResponseHeaders = function() {
|
||||
return this._object.getAllResponseHeaders();
|
||||
};
|
||||
|
||||
cXMLHttpRequest.prototype.getResponseHeader = function(sName) {
|
||||
return this._object.getResponseHeader(sName);
|
||||
};
|
||||
|
||||
cXMLHttpRequest.prototype.setRequestHeader = function(sName, sValue) {
|
||||
// BUGFIX: IE - cache issue
|
||||
if (!this._headers) {
|
||||
this._headers = {};
|
||||
}
|
||||
|
||||
this._headers[sName] = sValue;
|
||||
|
||||
return this._object.setRequestHeader(sName, sValue);
|
||||
};
|
||||
|
||||
// EventTarget interface implementation
|
||||
cXMLHttpRequest.prototype.addEventListener = function(sName, fHandler, bUseCapture) {
|
||||
for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++) {
|
||||
if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Add listener
|
||||
this._listeners.push([sName, fHandler, bUseCapture]);
|
||||
};
|
||||
|
||||
cXMLHttpRequest.prototype.removeEventListener = function(sName, fHandler, bUseCapture) {
|
||||
for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++) {
|
||||
if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove listener
|
||||
if (oListener) {
|
||||
this._listeners.splice(nIndex, 1);
|
||||
}
|
||||
};
|
||||
|
||||
cXMLHttpRequest.prototype.dispatchEvent = function(oEvent) {
|
||||
var oEventPseudo = {
|
||||
'type': oEvent.type,
|
||||
'target': this,
|
||||
'currentTarget': this,
|
||||
'eventPhase': 2,
|
||||
'bubbles': oEvent.bubbles,
|
||||
'cancelable': oEvent.cancelable,
|
||||
'timeStamp': oEvent.timeStamp,
|
||||
'stopPropagation': function() {}, // There is no flow
|
||||
'preventDefault': function() {}, // There is no default action
|
||||
'initEvent': function() {} // Original event object should be initialized
|
||||
};
|
||||
|
||||
// Execute onreadystatechange
|
||||
if (oEventPseudo.type == "readystatechange" && this.onreadystatechange) {
|
||||
(this.onreadystatechange.handleEvent || this.onreadystatechange).apply(this, [oEventPseudo]);
|
||||
}
|
||||
|
||||
|
||||
// Execute listeners
|
||||
for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++) {
|
||||
if (oListener[0] == oEventPseudo.type && !oListener[2]) {
|
||||
(oListener[1].handleEvent || oListener[1]).apply(this, [oEventPseudo]);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
cXMLHttpRequest.prototype.toString = function() {
|
||||
return '[' + "object" + ' ' + "XMLHttpRequest" + ']';
|
||||
};
|
||||
|
||||
cXMLHttpRequest.toString = function() {
|
||||
return '[' + "XMLHttpRequest" + ']';
|
||||
};
|
||||
|
||||
/**
|
||||
* // Queue manager
|
||||
* var oQueuePending = {"CRITICAL":[],"HIGH":[],"NORMAL":[],"LOW":[],"LOWEST":[]},
|
||||
* aQueueRunning = [];
|
||||
* function fQueue_add(oRequest) {
|
||||
* oQueuePending[oRequest.priority in oQueuePending ? oRequest.priority : "NORMAL"].push(oRequest);
|
||||
* //
|
||||
* setTimeout(fQueue_process);
|
||||
* };
|
||||
*
|
||||
* function fQueue_remove(oRequest) {
|
||||
* for (var nIndex = 0, bFound = false; nIndex < aQueueRunning.length; nIndex++)
|
||||
* if (bFound) {
|
||||
* aQueueRunning[nIndex - 1] = aQueueRunning[nIndex];
|
||||
* } else {
|
||||
* if (aQueueRunning[nIndex] == oRequest) {
|
||||
* bFound = true;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* if (bFound) {
|
||||
* aQueueRunning.length--;
|
||||
* }
|
||||
*
|
||||
*
|
||||
* //
|
||||
* setTimeout(fQueue_process);
|
||||
* };
|
||||
*
|
||||
* function fQueue_process() {
|
||||
* if (aQueueRunning.length < 6) {
|
||||
* for (var sPriority in oQueuePending) {
|
||||
* if (oQueuePending[sPriority].length) {
|
||||
* var oRequest = oQueuePending[sPriority][0];
|
||||
* oQueuePending[sPriority] = oQueuePending[sPriority].slice(1);
|
||||
* //
|
||||
* aQueueRunning.push(oRequest);
|
||||
* // Send request
|
||||
* fXMLHttpRequest_send(oRequest);
|
||||
* break;
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* };
|
||||
*/
|
||||
|
||||
// Helper function
|
||||
function fXMLHttpRequest_send(oRequest) {
|
||||
oRequest._object.send(oRequest._data);
|
||||
|
||||
// BUGFIX: Gecko - missing readystatechange calls in synchronous requests
|
||||
if (bGecko && !oRequest._async) {
|
||||
oRequest.readyState = cXMLHttpRequest.OPENED;
|
||||
|
||||
// Synchronize state
|
||||
fSynchronizeValues(oRequest);
|
||||
|
||||
// Simulate missing states
|
||||
while (oRequest.readyState < cXMLHttpRequest.DONE) {
|
||||
oRequest.readyState++;
|
||||
fReadyStateChange(oRequest);
|
||||
// Check if we are aborted
|
||||
if (oRequest._aborted) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fReadyStateChange(oRequest) {
|
||||
// Sniffing code
|
||||
if (cXMLHttpRequest.onreadystatechange){
|
||||
cXMLHttpRequest.onreadystatechange.apply(oRequest);
|
||||
}
|
||||
|
||||
|
||||
// Fake event
|
||||
oRequest.dispatchEvent({
|
||||
'type': "readystatechange",
|
||||
'bubbles': false,
|
||||
'cancelable': false,
|
||||
'timeStamp': new Date + 0
|
||||
});
|
||||
}
|
||||
|
||||
function fGetDocument(oRequest) {
|
||||
var oDocument = oRequest.responseXML;
|
||||
var sResponse = oRequest.responseText;
|
||||
// Try parsing responseText
|
||||
if (bIE && sResponse && oDocument && !oDocument.documentElement && oRequest.getResponseHeader("Content-Type").match(/[^\/]+\/[^\+]+\+xml/)) {
|
||||
oDocument = new window.ActiveXObject("Microsoft.XMLDOM");
|
||||
oDocument.async = false;
|
||||
oDocument.validateOnParse = false;
|
||||
oDocument.loadXML(sResponse);
|
||||
}
|
||||
|
||||
// Check if there is no error in document
|
||||
if (oDocument){
|
||||
if ((bIE && oDocument.parseError !== 0) || !oDocument.documentElement || (oDocument.documentElement && oDocument.documentElement.tagName == "parsererror")) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return oDocument;
|
||||
}
|
||||
|
||||
function fSynchronizeValues(oRequest) {
|
||||
try { oRequest.responseText = oRequest._object.responseText; } catch (e) {}
|
||||
try { oRequest.responseXML = fGetDocument(oRequest._object); } catch (e) {}
|
||||
try { oRequest.status = oRequest._object.status; } catch (e) {}
|
||||
try { oRequest.statusText = oRequest._object.statusText; } catch (e) {}
|
||||
}
|
||||
|
||||
function fCleanTransport(oRequest) {
|
||||
// BUGFIX: IE - memory leak (on-page leak)
|
||||
oRequest._object.onreadystatechange = new window.Function;
|
||||
}
|
||||
|
||||
// Internet Explorer 5.0 (missing apply)
|
||||
if (!window.Function.prototype.apply) {
|
||||
window.Function.prototype.apply = function(oRequest, oArguments) {
|
||||
if (!oArguments) {
|
||||
oArguments = [];
|
||||
}
|
||||
oRequest.__func = this;
|
||||
oRequest.__func(oArguments[0], oArguments[1], oArguments[2], oArguments[3], oArguments[4]);
|
||||
delete oRequest.__func;
|
||||
};
|
||||
}
|
||||
|
||||
// Register new object with window
|
||||
window.XMLHttpRequest = cXMLHttpRequest;
|
||||
|
||||
})();
|
2185
node_modules/esprima/test/3rdparty/ZeParser.js
generated
vendored
2185
node_modules/esprima/test/3rdparty/ZeParser.js
generated
vendored
File diff suppressed because it is too large
Load Diff
1158
node_modules/esprima/test/3rdparty/backbone-0.5.3.js
generated
vendored
1158
node_modules/esprima/test/3rdparty/backbone-0.5.3.js
generated
vendored
File diff suppressed because it is too large
Load Diff
3261
node_modules/esprima/test/3rdparty/benchmark.js
generated
vendored
3261
node_modules/esprima/test/3rdparty/benchmark.js
generated
vendored
File diff suppressed because it is too large
Load Diff
906
node_modules/esprima/test/3rdparty/escodegen.js
generated
vendored
906
node_modules/esprima/test/3rdparty/escodegen.js
generated
vendored
@@ -1,906 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
|
||||
Copyright (C) 2012 Mathias Bynens <mathias@qiwi.be>
|
||||
Copyright (C) 2012 Joost-Wim Boekesteijn <joost-wim@boekesteijn.nl>
|
||||
Copyright (C) 2012 Kris Kowal <kris.kowal@cixar.com>
|
||||
Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>
|
||||
Copyright (C) 2012 Arpad Borsos <arpad.borsos@googlemail.com>
|
||||
Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*jslint bitwise:true */
|
||||
/*global escodegen:true, exports:true, generateStatement: true*/
|
||||
|
||||
(function (exports) {
|
||||
'use strict';
|
||||
|
||||
var Syntax,
|
||||
Precedence,
|
||||
BinaryPrecedence,
|
||||
base,
|
||||
indent,
|
||||
extra,
|
||||
parse;
|
||||
|
||||
Syntax = {
|
||||
AssignmentExpression: 'AssignmentExpression',
|
||||
ArrayExpression: 'ArrayExpression',
|
||||
BlockStatement: 'BlockStatement',
|
||||
BinaryExpression: 'BinaryExpression',
|
||||
BreakStatement: 'BreakStatement',
|
||||
CallExpression: 'CallExpression',
|
||||
CatchClause: 'CatchClause',
|
||||
ConditionalExpression: 'ConditionalExpression',
|
||||
ContinueStatement: 'ContinueStatement',
|
||||
DoWhileStatement: 'DoWhileStatement',
|
||||
DebuggerStatement: 'DebuggerStatement',
|
||||
EmptyStatement: 'EmptyStatement',
|
||||
ExpressionStatement: 'ExpressionStatement',
|
||||
ForStatement: 'ForStatement',
|
||||
ForInStatement: 'ForInStatement',
|
||||
FunctionDeclaration: 'FunctionDeclaration',
|
||||
FunctionExpression: 'FunctionExpression',
|
||||
Identifier: 'Identifier',
|
||||
IfStatement: 'IfStatement',
|
||||
Literal: 'Literal',
|
||||
LabeledStatement: 'LabeledStatement',
|
||||
LogicalExpression: 'LogicalExpression',
|
||||
MemberExpression: 'MemberExpression',
|
||||
NewExpression: 'NewExpression',
|
||||
ObjectExpression: 'ObjectExpression',
|
||||
Program: 'Program',
|
||||
Property: 'Property',
|
||||
ReturnStatement: 'ReturnStatement',
|
||||
SequenceExpression: 'SequenceExpression',
|
||||
SwitchStatement: 'SwitchStatement',
|
||||
SwitchCase: 'SwitchCase',
|
||||
ThisExpression: 'ThisExpression',
|
||||
ThrowStatement: 'ThrowStatement',
|
||||
TryStatement: 'TryStatement',
|
||||
UnaryExpression: 'UnaryExpression',
|
||||
UpdateExpression: 'UpdateExpression',
|
||||
VariableDeclaration: 'VariableDeclaration',
|
||||
VariableDeclarator: 'VariableDeclarator',
|
||||
WhileStatement: 'WhileStatement',
|
||||
WithStatement: 'WithStatement'
|
||||
};
|
||||
|
||||
Precedence = {
|
||||
Sequence: 0,
|
||||
Assignment: 1,
|
||||
Conditional: 2,
|
||||
LogicalOR: 3,
|
||||
LogicalAND: 4,
|
||||
LogicalXOR: 5,
|
||||
BitwiseOR: 6,
|
||||
BitwiseAND: 7,
|
||||
Equality: 8,
|
||||
Relational: 9,
|
||||
BitwiseSHIFT: 10,
|
||||
Additive: 11,
|
||||
Multiplicative: 12,
|
||||
Unary: 13,
|
||||
Postfix: 14,
|
||||
Call: 15,
|
||||
New: 16,
|
||||
Member: 17,
|
||||
Primary: 18
|
||||
};
|
||||
|
||||
BinaryPrecedence = {
|
||||
'||': Precedence.LogicalOR,
|
||||
'&&': Precedence.LogicalAND,
|
||||
'^': Precedence.LogicalXOR,
|
||||
'|': Precedence.BitwiseOR,
|
||||
'&': Precedence.BitwiseAND,
|
||||
'==': Precedence.Equality,
|
||||
'!=': Precedence.Equality,
|
||||
'===': Precedence.Equality,
|
||||
'!==': Precedence.Equality,
|
||||
'<': Precedence.Relational,
|
||||
'>': Precedence.Relational,
|
||||
'<=': Precedence.Relational,
|
||||
'>=': Precedence.Relational,
|
||||
'in': Precedence.Relational,
|
||||
'instanceof': Precedence.Relational,
|
||||
'<<': Precedence.BitwiseSHIFT,
|
||||
'>>': Precedence.BitwiseSHIFT,
|
||||
'>>>': Precedence.BitwiseSHIFT,
|
||||
'+': Precedence.Additive,
|
||||
'-': Precedence.Additive,
|
||||
'*': Precedence.Multiplicative,
|
||||
'%': Precedence.Multiplicative,
|
||||
'/': Precedence.Multiplicative
|
||||
};
|
||||
|
||||
function getDefaultOptions() {
|
||||
// default options
|
||||
return {
|
||||
indent: null,
|
||||
base: null,
|
||||
parse: null,
|
||||
format: {
|
||||
indent: {
|
||||
style: ' ',
|
||||
base: 0
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function unicodeEscape(ch) {
|
||||
var result, i;
|
||||
result = ch.charCodeAt(0).toString(16);
|
||||
for (i = result.length; i < 4; i += 1) {
|
||||
result = '0' + result;
|
||||
}
|
||||
return '\\u' + result;
|
||||
}
|
||||
|
||||
function stringToArray(str) {
|
||||
var length = str.length,
|
||||
result = [],
|
||||
i;
|
||||
for (i = 0; i < length; i += 1) {
|
||||
result[i] = str.charAt(i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function stringRepeat(str, num) {
|
||||
var result = '';
|
||||
|
||||
for (num |= 0; num > 0; num >>>= 1, str += str) {
|
||||
if (num & 1) {
|
||||
result += str;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function updateDeeply(target, override) {
|
||||
var key, val;
|
||||
|
||||
function isHashObject(target) {
|
||||
return typeof target === 'object' && target instanceof Object && !(target instanceof RegExp);
|
||||
}
|
||||
|
||||
for (key in override) {
|
||||
if (override.hasOwnProperty(key)) {
|
||||
val = override[key];
|
||||
if (isHashObject(val)) {
|
||||
if (isHashObject(target[key])) {
|
||||
updateDeeply(target[key], val);
|
||||
} else {
|
||||
target[key] = updateDeeply({}, val);
|
||||
}
|
||||
} else {
|
||||
target[key] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
function escapeString(str) {
|
||||
var result = '', i, len, ch;
|
||||
|
||||
if (typeof str[0] === 'undefined') {
|
||||
str = stringToArray(str);
|
||||
}
|
||||
|
||||
for (i = 0, len = str.length; i < len; i += 1) {
|
||||
ch = str[i];
|
||||
if ('\'\\\b\f\n\r\t'.indexOf(ch) >= 0) {
|
||||
result += '\\';
|
||||
switch (ch) {
|
||||
case '\'':
|
||||
result += '\'';
|
||||
break;
|
||||
case '\\':
|
||||
result += '\\';
|
||||
break;
|
||||
case '\b':
|
||||
result += 'b';
|
||||
break;
|
||||
case '\f':
|
||||
result += 'f';
|
||||
break;
|
||||
case '\n':
|
||||
result += 'n';
|
||||
break;
|
||||
case '\r':
|
||||
result += 'r';
|
||||
break;
|
||||
case '\t':
|
||||
result += 't';
|
||||
break;
|
||||
}
|
||||
} else if (ch < ' ' || ch.charCodeAt(0) >= 0x80) {
|
||||
result += unicodeEscape(ch);
|
||||
} else {
|
||||
result += ch;
|
||||
}
|
||||
}
|
||||
|
||||
return '\'' + result + '\'';
|
||||
}
|
||||
|
||||
function addIndent(stmt) {
|
||||
return base + stmt;
|
||||
}
|
||||
|
||||
function parenthesize(text, current, should) {
|
||||
return (current < should) ? '(' + text + ')' : text;
|
||||
}
|
||||
|
||||
function maybeBlock(stmt, suffix) {
|
||||
var previousBase, result;
|
||||
|
||||
if (stmt.type === Syntax.BlockStatement) {
|
||||
result = ' ' + generateStatement(stmt);
|
||||
if (suffix) {
|
||||
return result + ' ';
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (stmt.type === Syntax.EmptyStatement) {
|
||||
result = ';';
|
||||
} else {
|
||||
previousBase = base;
|
||||
base += indent;
|
||||
result = '\n' + addIndent(generateStatement(stmt));
|
||||
base = previousBase;
|
||||
}
|
||||
|
||||
if (suffix) {
|
||||
return result + '\n' + addIndent('');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function generateFunctionBody(node) {
|
||||
var result, i, len;
|
||||
result = '(';
|
||||
for (i = 0, len = node.params.length; i < len; i += 1) {
|
||||
result += node.params[i].name;
|
||||
if ((i + 1) < len) {
|
||||
result += ', ';
|
||||
}
|
||||
}
|
||||
return result + ')' + maybeBlock(node.body);
|
||||
}
|
||||
|
||||
function generateExpression(expr, precedence) {
|
||||
var result, currentPrecedence, previousBase, i, len, raw;
|
||||
|
||||
if (!precedence) {
|
||||
precedence = Precedence.Sequence;
|
||||
}
|
||||
|
||||
switch (expr.type) {
|
||||
case Syntax.SequenceExpression:
|
||||
result = '';
|
||||
for (i = 0, len = expr.expressions.length; i < len; i += 1) {
|
||||
result += generateExpression(expr.expressions[i], Precedence.Assignment);
|
||||
if ((i + 1) < len) {
|
||||
result += ', ';
|
||||
}
|
||||
}
|
||||
result = parenthesize(result, Precedence.Sequence, precedence);
|
||||
break;
|
||||
|
||||
case Syntax.AssignmentExpression:
|
||||
result = parenthesize(
|
||||
generateExpression(expr.left, Precedence.Call) + ' ' + expr.operator + ' ' +
|
||||
generateExpression(expr.right, Precedence.Assignment),
|
||||
Precedence.Assignment,
|
||||
precedence
|
||||
);
|
||||
break;
|
||||
|
||||
case Syntax.ConditionalExpression:
|
||||
result = parenthesize(
|
||||
generateExpression(expr.test, Precedence.LogicalOR) + ' ? ' +
|
||||
generateExpression(expr.consequent, Precedence.Assignment) + ' : ' +
|
||||
generateExpression(expr.alternate, Precedence.Assignment),
|
||||
Precedence.Conditional,
|
||||
precedence
|
||||
);
|
||||
break;
|
||||
|
||||
case Syntax.LogicalExpression:
|
||||
case Syntax.BinaryExpression:
|
||||
currentPrecedence = BinaryPrecedence[expr.operator];
|
||||
|
||||
result = generateExpression(expr.left, currentPrecedence) +
|
||||
' ' + expr.operator + ' ' +
|
||||
generateExpression(expr.right, currentPrecedence + 1);
|
||||
if (expr.operator === 'in') {
|
||||
// TODO parenthesize only in allowIn = false case
|
||||
result = '(' + result + ')';
|
||||
} else {
|
||||
result = parenthesize(result, currentPrecedence, precedence);
|
||||
}
|
||||
break;
|
||||
|
||||
case Syntax.CallExpression:
|
||||
result = '';
|
||||
for (i = 0, len = expr['arguments'].length; i < len; i += 1) {
|
||||
result += generateExpression(expr['arguments'][i], Precedence.Assignment);
|
||||
if ((i + 1) < len) {
|
||||
result += ', ';
|
||||
}
|
||||
}
|
||||
result = parenthesize(
|
||||
generateExpression(expr.callee, Precedence.Call) + '(' + result + ')',
|
||||
Precedence.Call,
|
||||
precedence
|
||||
);
|
||||
break;
|
||||
|
||||
case Syntax.NewExpression:
|
||||
result = '';
|
||||
for (i = 0, len = expr['arguments'].length; i < len; i += 1) {
|
||||
result += generateExpression(expr['arguments'][i], Precedence.Assignment);
|
||||
if ((i + 1) < len) {
|
||||
result += ', ';
|
||||
}
|
||||
}
|
||||
result = parenthesize(
|
||||
'new ' + generateExpression(expr.callee, Precedence.New) + '(' + result + ')',
|
||||
Precedence.New,
|
||||
precedence
|
||||
);
|
||||
break;
|
||||
|
||||
case Syntax.MemberExpression:
|
||||
result = generateExpression(expr.object, Precedence.Call);
|
||||
if (expr.computed) {
|
||||
result += '[' + generateExpression(expr.property) + ']';
|
||||
} else {
|
||||
if (expr.object.type === Syntax.Literal && typeof expr.object.value === 'number') {
|
||||
if (result.indexOf('.') < 0) {
|
||||
if (!/[eExX]/.test(result) && !(result.length >= 2 && result[0] === '0')) {
|
||||
result += '.';
|
||||
}
|
||||
}
|
||||
}
|
||||
result += '.' + expr.property.name;
|
||||
}
|
||||
result = parenthesize(result, Precedence.Member, precedence);
|
||||
break;
|
||||
|
||||
case Syntax.UnaryExpression:
|
||||
result = expr.operator;
|
||||
if (result.length > 2) {
|
||||
result += ' ';
|
||||
}
|
||||
result = parenthesize(
|
||||
result + generateExpression(expr.argument, Precedence.Unary +
|
||||
(
|
||||
expr.argument.type === Syntax.UnaryExpression &&
|
||||
expr.operator.length < 3 &&
|
||||
expr.argument.operator === expr.operator ? 1 : 0
|
||||
)
|
||||
),
|
||||
Precedence.Unary,
|
||||
precedence
|
||||
);
|
||||
break;
|
||||
|
||||
case Syntax.UpdateExpression:
|
||||
if (expr.prefix) {
|
||||
result = parenthesize(
|
||||
expr.operator +
|
||||
generateExpression(expr.argument, Precedence.Unary),
|
||||
Precedence.Unary,
|
||||
precedence
|
||||
);
|
||||
} else {
|
||||
result = parenthesize(
|
||||
generateExpression(expr.argument, Precedence.Postfix) +
|
||||
expr.operator,
|
||||
Precedence.Postfix,
|
||||
precedence
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case Syntax.FunctionExpression:
|
||||
result = 'function ';
|
||||
if (expr.id) {
|
||||
result += expr.id.name;
|
||||
}
|
||||
result += generateFunctionBody(expr);
|
||||
break;
|
||||
|
||||
case Syntax.ArrayExpression:
|
||||
if (!expr.elements.length) {
|
||||
result = '[]';
|
||||
break;
|
||||
}
|
||||
result = '[\n';
|
||||
previousBase = base;
|
||||
base += indent;
|
||||
for (i = 0, len = expr.elements.length; i < len; i += 1) {
|
||||
if (!expr.elements[i]) {
|
||||
result += addIndent('');
|
||||
if ((i + 1) === len) {
|
||||
result += ',';
|
||||
}
|
||||
} else {
|
||||
result += addIndent(generateExpression(expr.elements[i], Precedence.Assignment));
|
||||
}
|
||||
if ((i + 1) < len) {
|
||||
result += ',\n';
|
||||
}
|
||||
}
|
||||
base = previousBase;
|
||||
result += '\n' + addIndent(']');
|
||||
break;
|
||||
|
||||
case Syntax.Property:
|
||||
if (expr.kind === 'get' || expr.kind === 'set') {
|
||||
result = expr.kind + ' ' + generateExpression(expr.key) +
|
||||
generateFunctionBody(expr.value);
|
||||
} else {
|
||||
result = generateExpression(expr.key) + ': ' +
|
||||
generateExpression(expr.value, Precedence.Assignment);
|
||||
}
|
||||
break;
|
||||
|
||||
case Syntax.ObjectExpression:
|
||||
if (!expr.properties.length) {
|
||||
result = '{}';
|
||||
break;
|
||||
}
|
||||
result = '{\n';
|
||||
previousBase = base;
|
||||
base += indent;
|
||||
for (i = 0, len = expr.properties.length; i < len; i += 1) {
|
||||
result += addIndent(generateExpression(expr.properties[i]));
|
||||
if ((i + 1) < len) {
|
||||
result += ',\n';
|
||||
}
|
||||
}
|
||||
base = previousBase;
|
||||
result += '\n' + addIndent('}');
|
||||
break;
|
||||
|
||||
case Syntax.ThisExpression:
|
||||
result = 'this';
|
||||
break;
|
||||
|
||||
case Syntax.Identifier:
|
||||
result = expr.name;
|
||||
break;
|
||||
|
||||
case Syntax.Literal:
|
||||
if (expr.hasOwnProperty('raw') && parse) {
|
||||
try {
|
||||
raw = parse(expr.raw).body[0].expression;
|
||||
if (raw.type === Syntax.Literal) {
|
||||
if (raw.value === expr.value) {
|
||||
result = expr.raw;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// not use raw property
|
||||
}
|
||||
}
|
||||
|
||||
if (expr.value === null) {
|
||||
result = 'null';
|
||||
break;
|
||||
}
|
||||
|
||||
if (typeof expr.value === 'string') {
|
||||
result = escapeString(expr.value);
|
||||
break;
|
||||
}
|
||||
|
||||
if (typeof expr.value === 'number' && expr.value === Infinity) {
|
||||
// Infinity is variable
|
||||
result = '1e+1000';
|
||||
break;
|
||||
}
|
||||
|
||||
result = expr.value.toString();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (result === undefined) {
|
||||
throw new Error('Unknown expression type: ' + expr.type);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function generateStatement(stmt) {
|
||||
var i, len, result, previousBase;
|
||||
|
||||
switch (stmt.type) {
|
||||
case Syntax.BlockStatement:
|
||||
result = '{\n';
|
||||
|
||||
previousBase = base;
|
||||
base += indent;
|
||||
for (i = 0, len = stmt.body.length; i < len; i += 1) {
|
||||
result += addIndent(generateStatement(stmt.body[i])) + '\n';
|
||||
}
|
||||
base = previousBase;
|
||||
|
||||
result += addIndent('}');
|
||||
break;
|
||||
|
||||
case Syntax.BreakStatement:
|
||||
if (stmt.label) {
|
||||
result = 'break ' + stmt.label.name + ';';
|
||||
} else {
|
||||
result = 'break;';
|
||||
}
|
||||
break;
|
||||
|
||||
case Syntax.ContinueStatement:
|
||||
if (stmt.label) {
|
||||
result = 'continue ' + stmt.label.name + ';';
|
||||
} else {
|
||||
result = 'continue;';
|
||||
}
|
||||
break;
|
||||
|
||||
case Syntax.DoWhileStatement:
|
||||
result = 'do' + maybeBlock(stmt.body, true) + 'while (' + generateExpression(stmt.test) + ');';
|
||||
break;
|
||||
|
||||
case Syntax.CatchClause:
|
||||
previousBase = base;
|
||||
base += indent;
|
||||
result = ' catch (' + generateExpression(stmt.param) + ')';
|
||||
base = previousBase;
|
||||
result += maybeBlock(stmt.body);
|
||||
break;
|
||||
|
||||
case Syntax.DebuggerStatement:
|
||||
result = 'debugger;';
|
||||
break;
|
||||
|
||||
case Syntax.EmptyStatement:
|
||||
result = ';';
|
||||
break;
|
||||
|
||||
case Syntax.ExpressionStatement:
|
||||
result = generateExpression(stmt.expression);
|
||||
// 12.4 '{', 'function' is not allowed in this position.
|
||||
// wrap espression with parentheses
|
||||
if (result[0] === '{' || result.indexOf('function ') === 0) {
|
||||
result = '(' + result + ');';
|
||||
} else {
|
||||
result += ';';
|
||||
}
|
||||
break;
|
||||
|
||||
case Syntax.VariableDeclarator:
|
||||
if (stmt.init) {
|
||||
result = stmt.id.name + ' = ' + generateExpression(stmt.init, Precedence.Assignment);
|
||||
} else {
|
||||
result = stmt.id.name;
|
||||
}
|
||||
break;
|
||||
|
||||
case Syntax.VariableDeclaration:
|
||||
result = stmt.kind + ' ';
|
||||
// special path for
|
||||
// var x = function () {
|
||||
// };
|
||||
if (stmt.declarations.length === 1 && stmt.declarations[0].init &&
|
||||
stmt.declarations[0].init.type === Syntax.FunctionExpression) {
|
||||
result += generateStatement(stmt.declarations[0]);
|
||||
} else {
|
||||
previousBase = base;
|
||||
base += indent;
|
||||
for (i = 0, len = stmt.declarations.length; i < len; i += 1) {
|
||||
result += generateStatement(stmt.declarations[i]);
|
||||
if ((i + 1) < len) {
|
||||
result += ', ';
|
||||
}
|
||||
}
|
||||
base = previousBase;
|
||||
}
|
||||
result += ';';
|
||||
break;
|
||||
|
||||
case Syntax.ThrowStatement:
|
||||
result = 'throw ' + generateExpression(stmt.argument) + ';';
|
||||
break;
|
||||
|
||||
case Syntax.TryStatement:
|
||||
result = 'try' + maybeBlock(stmt.block);
|
||||
for (i = 0, len = stmt.handlers.length; i < len; i += 1) {
|
||||
result += generateStatement(stmt.handlers[i]);
|
||||
}
|
||||
if (stmt.finalizer) {
|
||||
result += ' finally' + maybeBlock(stmt.finalizer);
|
||||
}
|
||||
break;
|
||||
|
||||
case Syntax.SwitchStatement:
|
||||
previousBase = base;
|
||||
base += indent;
|
||||
result = 'switch (' + generateExpression(stmt.discriminant) + ') {\n';
|
||||
base = previousBase;
|
||||
if (stmt.cases) {
|
||||
for (i = 0, len = stmt.cases.length; i < len; i += 1) {
|
||||
result += addIndent(generateStatement(stmt.cases[i])) + '\n';
|
||||
}
|
||||
}
|
||||
result += addIndent('}');
|
||||
break;
|
||||
|
||||
case Syntax.SwitchCase:
|
||||
previousBase = base;
|
||||
base += indent;
|
||||
if (stmt.test) {
|
||||
result = 'case ' + generateExpression(stmt.test) + ':';
|
||||
} else {
|
||||
result = 'default:';
|
||||
}
|
||||
|
||||
i = 0;
|
||||
len = stmt.consequent.length;
|
||||
if (len && stmt.consequent[0].type === Syntax.BlockStatement) {
|
||||
result += maybeBlock(stmt.consequent[0]);
|
||||
i = 1;
|
||||
}
|
||||
|
||||
for (; i < len; i += 1) {
|
||||
result += '\n' + addIndent(generateStatement(stmt.consequent[i]));
|
||||
}
|
||||
|
||||
base = previousBase;
|
||||
break;
|
||||
|
||||
case Syntax.IfStatement:
|
||||
if (stmt.alternate) {
|
||||
if (stmt.alternate.type === Syntax.IfStatement) {
|
||||
previousBase = base;
|
||||
base += indent;
|
||||
result = 'if (' + generateExpression(stmt.test) + ')';
|
||||
base = previousBase;
|
||||
result += maybeBlock(stmt.consequent, true) + 'else ' + generateStatement(stmt.alternate);
|
||||
} else {
|
||||
previousBase = base;
|
||||
base += indent;
|
||||
result = 'if (' + generateExpression(stmt.test) + ')';
|
||||
base = previousBase;
|
||||
result += maybeBlock(stmt.consequent, true) + 'else' + maybeBlock(stmt.alternate);
|
||||
}
|
||||
} else {
|
||||
previousBase = base;
|
||||
base += indent;
|
||||
result = 'if (' + generateExpression(stmt.test) + ')';
|
||||
base = previousBase;
|
||||
result += maybeBlock(stmt.consequent);
|
||||
}
|
||||
break;
|
||||
|
||||
case Syntax.ForStatement:
|
||||
previousBase = base;
|
||||
base += indent;
|
||||
result = 'for (';
|
||||
if (stmt.init) {
|
||||
if (stmt.init.type === Syntax.VariableDeclaration) {
|
||||
result += generateStatement(stmt.init);
|
||||
} else {
|
||||
result += generateExpression(stmt.init) + ';';
|
||||
}
|
||||
} else {
|
||||
result += ';';
|
||||
}
|
||||
|
||||
if (stmt.test) {
|
||||
result += ' ' + generateExpression(stmt.test) + ';';
|
||||
} else {
|
||||
result += ';';
|
||||
}
|
||||
|
||||
if (stmt.update) {
|
||||
result += ' ' + generateExpression(stmt.update) + ')';
|
||||
} else {
|
||||
result += ')';
|
||||
}
|
||||
base = previousBase;
|
||||
|
||||
result += maybeBlock(stmt.body);
|
||||
break;
|
||||
|
||||
case Syntax.ForInStatement:
|
||||
result = 'for (';
|
||||
if (stmt.left.type === Syntax.VariableDeclaration) {
|
||||
previousBase = base;
|
||||
base += indent + indent;
|
||||
result += stmt.left.kind + ' ' + generateStatement(stmt.left.declarations[0]);
|
||||
base = previousBase;
|
||||
} else {
|
||||
previousBase = base;
|
||||
base += indent;
|
||||
result += generateExpression(stmt.left, Precedence.Call);
|
||||
base = previousBase;
|
||||
}
|
||||
|
||||
previousBase = base;
|
||||
base += indent;
|
||||
result += ' in ' + generateExpression(stmt.right) + ')';
|
||||
base = previousBase;
|
||||
result += maybeBlock(stmt.body);
|
||||
break;
|
||||
|
||||
case Syntax.LabeledStatement:
|
||||
result = stmt.label.name + ':' + maybeBlock(stmt.body);
|
||||
break;
|
||||
|
||||
case Syntax.Program:
|
||||
result = '';
|
||||
for (i = 0, len = stmt.body.length; i < len; i += 1) {
|
||||
result += generateStatement(stmt.body[i]);
|
||||
if ((i + 1) < len) {
|
||||
result += '\n';
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Syntax.FunctionDeclaration:
|
||||
result = 'function ';
|
||||
if (stmt.id) {
|
||||
result += stmt.id.name;
|
||||
}
|
||||
result += generateFunctionBody(stmt);
|
||||
break;
|
||||
|
||||
case Syntax.ReturnStatement:
|
||||
if (stmt.argument) {
|
||||
result = 'return ' + generateExpression(stmt.argument) + ';';
|
||||
} else {
|
||||
result = 'return;';
|
||||
}
|
||||
break;
|
||||
|
||||
case Syntax.WhileStatement:
|
||||
previousBase = base;
|
||||
base += indent;
|
||||
result = 'while (' + generateExpression(stmt.test) + ')';
|
||||
base = previousBase;
|
||||
result += maybeBlock(stmt.body);
|
||||
break;
|
||||
|
||||
case Syntax.WithStatement:
|
||||
previousBase = base;
|
||||
base += indent;
|
||||
result = 'with (' + generateExpression(stmt.object) + ')';
|
||||
base = previousBase;
|
||||
result += maybeBlock(stmt.body);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (result === undefined) {
|
||||
throw new Error('Unknown statement type: ' + stmt.type);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function generate(node, options) {
|
||||
var defaultOptions = getDefaultOptions();
|
||||
|
||||
if (typeof options !== 'undefined') {
|
||||
// Obsolete options
|
||||
//
|
||||
// `options.indent`
|
||||
// `options.base`
|
||||
//
|
||||
// Instead of them, we can use `option.format.indent`.
|
||||
if (typeof options.indent === 'string') {
|
||||
defaultOptions.format.style = options.indent;
|
||||
}
|
||||
|
||||
options = updateDeeply(defaultOptions, options);
|
||||
indent = options.format.style;
|
||||
if (typeof options.base === 'string') {
|
||||
base = options.base;
|
||||
} else {
|
||||
base = stringRepeat(indent, options.format.base);
|
||||
}
|
||||
parse = options.parse;
|
||||
} else {
|
||||
options = defaultOptions;
|
||||
indent = options.format.style;
|
||||
base = stringRepeat(indent, options.format.base);
|
||||
parse = options.parse;
|
||||
}
|
||||
|
||||
switch (node.type) {
|
||||
case Syntax.BlockStatement:
|
||||
case Syntax.BreakStatement:
|
||||
case Syntax.CatchClause:
|
||||
case Syntax.ContinueStatement:
|
||||
case Syntax.DoWhileStatement:
|
||||
case Syntax.DebuggerStatement:
|
||||
case Syntax.EmptyStatement:
|
||||
case Syntax.ExpressionStatement:
|
||||
case Syntax.ForStatement:
|
||||
case Syntax.ForInStatement:
|
||||
case Syntax.FunctionDeclaration:
|
||||
case Syntax.IfStatement:
|
||||
case Syntax.LabeledStatement:
|
||||
case Syntax.Program:
|
||||
case Syntax.ReturnStatement:
|
||||
case Syntax.SwitchStatement:
|
||||
case Syntax.SwitchCase:
|
||||
case Syntax.ThrowStatement:
|
||||
case Syntax.TryStatement:
|
||||
case Syntax.VariableDeclaration:
|
||||
case Syntax.VariableDeclarator:
|
||||
case Syntax.WhileStatement:
|
||||
case Syntax.WithStatement:
|
||||
return generateStatement(node);
|
||||
|
||||
case Syntax.AssignmentExpression:
|
||||
case Syntax.ArrayExpression:
|
||||
case Syntax.BinaryExpression:
|
||||
case Syntax.CallExpression:
|
||||
case Syntax.ConditionalExpression:
|
||||
case Syntax.FunctionExpression:
|
||||
case Syntax.Identifier:
|
||||
case Syntax.Literal:
|
||||
case Syntax.LogicalExpression:
|
||||
case Syntax.MemberExpression:
|
||||
case Syntax.NewExpression:
|
||||
case Syntax.ObjectExpression:
|
||||
case Syntax.Property:
|
||||
case Syntax.SequenceExpression:
|
||||
case Syntax.ThisExpression:
|
||||
case Syntax.UnaryExpression:
|
||||
case Syntax.UpdateExpression:
|
||||
return generateExpression(node);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
throw new Error('Unknown node type: ' + node.type);
|
||||
}
|
||||
|
||||
// Sync with package.json.
|
||||
exports.version = '0.0.3-dev';
|
||||
|
||||
exports.generate = generate;
|
||||
|
||||
}(typeof exports === 'undefined' ? (escodegen = {}) : exports));
|
||||
/* vim: set sw=4 ts=4 et tw=80 : */
|
240
node_modules/esprima/test/3rdparty/esmorph.js
generated
vendored
240
node_modules/esprima/test/3rdparty/esmorph.js
generated
vendored
@@ -1,240 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*jslint node:true browser:true */
|
||||
/*global esmorph:true,esprima:true */
|
||||
|
||||
(function (exports) {
|
||||
'use strict';
|
||||
|
||||
var Syntax = {
|
||||
AssignmentExpression: 'AssignmentExpression',
|
||||
ArrayExpression: 'ArrayExpression',
|
||||
BlockStatement: 'BlockStatement',
|
||||
BinaryExpression: 'BinaryExpression',
|
||||
BreakStatement: 'BreakStatement',
|
||||
CallExpression: 'CallExpression',
|
||||
CatchClause: 'CatchClause',
|
||||
ConditionalExpression: 'ConditionalExpression',
|
||||
ContinueStatement: 'ContinueStatement',
|
||||
DoWhileStatement: 'DoWhileStatement',
|
||||
DebuggerStatement: 'DebuggerStatement',
|
||||
EmptyStatement: 'EmptyStatement',
|
||||
ExpressionStatement: 'ExpressionStatement',
|
||||
ForStatement: 'ForStatement',
|
||||
ForInStatement: 'ForInStatement',
|
||||
FunctionDeclaration: 'FunctionDeclaration',
|
||||
FunctionExpression: 'FunctionExpression',
|
||||
Identifier: 'Identifier',
|
||||
IfStatement: 'IfStatement',
|
||||
Literal: 'Literal',
|
||||
LabeledStatement: 'LabeledStatement',
|
||||
LogicalExpression: 'LogicalExpression',
|
||||
MemberExpression: 'MemberExpression',
|
||||
NewExpression: 'NewExpression',
|
||||
ObjectExpression: 'ObjectExpression',
|
||||
Program: 'Program',
|
||||
Property: 'Property',
|
||||
ReturnStatement: 'ReturnStatement',
|
||||
SequenceExpression: 'SequenceExpression',
|
||||
SwitchStatement: 'SwitchStatement',
|
||||
SwitchCase: 'SwitchCase',
|
||||
ThisExpression: 'ThisExpression',
|
||||
ThrowStatement: 'ThrowStatement',
|
||||
TryStatement: 'TryStatement',
|
||||
UnaryExpression: 'UnaryExpression',
|
||||
UpdateExpression: 'UpdateExpression',
|
||||
VariableDeclaration: 'VariableDeclaration',
|
||||
VariableDeclarator: 'VariableDeclarator',
|
||||
WhileStatement: 'WhileStatement',
|
||||
WithStatement: 'WithStatement'
|
||||
};
|
||||
|
||||
// Executes visitor on the object and its children (recursively).
|
||||
|
||||
function traverse(object, visitor, master) {
|
||||
var key, child, parent, path;
|
||||
|
||||
parent = (typeof master === 'undefined') ? [] : master;
|
||||
|
||||
if (visitor.call(null, object, parent) === false) {
|
||||
return;
|
||||
}
|
||||
for (key in object) {
|
||||
if (object.hasOwnProperty(key)) {
|
||||
child = object[key];
|
||||
path = [ object ];
|
||||
path.push(parent);
|
||||
if (typeof child === 'object' && child !== null) {
|
||||
traverse(child, visitor, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Insert a prolog in the body of every function.
|
||||
// It will be in the form of a function call:
|
||||
//
|
||||
// traceName(object);
|
||||
//
|
||||
// where the object contains the following properties:
|
||||
//
|
||||
// 'name' holds the name of the function
|
||||
// 'lineNumber' holds the starting line number of the function block
|
||||
// 'range' contains the index-based range of the function
|
||||
//
|
||||
// The name of the function represents the associated reference for
|
||||
// the function (deduced on a best-effort basis if it is not
|
||||
// a function declaration).
|
||||
//
|
||||
// If traceName is a function instead of a string, it will be invoked and
|
||||
// the result will be used as the entire prolog. The arguments for the
|
||||
// invocation are the function name, range, and location info.
|
||||
|
||||
function traceFunctionEntrance(traceName) {
|
||||
|
||||
return function (code) {
|
||||
var tree,
|
||||
functionList,
|
||||
param,
|
||||
signature,
|
||||
pos,
|
||||
i;
|
||||
|
||||
|
||||
tree = esprima.parse(code, { range: true, loc: true });
|
||||
|
||||
functionList = [];
|
||||
traverse(tree, function (node, path) {
|
||||
var parent;
|
||||
if (node.type === Syntax.FunctionDeclaration) {
|
||||
functionList.push({
|
||||
name: node.id.name,
|
||||
range: node.range,
|
||||
loc: node.loc,
|
||||
blockStart: node.body.range[0]
|
||||
});
|
||||
} else if (node.type === Syntax.FunctionExpression) {
|
||||
parent = path[0];
|
||||
if (parent.type === Syntax.AssignmentExpression) {
|
||||
if (typeof parent.left.range !== 'undefined') {
|
||||
functionList.push({
|
||||
name: code.slice(parent.left.range[0],
|
||||
parent.left.range[1] + 1),
|
||||
range: node.range,
|
||||
loc: node.loc,
|
||||
blockStart: node.body.range[0]
|
||||
});
|
||||
}
|
||||
} else if (parent.type === Syntax.VariableDeclarator) {
|
||||
functionList.push({
|
||||
name: parent.id.name,
|
||||
range: node.range,
|
||||
loc: node.loc,
|
||||
blockStart: node.body.range[0]
|
||||
});
|
||||
} else if (parent.type === Syntax.CallExpression) {
|
||||
functionList.push({
|
||||
name: parent.id ? parent.id.name : '[Anonymous]',
|
||||
range: node.range,
|
||||
loc: node.loc,
|
||||
blockStart: node.body.range[0]
|
||||
});
|
||||
} else if (typeof parent.length === 'number') {
|
||||
functionList.push({
|
||||
name: parent.id ? parent.id.name : '[Anonymous]',
|
||||
range: node.range,
|
||||
loc: node.loc,
|
||||
blockStart: node.body.range[0]
|
||||
});
|
||||
} else if (typeof parent.key !== 'undefined') {
|
||||
if (parent.key.type === 'Identifier') {
|
||||
if (parent.value === node && parent.key.name) {
|
||||
functionList.push({
|
||||
name: parent.key.name,
|
||||
range: node.range,
|
||||
loc: node.loc,
|
||||
blockStart: node.body.range[0]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Insert the instrumentation code from the last entry.
|
||||
// This is to ensure that the range for each entry remains valid)
|
||||
// (it won't shift due to some new inserting string before the range).
|
||||
for (i = functionList.length - 1; i >= 0; i -= 1) {
|
||||
param = {
|
||||
name: functionList[i].name,
|
||||
range: functionList[i].range,
|
||||
loc: functionList[i].loc
|
||||
};
|
||||
if (typeof traceName === 'function') {
|
||||
signature = traceName.call(null, param);
|
||||
} else {
|
||||
signature = traceName + '({ ';
|
||||
signature += 'name: \'' + functionList[i].name + '\', ';
|
||||
if (typeof functionList[i].loc !== 'undefined') {
|
||||
signature += 'lineNumber: ' + functionList[i].loc.start.line + ', ';
|
||||
}
|
||||
signature += 'range: [' + functionList[i].range[0] + ', ' +
|
||||
functionList[i].range[1] + '] ';
|
||||
signature += '});';
|
||||
}
|
||||
pos = functionList[i].blockStart + 1;
|
||||
code = code.slice(0, pos) + '\n' + signature + code.slice(pos, code.length);
|
||||
}
|
||||
|
||||
return code;
|
||||
};
|
||||
}
|
||||
|
||||
function modify(code, modifiers) {
|
||||
var i;
|
||||
|
||||
if (Object.prototype.toString.call(modifiers) === '[object Array]') {
|
||||
for (i = 0; i < modifiers.length; i += 1) {
|
||||
code = modifiers[i].call(null, code);
|
||||
}
|
||||
} else if (typeof modifiers === 'function') {
|
||||
code = modifiers.call(null, code);
|
||||
} else {
|
||||
throw new Error('Wrong use of esmorph.modify() function');
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
// Sync with package.json.
|
||||
exports.version = '0.0.0-dev';
|
||||
|
||||
exports.modify = modify;
|
||||
|
||||
exports.Tracer = {
|
||||
FunctionEntrance: traceFunctionEntrance
|
||||
};
|
||||
|
||||
}(typeof exports === 'undefined' ? (esmorph = {}) : exports));
|
6579
node_modules/esprima/test/3rdparty/ext-core-3.0.0.js
generated
vendored
6579
node_modules/esprima/test/3rdparty/ext-core-3.0.0.js
generated
vendored
File diff suppressed because it is too large
Load Diff
10255
node_modules/esprima/test/3rdparty/ext-core-3.1.0.js
generated
vendored
10255
node_modules/esprima/test/3rdparty/ext-core-3.1.0.js
generated
vendored
File diff suppressed because it is too large
Load Diff
9046
node_modules/esprima/test/3rdparty/jquery-1.6.4.js
generated
vendored
9046
node_modules/esprima/test/3rdparty/jquery-1.6.4.js
generated
vendored
File diff suppressed because it is too large
Load Diff
9266
node_modules/esprima/test/3rdparty/jquery-1.7.1.js
generated
vendored
9266
node_modules/esprima/test/3rdparty/jquery-1.7.1.js
generated
vendored
File diff suppressed because it is too large
Load Diff
6951
node_modules/esprima/test/3rdparty/jquery.mobile-1.0.js
generated
vendored
6951
node_modules/esprima/test/3rdparty/jquery.mobile-1.0.js
generated
vendored
File diff suppressed because it is too large
Load Diff
731
node_modules/esprima/test/3rdparty/jsdefs.js
generated
vendored
731
node_modules/esprima/test/3rdparty/jsdefs.js
generated
vendored
@@ -1,731 +0,0 @@
|
||||
/* vim: set sw=4 ts=4 et tw=78: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Narcissus JavaScript engine.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Brendan Eich <brendan@mozilla.org>.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Tom Austin <taustin@ucsc.edu>
|
||||
* Brendan Eich <brendan@mozilla.org>
|
||||
* Shu-Yu Guo <shu@rfrn.org>
|
||||
* Dave Herman <dherman@mozilla.com>
|
||||
* Dimitris Vardoulakis <dimvar@ccs.neu.edu>
|
||||
* Patrick Walton <pcwalton@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/*
|
||||
* Narcissus - JS implemented in JS.
|
||||
*
|
||||
* Well-known constants and lookup tables. Many consts are generated from the
|
||||
* tokens table via eval to minimize redundancy, so consumers must be compiled
|
||||
* separately to take advantage of the simple switch-case constant propagation
|
||||
* done by SpiderMonkey.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
|
||||
var narcissus = {
|
||||
options: {
|
||||
version: 185,
|
||||
// Global variables to hide from the interpreter
|
||||
hiddenHostGlobals: { Narcissus: true },
|
||||
// Desugar SpiderMonkey language extensions?
|
||||
desugarExtensions: false,
|
||||
// Allow HTML comments?
|
||||
allowHTMLComments: false
|
||||
},
|
||||
hostSupportsEvalConst: (function() {
|
||||
try {
|
||||
return eval("(function(s) { eval(s); return x })('const x = true;')");
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
})(),
|
||||
hostGlobal: this
|
||||
};
|
||||
Narcissus = narcissus;
|
||||
})();
|
||||
|
||||
Narcissus.definitions = (function() {
|
||||
|
||||
var tokens = [
|
||||
// End of source.
|
||||
"END",
|
||||
|
||||
// Operators and punctuators. Some pair-wise order matters, e.g. (+, -)
|
||||
// and (UNARY_PLUS, UNARY_MINUS).
|
||||
"\n", ";",
|
||||
",",
|
||||
"=",
|
||||
"?", ":", "CONDITIONAL",
|
||||
"||",
|
||||
"&&",
|
||||
"|",
|
||||
"^",
|
||||
"&",
|
||||
"==", "!=", "===", "!==",
|
||||
"<", "<=", ">=", ">",
|
||||
"<<", ">>", ">>>",
|
||||
"+", "-",
|
||||
"*", "/", "%",
|
||||
"!", "~", "UNARY_PLUS", "UNARY_MINUS",
|
||||
"++", "--",
|
||||
".",
|
||||
"[", "]",
|
||||
"{", "}",
|
||||
"(", ")",
|
||||
|
||||
// Nonterminal tree node type codes.
|
||||
"SCRIPT", "BLOCK", "LABEL", "FOR_IN", "CALL", "NEW_WITH_ARGS", "INDEX",
|
||||
"ARRAY_INIT", "OBJECT_INIT", "PROPERTY_INIT", "GETTER", "SETTER",
|
||||
"GROUP", "LIST", "LET_BLOCK", "ARRAY_COMP", "GENERATOR", "COMP_TAIL",
|
||||
|
||||
// Terminals.
|
||||
"IDENTIFIER", "NUMBER", "STRING", "REGEXP",
|
||||
|
||||
// Keywords.
|
||||
"break",
|
||||
"case", "catch", "const", "continue",
|
||||
"debugger", "default", "delete", "do",
|
||||
"else", "export",
|
||||
"false", "finally", "for", "function",
|
||||
"if", "import", "in", "instanceof",
|
||||
"let", "module",
|
||||
"new", "null",
|
||||
"return",
|
||||
"switch",
|
||||
"this", "throw", "true", "try", "typeof",
|
||||
"var", "void",
|
||||
"yield",
|
||||
"while", "with",
|
||||
];
|
||||
|
||||
var statementStartTokens = [
|
||||
"break",
|
||||
"const", "continue",
|
||||
"debugger", "do",
|
||||
"for",
|
||||
"if",
|
||||
"return",
|
||||
"switch",
|
||||
"throw", "try",
|
||||
"var",
|
||||
"yield",
|
||||
"while", "with",
|
||||
];
|
||||
|
||||
// Whitespace characters (see ECMA-262 7.2)
|
||||
var whitespaceChars = [
|
||||
// normal whitespace:
|
||||
"\u0009", "\u000B", "\u000C", "\u0020", "\u00A0", "\uFEFF",
|
||||
|
||||
// high-Unicode whitespace:
|
||||
"\u1680", "\u180E",
|
||||
"\u2000", "\u2001", "\u2002", "\u2003", "\u2004", "\u2005", "\u2006",
|
||||
"\u2007", "\u2008", "\u2009", "\u200A",
|
||||
"\u202F", "\u205F", "\u3000"
|
||||
];
|
||||
|
||||
var whitespace = {};
|
||||
for (var i = 0; i < whitespaceChars.length; i++) {
|
||||
whitespace[whitespaceChars[i]] = true;
|
||||
}
|
||||
|
||||
// Operator and punctuator mapping from token to tree node type name.
|
||||
// NB: because the lexer doesn't backtrack, all token prefixes must themselves
|
||||
// be valid tokens (e.g. !== is acceptable because its prefixes are the valid
|
||||
// tokens != and !).
|
||||
var opTypeNames = {
|
||||
'\n': "NEWLINE",
|
||||
';': "SEMICOLON",
|
||||
',': "COMMA",
|
||||
'?': "HOOK",
|
||||
':': "COLON",
|
||||
'||': "OR",
|
||||
'&&': "AND",
|
||||
'|': "BITWISE_OR",
|
||||
'^': "BITWISE_XOR",
|
||||
'&': "BITWISE_AND",
|
||||
'===': "STRICT_EQ",
|
||||
'==': "EQ",
|
||||
'=': "ASSIGN",
|
||||
'!==': "STRICT_NE",
|
||||
'!=': "NE",
|
||||
'<<': "LSH",
|
||||
'<=': "LE",
|
||||
'<': "LT",
|
||||
'>>>': "URSH",
|
||||
'>>': "RSH",
|
||||
'>=': "GE",
|
||||
'>': "GT",
|
||||
'++': "INCREMENT",
|
||||
'--': "DECREMENT",
|
||||
'+': "PLUS",
|
||||
'-': "MINUS",
|
||||
'*': "MUL",
|
||||
'/': "DIV",
|
||||
'%': "MOD",
|
||||
'!': "NOT",
|
||||
'~': "BITWISE_NOT",
|
||||
'.': "DOT",
|
||||
'[': "LEFT_BRACKET",
|
||||
']': "RIGHT_BRACKET",
|
||||
'{': "LEFT_CURLY",
|
||||
'}': "RIGHT_CURLY",
|
||||
'(': "LEFT_PAREN",
|
||||
')': "RIGHT_PAREN"
|
||||
};
|
||||
|
||||
// Hash of keyword identifier to tokens index. NB: we must null __proto__ to
|
||||
// avoid toString, etc. namespace pollution.
|
||||
var keywords = {__proto__: null};
|
||||
|
||||
// Define const END, etc., based on the token names. Also map name to index.
|
||||
var tokenIds = {};
|
||||
|
||||
// Building up a string to be eval'd in different contexts.
|
||||
var consts = Narcissus.hostSupportsEvalConst ? "const " : "var ";
|
||||
for (var i = 0, j = tokens.length; i < j; i++) {
|
||||
if (i > 0)
|
||||
consts += ", ";
|
||||
var t = tokens[i];
|
||||
var name;
|
||||
if (/^[a-z]/.test(t)) {
|
||||
name = t.toUpperCase();
|
||||
keywords[t] = i;
|
||||
} else {
|
||||
name = (/^\W/.test(t) ? opTypeNames[t] : t);
|
||||
}
|
||||
consts += name + " = " + i;
|
||||
tokenIds[name] = i;
|
||||
tokens[t] = i;
|
||||
}
|
||||
consts += ";";
|
||||
|
||||
var isStatementStartCode = {__proto__: null};
|
||||
for (i = 0, j = statementStartTokens.length; i < j; i++)
|
||||
isStatementStartCode[keywords[statementStartTokens[i]]] = true;
|
||||
|
||||
// Map assignment operators to their indexes in the tokens array.
|
||||
var assignOps = ['|', '^', '&', '<<', '>>', '>>>', '+', '-', '*', '/', '%'];
|
||||
|
||||
for (i = 0, j = assignOps.length; i < j; i++) {
|
||||
t = assignOps[i];
|
||||
assignOps[t] = tokens[t];
|
||||
}
|
||||
|
||||
function defineGetter(obj, prop, fn, dontDelete, dontEnum) {
|
||||
Object.defineProperty(obj, prop,
|
||||
{ get: fn, configurable: !dontDelete, enumerable: !dontEnum });
|
||||
}
|
||||
|
||||
function defineGetterSetter(obj, prop, getter, setter, dontDelete, dontEnum) {
|
||||
Object.defineProperty(obj, prop, {
|
||||
get: getter,
|
||||
set: setter,
|
||||
configurable: !dontDelete,
|
||||
enumerable: !dontEnum
|
||||
});
|
||||
}
|
||||
|
||||
function defineMemoGetter(obj, prop, fn, dontDelete, dontEnum) {
|
||||
Object.defineProperty(obj, prop, {
|
||||
get: function() {
|
||||
var val = fn();
|
||||
defineProperty(obj, prop, val, dontDelete, true, dontEnum);
|
||||
return val;
|
||||
},
|
||||
configurable: true,
|
||||
enumerable: !dontEnum
|
||||
});
|
||||
}
|
||||
|
||||
function defineProperty(obj, prop, val, dontDelete, readOnly, dontEnum) {
|
||||
Object.defineProperty(obj, prop,
|
||||
{ value: val, writable: !readOnly, configurable: !dontDelete,
|
||||
enumerable: !dontEnum });
|
||||
}
|
||||
|
||||
// Returns true if fn is a native function. (Note: SpiderMonkey specific.)
|
||||
function isNativeCode(fn) {
|
||||
// Relies on the toString method to identify native code.
|
||||
return ((typeof fn) === "function") && fn.toString().match(/\[native code\]/);
|
||||
}
|
||||
|
||||
var Fpapply = Function.prototype.apply;
|
||||
|
||||
function apply(f, o, a) {
|
||||
return Fpapply.call(f, [o].concat(a));
|
||||
}
|
||||
|
||||
var applyNew;
|
||||
|
||||
// ES5's bind is a simpler way to implement applyNew
|
||||
if (Function.prototype.bind) {
|
||||
applyNew = function applyNew(f, a) {
|
||||
return new (f.bind.apply(f, [,].concat(a)))();
|
||||
};
|
||||
} else {
|
||||
applyNew = function applyNew(f, a) {
|
||||
switch (a.length) {
|
||||
case 0:
|
||||
return new f();
|
||||
case 1:
|
||||
return new f(a[0]);
|
||||
case 2:
|
||||
return new f(a[0], a[1]);
|
||||
case 3:
|
||||
return new f(a[0], a[1], a[2]);
|
||||
default:
|
||||
var argStr = "a[0]";
|
||||
for (var i = 1, n = a.length; i < n; i++)
|
||||
argStr += ",a[" + i + "]";
|
||||
return eval("new f(" + argStr + ")");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function getPropertyDescriptor(obj, name) {
|
||||
while (obj) {
|
||||
if (({}).hasOwnProperty.call(obj, name))
|
||||
return Object.getOwnPropertyDescriptor(obj, name);
|
||||
obj = Object.getPrototypeOf(obj);
|
||||
}
|
||||
}
|
||||
|
||||
function getPropertyNames(obj) {
|
||||
var table = Object.create(null, {});
|
||||
while (obj) {
|
||||
var names = Object.getOwnPropertyNames(obj);
|
||||
for (var i = 0, n = names.length; i < n; i++)
|
||||
table[names[i]] = true;
|
||||
obj = Object.getPrototypeOf(obj);
|
||||
}
|
||||
return Object.keys(table);
|
||||
}
|
||||
|
||||
function getOwnProperties(obj) {
|
||||
var map = {};
|
||||
for (var name in Object.getOwnPropertyNames(obj))
|
||||
map[name] = Object.getOwnPropertyDescriptor(obj, name);
|
||||
return map;
|
||||
}
|
||||
|
||||
function blacklistHandler(target, blacklist) {
|
||||
var mask = Object.create(null, {});
|
||||
var redirect = StringMap.create(blacklist).mapObject(function(name) { return mask; });
|
||||
return mixinHandler(redirect, target);
|
||||
}
|
||||
|
||||
function whitelistHandler(target, whitelist) {
|
||||
var catchall = Object.create(null, {});
|
||||
var redirect = StringMap.create(whitelist).mapObject(function(name) { return target; });
|
||||
return mixinHandler(redirect, catchall);
|
||||
}
|
||||
|
||||
function mirrorHandler(target, writable) {
|
||||
var handler = makePassthruHandler(target);
|
||||
|
||||
var defineProperty = handler.defineProperty;
|
||||
handler.defineProperty = function(name, desc) {
|
||||
if (!desc.enumerable)
|
||||
throw new Error("mirror property must be enumerable");
|
||||
if (!desc.configurable)
|
||||
throw new Error("mirror property must be configurable");
|
||||
if (desc.writable !== writable)
|
||||
throw new Error("mirror property must " + (writable ? "" : "not ") + "be writable");
|
||||
defineProperty(name, desc);
|
||||
};
|
||||
|
||||
handler.fix = function() { };
|
||||
handler.getOwnPropertyDescriptor = handler.getPropertyDescriptor;
|
||||
handler.getOwnPropertyNames = getPropertyNames.bind(handler, target);
|
||||
handler.keys = handler.enumerate;
|
||||
handler["delete"] = function() { return false; };
|
||||
handler.hasOwn = handler.has;
|
||||
return handler;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mixin proxies break the single-inheritance model of prototypes, so
|
||||
* the handler treats all properties as own-properties:
|
||||
*
|
||||
* X
|
||||
* |
|
||||
* +------------+------------+
|
||||
* | O |
|
||||
* | | |
|
||||
* | O O O |
|
||||
* | | | | |
|
||||
* | O O O O |
|
||||
* | | | | | |
|
||||
* | O O O O O |
|
||||
* | | | | | | |
|
||||
* +-(*)--(w)--(x)--(y)--(z)-+
|
||||
*/
|
||||
|
||||
function mixinHandler(redirect, catchall) {
|
||||
function targetFor(name) {
|
||||
return hasOwn(redirect, name) ? redirect[name] : catchall;
|
||||
}
|
||||
|
||||
function getMuxPropertyDescriptor(name) {
|
||||
var desc = getPropertyDescriptor(targetFor(name), name);
|
||||
if (desc)
|
||||
desc.configurable = true;
|
||||
return desc;
|
||||
}
|
||||
|
||||
function getMuxPropertyNames() {
|
||||
var names1 = Object.getOwnPropertyNames(redirect).filter(function(name) {
|
||||
return name in redirect[name];
|
||||
});
|
||||
var names2 = getPropertyNames(catchall).filter(function(name) {
|
||||
return !hasOwn(redirect, name);
|
||||
});
|
||||
return names1.concat(names2);
|
||||
}
|
||||
|
||||
function enumerateMux() {
|
||||
var result = Object.getOwnPropertyNames(redirect).filter(function(name) {
|
||||
return name in redirect[name];
|
||||
});
|
||||
for (name in catchall) {
|
||||
if (!hasOwn(redirect, name))
|
||||
result.push(name);
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
function hasMux(name) {
|
||||
return name in targetFor(name);
|
||||
}
|
||||
|
||||
return {
|
||||
getOwnPropertyDescriptor: getMuxPropertyDescriptor,
|
||||
getPropertyDescriptor: getMuxPropertyDescriptor,
|
||||
getOwnPropertyNames: getMuxPropertyNames,
|
||||
defineProperty: function(name, desc) {
|
||||
Object.defineProperty(targetFor(name), name, desc);
|
||||
},
|
||||
"delete": function(name) {
|
||||
var target = targetFor(name);
|
||||
return delete target[name];
|
||||
},
|
||||
// FIXME: ha ha ha
|
||||
fix: function() { },
|
||||
has: hasMux,
|
||||
hasOwn: hasMux,
|
||||
get: function(receiver, name) {
|
||||
var target = targetFor(name);
|
||||
return target[name];
|
||||
},
|
||||
set: function(receiver, name, val) {
|
||||
var target = targetFor(name);
|
||||
target[name] = val;
|
||||
return true;
|
||||
},
|
||||
enumerate: enumerateMux,
|
||||
keys: enumerateMux
|
||||
};
|
||||
}
|
||||
|
||||
function makePassthruHandler(obj) {
|
||||
// Handler copied from
|
||||
// http://wiki.ecmascript.org/doku.php?id=harmony:proxies&s=proxy%20object#examplea_no-op_forwarding_proxy
|
||||
return {
|
||||
getOwnPropertyDescriptor: function(name) {
|
||||
var desc = Object.getOwnPropertyDescriptor(obj, name);
|
||||
|
||||
// a trapping proxy's properties must always be configurable
|
||||
desc.configurable = true;
|
||||
return desc;
|
||||
},
|
||||
getPropertyDescriptor: function(name) {
|
||||
var desc = getPropertyDescriptor(obj, name);
|
||||
|
||||
// a trapping proxy's properties must always be configurable
|
||||
desc.configurable = true;
|
||||
return desc;
|
||||
},
|
||||
getOwnPropertyNames: function() {
|
||||
return Object.getOwnPropertyNames(obj);
|
||||
},
|
||||
defineProperty: function(name, desc) {
|
||||
Object.defineProperty(obj, name, desc);
|
||||
},
|
||||
"delete": function(name) { return delete obj[name]; },
|
||||
fix: function() {
|
||||
if (Object.isFrozen(obj)) {
|
||||
return getOwnProperties(obj);
|
||||
}
|
||||
|
||||
// As long as obj is not frozen, the proxy won't allow itself to be fixed.
|
||||
return undefined; // will cause a TypeError to be thrown
|
||||
},
|
||||
|
||||
has: function(name) { return name in obj; },
|
||||
hasOwn: function(name) { return ({}).hasOwnProperty.call(obj, name); },
|
||||
get: function(receiver, name) { return obj[name]; },
|
||||
|
||||
// bad behavior when set fails in non-strict mode
|
||||
set: function(receiver, name, val) { obj[name] = val; return true; },
|
||||
enumerate: function() {
|
||||
var result = [];
|
||||
for (name in obj) { result.push(name); };
|
||||
return result;
|
||||
},
|
||||
keys: function() { return Object.keys(obj); }
|
||||
};
|
||||
}
|
||||
|
||||
var hasOwnProperty = ({}).hasOwnProperty;
|
||||
|
||||
function hasOwn(obj, name) {
|
||||
return hasOwnProperty.call(obj, name);
|
||||
}
|
||||
|
||||
function StringMap(table, size) {
|
||||
this.table = table || Object.create(null, {});
|
||||
this.size = size || 0;
|
||||
}
|
||||
|
||||
StringMap.create = function(table) {
|
||||
var init = Object.create(null, {});
|
||||
var size = 0;
|
||||
var names = Object.getOwnPropertyNames(table);
|
||||
for (var i = 0, n = names.length; i < n; i++) {
|
||||
var name = names[i];
|
||||
init[name] = table[name];
|
||||
size++;
|
||||
}
|
||||
return new StringMap(init, size);
|
||||
};
|
||||
|
||||
StringMap.prototype = {
|
||||
has: function(x) { return hasOwnProperty.call(this.table, x); },
|
||||
set: function(x, v) {
|
||||
if (!hasOwnProperty.call(this.table, x))
|
||||
this.size++;
|
||||
this.table[x] = v;
|
||||
},
|
||||
get: function(x) { return this.table[x]; },
|
||||
getDef: function(x, thunk) {
|
||||
if (!hasOwnProperty.call(this.table, x)) {
|
||||
this.size++;
|
||||
this.table[x] = thunk();
|
||||
}
|
||||
return this.table[x];
|
||||
},
|
||||
forEach: function(f) {
|
||||
var table = this.table;
|
||||
for (var key in table)
|
||||
f.call(this, key, table[key]);
|
||||
},
|
||||
map: function(f) {
|
||||
var table1 = this.table;
|
||||
var table2 = Object.create(null, {});
|
||||
this.forEach(function(key, val) {
|
||||
table2[key] = f.call(this, val, key);
|
||||
});
|
||||
return new StringMap(table2, this.size);
|
||||
},
|
||||
mapObject: function(f) {
|
||||
var table1 = this.table;
|
||||
var table2 = Object.create(null, {});
|
||||
this.forEach(function(key, val) {
|
||||
table2[key] = f.call(this, val, key);
|
||||
});
|
||||
return table2;
|
||||
},
|
||||
toObject: function() {
|
||||
return this.mapObject(function(val) { return val; });
|
||||
},
|
||||
choose: function() {
|
||||
return Object.getOwnPropertyNames(this.table)[0];
|
||||
},
|
||||
remove: function(x) {
|
||||
if (hasOwnProperty.call(this.table, x)) {
|
||||
this.size--;
|
||||
delete this.table[x];
|
||||
}
|
||||
},
|
||||
copy: function() {
|
||||
var table = Object.create(null, {});
|
||||
for (var key in this.table)
|
||||
table[key] = this.table[key];
|
||||
return new StringMap(table, this.size);
|
||||
},
|
||||
keys: function() {
|
||||
return Object.keys(this.table);
|
||||
},
|
||||
toString: function() { return "[object StringMap]" }
|
||||
};
|
||||
|
||||
// an object-key table with poor asymptotics (replace with WeakMap when possible)
|
||||
function ObjectMap(array) {
|
||||
this.array = array || [];
|
||||
}
|
||||
|
||||
function searchMap(map, key, found, notFound) {
|
||||
var a = map.array;
|
||||
for (var i = 0, n = a.length; i < n; i++) {
|
||||
var pair = a[i];
|
||||
if (pair.key === key)
|
||||
return found(pair, i);
|
||||
}
|
||||
return notFound();
|
||||
}
|
||||
|
||||
ObjectMap.prototype = {
|
||||
has: function(x) {
|
||||
return searchMap(this, x, function() { return true }, function() { return false });
|
||||
},
|
||||
set: function(x, v) {
|
||||
var a = this.array;
|
||||
searchMap(this, x,
|
||||
function(pair) { pair.value = v },
|
||||
function() { a.push({ key: x, value: v }) });
|
||||
},
|
||||
get: function(x) {
|
||||
return searchMap(this, x,
|
||||
function(pair) { return pair.value },
|
||||
function() { return null });
|
||||
},
|
||||
getDef: function(x, thunk) {
|
||||
var a = this.array;
|
||||
return searchMap(this, x,
|
||||
function(pair) { return pair.value },
|
||||
function() {
|
||||
var v = thunk();
|
||||
a.push({ key: x, value: v });
|
||||
return v;
|
||||
});
|
||||
},
|
||||
forEach: function(f) {
|
||||
var a = this.array;
|
||||
for (var i = 0, n = a.length; i < n; i++) {
|
||||
var pair = a[i];
|
||||
f.call(this, pair.key, pair.value);
|
||||
}
|
||||
},
|
||||
choose: function() {
|
||||
return this.array[0].key;
|
||||
},
|
||||
get size() {
|
||||
return this.array.length;
|
||||
},
|
||||
remove: function(x) {
|
||||
var a = this.array;
|
||||
searchMap(this, x,
|
||||
function(pair, i) { a.splice(i, 1) },
|
||||
function() { });
|
||||
},
|
||||
copy: function() {
|
||||
return new ObjectMap(this.array.map(function(pair) {
|
||||
return { key: pair.key, value: pair.value }
|
||||
}));
|
||||
},
|
||||
clear: function() {
|
||||
this.array = [];
|
||||
},
|
||||
toString: function() { return "[object ObjectMap]" }
|
||||
};
|
||||
|
||||
// non-destructive stack
|
||||
function Stack(elts) {
|
||||
this.elts = elts || null;
|
||||
}
|
||||
|
||||
Stack.prototype = {
|
||||
push: function(x) {
|
||||
return new Stack({ top: x, rest: this.elts });
|
||||
},
|
||||
top: function() {
|
||||
if (!this.elts)
|
||||
throw new Error("empty stack");
|
||||
return this.elts.top;
|
||||
},
|
||||
isEmpty: function() {
|
||||
return this.top === null;
|
||||
},
|
||||
find: function(test) {
|
||||
for (var elts = this.elts; elts; elts = elts.rest) {
|
||||
if (test(elts.top))
|
||||
return elts.top;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
has: function(x) {
|
||||
return Boolean(this.find(function(elt) { return elt === x }));
|
||||
},
|
||||
forEach: function(f) {
|
||||
for (var elts = this.elts; elts; elts = elts.rest) {
|
||||
f(elts.top);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (!Array.prototype.copy) {
|
||||
Array.prototype.copy = function() {
|
||||
var result = [];
|
||||
for (var i = 0, n = this.length; i < n; i++)
|
||||
result[i] = this[i];
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
tokens: tokens,
|
||||
whitespace: whitespace,
|
||||
opTypeNames: opTypeNames,
|
||||
keywords: keywords,
|
||||
isStatementStartCode: isStatementStartCode,
|
||||
tokenIds: tokenIds,
|
||||
consts: consts,
|
||||
assignOps: assignOps,
|
||||
defineGetter: defineGetter,
|
||||
defineGetterSetter: defineGetterSetter,
|
||||
defineMemoGetter: defineMemoGetter,
|
||||
defineProperty: defineProperty,
|
||||
isNativeCode: isNativeCode,
|
||||
apply: apply,
|
||||
applyNew: applyNew,
|
||||
mirrorHandler: mirrorHandler,
|
||||
mixinHandler: mixinHandler,
|
||||
whitelistHandler: whitelistHandler,
|
||||
blacklistHandler: blacklistHandler,
|
||||
makePassthruHandler: makePassthruHandler,
|
||||
StringMap: StringMap,
|
||||
ObjectMap: ObjectMap,
|
||||
Stack: Stack
|
||||
};
|
||||
}());
|
588
node_modules/esprima/test/3rdparty/jslex.js
generated
vendored
588
node_modules/esprima/test/3rdparty/jslex.js
generated
vendored
@@ -1,588 +0,0 @@
|
||||
/* vim: set sw=4 ts=4 et tw=78: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Narcissus JavaScript engine.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Brendan Eich <brendan@mozilla.org>.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Tom Austin <taustin@ucsc.edu>
|
||||
* Brendan Eich <brendan@mozilla.org>
|
||||
* Shu-Yu Guo <shu@rfrn.org>
|
||||
* Stephan Herhut <stephan.a.herhut@intel.com>
|
||||
* Dave Herman <dherman@mozilla.com>
|
||||
* Dimitris Vardoulakis <dimvar@ccs.neu.edu>
|
||||
* Patrick Walton <pcwalton@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/*
|
||||
* Narcissus - JS implemented in JS.
|
||||
*
|
||||
* Lexical scanner.
|
||||
*/
|
||||
|
||||
Narcissus.lexer = (function() {
|
||||
|
||||
var definitions = Narcissus.definitions;
|
||||
|
||||
// Set constants in the local scope.
|
||||
eval(definitions.consts);
|
||||
|
||||
// Banned keywords by language version
|
||||
const blackLists = { 160: {}, 185: {}, harmony: {} };
|
||||
blackLists[160][LET] = true;
|
||||
blackLists[160][MODULE] = true;
|
||||
blackLists[160][YIELD] = true;
|
||||
blackLists[185][MODULE] = true;
|
||||
|
||||
// Build up a trie of operator tokens.
|
||||
var opTokens = {};
|
||||
for (var op in definitions.opTypeNames) {
|
||||
if (op === '\n' || op === '.')
|
||||
continue;
|
||||
|
||||
var node = opTokens;
|
||||
for (var i = 0; i < op.length; i++) {
|
||||
var ch = op[i];
|
||||
if (!(ch in node))
|
||||
node[ch] = {};
|
||||
node = node[ch];
|
||||
node.op = op;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Since JavaScript provides no convenient way to determine if a
|
||||
* character is in a particular Unicode category, we use
|
||||
* metacircularity to accomplish this (oh yeaaaah!)
|
||||
*/
|
||||
function isValidIdentifierChar(ch, first) {
|
||||
// check directly for ASCII
|
||||
if (ch <= "\u007F") {
|
||||
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch === '$' || ch === '_' ||
|
||||
(!first && (ch >= '0' && ch <= '9'))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// create an object to test this in
|
||||
var x = {};
|
||||
x["x"+ch] = true;
|
||||
x[ch] = true;
|
||||
|
||||
// then use eval to determine if it's a valid character
|
||||
var valid = false;
|
||||
try {
|
||||
valid = (Function("x", "return (x." + (first?"":"x") + ch + ");")(x) === true);
|
||||
} catch (ex) {}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
function isIdentifier(str) {
|
||||
if (typeof str !== "string")
|
||||
return false;
|
||||
|
||||
if (str.length === 0)
|
||||
return false;
|
||||
|
||||
if (!isValidIdentifierChar(str[0], true))
|
||||
return false;
|
||||
|
||||
for (var i = 1; i < str.length; i++) {
|
||||
if (!isValidIdentifierChar(str[i], false))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tokenizer :: (source, filename, line number) -> Tokenizer
|
||||
*/
|
||||
function Tokenizer(s, f, l) {
|
||||
this.cursor = 0;
|
||||
this.source = String(s);
|
||||
this.tokens = [];
|
||||
this.tokenIndex = 0;
|
||||
this.lookahead = 0;
|
||||
this.scanNewlines = false;
|
||||
this.unexpectedEOF = false;
|
||||
this.filename = f || "";
|
||||
this.lineno = l || 1;
|
||||
this.blackList = blackLists[Narcissus.options.version];
|
||||
this.blockComments = null;
|
||||
}
|
||||
|
||||
Tokenizer.prototype = {
|
||||
get done() {
|
||||
// We need to set scanOperand to true here because the first thing
|
||||
// might be a regexp.
|
||||
return this.peek(true) === END;
|
||||
},
|
||||
|
||||
get token() {
|
||||
return this.tokens[this.tokenIndex];
|
||||
},
|
||||
|
||||
match: function (tt, scanOperand, keywordIsName) {
|
||||
return this.get(scanOperand, keywordIsName) === tt || this.unget();
|
||||
},
|
||||
|
||||
mustMatch: function (tt, keywordIsName) {
|
||||
if (!this.match(tt, false, keywordIsName)) {
|
||||
throw this.newSyntaxError("Missing " +
|
||||
definitions.tokens[tt].toLowerCase());
|
||||
}
|
||||
return this.token;
|
||||
},
|
||||
|
||||
peek: function (scanOperand) {
|
||||
var tt, next;
|
||||
if (this.lookahead) {
|
||||
next = this.tokens[(this.tokenIndex + this.lookahead) & 3];
|
||||
tt = (this.scanNewlines && next.lineno !== this.lineno)
|
||||
? NEWLINE
|
||||
: next.type;
|
||||
} else {
|
||||
tt = this.get(scanOperand);
|
||||
this.unget();
|
||||
}
|
||||
return tt;
|
||||
},
|
||||
|
||||
peekOnSameLine: function (scanOperand) {
|
||||
this.scanNewlines = true;
|
||||
var tt = this.peek(scanOperand);
|
||||
this.scanNewlines = false;
|
||||
return tt;
|
||||
},
|
||||
|
||||
lastBlockComment: function() {
|
||||
var length = this.blockComments.length;
|
||||
return length ? this.blockComments[length - 1] : null;
|
||||
},
|
||||
|
||||
// Eat comments and whitespace.
|
||||
skip: function () {
|
||||
var input = this.source;
|
||||
this.blockComments = [];
|
||||
for (;;) {
|
||||
var ch = input[this.cursor++];
|
||||
var next = input[this.cursor];
|
||||
// handle \r, \r\n and (always preferable) \n
|
||||
if (ch === '\r') {
|
||||
// if the next character is \n, we don't care about this at all
|
||||
if (next === '\n') continue;
|
||||
|
||||
// otherwise, we want to consider this as a newline
|
||||
ch = '\n';
|
||||
}
|
||||
|
||||
if (ch === '\n' && !this.scanNewlines) {
|
||||
this.lineno++;
|
||||
} else if (ch === '/' && next === '*') {
|
||||
var commentStart = ++this.cursor;
|
||||
for (;;) {
|
||||
ch = input[this.cursor++];
|
||||
if (ch === undefined)
|
||||
throw this.newSyntaxError("Unterminated comment");
|
||||
|
||||
if (ch === '*') {
|
||||
next = input[this.cursor];
|
||||
if (next === '/') {
|
||||
var commentEnd = this.cursor - 1;
|
||||
this.cursor++;
|
||||
break;
|
||||
}
|
||||
} else if (ch === '\n') {
|
||||
this.lineno++;
|
||||
}
|
||||
}
|
||||
this.blockComments.push(input.substring(commentStart, commentEnd));
|
||||
} else if ((ch === '/' && next === '/') ||
|
||||
(Narcissus.options.allowHTMLComments && ch === '<' && next === '!' &&
|
||||
input[this.cursor + 1] === '-' && input[this.cursor + 2] === '-' &&
|
||||
(this.cursor += 2))) {
|
||||
this.cursor++;
|
||||
for (;;) {
|
||||
ch = input[this.cursor++];
|
||||
next = input[this.cursor];
|
||||
if (ch === undefined)
|
||||
return;
|
||||
|
||||
if (ch === '\r') {
|
||||
// check for \r\n
|
||||
if (next !== '\n') ch = '\n';
|
||||
}
|
||||
|
||||
if (ch === '\n') {
|
||||
if (this.scanNewlines) {
|
||||
this.cursor--;
|
||||
} else {
|
||||
this.lineno++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (!(ch in definitions.whitespace)) {
|
||||
this.cursor--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Lex the exponential part of a number, if present. Return true iff an
|
||||
// exponential part was found.
|
||||
lexExponent: function() {
|
||||
var input = this.source;
|
||||
var next = input[this.cursor];
|
||||
if (next === 'e' || next === 'E') {
|
||||
this.cursor++;
|
||||
ch = input[this.cursor++];
|
||||
if (ch === '+' || ch === '-')
|
||||
ch = input[this.cursor++];
|
||||
|
||||
if (ch < '0' || ch > '9')
|
||||
throw this.newSyntaxError("Missing exponent");
|
||||
|
||||
do {
|
||||
ch = input[this.cursor++];
|
||||
} while (ch >= '0' && ch <= '9');
|
||||
this.cursor--;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
lexZeroNumber: function (ch) {
|
||||
var token = this.token, input = this.source;
|
||||
token.type = NUMBER;
|
||||
|
||||
ch = input[this.cursor++];
|
||||
if (ch === '.') {
|
||||
do {
|
||||
ch = input[this.cursor++];
|
||||
} while (ch >= '0' && ch <= '9');
|
||||
this.cursor--;
|
||||
|
||||
this.lexExponent();
|
||||
token.value = parseFloat(
|
||||
input.substring(token.start, this.cursor));
|
||||
} else if (ch === 'x' || ch === 'X') {
|
||||
do {
|
||||
ch = input[this.cursor++];
|
||||
} while ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') ||
|
||||
(ch >= 'A' && ch <= 'F'));
|
||||
this.cursor--;
|
||||
|
||||
token.value = parseInt(input.substring(token.start, this.cursor));
|
||||
} else if (ch >= '0' && ch <= '7') {
|
||||
do {
|
||||
ch = input[this.cursor++];
|
||||
} while (ch >= '0' && ch <= '7');
|
||||
this.cursor--;
|
||||
|
||||
token.value = parseInt(input.substring(token.start, this.cursor));
|
||||
} else {
|
||||
this.cursor--;
|
||||
this.lexExponent(); // 0E1, &c.
|
||||
token.value = 0;
|
||||
}
|
||||
},
|
||||
|
||||
lexNumber: function (ch) {
|
||||
var token = this.token, input = this.source;
|
||||
token.type = NUMBER;
|
||||
|
||||
var floating = false;
|
||||
do {
|
||||
ch = input[this.cursor++];
|
||||
if (ch === '.' && !floating) {
|
||||
floating = true;
|
||||
ch = input[this.cursor++];
|
||||
}
|
||||
} while (ch >= '0' && ch <= '9');
|
||||
|
||||
this.cursor--;
|
||||
|
||||
var exponent = this.lexExponent();
|
||||
floating = floating || exponent;
|
||||
|
||||
var str = input.substring(token.start, this.cursor);
|
||||
token.value = floating ? parseFloat(str) : parseInt(str);
|
||||
},
|
||||
|
||||
lexDot: function (ch) {
|
||||
var token = this.token, input = this.source;
|
||||
var next = input[this.cursor];
|
||||
if (next >= '0' && next <= '9') {
|
||||
do {
|
||||
ch = input[this.cursor++];
|
||||
} while (ch >= '0' && ch <= '9');
|
||||
this.cursor--;
|
||||
|
||||
this.lexExponent();
|
||||
|
||||
token.type = NUMBER;
|
||||
token.value = parseFloat(
|
||||
input.substring(token.start, this.cursor));
|
||||
} else {
|
||||
token.type = DOT;
|
||||
token.assignOp = null;
|
||||
token.value = '.';
|
||||
}
|
||||
},
|
||||
|
||||
lexString: function (ch) {
|
||||
var token = this.token, input = this.source;
|
||||
token.type = STRING;
|
||||
|
||||
var hasEscapes = false;
|
||||
var delim = ch;
|
||||
if (input.length <= this.cursor)
|
||||
throw this.newSyntaxError("Unterminated string literal");
|
||||
while ((ch = input[this.cursor++]) !== delim) {
|
||||
if (this.cursor == input.length)
|
||||
throw this.newSyntaxError("Unterminated string literal");
|
||||
if (ch === '\\') {
|
||||
hasEscapes = true;
|
||||
if (++this.cursor == input.length)
|
||||
throw this.newSyntaxError("Unterminated string literal");
|
||||
}
|
||||
}
|
||||
|
||||
token.value = hasEscapes
|
||||
? eval(input.substring(token.start, this.cursor))
|
||||
: input.substring(token.start + 1, this.cursor - 1);
|
||||
},
|
||||
|
||||
lexRegExp: function (ch) {
|
||||
var token = this.token, input = this.source;
|
||||
token.type = REGEXP;
|
||||
|
||||
do {
|
||||
ch = input[this.cursor++];
|
||||
if (ch === '\\') {
|
||||
this.cursor++;
|
||||
} else if (ch === '[') {
|
||||
do {
|
||||
if (ch === undefined)
|
||||
throw this.newSyntaxError("Unterminated character class");
|
||||
|
||||
if (ch === '\\')
|
||||
this.cursor++;
|
||||
|
||||
ch = input[this.cursor++];
|
||||
} while (ch !== ']');
|
||||
} else if (ch === undefined) {
|
||||
throw this.newSyntaxError("Unterminated regex");
|
||||
}
|
||||
} while (ch !== '/');
|
||||
|
||||
do {
|
||||
ch = input[this.cursor++];
|
||||
} while (ch >= 'a' && ch <= 'z');
|
||||
|
||||
this.cursor--;
|
||||
|
||||
token.value = eval(input.substring(token.start, this.cursor));
|
||||
},
|
||||
|
||||
lexOp: function (ch) {
|
||||
var token = this.token, input = this.source;
|
||||
|
||||
// A bit ugly, but it seems wasteful to write a trie lookup routine
|
||||
// for only 3 characters...
|
||||
var node = opTokens[ch];
|
||||
var next = input[this.cursor];
|
||||
if (next in node) {
|
||||
node = node[next];
|
||||
this.cursor++;
|
||||
next = input[this.cursor];
|
||||
if (next in node) {
|
||||
node = node[next];
|
||||
this.cursor++;
|
||||
next = input[this.cursor];
|
||||
}
|
||||
}
|
||||
|
||||
var op = node.op;
|
||||
if (definitions.assignOps[op] && input[this.cursor] === '=') {
|
||||
this.cursor++;
|
||||
token.type = ASSIGN;
|
||||
token.assignOp = definitions.tokenIds[definitions.opTypeNames[op]];
|
||||
op += '=';
|
||||
} else {
|
||||
token.type = definitions.tokenIds[definitions.opTypeNames[op]];
|
||||
token.assignOp = null;
|
||||
}
|
||||
|
||||
token.value = op;
|
||||
},
|
||||
|
||||
// FIXME: Unicode escape sequences
|
||||
lexIdent: function (ch, keywordIsName) {
|
||||
var token = this.token;
|
||||
var id = ch;
|
||||
|
||||
while ((ch = this.getValidIdentifierChar(false)) !== null) {
|
||||
id += ch;
|
||||
}
|
||||
|
||||
token.type = IDENTIFIER;
|
||||
token.value = id;
|
||||
|
||||
if (keywordIsName)
|
||||
return;
|
||||
|
||||
var kw = definitions.keywords[id];
|
||||
if (kw && !(kw in this.blackList))
|
||||
token.type = kw;
|
||||
},
|
||||
|
||||
/*
|
||||
* Tokenizer.get :: [boolean[, boolean]] -> token type
|
||||
*
|
||||
* Consume input *only* if there is no lookahead.
|
||||
* Dispatch to the appropriate lexing function depending on the input.
|
||||
*/
|
||||
get: function (scanOperand, keywordIsName) {
|
||||
var token;
|
||||
while (this.lookahead) {
|
||||
--this.lookahead;
|
||||
this.tokenIndex = (this.tokenIndex + 1) & 3;
|
||||
token = this.tokens[this.tokenIndex];
|
||||
if (token.type !== NEWLINE || this.scanNewlines)
|
||||
return token.type;
|
||||
}
|
||||
|
||||
this.skip();
|
||||
|
||||
this.tokenIndex = (this.tokenIndex + 1) & 3;
|
||||
token = this.tokens[this.tokenIndex];
|
||||
if (!token)
|
||||
this.tokens[this.tokenIndex] = token = {};
|
||||
|
||||
var input = this.source;
|
||||
if (this.cursor >= input.length)
|
||||
return token.type = END;
|
||||
|
||||
token.start = this.cursor;
|
||||
token.lineno = this.lineno;
|
||||
|
||||
var ich = this.getValidIdentifierChar(true);
|
||||
var ch = (ich === null) ? input[this.cursor++] : null;
|
||||
if (ich !== null) {
|
||||
this.lexIdent(ich, keywordIsName);
|
||||
} else if (scanOperand && ch === '/') {
|
||||
this.lexRegExp(ch);
|
||||
} else if (ch in opTokens) {
|
||||
this.lexOp(ch);
|
||||
} else if (ch === '.') {
|
||||
this.lexDot(ch);
|
||||
} else if (ch >= '1' && ch <= '9') {
|
||||
this.lexNumber(ch);
|
||||
} else if (ch === '0') {
|
||||
this.lexZeroNumber(ch);
|
||||
} else if (ch === '"' || ch === "'") {
|
||||
this.lexString(ch);
|
||||
} else if (this.scanNewlines && (ch === '\n' || ch === '\r')) {
|
||||
// if this was a \r, look for \r\n
|
||||
if (ch === '\r' && input[this.cursor] === '\n') this.cursor++;
|
||||
token.type = NEWLINE;
|
||||
token.value = '\n';
|
||||
this.lineno++;
|
||||
} else {
|
||||
throw this.newSyntaxError("Illegal token");
|
||||
}
|
||||
|
||||
token.end = this.cursor;
|
||||
return token.type;
|
||||
},
|
||||
|
||||
/*
|
||||
* Tokenizer.unget :: void -> undefined
|
||||
*
|
||||
* Match depends on unget returning undefined.
|
||||
*/
|
||||
unget: function () {
|
||||
if (++this.lookahead === 4) throw "PANIC: too much lookahead!";
|
||||
this.tokenIndex = (this.tokenIndex - 1) & 3;
|
||||
},
|
||||
|
||||
newSyntaxError: function (m) {
|
||||
m = (this.filename ? this.filename + ":" : "") + this.lineno + ": " + m;
|
||||
var e = new SyntaxError(m, this.filename, this.lineno);
|
||||
e.source = this.source;
|
||||
e.cursor = this.lookahead
|
||||
? this.tokens[(this.tokenIndex + this.lookahead) & 3].start
|
||||
: this.cursor;
|
||||
return e;
|
||||
},
|
||||
|
||||
|
||||
/* Gets a single valid identifier char from the input stream, or null
|
||||
* if there is none.
|
||||
*/
|
||||
getValidIdentifierChar: function(first) {
|
||||
var input = this.source;
|
||||
if (this.cursor >= input.length) return null;
|
||||
var ch = input[this.cursor];
|
||||
|
||||
// first check for \u escapes
|
||||
if (ch === '\\' && input[this.cursor+1] === 'u') {
|
||||
// get the character value
|
||||
try {
|
||||
ch = String.fromCharCode(parseInt(
|
||||
input.substring(this.cursor + 2, this.cursor + 6),
|
||||
16));
|
||||
} catch (ex) {
|
||||
return null;
|
||||
}
|
||||
this.cursor += 5;
|
||||
}
|
||||
|
||||
var valid = isValidIdentifierChar(ch, first);
|
||||
if (valid) this.cursor++;
|
||||
return (valid ? ch : null);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
return {
|
||||
isIdentifier: isIdentifier,
|
||||
Tokenizer: Tokenizer
|
||||
};
|
||||
|
||||
}());
|
1921
node_modules/esprima/test/3rdparty/jsparse.js
generated
vendored
1921
node_modules/esprima/test/3rdparty/jsparse.js
generated
vendored
File diff suppressed because it is too large
Load Diff
5952
node_modules/esprima/test/3rdparty/mootools-1.3.2.js
generated
vendored
5952
node_modules/esprima/test/3rdparty/mootools-1.3.2.js
generated
vendored
File diff suppressed because it is too large
Load Diff
6297
node_modules/esprima/test/3rdparty/mootools-1.4.1.js
generated
vendored
6297
node_modules/esprima/test/3rdparty/mootools-1.4.1.js
generated
vendored
File diff suppressed because it is too large
Load Diff
1342
node_modules/esprima/test/3rdparty/parse-js.js
generated
vendored
1342
node_modules/esprima/test/3rdparty/parse-js.js
generated
vendored
File diff suppressed because it is too large
Load Diff
878
node_modules/esprima/test/3rdparty/platform.js
generated
vendored
878
node_modules/esprima/test/3rdparty/platform.js
generated
vendored
@@ -1,878 +0,0 @@
|
||||
/*!
|
||||
* Platform.js v1.0.0-pre <http://mths.be/platform>
|
||||
* Copyright 2010-2012 John-David Dalton <http://allyoucanleet.com/>
|
||||
* Available under MIT license <http://mths.be/mit>
|
||||
*/
|
||||
;(function(window) {
|
||||
|
||||
/** Backup possible window/global object */
|
||||
var oldWin = window;
|
||||
|
||||
/** Detect free variable `exports` */
|
||||
var freeExports = typeof exports == 'object' && exports;
|
||||
|
||||
/** Detect free variable `global` */
|
||||
var freeGlobal = typeof global == 'object' && global &&
|
||||
(global == global.global ? (window = global) : global);
|
||||
|
||||
/** Opera regexp */
|
||||
var reOpera = /Opera/;
|
||||
|
||||
/** Used to resolve a value's internal [[Class]] */
|
||||
var toString = {}.toString;
|
||||
|
||||
/** Detect Java environment */
|
||||
var java = /Java/.test(getClassOf(window.java)) && window.java;
|
||||
|
||||
/** A character to represent alpha */
|
||||
var alpha = java ? 'a' : '\u03b1';
|
||||
|
||||
/** A character to represent beta */
|
||||
var beta = java ? 'b' : '\u03b2';
|
||||
|
||||
/** Browser document object */
|
||||
var doc = window.document || {};
|
||||
|
||||
/** Used to check for own properties of an object */
|
||||
var hasOwnProperty = {}.hasOwnProperty;
|
||||
|
||||
/** Browser navigator object */
|
||||
var nav = window.navigator || {};
|
||||
|
||||
/**
|
||||
* Detect Opera browser
|
||||
* http://www.howtocreate.co.uk/operaStuff/operaObject.html
|
||||
* http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini
|
||||
*/
|
||||
var opera = window.operamini || window.opera;
|
||||
|
||||
/** Opera [[Class]] */
|
||||
var operaClass = reOpera.test(operaClass = getClassOf(opera)) ? operaClass : (opera = null);
|
||||
|
||||
/** Possible global object */
|
||||
var thisBinding = this;
|
||||
|
||||
/** Browser user agent string */
|
||||
var userAgent = nav.userAgent || '';
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Capitalizes a string value.
|
||||
* @private
|
||||
* @param {String} string The string to capitalize.
|
||||
* @returns {String} The capitalized string.
|
||||
*/
|
||||
function capitalize(string) {
|
||||
string = String(string);
|
||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* An iteration utility for arrays and objects.
|
||||
* @private
|
||||
* @param {Array|Object} object The object to iterate over.
|
||||
* @param {Function} callback The function called per iteration.
|
||||
*/
|
||||
function each(object, callback) {
|
||||
var index = -1,
|
||||
length = object.length;
|
||||
|
||||
if (length == length >>> 0) {
|
||||
while (++index < length) {
|
||||
callback(object[index], index, object);
|
||||
}
|
||||
} else {
|
||||
forOwn(object, callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates over an object's own properties, executing the `callback` for each.
|
||||
* @private
|
||||
* @param {Object} object The object to iterate over.
|
||||
* @param {Function} callback The function executed per own property.
|
||||
*/
|
||||
function forOwn(object, callback) {
|
||||
for (var key in object) {
|
||||
hasKey(object, key) && callback(object[key], key, object);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trim and conditionally capitalize string values.
|
||||
* @private
|
||||
* @param {String} string The string to format.
|
||||
* @returns {String} The formatted string.
|
||||
*/
|
||||
function format(string) {
|
||||
string = trim(string);
|
||||
return /^(?:webOS|i(?:OS|P))/.test(string)
|
||||
? string
|
||||
: capitalize(string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the internal [[Class]] of a value.
|
||||
* @private
|
||||
* @param {Mixed} value The value.
|
||||
* @returns {String} The [[Class]].
|
||||
*/
|
||||
function getClassOf(value) {
|
||||
return value == null
|
||||
? capitalize(value)
|
||||
: toString.call(value).slice(8, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an object has the specified key as a direct property.
|
||||
* @private
|
||||
* @param {Object} object The object to check.
|
||||
* @param {String} key The key to check for.
|
||||
* @returns {Boolean} Returns `true` if key is a direct property, else `false`.
|
||||
*/
|
||||
function hasKey() {
|
||||
// lazy define for others (not as accurate)
|
||||
hasKey = function(object, key) {
|
||||
var parent = object != null && (object.constructor || Object).prototype;
|
||||
return !!parent && key in Object(object) && !(key in parent && object[key] === parent[key]);
|
||||
};
|
||||
// for modern browsers
|
||||
if (getClassOf(hasOwnProperty) == 'Function') {
|
||||
hasKey = function(object, key) {
|
||||
return object != null && hasOwnProperty.call(object, key);
|
||||
};
|
||||
}
|
||||
// for Safari 2
|
||||
else if ({}.__proto__ == Object.prototype) {
|
||||
hasKey = function(object, key) {
|
||||
var result = false;
|
||||
if (object != null) {
|
||||
object = Object(object);
|
||||
object.__proto__ = [object.__proto__, object.__proto__ = null, result = key in object][0];
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
return hasKey.apply(this, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Host objects can return type values that are different from their actual
|
||||
* data type. The objects we are concerned with usually return non-primitive
|
||||
* types of object, function, or unknown.
|
||||
* @private
|
||||
* @param {Mixed} object The owner of the property.
|
||||
* @param {String} property The property to check.
|
||||
* @returns {Boolean} Returns `true` if the property value is a non-primitive, else `false`.
|
||||
*/
|
||||
function isHostType(object, property) {
|
||||
var type = object != null ? typeof object[property] : 'number';
|
||||
return !/^(?:boolean|number|string|undefined)$/.test(type) &&
|
||||
(type == 'object' ? !!object[property] : true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a string for use in a RegExp constructor by making hyphens and spaces optional.
|
||||
* @private
|
||||
* @param {String} string The string to qualify.
|
||||
* @returns {String} The qualified string.
|
||||
*/
|
||||
function qualify(string) {
|
||||
return String(string).replace(/([ -])(?!$)/g, '$1?');
|
||||
}
|
||||
|
||||
/**
|
||||
* A bare-bones` Array#reduce` like utility function.
|
||||
* @private
|
||||
* @param {Array} array The array to iterate over.
|
||||
* @param {Function} callback The function called per iteration.
|
||||
* @param {Mixed} accumulator Initial value of the accumulator.
|
||||
* @returns {Mixed} The accumulator.
|
||||
*/
|
||||
function reduce(array, callback) {
|
||||
var accumulator = null;
|
||||
each(array, function(value, index) {
|
||||
accumulator = callback(accumulator, value, index, array);
|
||||
});
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes leading and trailing whitespace from a string.
|
||||
* @private
|
||||
* @param {String} string The string to trim.
|
||||
* @returns {String} The trimmed string.
|
||||
*/
|
||||
function trim(string) {
|
||||
return String(string).replace(/^ +| +$/g, '');
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Creates a new platform object.
|
||||
* @memberOf platform
|
||||
* @param {String} [ua = navigator.userAgent] The user agent string.
|
||||
* @returns {Object} A platform object.
|
||||
*/
|
||||
function parse(ua) {
|
||||
|
||||
ua || (ua = userAgent);
|
||||
|
||||
/** Temporary variable used over the script's lifetime */
|
||||
var data;
|
||||
|
||||
/** The CPU architecture */
|
||||
var arch = ua;
|
||||
|
||||
/** Platform description array */
|
||||
var description = [];
|
||||
|
||||
/** Platform alpha/beta indicator */
|
||||
var prerelease = null;
|
||||
|
||||
/** A flag to indicate that environment features should be used to resolve the platform */
|
||||
var useFeatures = ua == userAgent;
|
||||
|
||||
/** The browser/environment version */
|
||||
var version = useFeatures && opera && typeof opera.version == 'function' && opera.version();
|
||||
|
||||
/* Detectable layout engines (order is important) */
|
||||
var layout = getLayout([
|
||||
{ 'label': 'WebKit', 'pattern': 'AppleWebKit' },
|
||||
'iCab',
|
||||
'Presto',
|
||||
'NetFront',
|
||||
'Tasman',
|
||||
'Trident',
|
||||
'KHTML',
|
||||
'Gecko'
|
||||
]);
|
||||
|
||||
/* Detectable browser names (order is important) */
|
||||
var name = getName([
|
||||
'Adobe AIR',
|
||||
'Arora',
|
||||
'Avant Browser',
|
||||
'Camino',
|
||||
'Epiphany',
|
||||
'Fennec',
|
||||
'Flock',
|
||||
'Galeon',
|
||||
'GreenBrowser',
|
||||
'iCab',
|
||||
'Iceweasel',
|
||||
'Iron',
|
||||
'K-Meleon',
|
||||
'Konqueror',
|
||||
'Lunascape',
|
||||
'Maxthon',
|
||||
'Midori',
|
||||
'Nook Browser',
|
||||
'PhantomJS',
|
||||
'Raven',
|
||||
'Rekonq',
|
||||
'RockMelt',
|
||||
'SeaMonkey',
|
||||
{ 'label': 'Silk', 'pattern': '(?:Cloud9|Silk)' },
|
||||
'Sleipnir',
|
||||
'SlimBrowser',
|
||||
'Sunrise',
|
||||
'Swiftfox',
|
||||
'WebPositive',
|
||||
'Opera Mini',
|
||||
'Opera',
|
||||
'Chrome',
|
||||
{ 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' },
|
||||
{ 'label': 'IE', 'pattern': 'MSIE' },
|
||||
'Safari'
|
||||
]);
|
||||
|
||||
/* Detectable products (order is important) */
|
||||
var product = getProduct([
|
||||
'BlackBerry',
|
||||
{ 'label': 'Galaxy S', 'pattern': 'GT-I9000' },
|
||||
{ 'label': 'Galaxy S2', 'pattern': 'GT-I9100' },
|
||||
'iPad',
|
||||
'iPod',
|
||||
'iPhone',
|
||||
'Kindle',
|
||||
{ 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk)' },
|
||||
'Nook',
|
||||
'PlayBook',
|
||||
'TouchPad',
|
||||
'Transformer',
|
||||
'Xoom'
|
||||
]);
|
||||
|
||||
/* Detectable manufacturers */
|
||||
var manufacturer = getManufacturer({
|
||||
'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 },
|
||||
'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 },
|
||||
'Asus': { 'Transformer': 1 },
|
||||
'Barnes & Noble': { 'Nook': 1 },
|
||||
'BlackBerry': { 'PlayBook': 1 },
|
||||
'HP': { 'TouchPad': 1 },
|
||||
'LG': { },
|
||||
'Motorola': { 'Xoom': 1 },
|
||||
'Nokia': { },
|
||||
'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1 }
|
||||
});
|
||||
|
||||
/* Detectable OSes (order is important) */
|
||||
var os = getOS([
|
||||
'Android',
|
||||
'CentOS',
|
||||
'Debian',
|
||||
'Fedora',
|
||||
'FreeBSD',
|
||||
'Gentoo',
|
||||
'Haiku',
|
||||
'Kubuntu',
|
||||
'Linux Mint',
|
||||
'Red Hat',
|
||||
'SuSE',
|
||||
'Ubuntu',
|
||||
'Xubuntu',
|
||||
'Cygwin',
|
||||
'Symbian OS',
|
||||
'hpwOS',
|
||||
'webOS ',
|
||||
'webOS',
|
||||
'Tablet OS',
|
||||
'Linux',
|
||||
'Mac OS X',
|
||||
'Macintosh',
|
||||
'Mac',
|
||||
'Windows 98;',
|
||||
'Windows '
|
||||
]);
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Picks the layout engine from an array of guesses.
|
||||
* @private
|
||||
* @param {Array} guesses An array of guesses.
|
||||
* @returns {String|Null} The detected layout engine.
|
||||
*/
|
||||
function getLayout(guesses) {
|
||||
return reduce(guesses, function(result, guess) {
|
||||
return result || RegExp('\\b' + (
|
||||
guess.pattern || qualify(guess)
|
||||
) + '\\b', 'i').exec(ua) && (guess.label || guess);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Picks the manufacturer from an array of guesses.
|
||||
* @private
|
||||
* @param {Array} guesses An array of guesses.
|
||||
* @returns {String|Null} The detected manufacturer.
|
||||
*/
|
||||
function getManufacturer(guesses) {
|
||||
return reduce(guesses, function(result, value, key) {
|
||||
// lookup the manufacturer by product or scan the UA for the manufacturer
|
||||
return result || (
|
||||
value[product] ||
|
||||
value[0/*Opera 9.25 fix*/, /^[a-z]+/i.exec(product)] ||
|
||||
RegExp('\\b' + (key.pattern || qualify(key)) + '(?:\\b|\\w*\\d)', 'i').exec(ua)
|
||||
) && (key.label || key);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Picks the browser name from an array of guesses.
|
||||
* @private
|
||||
* @param {Array} guesses An array of guesses.
|
||||
* @returns {String|Null} The detected browser name.
|
||||
*/
|
||||
function getName(guesses) {
|
||||
return reduce(guesses, function(result, guess) {
|
||||
return result || RegExp('\\b' + (
|
||||
guess.pattern || qualify(guess)
|
||||
) + '\\b', 'i').exec(ua) && (guess.label || guess);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Picks the OS name from an array of guesses.
|
||||
* @private
|
||||
* @param {Array} guesses An array of guesses.
|
||||
* @returns {String|Null} The detected OS name.
|
||||
*/
|
||||
function getOS(guesses) {
|
||||
return reduce(guesses, function(result, guess) {
|
||||
var pattern = guess.pattern || qualify(guess);
|
||||
if (!result && (result =
|
||||
RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua))) {
|
||||
// platform tokens defined at
|
||||
// http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx
|
||||
// http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx
|
||||
data = {
|
||||
'6.2': '8',
|
||||
'6.1': 'Server 2008 R2 / 7',
|
||||
'6.0': 'Server 2008 / Vista',
|
||||
'5.2': 'Server 2003 / XP 64-bit',
|
||||
'5.1': 'XP',
|
||||
'5.01': '2000 SP1',
|
||||
'5.0': '2000',
|
||||
'4.0': 'NT',
|
||||
'4.90': 'ME'
|
||||
};
|
||||
// detect Windows version from platform tokens
|
||||
if (/^Win/i.test(result) &&
|
||||
(data = data[0/*Opera 9.25 fix*/, /[\d.]+$/.exec(result)])) {
|
||||
result = 'Windows ' + data;
|
||||
}
|
||||
// correct character case and cleanup
|
||||
result = format(String(result)
|
||||
.replace(RegExp(pattern, 'i'), guess.label || guess)
|
||||
.replace(/ ce$/i, ' CE')
|
||||
.replace(/hpw/i, 'web')
|
||||
.replace(/Macintosh/, 'Mac OS')
|
||||
.replace(/_PowerPC/i, ' OS')
|
||||
.replace(/(OS X) [^ \d]+/i, '$1')
|
||||
.replace(/\/(\d)/, ' $1')
|
||||
.replace(/_/g, '.')
|
||||
.replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '')
|
||||
.replace(/x86\.64/gi, 'x86_64')
|
||||
.split(' on ')[0]);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Picks the product name from an array of guesses.
|
||||
* @private
|
||||
* @param {Array} guesses An array of guesses.
|
||||
* @returns {String|Null} The detected product name.
|
||||
*/
|
||||
function getProduct(guesses) {
|
||||
return reduce(guesses, function(result, guess) {
|
||||
var pattern = guess.pattern || qualify(guess);
|
||||
if (!result && (result =
|
||||
RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) ||
|
||||
RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua)
|
||||
)) {
|
||||
// split by forward slash and append product version if needed
|
||||
if ((result = String(guess.label || result).split('/'))[1] && !/[\d.]+/.test(result[0])) {
|
||||
result[0] += ' ' + result[1];
|
||||
}
|
||||
// correct character case and cleanup
|
||||
guess = guess.label || guess;
|
||||
result = format(result[0]
|
||||
.replace(RegExp(pattern, 'i'), guess)
|
||||
.replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ')
|
||||
.replace(RegExp('(' + guess + ')(\\w)', 'i'), '$1 $2'));
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the version using an array of UA patterns.
|
||||
* @private
|
||||
* @param {Array} patterns An array of UA patterns.
|
||||
* @returns {String|Null} The detected version.
|
||||
*/
|
||||
function getVersion(patterns) {
|
||||
return reduce(patterns, function(result, pattern) {
|
||||
return result || (RegExp(pattern +
|
||||
'(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/-]*)', 'i').exec(ua) || 0)[1] || null;
|
||||
});
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Return platform description when the platform object is coerced to a string.
|
||||
* @name toString
|
||||
* @memberOf platform
|
||||
* @type Function
|
||||
* @returns {String} The platform description.
|
||||
*/
|
||||
function toStringPlatform() {
|
||||
return this.description || '';
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
// convert layout to an array so we can add extra details
|
||||
layout && (layout = [layout]);
|
||||
|
||||
// detect product names that contain their manufacturer's name
|
||||
if (manufacturer && !product) {
|
||||
product = getProduct([manufacturer]);
|
||||
}
|
||||
// detect simulators
|
||||
if (/\bSimulator\b/i.test(ua)) {
|
||||
product = (product ? product + ' ' : '') + 'Simulator';
|
||||
}
|
||||
// detect iOS
|
||||
if (/^iP/.test(product)) {
|
||||
name || (name = 'Safari');
|
||||
os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua))
|
||||
? ' ' + data[1].replace(/_/g, '.')
|
||||
: '');
|
||||
}
|
||||
// detect Kubuntu
|
||||
else if (name == 'Konqueror' && !/buntu/i.test(os)) {
|
||||
os = 'Kubuntu';
|
||||
}
|
||||
// detect Android browsers
|
||||
else if (name == 'Chrome' && manufacturer) {
|
||||
name = 'Android Browser';
|
||||
os = /Android/.test(os) ? os : 'Android';
|
||||
}
|
||||
// detect false positives for Firefox/Safari
|
||||
else if (!name || (data = !/\bMinefield\b/i.test(ua) && /Firefox|Safari/.exec(name))) {
|
||||
// escape the `/` for Firefox 1
|
||||
if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) {
|
||||
// clear name of false positives
|
||||
name = null;
|
||||
}
|
||||
// reassign a generic name
|
||||
if ((data = product || manufacturer || os) &&
|
||||
(product || manufacturer || /Android|Symbian OS|Tablet OS|webOS/.test(os))) {
|
||||
name = /[a-z]+(?: Hat)?/i.exec(/Android/.test(os) ? os : data) + ' Browser';
|
||||
}
|
||||
}
|
||||
// detect non-Opera versions (order is important)
|
||||
if (!version) {
|
||||
version = getVersion([
|
||||
'(?:Cloud9|Opera ?Mini|Raven|Silk)',
|
||||
'Version',
|
||||
qualify(name),
|
||||
'(?:Firefox|Minefield|NetFront)'
|
||||
]);
|
||||
}
|
||||
// detect stubborn layout engines
|
||||
if (layout == 'iCab' && parseFloat(version) > 3) {
|
||||
layout = ['WebKit'];
|
||||
} else if (name == 'Konqueror' && /\bKHTML\b/i.test(ua)) {
|
||||
layout = ['KHTML'];
|
||||
} else if (data =
|
||||
/Opera/.test(name) && 'Presto' ||
|
||||
/\b(?:Midori|Nook|Safari)\b/i.test(ua) && 'WebKit' ||
|
||||
!layout && /\bMSIE\b/i.test(ua) && (/^Mac/.test(os) ? 'Tasman' : 'Trident')) {
|
||||
layout = [data];
|
||||
}
|
||||
// leverage environment features
|
||||
if (useFeatures) {
|
||||
// detect server-side environments
|
||||
// Rhino has a global function while others have a global object
|
||||
if (isHostType(thisBinding, 'global')) {
|
||||
if (java) {
|
||||
data = java.lang.System;
|
||||
arch = data.getProperty('os.arch');
|
||||
os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version');
|
||||
}
|
||||
if (typeof exports == 'object' && exports) {
|
||||
// if `thisBinding` is the [ModuleScope]
|
||||
if (thisBinding == oldWin && typeof system == 'object' && (data = [system])[0]) {
|
||||
os || (os = data[0].os || null);
|
||||
try {
|
||||
data[1] = require('ringo/engine').version;
|
||||
version = data[1].join('.');
|
||||
name = 'RingoJS';
|
||||
} catch(e) {
|
||||
if (data[0].global == freeGlobal) {
|
||||
name = 'Narwhal';
|
||||
}
|
||||
}
|
||||
} else if (typeof process == 'object' && (data = process)) {
|
||||
name = 'Node.js';
|
||||
arch = data.arch;
|
||||
os = data.platform;
|
||||
version = /[\d.]+/.exec(data.version)[0];
|
||||
}
|
||||
} else if (getClassOf(window.environment) == 'Environment') {
|
||||
name = 'Rhino';
|
||||
}
|
||||
}
|
||||
// detect Adobe AIR
|
||||
else if (getClassOf(data = window.runtime) == 'ScriptBridgingProxyObject') {
|
||||
name = 'Adobe AIR';
|
||||
os = data.flash.system.Capabilities.os;
|
||||
}
|
||||
// detect PhantomJS
|
||||
else if (getClassOf(data = window.phantom) == 'RuntimeObject') {
|
||||
name = 'PhantomJS';
|
||||
version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch);
|
||||
}
|
||||
// detect IE compatibility modes
|
||||
else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) {
|
||||
// we're in compatibility mode when the Trident version + 4 doesn't
|
||||
// equal the document mode
|
||||
version = [version, doc.documentMode];
|
||||
if ((data = +data[1] + 4) != version[1]) {
|
||||
description.push('IE ' + version[1] + ' mode');
|
||||
layout[1] = '';
|
||||
version[1] = data;
|
||||
}
|
||||
version = name == 'IE' ? String(version[1].toFixed(1)) : version[0];
|
||||
}
|
||||
os = os && format(os);
|
||||
}
|
||||
// detect prerelease phases
|
||||
if (version && (data =
|
||||
/(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) ||
|
||||
/(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) ||
|
||||
/\bMinefield\b/i.test(ua) && 'a')) {
|
||||
prerelease = /b/i.test(data) ? 'beta' : 'alpha';
|
||||
version = version.replace(RegExp(data + '\\+?$'), '') +
|
||||
(prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || '');
|
||||
}
|
||||
// obscure Maxthon's unreliable version
|
||||
if (name == 'Maxthon' && version) {
|
||||
version = version.replace(/\.[\d.]+/, '.x');
|
||||
}
|
||||
// detect Silk desktop/accelerated modes
|
||||
else if (name == 'Silk') {
|
||||
if (!/Mobi/i.test(ua)) {
|
||||
os = 'Android';
|
||||
description.unshift('desktop mode');
|
||||
}
|
||||
if (/Accelerated *= *true/i.test(ua)) {
|
||||
description.unshift('accelerated');
|
||||
}
|
||||
}
|
||||
// detect Windows Phone desktop mode
|
||||
else if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) {
|
||||
name += ' Mobile';
|
||||
os = 'Windows Phone OS ' + data + '.x';
|
||||
description.unshift('desktop mode');
|
||||
}
|
||||
// add mobile postfix
|
||||
else if ((name == 'IE' || name && !product && !/Browser/.test(name)) &&
|
||||
(os == 'Windows CE' || /Mobi/i.test(ua))) {
|
||||
name += ' Mobile';
|
||||
}
|
||||
// detect IE platform preview
|
||||
else if (name == 'IE' && useFeatures && typeof external == 'object' && !external) {
|
||||
description.unshift('platform preview');
|
||||
}
|
||||
// detect BlackBerry OS version
|
||||
// http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp
|
||||
else if (/BlackBerry/.test(product) && (data =
|
||||
(RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] ||
|
||||
version)) {
|
||||
os = 'Device Software ' + data;
|
||||
version = null;
|
||||
}
|
||||
// detect Opera identifying/masking itself as another browser
|
||||
// http://www.opera.com/support/kb/view/843/
|
||||
else if (this != forOwn && (
|
||||
(useFeatures && opera) ||
|
||||
(/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) ||
|
||||
(name == 'Firefox' && /OS X (?:\d+\.){2,}/.test(os)) ||
|
||||
(name == 'IE' && (
|
||||
(os && !/^Win/.test(os) && version > 5.5) ||
|
||||
/Windows XP/.test(os) && version > 8 ||
|
||||
version == 8 && !/Trident/.test(ua)
|
||||
))
|
||||
) && !reOpera.test(data = parse.call(forOwn, ua.replace(reOpera, '') + ';')) && data.name) {
|
||||
|
||||
// when "indentifying" the UA contains both Opera and the other browser's name
|
||||
data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : '');
|
||||
if (reOpera.test(name)) {
|
||||
if (/IE/.test(data) && os == 'Mac OS') {
|
||||
os = null;
|
||||
}
|
||||
data = 'identify' + data;
|
||||
}
|
||||
// when "masking" the UA contains only the other browser's name
|
||||
else {
|
||||
data = 'mask' + data;
|
||||
if (operaClass) {
|
||||
name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2'));
|
||||
} else {
|
||||
name = 'Opera';
|
||||
}
|
||||
if (/IE/.test(data)) {
|
||||
os = null;
|
||||
}
|
||||
if (!useFeatures) {
|
||||
version = null;
|
||||
}
|
||||
}
|
||||
layout = ['Presto'];
|
||||
description.push(data);
|
||||
}
|
||||
// detect WebKit Nightly and approximate Chrome/Safari versions
|
||||
if ((data = (/AppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) {
|
||||
// correct build for numeric comparison
|
||||
// (e.g. "532.5" becomes "532.05")
|
||||
data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data];
|
||||
// nightly builds are postfixed with a `+`
|
||||
if (name == 'Safari' && data[1].slice(-1) == '+') {
|
||||
name = 'WebKit Nightly';
|
||||
prerelease = 'alpha';
|
||||
version = data[1].slice(0, -1);
|
||||
}
|
||||
// clear incorrect browser versions
|
||||
else if (version == data[1] ||
|
||||
version == (/Safari\/([\d.]+\+?)/i.exec(ua) || 0)[1]) {
|
||||
version = null;
|
||||
}
|
||||
// use the full Chrome version when available
|
||||
data = [data[0], (/Chrome\/([\d.]+)/i.exec(ua) || 0)[1]];
|
||||
|
||||
// detect JavaScriptCore
|
||||
// http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi
|
||||
if (!useFeatures || (/internal|\n/i.test(toString.toString()) && !data[1])) {
|
||||
layout[1] = 'like Safari';
|
||||
data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : '5');
|
||||
} else {
|
||||
layout[1] = 'like Chrome';
|
||||
data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 535.21 ? 18 : '19');
|
||||
}
|
||||
// add the postfix of ".x" or "+" for approximate versions
|
||||
layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+');
|
||||
// obscure version for some Safari 1-2 releases
|
||||
if (name == 'Safari' && (!version || parseInt(version) > 45)) {
|
||||
version = data;
|
||||
}
|
||||
}
|
||||
// strip incorrect OS versions
|
||||
if (version && version.indexOf(data = /[\d.]+$/.exec(os)) == 0 &&
|
||||
ua.indexOf('/' + data + '-') > -1) {
|
||||
os = trim(os.replace(data, ''));
|
||||
}
|
||||
// add layout engine
|
||||
if (layout && !/Avant|Nook/.test(name) && (
|
||||
/Browser|Lunascape|Maxthon/.test(name) ||
|
||||
/^(?:Adobe|Arora|Midori|Phantom|Rekonq|Rock|Sleipnir|Web)/.test(name) && layout[1])) {
|
||||
// don't add layout details to description if they are falsey
|
||||
(data = layout[layout.length - 1]) && description.push(data);
|
||||
}
|
||||
// combine contextual information
|
||||
if (description.length) {
|
||||
description = ['(' + description.join('; ') + ')'];
|
||||
}
|
||||
// append manufacturer
|
||||
if (manufacturer && product && product.indexOf(manufacturer) < 0) {
|
||||
description.push('on ' + manufacturer);
|
||||
}
|
||||
// append product
|
||||
if (product) {
|
||||
description.push((/^on /.test(description[description.length -1]) ? '' : 'on ') + product);
|
||||
}
|
||||
// add browser/OS architecture
|
||||
if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i).test(arch) && !/\bi686\b/i.test(arch)) {
|
||||
os = os && os + (data.test(os) ? '' : ' 64-bit');
|
||||
if (name && (/WOW64/i.test(ua) ||
|
||||
(useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform)))) {
|
||||
description.unshift('32-bit');
|
||||
}
|
||||
}
|
||||
|
||||
ua || (ua = null);
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* The platform object.
|
||||
* @name platform
|
||||
* @type Object
|
||||
*/
|
||||
return {
|
||||
|
||||
/**
|
||||
* The browser/environment version.
|
||||
* @memberOf platform
|
||||
* @type String|Null
|
||||
*/
|
||||
'version': name && version && (description.unshift(version), version),
|
||||
|
||||
/**
|
||||
* The name of the browser/environment.
|
||||
* @memberOf platform
|
||||
* @type String|Null
|
||||
*/
|
||||
'name': name && (description.unshift(name), name),
|
||||
|
||||
/**
|
||||
* The name of the operating system.
|
||||
* @memberOf platform
|
||||
* @type String|Null
|
||||
*/
|
||||
'os': os && (name &&
|
||||
!(os == os.split(' ')[0] && (os == name.split(' ')[0] || product)) &&
|
||||
description.push(product ? '(' + os + ')' : 'on ' + os), os),
|
||||
|
||||
/**
|
||||
* The platform description.
|
||||
* @memberOf platform
|
||||
* @type String|Null
|
||||
*/
|
||||
'description': description.length ? description.join(' ') : ua,
|
||||
|
||||
/**
|
||||
* The name of the browser layout engine.
|
||||
* @memberOf platform
|
||||
* @type String|Null
|
||||
*/
|
||||
'layout': layout && layout[0],
|
||||
|
||||
/**
|
||||
* The name of the product's manufacturer.
|
||||
* @memberOf platform
|
||||
* @type String|Null
|
||||
*/
|
||||
'manufacturer': manufacturer,
|
||||
|
||||
/**
|
||||
* The alpha/beta release indicator.
|
||||
* @memberOf platform
|
||||
* @type String|Null
|
||||
*/
|
||||
'prerelease': prerelease,
|
||||
|
||||
/**
|
||||
* The name of the product hosting the browser.
|
||||
* @memberOf platform
|
||||
* @type String|Null
|
||||
*/
|
||||
'product': product,
|
||||
|
||||
/**
|
||||
* The browser's user agent string.
|
||||
* @memberOf platform
|
||||
* @type String|Null
|
||||
*/
|
||||
'ua': ua,
|
||||
|
||||
// parses a user agent string into a platform object
|
||||
'parse': parse,
|
||||
|
||||
// returns the platform description
|
||||
'toString': toStringPlatform
|
||||
};
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
// expose platform
|
||||
// in Narwhal, Node.js, or RingoJS
|
||||
if (freeExports) {
|
||||
forOwn(parse(), function(value, key) {
|
||||
freeExports[key] = value;
|
||||
});
|
||||
}
|
||||
// via an AMD loader
|
||||
else if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
|
||||
define('platform', function() {
|
||||
return parse();
|
||||
});
|
||||
}
|
||||
// in a browser or Rhino
|
||||
else {
|
||||
// use square bracket notation so Closure Compiler won't munge `platform`
|
||||
// http://code.google.com/closure/compiler/docs/api-tutorial3.html#export
|
||||
window['platform'] = parse();
|
||||
}
|
||||
}(this));
|
4874
node_modules/esprima/test/3rdparty/prototype-1.6.1.js
generated
vendored
4874
node_modules/esprima/test/3rdparty/prototype-1.6.1.js
generated
vendored
File diff suppressed because it is too large
Load Diff
6082
node_modules/esprima/test/3rdparty/prototype-1.7.0.0.js
generated
vendored
6082
node_modules/esprima/test/3rdparty/prototype-1.7.0.0.js
generated
vendored
File diff suppressed because it is too large
Load Diff
981
node_modules/esprima/test/3rdparty/underscore-1.2.3.js
generated
vendored
981
node_modules/esprima/test/3rdparty/underscore-1.2.3.js
generated
vendored
@@ -1,981 +0,0 @@
|
||||
// Underscore.js 1.2.3
|
||||
// (c) 2009-2011 Jeremy Ashkenas, DocumentCloud Inc.
|
||||
// Underscore is freely distributable under the MIT license.
|
||||
// Portions of Underscore are inspired or borrowed from Prototype,
|
||||
// Oliver Steele's Functional, and John Resig's Micro-Templating.
|
||||
// For all details and documentation:
|
||||
// http://documentcloud.github.com/underscore
|
||||
|
||||
(function() {
|
||||
|
||||
// Baseline setup
|
||||
// --------------
|
||||
|
||||
// Establish the root object, `window` in the browser, or `global` on the server.
|
||||
var root = this;
|
||||
|
||||
// Save the previous value of the `_` variable.
|
||||
var previousUnderscore = root._;
|
||||
|
||||
// Establish the object that gets returned to break out of a loop iteration.
|
||||
var breaker = {};
|
||||
|
||||
// Save bytes in the minified (but not gzipped) version:
|
||||
var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
|
||||
|
||||
// Create quick reference variables for speed access to core prototypes.
|
||||
var slice = ArrayProto.slice,
|
||||
concat = ArrayProto.concat,
|
||||
unshift = ArrayProto.unshift,
|
||||
toString = ObjProto.toString,
|
||||
hasOwnProperty = ObjProto.hasOwnProperty;
|
||||
|
||||
// All **ECMAScript 5** native function implementations that we hope to use
|
||||
// are declared here.
|
||||
var
|
||||
nativeForEach = ArrayProto.forEach,
|
||||
nativeMap = ArrayProto.map,
|
||||
nativeReduce = ArrayProto.reduce,
|
||||
nativeReduceRight = ArrayProto.reduceRight,
|
||||
nativeFilter = ArrayProto.filter,
|
||||
nativeEvery = ArrayProto.every,
|
||||
nativeSome = ArrayProto.some,
|
||||
nativeIndexOf = ArrayProto.indexOf,
|
||||
nativeLastIndexOf = ArrayProto.lastIndexOf,
|
||||
nativeIsArray = Array.isArray,
|
||||
nativeKeys = Object.keys,
|
||||
nativeBind = FuncProto.bind;
|
||||
|
||||
// Create a safe reference to the Underscore object for use below.
|
||||
var _ = function(obj) { return new wrapper(obj); };
|
||||
|
||||
// Export the Underscore object for **Node.js** and **"CommonJS"**, with
|
||||
// backwards-compatibility for the old `require()` API. If we're not in
|
||||
// CommonJS, add `_` to the global object.
|
||||
if (typeof exports !== 'undefined') {
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
exports = module.exports = _;
|
||||
}
|
||||
exports._ = _;
|
||||
} else if (typeof define === 'function' && define.amd) {
|
||||
// Register as a named module with AMD.
|
||||
define('underscore', function() {
|
||||
return _;
|
||||
});
|
||||
} else {
|
||||
// Exported as a string, for Closure Compiler "advanced" mode.
|
||||
root['_'] = _;
|
||||
}
|
||||
|
||||
// Current version.
|
||||
_.VERSION = '1.2.3';
|
||||
|
||||
// Collection Functions
|
||||
// --------------------
|
||||
|
||||
// The cornerstone, an `each` implementation, aka `forEach`.
|
||||
// Handles objects with the built-in `forEach`, arrays, and raw objects.
|
||||
// Delegates to **ECMAScript 5**'s native `forEach` if available.
|
||||
var each = _.each = _.forEach = function(obj, iterator, context) {
|
||||
if (obj == null) return;
|
||||
if (nativeForEach && obj.forEach === nativeForEach) {
|
||||
obj.forEach(iterator, context);
|
||||
} else if (obj.length === +obj.length) {
|
||||
for (var i = 0, l = obj.length; i < l; i++) {
|
||||
if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;
|
||||
}
|
||||
} else {
|
||||
for (var key in obj) {
|
||||
if (hasOwnProperty.call(obj, key)) {
|
||||
if (iterator.call(context, obj[key], key, obj) === breaker) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Return the results of applying the iterator to each element.
|
||||
// Delegates to **ECMAScript 5**'s native `map` if available.
|
||||
_.map = function(obj, iterator, context) {
|
||||
var results = [];
|
||||
if (obj == null) return results;
|
||||
if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
|
||||
each(obj, function(value, index, list) {
|
||||
results[results.length] = iterator.call(context, value, index, list);
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
// **Reduce** builds up a single result from a list of values, aka `inject`,
|
||||
// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
|
||||
_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
|
||||
var initial = arguments.length > 2;
|
||||
if (obj == null) obj = [];
|
||||
if (nativeReduce && obj.reduce === nativeReduce) {
|
||||
if (context) iterator = _.bind(iterator, context);
|
||||
return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
|
||||
}
|
||||
each(obj, function(value, index, list) {
|
||||
if (!initial) {
|
||||
memo = value;
|
||||
initial = true;
|
||||
} else {
|
||||
memo = iterator.call(context, memo, value, index, list);
|
||||
}
|
||||
});
|
||||
if (!initial) throw new TypeError('Reduce of empty array with no initial value');
|
||||
return memo;
|
||||
};
|
||||
|
||||
// The right-associative version of reduce, also known as `foldr`.
|
||||
// Delegates to **ECMAScript 5**'s native `reduceRight` if available.
|
||||
_.reduceRight = _.foldr = function(obj, iterator, memo, context) {
|
||||
var initial = arguments.length > 2;
|
||||
if (obj == null) obj = [];
|
||||
if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
|
||||
if (context) iterator = _.bind(iterator, context);
|
||||
return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
|
||||
}
|
||||
var reversed = _.toArray(obj).reverse();
|
||||
if (context && !initial) iterator = _.bind(iterator, context);
|
||||
return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator);
|
||||
};
|
||||
|
||||
// Return the first value which passes a truth test. Aliased as `detect`.
|
||||
_.find = _.detect = function(obj, iterator, context) {
|
||||
var result;
|
||||
any(obj, function(value, index, list) {
|
||||
if (iterator.call(context, value, index, list)) {
|
||||
result = value;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
// Return all the elements that pass a truth test.
|
||||
// Delegates to **ECMAScript 5**'s native `filter` if available.
|
||||
// Aliased as `select`.
|
||||
_.filter = _.select = function(obj, iterator, context) {
|
||||
var results = [];
|
||||
if (obj == null) return results;
|
||||
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
|
||||
each(obj, function(value, index, list) {
|
||||
if (iterator.call(context, value, index, list)) results[results.length] = value;
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
// Return all the elements for which a truth test fails.
|
||||
_.reject = function(obj, iterator, context) {
|
||||
var results = [];
|
||||
if (obj == null) return results;
|
||||
each(obj, function(value, index, list) {
|
||||
if (!iterator.call(context, value, index, list)) results[results.length] = value;
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
// Determine whether all of the elements match a truth test.
|
||||
// Delegates to **ECMAScript 5**'s native `every` if available.
|
||||
// Aliased as `all`.
|
||||
_.every = _.all = function(obj, iterator, context) {
|
||||
var result = true;
|
||||
if (obj == null) return result;
|
||||
if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
|
||||
each(obj, function(value, index, list) {
|
||||
if (!(result = result && iterator.call(context, value, index, list))) return breaker;
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
// Determine if at least one element in the object matches a truth test.
|
||||
// Delegates to **ECMAScript 5**'s native `some` if available.
|
||||
// Aliased as `any`.
|
||||
var any = _.some = _.any = function(obj, iterator, context) {
|
||||
iterator || (iterator = _.identity);
|
||||
var result = false;
|
||||
if (obj == null) return result;
|
||||
if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
|
||||
each(obj, function(value, index, list) {
|
||||
if (result || (result = iterator.call(context, value, index, list))) return breaker;
|
||||
});
|
||||
return !!result;
|
||||
};
|
||||
|
||||
// Determine if a given value is included in the array or object using `===`.
|
||||
// Aliased as `contains`.
|
||||
_.include = _.contains = function(obj, target) {
|
||||
var found = false;
|
||||
if (obj == null) return found;
|
||||
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
|
||||
found = any(obj, function(value) {
|
||||
return value === target;
|
||||
});
|
||||
return found;
|
||||
};
|
||||
|
||||
// Invoke a method (with arguments) on every item in a collection.
|
||||
_.invoke = function(obj, method) {
|
||||
var args = slice.call(arguments, 2);
|
||||
return _.map(obj, function(value) {
|
||||
return (method.call ? method || value : value[method]).apply(value, args);
|
||||
});
|
||||
};
|
||||
|
||||
// Convenience version of a common use case of `map`: fetching a property.
|
||||
_.pluck = function(obj, key) {
|
||||
return _.map(obj, function(value){ return value[key]; });
|
||||
};
|
||||
|
||||
// Return the maximum element or (element-based computation).
|
||||
_.max = function(obj, iterator, context) {
|
||||
if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
|
||||
if (!iterator && _.isEmpty(obj)) return -Infinity;
|
||||
var result = {computed : -Infinity};
|
||||
each(obj, function(value, index, list) {
|
||||
var computed = iterator ? iterator.call(context, value, index, list) : value;
|
||||
computed >= result.computed && (result = {value : value, computed : computed});
|
||||
});
|
||||
return result.value;
|
||||
};
|
||||
|
||||
// Return the minimum element (or element-based computation).
|
||||
_.min = function(obj, iterator, context) {
|
||||
if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
|
||||
if (!iterator && _.isEmpty(obj)) return Infinity;
|
||||
var result = {computed : Infinity};
|
||||
each(obj, function(value, index, list) {
|
||||
var computed = iterator ? iterator.call(context, value, index, list) : value;
|
||||
computed < result.computed && (result = {value : value, computed : computed});
|
||||
});
|
||||
return result.value;
|
||||
};
|
||||
|
||||
// Shuffle an array.
|
||||
_.shuffle = function(obj) {
|
||||
var shuffled = [], rand;
|
||||
each(obj, function(value, index, list) {
|
||||
if (index == 0) {
|
||||
shuffled[0] = value;
|
||||
} else {
|
||||
rand = Math.floor(Math.random() * (index + 1));
|
||||
shuffled[index] = shuffled[rand];
|
||||
shuffled[rand] = value;
|
||||
}
|
||||
});
|
||||
return shuffled;
|
||||
};
|
||||
|
||||
// Sort the object's values by a criterion produced by an iterator.
|
||||
_.sortBy = function(obj, iterator, context) {
|
||||
return _.pluck(_.map(obj, function(value, index, list) {
|
||||
return {
|
||||
value : value,
|
||||
criteria : iterator.call(context, value, index, list)
|
||||
};
|
||||
}).sort(function(left, right) {
|
||||
var a = left.criteria, b = right.criteria;
|
||||
return a < b ? -1 : a > b ? 1 : 0;
|
||||
}), 'value');
|
||||
};
|
||||
|
||||
// Groups the object's values by a criterion. Pass either a string attribute
|
||||
// to group by, or a function that returns the criterion.
|
||||
_.groupBy = function(obj, val) {
|
||||
var result = {};
|
||||
var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
|
||||
each(obj, function(value, index) {
|
||||
var key = iterator(value, index);
|
||||
(result[key] || (result[key] = [])).push(value);
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
// Use a comparator function to figure out at what index an object should
|
||||
// be inserted so as to maintain order. Uses binary search.
|
||||
_.sortedIndex = function(array, obj, iterator) {
|
||||
iterator || (iterator = _.identity);
|
||||
var low = 0, high = array.length;
|
||||
while (low < high) {
|
||||
var mid = (low + high) >> 1;
|
||||
iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
|
||||
}
|
||||
return low;
|
||||
};
|
||||
|
||||
// Safely convert anything iterable into a real, live array.
|
||||
_.toArray = function(iterable) {
|
||||
if (!iterable) return [];
|
||||
if (iterable.toArray) return iterable.toArray();
|
||||
if (_.isArray(iterable)) return slice.call(iterable);
|
||||
if (_.isArguments(iterable)) return slice.call(iterable);
|
||||
return _.values(iterable);
|
||||
};
|
||||
|
||||
// Return the number of elements in an object.
|
||||
_.size = function(obj) {
|
||||
return _.toArray(obj).length;
|
||||
};
|
||||
|
||||
// Array Functions
|
||||
// ---------------
|
||||
|
||||
// Get the first element of an array. Passing **n** will return the first N
|
||||
// values in the array. Aliased as `head`. The **guard** check allows it to work
|
||||
// with `_.map`.
|
||||
_.first = _.head = function(array, n, guard) {
|
||||
return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
|
||||
};
|
||||
|
||||
// Returns everything but the last entry of the array. Especcialy useful on
|
||||
// the arguments object. Passing **n** will return all the values in
|
||||
// the array, excluding the last N. The **guard** check allows it to work with
|
||||
// `_.map`.
|
||||
_.initial = function(array, n, guard) {
|
||||
return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
|
||||
};
|
||||
|
||||
// Get the last element of an array. Passing **n** will return the last N
|
||||
// values in the array. The **guard** check allows it to work with `_.map`.
|
||||
_.last = function(array, n, guard) {
|
||||
if ((n != null) && !guard) {
|
||||
return slice.call(array, Math.max(array.length - n, 0));
|
||||
} else {
|
||||
return array[array.length - 1];
|
||||
}
|
||||
};
|
||||
|
||||
// Returns everything but the first entry of the array. Aliased as `tail`.
|
||||
// Especially useful on the arguments object. Passing an **index** will return
|
||||
// the rest of the values in the array from that index onward. The **guard**
|
||||
// check allows it to work with `_.map`.
|
||||
_.rest = _.tail = function(array, index, guard) {
|
||||
return slice.call(array, (index == null) || guard ? 1 : index);
|
||||
};
|
||||
|
||||
// Trim out all falsy values from an array.
|
||||
_.compact = function(array) {
|
||||
return _.filter(array, function(value){ return !!value; });
|
||||
};
|
||||
|
||||
// Return a completely flattened version of an array.
|
||||
_.flatten = function(array, shallow) {
|
||||
return _.reduce(array, function(memo, value) {
|
||||
if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));
|
||||
memo[memo.length] = value;
|
||||
return memo;
|
||||
}, []);
|
||||
};
|
||||
|
||||
// Return a version of the array that does not contain the specified value(s).
|
||||
_.without = function(array) {
|
||||
return _.difference(array, slice.call(arguments, 1));
|
||||
};
|
||||
|
||||
// Produce a duplicate-free version of the array. If the array has already
|
||||
// been sorted, you have the option of using a faster algorithm.
|
||||
// Aliased as `unique`.
|
||||
_.uniq = _.unique = function(array, isSorted, iterator) {
|
||||
var initial = iterator ? _.map(array, iterator) : array;
|
||||
var result = [];
|
||||
_.reduce(initial, function(memo, el, i) {
|
||||
if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) {
|
||||
memo[memo.length] = el;
|
||||
result[result.length] = array[i];
|
||||
}
|
||||
return memo;
|
||||
}, []);
|
||||
return result;
|
||||
};
|
||||
|
||||
// Produce an array that contains the union: each distinct element from all of
|
||||
// the passed-in arrays.
|
||||
_.union = function() {
|
||||
return _.uniq(_.flatten(arguments, true));
|
||||
};
|
||||
|
||||
// Produce an array that contains every item shared between all the
|
||||
// passed-in arrays. (Aliased as "intersect" for back-compat.)
|
||||
_.intersection = _.intersect = function(array) {
|
||||
var rest = slice.call(arguments, 1);
|
||||
return _.filter(_.uniq(array), function(item) {
|
||||
return _.every(rest, function(other) {
|
||||
return _.indexOf(other, item) >= 0;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Take the difference between one array and a number of other arrays.
|
||||
// Only the elements present in just the first array will remain.
|
||||
_.difference = function(array) {
|
||||
var rest = _.flatten(slice.call(arguments, 1));
|
||||
return _.filter(array, function(value){ return !_.include(rest, value); });
|
||||
};
|
||||
|
||||
// Zip together multiple lists into a single array -- elements that share
|
||||
// an index go together.
|
||||
_.zip = function() {
|
||||
var args = slice.call(arguments);
|
||||
var length = _.max(_.pluck(args, 'length'));
|
||||
var results = new Array(length);
|
||||
for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);
|
||||
return results;
|
||||
};
|
||||
|
||||
// If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
|
||||
// we need this function. Return the position of the first occurrence of an
|
||||
// item in an array, or -1 if the item is not included in the array.
|
||||
// Delegates to **ECMAScript 5**'s native `indexOf` if available.
|
||||
// If the array is large and already in sort order, pass `true`
|
||||
// for **isSorted** to use binary search.
|
||||
_.indexOf = function(array, item, isSorted) {
|
||||
if (array == null) return -1;
|
||||
var i, l;
|
||||
if (isSorted) {
|
||||
i = _.sortedIndex(array, item);
|
||||
return array[i] === item ? i : -1;
|
||||
}
|
||||
if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
|
||||
for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i;
|
||||
return -1;
|
||||
};
|
||||
|
||||
// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
|
||||
_.lastIndexOf = function(array, item) {
|
||||
if (array == null) return -1;
|
||||
if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
|
||||
var i = array.length;
|
||||
while (i--) if (i in array && array[i] === item) return i;
|
||||
return -1;
|
||||
};
|
||||
|
||||
// Generate an integer Array containing an arithmetic progression. A port of
|
||||
// the native Python `range()` function. See
|
||||
// [the Python documentation](http://docs.python.org/library/functions.html#range).
|
||||
_.range = function(start, stop, step) {
|
||||
if (arguments.length <= 1) {
|
||||
stop = start || 0;
|
||||
start = 0;
|
||||
}
|
||||
step = arguments[2] || 1;
|
||||
|
||||
var len = Math.max(Math.ceil((stop - start) / step), 0);
|
||||
var idx = 0;
|
||||
var range = new Array(len);
|
||||
|
||||
while(idx < len) {
|
||||
range[idx++] = start;
|
||||
start += step;
|
||||
}
|
||||
|
||||
return range;
|
||||
};
|
||||
|
||||
// Function (ahem) Functions
|
||||
// ------------------
|
||||
|
||||
// Reusable constructor function for prototype setting.
|
||||
var ctor = function(){};
|
||||
|
||||
// Create a function bound to a given object (assigning `this`, and arguments,
|
||||
// optionally). Binding with arguments is also known as `curry`.
|
||||
// Delegates to **ECMAScript 5**'s native `Function.bind` if available.
|
||||
// We check for `func.bind` first, to fail fast when `func` is undefined.
|
||||
_.bind = function bind(func, context) {
|
||||
var bound, args;
|
||||
if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
|
||||
if (!_.isFunction(func)) throw new TypeError;
|
||||
args = slice.call(arguments, 2);
|
||||
return bound = function() {
|
||||
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
|
||||
ctor.prototype = func.prototype;
|
||||
var self = new ctor;
|
||||
var result = func.apply(self, args.concat(slice.call(arguments)));
|
||||
if (Object(result) === result) return result;
|
||||
return self;
|
||||
};
|
||||
};
|
||||
|
||||
// Bind all of an object's methods to that object. Useful for ensuring that
|
||||
// all callbacks defined on an object belong to it.
|
||||
_.bindAll = function(obj) {
|
||||
var funcs = slice.call(arguments, 1);
|
||||
if (funcs.length == 0) funcs = _.functions(obj);
|
||||
each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
|
||||
return obj;
|
||||
};
|
||||
|
||||
// Memoize an expensive function by storing its results.
|
||||
_.memoize = function(func, hasher) {
|
||||
var memo = {};
|
||||
hasher || (hasher = _.identity);
|
||||
return function() {
|
||||
var key = hasher.apply(this, arguments);
|
||||
return hasOwnProperty.call(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
|
||||
};
|
||||
};
|
||||
|
||||
// Delays a function for the given number of milliseconds, and then calls
|
||||
// it with the arguments supplied.
|
||||
_.delay = function(func, wait) {
|
||||
var args = slice.call(arguments, 2);
|
||||
return setTimeout(function(){ return func.apply(func, args); }, wait);
|
||||
};
|
||||
|
||||
// Defers a function, scheduling it to run after the current call stack has
|
||||
// cleared.
|
||||
_.defer = function(func) {
|
||||
return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
|
||||
};
|
||||
|
||||
// Returns a function, that, when invoked, will only be triggered at most once
|
||||
// during a given window of time.
|
||||
_.throttle = function(func, wait) {
|
||||
var context, args, timeout, throttling, more;
|
||||
var whenDone = _.debounce(function(){ more = throttling = false; }, wait);
|
||||
return function() {
|
||||
context = this; args = arguments;
|
||||
var later = function() {
|
||||
timeout = null;
|
||||
if (more) func.apply(context, args);
|
||||
whenDone();
|
||||
};
|
||||
if (!timeout) timeout = setTimeout(later, wait);
|
||||
if (throttling) {
|
||||
more = true;
|
||||
} else {
|
||||
func.apply(context, args);
|
||||
}
|
||||
whenDone();
|
||||
throttling = true;
|
||||
};
|
||||
};
|
||||
|
||||
// Returns a function, that, as long as it continues to be invoked, will not
|
||||
// be triggered. The function will be called after it stops being called for
|
||||
// N milliseconds.
|
||||
_.debounce = function(func, wait) {
|
||||
var timeout;
|
||||
return function() {
|
||||
var context = this, args = arguments;
|
||||
var later = function() {
|
||||
timeout = null;
|
||||
func.apply(context, args);
|
||||
};
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(later, wait);
|
||||
};
|
||||
};
|
||||
|
||||
// Returns a function that will be executed at most one time, no matter how
|
||||
// often you call it. Useful for lazy initialization.
|
||||
_.once = function(func) {
|
||||
var ran = false, memo;
|
||||
return function() {
|
||||
if (ran) return memo;
|
||||
ran = true;
|
||||
return memo = func.apply(this, arguments);
|
||||
};
|
||||
};
|
||||
|
||||
// Returns the first function passed as an argument to the second,
|
||||
// allowing you to adjust arguments, run code before and after, and
|
||||
// conditionally execute the original function.
|
||||
_.wrap = function(func, wrapper) {
|
||||
return function() {
|
||||
var args = concat.apply([func], arguments);
|
||||
return wrapper.apply(this, args);
|
||||
};
|
||||
};
|
||||
|
||||
// Returns a function that is the composition of a list of functions, each
|
||||
// consuming the return value of the function that follows.
|
||||
_.compose = function() {
|
||||
var funcs = arguments;
|
||||
return function() {
|
||||
var args = arguments;
|
||||
for (var i = funcs.length - 1; i >= 0; i--) {
|
||||
args = [funcs[i].apply(this, args)];
|
||||
}
|
||||
return args[0];
|
||||
};
|
||||
};
|
||||
|
||||
// Returns a function that will only be executed after being called N times.
|
||||
_.after = function(times, func) {
|
||||
if (times <= 0) return func();
|
||||
return function() {
|
||||
if (--times < 1) { return func.apply(this, arguments); }
|
||||
};
|
||||
};
|
||||
|
||||
// Object Functions
|
||||
// ----------------
|
||||
|
||||
// Retrieve the names of an object's properties.
|
||||
// Delegates to **ECMAScript 5**'s native `Object.keys`
|
||||
_.keys = nativeKeys || function(obj) {
|
||||
if (obj !== Object(obj)) throw new TypeError('Invalid object');
|
||||
var keys = [];
|
||||
for (var key in obj) if (hasOwnProperty.call(obj, key)) keys[keys.length] = key;
|
||||
return keys;
|
||||
};
|
||||
|
||||
// Retrieve the values of an object's properties.
|
||||
_.values = function(obj) {
|
||||
return _.map(obj, _.identity);
|
||||
};
|
||||
|
||||
// Return a sorted list of the function names available on the object.
|
||||
// Aliased as `methods`
|
||||
_.functions = _.methods = function(obj) {
|
||||
var names = [];
|
||||
for (var key in obj) {
|
||||
if (_.isFunction(obj[key])) names.push(key);
|
||||
}
|
||||
return names.sort();
|
||||
};
|
||||
|
||||
// Extend a given object with all the properties in passed-in object(s).
|
||||
_.extend = function(obj) {
|
||||
each(slice.call(arguments, 1), function(source) {
|
||||
for (var prop in source) {
|
||||
if (source[prop] !== void 0) obj[prop] = source[prop];
|
||||
}
|
||||
});
|
||||
return obj;
|
||||
};
|
||||
|
||||
// Fill in a given object with default properties.
|
||||
_.defaults = function(obj) {
|
||||
each(slice.call(arguments, 1), function(source) {
|
||||
for (var prop in source) {
|
||||
if (obj[prop] == null) obj[prop] = source[prop];
|
||||
}
|
||||
});
|
||||
return obj;
|
||||
};
|
||||
|
||||
// Create a (shallow-cloned) duplicate of an object.
|
||||
_.clone = function(obj) {
|
||||
if (!_.isObject(obj)) return obj;
|
||||
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
|
||||
};
|
||||
|
||||
// Invokes interceptor with the obj, and then returns obj.
|
||||
// The primary purpose of this method is to "tap into" a method chain, in
|
||||
// order to perform operations on intermediate results within the chain.
|
||||
_.tap = function(obj, interceptor) {
|
||||
interceptor(obj);
|
||||
return obj;
|
||||
};
|
||||
|
||||
// Internal recursive comparison function.
|
||||
function eq(a, b, stack) {
|
||||
// Identical objects are equal. `0 === -0`, but they aren't identical.
|
||||
// See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
|
||||
if (a === b) return a !== 0 || 1 / a == 1 / b;
|
||||
// A strict comparison is necessary because `null == undefined`.
|
||||
if (a == null || b == null) return a === b;
|
||||
// Unwrap any wrapped objects.
|
||||
if (a._chain) a = a._wrapped;
|
||||
if (b._chain) b = b._wrapped;
|
||||
// Invoke a custom `isEqual` method if one is provided.
|
||||
if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b);
|
||||
if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a);
|
||||
// Compare `[[Class]]` names.
|
||||
var className = toString.call(a);
|
||||
if (className != toString.call(b)) return false;
|
||||
switch (className) {
|
||||
// Strings, numbers, dates, and booleans are compared by value.
|
||||
case '[object String]':
|
||||
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
|
||||
// equivalent to `new String("5")`.
|
||||
return a == String(b);
|
||||
case '[object Number]':
|
||||
// `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
|
||||
// other numeric values.
|
||||
return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
|
||||
case '[object Date]':
|
||||
case '[object Boolean]':
|
||||
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
|
||||
// millisecond representations. Note that invalid dates with millisecond representations
|
||||
// of `NaN` are not equivalent.
|
||||
return +a == +b;
|
||||
// RegExps are compared by their source patterns and flags.
|
||||
case '[object RegExp]':
|
||||
return a.source == b.source &&
|
||||
a.global == b.global &&
|
||||
a.multiline == b.multiline &&
|
||||
a.ignoreCase == b.ignoreCase;
|
||||
}
|
||||
if (typeof a != 'object' || typeof b != 'object') return false;
|
||||
// Assume equality for cyclic structures. The algorithm for detecting cyclic
|
||||
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
|
||||
var length = stack.length;
|
||||
while (length--) {
|
||||
// Linear search. Performance is inversely proportional to the number of
|
||||
// unique nested structures.
|
||||
if (stack[length] == a) return true;
|
||||
}
|
||||
// Add the first object to the stack of traversed objects.
|
||||
stack.push(a);
|
||||
var size = 0, result = true;
|
||||
// Recursively compare objects and arrays.
|
||||
if (className == '[object Array]') {
|
||||
// Compare array lengths to determine if a deep comparison is necessary.
|
||||
size = a.length;
|
||||
result = size == b.length;
|
||||
if (result) {
|
||||
// Deep compare the contents, ignoring non-numeric properties.
|
||||
while (size--) {
|
||||
// Ensure commutative equality for sparse arrays.
|
||||
if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Objects with different constructors are not equivalent.
|
||||
if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false;
|
||||
// Deep compare objects.
|
||||
for (var key in a) {
|
||||
if (hasOwnProperty.call(a, key)) {
|
||||
// Count the expected number of properties.
|
||||
size++;
|
||||
// Deep compare each member.
|
||||
if (!(result = hasOwnProperty.call(b, key) && eq(a[key], b[key], stack))) break;
|
||||
}
|
||||
}
|
||||
// Ensure that both objects contain the same number of properties.
|
||||
if (result) {
|
||||
for (key in b) {
|
||||
if (hasOwnProperty.call(b, key) && !(size--)) break;
|
||||
}
|
||||
result = !size;
|
||||
}
|
||||
}
|
||||
// Remove the first object from the stack of traversed objects.
|
||||
stack.pop();
|
||||
return result;
|
||||
}
|
||||
|
||||
// Perform a deep comparison to check if two objects are equal.
|
||||
_.isEqual = function(a, b) {
|
||||
return eq(a, b, []);
|
||||
};
|
||||
|
||||
// Is a given array, string, or object empty?
|
||||
// An "empty" object has no enumerable own-properties.
|
||||
_.isEmpty = function(obj) {
|
||||
if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
|
||||
for (var key in obj) if (hasOwnProperty.call(obj, key)) return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
// Is a given value a DOM element?
|
||||
_.isElement = function(obj) {
|
||||
return !!(obj && obj.nodeType == 1);
|
||||
};
|
||||
|
||||
// Is a given value an array?
|
||||
// Delegates to ECMA5's native Array.isArray
|
||||
_.isArray = nativeIsArray || function(obj) {
|
||||
return toString.call(obj) == '[object Array]';
|
||||
};
|
||||
|
||||
// Is a given variable an object?
|
||||
_.isObject = function(obj) {
|
||||
return obj === Object(obj);
|
||||
};
|
||||
|
||||
// Is a given variable an arguments object?
|
||||
_.isArguments = function(obj) {
|
||||
return toString.call(obj) == '[object Arguments]';
|
||||
};
|
||||
if (!_.isArguments(arguments)) {
|
||||
_.isArguments = function(obj) {
|
||||
return !!(obj && hasOwnProperty.call(obj, 'callee'));
|
||||
};
|
||||
}
|
||||
|
||||
// Is a given value a function?
|
||||
_.isFunction = function(obj) {
|
||||
return toString.call(obj) == '[object Function]';
|
||||
};
|
||||
|
||||
// Is a given value a string?
|
||||
_.isString = function(obj) {
|
||||
return toString.call(obj) == '[object String]';
|
||||
};
|
||||
|
||||
// Is a given value a number?
|
||||
_.isNumber = function(obj) {
|
||||
return toString.call(obj) == '[object Number]';
|
||||
};
|
||||
|
||||
// Is the given value `NaN`?
|
||||
_.isNaN = function(obj) {
|
||||
// `NaN` is the only value for which `===` is not reflexive.
|
||||
return obj !== obj;
|
||||
};
|
||||
|
||||
// Is a given value a boolean?
|
||||
_.isBoolean = function(obj) {
|
||||
return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
|
||||
};
|
||||
|
||||
// Is a given value a date?
|
||||
_.isDate = function(obj) {
|
||||
return toString.call(obj) == '[object Date]';
|
||||
};
|
||||
|
||||
// Is the given value a regular expression?
|
||||
_.isRegExp = function(obj) {
|
||||
return toString.call(obj) == '[object RegExp]';
|
||||
};
|
||||
|
||||
// Is a given value equal to null?
|
||||
_.isNull = function(obj) {
|
||||
return obj === null;
|
||||
};
|
||||
|
||||
// Is a given variable undefined?
|
||||
_.isUndefined = function(obj) {
|
||||
return obj === void 0;
|
||||
};
|
||||
|
||||
// Utility Functions
|
||||
// -----------------
|
||||
|
||||
// Run Underscore.js in *noConflict* mode, returning the `_` variable to its
|
||||
// previous owner. Returns a reference to the Underscore object.
|
||||
_.noConflict = function() {
|
||||
root._ = previousUnderscore;
|
||||
return this;
|
||||
};
|
||||
|
||||
// Keep the identity function around for default iterators.
|
||||
_.identity = function(value) {
|
||||
return value;
|
||||
};
|
||||
|
||||
// Run a function **n** times.
|
||||
_.times = function (n, iterator, context) {
|
||||
for (var i = 0; i < n; i++) iterator.call(context, i);
|
||||
};
|
||||
|
||||
// Escape a string for HTML interpolation.
|
||||
_.escape = function(string) {
|
||||
return (''+string).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g,'/');
|
||||
};
|
||||
|
||||
// Add your own custom functions to the Underscore object, ensuring that
|
||||
// they're correctly added to the OOP wrapper as well.
|
||||
_.mixin = function(obj) {
|
||||
each(_.functions(obj), function(name){
|
||||
addToWrapper(name, _[name] = obj[name]);
|
||||
});
|
||||
};
|
||||
|
||||
// Generate a unique integer id (unique within the entire client session).
|
||||
// Useful for temporary DOM ids.
|
||||
var idCounter = 0;
|
||||
_.uniqueId = function(prefix) {
|
||||
var id = idCounter++;
|
||||
return prefix ? prefix + id : id;
|
||||
};
|
||||
|
||||
// By default, Underscore uses ERB-style template delimiters, change the
|
||||
// following template settings to use alternative delimiters.
|
||||
_.templateSettings = {
|
||||
evaluate : /<%([\s\S]+?)%>/g,
|
||||
interpolate : /<%=([\s\S]+?)%>/g,
|
||||
escape : /<%-([\s\S]+?)%>/g
|
||||
};
|
||||
|
||||
// JavaScript micro-templating, similar to John Resig's implementation.
|
||||
// Underscore templating handles arbitrary delimiters, preserves whitespace,
|
||||
// and correctly escapes quotes within interpolated code.
|
||||
_.template = function(str, data) {
|
||||
var c = _.templateSettings;
|
||||
var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
|
||||
'with(obj||{}){__p.push(\'' +
|
||||
str.replace(/\\/g, '\\\\')
|
||||
.replace(/'/g, "\\'")
|
||||
.replace(c.escape, function(match, code) {
|
||||
return "',_.escape(" + code.replace(/\\'/g, "'") + "),'";
|
||||
})
|
||||
.replace(c.interpolate, function(match, code) {
|
||||
return "'," + code.replace(/\\'/g, "'") + ",'";
|
||||
})
|
||||
.replace(c.evaluate || null, function(match, code) {
|
||||
return "');" + code.replace(/\\'/g, "'")
|
||||
.replace(/[\r\n\t]/g, ' ') + ";__p.push('";
|
||||
})
|
||||
.replace(/\r/g, '\\r')
|
||||
.replace(/\n/g, '\\n')
|
||||
.replace(/\t/g, '\\t')
|
||||
+ "');}return __p.join('');";
|
||||
var func = new Function('obj', '_', tmpl);
|
||||
if (data) return func(data, _);
|
||||
return function(data) {
|
||||
return func.call(this, data, _);
|
||||
};
|
||||
};
|
||||
|
||||
// The OOP Wrapper
|
||||
// ---------------
|
||||
|
||||
// If Underscore is called as a function, it returns a wrapped object that
|
||||
// can be used OO-style. This wrapper holds altered versions of all the
|
||||
// underscore functions. Wrapped objects may be chained.
|
||||
var wrapper = function(obj) { this._wrapped = obj; };
|
||||
|
||||
// Expose `wrapper.prototype` as `_.prototype`
|
||||
_.prototype = wrapper.prototype;
|
||||
|
||||
// Helper function to continue chaining intermediate results.
|
||||
var result = function(obj, chain) {
|
||||
return chain ? _(obj).chain() : obj;
|
||||
};
|
||||
|
||||
// A method to easily add functions to the OOP wrapper.
|
||||
var addToWrapper = function(name, func) {
|
||||
wrapper.prototype[name] = function() {
|
||||
var args = slice.call(arguments);
|
||||
unshift.call(args, this._wrapped);
|
||||
return result(func.apply(_, args), this._chain);
|
||||
};
|
||||
};
|
||||
|
||||
// Add all of the Underscore functions to the wrapper object.
|
||||
_.mixin(_);
|
||||
|
||||
// Add all mutator Array functions to the wrapper.
|
||||
each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
|
||||
var method = ArrayProto[name];
|
||||
wrapper.prototype[name] = function() {
|
||||
method.apply(this._wrapped, arguments);
|
||||
return result(this._wrapped, this._chain);
|
||||
};
|
||||
});
|
||||
|
||||
// Add all accessor Array functions to the wrapper.
|
||||
each(['concat', 'join', 'slice'], function(name) {
|
||||
var method = ArrayProto[name];
|
||||
wrapper.prototype[name] = function() {
|
||||
return result(method.apply(this._wrapped, arguments), this._chain);
|
||||
};
|
||||
});
|
||||
|
||||
// Start chaining a wrapped Underscore object.
|
||||
wrapper.prototype.chain = function() {
|
||||
this._chain = true;
|
||||
return this;
|
||||
};
|
||||
|
||||
// Extracts the result from a wrapped and chained object.
|
||||
wrapper.prototype.value = function() {
|
||||
return this._wrapped;
|
||||
};
|
||||
|
||||
}).call(this);
|
58
node_modules/esprima/test/benchmarks.html
generated
vendored
58
node_modules/esprima/test/benchmarks.html
generated
vendored
@@ -1,58 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Esprima: Benchmarks</title>
|
||||
<link rel="stylesheet" type="text/css" href="../assets/style.css"/>
|
||||
<script src="../esprima.js"></script>
|
||||
<script src="../assets/json2.js"></script>
|
||||
<script src="benchmarks.js"></script>
|
||||
<script src="3rdparty/benchmark.js"></script>
|
||||
<script src="3rdparty/XMLHttpRequest.js"></script>
|
||||
<script>
|
||||
/*jslint browser:true, sloppy:true */
|
||||
/*global setupBenchmarks:true*/
|
||||
window.onload = function () {
|
||||
window.setTimeout(setupBenchmarks, 211);
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<div class="topbar">
|
||||
<ul class="nav">
|
||||
<li><a href="../index.html">← Home</a></li>
|
||||
<li><a href="http://github.com/ariya/esprima">Code</a></li>
|
||||
<li><a href="http://wiki.esprima.org">Documentation</a></li>
|
||||
<li><a href="http://issues.esprima.org">Issues</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h1>Benchmarks <small>show the speed</small></h1>
|
||||
|
||||
<p>Time measurement is carried out using <a href="http://benchmarkjs.com" target="_blank">Benchmark.js</a><span id="benchmarkjs-version"></span>.</p>
|
||||
|
||||
<p>Esprima version <span id="version"></span>.</p>
|
||||
|
||||
<p id="status">Please wait...</p>
|
||||
|
||||
<p>
|
||||
<input id="runquick" type="submit" value="Run quick benchmarks" disabled xstyle="visibility: hidden;"/>
|
||||
<input id="runfull" type="submit" value="Run full benchmarks" disabled xstyle="visibility: hidden;"/>
|
||||
</p>
|
||||
|
||||
<p id="result"></p>
|
||||
|
||||
<p><strong>Note</strong>: On a modern machine and up-to-date web browsers,
|
||||
running full benchmarks suite takes around 1 minute.<br>
|
||||
For the quick benchmarks, the running time is only about 15 seconds.</p>
|
||||
|
||||
<div class="footer"><strong>Esprima</strong> is created by
|
||||
<a href="http://ariya.ofilabs.com/about" target="_blank">Ariya Hidayat</a>. Follow <a href="http://twitter.com/ariyahidayat">@ariyahidayat</a> on Twitter.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
328
node_modules/esprima/test/benchmarks.js
generated
vendored
328
node_modules/esprima/test/benchmarks.js
generated
vendored
@@ -1,328 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>
|
||||
Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
/*jslint browser: true node: true */
|
||||
/*global load:true, print:true */
|
||||
var setupBenchmarks,
|
||||
fixture;
|
||||
|
||||
fixture = [
|
||||
'jQuery 1.7.1',
|
||||
'jQuery 1.6.4',
|
||||
'jQuery.Mobile 1.0',
|
||||
'Prototype 1.7.0.0',
|
||||
'Prototype 1.6.1',
|
||||
'Ext Core 3.1.0',
|
||||
'Ext Core 3.0.0',
|
||||
'MooTools 1.4.1',
|
||||
'MooTools 1.3.2',
|
||||
'Backbone 0.5.3',
|
||||
'Underscore 1.2.3'
|
||||
];
|
||||
|
||||
function slug(name) {
|
||||
'use strict';
|
||||
return name.toLowerCase().replace(/\s/g, '-');
|
||||
}
|
||||
|
||||
function kb(bytes) {
|
||||
'use strict';
|
||||
return (bytes / 1024).toFixed(1);
|
||||
}
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
// Run all tests in a browser environment.
|
||||
setupBenchmarks = function () {
|
||||
'use strict';
|
||||
|
||||
function id(i) {
|
||||
return document.getElementById(i);
|
||||
}
|
||||
|
||||
function setText(id, str) {
|
||||
var el = document.getElementById(id);
|
||||
if (typeof el.innerText === 'string') {
|
||||
el.innerText = str;
|
||||
} else {
|
||||
el.textContent = str;
|
||||
}
|
||||
}
|
||||
|
||||
function enableRunButtons() {
|
||||
id('runquick').disabled = false;
|
||||
id('runfull').disabled = false;
|
||||
}
|
||||
|
||||
function disableRunButtons() {
|
||||
id('runquick').disabled = true;
|
||||
id('runfull').disabled = true;
|
||||
}
|
||||
|
||||
function createTable() {
|
||||
var str = '',
|
||||
index,
|
||||
test,
|
||||
name;
|
||||
|
||||
str += '<table>';
|
||||
str += '<thead><tr><th>Source</th><th>Size (KiB)</th>';
|
||||
str += '<th>Time (ms)</th><th>Variance</th></tr></thead>';
|
||||
str += '<tbody>';
|
||||
for (index = 0; index < fixture.length; index += 1) {
|
||||
test = fixture[index];
|
||||
name = slug(test);
|
||||
str += '<tr>';
|
||||
str += '<td>' + test + '</td>';
|
||||
str += '<td id="' + name + '-size"></td>';
|
||||
str += '<td id="' + name + '-time"></td>';
|
||||
str += '<td id="' + name + '-variance"></td>';
|
||||
str += '</tr>';
|
||||
}
|
||||
str += '<tr><td><b>Total</b></td>';
|
||||
str += '<td id="total-size"></td>';
|
||||
str += '<td id="total-time"></td>';
|
||||
str += '<td></td></tr>';
|
||||
str += '</tbody>';
|
||||
str += '</table>';
|
||||
|
||||
id('result').innerHTML = str;
|
||||
}
|
||||
|
||||
function loadTests() {
|
||||
|
||||
var index = 0,
|
||||
totalSize = 0;
|
||||
|
||||
function load(test, callback) {
|
||||
var xhr = new XMLHttpRequest(),
|
||||
src = '3rdparty/' + test + '.js';
|
||||
|
||||
window.data = window.data || {};
|
||||
window.data[test] = '';
|
||||
|
||||
try {
|
||||
xhr.timeout = 30000;
|
||||
xhr.open('GET', src, true);
|
||||
|
||||
xhr.ontimeout = function () {
|
||||
setText('status', 'Error: time out while loading ' + test);
|
||||
callback.apply();
|
||||
};
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
var success = false,
|
||||
size = 0;
|
||||
|
||||
if (this.readyState === XMLHttpRequest.DONE) {
|
||||
if (this.status === 200) {
|
||||
window.data[test] = this.responseText;
|
||||
size = this.responseText.length;
|
||||
totalSize += size;
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (success) {
|
||||
setText(test + '-size', kb(size));
|
||||
} else {
|
||||
setText('status', 'Please wait. Error loading ' + src);
|
||||
setText(test + '-size', 'Error');
|
||||
}
|
||||
|
||||
callback.apply();
|
||||
};
|
||||
|
||||
xhr.send(null);
|
||||
} catch (e) {
|
||||
setText('status', 'Please wait. Error loading ' + src);
|
||||
callback.apply();
|
||||
}
|
||||
}
|
||||
|
||||
function loadNextTest() {
|
||||
var test;
|
||||
|
||||
if (index < fixture.length) {
|
||||
test = fixture[index];
|
||||
index += 1;
|
||||
setText('status', 'Please wait. Loading ' + test +
|
||||
' (' + index + ' of ' + fixture.length + ')');
|
||||
window.setTimeout(function () {
|
||||
load(slug(test), loadNextTest);
|
||||
}, 100);
|
||||
} else {
|
||||
setText('total-size', kb(totalSize));
|
||||
setText('status', 'Ready.');
|
||||
enableRunButtons();
|
||||
}
|
||||
}
|
||||
|
||||
loadNextTest();
|
||||
}
|
||||
|
||||
function runBenchmarks(suite) {
|
||||
|
||||
var index = 0,
|
||||
totalTime = 0;
|
||||
|
||||
function reset() {
|
||||
var i, name;
|
||||
for (i = 0; i < fixture.length; i += 1) {
|
||||
name = slug(fixture[i]);
|
||||
setText(name + '-time', '');
|
||||
setText(name + '-variance', '');
|
||||
}
|
||||
setText('total-time', '');
|
||||
}
|
||||
|
||||
function run() {
|
||||
var el, test, source, benchmark;
|
||||
|
||||
if (index >= suite.length) {
|
||||
setText('total-time', (1000 * totalTime).toFixed(1));
|
||||
setText('status', 'Ready.');
|
||||
enableRunButtons();
|
||||
return;
|
||||
}
|
||||
|
||||
test = slug(suite[index]);
|
||||
el = id(test);
|
||||
source = window.data[test];
|
||||
setText(test + '-time', 'Running...');
|
||||
|
||||
// Force the result to be held in this array, thus defeating any
|
||||
// possible "dead core elimination" optimization.
|
||||
window.tree = [];
|
||||
|
||||
benchmark = new window.Benchmark(test, function (o) {
|
||||
var syntax = window.esprima.parse(source);
|
||||
window.tree.push(syntax.body.length);
|
||||
}, {
|
||||
'onComplete': function () {
|
||||
setText(this.name + '-time', (1000 * this.stats.mean).toFixed(1));
|
||||
setText(this.name + '-variance', (1000 * this.stats.variance).toFixed(1));
|
||||
totalTime += this.stats.mean;
|
||||
}
|
||||
});
|
||||
|
||||
window.setTimeout(function () {
|
||||
benchmark.run();
|
||||
index += 1;
|
||||
window.setTimeout(run, 211);
|
||||
}, 211);
|
||||
}
|
||||
|
||||
|
||||
disableRunButtons();
|
||||
setText('status', 'Please wait. Running benchmarks...');
|
||||
|
||||
reset();
|
||||
run();
|
||||
}
|
||||
|
||||
id('runquick').onclick = function () {
|
||||
runBenchmarks(['jQuery 1.7.1', 'jQuery.Mobile 1.0', 'Backbone 0.5.3']);
|
||||
};
|
||||
|
||||
id('runfull').onclick = function () {
|
||||
runBenchmarks(fixture);
|
||||
};
|
||||
|
||||
setText('benchmarkjs-version', ' version ' + window.Benchmark.version);
|
||||
setText('version', window.esprima.version);
|
||||
|
||||
createTable();
|
||||
disableRunButtons();
|
||||
loadTests();
|
||||
};
|
||||
} else {
|
||||
|
||||
(function (global) {
|
||||
'use strict';
|
||||
var Benchmark,
|
||||
esprima,
|
||||
dirname,
|
||||
option,
|
||||
fs,
|
||||
readFileSync,
|
||||
log;
|
||||
|
||||
if (typeof require === 'undefined') {
|
||||
dirname = 'test';
|
||||
load(dirname + '/3rdparty/benchmark.js');
|
||||
load(dirname + '/../esprima.js');
|
||||
Benchmark = global.Benchmark;
|
||||
esprima = global.esprima;
|
||||
readFileSync = global.read;
|
||||
log = print;
|
||||
} else {
|
||||
Benchmark = require('./3rdparty/benchmark');
|
||||
esprima = require('../esprima');
|
||||
fs = require('fs');
|
||||
option = process.argv[2];
|
||||
readFileSync = function readFileSync(filename) {
|
||||
return fs.readFileSync(filename, 'utf-8');
|
||||
};
|
||||
dirname = __dirname;
|
||||
log = console.log.bind(console);
|
||||
}
|
||||
|
||||
function runTests(tests) {
|
||||
var index,
|
||||
tree = [],
|
||||
totalTime = 0,
|
||||
totalSize = 0;
|
||||
|
||||
tests.reduce(function (suite, filename) {
|
||||
var source = readFileSync(dirname + '/3rdparty/' + slug(filename) + '.js'),
|
||||
size = source.length;
|
||||
totalSize += size;
|
||||
return suite.add(filename, function () {
|
||||
var syntax = esprima.parse(source);
|
||||
tree.push(syntax.body.length);
|
||||
}, {
|
||||
'onComplete': function (event, bench) {
|
||||
log(this.name +
|
||||
' size ' + kb(size) +
|
||||
' time ' + (1000 * this.stats.mean).toFixed(1) +
|
||||
' variance ' + (1000 * this.stats.variance).toFixed(1));
|
||||
totalTime += this.stats.mean;
|
||||
}
|
||||
});
|
||||
}, new Benchmark.Suite()).on('complete', function () {
|
||||
log('Total size ' + kb(totalSize) +
|
||||
' time ' + (1000 * totalTime).toFixed(1));
|
||||
}).run();
|
||||
}
|
||||
|
||||
if (option === 'quick') {
|
||||
runTests(['jQuery 1.7.1', 'jQuery.Mobile 1.0', 'Backbone 0.5.3']);
|
||||
} else {
|
||||
runTests(fixture);
|
||||
}
|
||||
}(this));
|
||||
}
|
||||
/* vim: set sw=4 ts=4 et tw=80 : */
|
140
node_modules/esprima/test/compare.html
generated
vendored
140
node_modules/esprima/test/compare.html
generated
vendored
@@ -1,140 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Esprima: Speed Comparison</title>
|
||||
<link rel="stylesheet" type="text/css" href="../assets/style.css"/>
|
||||
<script src="../esprima.js"></script>
|
||||
<script src="../assets/json2.js"></script>
|
||||
<script src="compare.js"></script>
|
||||
<script src="3rdparty/benchmark.js"></script>
|
||||
<script src="3rdparty/XMLHttpRequest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<div class="topbar">
|
||||
<ul class="nav">
|
||||
<li><a href="../index.html">← Home</a></li>
|
||||
<li><a href="http://github.com/ariya/esprima">Code</a></li>
|
||||
<li><a href="http://wiki.esprima.org">Documentation</a></li>
|
||||
<li><a href="http://issues.esprima.org">Issues</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h1>Compare <small>with other parsers</small></h1>
|
||||
|
||||
<p>Time measurement is carried out using <a href="http://benchmarkjs.com" target="_blank">Benchmark.js</a><span id="benchmarkjs-version"></span>.</p>
|
||||
|
||||
<p>Esprima version <span id="version"></span>.</p>
|
||||
|
||||
<p><span id="status">Please wait...</span>
|
||||
<input id="run" type="submit" value="Run speed comparison" disabled /></p>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Source</th>
|
||||
<th>Size (KiB)</th>
|
||||
<th>Esprima</th>
|
||||
<th>parse-js</th>
|
||||
<th>ZeParser</th>
|
||||
<th>Narcissus</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>jQuery 1.7.1</td>
|
||||
<td id="jquery-1.7.1-size"></td>
|
||||
<td id="esprima-jquery-1.7.1"></td>
|
||||
<td id="parsejs-jquery-1.7.1"></td>
|
||||
<td id="zeparser-jquery-1.7.1"></td>
|
||||
<td id="narcissus-jquery-1.7.1"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Prototype 1.7.0.0</td>
|
||||
<td id="prototype-1.7.0.0-size"></td>
|
||||
<td id="esprima-prototype-1.7.0.0"></td>
|
||||
<td id="parsejs-prototype-1.7.0.0"></td>
|
||||
<td id="zeparser-prototype-1.7.0.0"></td>
|
||||
<td id="narcissus-prototype-1.7.0.0"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MooTools 1.4.1</td>
|
||||
<td id="mootools-1.4.1-size"></td>
|
||||
<td id="esprima-mootools-1.4.1"></td>
|
||||
<td id="parsejs-mootools-1.4.1"></td>
|
||||
<td id="zeparser-mootools-1.4.1"></td>
|
||||
<td id="narcissus-mootools-1.4.1"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Ext Core 3.1.0</td>
|
||||
<td id="ext-core-3.1.0-size"></td>
|
||||
<td id="esprima-ext-core-3.1.0"></td>
|
||||
<td id="parsejs-ext-core-3.1.0"></td>
|
||||
<td id="zeparser-ext-core-3.1.0"></td>
|
||||
<td id="narcissus-ext-core-3.1.0"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Total</td>
|
||||
<td id="total-size"></td>
|
||||
<td id="esprima-time"></td>
|
||||
<td id="parsejs-time"></td>
|
||||
<td id="zeparser-time"></td>
|
||||
<td id="narcissus-time"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p><strong>Warning:</strong> Since each parser has a different format for the syntax tree, the speed is not fully comparable (the cost of constructing different result is not taken into account). These tests exist only to ensure that Esprima parser is not ridiculously slow compare to other parsers.</p>
|
||||
|
||||
<p><strong>parse-js</strong> is the parser used in <a href="https://github.com/mishoo/UglifyJS">UglifyJS</a>. It's a JavaScript port of the Common LISP version. This test uses <code>parse-js</code> from UglifyJS version 1.2.5 (Jan 13 2011).</p>
|
||||
|
||||
<p><strong>ZeParser</strong> is from <a href="https://github.com/qfox/ZeParser">github.com/qfox/ZeParser</a> revision 51e52908 (dated Dec 24 2011). Beside the syntax tree, ZeParser also provides location info for the syntax nodes, as well as the list of all tokens.</p>
|
||||
|
||||
<p><strong>Narcissus</strong> is Mozilla's JavaScript engine implemented in JavaScript. This test uses the parser from Narcissus, taken from its
|
||||
<a href="https://github.com/mozilla/narcissus">code repository</a> revision b5caa7df (dated Oct 26 2011). Narcissus supports many extensions (generators, comprehension, destructuring, etc) and therefore it takes longer to parse JavaScript code. Narcissus parser output also contains the location info for the syntax node. <strong>Note</strong>: Narcissus will not work if <code>Object.create</code> and <code>Object.defineProperty</code> are not available.</p>
|
||||
|
||||
<div class="footer"><strong>Esprima</strong> is created by
|
||||
<a href="http://ariya.ofilabs.com/about" target="_blank">Ariya Hidayat</a>. Follow <a href="http://twitter.com/ariyahidayat">@ariyahidayat</a> on Twitter.
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
/*jslint sloppy:true, browser:true */
|
||||
/*global runBenchmarks: true, exports: true */
|
||||
window.onload = function () {
|
||||
|
||||
function inject(fname) {
|
||||
var head = document.getElementsByTagName('head')[0],
|
||||
script = document.createElement('script');
|
||||
|
||||
script.src = fname;
|
||||
script.type = 'text/javascript';
|
||||
head.appendChild(script);
|
||||
}
|
||||
|
||||
// Mozilla Narcissus
|
||||
if (typeof Object.create === 'function' && typeof Object.defineProperty === 'function') {
|
||||
inject('3rdparty/jsdefs.js');
|
||||
inject('3rdparty/jslex.js');
|
||||
inject('3rdparty/jsparse.js');
|
||||
}
|
||||
|
||||
window.setTimeout(runBenchmarks, 211);
|
||||
};
|
||||
</script>
|
||||
|
||||
<!-- ZeParser (https://github.com/qfox/ZeParser) -->
|
||||
<script src="3rdparty/Tokenizer.js"></script>
|
||||
<script src="3rdparty/ZeParser.js"></script>
|
||||
|
||||
<!-- parse-js, part of UglifyJS -->
|
||||
<script>
|
||||
exports = window.parseJS = {};
|
||||
</script>
|
||||
<script src="3rdparty/parse-js.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
270
node_modules/esprima/test/compare.js
generated
vendored
270
node_modules/esprima/test/compare.js
generated
vendored
@@ -1,270 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*jslint browser: true */
|
||||
|
||||
function runBenchmarks() {
|
||||
'use strict';
|
||||
|
||||
var index = 0,
|
||||
totalSize = 0,
|
||||
totalTime = {},
|
||||
fixture;
|
||||
|
||||
fixture = [
|
||||
'esprima jquery-1.7.1',
|
||||
'parsejs jquery-1.7.1',
|
||||
'zeparser jquery-1.7.1',
|
||||
'narcissus jquery-1.7.1',
|
||||
|
||||
'esprima prototype-1.7.0.0',
|
||||
'parsejs prototype-1.7.0.0',
|
||||
'zeparser prototype-1.7.0.0',
|
||||
'narcissus prototype-1.7.0.0',
|
||||
|
||||
'esprima mootools-1.4.1',
|
||||
'parsejs mootools-1.4.1',
|
||||
'zeparser mootools-1.4.1',
|
||||
'narcissus mootools-1.4.1',
|
||||
|
||||
'esprima ext-core-3.1.0',
|
||||
'parsejs ext-core-3.1.0',
|
||||
'zeparser ext-core-3.1.0',
|
||||
'narcissus ext-core-3.1.0'
|
||||
];
|
||||
|
||||
function id(i) {
|
||||
return document.getElementById(i);
|
||||
}
|
||||
|
||||
function kb(bytes) {
|
||||
return (bytes / 1024).toFixed(1);
|
||||
}
|
||||
|
||||
function setText(id, str) {
|
||||
var el = document.getElementById(id);
|
||||
if (typeof el.innerText === 'string') {
|
||||
el.innerText = str;
|
||||
} else {
|
||||
el.textContent = str;
|
||||
}
|
||||
}
|
||||
|
||||
function ready() {
|
||||
setText('status', 'Ready.');
|
||||
id('run').disabled = false;
|
||||
id('run').style.visibility = 'visible';
|
||||
}
|
||||
|
||||
function load(tst, callback) {
|
||||
var xhr = new XMLHttpRequest(),
|
||||
src = '3rdparty/' + tst + '.js';
|
||||
|
||||
// Already available? Don't reload from server.
|
||||
if (window.data && window.data.hasOwnProperty(tst)) {
|
||||
callback.apply();
|
||||
}
|
||||
|
||||
try {
|
||||
xhr.timeout = 30000;
|
||||
xhr.open('GET', src, true);
|
||||
setText('status', 'Please wait. Loading ' + src);
|
||||
|
||||
xhr.ontimeout = function () {
|
||||
setText('status', 'Please wait. Error: time out while loading ' + src + ' ');
|
||||
callback.apply();
|
||||
};
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
var success = false,
|
||||
size = 0;
|
||||
|
||||
if (this.readyState === XMLHttpRequest.DONE) {
|
||||
if (this.status === 200) {
|
||||
window.data = window.data || {};
|
||||
window.data[tst] = this.responseText;
|
||||
size = this.responseText.length;
|
||||
totalSize += size;
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (success) {
|
||||
setText(tst + '-size', kb(size));
|
||||
} else {
|
||||
setText('status', 'Please wait. Error loading ' + src);
|
||||
setText(tst + '-size', 'Error');
|
||||
}
|
||||
|
||||
callback.apply();
|
||||
};
|
||||
|
||||
xhr.send(null);
|
||||
} catch (e) {
|
||||
setText('status', 'Please wait. Error loading ' + src);
|
||||
callback.apply();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function loadTests() {
|
||||
var sources = fixture.slice();
|
||||
|
||||
function loadNextTest() {
|
||||
var tst;
|
||||
|
||||
if (sources.length > 0) {
|
||||
tst = sources[0].split(' ');
|
||||
tst = tst[1];
|
||||
sources.splice(0, 1);
|
||||
window.setTimeout(function () {
|
||||
load(tst, loadNextTest);
|
||||
}, 100);
|
||||
} else {
|
||||
setText('total-size', kb(totalSize));
|
||||
ready();
|
||||
}
|
||||
}
|
||||
|
||||
id('run').style.visibility = 'hidden';
|
||||
loadNextTest();
|
||||
}
|
||||
|
||||
function runBenchmark() {
|
||||
var test, source, parser, fn, benchmark;
|
||||
|
||||
function formatTime(t) {
|
||||
return (t === 0) ? 'N/A' : (1000 * t).toFixed(1) + ' ms';
|
||||
}
|
||||
|
||||
if (index >= fixture.length) {
|
||||
setText('total-size', kb(totalSize));
|
||||
setText('esprima-time', formatTime(totalTime.esprima));
|
||||
setText('parsejs-time', formatTime(totalTime.parsejs));
|
||||
setText('zeparser-time', formatTime(totalTime.zeparser));
|
||||
setText('narcissus-time', formatTime(totalTime.narcissus));
|
||||
ready();
|
||||
return;
|
||||
}
|
||||
|
||||
test = fixture[index].split(' ');
|
||||
parser = test[0];
|
||||
test = test[1];
|
||||
|
||||
source = window.data[test];
|
||||
setText(parser + '-' + test, 'Running...');
|
||||
|
||||
// Force the result to be held in this array, thus defeating any
|
||||
// possible "dead core elimination" optimization.
|
||||
window.tree = [];
|
||||
|
||||
switch (parser) {
|
||||
case 'esprima':
|
||||
fn = function () {
|
||||
var syntax = window.esprima.parse(source);
|
||||
window.tree.push(syntax.body.length);
|
||||
};
|
||||
break;
|
||||
case 'narcissus':
|
||||
fn = function () {
|
||||
var syntax = window.Narcissus.parser.parse(source);
|
||||
window.tree.push(syntax.children.length);
|
||||
};
|
||||
break;
|
||||
case 'parsejs':
|
||||
fn = function () {
|
||||
var syntax = window.parseJS.parse(source);
|
||||
window.tree.push(syntax.length);
|
||||
};
|
||||
break;
|
||||
case 'zeparser':
|
||||
fn = function () {
|
||||
var syntax = window.ZeParser.parse(source, false);
|
||||
window.tree.push(syntax.length);
|
||||
};
|
||||
break;
|
||||
default:
|
||||
throw 'Unknown parser type ' + parser;
|
||||
}
|
||||
|
||||
benchmark = new window.Benchmark(test, fn, {
|
||||
'onComplete': function () {
|
||||
setText(parser + '-' + this.name, formatTime(this.stats.mean));
|
||||
totalSize += source.length;
|
||||
totalTime[parser] += this.stats.mean;
|
||||
}
|
||||
});
|
||||
|
||||
window.setTimeout(function () {
|
||||
benchmark.run();
|
||||
index += 1;
|
||||
window.setTimeout(runBenchmark, 211);
|
||||
}, 211);
|
||||
}
|
||||
|
||||
id('run').onclick = function () {
|
||||
|
||||
var test;
|
||||
|
||||
for (index = 0; index < fixture.length; index += 1) {
|
||||
test = fixture[index].split(' ').join('-');
|
||||
setText(test, '');
|
||||
}
|
||||
|
||||
setText('status', 'Please wait. Running benchmarks...');
|
||||
id('run').style.visibility = 'hidden';
|
||||
|
||||
index = 0;
|
||||
totalTime = {
|
||||
'esprima': 0,
|
||||
'narcissus': 0,
|
||||
'parsejs': 0,
|
||||
'zeparser': 0
|
||||
};
|
||||
|
||||
for (test in totalTime) {
|
||||
if (totalTime.hasOwnProperty(test)) {
|
||||
setText(test + '-time', '');
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof window.Narcissus !== 'object') {
|
||||
window.Narcissus = {
|
||||
parser: {
|
||||
parse: function (code) {
|
||||
throw new Error('Narcissus is not available!');
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
runBenchmark();
|
||||
};
|
||||
|
||||
setText('benchmarkjs-version', ' version ' + window.Benchmark.version);
|
||||
setText('version', window.esprima.version);
|
||||
|
||||
loadTests();
|
||||
}
|
||||
/* vim: set sw=4 ts=4 et tw=80 : */
|
40
node_modules/esprima/test/compat.html
generated
vendored
40
node_modules/esprima/test/compat.html
generated
vendored
@@ -1,40 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Esprima: Compatibility Tests</title>
|
||||
<link rel="stylesheet" type="text/css" href="../assets/style.css"/>
|
||||
<script src="../esprima.js"></script>
|
||||
<script src="../assets/json2.js"></script>
|
||||
<script id="reflect" src="reflect.js"></script>
|
||||
<script src="compat.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
||||
<div class="topbar">
|
||||
<ul class="nav">
|
||||
<li><a href="../index.html">← Home</a></li>
|
||||
<li><a href="http://github.com/ariya/esprima">Code</a></li>
|
||||
<li><a href="http://wiki.esprima.org">Documentation</a></li>
|
||||
<li><a href="http://issues.esprima.org">Issues</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h1>Compatibility <small>keeps everyone happy</small></h1>
|
||||
<p>Esprima version <span id="version"></span>.</p>
|
||||
<p>The following tests are to ensure that the syntax tree is compatible to
|
||||
that produced by Mozilla SpiderMonkey
|
||||
<a href="https://developer.mozilla.org/en/SpiderMonkey/Parser_API">Parser reflection</a>.</p>
|
||||
<p id="status">Please wait...</p>
|
||||
<div id="report"></div>
|
||||
<div class="footer"><strong>Esprima</strong> is created by
|
||||
<a href="http://ariya.ofilabs.com/about" target="_blank">Ariya Hidayat</a>. Follow <a href="http://twitter.com/ariyahidayat">@ariyahidayat</a> on Twitter.
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
/*jslint browser:true*/
|
||||
window.onload = window.runTests;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
239
node_modules/esprima/test/compat.js
generated
vendored
239
node_modules/esprima/test/compat.js
generated
vendored
@@ -1,239 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2012 Joost-Wim Boekesteijn <joost-wim@boekesteijn.nl>
|
||||
Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*jslint node: true */
|
||||
/*global document: true, window:true, esprima: true, testReflect: true */
|
||||
|
||||
var runTests;
|
||||
|
||||
function getContext(esprima, reportCase, reportFailure) {
|
||||
'use strict';
|
||||
|
||||
var Reflect, Pattern;
|
||||
|
||||
// Maps Mozilla Reflect object to our Esprima parser.
|
||||
Reflect = {
|
||||
parse: function (code) {
|
||||
var result;
|
||||
|
||||
reportCase(code);
|
||||
|
||||
try {
|
||||
result = esprima.parse(code);
|
||||
} catch (error) {
|
||||
result = error;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
// This is used by Reflect test suite to match a syntax tree.
|
||||
Pattern = function (obj) {
|
||||
var pattern;
|
||||
|
||||
// Poor man's deep object cloning.
|
||||
pattern = JSON.parse(JSON.stringify(obj));
|
||||
|
||||
// Special handling for regular expression literal since we need to
|
||||
// convert it to a string literal, otherwise it will be decoded
|
||||
// as object "{}" and the regular expression would be lost.
|
||||
if (obj.type && obj.type === 'Literal') {
|
||||
if (obj.value instanceof RegExp) {
|
||||
pattern = {
|
||||
type: obj.type,
|
||||
value: obj.value.toString()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Special handling for branch statement because SpiderMonkey
|
||||
// prefers to put the 'alternate' property before 'consequent'.
|
||||
if (obj.type && obj.type === 'IfStatement') {
|
||||
pattern = {
|
||||
type: pattern.type,
|
||||
test: pattern.test,
|
||||
consequent: pattern.consequent,
|
||||
alternate: pattern.alternate
|
||||
};
|
||||
}
|
||||
|
||||
// Special handling for do while statement because SpiderMonkey
|
||||
// prefers to put the 'test' property before 'body'.
|
||||
if (obj.type && obj.type === 'DoWhileStatement') {
|
||||
pattern = {
|
||||
type: pattern.type,
|
||||
body: pattern.body,
|
||||
test: pattern.test
|
||||
};
|
||||
}
|
||||
|
||||
function adjustRegexLiteralAndRaw(key, value) {
|
||||
if (key === 'value' && value instanceof RegExp) {
|
||||
value = value.toString();
|
||||
} else if (key === 'raw' && typeof value === "string") {
|
||||
// Ignore Esprima-specific 'raw' property.
|
||||
return undefined;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
if (obj.type && (obj.type === 'Program')) {
|
||||
pattern.assert = function (tree) {
|
||||
var actual, expected;
|
||||
actual = JSON.stringify(tree, adjustRegexLiteralAndRaw, 4);
|
||||
expected = JSON.stringify(obj, null, 4);
|
||||
|
||||
if (expected !== actual) {
|
||||
reportFailure(expected, actual);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return pattern;
|
||||
};
|
||||
|
||||
return {
|
||||
Reflect: Reflect,
|
||||
Pattern: Pattern
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
// Run all tests in a browser environment.
|
||||
runTests = function () {
|
||||
'use strict';
|
||||
|
||||
var total = 0,
|
||||
failures = 0;
|
||||
|
||||
function setText(el, str) {
|
||||
if (typeof el.innerText === 'string') {
|
||||
el.innerText = str;
|
||||
} else {
|
||||
el.textContent = str;
|
||||
}
|
||||
}
|
||||
|
||||
function reportCase(code) {
|
||||
var report, e;
|
||||
report = document.getElementById('report');
|
||||
e = document.createElement('pre');
|
||||
e.setAttribute('class', 'code');
|
||||
setText(e, code);
|
||||
report.appendChild(e);
|
||||
total += 1;
|
||||
}
|
||||
|
||||
function reportFailure(expected, actual) {
|
||||
var report, e;
|
||||
|
||||
failures += 1;
|
||||
|
||||
report = document.getElementById('report');
|
||||
|
||||
e = document.createElement('p');
|
||||
setText(e, 'Expected');
|
||||
report.appendChild(e);
|
||||
|
||||
e = document.createElement('pre');
|
||||
e.setAttribute('class', 'expected');
|
||||
setText(e, expected);
|
||||
report.appendChild(e);
|
||||
|
||||
e = document.createElement('p');
|
||||
setText(e, 'Actual');
|
||||
report.appendChild(e);
|
||||
|
||||
e = document.createElement('pre');
|
||||
e.setAttribute('class', 'actual');
|
||||
setText(e, actual);
|
||||
report.appendChild(e);
|
||||
}
|
||||
|
||||
setText(document.getElementById('version'), esprima.version);
|
||||
|
||||
window.setTimeout(function () {
|
||||
var tick, context = getContext(esprima, reportCase, reportFailure);
|
||||
|
||||
tick = new Date();
|
||||
testReflect(context.Reflect, context.Pattern);
|
||||
tick = (new Date()) - tick;
|
||||
|
||||
if (failures > 0) {
|
||||
setText(document.getElementById('status'), total + ' tests. ' +
|
||||
'Failures: ' + failures + '. ' + tick + ' ms');
|
||||
} else {
|
||||
setText(document.getElementById('status'), total + ' tests. ' +
|
||||
'No failure. ' + tick + ' ms');
|
||||
}
|
||||
}, 513);
|
||||
};
|
||||
} else {
|
||||
(function (global) {
|
||||
'use strict';
|
||||
var esprima = require('../esprima'),
|
||||
tick,
|
||||
total = 0,
|
||||
failures = [],
|
||||
header,
|
||||
current,
|
||||
context;
|
||||
|
||||
function reportCase(code) {
|
||||
total += 1;
|
||||
current = code;
|
||||
}
|
||||
|
||||
function reportFailure(expected, actual) {
|
||||
failures.push({
|
||||
source: current,
|
||||
expected: expected.toString(),
|
||||
actual: actual.toString()
|
||||
});
|
||||
}
|
||||
|
||||
context = getContext(esprima, reportCase, reportFailure);
|
||||
|
||||
tick = new Date();
|
||||
require('./reflect').testReflect(context.Reflect, context.Pattern);
|
||||
tick = (new Date()) - tick;
|
||||
|
||||
header = total + ' tests. ' + failures.length + ' failures. ' +
|
||||
tick + ' ms';
|
||||
if (failures.length) {
|
||||
console.error(header);
|
||||
failures.forEach(function (failure) {
|
||||
console.error(failure.source + ': Expected\n ' +
|
||||
failure.expected.split('\n').join('\n ') +
|
||||
'\nto match\n ' + failure.actual);
|
||||
});
|
||||
} else {
|
||||
console.log(header);
|
||||
}
|
||||
process.exit(failures.length === 0 ? 0 : 1);
|
||||
}(this));
|
||||
}
|
||||
/* vim: set sw=4 ts=4 et tw=80 : */
|
3
node_modules/esprima/test/coverage.footer.html
generated
vendored
3
node_modules/esprima/test/coverage.footer.html
generated
vendored
@@ -1,3 +0,0 @@
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
37
node_modules/esprima/test/coverage.header.html
generated
vendored
37
node_modules/esprima/test/coverage.header.html
generated
vendored
@@ -1,37 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Esprima: Coverage Analysis Report</title>
|
||||
<link rel="stylesheet" type="text/css" href="../assets/style.css"/>
|
||||
</head>
|
||||
<style>
|
||||
span.covered {
|
||||
}
|
||||
|
||||
span.uncovered {
|
||||
background: #FDD;
|
||||
}
|
||||
|
||||
span.partial {
|
||||
background: #FFA;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
||||
<div class="topbar">
|
||||
<ul class="nav">
|
||||
<li><a href="../index.html">← Home</a></li>
|
||||
<li><a href="http://github.com/ariya/esprima">Code</a></li>
|
||||
<li><a href="http://wiki.esprima.org">Documentation</a></li>
|
||||
<li><a href="http://issues.esprima.org">Issues</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h1>Coverage Analysis <small>ensures systematic exercise of the parser</small></h1>
|
||||
|
||||
<p><strong>Note</strong>: This is not a live (in-browser) code coverage report.
|
||||
The analysis is <a href="http://code.google.com/p/esprima/wiki/Testing#Code_coverage_test">performed</a> offline
|
||||
(using <a href="https://github.com/itay/node-cover">node-cover</a>).<br>
|
||||
|
3617
node_modules/esprima/test/coverage.html
generated
vendored
3617
node_modules/esprima/test/coverage.html
generated
vendored
File diff suppressed because one or more lines are too long
36
node_modules/esprima/test/index.html
generated
vendored
36
node_modules/esprima/test/index.html
generated
vendored
@@ -1,36 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Esprima: Unit Tests</title>
|
||||
<link rel="stylesheet" type="text/css" href="../assets/style.css"/>
|
||||
<script src="../esprima.js"></script>
|
||||
<script src="../assets/json2.js"></script>
|
||||
<script src="test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
||||
<div class="topbar">
|
||||
<ul class="nav">
|
||||
<li><a href="../index.html">← Home</a></li>
|
||||
<li><a href="http://github.com/ariya/esprima">Code</a></li>
|
||||
<li><a href="http://wiki.esprima.org">Documentation</a></li>
|
||||
<li><a href="http://issues.esprima.org">Issues</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h1>Unit Tests <small>ensures the correct implementation</small></h1>
|
||||
<p>Esprima version <span id="version"></span>.</p>
|
||||
<p id="status">Please wait...</p>
|
||||
<div id="report"></div>
|
||||
<div class="footer"><strong>Esprima</strong> is created by
|
||||
<a href="http://ariya.ofilabs.com/about" target="_blank">Ariya Hidayat</a>. Follow <a href="http://twitter.com/ariyahidayat">@ariyahidayat</a> on Twitter.
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
/*jslint browser: true */
|
||||
window.onload = window.runTests;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
403
node_modules/esprima/test/reflect.js
generated
vendored
403
node_modules/esprima/test/reflect.js
generated
vendored
@@ -1,403 +0,0 @@
|
||||
// This is modified from Mozilla Reflect.parse test suite (the file is located
|
||||
// at js/src/tests/js1_8_5/extensions/reflect-parse.js in the source tree).
|
||||
//
|
||||
// Some notable changes:
|
||||
// * Removed unsupported features (destructuring, let, comprehensions...).
|
||||
// * Removed tests for E4X (ECMAScript for XML).
|
||||
// * Removed everything related to builder.
|
||||
// * Enclosed every 'Pattern' construct with a scope.
|
||||
// * Tweaked some expected tree to remove generator field.
|
||||
// * Removed the test for bug 632030 and bug 632024.
|
||||
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
(function (exports) {
|
||||
|
||||
function testReflect(Reflect, Pattern) {
|
||||
|
||||
function program(elts) { return Pattern({ type: "Program", body: elts }) }
|
||||
function exprStmt(expr) { return Pattern({ type: "ExpressionStatement", expression: expr }) }
|
||||
function throwStmt(expr) { return Pattern({ type: "ThrowStatement", argument: expr }) }
|
||||
function returnStmt(expr) { return Pattern({ type: "ReturnStatement", argument: expr }) }
|
||||
function yieldExpr(expr) { return Pattern({ type: "YieldExpression", argument: expr }) }
|
||||
function lit(val) { return Pattern({ type: "Literal", value: val }) }
|
||||
var thisExpr = Pattern({ type: "ThisExpression" });
|
||||
function funDecl(id, params, body) { return Pattern({ type: "FunctionDeclaration",
|
||||
id: id,
|
||||
params: params,
|
||||
body: body
|
||||
}) }
|
||||
function genFunDecl(id, params, body) { return Pattern({ type: "FunctionDeclaration",
|
||||
id: id,
|
||||
params: params,
|
||||
body: body
|
||||
}) }
|
||||
function declarator(id, init) { return Pattern({ type: "VariableDeclarator", id: id, init: init }) }
|
||||
function varDecl(decls) { return Pattern({ type: "VariableDeclaration", declarations: decls, kind: "var" }) }
|
||||
function letDecl(decls) { return Pattern({ type: "VariableDeclaration", declarations: decls, kind: "let" }) }
|
||||
function constDecl(decls) { return Pattern({ type: "VariableDeclaration", declarations: decls, kind: "const" }) }
|
||||
function ident(name) { return Pattern({ type: "Identifier", name: name }) }
|
||||
function dotExpr(obj, id) { return Pattern({ type: "MemberExpression", computed: false, object: obj, property: id }) }
|
||||
function memExpr(obj, id) { return Pattern({ type: "MemberExpression", computed: true, object: obj, property: id }) }
|
||||
function forStmt(init, test, update, body) { return Pattern({ type: "ForStatement", init: init, test: test, update: update, body: body }) }
|
||||
function forInStmt(lhs, rhs, body) { return Pattern({ type: "ForInStatement", left: lhs, right: rhs, body: body, each: false }) }
|
||||
function forEachInStmt(lhs, rhs, body) { return Pattern({ type: "ForInStatement", left: lhs, right: rhs, body: body, each: true }) }
|
||||
function breakStmt(lab) { return Pattern({ type: "BreakStatement", label: lab }) }
|
||||
function continueStmt(lab) { return Pattern({ type: "ContinueStatement", label: lab }) }
|
||||
function blockStmt(body) { return Pattern({ type: "BlockStatement", body: body }) }
|
||||
var emptyStmt = Pattern({ type: "EmptyStatement" });
|
||||
function ifStmt(test, cons, alt) { return Pattern({ type: "IfStatement", test: test, alternate: alt, consequent: cons }) }
|
||||
function labStmt(lab, stmt) { return Pattern({ type: "LabeledStatement", label: lab, body: stmt }) }
|
||||
function withStmt(obj, stmt) { return Pattern({ type: "WithStatement", object: obj, body: stmt }) }
|
||||
function whileStmt(test, stmt) { return Pattern({ type: "WhileStatement", test: test, body: stmt }) }
|
||||
function doStmt(stmt, test) { return Pattern({ type: "DoWhileStatement", test: test, body: stmt }) }
|
||||
function switchStmt(disc, cases) { return Pattern({ type: "SwitchStatement", discriminant: disc, cases: cases }) }
|
||||
function caseClause(test, stmts) { return Pattern({ type: "SwitchCase", test: test, consequent: stmts }) }
|
||||
function defaultClause(stmts) { return Pattern({ type: "SwitchCase", test: null, consequent: stmts }) }
|
||||
function catchClause(id, guard, body) { return Pattern({ type: "CatchClause", param: id, guard: guard, body: body }) }
|
||||
function tryStmt(body, catches, fin) { return Pattern({ type: "TryStatement", block: body, handlers: catches, finalizer: fin }) }
|
||||
function letStmt(head, body) { return Pattern({ type: "LetStatement", head: head, body: body }) }
|
||||
function funExpr(id, args, body, gen) { return Pattern({ type: "FunctionExpression",
|
||||
id: id,
|
||||
params: args,
|
||||
body: body
|
||||
}) }
|
||||
function genFunExpr(id, args, body) { return Pattern({ type: "FunctionExpression",
|
||||
id: id,
|
||||
params: args,
|
||||
body: body
|
||||
}) }
|
||||
|
||||
function unExpr(op, arg) { return Pattern({ type: "UnaryExpression", operator: op, argument: arg }) }
|
||||
function binExpr(op, left, right) { return Pattern({ type: "BinaryExpression", operator: op, left: left, right: right }) }
|
||||
function aExpr(op, left, right) { return Pattern({ type: "AssignmentExpression", operator: op, left: left, right: right }) }
|
||||
function updExpr(op, arg, prefix) { return Pattern({ type: "UpdateExpression", operator: op, argument: arg, prefix: prefix }) }
|
||||
function logExpr(op, left, right) { return Pattern({ type: "LogicalExpression", operator: op, left: left, right: right }) }
|
||||
|
||||
function condExpr(test, cons, alt) { return Pattern({ type: "ConditionalExpression", test: test, consequent: cons, alternate: alt }) }
|
||||
function seqExpr(exprs) { return Pattern({ type: "SequenceExpression", expressions: exprs }) }
|
||||
function newExpr(callee, args) { return Pattern({ type: "NewExpression", callee: callee, arguments: args }) }
|
||||
function callExpr(callee, args) { return Pattern({ type: "CallExpression", callee: callee, arguments: args }) }
|
||||
function arrExpr(elts) { return Pattern({ type: "ArrayExpression", elements: elts }) }
|
||||
function objExpr(elts) { return Pattern({ type: "ObjectExpression", properties: elts }) }
|
||||
function objProp(key, value, kind) { return Pattern({ type: "Property", key: key, value: value, kind: kind }) }
|
||||
|
||||
function arrPatt(elts) { return Pattern({ type: "ArrayPattern", elements: elts }) }
|
||||
function objPatt(elts) { return Pattern({ type: "ObjectPattern", properties: elts }) }
|
||||
|
||||
function localSrc(src) { return "(function(){ " + src + " })" }
|
||||
function localPatt(patt) { return program([exprStmt(funExpr(null, [], blockStmt([patt])))]) }
|
||||
function blockSrc(src) { return "(function(){ { " + src + " } })" }
|
||||
function blockPatt(patt) { return program([exprStmt(funExpr(null, [], blockStmt([blockStmt([patt])])))]) }
|
||||
|
||||
function assertBlockStmt(src, patt) {
|
||||
blockPatt(patt).assert(Reflect.parse(blockSrc(src)));
|
||||
}
|
||||
|
||||
function assertBlockExpr(src, patt) {
|
||||
assertBlockStmt(src, exprStmt(patt));
|
||||
}
|
||||
|
||||
function assertBlockDecl(src, patt, builder) {
|
||||
blockPatt(patt).assert(Reflect.parse(blockSrc(src), {builder: builder}));
|
||||
}
|
||||
|
||||
function assertLocalStmt(src, patt) {
|
||||
localPatt(patt).assert(Reflect.parse(localSrc(src)));
|
||||
}
|
||||
|
||||
function assertLocalExpr(src, patt) {
|
||||
assertLocalStmt(src, exprStmt(patt));
|
||||
}
|
||||
|
||||
function assertLocalDecl(src, patt) {
|
||||
localPatt(patt).assert(Reflect.parse(localSrc(src)));
|
||||
}
|
||||
|
||||
function assertGlobalStmt(src, patt, builder) {
|
||||
program([patt]).assert(Reflect.parse(src, {builder: builder}));
|
||||
}
|
||||
|
||||
function assertGlobalExpr(src, patt, builder) {
|
||||
program([exprStmt(patt)]).assert(Reflect.parse(src, {builder: builder}));
|
||||
//assertStmt(src, exprStmt(patt));
|
||||
}
|
||||
|
||||
function assertGlobalDecl(src, patt) {
|
||||
program([patt]).assert(Reflect.parse(src));
|
||||
}
|
||||
|
||||
function assertProg(src, patt) {
|
||||
program(patt).assert(Reflect.parse(src));
|
||||
}
|
||||
|
||||
function assertStmt(src, patt) {
|
||||
assertLocalStmt(src, patt);
|
||||
assertGlobalStmt(src, patt);
|
||||
assertBlockStmt(src, patt);
|
||||
}
|
||||
|
||||
function assertExpr(src, patt) {
|
||||
assertLocalExpr(src, patt);
|
||||
assertGlobalExpr(src, patt);
|
||||
assertBlockExpr(src, patt);
|
||||
}
|
||||
|
||||
function assertDecl(src, patt) {
|
||||
assertLocalDecl(src, patt);
|
||||
assertGlobalDecl(src, patt);
|
||||
assertBlockDecl(src, patt);
|
||||
}
|
||||
|
||||
function assertError(src, errorType) {
|
||||
try {
|
||||
Reflect.parse(src);
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
throw new Error("expected " + errorType.name + " for " + uneval(src));
|
||||
}
|
||||
|
||||
|
||||
// general tests
|
||||
|
||||
// NB: These are useful but for now jit-test doesn't do I/O reliably.
|
||||
|
||||
//program(_).assert(Reflect.parse(snarf('data/flapjax.txt')));
|
||||
//program(_).assert(Reflect.parse(snarf('data/jquery-1.4.2.txt')));
|
||||
//program(_).assert(Reflect.parse(snarf('data/prototype.js')));
|
||||
//program(_).assert(Reflect.parse(snarf('data/dojo.js.uncompressed.js')));
|
||||
//program(_).assert(Reflect.parse(snarf('data/mootools-1.2.4-core-nc.js')));
|
||||
|
||||
|
||||
// declarations
|
||||
|
||||
assertDecl("var x = 1, y = 2, z = 3",
|
||||
varDecl([declarator(ident("x"), lit(1)),
|
||||
declarator(ident("y"), lit(2)),
|
||||
declarator(ident("z"), lit(3))]));
|
||||
assertDecl("var x, y, z",
|
||||
varDecl([declarator(ident("x"), null),
|
||||
declarator(ident("y"), null),
|
||||
declarator(ident("z"), null)]));
|
||||
assertDecl("function foo() { }",
|
||||
funDecl(ident("foo"), [], blockStmt([])));
|
||||
assertDecl("function foo() { return 42 }",
|
||||
funDecl(ident("foo"), [], blockStmt([returnStmt(lit(42))])));
|
||||
|
||||
|
||||
// Bug 591437: rebound args have their defs turned into uses
|
||||
assertDecl("function f(a) { function a() { } }",
|
||||
funDecl(ident("f"), [ident("a")], blockStmt([funDecl(ident("a"), [], blockStmt([]))])));
|
||||
assertDecl("function f(a,b,c) { function b() { } }",
|
||||
funDecl(ident("f"), [ident("a"),ident("b"),ident("c")], blockStmt([funDecl(ident("b"), [], blockStmt([]))])));
|
||||
|
||||
// expressions
|
||||
|
||||
assertExpr("true", lit(true));
|
||||
assertExpr("false", lit(false));
|
||||
assertExpr("42", lit(42));
|
||||
assertExpr("(/asdf/)", lit(/asdf/));
|
||||
assertExpr("this", thisExpr);
|
||||
assertExpr("foo", ident("foo"));
|
||||
assertExpr("foo.bar", dotExpr(ident("foo"), ident("bar")));
|
||||
assertExpr("foo[bar]", memExpr(ident("foo"), ident("bar")));
|
||||
assertExpr("(function(){})", funExpr(null, [], blockStmt([])));
|
||||
assertExpr("(function f() {})", funExpr(ident("f"), [], blockStmt([])));
|
||||
assertExpr("(function f(x,y,z) {})", funExpr(ident("f"), [ident("x"),ident("y"),ident("z")], blockStmt([])));
|
||||
assertExpr("(++x)", updExpr("++", ident("x"), true));
|
||||
assertExpr("(x++)", updExpr("++", ident("x"), false));
|
||||
assertExpr("(+x)", unExpr("+", ident("x")));
|
||||
assertExpr("(-x)", unExpr("-", ident("x")));
|
||||
assertExpr("(!x)", unExpr("!", ident("x")));
|
||||
assertExpr("(~x)", unExpr("~", ident("x")));
|
||||
assertExpr("(delete x)", unExpr("delete", ident("x")));
|
||||
assertExpr("(typeof x)", unExpr("typeof", ident("x")));
|
||||
assertExpr("(void x)", unExpr("void", ident("x")));
|
||||
assertExpr("(x == y)", binExpr("==", ident("x"), ident("y")));
|
||||
assertExpr("(x != y)", binExpr("!=", ident("x"), ident("y")));
|
||||
assertExpr("(x === y)", binExpr("===", ident("x"), ident("y")));
|
||||
assertExpr("(x !== y)", binExpr("!==", ident("x"), ident("y")));
|
||||
assertExpr("(x < y)", binExpr("<", ident("x"), ident("y")));
|
||||
assertExpr("(x <= y)", binExpr("<=", ident("x"), ident("y")));
|
||||
assertExpr("(x > y)", binExpr(">", ident("x"), ident("y")));
|
||||
assertExpr("(x >= y)", binExpr(">=", ident("x"), ident("y")));
|
||||
assertExpr("(x << y)", binExpr("<<", ident("x"), ident("y")));
|
||||
assertExpr("(x >> y)", binExpr(">>", ident("x"), ident("y")));
|
||||
assertExpr("(x >>> y)", binExpr(">>>", ident("x"), ident("y")));
|
||||
assertExpr("(x + y)", binExpr("+", ident("x"), ident("y")));
|
||||
assertExpr("(w + x + y + z)", binExpr("+", binExpr("+", binExpr("+", ident("w"), ident("x")), ident("y")), ident("z")));
|
||||
assertExpr("(x - y)", binExpr("-", ident("x"), ident("y")));
|
||||
assertExpr("(w - x - y - z)", binExpr("-", binExpr("-", binExpr("-", ident("w"), ident("x")), ident("y")), ident("z")));
|
||||
assertExpr("(x * y)", binExpr("*", ident("x"), ident("y")));
|
||||
assertExpr("(x / y)", binExpr("/", ident("x"), ident("y")));
|
||||
assertExpr("(x % y)", binExpr("%", ident("x"), ident("y")));
|
||||
assertExpr("(x | y)", binExpr("|", ident("x"), ident("y")));
|
||||
assertExpr("(x ^ y)", binExpr("^", ident("x"), ident("y")));
|
||||
assertExpr("(x & y)", binExpr("&", ident("x"), ident("y")));
|
||||
assertExpr("(x in y)", binExpr("in", ident("x"), ident("y")));
|
||||
assertExpr("(x instanceof y)", binExpr("instanceof", ident("x"), ident("y")));
|
||||
assertExpr("(x = y)", aExpr("=", ident("x"), ident("y")));
|
||||
assertExpr("(x += y)", aExpr("+=", ident("x"), ident("y")));
|
||||
assertExpr("(x -= y)", aExpr("-=", ident("x"), ident("y")));
|
||||
assertExpr("(x *= y)", aExpr("*=", ident("x"), ident("y")));
|
||||
assertExpr("(x /= y)", aExpr("/=", ident("x"), ident("y")));
|
||||
assertExpr("(x %= y)", aExpr("%=", ident("x"), ident("y")));
|
||||
assertExpr("(x <<= y)", aExpr("<<=", ident("x"), ident("y")));
|
||||
assertExpr("(x >>= y)", aExpr(">>=", ident("x"), ident("y")));
|
||||
assertExpr("(x >>>= y)", aExpr(">>>=", ident("x"), ident("y")));
|
||||
assertExpr("(x |= y)", aExpr("|=", ident("x"), ident("y")));
|
||||
assertExpr("(x ^= y)", aExpr("^=", ident("x"), ident("y")));
|
||||
assertExpr("(x &= y)", aExpr("&=", ident("x"), ident("y")));
|
||||
assertExpr("(x || y)", logExpr("||", ident("x"), ident("y")));
|
||||
assertExpr("(x && y)", logExpr("&&", ident("x"), ident("y")));
|
||||
assertExpr("(w || x || y || z)", logExpr("||", logExpr("||", logExpr("||", ident("w"), ident("x")), ident("y")), ident("z")))
|
||||
assertExpr("(x ? y : z)", condExpr(ident("x"), ident("y"), ident("z")));
|
||||
assertExpr("(x,y)", seqExpr([ident("x"),ident("y")]))
|
||||
assertExpr("(x,y,z)", seqExpr([ident("x"),ident("y"),ident("z")]))
|
||||
assertExpr("(a,b,c,d,e,f,g)", seqExpr([ident("a"),ident("b"),ident("c"),ident("d"),ident("e"),ident("f"),ident("g")]));
|
||||
assertExpr("(new Object)", newExpr(ident("Object"), []));
|
||||
assertExpr("(new Object())", newExpr(ident("Object"), []));
|
||||
assertExpr("(new Object(42))", newExpr(ident("Object"), [lit(42)]));
|
||||
assertExpr("(new Object(1,2,3))", newExpr(ident("Object"), [lit(1),lit(2),lit(3)]));
|
||||
assertExpr("(String())", callExpr(ident("String"), []));
|
||||
assertExpr("(String(42))", callExpr(ident("String"), [lit(42)]));
|
||||
assertExpr("(String(1,2,3))", callExpr(ident("String"), [lit(1),lit(2),lit(3)]));
|
||||
assertExpr("[]", arrExpr([]));
|
||||
assertExpr("[1]", arrExpr([lit(1)]));
|
||||
assertExpr("[1,2]", arrExpr([lit(1),lit(2)]));
|
||||
assertExpr("[1,2,3]", arrExpr([lit(1),lit(2),lit(3)]));
|
||||
assertExpr("[1,,2,3]", arrExpr([lit(1),,lit(2),lit(3)]));
|
||||
assertExpr("[1,,,2,3]", arrExpr([lit(1),,,lit(2),lit(3)]));
|
||||
assertExpr("[1,,,2,,3]", arrExpr([lit(1),,,lit(2),,lit(3)]));
|
||||
assertExpr("[1,,,2,,,3]", arrExpr([lit(1),,,lit(2),,,lit(3)]));
|
||||
assertExpr("[,1,2,3]", arrExpr([,lit(1),lit(2),lit(3)]));
|
||||
assertExpr("[,,1,2,3]", arrExpr([,,lit(1),lit(2),lit(3)]));
|
||||
assertExpr("[,,,1,2,3]", arrExpr([,,,lit(1),lit(2),lit(3)]));
|
||||
assertExpr("[,,,1,2,3,]", arrExpr([,,,lit(1),lit(2),lit(3)]));
|
||||
assertExpr("[,,,1,2,3,,]", arrExpr([,,,lit(1),lit(2),lit(3),undefined]));
|
||||
assertExpr("[,,,1,2,3,,,]", arrExpr([,,,lit(1),lit(2),lit(3),undefined,undefined]));
|
||||
assertExpr("[,,,,,]", arrExpr([undefined,undefined,undefined,undefined,undefined]));
|
||||
assertExpr("({})", objExpr([]));
|
||||
assertExpr("({x:1})", objExpr([objProp(ident("x"), lit(1), "init")]));
|
||||
assertExpr("({x:1, y:2})", objExpr([objProp(ident("x"), lit(1), "init"),
|
||||
objProp(ident("y"), lit(2), "init")]));
|
||||
assertExpr("({x:1, y:2, z:3})", objExpr([objProp(ident("x"), lit(1), "init"),
|
||||
objProp(ident("y"), lit(2), "init"),
|
||||
objProp(ident("z"), lit(3), "init") ]));
|
||||
assertExpr("({x:1, 'y':2, z:3})", objExpr([objProp(ident("x"), lit(1), "init"),
|
||||
objProp(lit("y"), lit(2), "init"),
|
||||
objProp(ident("z"), lit(3), "init") ]));
|
||||
assertExpr("({'x':1, 'y':2, z:3})", objExpr([objProp(lit("x"), lit(1), "init"),
|
||||
objProp(lit("y"), lit(2), "init"),
|
||||
objProp(ident("z"), lit(3), "init") ]));
|
||||
assertExpr("({'x':1, 'y':2, 3:3})", objExpr([objProp(lit("x"), lit(1), "init"),
|
||||
objProp(lit("y"), lit(2), "init"),
|
||||
objProp(lit(3), lit(3), "init") ]));
|
||||
|
||||
// Bug 571617: eliminate constant-folding
|
||||
assertExpr("2 + 3", binExpr("+", lit(2), lit(3)));
|
||||
|
||||
// Bug 632026: constant-folding
|
||||
assertExpr("typeof(0?0:a)", unExpr("typeof", condExpr(lit(0), lit(0), ident("a"))));
|
||||
|
||||
// Bug 632056: constant-folding
|
||||
program([exprStmt(ident("f")),
|
||||
ifStmt(lit(1),
|
||||
funDecl(ident("f"), [], blockStmt([])),
|
||||
null)]).assert(Reflect.parse("f; if (1) function f(){}"));
|
||||
|
||||
// statements
|
||||
|
||||
assertStmt("throw 42", throwStmt(lit(42)));
|
||||
assertStmt("for (;;) break", forStmt(null, null, null, breakStmt(null)));
|
||||
assertStmt("for (x; y; z) break", forStmt(ident("x"), ident("y"), ident("z"), breakStmt(null)));
|
||||
assertStmt("for (var x; y; z) break", forStmt(varDecl([declarator(ident("x"), null)]), ident("y"), ident("z"), breakStmt(null)));
|
||||
assertStmt("for (var x = 42; y; z) break", forStmt(varDecl([declarator(ident("x"), lit(42))]), ident("y"), ident("z"), breakStmt(null)));
|
||||
assertStmt("for (x; ; z) break", forStmt(ident("x"), null, ident("z"), breakStmt(null)));
|
||||
assertStmt("for (var x; ; z) break", forStmt(varDecl([declarator(ident("x"), null)]), null, ident("z"), breakStmt(null)));
|
||||
assertStmt("for (var x = 42; ; z) break", forStmt(varDecl([declarator(ident("x"), lit(42))]), null, ident("z"), breakStmt(null)));
|
||||
assertStmt("for (x; y; ) break", forStmt(ident("x"), ident("y"), null, breakStmt(null)));
|
||||
assertStmt("for (var x; y; ) break", forStmt(varDecl([declarator(ident("x"), null)]), ident("y"), null, breakStmt(null)));
|
||||
assertStmt("for (var x = 42; y; ) break", forStmt(varDecl([declarator(ident("x"),lit(42))]), ident("y"), null, breakStmt(null)));
|
||||
assertStmt("for (var x in y) break", forInStmt(varDecl([declarator(ident("x"),null)]), ident("y"), breakStmt(null)));
|
||||
assertStmt("for (x in y) break", forInStmt(ident("x"), ident("y"), breakStmt(null)));
|
||||
assertStmt("{ }", blockStmt([]));
|
||||
assertStmt("{ throw 1; throw 2; throw 3; }", blockStmt([ throwStmt(lit(1)), throwStmt(lit(2)), throwStmt(lit(3))]));
|
||||
assertStmt(";", emptyStmt);
|
||||
assertStmt("if (foo) throw 42;", ifStmt(ident("foo"), throwStmt(lit(42)), null));
|
||||
assertStmt("if (foo) throw 42; else true;", ifStmt(ident("foo"), throwStmt(lit(42)), exprStmt(lit(true))));
|
||||
assertStmt("if (foo) { throw 1; throw 2; throw 3; }",
|
||||
ifStmt(ident("foo"),
|
||||
blockStmt([throwStmt(lit(1)), throwStmt(lit(2)), throwStmt(lit(3))]),
|
||||
null));
|
||||
assertStmt("if (foo) { throw 1; throw 2; throw 3; } else true;",
|
||||
ifStmt(ident("foo"),
|
||||
blockStmt([throwStmt(lit(1)), throwStmt(lit(2)), throwStmt(lit(3))]),
|
||||
exprStmt(lit(true))));
|
||||
assertStmt("foo: for(;;) break foo;", labStmt(ident("foo"), forStmt(null, null, null, breakStmt(ident("foo")))));
|
||||
assertStmt("foo: for(;;) continue foo;", labStmt(ident("foo"), forStmt(null, null, null, continueStmt(ident("foo")))));
|
||||
assertStmt("with (obj) { }", withStmt(ident("obj"), blockStmt([])));
|
||||
assertStmt("with (obj) { obj; }", withStmt(ident("obj"), blockStmt([exprStmt(ident("obj"))])));
|
||||
assertStmt("while (foo) { }", whileStmt(ident("foo"), blockStmt([])));
|
||||
assertStmt("while (foo) { foo; }", whileStmt(ident("foo"), blockStmt([exprStmt(ident("foo"))])));
|
||||
assertStmt("do { } while (foo);", doStmt(blockStmt([]), ident("foo")));
|
||||
assertStmt("do { foo; } while (foo)", doStmt(blockStmt([exprStmt(ident("foo"))]), ident("foo")));
|
||||
assertStmt("switch (foo) { case 1: 1; break; case 2: 2; break; default: 3; }",
|
||||
switchStmt(ident("foo"),
|
||||
[ caseClause(lit(1), [ exprStmt(lit(1)), breakStmt(null) ]),
|
||||
caseClause(lit(2), [ exprStmt(lit(2)), breakStmt(null) ]),
|
||||
defaultClause([ exprStmt(lit(3)) ]) ]));
|
||||
assertStmt("switch (foo) { case 1: 1; break; case 2: 2; break; default: 3; case 42: 42; }",
|
||||
switchStmt(ident("foo"),
|
||||
[ caseClause(lit(1), [ exprStmt(lit(1)), breakStmt(null) ]),
|
||||
caseClause(lit(2), [ exprStmt(lit(2)), breakStmt(null) ]),
|
||||
defaultClause([ exprStmt(lit(3)) ]),
|
||||
caseClause(lit(42), [ exprStmt(lit(42)) ]) ]));
|
||||
assertStmt("try { } catch (e) { }",
|
||||
tryStmt(blockStmt([]),
|
||||
[ catchClause(ident("e"), null, blockStmt([])) ],
|
||||
null));
|
||||
assertStmt("try { } catch (e) { } finally { }",
|
||||
tryStmt(blockStmt([]),
|
||||
[ catchClause(ident("e"), null, blockStmt([])) ],
|
||||
blockStmt([])));
|
||||
assertStmt("try { } finally { }",
|
||||
tryStmt(blockStmt([]),
|
||||
[],
|
||||
blockStmt([])));
|
||||
|
||||
// redeclarations (TOK_NAME nodes with lexdef)
|
||||
|
||||
assertStmt("function f() { function g() { } function g() { } }",
|
||||
funDecl(ident("f"), [], blockStmt([funDecl(ident("g"), [], blockStmt([])),
|
||||
funDecl(ident("g"), [], blockStmt([]))])));
|
||||
|
||||
assertStmt("function f() { function g() { } function g() { return 42 } }",
|
||||
funDecl(ident("f"), [], blockStmt([funDecl(ident("g"), [], blockStmt([])),
|
||||
funDecl(ident("g"), [], blockStmt([returnStmt(lit(42))]))])));
|
||||
|
||||
assertStmt("function f() { var x = 42; var x = 43; }",
|
||||
funDecl(ident("f"), [], blockStmt([varDecl([declarator(ident("x"),lit(42))]),
|
||||
varDecl([declarator(ident("x"),lit(43))])])));
|
||||
|
||||
// getters and setters
|
||||
|
||||
assertExpr("({ get x() { return 42 } })",
|
||||
objExpr([ objProp(ident("x"),
|
||||
funExpr(null, [], blockStmt([returnStmt(lit(42))])),
|
||||
"get" ) ]));
|
||||
assertExpr("({ set x(v) { return 42 } })",
|
||||
objExpr([ objProp(ident("x"),
|
||||
funExpr(null, [ident("v")], blockStmt([returnStmt(lit(42))])),
|
||||
"set" ) ]));
|
||||
|
||||
}
|
||||
|
||||
exports.testReflect = testReflect;
|
||||
|
||||
}(typeof exports === 'undefined' ? this : exports));
|
66
node_modules/esprima/test/run.js
generated
vendored
66
node_modules/esprima/test/run.js
generated
vendored
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>
|
||||
Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*jslint node:true */
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var child = require('child_process'),
|
||||
nodejs = '"' + process.execPath + '"',
|
||||
ret = 0,
|
||||
suites,
|
||||
index;
|
||||
|
||||
suites = [
|
||||
'test',
|
||||
'compat'
|
||||
];
|
||||
|
||||
function nextTest() {
|
||||
var suite = suites[index];
|
||||
|
||||
if (index < suites.length) {
|
||||
child.exec(nodejs + ' ./test/' + suite + '.js', function (err, stdout, stderr) {
|
||||
if (stdout) {
|
||||
process.stdout.write(suite + ': ' + stdout);
|
||||
}
|
||||
if (stderr) {
|
||||
process.stderr.write(suite + ': ' + stderr);
|
||||
}
|
||||
if (err) {
|
||||
ret = err.code;
|
||||
}
|
||||
index += 1;
|
||||
nextTest();
|
||||
});
|
||||
} else {
|
||||
process.exit(ret);
|
||||
}
|
||||
}
|
||||
|
||||
index = 0;
|
||||
nextTest();
|
||||
}());
|
16659
node_modules/esprima/test/test.js
generated
vendored
16659
node_modules/esprima/test/test.js
generated
vendored
File diff suppressed because it is too large
Load Diff
164
node_modules/esprima/tools/generate-unicode-regex.py
generated
vendored
164
node_modules/esprima/tools/generate-unicode-regex.py
generated
vendored
@@ -1,164 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
# By Yusuke Suzuki <utatane.tea@gmail.com>
|
||||
# Modified by Mathias Bynens <http://mathiasbynens.be/>
|
||||
# http://code.google.com/p/esprima/issues/detail?id=110
|
||||
|
||||
import sys
|
||||
import string
|
||||
import re
|
||||
|
||||
class RegExpGenerator(object):
|
||||
def __init__(self, detector):
|
||||
self.detector = detector
|
||||
|
||||
def generate_identifier_start(self):
|
||||
r = [ ch for ch in range(0xFFFF + 1) if self.detector.is_identifier_start(ch)]
|
||||
return self._generate_range(r)
|
||||
|
||||
def generate_identifier_part(self):
|
||||
r = [ ch for ch in range(0xFFFF + 1) if self.detector.is_identifier_part(ch)]
|
||||
return self._generate_range(r)
|
||||
|
||||
def generate_non_ascii_identifier_start(self):
|
||||
r = [ ch for ch in xrange(0x0080, 0xFFFF + 1) if self.detector.is_identifier_start(ch)]
|
||||
return self._generate_range(r)
|
||||
|
||||
def generate_non_ascii_identifier_part(self):
|
||||
r = [ ch for ch in range(0x0080, 0xFFFF + 1) if self.detector.is_identifier_part(ch)]
|
||||
return self._generate_range(r)
|
||||
|
||||
def generate_non_ascii_separator_space(self):
|
||||
r = [ ch for ch in range(0x0080, 0xFFFF + 1) if self.detector.is_separator_space(ch)]
|
||||
return self._generate_range(r)
|
||||
|
||||
def _generate_range(self, r):
|
||||
if len(r) == 0:
|
||||
return '[]'
|
||||
|
||||
buf = []
|
||||
start = r[0]
|
||||
end = r[0]
|
||||
predict = start + 1
|
||||
r = r[1:]
|
||||
|
||||
for code in r:
|
||||
if predict == code:
|
||||
end = code
|
||||
predict = code + 1
|
||||
continue
|
||||
else:
|
||||
if start == end:
|
||||
buf.append("\\u%04X" % start)
|
||||
elif end == start + 1:
|
||||
buf.append("\\u%04X\\u%04X" % (start, end))
|
||||
else:
|
||||
buf.append("\\u%04X-\\u%04X" % (start, end))
|
||||
start = code
|
||||
end = code
|
||||
predict = code + 1
|
||||
|
||||
if start == end:
|
||||
buf.append("\\u%04X" % start)
|
||||
else:
|
||||
buf.append("\\u%04X-\\u%04X" % (start, end))
|
||||
|
||||
return '[' + ''.join(buf) + ']'
|
||||
|
||||
|
||||
class Detector(object):
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
|
||||
def is_ascii(self, ch):
|
||||
return ch < 0x80
|
||||
|
||||
def is_ascii_alpha(self, ch):
|
||||
v = ch | 0x20
|
||||
return v >= ord('a') and v <= ord('z')
|
||||
|
||||
def is_decimal_digit(self, ch):
|
||||
return ch >= ord('0') and ch <= ord('9')
|
||||
|
||||
def is_octal_digit(self, ch):
|
||||
return ch >= ord('0') and ch <= ord('7')
|
||||
|
||||
def is_hex_digit(self, ch):
|
||||
v = ch | 0x20
|
||||
return self.is_decimal_digit(c) or (v >= ord('a') and v <= ord('f'))
|
||||
|
||||
def is_digit(self, ch):
|
||||
return self.is_decimal_digit(ch) or self.data[ch] == 'Nd'
|
||||
|
||||
def is_ascii_alphanumeric(self, ch):
|
||||
return self.is_decimal_digit(ch) or self.is_ascii_alpha(ch)
|
||||
|
||||
def _is_non_ascii_identifier_start(self, ch):
|
||||
c = self.data[ch]
|
||||
return c == 'Lu' or c == 'Ll' or c == 'Lt' or c == 'Lm' or c == 'Lo' or c == 'Nl'
|
||||
|
||||
def _is_non_ascii_identifier_part(self, ch):
|
||||
c = self.data[ch]
|
||||
return c == 'Lu' or c == 'Ll' or c == 'Lt' or c == 'Lm' or c == 'Lo' or c == 'Nl' or c == 'Mn' or c == 'Mc' or c == 'Nd' or c == 'Pc' or ch == 0x200C or ch == 0x200D
|
||||
|
||||
def is_separator_space(self, ch):
|
||||
return self.data[ch] == 'Zs'
|
||||
|
||||
def is_white_space(self, ch):
|
||||
return ch == ord(' ') or ch == ord("\t") or ch == 0xB or ch == 0xC or ch == 0x00A0 or ch == 0xFEFF or self.is_separator_space(ch)
|
||||
|
||||
def is_line_terminator(self, ch):
|
||||
return ch == 0x000D or ch == 0x000A or self.is_line_or_paragraph_terminator(ch)
|
||||
|
||||
def is_line_or_paragraph_terminator(self, ch):
|
||||
return ch == 0x2028 or ch == 0x2029
|
||||
|
||||
def is_identifier_start(self, ch):
|
||||
if self.is_ascii(ch):
|
||||
return ch == ord('$') or ch == ord('_') or ch == ord('\\') or self.is_ascii_alpha(ch)
|
||||
return self._is_non_ascii_identifier_start(ch)
|
||||
|
||||
def is_identifier_part(self, ch):
|
||||
if self.is_ascii(ch):
|
||||
return ch == ord('$') or ch == ord('_') or ch == ord('\\') or self.is_ascii_alphanumeric(ch)
|
||||
return self._is_non_ascii_identifier_part(ch)
|
||||
|
||||
def analyze(source):
|
||||
data = []
|
||||
dictionary = {}
|
||||
with open(source) as uni:
|
||||
flag = False
|
||||
first = 0
|
||||
for line in uni:
|
||||
d = string.split(line.strip(), ";")
|
||||
val = int(d[0], 16)
|
||||
if flag:
|
||||
if re.compile("<.+, Last>").match(d[1]):
|
||||
# print "%s : u%X" % (d[1], val)
|
||||
flag = False
|
||||
for t in range(first, val+1):
|
||||
dictionary[t] = str(d[2])
|
||||
else:
|
||||
raise "Database Exception"
|
||||
else:
|
||||
if re.compile("<.+, First>").match(d[1]):
|
||||
# print "%s : u%X" % (d[1], val)
|
||||
flag = True
|
||||
first = val
|
||||
else:
|
||||
dictionary[val] = str(d[2])
|
||||
for i in range(0xFFFF + 1):
|
||||
if dictionary.get(i) == None:
|
||||
data.append("Un")
|
||||
else:
|
||||
data.append(dictionary[i])
|
||||
return RegExpGenerator(Detector(data))
|
||||
|
||||
def main(source):
|
||||
generator = analyze(source)
|
||||
print generator.generate_non_ascii_identifier_start()
|
||||
print generator.generate_non_ascii_identifier_part()
|
||||
print generator.generate_non_ascii_separator_space()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv[1])
|
28
node_modules/esprima/tools/update-coverage.sh
generated
vendored
28
node_modules/esprima/tools/update-coverage.sh
generated
vendored
@@ -1,28 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ `command -v cover` ]; then
|
||||
|
||||
REVISION=`git log -1 --pretty=%h`
|
||||
DATE=`git log -1 --pretty=%cD | cut -c 6-16`
|
||||
|
||||
echo "Running coverage analysis..."
|
||||
rm -rf .coverage_data
|
||||
rm -rf cover_index
|
||||
|
||||
cover run test/test.js
|
||||
cover report html
|
||||
|
||||
cat test/coverage.header.html > test/coverage.html
|
||||
echo "Tested revision: <a href='https://github.com/ariya/esprima/commit/${REVISION}'>${REVISION}</a>" >> test/coverage.html
|
||||
echo " (dated ${DATE}).</p>" >> test/coverage.html
|
||||
|
||||
echo '<pre>' >> test/coverage.html
|
||||
grep -h '^<span class' cover_html/*esprima\.js\.html >> test/coverage.html
|
||||
echo '</pre>' >> test/coverage.html
|
||||
cat test/coverage.footer.html >> test/coverage.html
|
||||
|
||||
rm -rf cover_html
|
||||
rm -rf .coverage_data
|
||||
else
|
||||
echo "Please install node-cover first!"
|
||||
fi
|
Reference in New Issue
Block a user