|
|
@@ -30,13 +30,13 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
|
|
|
|
var jsKeywords = {
|
|
|
"if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
|
|
|
- "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, "debugger": C,
|
|
|
+ "return": C, "break": C, "continue": C, "new": kw("new"), "delete": C, "throw": C, "debugger": 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,
|
|
|
- "this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"),
|
|
|
+ "this": kw("this"), "class": kw("class"), "super": kw("atom"),
|
|
|
"yield": C, "export": kw("export"), "import": kw("import"), "extends": C
|
|
|
};
|
|
|
|
|
|
@@ -56,7 +56,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
|
"static": kw("static"),
|
|
|
|
|
|
// types
|
|
|
- "string": type, "number": type, "bool": type, "any": type
|
|
|
+ "string": type, "number": type, "boolean": type, "any": type
|
|
|
};
|
|
|
|
|
|
for (var attr in tsKeywords) {
|
|
|
@@ -105,6 +105,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
|
} else if (ch == "0" && stream.eat(/x/i)) {
|
|
|
stream.eatWhile(/[\da-f]/i);
|
|
|
return ret("number", "number");
|
|
|
+ } else if (ch == "0" && stream.eat(/o/i)) {
|
|
|
+ stream.eatWhile(/[0-7]/i);
|
|
|
+ return ret("number", "number");
|
|
|
+ } else if (ch == "0" && stream.eat(/b/i)) {
|
|
|
+ stream.eatWhile(/[01]/i);
|
|
|
+ return ret("number", "number");
|
|
|
} else if (/\d/.test(ch)) {
|
|
|
stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
|
|
|
return ret("number", "number");
|
|
|
@@ -115,10 +121,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
|
} else if (stream.eat("/")) {
|
|
|
stream.skipToEnd();
|
|
|
return ret("comment", "comment");
|
|
|
- } else if (state.lastType == "operator" || state.lastType == "keyword c" ||
|
|
|
- state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) {
|
|
|
+ } else if (/^(?:operator|sof|keyword c|case|new|[\[{}\(,;:])$/.test(state.lastType)) {
|
|
|
readRegexp(stream);
|
|
|
- stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
|
|
|
+ stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
|
|
|
return ret("regexp", "string-2");
|
|
|
} else {
|
|
|
stream.eatWhile(isOperatorChar);
|
|
|
@@ -205,6 +210,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
|
++depth;
|
|
|
} else if (wordRE.test(ch)) {
|
|
|
sawSomething = true;
|
|
|
+ } else if (/["'\/]/.test(ch)) {
|
|
|
+ return;
|
|
|
} else if (sawSomething && !depth) {
|
|
|
++pos;
|
|
|
break;
|
|
|
@@ -273,8 +280,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
|
return false;
|
|
|
}
|
|
|
var state = cx.state;
|
|
|
+ cx.marked = "def";
|
|
|
if (state.context) {
|
|
|
- cx.marked = "def";
|
|
|
if (inList(state.localVars)) return;
|
|
|
state.localVars = {name: varname, next: state.localVars};
|
|
|
} else {
|
|
|
@@ -345,10 +352,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
|
if (type == "default") return cont(expect(":"));
|
|
|
if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
|
|
|
statement, poplex, popcontext);
|
|
|
- if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex);
|
|
|
if (type == "class") return cont(pushlex("form"), className, poplex);
|
|
|
- if (type == "export") return cont(pushlex("form"), afterExport, poplex);
|
|
|
- if (type == "import") return cont(pushlex("form"), afterImport, poplex);
|
|
|
+ if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
|
|
|
+ if (type == "import") return cont(pushlex("stat"), afterImport, poplex);
|
|
|
return pass(pushlex("stat"), expression, expect(";"), poplex);
|
|
|
}
|
|
|
function expression(type) {
|
|
|
@@ -372,7 +378,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
|
if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
|
|
|
if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
|
|
|
if (type == "{") return contCommasep(objprop, "}", null, maybeop);
|
|
|
- if (type == "quasi") { return pass(quasi, maybeop); }
|
|
|
+ if (type == "quasi") return pass(quasi, maybeop);
|
|
|
+ if (type == "new") return cont(maybeTarget(noComma));
|
|
|
return cont();
|
|
|
}
|
|
|
function maybeexpression(type) {
|
|
|
@@ -423,6 +430,18 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
|
findFatArrow(cx.stream, cx.state);
|
|
|
return pass(type == "{" ? statement : expressionNoComma);
|
|
|
}
|
|
|
+ function maybeTarget(noComma) {
|
|
|
+ return function(type) {
|
|
|
+ if (type == ".") return cont(noComma ? targetNoComma : target);
|
|
|
+ else return pass(noComma ? expressionNoComma : expression);
|
|
|
+ };
|
|
|
+ }
|
|
|
+ function target(_, value) {
|
|
|
+ if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorComma); }
|
|
|
+ }
|
|
|
+ function targetNoComma(_, value) {
|
|
|
+ if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorNoComma); }
|
|
|
+ }
|
|
|
function maybelabel(type) {
|
|
|
if (type == ":") return cont(poplex, statement);
|
|
|
return pass(maybeoperatorComma, expect(";"), poplex);
|
|
|
@@ -442,6 +461,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
|
return cont(afterprop);
|
|
|
} else if (type == "[") {
|
|
|
return cont(expression, expect("]"), afterprop);
|
|
|
+ } else if (type == "spread") {
|
|
|
+ return cont(expression);
|
|
|
}
|
|
|
}
|
|
|
function getterSetter(type) {
|
|
|
@@ -480,14 +501,18 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
|
function maybetype(type) {
|
|
|
if (isTS && type == ":") return cont(typedef);
|
|
|
}
|
|
|
+ function maybedefault(_, value) {
|
|
|
+ if (value == "=") return cont(expressionNoComma);
|
|
|
+ }
|
|
|
function typedef(type) {
|
|
|
- if (type == "variable"){cx.marked = "variable-3"; return cont();}
|
|
|
+ if (type == "variable") {cx.marked = "variable-3"; return cont();}
|
|
|
}
|
|
|
function vardef() {
|
|
|
return pass(pattern, maybetype, maybeAssign, vardefCont);
|
|
|
}
|
|
|
function pattern(type, value) {
|
|
|
if (type == "variable") { register(value); return cont(); }
|
|
|
+ if (type == "spread") return cont(pattern);
|
|
|
if (type == "[") return contCommasep(pattern, "]");
|
|
|
if (type == "{") return contCommasep(proppattern, "}");
|
|
|
}
|
|
|
@@ -497,6 +522,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
|
return cont(maybeAssign);
|
|
|
}
|
|
|
if (type == "variable") cx.marked = "property";
|
|
|
+ if (type == "spread") return cont(pattern);
|
|
|
return cont(expect(":"), pattern, maybeAssign);
|
|
|
}
|
|
|
function maybeAssign(_type, value) {
|
|
|
@@ -536,7 +562,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
|
}
|
|
|
function funarg(type) {
|
|
|
if (type == "spread") return cont(funarg);
|
|
|
- return pass(pattern, maybetype);
|
|
|
+ return pass(pattern, maybetype, maybedefault);
|
|
|
}
|
|
|
function className(type, value) {
|
|
|
if (type == "variable") {register(value); return cont(classNameAfter);}
|
|
|
@@ -547,6 +573,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
|
}
|
|
|
function classBody(type, value) {
|
|
|
if (type == "variable" || cx.style == "keyword") {
|
|
|
+ if (value == "static") {
|
|
|
+ cx.marked = "keyword";
|
|
|
+ return cont(classBody);
|
|
|
+ }
|
|
|
cx.marked = "property";
|
|
|
if (value == "get" || value == "set") return cont(classGetterSetter, functiondef, classBody);
|
|
|
return cont(functiondef, classBody);
|
|
|
@@ -563,10 +593,6 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
|
cx.marked = "property";
|
|
|
return cont();
|
|
|
}
|
|
|
- function afterModule(type, value) {
|
|
|
- if (type == "string") return cont(statement);
|
|
|
- if (type == "variable") { register(value); return cont(maybeFrom); }
|
|
|
- }
|
|
|
function afterExport(_type, value) {
|
|
|
if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
|
|
|
if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
|
|
|
@@ -579,7 +605,11 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
|
function importSpec(type, value) {
|
|
|
if (type == "{") return contCommasep(importSpec, "}");
|
|
|
if (type == "variable") register(value);
|
|
|
- return cont();
|
|
|
+ if (value == "*") cx.marked = "keyword";
|
|
|
+ return cont(maybeAs);
|
|
|
+ }
|
|
|
+ function maybeAs(_type, value) {
|
|
|
+ if (value == "as") { cx.marked = "keyword"; return cont(importSpec); }
|
|
|
}
|
|
|
function maybeFrom(_type, value) {
|
|
|
if (value == "from") { cx.marked = "keyword"; return cont(expression); }
|
|
|
@@ -598,6 +628,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
|
if (type == "if") return cont(expression, comprehension);
|
|
|
}
|
|
|
|
|
|
+ function isContinuedStatement(state, textAfter) {
|
|
|
+ return state.lastType == "operator" || state.lastType == "," ||
|
|
|
+ isOperatorChar.test(textAfter.charAt(0)) ||
|
|
|
+ /[,.]/.test(textAfter.charAt(0));
|
|
|
+ }
|
|
|
+
|
|
|
// Interface
|
|
|
|
|
|
return {
|
|
|
@@ -649,7 +685,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
|
else if (type == "form" && firstChar == "{") return lexical.indented;
|
|
|
else if (type == "form") return lexical.indented + indentUnit;
|
|
|
else if (type == "stat")
|
|
|
- return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? statementIndent || indentUnit : 0);
|
|
|
+ return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0);
|
|
|
else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
|
|
|
return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
|
|
|
else if (lexical.align) return lexical.column + (closing ? 0 : 1);
|
|
|
@@ -661,6 +697,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
|
blockCommentEnd: jsonMode ? null : "*/",
|
|
|
lineComment: jsonMode ? null : "//",
|
|
|
fold: "brace",
|
|
|
+ closeBrackets: "()[]{}''\"\"``",
|
|
|
|
|
|
helperType: jsonMode ? "json" : "javascript",
|
|
|
jsonldMode: jsonldMode,
|