|
@@ -13,6 +13,11 @@
|
|
|
})(function(CodeMirror) {
|
|
|
"use strict";
|
|
|
|
|
|
+function expressionAllowed(stream, state, backUp) {
|
|
|
+ return /^(?:operator|sof|keyword c|case|new|[\[{}\(,;:]|=>)$/.test(state.lastType) ||
|
|
|
+ (state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0))))
|
|
|
+}
|
|
|
+
|
|
|
CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
|
var indentUnit = config.indentUnit;
|
|
|
var statementIndent = parserConfig.statementIndent;
|
|
@@ -30,13 +35,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
|
|
|
};
|
|
|
|
|
@@ -45,18 +50,23 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
|
var type = {type: "variable", style: "variable-3"};
|
|
|
var tsKeywords = {
|
|
|
// object-like things
|
|
|
- "interface": kw("interface"),
|
|
|
- "extends": kw("extends"),
|
|
|
- "constructor": kw("constructor"),
|
|
|
+ "interface": kw("class"),
|
|
|
+ "implements": C,
|
|
|
+ "namespace": C,
|
|
|
+ "module": kw("module"),
|
|
|
+ "enum": kw("module"),
|
|
|
|
|
|
// scope modifiers
|
|
|
- "public": kw("public"),
|
|
|
- "private": kw("private"),
|
|
|
- "protected": kw("protected"),
|
|
|
- "static": kw("static"),
|
|
|
+ "public": kw("modifier"),
|
|
|
+ "private": kw("modifier"),
|
|
|
+ "protected": kw("modifier"),
|
|
|
+ "abstract": kw("modifier"),
|
|
|
+
|
|
|
+ // operators
|
|
|
+ "as": operator,
|
|
|
|
|
|
// types
|
|
|
- "string": type, "number": type, "bool": type, "any": type
|
|
|
+ "string": type, "number": type, "boolean": type, "any": type
|
|
|
};
|
|
|
|
|
|
for (var attr in tsKeywords) {
|
|
@@ -105,6 +115,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,8 +131,7 @@ 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 (expressionAllowed(stream, state, 1)) {
|
|
|
readRegexp(stream);
|
|
|
stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
|
|
|
return ret("regexp", "string-2");
|
|
@@ -275,8 +290,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 {
|
|
@@ -347,10 +362,10 @@ 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);
|
|
|
+ if (type == "module") return cont(pushlex("form"), pattern, pushlex("}"), expect("{"), block, poplex, poplex)
|
|
|
return pass(pushlex("stat"), expression, expect(";"), poplex);
|
|
|
}
|
|
|
function expression(type) {
|
|
@@ -374,7 +389,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) {
|
|
@@ -425,6 +441,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,8 +470,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
|
return cont(afterprop);
|
|
|
} else if (type == "jsonld-keyword") {
|
|
|
return cont(afterprop);
|
|
|
+ } else if (type == "modifier") {
|
|
|
+ return cont(objprop)
|
|
|
} else if (type == "[") {
|
|
|
return cont(expression, expect("]"), afterprop);
|
|
|
+ } else if (type == "spread") {
|
|
|
+ return cont(expression);
|
|
|
}
|
|
|
}
|
|
|
function getterSetter(type) {
|
|
@@ -482,14 +514,19 @@ 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 == "modifier") return cont(pattern)
|
|
|
if (type == "variable") { register(value); return cont(); }
|
|
|
+ if (type == "spread") return cont(pattern);
|
|
|
if (type == "[") return contCommasep(pattern, "]");
|
|
|
if (type == "{") return contCommasep(proppattern, "}");
|
|
|
}
|
|
@@ -499,6 +536,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
|
return cont(maybeAssign);
|
|
|
}
|
|
|
if (type == "variable") cx.marked = "property";
|
|
|
+ if (type == "spread") return cont(pattern);
|
|
|
+ if (type == "}") return pass();
|
|
|
return cont(expect(":"), pattern, maybeAssign);
|
|
|
}
|
|
|
function maybeAssign(_type, value) {
|
|
@@ -538,7 +577,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);}
|
|
@@ -569,10 +608,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(";")); }
|
|
@@ -585,7 +620,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); }
|
|
@@ -621,7 +660,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
|
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
|
|
|
localVars: parserConfig.localVars,
|
|
|
context: parserConfig.localVars && {vars: parserConfig.localVars},
|
|
|
- indented: 0
|
|
|
+ indented: basecolumn || 0
|
|
|
};
|
|
|
if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
|
|
|
state.globalVars = parserConfig.globalVars;
|
|
@@ -677,7 +716,13 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
|
|
|
|
|
|
helperType: jsonMode ? "json" : "javascript",
|
|
|
jsonldMode: jsonldMode,
|
|
|
- jsonMode: jsonMode
|
|
|
+ jsonMode: jsonMode,
|
|
|
+
|
|
|
+ expressionAllowed: expressionAllowed,
|
|
|
+ skipExpression: function(state) {
|
|
|
+ var top = state.cc[state.cc.length - 1]
|
|
|
+ if (top == expression || top == expressionNoComma) state.cc.pop()
|
|
|
+ }
|
|
|
};
|
|
|
});
|
|
|
|