Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(36)

Side by Side Diff: Source/devtools/front_end/cm/javascript.js

Issue 354833004: DevTools: [CodeMirror] roll CodeMirror to version @e20d175 (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: address comments Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3
1 // TODO actually recognize syntax of TypeScript constructs 4 // TODO actually recognize syntax of TypeScript constructs
2 5
6 (function(mod) {
7 if (typeof exports == "object" && typeof module == "object") // CommonJS
8 mod(require("../../lib/codemirror"));
9 else if (typeof define == "function" && define.amd) // AMD
10 define(["../../lib/codemirror"], mod);
11 else // Plain browser env
12 mod(CodeMirror);
13 })(function(CodeMirror) {
14 "use strict";
15
3 CodeMirror.defineMode("javascript", function(config, parserConfig) { 16 CodeMirror.defineMode("javascript", function(config, parserConfig) {
4 var indentUnit = config.indentUnit; 17 var indentUnit = config.indentUnit;
5 var statementIndent = parserConfig.statementIndent; 18 var statementIndent = parserConfig.statementIndent;
6 var jsonMode = parserConfig.json; 19 var jsonldMode = parserConfig.jsonld;
20 var jsonMode = parserConfig.json || jsonldMode;
7 var isTS = parserConfig.typescript; 21 var isTS = parserConfig.typescript;
8 22
9 // Tokenizer 23 // Tokenizer
10 24
11 var keywords = function(){ 25 var keywords = function(){
12 function kw(type) {return {type: type, style: "keyword"};} 26 function kw(type) {return {type: type, style: "keyword"};}
13 var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"); 27 var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
14 var operator = kw("operator"), atom = {type: "atom", style: "atom"}; 28 var operator = kw("operator"), atom = {type: "atom", style: "atom"};
15 29
16 var jsKeywords = { 30 var jsKeywords = {
17 "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "fina lly": B, 31 "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "fina lly": B,
18 "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, 32 "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, "debugger": C,
19 "var": kw("var"), "const": kw("var"), "let": kw("var"), 33 "var": kw("var"), "const": kw("var"), "let": kw("var"),
20 "function": kw("function"), "catch": kw("catch"), 34 "function": kw("function"), "catch": kw("catch"),
21 "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": k w("default"), 35 "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": k w("default"),
22 "in": operator, "typeof": operator, "instanceof": operator, 36 "in": operator, "typeof": operator, "instanceof": operator,
23 "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom, 37 "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
24 "this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"), 38 "this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"),
25 "yield": C, "export": kw("export"), "import": kw("import"), "extends": C 39 "yield": C, "export": kw("export"), "import": kw("import"), "extends": C
26 }; 40 };
27 41
28 // Extend the 'normal' keywords with the TypeScript language extensions 42 // Extend the 'normal' keywords with the TypeScript language extensions
(...skipping 17 matching lines...) Expand all
46 60
47 for (var attr in tsKeywords) { 61 for (var attr in tsKeywords) {
48 jsKeywords[attr] = tsKeywords[attr]; 62 jsKeywords[attr] = tsKeywords[attr];
49 } 63 }
50 } 64 }
51 65
52 return jsKeywords; 66 return jsKeywords;
53 }(); 67 }();
54 68
55 var isOperatorChar = /[+\-*&%=<>!?|~^]/; 69 var isOperatorChar = /[+\-*&%=<>!?|~^]/;
70 var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|re verse|index|base|vocab|graph)"/;
56 71
57 function nextUntilUnescaped(stream, end) { 72 function readRegexp(stream) {
58 var escaped = false, next; 73 var escaped = false, next, inSet = false;
59 while ((next = stream.next()) != null) { 74 while ((next = stream.next()) != null) {
60 if (next == end && !escaped) 75 if (!escaped) {
61 return false; 76 if (next == "/" && !inSet) return;
77 if (next == "[") inSet = true;
78 else if (inSet && next == "]") inSet = false;
79 }
62 escaped = !escaped && next == "\\"; 80 escaped = !escaped && next == "\\";
63 } 81 }
64 return escaped;
65 } 82 }
66 83
67 // Used as scratch variables to communicate multiple values without 84 // Used as scratch variables to communicate multiple values without
68 // consing up tons of objects. 85 // consing up tons of objects.
69 var type, content; 86 var type, content;
70 function ret(tp, style, cont) { 87 function ret(tp, style, cont) {
71 type = tp; content = cont; 88 type = tp; content = cont;
72 return style; 89 return style;
73 } 90 }
74 function tokenBase(stream, state) { 91 function tokenBase(stream, state) {
75 var ch = stream.next(); 92 var ch = stream.next();
76 if (ch == '"' || ch == "'") { 93 if (ch == '"' || ch == "'") {
77 state.tokenize = tokenString(ch); 94 state.tokenize = tokenString(ch);
78 return state.tokenize(stream, state); 95 return state.tokenize(stream, state);
79 } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) { 96 } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
80 return ret("number", "number"); 97 return ret("number", "number");
81 } else if (ch == "." && stream.match("..")) { 98 } else if (ch == "." && stream.match("..")) {
82 return ret("spread", "meta"); 99 return ret("spread", "meta");
83 } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) { 100 } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
84 return ret(ch); 101 return ret(ch);
85 } else if (ch == "=" && stream.eat(">")) { 102 } else if (ch == "=" && stream.eat(">")) {
86 return ret("=>"); 103 return ret("=>", "operator");
87 } else if (ch == "0" && stream.eat(/x/i)) { 104 } else if (ch == "0" && stream.eat(/x/i)) {
88 stream.eatWhile(/[\da-f]/i); 105 stream.eatWhile(/[\da-f]/i);
89 return ret("number", "number"); 106 return ret("number", "number");
90 } else if (/\d/.test(ch)) { 107 } else if (/\d/.test(ch)) {
91 stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/); 108 stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
92 return ret("number", "number"); 109 return ret("number", "number");
93 } else if (ch == "/") { 110 } else if (ch == "/") {
94 if (stream.eat("*")) { 111 if (stream.eat("*")) {
95 state.tokenize = tokenComment; 112 state.tokenize = tokenComment;
96 return tokenComment(stream, state); 113 return tokenComment(stream, state);
97 } else if (stream.eat("/")) { 114 } else if (stream.eat("/")) {
98 stream.skipToEnd(); 115 stream.skipToEnd();
99 return ret("comment", "comment"); 116 return ret("comment", "comment");
100 } else if (state.lastType == "operator" || state.lastType == "keyword c" | | 117 } else if (state.lastType == "operator" || state.lastType == "keyword c" | |
101 state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) { 118 state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) {
102 nextUntilUnescaped(stream, "/"); 119 readRegexp(stream);
103 stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla 120 stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
104 return ret("regexp", "string-2"); 121 return ret("regexp", "string-2");
105 } else { 122 } else {
106 stream.eatWhile(isOperatorChar); 123 stream.eatWhile(isOperatorChar);
107 return ret("operator", null, stream.current()); 124 return ret("operator", "operator", stream.current());
108 } 125 }
109 } else if (ch == "`") { 126 } else if (ch == "`") {
110 state.tokenize = tokenQuasi; 127 state.tokenize = tokenQuasi;
111 return tokenQuasi(stream, state); 128 return tokenQuasi(stream, state);
112 } else if (ch == "#") { 129 } else if (ch == "#") {
113 stream.skipToEnd(); 130 stream.skipToEnd();
114 return ret("error", "error"); 131 return ret("error", "error");
115 } else if (isOperatorChar.test(ch)) { 132 } else if (isOperatorChar.test(ch)) {
116 stream.eatWhile(isOperatorChar); 133 stream.eatWhile(isOperatorChar);
117 return ret("operator", null, stream.current()); 134 return ret("operator", "operator", stream.current());
118 } else { 135 } else {
119 stream.eatWhile(/[\w\$_]/); 136 stream.eatWhile(/[\w\$_]/);
120 var word = stream.current(), known = keywords.propertyIsEnumerable(word) & & keywords[word]; 137 var word = stream.current(), known = keywords.propertyIsEnumerable(word) & & keywords[word];
121 return (known && state.lastType != ".") ? ret(known.type, known.style, wor d) : 138 return (known && state.lastType != ".") ? ret(known.type, known.style, wor d) :
122 ret("variable", "variable", word); 139 ret("variable", "variable", word);
123 } 140 }
124 } 141 }
125 142
126 function tokenString(quote) { 143 function tokenString(quote) {
127 return function(stream, state) { 144 return function(stream, state) {
128 if (!nextUntilUnescaped(stream, quote)) 145 var escaped = false, next;
146 if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){
129 state.tokenize = tokenBase; 147 state.tokenize = tokenBase;
148 return ret("jsonld-keyword", "meta");
149 }
150 while ((next = stream.next()) != null) {
151 if (next == quote && !escaped) break;
152 escaped = !escaped && next == "\\";
153 }
154 if (!escaped) state.tokenize = tokenBase;
130 return ret("string", "string"); 155 return ret("string", "string");
131 }; 156 };
132 } 157 }
133 158
134 function tokenComment(stream, state) { 159 function tokenComment(stream, state) {
135 var maybeEnd = false, ch; 160 var maybeEnd = false, ch;
136 while (ch = stream.next()) { 161 while (ch = stream.next()) {
137 if (ch == "/" && maybeEnd) { 162 if (ch == "/" && maybeEnd) {
138 state.tokenize = tokenBase; 163 state.tokenize = tokenBase;
139 break; 164 break;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 } else if (sawSomething && !depth) { 207 } else if (sawSomething && !depth) {
183 ++pos; 208 ++pos;
184 break; 209 break;
185 } 210 }
186 } 211 }
187 if (sawSomething && !depth) state.fatArrowAt = pos; 212 if (sawSomething && !depth) state.fatArrowAt = pos;
188 } 213 }
189 214
190 // Parser 215 // Parser
191 216
192 var atomicTypes = {"atom": true, "number": true, "variable": true, "string": t rue, "regexp": true, "this": true}; 217 var atomicTypes = {"atom": true, "number": true, "variable": true, "string": t rue, "regexp": true, "this": true, "jsonld-keyword": true};
193 218
194 function JSLexical(indented, column, type, align, prev, info) { 219 function JSLexical(indented, column, type, align, prev, info) {
195 this.indented = indented; 220 this.indented = indented;
196 this.column = column; 221 this.column = column;
197 this.type = type; 222 this.type = type;
198 this.prev = prev; 223 this.prev = prev;
199 this.info = info; 224 this.info = info;
200 if (align != null) this.align = align; 225 if (align != null) this.align = align;
201 } 226 }
202 227
203 function inScope(state, varname) { 228 function inScope(state, varname) {
204 for (var v = state.localVars; v; v = v.next) 229 for (var v = state.localVars; v; v = v.next)
205 if (v.name == varname) return true; 230 if (v.name == varname) return true;
206 for (var cx = state.context; cx; cx = cx.prev) { 231 for (var cx = state.context; cx; cx = cx.prev) {
207 for (var v = cx.vars; v; v = v.next) 232 for (var v = cx.vars; v; v = v.next)
208 if (v.name == varname) return true; 233 if (v.name == varname) return true;
209 } 234 }
210 } 235 }
211 236
212 function parseJS(state, style, type, content, stream) { 237 function parseJS(state, style, type, content, stream) {
213 var cc = state.cc; 238 var cc = state.cc;
214 // Communicate our context to the combinators. 239 // Communicate our context to the combinators.
215 // (Less wasteful than consing up a hundred closures on every call.) 240 // (Less wasteful than consing up a hundred closures on every call.)
216 cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; 241 cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style;
217 242
218 if (!state.lexical.hasOwnProperty("align")) 243 if (!state.lexical.hasOwnProperty("align"))
219 state.lexical.align = true; 244 state.lexical.align = true;
220 245
221 while(true) { 246 while(true) {
222 var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement; 247 var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
223 if (combinator(type, content)) { 248 if (combinator(type, content)) {
224 while(cc.length && cc[cc.length - 1].lex) 249 while(cc.length && cc[cc.length - 1].lex)
225 cc.pop()(); 250 cc.pop()();
226 if (cx.marked) return cx.marked; 251 if (cx.marked) return cx.marked;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 var state = cx.state; 307 var state = cx.state;
283 if (state.lexical.prev) { 308 if (state.lexical.prev) {
284 if (state.lexical.type == ")") 309 if (state.lexical.type == ")")
285 state.indented = state.lexical.indented; 310 state.indented = state.lexical.indented;
286 state.lexical = state.lexical.prev; 311 state.lexical = state.lexical.prev;
287 } 312 }
288 } 313 }
289 poplex.lex = true; 314 poplex.lex = true;
290 315
291 function expect(wanted) { 316 function expect(wanted) {
292 return function(type) { 317 function exp(type) {
293 if (type == wanted) return cont(); 318 if (type == wanted) return cont();
294 else if (wanted == ";") return pass(); 319 else if (wanted == ";") return pass();
295 else return cont(arguments.callee); 320 else return cont(exp);
296 }; 321 };
322 return exp;
297 } 323 }
298 324
299 function statement(type, value) { 325 function statement(type, value) {
300 if (type == "var") return cont(pushlex("vardef", value.length), vardef, expe ct(";"), poplex); 326 if (type == "var") return cont(pushlex("vardef", value.length), vardef, expe ct(";"), poplex);
301 if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex); 327 if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
302 if (type == "keyword b") return cont(pushlex("form"), statement, poplex); 328 if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
303 if (type == "{") return cont(pushlex("}"), block, poplex); 329 if (type == "{") return cont(pushlex("}"), block, poplex);
304 if (type == ";") return cont(); 330 if (type == ";") return cont();
305 if (type == "if") return cont(pushlex("form"), expression, statement, poplex , maybeelse); 331 if (type == "if") {
332 if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
333 cx.state.cc.pop()();
334 return cont(pushlex("form"), expression, statement, poplex, maybeelse);
335 }
306 if (type == "function") return cont(functiondef); 336 if (type == "function") return cont(functiondef);
307 if (type == "for") return cont(pushlex("form"), forspec, poplex, statement, poplex); 337 if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
308 if (type == "variable") return cont(pushlex("stat"), maybelabel); 338 if (type == "variable") return cont(pushlex("stat"), maybelabel);
309 if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), 339 if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
310 block, poplex, poplex); 340 block, poplex, poplex);
311 if (type == "case") return cont(expression, expect(":")); 341 if (type == "case") return cont(expression, expect(":"));
312 if (type == "default") return cont(expect(":")); 342 if (type == "default") return cont(expect(":"));
313 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), 343 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
314 statement, poplex, popcontext); 344 statement, poplex, popcontext);
315 if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex); 345 if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex);
316 if (type == "class") return cont(pushlex("form"), className, objlit, poplex) ; 346 if (type == "class") return cont(pushlex("form"), className, poplex);
317 if (type == "export") return cont(pushlex("form"), afterExport, poplex); 347 if (type == "export") return cont(pushlex("form"), afterExport, poplex);
318 if (type == "import") return cont(pushlex("form"), afterImport, poplex); 348 if (type == "import") return cont(pushlex("form"), afterImport, poplex);
319 return pass(pushlex("stat"), expression, expect(";"), poplex); 349 return pass(pushlex("stat"), expression, expect(";"), poplex);
320 } 350 }
321 function expression(type) { 351 function expression(type) {
322 return expressionInner(type, false); 352 return expressionInner(type, false);
323 } 353 }
324 function expressionNoComma(type) { 354 function expressionNoComma(type) {
325 return expressionInner(type, true); 355 return expressionInner(type, true);
326 } 356 }
327 function expressionInner(type, noComma) { 357 function expressionInner(type, noComma) {
328 if (cx.state.fatArrowAt == cx.stream.start) { 358 if (cx.state.fatArrowAt == cx.stream.start) {
329 var body = noComma ? arrowBodyNoComma : arrowBody; 359 var body = noComma ? arrowBodyNoComma : arrowBody;
330 if (type == "(") return cont(pushcontext, commasep(pattern, ")"), expect(" =>"), body, popcontext); 360 if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext);
331 else if (type == "variable") return pass(pushcontext, pattern, expect("=>" ), body, popcontext); 361 else if (type == "variable") return pass(pushcontext, pattern, expect("=>" ), body, popcontext);
332 } 362 }
333 363
334 var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; 364 var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
335 if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); 365 if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
336 if (type == "function") return cont(functiondef); 366 if (type == "function") return cont(functiondef, maybeop);
337 if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : mayb eexpression); 367 if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : mayb eexpression);
338 if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, e xpect(")"), poplex, maybeop); 368 if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, e xpect(")"), poplex, maybeop);
339 if (type == "operator" || type == "spread") return cont(noComma ? expression NoComma : expression); 369 if (type == "operator" || type == "spread") return cont(noComma ? expression NoComma : expression);
340 if (type == "[") return cont(pushlex("]"), expressionNoComma, maybeArrayComp rehension, poplex, maybeop); 370 if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
341 if (type == "{") return cont(commasep(objprop, "}"), maybeop); 371 if (type == "{") return contCommasep(objprop, "}", null, maybeop);
372 if (type == "quasi") { return pass(quasi, maybeop); }
342 return cont(); 373 return cont();
343 } 374 }
344 function maybeexpression(type) { 375 function maybeexpression(type) {
345 if (type.match(/[;\}\)\],]/)) return pass(); 376 if (type.match(/[;\}\)\],]/)) return pass();
346 return pass(expression); 377 return pass(expression);
347 } 378 }
348 function maybeexpressionNoComma(type) { 379 function maybeexpressionNoComma(type) {
349 if (type.match(/[;\}\)\],]/)) return pass(); 380 if (type.match(/[;\}\)\],]/)) return pass();
350 return pass(expressionNoComma); 381 return pass(expressionNoComma);
351 } 382 }
352 383
353 function maybeoperatorComma(type, value) { 384 function maybeoperatorComma(type, value) {
354 if (type == ",") return cont(expression); 385 if (type == ",") return cont(expression);
355 return maybeoperatorNoComma(type, value, false); 386 return maybeoperatorNoComma(type, value, false);
356 } 387 }
357 function maybeoperatorNoComma(type, value, noComma) { 388 function maybeoperatorNoComma(type, value, noComma) {
358 var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma; 389 var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
359 var expr = noComma == false ? expression : expressionNoComma; 390 var expr = noComma == false ? expression : expressionNoComma;
360 if (value == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arr owBody, popcontext); 391 if (value == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arr owBody, popcontext);
361 if (type == "operator") { 392 if (type == "operator") {
362 if (/\+\+|--/.test(value)) return cont(me); 393 if (/\+\+|--/.test(value)) return cont(me);
363 if (value == "?") return cont(expression, expect(":"), expr); 394 if (value == "?") return cont(expression, expect(":"), expr);
364 return cont(expr); 395 return cont(expr);
365 } 396 }
366 if (type == "quasi") { cx.cc.push(me); return quasi(value); } 397 if (type == "quasi") { return pass(quasi, me); }
367 if (type == ";") return; 398 if (type == ";") return;
368 if (type == "(") return cont(commasep(expressionNoComma, ")", "call"), me); 399 if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
369 if (type == ".") return cont(property, me); 400 if (type == ".") return cont(property, me);
370 if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), pop lex, me); 401 if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), pop lex, me);
371 } 402 }
372 function quasi(value) { 403 function quasi(type, value) {
373 if (!value) debugger; 404 if (type != "quasi") return pass();
374 if (value.slice(value.length - 2) != "${") return cont(); 405 if (value.slice(value.length - 2) != "${") return cont(quasi);
375 return cont(expression, continueQuasi); 406 return cont(expression, continueQuasi);
376 } 407 }
377 function continueQuasi(type) { 408 function continueQuasi(type) {
378 if (type == "}") { 409 if (type == "}") {
379 cx.marked = "string-2"; 410 cx.marked = "string-2";
380 cx.state.tokenize = tokenQuasi; 411 cx.state.tokenize = tokenQuasi;
381 return cont(); 412 return cont(quasi);
382 } 413 }
383 } 414 }
384 function arrowBody(type) { 415 function arrowBody(type) {
385 findFatArrow(cx.stream, cx.state); 416 findFatArrow(cx.stream, cx.state);
386 if (type == "{") return pass(statement); 417 if (type == "{") return pass(statement);
387 return pass(expression); 418 return pass(expression);
388 } 419 }
389 function arrowBodyNoComma(type) { 420 function arrowBodyNoComma(type) {
390 findFatArrow(cx.stream, cx.state); 421 findFatArrow(cx.stream, cx.state);
391 if (type == "{") return pass(statement); 422 if (type == "{") return pass(statement);
392 return pass(expressionNoComma); 423 return pass(expressionNoComma);
393 } 424 }
394 function maybelabel(type) { 425 function maybelabel(type) {
395 if (type == ":") return cont(poplex, statement); 426 if (type == ":") return cont(poplex, statement);
396 return pass(maybeoperatorComma, expect(";"), poplex); 427 return pass(maybeoperatorComma, expect(";"), poplex);
397 } 428 }
398 function property(type) { 429 function property(type) {
399 if (type == "variable") {cx.marked = "property"; return cont();} 430 if (type == "variable") {cx.marked = "property"; return cont();}
400 } 431 }
401 function objprop(type, value) { 432 function objprop(type, value) {
402 if (type == "variable") { 433 if (type == "variable" || cx.style == "keyword") {
403 cx.marked = "property"; 434 cx.marked = "property";
404 if (value == "get" || value == "set") return cont(getterSetter); 435 if (value == "get" || value == "set") return cont(getterSetter);
436 return cont(afterprop);
405 } else if (type == "number" || type == "string") { 437 } else if (type == "number" || type == "string") {
406 cx.marked = type + " property"; 438 cx.marked = jsonldMode ? "property" : (cx.style + " property");
439 return cont(afterprop);
440 } else if (type == "jsonld-keyword") {
441 return cont(afterprop);
407 } else if (type == "[") { 442 } else if (type == "[") {
408 return cont(expression, expect("]"), afterprop); 443 return cont(expression, expect("]"), afterprop);
409 } 444 }
410 if (atomicTypes.hasOwnProperty(type)) return cont(afterprop);
411 } 445 }
412 function getterSetter(type) { 446 function getterSetter(type) {
413 if (type != "variable") return pass(afterprop); 447 if (type != "variable") return pass(afterprop);
414 cx.marked = "property"; 448 cx.marked = "property";
415 return cont(functiondef); 449 return cont(functiondef);
416 } 450 }
417 function afterprop(type) { 451 function afterprop(type) {
418 if (type == ":") return cont(expressionNoComma); 452 if (type == ":") return cont(expressionNoComma);
419 if (type == "(") return pass(functiondef); 453 if (type == "(") return pass(functiondef);
420 } 454 }
421 function commasep(what, end, info) { 455 function commasep(what, end) {
422 function proceed(type) { 456 function proceed(type) {
423 if (type == ",") { 457 if (type == ",") {
424 var lex = cx.state.lexical; 458 var lex = cx.state.lexical;
425 if (lex.info == "call") lex.pos = (lex.pos || 0) + 1; 459 if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
426 return cont(what, proceed); 460 return cont(what, proceed);
427 } 461 }
428 if (type == end) return cont(); 462 if (type == end) return cont();
429 return cont(expect(end)); 463 return cont(expect(end));
430 } 464 }
431 return function(type) { 465 return function(type) {
432 if (type == end) return cont(); 466 if (type == end) return cont();
433 if (info === false) return pass(what, proceed); 467 return pass(what, proceed);
434 return pass(pushlex(end, info), what, proceed, poplex);
435 }; 468 };
436 } 469 }
470 function contCommasep(what, end, info) {
471 for (var i = 3; i < arguments.length; i++)
472 cx.cc.push(arguments[i]);
473 return cont(pushlex(end, info), commasep(what, end), poplex);
474 }
437 function block(type) { 475 function block(type) {
438 if (type == "}") return cont(); 476 if (type == "}") return cont();
439 return pass(statement, block); 477 return pass(statement, block);
440 } 478 }
441 function maybetype(type) { 479 function maybetype(type) {
442 if (isTS && type == ":") return cont(typedef); 480 if (isTS && type == ":") return cont(typedef);
443 } 481 }
444 function typedef(type) { 482 function typedef(type) {
445 if (type == "variable"){cx.marked = "variable-3"; return cont();} 483 if (type == "variable"){cx.marked = "variable-3"; return cont();}
446 } 484 }
447 function vardef() { 485 function vardef() {
448 return pass(pattern, maybetype, maybeAssign, vardefCont); 486 return pass(pattern, maybetype, maybeAssign, vardefCont);
449 } 487 }
450 function pattern(type, value) { 488 function pattern(type, value) {
451 if (type == "variable") { register(value); return cont(); } 489 if (type == "variable") { register(value); return cont(); }
452 if (type == "[") return cont(commasep(pattern, "]")); 490 if (type == "[") return contCommasep(pattern, "]");
453 if (type == "{") return cont(commasep(proppattern, "}")); 491 if (type == "{") return contCommasep(proppattern, "}");
454 } 492 }
455 function proppattern(type, value) { 493 function proppattern(type, value) {
456 if (type == "variable" && !cx.stream.match(/^\s*:/, false)) { 494 if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
457 register(value); 495 register(value);
458 return cont(maybeAssign); 496 return cont(maybeAssign);
459 } 497 }
460 if (type == "variable") cx.marked = "property"; 498 if (type == "variable") cx.marked = "property";
461 return cont(expect(":"), pattern, maybeAssign); 499 return cont(expect(":"), pattern, maybeAssign);
462 } 500 }
463 function maybeAssign(_type, value) { 501 function maybeAssign(_type, value) {
464 if (value == "=") return cont(expressionNoComma); 502 if (value == "=") return cont(expressionNoComma);
465 } 503 }
466 function vardefCont(type) { 504 function vardefCont(type) {
467 if (type == ",") return cont(vardef); 505 if (type == ",") return cont(vardef);
468 } 506 }
469 function maybeelse(type, value) { 507 function maybeelse(type, value) {
470 if (type == "keyword b" && value == "else") return cont(pushlex("form"), sta tement, poplex); 508 if (type == "keyword b" && value == "else") return cont(pushlex("form", "els e"), statement, poplex);
471 } 509 }
472 function forspec(type) { 510 function forspec(type) {
473 if (type == "(") return cont(pushlex(")"), forspec1, expect(")")); 511 if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
474 } 512 }
475 function forspec1(type) { 513 function forspec1(type) {
476 if (type == "var") return cont(vardef, expect(";"), forspec2); 514 if (type == "var") return cont(vardef, expect(";"), forspec2);
477 if (type == ";") return cont(forspec2); 515 if (type == ";") return cont(forspec2);
478 if (type == "variable") return cont(formaybeinof); 516 if (type == "variable") return cont(formaybeinof);
479 return pass(expression, expect(";"), forspec2); 517 return pass(expression, expect(";"), forspec2);
480 } 518 }
481 function formaybeinof(_type, value) { 519 function formaybeinof(_type, value) {
482 if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(exp ression); } 520 if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(exp ression); }
483 return cont(maybeoperatorComma, forspec2); 521 return cont(maybeoperatorComma, forspec2);
484 } 522 }
485 function forspec2(type, value) { 523 function forspec2(type, value) {
486 if (type == ";") return cont(forspec3); 524 if (type == ";") return cont(forspec3);
487 if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(exp ression); } 525 if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(exp ression); }
488 return pass(expression, expect(";"), forspec3); 526 return pass(expression, expect(";"), forspec3);
489 } 527 }
490 function forspec3(type) { 528 function forspec3(type) {
491 if (type != ")") cont(expression); 529 if (type != ")") cont(expression);
492 } 530 }
493 function functiondef(type, value) { 531 function functiondef(type, value) {
494 if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} 532 if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
495 if (type == "variable") {register(value); return cont(functiondef);} 533 if (type == "variable") {register(value); return cont(functiondef);}
496 if (type == "(") return cont(pushcontext, commasep(funarg, ")"), statement, popcontext); 534 if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")" ), poplex, statement, popcontext);
497 } 535 }
498 function funarg(type) { 536 function funarg(type) {
499 if (type == "spread") return cont(funarg); 537 if (type == "spread") return cont(funarg);
500 return pass(pattern, maybetype); 538 return pass(pattern, maybetype);
501 } 539 }
502 function className(type, value) { 540 function className(type, value) {
503 if (type == "variable") {register(value); return cont(classNameAfter);} 541 if (type == "variable") {register(value); return cont(classNameAfter);}
504 } 542 }
505 function classNameAfter(_type, value) { 543 function classNameAfter(type, value) {
506 if (value == "extends") return cont(expression); 544 if (value == "extends") return cont(expression, classNameAfter);
545 if (type == "{") return cont(pushlex("}"), classBody, poplex);
507 } 546 }
508 function objlit(type) { 547 function classBody(type, value) {
509 if (type == "{") return cont(commasep(objprop, "}")); 548 if (type == "variable" || cx.style == "keyword") {
549 cx.marked = "property";
550 if (value == "get" || value == "set") return cont(classGetterSetter, funct iondef, classBody);
551 return cont(functiondef, classBody);
552 }
553 if (value == "*") {
554 cx.marked = "keyword";
555 return cont(classBody);
556 }
557 if (type == ";") return cont(classBody);
558 if (type == "}") return cont();
559 }
560 function classGetterSetter(type) {
561 if (type != "variable") return pass();
562 cx.marked = "property";
563 return cont();
510 } 564 }
511 function afterModule(type, value) { 565 function afterModule(type, value) {
512 if (type == "string") return cont(statement); 566 if (type == "string") return cont(statement);
513 if (type == "variable") { register(value); return cont(maybeFrom); } 567 if (type == "variable") { register(value); return cont(maybeFrom); }
514 } 568 }
515 function afterExport(_type, value) { 569 function afterExport(_type, value) {
516 if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";" )); } 570 if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";" )); }
517 if (value == "default") { cx.marked = "keyword"; return cont(expression, exp ect(";")); } 571 if (value == "default") { cx.marked = "keyword"; return cont(expression, exp ect(";")); }
518 return pass(statement); 572 return pass(statement);
519 } 573 }
520 function afterImport(type) { 574 function afterImport(type) {
521 if (type == "string") return cont(); 575 if (type == "string") return cont();
522 return pass(importSpec, maybeFrom); 576 return pass(importSpec, maybeFrom);
523 } 577 }
524 function importSpec(type, value) { 578 function importSpec(type, value) {
525 if (type == "{") return cont(commasep(importSpec, "}")); 579 if (type == "{") return contCommasep(importSpec, "}");
526 if (type == "variable") register(value); 580 if (type == "variable") register(value);
527 return cont(); 581 return cont();
528 } 582 }
529 function maybeFrom(_type, value) { 583 function maybeFrom(_type, value) {
530 if (value == "from") { cx.marked = "keyword"; return cont(expression); } 584 if (value == "from") { cx.marked = "keyword"; return cont(expression); }
531 } 585 }
586 function arrayLiteral(type) {
587 if (type == "]") return cont();
588 return pass(expressionNoComma, maybeArrayComprehension);
589 }
532 function maybeArrayComprehension(type) { 590 function maybeArrayComprehension(type) {
533 if (type == "for") return pass(comprehension); 591 if (type == "for") return pass(comprehension, expect("]"));
534 if (type == ",") return cont(commasep(expressionNoComma, "]", false)); 592 if (type == ",") return cont(commasep(expressionNoComma, "]"));
535 return pass(commasep(expressionNoComma, "]", false)); 593 return pass(commasep(expressionNoComma, "]"));
536 } 594 }
537 function comprehension(type) { 595 function comprehension(type) {
538 if (type == "for") return cont(forspec, comprehension); 596 if (type == "for") return cont(forspec, comprehension);
539 if (type == "if") return cont(expression, comprehension); 597 if (type == "if") return cont(expression, comprehension);
540 } 598 }
541 599
542 // Interface 600 // Interface
543 601
544 return { 602 return {
545 startState: function(basecolumn) { 603 startState: function(basecolumn) {
546 var state = { 604 var state = {
547 tokenize: tokenBase, 605 tokenize: tokenBase,
548 lastType: "sof", 606 lastType: "sof",
549 cc: [], 607 cc: [],
550 lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false ), 608 lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false ),
551 localVars: parserConfig.localVars, 609 localVars: parserConfig.localVars,
552 context: parserConfig.localVars && {vars: parserConfig.localVars}, 610 context: parserConfig.localVars && {vars: parserConfig.localVars},
553 indented: 0 611 indented: 0
554 }; 612 };
555 if (parserConfig.globalVars) state.globalVars = parserConfig.globalVars; 613 if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
614 state.globalVars = parserConfig.globalVars;
556 return state; 615 return state;
557 }, 616 },
558 617
559 token: function(stream, state) { 618 token: function(stream, state) {
560 if (stream.sol()) { 619 if (stream.sol()) {
561 if (!state.lexical.hasOwnProperty("align")) 620 if (!state.lexical.hasOwnProperty("align"))
562 state.lexical.align = false; 621 state.lexical.align = false;
563 state.indented = stream.indentation(); 622 state.indented = stream.indentation();
564 findFatArrow(stream, state); 623 findFatArrow(stream, state);
565 } 624 }
566 if (state.tokenize != tokenComment && stream.eatSpace()) return null; 625 if (state.tokenize != tokenComment && stream.eatSpace()) return null;
567 var style = state.tokenize(stream, state); 626 var style = state.tokenize(stream, state);
568 if (type == "comment") return style; 627 if (type == "comment") return style;
569 state.lastType = type == "operator" && (content == "++" || content == "--" ) ? "incdec" : type; 628 state.lastType = type == "operator" && (content == "++" || content == "--" ) ? "incdec" : type;
570 return parseJS(state, style, type, content, stream); 629 return parseJS(state, style, type, content, stream);
571 }, 630 },
572 631
573 indent: function(state, textAfter) { 632 indent: function(state, textAfter) {
574 if (state.tokenize == tokenComment) return CodeMirror.Pass; 633 if (state.tokenize == tokenComment) return CodeMirror.Pass;
575 if (state.tokenize != tokenBase) return 0; 634 if (state.tokenize != tokenBase) return 0;
576 var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical; 635 var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
577 // Kludge to prevent 'maybelse' from blocking lexical scope pops 636 // Kludge to prevent 'maybelse' from blocking lexical scope pops
578 for (var i = state.cc.length - 1; i >= 0; --i) { 637 if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {
579 var c = state.cc[i]; 638 var c = state.cc[i];
580 if (c == poplex) lexical = lexical.prev; 639 if (c == poplex) lexical = lexical.prev;
581 else if (c != maybeelse) break; 640 else if (c != maybeelse) break;
582 } 641 }
583 if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev; 642 if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
584 if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat") 643 if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
585 lexical = lexical.prev; 644 lexical = lexical.prev;
586 var type = lexical.type, closing = firstChar == type; 645 var type = lexical.type, closing = firstChar == type;
587 646
588 if (type == "vardef") return lexical.indented + (state.lastType == "operat or" || state.lastType == "," ? lexical.info + 1 : 0); 647 if (type == "vardef") return lexical.indented + (state.lastType == "operat or" || state.lastType == "," ? lexical.info + 1 : 0);
589 else if (type == "form" && firstChar == "{") return lexical.indented; 648 else if (type == "form" && firstChar == "{") return lexical.indented;
590 else if (type == "form") return lexical.indented + indentUnit; 649 else if (type == "form") return lexical.indented + indentUnit;
591 else if (type == "stat") 650 else if (type == "stat")
592 return lexical.indented + (state.lastType == "operator" || state.lastTyp e == "," ? statementIndent || indentUnit : 0); 651 return lexical.indented + (state.lastType == "operator" || state.lastTyp e == "," ? statementIndent || indentUnit : 0);
593 else if (lexical.info == "switch" && !closing && parserConfig.doubleIndent Switch != false) 652 else if (lexical.info == "switch" && !closing && parserConfig.doubleIndent Switch != false)
594 return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? inden tUnit : 2 * indentUnit); 653 return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? inden tUnit : 2 * indentUnit);
595 else if (lexical.align) return lexical.column + (closing ? 0 : 1); 654 else if (lexical.align) return lexical.column + (closing ? 0 : 1);
596 else return lexical.indented + (closing ? 0 : indentUnit); 655 else return lexical.indented + (closing ? 0 : indentUnit);
597 }, 656 },
598 657
599 electricChars: ":{}", 658 electricChars: ":{}",
600 blockCommentStart: jsonMode ? null : "/*", 659 blockCommentStart: jsonMode ? null : "/*",
601 blockCommentEnd: jsonMode ? null : "*/", 660 blockCommentEnd: jsonMode ? null : "*/",
602 lineComment: jsonMode ? null : "//", 661 lineComment: jsonMode ? null : "//",
603 fold: "brace", 662 fold: "brace",
604 663
605 helperType: jsonMode ? "json" : "javascript", 664 helperType: jsonMode ? "json" : "javascript",
665 jsonldMode: jsonldMode,
606 jsonMode: jsonMode 666 jsonMode: jsonMode
607 }; 667 };
608 }); 668 });
609 669
670 CodeMirror.registerHelper("wordChars", "javascript", /[\\w$]/);
671
610 CodeMirror.defineMIME("text/javascript", "javascript"); 672 CodeMirror.defineMIME("text/javascript", "javascript");
611 CodeMirror.defineMIME("text/ecmascript", "javascript"); 673 CodeMirror.defineMIME("text/ecmascript", "javascript");
612 CodeMirror.defineMIME("application/javascript", "javascript"); 674 CodeMirror.defineMIME("application/javascript", "javascript");
675 CodeMirror.defineMIME("application/x-javascript", "javascript");
613 CodeMirror.defineMIME("application/ecmascript", "javascript"); 676 CodeMirror.defineMIME("application/ecmascript", "javascript");
614 CodeMirror.defineMIME("application/json", {name: "javascript", json: true}); 677 CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
615 CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true}); 678 CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
679 CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true}) ;
616 CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true }); 680 CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
617 CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript : true }); 681 CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript : true });
682
683 });
OLDNEW
« no previous file with comments | « Source/devtools/front_end/cm/htmlmixed.js ('k') | Source/devtools/front_end/cm/markselection.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698