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 | 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); |
(...skipping 24 matching lines...) Expand all Loading... |
35 | 35 |
36 var jsKeywords = { | 36 var jsKeywords = { |
37 "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "fina
lly": B, | 37 "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "fina
lly": B, |
38 "return": C, "break": C, "continue": C, "new": kw("new"), "delete": C, "th
row": C, "debugger": C, | 38 "return": C, "break": C, "continue": C, "new": kw("new"), "delete": C, "th
row": C, "debugger": C, |
39 "var": kw("var"), "const": kw("var"), "let": kw("var"), | 39 "var": kw("var"), "const": kw("var"), "let": kw("var"), |
40 "function": kw("function"), "catch": kw("catch"), | 40 "function": kw("function"), "catch": kw("catch"), |
41 "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": k
w("default"), | 41 "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": k
w("default"), |
42 "in": operator, "typeof": operator, "instanceof": operator, | 42 "in": operator, "typeof": operator, "instanceof": operator, |
43 "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom,
"Infinity": atom, | 43 "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom,
"Infinity": atom, |
44 "this": kw("this"), "class": kw("class"), "super": kw("atom"), | 44 "this": kw("this"), "class": kw("class"), "super": kw("atom"), |
45 "yield": C, "export": kw("export"), "import": kw("import"), "extends": C | 45 "yield": C, "export": kw("export"), "import": kw("import"), "extends": C, |
| 46 "await": C, "async": kw("async") |
46 }; | 47 }; |
47 | 48 |
48 // Extend the 'normal' keywords with the TypeScript language extensions | 49 // Extend the 'normal' keywords with the TypeScript language extensions |
49 if (isTS) { | 50 if (isTS) { |
50 var type = {type: "variable", style: "variable-3"}; | 51 var type = {type: "variable", style: "variable-3"}; |
51 var tsKeywords = { | 52 var tsKeywords = { |
52 // object-like things | 53 // object-like things |
53 "interface": kw("class"), | 54 "interface": kw("class"), |
54 "implements": C, | 55 "implements": C, |
55 "namespace": C, | 56 "namespace": C, |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
359 if (type == "switch") return cont(pushlex("form"), expression, pushlex("}",
"switch"), expect("{"), | 360 if (type == "switch") return cont(pushlex("form"), expression, pushlex("}",
"switch"), expect("{"), |
360 block, poplex, poplex); | 361 block, poplex, poplex); |
361 if (type == "case") return cont(expression, expect(":")); | 362 if (type == "case") return cont(expression, expect(":")); |
362 if (type == "default") return cont(expect(":")); | 363 if (type == "default") return cont(expect(":")); |
363 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("),
funarg, expect(")"), | 364 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("),
funarg, expect(")"), |
364 statement, poplex, popcontext); | 365 statement, poplex, popcontext); |
365 if (type == "class") return cont(pushlex("form"), className, poplex); | 366 if (type == "class") return cont(pushlex("form"), className, poplex); |
366 if (type == "export") return cont(pushlex("stat"), afterExport, poplex); | 367 if (type == "export") return cont(pushlex("stat"), afterExport, poplex); |
367 if (type == "import") return cont(pushlex("stat"), afterImport, poplex); | 368 if (type == "import") return cont(pushlex("stat"), afterImport, poplex); |
368 if (type == "module") return cont(pushlex("form"), pattern, pushlex("}"), ex
pect("{"), block, poplex, poplex) | 369 if (type == "module") return cont(pushlex("form"), pattern, pushlex("}"), ex
pect("{"), block, poplex, poplex) |
| 370 if (type == "async") return cont(statement) |
369 return pass(pushlex("stat"), expression, expect(";"), poplex); | 371 return pass(pushlex("stat"), expression, expect(";"), poplex); |
370 } | 372 } |
371 function expression(type) { | 373 function expression(type) { |
372 return expressionInner(type, false); | 374 return expressionInner(type, false); |
373 } | 375 } |
374 function expressionNoComma(type) { | 376 function expressionNoComma(type) { |
375 return expressionInner(type, true); | 377 return expressionInner(type, true); |
376 } | 378 } |
377 function expressionInner(type, noComma) { | 379 function expressionInner(type, noComma) { |
378 if (cx.state.fatArrowAt == cx.stream.start) { | 380 if (cx.state.fatArrowAt == cx.stream.start) { |
379 var body = noComma ? arrowBodyNoComma : arrowBody; | 381 var body = noComma ? arrowBodyNoComma : arrowBody; |
380 if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern,
")"), poplex, expect("=>"), body, popcontext); | 382 if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern,
")"), poplex, expect("=>"), body, popcontext); |
381 else if (type == "variable") return pass(pushcontext, pattern, expect("=>"
), body, popcontext); | 383 else if (type == "variable") return pass(pushcontext, pattern, expect("=>"
), body, popcontext); |
382 } | 384 } |
383 | 385 |
384 var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; | 386 var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; |
385 if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); | 387 if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); |
386 if (type == "function") return cont(functiondef, maybeop); | 388 if (type == "function") return cont(functiondef, maybeop); |
387 if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : mayb
eexpression); | 389 if (type == "keyword c" || type == "async") return cont(noComma ? maybeexpre
ssionNoComma : maybeexpression); |
388 if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, e
xpect(")"), poplex, maybeop); | 390 if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), pop
lex, maybeop); |
389 if (type == "operator" || type == "spread") return cont(noComma ? expression
NoComma : expression); | 391 if (type == "operator" || type == "spread") return cont(noComma ? expression
NoComma : expression); |
390 if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop); | 392 if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop); |
391 if (type == "{") return contCommasep(objprop, "}", null, maybeop); | 393 if (type == "{") return contCommasep(objprop, "}", null, maybeop); |
392 if (type == "quasi") return pass(quasi, maybeop); | 394 if (type == "quasi") return pass(quasi, maybeop); |
393 if (type == "new") return cont(maybeTarget(noComma)); | 395 if (type == "new") return cont(maybeTarget(noComma)); |
394 return cont(); | 396 return cont(); |
395 } | 397 } |
396 function maybeexpression(type) { | 398 function maybeexpression(type) { |
397 if (type.match(/[;\}\)\],]/)) return pass(); | 399 if (type.match(/[;\}\)\],]/)) return pass(); |
398 return pass(expression); | 400 return pass(expression); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorNoC
omma); } | 456 if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorNoC
omma); } |
455 } | 457 } |
456 function maybelabel(type) { | 458 function maybelabel(type) { |
457 if (type == ":") return cont(poplex, statement); | 459 if (type == ":") return cont(poplex, statement); |
458 return pass(maybeoperatorComma, expect(";"), poplex); | 460 return pass(maybeoperatorComma, expect(";"), poplex); |
459 } | 461 } |
460 function property(type) { | 462 function property(type) { |
461 if (type == "variable") {cx.marked = "property"; return cont();} | 463 if (type == "variable") {cx.marked = "property"; return cont();} |
462 } | 464 } |
463 function objprop(type, value) { | 465 function objprop(type, value) { |
| 466 if (type == "async") return cont(objprop); |
464 if (type == "variable" || cx.style == "keyword") { | 467 if (type == "variable" || cx.style == "keyword") { |
465 cx.marked = "property"; | 468 cx.marked = "property"; |
466 if (value == "get" || value == "set") return cont(getterSetter); | 469 if (value == "get" || value == "set") return cont(getterSetter); |
467 return cont(afterprop); | 470 return cont(afterprop); |
468 } else if (type == "number" || type == "string") { | 471 } else if (type == "number" || type == "string") { |
469 cx.marked = jsonldMode ? "property" : (cx.style + " property"); | 472 cx.marked = jsonldMode ? "property" : (cx.style + " property"); |
470 return cont(afterprop); | 473 return cont(afterprop); |
471 } else if (type == "jsonld-keyword") { | 474 } else if (type == "jsonld-keyword") { |
472 return cont(afterprop); | 475 return cont(afterprop); |
473 } else if (type == "modifier") { | 476 } else if (type == "modifier") { |
474 return cont(objprop) | 477 return cont(objprop) |
475 } else if (type == "[") { | 478 } else if (type == "[") { |
476 return cont(expression, expect("]"), afterprop); | 479 return cont(expression, expect("]"), afterprop); |
477 } else if (type == "spread") { | 480 } else if (type == "spread") { |
478 return cont(expression); | 481 return cont(expression); |
479 } | 482 } |
480 } | 483 } |
481 function getterSetter(type) { | 484 function getterSetter(type) { |
482 if (type != "variable") return pass(afterprop); | 485 if (type != "variable") return pass(afterprop); |
483 cx.marked = "property"; | 486 cx.marked = "property"; |
484 return cont(functiondef); | 487 return cont(functiondef); |
485 } | 488 } |
486 function afterprop(type) { | 489 function afterprop(type) { |
487 if (type == ":") return cont(expressionNoComma); | 490 if (type == ":") return cont(expressionNoComma); |
488 if (type == "(") return pass(functiondef); | 491 if (type == "(") return pass(functiondef); |
489 } | 492 } |
490 function commasep(what, end) { | 493 function commasep(what, end) { |
491 function proceed(type) { | 494 function proceed(type, value) { |
492 if (type == ",") { | 495 if (type == ",") { |
493 var lex = cx.state.lexical; | 496 var lex = cx.state.lexical; |
494 if (lex.info == "call") lex.pos = (lex.pos || 0) + 1; | 497 if (lex.info == "call") lex.pos = (lex.pos || 0) + 1; |
495 return cont(what, proceed); | 498 return cont(function(type, value) { |
| 499 if (type == end || value == end) return pass() |
| 500 return pass(what) |
| 501 }, proceed); |
496 } | 502 } |
497 if (type == end) return cont(); | 503 if (type == end || value == end) return cont(); |
498 return cont(expect(end)); | 504 return cont(expect(end)); |
499 } | 505 } |
500 return function(type) { | 506 return function(type, value) { |
501 if (type == end) return cont(); | 507 if (type == end || value == end) return cont(); |
502 return pass(what, proceed); | 508 return pass(what, proceed); |
503 }; | 509 }; |
504 } | 510 } |
505 function contCommasep(what, end, info) { | 511 function contCommasep(what, end, info) { |
506 for (var i = 3; i < arguments.length; i++) | 512 for (var i = 3; i < arguments.length; i++) |
507 cx.cc.push(arguments[i]); | 513 cx.cc.push(arguments[i]); |
508 return cont(pushlex(end, info), commasep(what, end), poplex); | 514 return cont(pushlex(end, info), commasep(what, end), poplex); |
509 } | 515 } |
510 function block(type) { | 516 function block(type) { |
511 if (type == "}") return cont(); | 517 if (type == "}") return cont(); |
512 return pass(statement, block); | 518 return pass(statement, block); |
513 } | 519 } |
514 function maybetype(type) { | 520 function maybetype(type) { |
515 if (isTS && type == ":") return cont(typedef); | 521 if (isTS && type == ":") return cont(typeexpr); |
516 } | 522 } |
517 function maybedefault(_, value) { | 523 function maybedefault(_, value) { |
518 if (value == "=") return cont(expressionNoComma); | 524 if (value == "=") return cont(expressionNoComma); |
519 } | 525 } |
520 function typedef(type) { | 526 function typeexpr(type) { |
521 if (type == "variable") {cx.marked = "variable-3"; return cont();} | 527 if (type == "variable") {cx.marked = "variable-3"; return cont(afterType);} |
| 528 } |
| 529 function afterType(type, value) { |
| 530 if (value == "<") return cont(commasep(typeexpr, ">"), afterType) |
| 531 if (type == "[") return cont(expect("]"), afterType) |
522 } | 532 } |
523 function vardef() { | 533 function vardef() { |
524 return pass(pattern, maybetype, maybeAssign, vardefCont); | 534 return pass(pattern, maybetype, maybeAssign, vardefCont); |
525 } | 535 } |
526 function pattern(type, value) { | 536 function pattern(type, value) { |
527 if (type == "modifier") return cont(pattern) | 537 if (type == "modifier") return cont(pattern) |
528 if (type == "variable") { register(value); return cont(); } | 538 if (type == "variable") { register(value); return cont(); } |
529 if (type == "spread") return cont(pattern); | 539 if (type == "spread") return cont(pattern); |
530 if (type == "[") return contCommasep(pattern, "]"); | 540 if (type == "[") return contCommasep(pattern, "]"); |
531 if (type == "{") return contCommasep(proppattern, "}"); | 541 if (type == "{") return contCommasep(proppattern, "}"); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
566 if (type == ";") return cont(forspec3); | 576 if (type == ";") return cont(forspec3); |
567 if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(exp
ression); } | 577 if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(exp
ression); } |
568 return pass(expression, expect(";"), forspec3); | 578 return pass(expression, expect(";"), forspec3); |
569 } | 579 } |
570 function forspec3(type) { | 580 function forspec3(type) { |
571 if (type != ")") cont(expression); | 581 if (type != ")") cont(expression); |
572 } | 582 } |
573 function functiondef(type, value) { | 583 function functiondef(type, value) { |
574 if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} | 584 if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} |
575 if (type == "variable") {register(value); return cont(functiondef);} | 585 if (type == "variable") {register(value); return cont(functiondef);} |
576 if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"
), poplex, statement, popcontext); | 586 if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"
), poplex, maybetype, statement, popcontext); |
577 } | 587 } |
578 function funarg(type) { | 588 function funarg(type) { |
579 if (type == "spread") return cont(funarg); | 589 if (type == "spread") return cont(funarg); |
580 return pass(pattern, maybetype, maybedefault); | 590 return pass(pattern, maybetype, maybedefault); |
581 } | 591 } |
582 function className(type, value) { | 592 function className(type, value) { |
583 if (type == "variable") {register(value); return cont(classNameAfter);} | 593 if (type == "variable") {register(value); return cont(classNameAfter);} |
584 } | 594 } |
585 function classNameAfter(type, value) { | 595 function classNameAfter(type, value) { |
586 if (value == "extends") return cont(expression, classNameAfter); | 596 if (value == "extends") return cont(expression, classNameAfter); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 return cont(maybeAs); | 634 return cont(maybeAs); |
625 } | 635 } |
626 function maybeAs(_type, value) { | 636 function maybeAs(_type, value) { |
627 if (value == "as") { cx.marked = "keyword"; return cont(importSpec); } | 637 if (value == "as") { cx.marked = "keyword"; return cont(importSpec); } |
628 } | 638 } |
629 function maybeFrom(_type, value) { | 639 function maybeFrom(_type, value) { |
630 if (value == "from") { cx.marked = "keyword"; return cont(expression); } | 640 if (value == "from") { cx.marked = "keyword"; return cont(expression); } |
631 } | 641 } |
632 function arrayLiteral(type) { | 642 function arrayLiteral(type) { |
633 if (type == "]") return cont(); | 643 if (type == "]") return cont(); |
634 return pass(expressionNoComma, maybeArrayComprehension); | 644 return pass(expressionNoComma, commasep(expressionNoComma, "]")); |
635 } | |
636 function maybeArrayComprehension(type) { | |
637 if (type == "for") return pass(comprehension, expect("]")); | |
638 if (type == ",") return cont(commasep(maybeexpressionNoComma, "]")); | |
639 return pass(commasep(expressionNoComma, "]")); | |
640 } | |
641 function comprehension(type) { | |
642 if (type == "for") return cont(forspec, comprehension); | |
643 if (type == "if") return cont(expression, comprehension); | |
644 } | 645 } |
645 | 646 |
646 function isContinuedStatement(state, textAfter) { | 647 function isContinuedStatement(state, textAfter) { |
647 return state.lastType == "operator" || state.lastType == "," || | 648 return state.lastType == "operator" || state.lastType == "," || |
648 isOperatorChar.test(textAfter.charAt(0)) || | 649 isOperatorChar.test(textAfter.charAt(0)) || |
649 /[,.]/.test(textAfter.charAt(0)); | 650 /[,.]/.test(textAfter.charAt(0)); |
650 } | 651 } |
651 | 652 |
652 // Interface | 653 // Interface |
653 | 654 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
733 CodeMirror.defineMIME("application/javascript", "javascript"); | 734 CodeMirror.defineMIME("application/javascript", "javascript"); |
734 CodeMirror.defineMIME("application/x-javascript", "javascript"); | 735 CodeMirror.defineMIME("application/x-javascript", "javascript"); |
735 CodeMirror.defineMIME("application/ecmascript", "javascript"); | 736 CodeMirror.defineMIME("application/ecmascript", "javascript"); |
736 CodeMirror.defineMIME("application/json", {name: "javascript", json: true}); | 737 CodeMirror.defineMIME("application/json", {name: "javascript", json: true}); |
737 CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true}); | 738 CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true}); |
738 CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true})
; | 739 CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true})
; |
739 CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true
}); | 740 CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true
}); |
740 CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript
: true }); | 741 CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript
: true }); |
741 | 742 |
742 }); | 743 }); |
OLD | NEW |