| OLD | NEW |
| 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 | |
| 5 | |
| 6 (function(mod) { | 4 (function(mod) { |
| 7 if (typeof exports == "object" && typeof module == "object") // CommonJS | 5 if (typeof exports == "object" && typeof module == "object") // CommonJS |
| 8 mod(require("../../lib/codemirror")); | 6 mod(require("../../lib/codemirror")); |
| 9 else if (typeof define == "function" && define.amd) // AMD | 7 else if (typeof define == "function" && define.amd) // AMD |
| 10 define(["../../lib/codemirror"], mod); | 8 define(["../../lib/codemirror"], mod); |
| 11 else // Plain browser env | 9 else // Plain browser env |
| 12 mod(CodeMirror); | 10 mod(CodeMirror); |
| 13 })(function(CodeMirror) { | 11 })(function(CodeMirror) { |
| 14 "use strict"; | 12 "use strict"; |
| 15 | 13 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 // Extend the 'normal' keywords with the TypeScript language extensions | 47 // Extend the 'normal' keywords with the TypeScript language extensions |
| 50 if (isTS) { | 48 if (isTS) { |
| 51 var type = {type: "variable", style: "variable-3"}; | 49 var type = {type: "variable", style: "variable-3"}; |
| 52 var tsKeywords = { | 50 var tsKeywords = { |
| 53 // object-like things | 51 // object-like things |
| 54 "interface": kw("class"), | 52 "interface": kw("class"), |
| 55 "implements": C, | 53 "implements": C, |
| 56 "namespace": C, | 54 "namespace": C, |
| 57 "module": kw("module"), | 55 "module": kw("module"), |
| 58 "enum": kw("module"), | 56 "enum": kw("module"), |
| 57 "type": kw("type"), |
| 59 | 58 |
| 60 // scope modifiers | 59 // scope modifiers |
| 61 "public": kw("modifier"), | 60 "public": kw("modifier"), |
| 62 "private": kw("modifier"), | 61 "private": kw("modifier"), |
| 63 "protected": kw("modifier"), | 62 "protected": kw("modifier"), |
| 64 "abstract": kw("modifier"), | 63 "abstract": kw("modifier"), |
| 65 | 64 |
| 66 // operators | 65 // operators |
| 67 "as": operator, | 66 "as": operator, |
| 68 | 67 |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 // actually hit the arrow token. It only works if the arrow is on | 202 // actually hit the arrow token. It only works if the arrow is on |
| 204 // the same line as the arguments and there's no strange noise | 203 // the same line as the arguments and there's no strange noise |
| 205 // (comments) in between. Fallback is to only notice when we hit the | 204 // (comments) in between. Fallback is to only notice when we hit the |
| 206 // arrow, and not declare the arguments as locals for the arrow | 205 // arrow, and not declare the arguments as locals for the arrow |
| 207 // body. | 206 // body. |
| 208 function findFatArrow(stream, state) { | 207 function findFatArrow(stream, state) { |
| 209 if (state.fatArrowAt) state.fatArrowAt = null; | 208 if (state.fatArrowAt) state.fatArrowAt = null; |
| 210 var arrow = stream.string.indexOf("=>", stream.start); | 209 var arrow = stream.string.indexOf("=>", stream.start); |
| 211 if (arrow < 0) return; | 210 if (arrow < 0) return; |
| 212 | 211 |
| 212 if (isTS) { // Try to skip TypeScript return type declarations after the arg
uments |
| 213 var m = /:\s*(?:\w+(?:<[^>]*>|\[\])?|\{[^}]*\})\s*$/.exec(stream.string.sl
ice(stream.start, arrow)) |
| 214 if (m) arrow = m.index |
| 215 } |
| 216 |
| 213 var depth = 0, sawSomething = false; | 217 var depth = 0, sawSomething = false; |
| 214 for (var pos = arrow - 1; pos >= 0; --pos) { | 218 for (var pos = arrow - 1; pos >= 0; --pos) { |
| 215 var ch = stream.string.charAt(pos); | 219 var ch = stream.string.charAt(pos); |
| 216 var bracket = brackets.indexOf(ch); | 220 var bracket = brackets.indexOf(ch); |
| 217 if (bracket >= 0 && bracket < 3) { | 221 if (bracket >= 0 && bracket < 3) { |
| 218 if (!depth) { ++pos; break; } | 222 if (!depth) { ++pos; break; } |
| 219 if (--depth == 0) break; | 223 if (--depth == 0) { if (ch == "(") sawSomething = true; break; } |
| 220 } else if (bracket >= 3 && bracket < 6) { | 224 } else if (bracket >= 3 && bracket < 6) { |
| 221 ++depth; | 225 ++depth; |
| 222 } else if (wordRE.test(ch)) { | 226 } else if (wordRE.test(ch)) { |
| 223 sawSomething = true; | 227 sawSomething = true; |
| 224 } else if (/["'\/]/.test(ch)) { | 228 } else if (/["'\/]/.test(ch)) { |
| 225 return; | 229 return; |
| 226 } else if (sawSomething && !depth) { | 230 } else if (sawSomething && !depth) { |
| 227 ++pos; | 231 ++pos; |
| 228 break; | 232 break; |
| 229 } | 233 } |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 function exp(type) { | 342 function exp(type) { |
| 339 if (type == wanted) return cont(); | 343 if (type == wanted) return cont(); |
| 340 else if (wanted == ";") return pass(); | 344 else if (wanted == ";") return pass(); |
| 341 else return cont(exp); | 345 else return cont(exp); |
| 342 }; | 346 }; |
| 343 return exp; | 347 return exp; |
| 344 } | 348 } |
| 345 | 349 |
| 346 function statement(type, value) { | 350 function statement(type, value) { |
| 347 if (type == "var") return cont(pushlex("vardef", value.length), vardef, expe
ct(";"), poplex); | 351 if (type == "var") return cont(pushlex("vardef", value.length), vardef, expe
ct(";"), poplex); |
| 348 if (type == "keyword a") return cont(pushlex("form"), expression, statement,
poplex); | 352 if (type == "keyword a") return cont(pushlex("form"), parenExpr, statement,
poplex); |
| 349 if (type == "keyword b") return cont(pushlex("form"), statement, poplex); | 353 if (type == "keyword b") return cont(pushlex("form"), statement, poplex); |
| 350 if (type == "{") return cont(pushlex("}"), block, poplex); | 354 if (type == "{") return cont(pushlex("}"), block, poplex); |
| 351 if (type == ";") return cont(); | 355 if (type == ";") return cont(); |
| 352 if (type == "if") { | 356 if (type == "if") { |
| 353 if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1]
== poplex) | 357 if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1]
== poplex) |
| 354 cx.state.cc.pop()(); | 358 cx.state.cc.pop()(); |
| 355 return cont(pushlex("form"), expression, statement, poplex, maybeelse); | 359 return cont(pushlex("form"), parenExpr, statement, poplex, maybeelse); |
| 356 } | 360 } |
| 357 if (type == "function") return cont(functiondef); | 361 if (type == "function") return cont(functiondef); |
| 358 if (type == "for") return cont(pushlex("form"), forspec, statement, poplex); | 362 if (type == "for") return cont(pushlex("form"), forspec, statement, poplex); |
| 359 if (type == "variable") return cont(pushlex("stat"), maybelabel); | 363 if (type == "variable") return cont(pushlex("stat"), maybelabel); |
| 360 if (type == "switch") return cont(pushlex("form"), expression, pushlex("}",
"switch"), expect("{"), | 364 if (type == "switch") return cont(pushlex("form"), parenExpr, pushlex("}", "
switch"), expect("{"), |
| 361 block, poplex, poplex); | 365 block, poplex, poplex); |
| 362 if (type == "case") return cont(expression, expect(":")); | 366 if (type == "case") return cont(expression, expect(":")); |
| 363 if (type == "default") return cont(expect(":")); | 367 if (type == "default") return cont(expect(":")); |
| 364 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("),
funarg, expect(")"), | 368 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("),
funarg, expect(")"), |
| 365 statement, poplex, popcontext); | 369 statement, poplex, popcontext); |
| 366 if (type == "class") return cont(pushlex("form"), className, poplex); | 370 if (type == "class") return cont(pushlex("form"), className, poplex); |
| 367 if (type == "export") return cont(pushlex("stat"), afterExport, poplex); | 371 if (type == "export") return cont(pushlex("stat"), afterExport, poplex); |
| 368 if (type == "import") return cont(pushlex("stat"), afterImport, poplex); | 372 if (type == "import") return cont(pushlex("stat"), afterImport, poplex); |
| 369 if (type == "module") return cont(pushlex("form"), pattern, pushlex("}"), ex
pect("{"), block, poplex, poplex) | 373 if (type == "module") return cont(pushlex("form"), pattern, pushlex("}"), ex
pect("{"), block, poplex, poplex) |
| 374 if (type == "type") return cont(typeexpr, expect("operator"), typeexpr, expe
ct(";")); |
| 370 if (type == "async") return cont(statement) | 375 if (type == "async") return cont(statement) |
| 371 return pass(pushlex("stat"), expression, expect(";"), poplex); | 376 return pass(pushlex("stat"), expression, expect(";"), poplex); |
| 372 } | 377 } |
| 373 function expression(type) { | 378 function expression(type) { |
| 374 return expressionInner(type, false); | 379 return expressionInner(type, false); |
| 375 } | 380 } |
| 376 function expressionNoComma(type) { | 381 function expressionNoComma(type) { |
| 377 return expressionInner(type, true); | 382 return expressionInner(type, true); |
| 378 } | 383 } |
| 384 function parenExpr(type) { |
| 385 if (type != "(") return pass() |
| 386 return cont(pushlex(")"), expression, expect(")"), poplex) |
| 387 } |
| 379 function expressionInner(type, noComma) { | 388 function expressionInner(type, noComma) { |
| 380 if (cx.state.fatArrowAt == cx.stream.start) { | 389 if (cx.state.fatArrowAt == cx.stream.start) { |
| 381 var body = noComma ? arrowBodyNoComma : arrowBody; | 390 var body = noComma ? arrowBodyNoComma : arrowBody; |
| 382 if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern,
")"), poplex, expect("=>"), body, popcontext); | 391 if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern,
")"), poplex, expect("=>"), body, popcontext); |
| 383 else if (type == "variable") return pass(pushcontext, pattern, expect("=>"
), body, popcontext); | 392 else if (type == "variable") return pass(pushcontext, pattern, expect("=>"
), body, popcontext); |
| 384 } | 393 } |
| 385 | 394 |
| 386 var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; | 395 var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; |
| 387 if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); | 396 if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); |
| 388 if (type == "function") return cont(functiondef, maybeop); | 397 if (type == "function") return cont(functiondef, maybeop); |
| 398 if (type == "class") return cont(pushlex("form"), classExpression, poplex); |
| 389 if (type == "keyword c" || type == "async") return cont(noComma ? maybeexpre
ssionNoComma : maybeexpression); | 399 if (type == "keyword c" || type == "async") return cont(noComma ? maybeexpre
ssionNoComma : maybeexpression); |
| 390 if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), pop
lex, maybeop); | 400 if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), pop
lex, maybeop); |
| 391 if (type == "operator" || type == "spread") return cont(noComma ? expression
NoComma : expression); | 401 if (type == "operator" || type == "spread") return cont(noComma ? expression
NoComma : expression); |
| 392 if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop); | 402 if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop); |
| 393 if (type == "{") return contCommasep(objprop, "}", null, maybeop); | 403 if (type == "{") return contCommasep(objprop, "}", null, maybeop); |
| 394 if (type == "quasi") return pass(quasi, maybeop); | 404 if (type == "quasi") return pass(quasi, maybeop); |
| 395 if (type == "new") return cont(maybeTarget(noComma)); | 405 if (type == "new") return cont(maybeTarget(noComma)); |
| 396 return cont(); | 406 return cont(); |
| 397 } | 407 } |
| 398 function maybeexpression(type) { | 408 function maybeexpression(type) { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorNoC
omma); } | 466 if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorNoC
omma); } |
| 457 } | 467 } |
| 458 function maybelabel(type) { | 468 function maybelabel(type) { |
| 459 if (type == ":") return cont(poplex, statement); | 469 if (type == ":") return cont(poplex, statement); |
| 460 return pass(maybeoperatorComma, expect(";"), poplex); | 470 return pass(maybeoperatorComma, expect(";"), poplex); |
| 461 } | 471 } |
| 462 function property(type) { | 472 function property(type) { |
| 463 if (type == "variable") {cx.marked = "property"; return cont();} | 473 if (type == "variable") {cx.marked = "property"; return cont();} |
| 464 } | 474 } |
| 465 function objprop(type, value) { | 475 function objprop(type, value) { |
| 466 if (type == "async") return cont(objprop); | 476 if (type == "async") { |
| 467 if (type == "variable" || cx.style == "keyword") { | 477 cx.marked = "property"; |
| 478 return cont(objprop); |
| 479 } else if (type == "variable" || cx.style == "keyword") { |
| 468 cx.marked = "property"; | 480 cx.marked = "property"; |
| 469 if (value == "get" || value == "set") return cont(getterSetter); | 481 if (value == "get" || value == "set") return cont(getterSetter); |
| 470 return cont(afterprop); | 482 return cont(afterprop); |
| 471 } else if (type == "number" || type == "string") { | 483 } else if (type == "number" || type == "string") { |
| 472 cx.marked = jsonldMode ? "property" : (cx.style + " property"); | 484 cx.marked = jsonldMode ? "property" : (cx.style + " property"); |
| 473 return cont(afterprop); | 485 return cont(afterprop); |
| 474 } else if (type == "jsonld-keyword") { | 486 } else if (type == "jsonld-keyword") { |
| 475 return cont(afterprop); | 487 return cont(afterprop); |
| 476 } else if (type == "modifier") { | 488 } else if (type == "modifier") { |
| 477 return cont(objprop) | 489 return cont(objprop) |
| 478 } else if (type == "[") { | 490 } else if (type == "[") { |
| 479 return cont(expression, expect("]"), afterprop); | 491 return cont(expression, expect("]"), afterprop); |
| 480 } else if (type == "spread") { | 492 } else if (type == "spread") { |
| 481 return cont(expression); | 493 return cont(expression); |
| 494 } else if (type == ":") { |
| 495 return pass(afterprop) |
| 482 } | 496 } |
| 483 } | 497 } |
| 484 function getterSetter(type) { | 498 function getterSetter(type) { |
| 485 if (type != "variable") return pass(afterprop); | 499 if (type != "variable") return pass(afterprop); |
| 486 cx.marked = "property"; | 500 cx.marked = "property"; |
| 487 return cont(functiondef); | 501 return cont(functiondef); |
| 488 } | 502 } |
| 489 function afterprop(type) { | 503 function afterprop(type) { |
| 490 if (type == ":") return cont(expressionNoComma); | 504 if (type == ":") return cont(expressionNoComma); |
| 491 if (type == "(") return pass(functiondef); | 505 if (type == "(") return pass(functiondef); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 510 } | 524 } |
| 511 function contCommasep(what, end, info) { | 525 function contCommasep(what, end, info) { |
| 512 for (var i = 3; i < arguments.length; i++) | 526 for (var i = 3; i < arguments.length; i++) |
| 513 cx.cc.push(arguments[i]); | 527 cx.cc.push(arguments[i]); |
| 514 return cont(pushlex(end, info), commasep(what, end), poplex); | 528 return cont(pushlex(end, info), commasep(what, end), poplex); |
| 515 } | 529 } |
| 516 function block(type) { | 530 function block(type) { |
| 517 if (type == "}") return cont(); | 531 if (type == "}") return cont(); |
| 518 return pass(statement, block); | 532 return pass(statement, block); |
| 519 } | 533 } |
| 520 function maybetype(type) { | 534 function maybetype(type, value) { |
| 521 if (isTS && type == ":") return cont(typeexpr); | 535 if (isTS) { |
| 522 } | 536 if (type == ":") return cont(typeexpr); |
| 523 function maybedefault(_, value) { | 537 if (value == "?") return cont(maybetype); |
| 524 if (value == "=") return cont(expressionNoComma); | 538 } |
| 525 } | 539 } |
| 526 function typeexpr(type) { | 540 function typeexpr(type) { |
| 527 if (type == "variable") {cx.marked = "variable-3"; return cont(afterType);} | 541 if (type == "variable") {cx.marked = "variable-3"; return cont(afterType);} |
| 542 if (type == "{") return cont(commasep(typeprop, "}")) |
| 543 if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType) |
| 544 } |
| 545 function maybeReturnType(type) { |
| 546 if (type == "=>") return cont(typeexpr) |
| 547 } |
| 548 function typeprop(type) { |
| 549 if (type == "variable" || cx.style == "keyword") { |
| 550 cx.marked = "property" |
| 551 return cont(typeprop) |
| 552 } else if (type == ":") { |
| 553 return cont(typeexpr) |
| 554 } |
| 555 } |
| 556 function typearg(type) { |
| 557 if (type == "variable") return cont(typearg) |
| 558 else if (type == ":") return cont(typeexpr) |
| 528 } | 559 } |
| 529 function afterType(type, value) { | 560 function afterType(type, value) { |
| 530 if (value == "<") return cont(commasep(typeexpr, ">"), afterType) | 561 if (value == "<") return cont(commasep(typeexpr, ">"), afterType) |
| 531 if (type == "[") return cont(expect("]"), afterType) | 562 if (type == "[") return cont(expect("]"), afterType) |
| 532 } | 563 } |
| 533 function vardef() { | 564 function vardef() { |
| 534 return pass(pattern, maybetype, maybeAssign, vardefCont); | 565 return pass(pattern, maybetype, maybeAssign, vardefCont); |
| 535 } | 566 } |
| 536 function pattern(type, value) { | 567 function pattern(type, value) { |
| 537 if (type == "modifier") return cont(pattern) | 568 if (type == "modifier") return cont(pattern) |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 580 function forspec3(type) { | 611 function forspec3(type) { |
| 581 if (type != ")") cont(expression); | 612 if (type != ")") cont(expression); |
| 582 } | 613 } |
| 583 function functiondef(type, value) { | 614 function functiondef(type, value) { |
| 584 if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} | 615 if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} |
| 585 if (type == "variable") {register(value); return cont(functiondef);} | 616 if (type == "variable") {register(value); return cont(functiondef);} |
| 586 if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"
), poplex, maybetype, statement, popcontext); | 617 if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"
), poplex, maybetype, statement, popcontext); |
| 587 } | 618 } |
| 588 function funarg(type) { | 619 function funarg(type) { |
| 589 if (type == "spread") return cont(funarg); | 620 if (type == "spread") return cont(funarg); |
| 590 return pass(pattern, maybetype, maybedefault); | 621 return pass(pattern, maybetype, maybeAssign); |
| 622 } |
| 623 function classExpression(type, value) { |
| 624 // Class expressions may have an optional name. |
| 625 if (type == "variable") return className(type, value); |
| 626 return classNameAfter(type, value); |
| 591 } | 627 } |
| 592 function className(type, value) { | 628 function className(type, value) { |
| 593 if (type == "variable") {register(value); return cont(classNameAfter);} | 629 if (type == "variable") {register(value); return cont(classNameAfter);} |
| 594 } | 630 } |
| 595 function classNameAfter(type, value) { | 631 function classNameAfter(type, value) { |
| 596 if (value == "extends") return cont(expression, classNameAfter); | 632 if (value == "extends" || value == "implements") return cont(isTS ? typeexpr
: expression, classNameAfter); |
| 597 if (type == "{") return cont(pushlex("}"), classBody, poplex); | 633 if (type == "{") return cont(pushlex("}"), classBody, poplex); |
| 598 } | 634 } |
| 599 function classBody(type, value) { | 635 function classBody(type, value) { |
| 600 if (type == "variable" || cx.style == "keyword") { | 636 if (type == "variable" || cx.style == "keyword") { |
| 601 if (value == "static") { | 637 if ((value == "static" || value == "get" || value == "set" || |
| 638 (isTS && (value == "public" || value == "private" || value == "protec
ted" || value == "readonly" || value == "abstract"))) && |
| 639 cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false)) { |
| 602 cx.marked = "keyword"; | 640 cx.marked = "keyword"; |
| 603 return cont(classBody); | 641 return cont(classBody); |
| 604 } | 642 } |
| 605 cx.marked = "property"; | 643 cx.marked = "property"; |
| 606 if (value == "get" || value == "set") return cont(classGetterSetter, funct
iondef, classBody); | 644 return cont(isTS ? classfield : functiondef, classBody); |
| 607 return cont(functiondef, classBody); | |
| 608 } | 645 } |
| 609 if (value == "*") { | 646 if (value == "*") { |
| 610 cx.marked = "keyword"; | 647 cx.marked = "keyword"; |
| 611 return cont(classBody); | 648 return cont(classBody); |
| 612 } | 649 } |
| 613 if (type == ";") return cont(classBody); | 650 if (type == ";") return cont(classBody); |
| 614 if (type == "}") return cont(); | 651 if (type == "}") return cont(); |
| 615 } | 652 } |
| 616 function classGetterSetter(type) { | 653 function classfield(type, value) { |
| 617 if (type != "variable") return pass(); | 654 if (value == "?") return cont(classfield) |
| 618 cx.marked = "property"; | 655 if (type == ":") return cont(typeexpr, maybeAssign) |
| 619 return cont(); | 656 return pass(functiondef) |
| 620 } | 657 } |
| 621 function afterExport(_type, value) { | 658 function afterExport(_type, value) { |
| 622 if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";"
)); } | 659 if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";"
)); } |
| 623 if (value == "default") { cx.marked = "keyword"; return cont(expression, exp
ect(";")); } | 660 if (value == "default") { cx.marked = "keyword"; return cont(expression, exp
ect(";")); } |
| 624 return pass(statement); | 661 return pass(statement); |
| 625 } | 662 } |
| 626 function afterImport(type) { | 663 function afterImport(type) { |
| 627 if (type == "string") return cont(); | 664 if (type == "string") return cont(); |
| 628 return pass(importSpec, maybeFrom); | 665 return pass(importSpec, maybeFrom); |
| 629 } | 666 } |
| 630 function importSpec(type, value) { | 667 function importSpec(type, value) { |
| 631 if (type == "{") return contCommasep(importSpec, "}"); | 668 if (type == "{") return contCommasep(importSpec, "}"); |
| 632 if (type == "variable") register(value); | 669 if (type == "variable") register(value); |
| 633 if (value == "*") cx.marked = "keyword"; | 670 if (value == "*") cx.marked = "keyword"; |
| 634 return cont(maybeAs); | 671 return cont(maybeAs); |
| 635 } | 672 } |
| 636 function maybeAs(_type, value) { | 673 function maybeAs(_type, value) { |
| 637 if (value == "as") { cx.marked = "keyword"; return cont(importSpec); } | 674 if (value == "as") { cx.marked = "keyword"; return cont(importSpec); } |
| 638 } | 675 } |
| 639 function maybeFrom(_type, value) { | 676 function maybeFrom(_type, value) { |
| 640 if (value == "from") { cx.marked = "keyword"; return cont(expression); } | 677 if (value == "from") { cx.marked = "keyword"; return cont(expression); } |
| 641 } | 678 } |
| 642 function arrayLiteral(type) { | 679 function arrayLiteral(type) { |
| 643 if (type == "]") return cont(); | 680 if (type == "]") return cont(); |
| 644 return pass(expressionNoComma, commasep(expressionNoComma, "]")); | 681 return pass(commasep(expressionNoComma, "]")); |
| 645 } | 682 } |
| 646 | 683 |
| 647 function isContinuedStatement(state, textAfter) { | 684 function isContinuedStatement(state, textAfter) { |
| 648 return state.lastType == "operator" || state.lastType == "," || | 685 return state.lastType == "operator" || state.lastType == "," || |
| 649 isOperatorChar.test(textAfter.charAt(0)) || | 686 isOperatorChar.test(textAfter.charAt(0)) || |
| 650 /[,.]/.test(textAfter.charAt(0)); | 687 /[,.]/.test(textAfter.charAt(0)); |
| 651 } | 688 } |
| 652 | 689 |
| 653 // Interface | 690 // Interface |
| 654 | 691 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 678 if (state.tokenize != tokenComment && stream.eatSpace()) return null; | 715 if (state.tokenize != tokenComment && stream.eatSpace()) return null; |
| 679 var style = state.tokenize(stream, state); | 716 var style = state.tokenize(stream, state); |
| 680 if (type == "comment") return style; | 717 if (type == "comment") return style; |
| 681 state.lastType = type == "operator" && (content == "++" || content == "--"
) ? "incdec" : type; | 718 state.lastType = type == "operator" && (content == "++" || content == "--"
) ? "incdec" : type; |
| 682 return parseJS(state, style, type, content, stream); | 719 return parseJS(state, style, type, content, stream); |
| 683 }, | 720 }, |
| 684 | 721 |
| 685 indent: function(state, textAfter) { | 722 indent: function(state, textAfter) { |
| 686 if (state.tokenize == tokenComment) return CodeMirror.Pass; | 723 if (state.tokenize == tokenComment) return CodeMirror.Pass; |
| 687 if (state.tokenize != tokenBase) return 0; | 724 if (state.tokenize != tokenBase) return 0; |
| 688 var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical; | 725 var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical,
top |
| 689 // Kludge to prevent 'maybelse' from blocking lexical scope pops | 726 // Kludge to prevent 'maybelse' from blocking lexical scope pops |
| 690 if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >=
0; --i) { | 727 if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >=
0; --i) { |
| 691 var c = state.cc[i]; | 728 var c = state.cc[i]; |
| 692 if (c == poplex) lexical = lexical.prev; | 729 if (c == poplex) lexical = lexical.prev; |
| 693 else if (c != maybeelse) break; | 730 else if (c != maybeelse) break; |
| 694 } | 731 } |
| 695 if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev; | 732 while ((lexical.type == "stat" || lexical.type == "form") && |
| 733 (firstChar == "}" || ((top = state.cc[state.cc.length - 1]) && |
| 734 (top == maybeoperatorComma || top == maybeope
ratorNoComma) && |
| 735 !/^[,\.=+\-*:?[\(]/.test(textAfter)))) |
| 736 lexical = lexical.prev; |
| 696 if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat") | 737 if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat") |
| 697 lexical = lexical.prev; | 738 lexical = lexical.prev; |
| 698 var type = lexical.type, closing = firstChar == type; | 739 var type = lexical.type, closing = firstChar == type; |
| 699 | 740 |
| 700 if (type == "vardef") return lexical.indented + (state.lastType == "operat
or" || state.lastType == "," ? lexical.info + 1 : 0); | 741 if (type == "vardef") return lexical.indented + (state.lastType == "operat
or" || state.lastType == "," ? lexical.info + 1 : 0); |
| 701 else if (type == "form" && firstChar == "{") return lexical.indented; | 742 else if (type == "form" && firstChar == "{") return lexical.indented; |
| 702 else if (type == "form") return lexical.indented + indentUnit; | 743 else if (type == "form") return lexical.indented + indentUnit; |
| 703 else if (type == "stat") | 744 else if (type == "stat") |
| 704 return lexical.indented + (isContinuedStatement(state, textAfter) ? stat
ementIndent || indentUnit : 0); | 745 return lexical.indented + (isContinuedStatement(state, textAfter) ? stat
ementIndent || indentUnit : 0); |
| 705 else if (lexical.info == "switch" && !closing && parserConfig.doubleIndent
Switch != false) | 746 else if (lexical.info == "switch" && !closing && parserConfig.doubleIndent
Switch != false) |
| (...skipping 27 matching lines...) Expand all Loading... |
| 733 CodeMirror.defineMIME("text/ecmascript", "javascript"); | 774 CodeMirror.defineMIME("text/ecmascript", "javascript"); |
| 734 CodeMirror.defineMIME("application/javascript", "javascript"); | 775 CodeMirror.defineMIME("application/javascript", "javascript"); |
| 735 CodeMirror.defineMIME("application/x-javascript", "javascript"); | 776 CodeMirror.defineMIME("application/x-javascript", "javascript"); |
| 736 CodeMirror.defineMIME("application/ecmascript", "javascript"); | 777 CodeMirror.defineMIME("application/ecmascript", "javascript"); |
| 737 CodeMirror.defineMIME("application/json", {name: "javascript", json: true}); | 778 CodeMirror.defineMIME("application/json", {name: "javascript", json: true}); |
| 738 CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true}); | 779 CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true}); |
| 739 CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true})
; | 780 CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true})
; |
| 740 CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true
}); | 781 CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true
}); |
| 741 CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript
: true }); | 782 CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript
: true }); |
| 742 | 783 |
| 743 }); | 784 }); |
| OLD | NEW |