summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorManu Sridharan2013-07-22 18:03:18 (EDT)
committer Mark Macdonald2013-07-22 18:22:23 (EDT)
commit332b5388728c790671492bd461e519493486980a (patch)
treec505a9da44386efdce00acfe675d2a32a42946bb
parent425737d1e4e01e0a935d43c8e9a9e62ab2e1b225 (diff)
downloadorg.eclipse.orion.client-332b5388728c790671492bd461e519493486980a.zip
org.eclipse.orion.client-332b5388728c790671492bd461e519493486980a.tar.gz
org.eclipse.orion.client-332b5388728c790671492bd461e519493486980a.tar.bz2
[corrected Author] better tolerant parsing of functions.v20130722-2222
Signed-off-by: Manu Sridharan <msridhar@us.ibm.com>
-rw-r--r--bundles/org.eclipse.orion.client.ui/web/esprima/esprima.js68
-rw-r--r--bundles/org.eclipse.orion.client.ui/web/js-tests/esprima/esprimaJsContentAssistTests.js67
2 files changed, 115 insertions, 20 deletions
diff --git a/bundles/org.eclipse.orion.client.ui/web/esprima/esprima.js b/bundles/org.eclipse.orion.client.ui/web/esprima/esprima.js
index 18792b5..d4efc2a 100644
--- a/bundles/org.eclipse.orion.client.ui/web/esprima/esprima.js
+++ b/bundles/org.eclipse.orion.client.ui/web/esprima/esprima.js
@@ -39,7 +39,8 @@
/*jslint bitwise:true plusplus:true */
/*global esprima:true, exports:true,
throwError: true, createLiteral: true, generateStatement: true,
-parseAssignmentExpression: true, parseBlock: true, parseExpression: true,
+parseAssignmentExpression: true, parseBlock: true,
+expectCloseBracketWrapThrow: true, parseExpression: true,
parseFunctionDeclaration: true, parseFunctionExpression: true,
parseFunctionSourceElements: true, parseVariableIdentifier: true,
parseLeftHandSideExpression: true,
@@ -2165,7 +2166,8 @@ parseStatement: true, parseSourceElement: true */
block = parseStatementList();
- expect('}');
+ //expect('}');
+ expectCloseBracketWrapThrow();
return {
type: Syntax.BlockStatement,
@@ -2299,17 +2301,13 @@ parseStatement: true, parseSourceElement: true */
extra.errors.push(error);
}
- // 12.5 If statement
-
- function parseIfStatement() {
- var test, consequent, alternate;
-
- expectKeyword('if');
-
- expect('(');
-
- test = parseExpression();
-
+ /**
+ * for statements like if, while, for, etc.
+ * Check for the ')' on the condition. If
+ * it is not present, catch the error, and backtrack
+ * if we see a '{' instead (to continue parsing the block)
+ */
+ function expectCloseParenWrapThrow() {
// needs generalizing to a 'expect A but don't consume if you hit B or C'
try {
expect(')');
@@ -2321,8 +2319,8 @@ parseStatement: true, parseSourceElement: true */
if (source[e.index] === '{') {
index=e.index;
buffer=null;
- // activating this block will mean the following statement is parsed as a consequent.
- // without it the statement is considered not at all part of the if at all
+ // activating this block will mean the following statement is parsed as a consequent / body.
+ // without it the statement is considered not at all part of the enclosing statement at all
// } else {
// rewind();
}
@@ -2331,6 +2329,20 @@ parseStatement: true, parseSourceElement: true */
}
}
+ }
+ // 12.5 If statement
+
+ function parseIfStatement() {
+ var test, consequent, alternate;
+
+ expectKeyword('if');
+
+ expect('(');
+
+ test = parseExpression();
+
+ expectCloseParenWrapThrow();
+
consequent = parseStatement();
// required because of the check in wrapTracking that returns nothing if node is undefined
if (!consequent) {
@@ -2394,8 +2406,8 @@ parseStatement: true, parseSourceElement: true */
test = parseExpression();
- expect(')');
-
+ expectCloseParenWrapThrow();
+
oldInIteration = state.inIteration;
state.inIteration = true;
@@ -2477,8 +2489,9 @@ parseStatement: true, parseSourceElement: true */
}
}
- expect(')');
-
+// expect(')');
+ expectCloseParenWrapThrow();
+
oldInIteration = state.inIteration;
state.inIteration = true;
@@ -2936,6 +2949,21 @@ parseStatement: true, parseSourceElement: true */
}
// 13 Function Definition
+ function expectCloseBracketWrapThrow() {
+ if (extra.errors) {
+ // continue parsing even with missing close
+ // brace. This gives a better AST for the
+ // block, as information about
+ // the parsed statements remain
+ try {
+ expect('}');
+ } catch (e) {
+ pushError(e);
+ }
+ } else {
+ expect('}');
+ }
+ }
function parseFunctionSourceElements() {
var sourceElement, sourceElements = [], token, directive, firstRestricted,
@@ -2989,7 +3017,7 @@ parseStatement: true, parseSourceElement: true */
sourceElements.push(sourceElement);
}
- expect('}');
+ expectCloseBracketWrapThrow();
state.labelSet = oldLabelSet;
state.inIteration = oldInIteration;
diff --git a/bundles/org.eclipse.orion.client.ui/web/js-tests/esprima/esprimaJsContentAssistTests.js b/bundles/org.eclipse.orion.client.ui/web/js-tests/esprima/esprimaJsContentAssistTests.js
index 5f5a272..81eb186 100644
--- a/bundles/org.eclipse.orion.client.ui/web/js-tests/esprima/esprimaJsContentAssistTests.js
+++ b/bundles/org.eclipse.orion.client.ui/web/js-tests/esprima/esprimaJsContentAssistTests.js
@@ -4175,6 +4175,73 @@ define(["plugins/esprima/esprimaJsContentAssist", "orion/assert", "esprima/espri
["prototype", "prototype : Object"]
]);
};
+
+ tests["test tolerant parsing function 1"] = function() {
+ var results = computeContentAssist(
+ "var xxxyyy = {};\n" +
+ "function foo() {\n" +
+ " if (xx", "xx");
+ testProposals(results, [["xxxyyy", "xxxyyy : {}"]]);
+ };
+
+ tests["test tolerant parsing function 2"] = function() {
+ var results = computeContentAssist(
+ "function foo() {\n" +
+ " var xxxyyy = false;\n" +
+ " if (!xx", "xx");
+ testProposals(results, [["xxxyyy", "xxxyyy : Boolean"]]);
+ };
+
+ tests["test tolerant parsing function 3"] = function() {
+ var results = computeContentAssist(
+ "function foo(xxxyyy) {\n" +
+ " if (!xx", "xx");
+ testProposals(results, [["xxxyyy", "xxxyyy : {}"]]);
+ };
+
+ tests["test tolerant parsing function 4"] = function() {
+ var results = computeContentAssist(
+ "var x = { bazz: 3 };\n" +
+ "function foo() {\n" +
+ " if (x.b", "b");
+ testProposals(results, [["bazz", "bazz : Number"]]);
+ };
+
+ tests["test tolerant parsing function 5"] = function() {
+ var results = computeContentAssist(
+ "function foo(p) {\n" +
+ " p.ffffff = false;\n" +
+ " while (p.ff", "ff");
+ testProposals(results, [["ffffff", "ffffff : Boolean"]]);
+ };
+
+ tests["test tolerant parsing function 6"] = function() {
+ var results = computeContentAssist(
+ "function foo(p) {\n" +
+ " p.ffffff = false;\n" +
+ " if (p) {\n" +
+ " while (p.ff", "ff");
+ testProposals(results, [["ffffff", "ffffff : Boolean"]]);
+ };
+
+ tests["test tolerant parsing function 7"] = function() {
+ var results = computeContentAssist(
+ "function foo(p) {\n" +
+ " p.ffffff = false;\n" +
+ " if (p) {\n" +
+ " for (var q in p.ff", "ff");
+ testProposals(results, [["ffffff", "ffffff : Boolean"]]);
+ };
+
+ tests["test tolerant parsing function 8"] = function() {
+ var results = computeContentAssist(
+ "function foo(p) {\n" +
+ " p.ffffff = false;\n" +
+ " if (p) {\n" +
+ " for (var q in p) {\n" +
+ " while (p.ff", "ff");
+ testProposals(results, [["ffffff", "ffffff : Boolean"]]);
+ };
return tests;
});