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

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

Issue 1296733002: DevTools: roll Codemirror JavaScript Mode to @7c3fb5cc (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 4 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 // TODO actually recognize syntax of TypeScript constructs 4 // TODO actually recognize syntax of TypeScript constructs
5 5
6 (function(mod) { 6 (function(mod) {
7 if (typeof exports == "object" && typeof module == "object") // CommonJS 7 if (typeof exports == "object" && typeof module == "object") // CommonJS
8 mod(require("../../lib/codemirror")); 8 mod(require("../../lib/codemirror"));
9 else if (typeof define == "function" && define.amd) // AMD 9 else if (typeof define == "function" && define.amd) // AMD
10 define(["../../lib/codemirror"], mod); 10 define(["../../lib/codemirror"], mod);
11 else // Plain browser env 11 else // Plain browser env
12 mod(CodeMirror); 12 mod(CodeMirror);
13 })(function(CodeMirror) { 13 })(function(CodeMirror) {
14 "use strict"; 14 "use strict";
15 15
16 CodeMirror.defineMode("javascript", function(config, parserConfig) { 16 CodeMirror.defineMode("javascript", function(config, parserConfig) {
17 var indentUnit = config.indentUnit; 17 var indentUnit = config.indentUnit;
18 var statementIndent = parserConfig.statementIndent; 18 var statementIndent = parserConfig.statementIndent;
19 var jsonldMode = parserConfig.jsonld; 19 var jsonldMode = parserConfig.jsonld;
20 var jsonMode = parserConfig.json || jsonldMode; 20 var jsonMode = parserConfig.json || jsonldMode;
21 var isTS = parserConfig.typescript; 21 var isTS = parserConfig.typescript;
22 var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/;
22 23
23 // Tokenizer 24 // Tokenizer
24 25
25 var keywords = function(){ 26 var keywords = function(){
26 function kw(type) {return {type: type, style: "keyword"};} 27 function kw(type) {return {type: type, style: "keyword"};}
27 var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"); 28 var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
28 var operator = kw("operator"), atom = {type: "atom", style: "atom"}; 29 var operator = kw("operator"), atom = {type: "atom", style: "atom"};
29 30
30 var jsKeywords = { 31 var jsKeywords = {
31 "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "fina lly": B, 32 "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "fina lly": B,
32 "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, "debugger": C, 33 "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, "debugger": C,
33 "var": kw("var"), "const": kw("var"), "let": kw("var"), 34 "var": kw("var"), "const": kw("var"), "let": kw("var"),
34 "function": kw("function"), "catch": kw("catch"), 35 "function": kw("function"), "catch": kw("catch"),
35 "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": k w("default"), 36 "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": k w("default"),
36 "in": operator, "typeof": operator, "instanceof": operator, 37 "in": operator, "typeof": operator, "instanceof": operator,
37 "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom, 38 "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
38 "this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"), 39 "this": kw("this"), "class": kw("class"), "super": kw("atom"),
39 "yield": C, "export": kw("export"), "import": kw("import"), "extends": C 40 "yield": C, "export": kw("export"), "import": kw("import"), "extends": C
40 }; 41 };
41 42
42 // Extend the 'normal' keywords with the TypeScript language extensions 43 // Extend the 'normal' keywords with the TypeScript language extensions
43 if (isTS) { 44 if (isTS) {
44 var type = {type: "variable", style: "variable-3"}; 45 var type = {type: "variable", style: "variable-3"};
45 var tsKeywords = { 46 var tsKeywords = {
46 // object-like things 47 // object-like things
47 "interface": kw("interface"), 48 "interface": kw("interface"),
48 "extends": kw("extends"), 49 "extends": kw("extends"),
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 } else if (ch == "/") { 111 } else if (ch == "/") {
111 if (stream.eat("*")) { 112 if (stream.eat("*")) {
112 state.tokenize = tokenComment; 113 state.tokenize = tokenComment;
113 return tokenComment(stream, state); 114 return tokenComment(stream, state);
114 } else if (stream.eat("/")) { 115 } else if (stream.eat("/")) {
115 stream.skipToEnd(); 116 stream.skipToEnd();
116 return ret("comment", "comment"); 117 return ret("comment", "comment");
117 } else if (state.lastType == "operator" || state.lastType == "keyword c" | | 118 } else if (state.lastType == "operator" || state.lastType == "keyword c" | |
118 state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) { 119 state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) {
119 readRegexp(stream); 120 readRegexp(stream);
120 stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla 121 stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
121 return ret("regexp", "string-2"); 122 return ret("regexp", "string-2");
122 } else { 123 } else {
123 stream.eatWhile(isOperatorChar); 124 stream.eatWhile(isOperatorChar);
124 return ret("operator", "operator", stream.current()); 125 return ret("operator", "operator", stream.current());
125 } 126 }
126 } else if (ch == "`") { 127 } else if (ch == "`") {
127 state.tokenize = tokenQuasi; 128 state.tokenize = tokenQuasi;
128 return tokenQuasi(stream, state); 129 return tokenQuasi(stream, state);
129 } else if (ch == "#") { 130 } else if (ch == "#") {
130 stream.skipToEnd(); 131 stream.skipToEnd();
131 return ret("error", "error"); 132 return ret("error", "error");
132 } else if (isOperatorChar.test(ch)) { 133 } else if (isOperatorChar.test(ch)) {
133 stream.eatWhile(isOperatorChar); 134 stream.eatWhile(isOperatorChar);
134 return ret("operator", "operator", stream.current()); 135 return ret("operator", "operator", stream.current());
135 } else { 136 } else if (wordRE.test(ch)) {
136 stream.eatWhile(/[\w\$_]/); 137 stream.eatWhile(wordRE);
137 var word = stream.current(), known = keywords.propertyIsEnumerable(word) & & keywords[word]; 138 var word = stream.current(), known = keywords.propertyIsEnumerable(word) & & keywords[word];
138 return (known && state.lastType != ".") ? ret(known.type, known.style, wor d) : 139 return (known && state.lastType != ".") ? ret(known.type, known.style, wor d) :
139 ret("variable", "variable", word); 140 ret("variable", "variable", word);
140 } 141 }
141 } 142 }
142 143
143 function tokenString(quote) { 144 function tokenString(quote) {
144 return function(stream, state) { 145 return function(stream, state) {
145 var escaped = false, next; 146 var escaped = false, next;
146 if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){ 147 if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 196
196 var depth = 0, sawSomething = false; 197 var depth = 0, sawSomething = false;
197 for (var pos = arrow - 1; pos >= 0; --pos) { 198 for (var pos = arrow - 1; pos >= 0; --pos) {
198 var ch = stream.string.charAt(pos); 199 var ch = stream.string.charAt(pos);
199 var bracket = brackets.indexOf(ch); 200 var bracket = brackets.indexOf(ch);
200 if (bracket >= 0 && bracket < 3) { 201 if (bracket >= 0 && bracket < 3) {
201 if (!depth) { ++pos; break; } 202 if (!depth) { ++pos; break; }
202 if (--depth == 0) break; 203 if (--depth == 0) break;
203 } else if (bracket >= 3 && bracket < 6) { 204 } else if (bracket >= 3 && bracket < 6) {
204 ++depth; 205 ++depth;
205 } else if (/[$\w]/.test(ch)) { 206 } else if (wordRE.test(ch)) {
206 sawSomething = true; 207 sawSomething = true;
208 } else if (/["'\/]/.test(ch)) {
209 return;
207 } else if (sawSomething && !depth) { 210 } else if (sawSomething && !depth) {
208 ++pos; 211 ++pos;
209 break; 212 break;
210 } 213 }
211 } 214 }
212 if (sawSomething && !depth) state.fatArrowAt = pos; 215 if (sawSomething && !depth) state.fatArrowAt = pos;
213 } 216 }
214 217
215 // Parser 218 // Parser
216 219
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 cx.state.localVars = defaultVars; 294 cx.state.localVars = defaultVars;
292 } 295 }
293 function popcontext() { 296 function popcontext() {
294 cx.state.localVars = cx.state.context.vars; 297 cx.state.localVars = cx.state.context.vars;
295 cx.state.context = cx.state.context.prev; 298 cx.state.context = cx.state.context.prev;
296 } 299 }
297 function pushlex(type, info) { 300 function pushlex(type, info) {
298 var result = function() { 301 var result = function() {
299 var state = cx.state, indent = state.indented; 302 var state = cx.state, indent = state.indented;
300 if (state.lexical.type == "stat") indent = state.lexical.indented; 303 if (state.lexical.type == "stat") indent = state.lexical.indented;
304 else for (var outer = state.lexical; outer && outer.type == ")" && outer.a lign; outer = outer.prev)
305 indent = outer.indented;
301 state.lexical = new JSLexical(indent, cx.stream.column(), type, null, stat e.lexical, info); 306 state.lexical = new JSLexical(indent, cx.stream.column(), type, null, stat e.lexical, info);
302 }; 307 };
303 result.lex = true; 308 result.lex = true;
304 return result; 309 return result;
305 } 310 }
306 function poplex() { 311 function poplex() {
307 var state = cx.state; 312 var state = cx.state;
308 if (state.lexical.prev) { 313 if (state.lexical.prev) {
309 if (state.lexical.type == ")") 314 if (state.lexical.type == ")")
310 state.indented = state.lexical.indented; 315 state.indented = state.lexical.indented;
(...skipping 24 matching lines...) Expand all
335 } 340 }
336 if (type == "function") return cont(functiondef); 341 if (type == "function") return cont(functiondef);
337 if (type == "for") return cont(pushlex("form"), forspec, statement, poplex); 342 if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
338 if (type == "variable") return cont(pushlex("stat"), maybelabel); 343 if (type == "variable") return cont(pushlex("stat"), maybelabel);
339 if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), 344 if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
340 block, poplex, poplex); 345 block, poplex, poplex);
341 if (type == "case") return cont(expression, expect(":")); 346 if (type == "case") return cont(expression, expect(":"));
342 if (type == "default") return cont(expect(":")); 347 if (type == "default") return cont(expect(":"));
343 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), 348 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
344 statement, poplex, popcontext); 349 statement, poplex, popcontext);
345 if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex);
346 if (type == "class") return cont(pushlex("form"), className, poplex); 350 if (type == "class") return cont(pushlex("form"), className, poplex);
347 if (type == "export") return cont(pushlex("form"), afterExport, poplex); 351 if (type == "export") return cont(pushlex("form"), afterExport, poplex);
348 if (type == "import") return cont(pushlex("form"), afterImport, poplex); 352 if (type == "import") return cont(pushlex("form"), afterImport, poplex);
349 return pass(pushlex("stat"), expression, expect(";"), poplex); 353 return pass(pushlex("stat"), expression, expect(";"), poplex);
350 } 354 }
351 function expression(type) { 355 function expression(type) {
352 return expressionInner(type, false); 356 return expressionInner(type, false);
353 } 357 }
354 function expressionNoComma(type) { 358 function expressionNoComma(type) {
355 return expressionInner(type, true); 359 return expressionInner(type, true);
(...skipping 25 matching lines...) Expand all
381 return pass(expressionNoComma); 385 return pass(expressionNoComma);
382 } 386 }
383 387
384 function maybeoperatorComma(type, value) { 388 function maybeoperatorComma(type, value) {
385 if (type == ",") return cont(expression); 389 if (type == ",") return cont(expression);
386 return maybeoperatorNoComma(type, value, false); 390 return maybeoperatorNoComma(type, value, false);
387 } 391 }
388 function maybeoperatorNoComma(type, value, noComma) { 392 function maybeoperatorNoComma(type, value, noComma) {
389 var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma; 393 var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
390 var expr = noComma == false ? expression : expressionNoComma; 394 var expr = noComma == false ? expression : expressionNoComma;
391 if (value == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arr owBody, popcontext); 395 if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arro wBody, popcontext);
392 if (type == "operator") { 396 if (type == "operator") {
393 if (/\+\+|--/.test(value)) return cont(me); 397 if (/\+\+|--/.test(value)) return cont(me);
394 if (value == "?") return cont(expression, expect(":"), expr); 398 if (value == "?") return cont(expression, expect(":"), expr);
395 return cont(expr); 399 return cont(expr);
396 } 400 }
397 if (type == "quasi") { return pass(quasi, me); } 401 if (type == "quasi") { return pass(quasi, me); }
398 if (type == ";") return; 402 if (type == ";") return;
399 if (type == "(") return contCommasep(expressionNoComma, ")", "call", me); 403 if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
400 if (type == ".") return cont(property, me); 404 if (type == ".") return cont(property, me);
401 if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), pop lex, me); 405 if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), pop lex, me);
402 } 406 }
403 function quasi(type, value) { 407 function quasi(type, value) {
404 if (type != "quasi") return pass(); 408 if (type != "quasi") return pass();
405 if (value.slice(value.length - 2) != "${") return cont(quasi); 409 if (value.slice(value.length - 2) != "${") return cont(quasi);
406 return cont(expression, continueQuasi); 410 return cont(expression, continueQuasi);
407 } 411 }
408 function continueQuasi(type) { 412 function continueQuasi(type) {
409 if (type == "}") { 413 if (type == "}") {
410 cx.marked = "string-2"; 414 cx.marked = "string-2";
411 cx.state.tokenize = tokenQuasi; 415 cx.state.tokenize = tokenQuasi;
412 return cont(quasi); 416 return cont(quasi);
413 } 417 }
414 } 418 }
415 function arrowBody(type) { 419 function arrowBody(type) {
416 findFatArrow(cx.stream, cx.state); 420 findFatArrow(cx.stream, cx.state);
417 if (type == "{") return pass(statement); 421 return pass(type == "{" ? statement : expression);
418 return pass(expression);
419 } 422 }
420 function arrowBodyNoComma(type) { 423 function arrowBodyNoComma(type) {
421 findFatArrow(cx.stream, cx.state); 424 findFatArrow(cx.stream, cx.state);
422 if (type == "{") return pass(statement); 425 return pass(type == "{" ? statement : expressionNoComma);
423 return pass(expressionNoComma);
424 } 426 }
425 function maybelabel(type) { 427 function maybelabel(type) {
426 if (type == ":") return cont(poplex, statement); 428 if (type == ":") return cont(poplex, statement);
427 return pass(maybeoperatorComma, expect(";"), poplex); 429 return pass(maybeoperatorComma, expect(";"), poplex);
428 } 430 }
429 function property(type) { 431 function property(type) {
430 if (type == "variable") {cx.marked = "property"; return cont();} 432 if (type == "variable") {cx.marked = "property"; return cont();}
431 } 433 }
432 function objprop(type, value) { 434 function objprop(type, value) {
433 if (type == "variable" || cx.style == "keyword") { 435 if (type == "variable" || cx.style == "keyword") {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 cx.cc.push(arguments[i]); 474 cx.cc.push(arguments[i]);
473 return cont(pushlex(end, info), commasep(what, end), poplex); 475 return cont(pushlex(end, info), commasep(what, end), poplex);
474 } 476 }
475 function block(type) { 477 function block(type) {
476 if (type == "}") return cont(); 478 if (type == "}") return cont();
477 return pass(statement, block); 479 return pass(statement, block);
478 } 480 }
479 function maybetype(type) { 481 function maybetype(type) {
480 if (isTS && type == ":") return cont(typedef); 482 if (isTS && type == ":") return cont(typedef);
481 } 483 }
484 function maybedefault(_, value) {
485 if (value == "=") return cont(expressionNoComma);
486 }
482 function typedef(type) { 487 function typedef(type) {
483 if (type == "variable"){cx.marked = "variable-3"; return cont();} 488 if (type == "variable") {cx.marked = "variable-3"; return cont();}
484 } 489 }
485 function vardef() { 490 function vardef() {
486 return pass(pattern, maybetype, maybeAssign, vardefCont); 491 return pass(pattern, maybetype, maybeAssign, vardefCont);
487 } 492 }
488 function pattern(type, value) { 493 function pattern(type, value) {
489 if (type == "variable") { register(value); return cont(); } 494 if (type == "variable") { register(value); return cont(); }
490 if (type == "[") return contCommasep(pattern, "]"); 495 if (type == "[") return contCommasep(pattern, "]");
491 if (type == "{") return contCommasep(proppattern, "}"); 496 if (type == "{") return contCommasep(proppattern, "}");
492 } 497 }
493 function proppattern(type, value) { 498 function proppattern(type, value) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 function forspec3(type) { 533 function forspec3(type) {
529 if (type != ")") cont(expression); 534 if (type != ")") cont(expression);
530 } 535 }
531 function functiondef(type, value) { 536 function functiondef(type, value) {
532 if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} 537 if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
533 if (type == "variable") {register(value); return cont(functiondef);} 538 if (type == "variable") {register(value); return cont(functiondef);}
534 if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")" ), poplex, statement, popcontext); 539 if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")" ), poplex, statement, popcontext);
535 } 540 }
536 function funarg(type) { 541 function funarg(type) {
537 if (type == "spread") return cont(funarg); 542 if (type == "spread") return cont(funarg);
538 return pass(pattern, maybetype); 543 return pass(pattern, maybetype, maybedefault);
539 } 544 }
540 function className(type, value) { 545 function className(type, value) {
541 if (type == "variable") {register(value); return cont(classNameAfter);} 546 if (type == "variable") {register(value); return cont(classNameAfter);}
542 } 547 }
543 function classNameAfter(type, value) { 548 function classNameAfter(type, value) {
544 if (value == "extends") return cont(expression, classNameAfter); 549 if (value == "extends") return cont(expression, classNameAfter);
545 if (type == "{") return cont(pushlex("}"), classBody, poplex); 550 if (type == "{") return cont(pushlex("}"), classBody, poplex);
546 } 551 }
547 function classBody(type, value) { 552 function classBody(type, value) {
548 if (type == "variable" || cx.style == "keyword") { 553 if (type == "variable" || cx.style == "keyword") {
554 if (value == "static") {
555 cx.marked = "keyword";
556 return cont(classBody);
557 }
549 cx.marked = "property"; 558 cx.marked = "property";
550 if (value == "get" || value == "set") return cont(classGetterSetter, funct iondef, classBody); 559 if (value == "get" || value == "set") return cont(classGetterSetter, funct iondef, classBody);
551 return cont(functiondef, classBody); 560 return cont(functiondef, classBody);
552 } 561 }
553 if (value == "*") { 562 if (value == "*") {
554 cx.marked = "keyword"; 563 cx.marked = "keyword";
555 return cont(classBody); 564 return cont(classBody);
556 } 565 }
557 if (type == ";") return cont(classBody); 566 if (type == ";") return cont(classBody);
558 if (type == "}") return cont(); 567 if (type == "}") return cont();
559 } 568 }
560 function classGetterSetter(type) { 569 function classGetterSetter(type) {
561 if (type != "variable") return pass(); 570 if (type != "variable") return pass();
562 cx.marked = "property"; 571 cx.marked = "property";
563 return cont(); 572 return cont();
564 } 573 }
565 function afterModule(type, value) {
566 if (type == "string") return cont(statement);
567 if (type == "variable") { register(value); return cont(maybeFrom); }
568 }
569 function afterExport(_type, value) { 574 function afterExport(_type, value) {
570 if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";" )); } 575 if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";" )); }
571 if (value == "default") { cx.marked = "keyword"; return cont(expression, exp ect(";")); } 576 if (value == "default") { cx.marked = "keyword"; return cont(expression, exp ect(";")); }
572 return pass(statement); 577 return pass(statement);
573 } 578 }
574 function afterImport(type) { 579 function afterImport(type) {
575 if (type == "string") return cont(); 580 if (type == "string") return cont();
576 return pass(importSpec, maybeFrom); 581 return pass(importSpec, maybeFrom);
577 } 582 }
578 function importSpec(type, value) { 583 function importSpec(type, value) {
579 if (type == "{") return contCommasep(importSpec, "}"); 584 if (type == "{") return contCommasep(importSpec, "}");
580 if (type == "variable") register(value); 585 if (type == "variable") register(value);
581 return cont(); 586 if (value == "*") cx.marked = "keyword";
587 return cont(maybeAs);
588 }
589 function maybeAs(_type, value) {
590 if (value == "as") { cx.marked = "keyword"; return cont(importSpec); }
582 } 591 }
583 function maybeFrom(_type, value) { 592 function maybeFrom(_type, value) {
584 if (value == "from") { cx.marked = "keyword"; return cont(expression); } 593 if (value == "from") { cx.marked = "keyword"; return cont(expression); }
585 } 594 }
586 function arrayLiteral(type) { 595 function arrayLiteral(type) {
587 if (type == "]") return cont(); 596 if (type == "]") return cont();
588 return pass(expressionNoComma, maybeArrayComprehension); 597 return pass(expressionNoComma, maybeArrayComprehension);
589 } 598 }
590 function maybeArrayComprehension(type) { 599 function maybeArrayComprehension(type) {
591 if (type == "for") return pass(comprehension, expect("]")); 600 if (type == "for") return pass(comprehension, expect("]"));
592 if (type == ",") return cont(commasep(expressionNoComma, "]")); 601 if (type == ",") return cont(commasep(maybeexpressionNoComma, "]"));
593 return pass(commasep(expressionNoComma, "]")); 602 return pass(commasep(expressionNoComma, "]"));
594 } 603 }
595 function comprehension(type) { 604 function comprehension(type) {
596 if (type == "for") return cont(forspec, comprehension); 605 if (type == "for") return cont(forspec, comprehension);
597 if (type == "if") return cont(expression, comprehension); 606 if (type == "if") return cont(expression, comprehension);
598 } 607 }
599 608
609 function isContinuedStatement(state, textAfter) {
610 return state.lastType == "operator" || state.lastType == "," ||
611 isOperatorChar.test(textAfter.charAt(0)) ||
612 /[,.]/.test(textAfter.charAt(0));
613 }
614
600 // Interface 615 // Interface
601 616
602 return { 617 return {
603 startState: function(basecolumn) { 618 startState: function(basecolumn) {
604 var state = { 619 var state = {
605 tokenize: tokenBase, 620 tokenize: tokenBase,
606 lastType: "sof", 621 lastType: "sof",
607 cc: [], 622 cc: [],
608 lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false ), 623 lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false ),
609 localVars: parserConfig.localVars, 624 localVars: parserConfig.localVars,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 } 656 }
642 if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev; 657 if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
643 if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat") 658 if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
644 lexical = lexical.prev; 659 lexical = lexical.prev;
645 var type = lexical.type, closing = firstChar == type; 660 var type = lexical.type, closing = firstChar == type;
646 661
647 if (type == "vardef") return lexical.indented + (state.lastType == "operat or" || state.lastType == "," ? lexical.info + 1 : 0); 662 if (type == "vardef") return lexical.indented + (state.lastType == "operat or" || state.lastType == "," ? lexical.info + 1 : 0);
648 else if (type == "form" && firstChar == "{") return lexical.indented; 663 else if (type == "form" && firstChar == "{") return lexical.indented;
649 else if (type == "form") return lexical.indented + indentUnit; 664 else if (type == "form") return lexical.indented + indentUnit;
650 else if (type == "stat") 665 else if (type == "stat")
651 return lexical.indented + (state.lastType == "operator" || state.lastTyp e == "," ? statementIndent || indentUnit : 0); 666 return lexical.indented + (isContinuedStatement(state, textAfter) ? stat ementIndent || indentUnit : 0);
652 else if (lexical.info == "switch" && !closing && parserConfig.doubleIndent Switch != false) 667 else if (lexical.info == "switch" && !closing && parserConfig.doubleIndent Switch != false)
653 return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? inden tUnit : 2 * indentUnit); 668 return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? inden tUnit : 2 * indentUnit);
654 else if (lexical.align) return lexical.column + (closing ? 0 : 1); 669 else if (lexical.align) return lexical.column + (closing ? 0 : 1);
655 else return lexical.indented + (closing ? 0 : indentUnit); 670 else return lexical.indented + (closing ? 0 : indentUnit);
656 }, 671 },
657 672
658 electricChars: ":{}", 673 electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
659 blockCommentStart: jsonMode ? null : "/*", 674 blockCommentStart: jsonMode ? null : "/*",
660 blockCommentEnd: jsonMode ? null : "*/", 675 blockCommentEnd: jsonMode ? null : "*/",
661 lineComment: jsonMode ? null : "//", 676 lineComment: jsonMode ? null : "//",
662 fold: "brace", 677 fold: "brace",
678 closeBrackets: "()[]{}''\"\"``",
663 679
664 helperType: jsonMode ? "json" : "javascript", 680 helperType: jsonMode ? "json" : "javascript",
665 jsonldMode: jsonldMode, 681 jsonldMode: jsonldMode,
666 jsonMode: jsonMode 682 jsonMode: jsonMode
667 }; 683 };
668 }); 684 });
669 685
670 CodeMirror.registerHelper("wordChars", "javascript", /[\\w$]/); 686 CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/);
671 687
672 CodeMirror.defineMIME("text/javascript", "javascript"); 688 CodeMirror.defineMIME("text/javascript", "javascript");
673 CodeMirror.defineMIME("text/ecmascript", "javascript"); 689 CodeMirror.defineMIME("text/ecmascript", "javascript");
674 CodeMirror.defineMIME("application/javascript", "javascript"); 690 CodeMirror.defineMIME("application/javascript", "javascript");
675 CodeMirror.defineMIME("application/x-javascript", "javascript"); 691 CodeMirror.defineMIME("application/x-javascript", "javascript");
676 CodeMirror.defineMIME("application/ecmascript", "javascript"); 692 CodeMirror.defineMIME("application/ecmascript", "javascript");
677 CodeMirror.defineMIME("application/json", {name: "javascript", json: true}); 693 CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
678 CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true}); 694 CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
679 CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true}) ; 695 CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true}) ;
680 CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true }); 696 CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
681 CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript : true }); 697 CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript : true });
682 698
683 }); 699 });
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698