Changeset 3758:6338fb89e8df for admin/js/codemirror/mode
- Timestamp:
- 06/13/18 12:31:58 (7 years ago)
- Branch:
- default
- Location:
- admin/js/codemirror/mode
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
admin/js/codemirror/mode/javascript/javascript.js
r3617 r3758 27 27 var operator = kw("operator"), atom = {type: "atom", style: "atom"}; 28 28 29 var jsKeywords ={29 return { 30 30 "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B, 31 31 "return": D, "break": D, "continue": D, "new": kw("new"), "delete": C, "void": C, "throw": C, … … 39 39 "await": C 40 40 }; 41 42 // Extend the 'normal' keywords with the TypeScript language extensions43 if (isTS) {44 var type = {type: "variable", style: "type"};45 var tsKeywords = {46 // object-like things47 "interface": kw("class"),48 "implements": C,49 "namespace": C,50 51 // scope modifiers52 "public": kw("modifier"),53 "private": kw("modifier"),54 "protected": kw("modifier"),55 "abstract": kw("modifier"),56 "readonly": kw("modifier"),57 58 // types59 "string": type, "number": type, "boolean": type, "any": type60 };61 62 for (var attr in tsKeywords) {63 jsKeywords[attr] = tsKeywords[attr];64 }65 }66 67 return jsKeywords;68 41 }(); 69 42 … … 103 76 } else if (ch == "=" && stream.eat(">")) { 104 77 return ret("=>", "operator"); 105 } else if (ch == "0" && stream.eat(/x/i)) { 106 stream.eatWhile(/[\da-f]/i); 107 return ret("number", "number"); 108 } else if (ch == "0" && stream.eat(/o/i)) { 109 stream.eatWhile(/[0-7]/i); 110 return ret("number", "number"); 111 } else if (ch == "0" && stream.eat(/b/i)) { 112 stream.eatWhile(/[01]/i); 78 } else if (ch == "0" && stream.match(/^(?:x[\da-f]+|o[0-7]+|b[01]+)n?/i)) { 113 79 return ret("number", "number"); 114 80 } else if (/\d/.test(ch)) { 115 stream.match(/^\d*(?: \.\d*)?(?:[eE][+\-]?\d+)?/);81 stream.match(/^\d*(?:n|(?:\.\d*)?(?:[eE][+\-]?\d+)?)?/); 116 82 return ret("number", "number"); 117 83 } else if (ch == "/") { … … 124 90 } else if (expressionAllowed(stream, state, 1)) { 125 91 readRegexp(stream); 126 stream.match(/^\b(([gimyu ])(?![gimyu]*\2))+\b/);92 stream.match(/^\b(([gimyus])(?![gimyus]*\2))+\b/); 127 93 return ret("regexp", "string-2"); 128 94 } else { … … 154 120 return ret(kw.type, kw.style, word) 155 121 } 156 if (word == "async" && stream.match(/^(\s|\/\*.*?\*\/)*[\ (\w]/, false))122 if (word == "async" && stream.match(/^(\s|\/\*.*?\*\/)*[\[\(\w]/, false)) 157 123 return ret("async", "keyword", word) 158 124 } … … 293 259 return true; 294 260 } 261 function inList(name, list) { 262 for (var v = list; v; v = v.next) if (v.name == name) return true 263 return false; 264 } 295 265 function register(varname) { 296 function inList(list) {297 for (var v = list; v; v = v.next)298 if (v.name == varname) return true;299 return false;300 }301 266 var state = cx.state; 302 267 cx.marked = "def"; 303 268 if (state.context) { 304 if (inList(state.localVars)) return; 305 state.localVars = {name: varname, next: state.localVars}; 269 if (state.lexical.info == "var" && state.context && state.context.block) { 270 // FIXME function decls are also not block scoped 271 var newContext = registerVarScoped(varname, state.context) 272 if (newContext != null) { 273 state.context = newContext 274 return 275 } 276 } else if (!inList(varname, state.localVars)) { 277 state.localVars = new Var(varname, state.localVars) 278 return 279 } 280 } 281 // Fall through means this is global 282 if (parserConfig.globalVars && !inList(varname, state.globalVars)) 283 state.globalVars = new Var(varname, state.globalVars) 284 } 285 function registerVarScoped(varname, context) { 286 if (!context) { 287 return null 288 } else if (context.block) { 289 var inner = registerVarScoped(varname, context.prev) 290 if (!inner) return null 291 if (inner == context.prev) return context 292 return new Context(inner, context.vars, true) 293 } else if (inList(varname, context.vars)) { 294 return context 306 295 } else { 307 if (inList(state.globalVars)) return; 308 if (parserConfig.globalVars) 309 state.globalVars = {name: varname, next: state.globalVars}; 310 } 296 return new Context(context.prev, new Var(varname, context.vars), false) 297 } 298 } 299 300 function isModifier(name) { 301 return name == "public" || name == "private" || name == "protected" || name == "abstract" || name == "readonly" 311 302 } 312 303 313 304 // Combinators 314 305 315 var defaultVars = {name: "this", next: {name: "arguments"}}; 306 function Context(prev, vars, block) { this.prev = prev; this.vars = vars; this.block = block } 307 function Var(name, next) { this.name = name; this.next = next } 308 309 var defaultVars = new Var("this", new Var("arguments", null)) 316 310 function pushcontext() { 317 cx.state.context = {prev: cx.state.context, vars: cx.state.localVars}; 318 cx.state.localVars = defaultVars; 311 cx.state.context = new Context(cx.state.context, cx.state.localVars, false) 312 cx.state.localVars = defaultVars 313 } 314 function pushblockcontext() { 315 cx.state.context = new Context(cx.state.context, cx.state.localVars, true) 316 cx.state.localVars = null 319 317 } 320 318 function popcontext() { 321 cx.state.localVars = cx.state.context.vars; 322 cx.state.context = cx.state.context.prev; 323 } 319 cx.state.localVars = cx.state.context.vars 320 cx.state.context = cx.state.context.prev 321 } 322 popcontext.lex = true 324 323 function pushlex(type, info) { 325 324 var result = function() { … … 346 345 function exp(type) { 347 346 if (type == wanted) return cont(); 348 else if (wanted == ";" ) return pass();347 else if (wanted == ";" || type == "}" || type == ")" || type == "]") return pass(); 349 348 else return cont(exp); 350 349 }; … … 353 352 354 353 function statement(type, value) { 355 if (type == "var") return cont(pushlex("vardef", value .length), vardef, expect(";"), poplex);354 if (type == "var") return cont(pushlex("vardef", value), vardef, expect(";"), poplex); 356 355 if (type == "keyword a") return cont(pushlex("form"), parenExpr, statement, poplex); 357 356 if (type == "keyword b") return cont(pushlex("form"), statement, poplex); 358 357 if (type == "keyword d") return cx.stream.match(/^\s*$/, false) ? cont() : cont(pushlex("stat"), maybeexpression, expect(";"), poplex); 359 358 if (type == "debugger") return cont(expect(";")); 360 if (type == "{") return cont(pushlex("}"), block, poplex);359 if (type == "{") return cont(pushlex("}"), pushblockcontext, block, poplex, popcontext); 361 360 if (type == ";") return cont(); 362 361 if (type == "if") { … … 367 366 if (type == "function") return cont(functiondef); 368 367 if (type == "for") return cont(pushlex("form"), forspec, statement, poplex); 368 if (type == "class" || (isTS && value == "interface")) { cx.marked = "keyword"; return cont(pushlex("form"), className, poplex); } 369 369 if (type == "variable") { 370 if (isTS && value == "type") { 371 cx.marked = "keyword" 372 return cont(typeexpr, expect("operator"), typeexpr, expect(";")); 373 } else if (isTS && value == "declare") { 370 if (isTS && value == "declare") { 374 371 cx.marked = "keyword" 375 372 return cont(statement) 376 } else if (isTS && (value == "module" || value == "enum" ) && cx.stream.match(/^\s*\w/, false)) {373 } else if (isTS && (value == "module" || value == "enum" || value == "type") && cx.stream.match(/^\s*\w/, false)) { 377 374 cx.marked = "keyword" 378 return cont(pushlex("form"), pattern, expect("{"), pushlex("}"), block, poplex, poplex) 375 if (value == "enum") return cont(enumdef); 376 else if (value == "type") return cont(typeexpr, expect("operator"), typeexpr, expect(";")); 377 else return cont(pushlex("form"), pattern, expect("{"), pushlex("}"), block, poplex, poplex) 378 } else if (isTS && value == "namespace") { 379 cx.marked = "keyword" 380 return cont(pushlex("form"), expression, block, poplex) 381 } else if (isTS && value == "abstract") { 382 cx.marked = "keyword" 383 return cont(statement) 379 384 } else { 380 385 return cont(pushlex("stat"), maybelabel); 381 386 } 382 387 } 383 if (type == "switch") return cont(pushlex("form"), parenExpr, expect("{"), pushlex("}", "switch"), 384 block, poplex, poplex );388 if (type == "switch") return cont(pushlex("form"), parenExpr, expect("{"), pushlex("}", "switch"), pushblockcontext, 389 block, poplex, poplex, popcontext); 385 390 if (type == "case") return cont(expression, expect(":")); 386 391 if (type == "default") return cont(expect(":")); 387 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), 388 statement, poplex, popcontext); 389 if (type == "class") return cont(pushlex("form"), className, poplex); 392 if (type == "catch") return cont(pushlex("form"), pushcontext, maybeCatchBinding, statement, poplex, popcontext); 390 393 if (type == "export") return cont(pushlex("stat"), afterExport, poplex); 391 394 if (type == "import") return cont(pushlex("stat"), afterImport, poplex); … … 394 397 return pass(pushlex("stat"), expression, expect(";"), poplex); 395 398 } 396 function expression(type) { 397 return expressionInner(type, false); 398 } 399 function expressionNoComma(type) { 400 return expressionInner(type, true); 399 function maybeCatchBinding(type) { 400 if (type == "(") return cont(funarg, expect(")")) 401 } 402 function expression(type, value) { 403 return expressionInner(type, value, false); 404 } 405 function expressionNoComma(type, value) { 406 return expressionInner(type, value, true); 401 407 } 402 408 function parenExpr(type) { … … 404 410 return cont(pushlex(")"), expression, expect(")"), poplex) 405 411 } 406 function expressionInner(type, noComma) {412 function expressionInner(type, value, noComma) { 407 413 if (cx.state.fatArrowAt == cx.stream.start) { 408 414 var body = noComma ? arrowBodyNoComma : arrowBody; … … 414 420 if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); 415 421 if (type == "function") return cont(functiondef, maybeop); 416 if (type == "class" ) return cont(pushlex("form"), classExpression, poplex);422 if (type == "class" || (isTS && value == "interface")) { cx.marked = "keyword"; return cont(pushlex("form"), classExpression, poplex); } 417 423 if (type == "keyword c" || type == "async") return cont(noComma ? expressionNoComma : expression); 418 424 if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop); … … 422 428 if (type == "quasi") return pass(quasi, maybeop); 423 429 if (type == "new") return cont(maybeTarget(noComma)); 430 if (type == "import") return cont(expression); 424 431 return cont(); 425 432 } … … 512 519 } else if (type == "jsonld-keyword") { 513 520 return cont(afterprop); 514 } else if (type == "modifier") { 521 } else if (isTS && isModifier(value)) { 522 cx.marked = "keyword" 515 523 return cont(objprop) 516 524 } else if (type == "[") { 517 return cont(expression, expect("]"), afterprop);525 return cont(expression, maybetype, expect("]"), afterprop); 518 526 } else if (type == "spread") { 519 527 return cont(expressionNoComma, afterprop); … … 580 588 } 581 589 function typeexpr(type, value) { 590 if (value == "keyof" || value == "typeof") { 591 cx.marked = "keyword" 592 return cont(value == "keyof" ? typeexpr : expressionNoComma) 593 } 582 594 if (type == "variable" || value == "void") { 583 if (value == "keyof") { 584 cx.marked = "keyword" 585 return cont(typeexpr) 586 } else { 587 cx.marked = "type" 588 return cont(afterType) 589 } 595 cx.marked = "type" 596 return cont(afterType) 590 597 } 591 598 if (type == "string" || type == "number" || type == "atom") return cont(afterType); … … 593 600 if (type == "{") return cont(pushlex("}"), commasep(typeprop, "}", ",;"), poplex, afterType) 594 601 if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType) 602 if (type == "<") return cont(commasep(typeexpr, ">"), typeexpr) 595 603 } 596 604 function maybeReturnType(type) { … … 609 617 } 610 618 } 611 function typearg(type) { 612 if (type == "variable") return cont(typearg) 613 else if (type == ":") return cont(typeexpr) 619 function typearg(type, value) { 620 if (type == "variable" && cx.stream.match(/^\s*[?:]/, false) || value == "?") return cont(typearg) 621 if (type == ":") return cont(typeexpr) 622 return pass(typeexpr) 614 623 } 615 624 function afterType(type, value) { 616 625 if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType) 617 if (value == "|" || type == "." ) return cont(typeexpr)626 if (value == "|" || type == "." || value == "&") return cont(typeexpr) 618 627 if (type == "[") return cont(expect("]"), afterType) 619 if (value == "extends" ) return cont(typeexpr)628 if (value == "extends" || value == "implements") { cx.marked = "keyword"; return cont(typeexpr) } 620 629 } 621 630 function maybeTypeArgs(_, value) { … … 628 637 if (value == "=") return cont(typeexpr) 629 638 } 630 function vardef() { 639 function vardef(_, value) { 640 if (value == "enum") {cx.marked = "keyword"; return cont(enumdef)} 631 641 return pass(pattern, maybetype, maybeAssign, vardefCont); 632 642 } 633 643 function pattern(type, value) { 634 if ( type == "modifier") return cont(pattern)644 if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(pattern) } 635 645 if (type == "variable") { register(value); return cont(); } 636 646 if (type == "spread") return cont(pattern); … … 657 667 if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex); 658 668 } 659 function forspec(type) { 669 function forspec(type, value) { 670 if (value == "await") return cont(forspec); 660 671 if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex); 661 672 } … … 686 697 function funarg(type, value) { 687 698 if (value == "@") cont(expression, funarg) 688 if (type == "spread" || type == "modifier") return cont(funarg); 699 if (type == "spread") return cont(funarg); 700 if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(funarg); } 689 701 return pass(pattern, maybetype, maybeAssign); 690 702 } … … 699 711 function classNameAfter(type, value) { 700 712 if (value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, classNameAfter) 701 if (value == "extends" || value == "implements" || (isTS && type == ",")) 713 if (value == "extends" || value == "implements" || (isTS && type == ",")) { 714 if (value == "implements") cx.marked = "keyword"; 702 715 return cont(isTS ? typeexpr : expression, classNameAfter); 716 } 703 717 if (type == "{") return cont(pushlex("}"), classBody, poplex); 704 718 } 705 719 function classBody(type, value) { 706 if (type == " modifier" || type == "async" ||720 if (type == "async" || 707 721 (type == "variable" && 708 (value == "static" || value == "get" || value == "set" ) &&722 (value == "static" || value == "get" || value == "set" || (isTS && isModifier(value))) && 709 723 cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false))) { 710 724 cx.marked = "keyword"; … … 716 730 } 717 731 if (type == "[") 718 return cont(expression, expect("]"), isTS ? classfield : functiondef, classBody)732 return cont(expression, maybetype, expect("]"), isTS ? classfield : functiondef, classBody) 719 733 if (value == "*") { 720 734 cx.marked = "keyword"; … … 743 757 function afterImport(type) { 744 758 if (type == "string") return cont(); 759 if (type == "(") return pass(expression); 745 760 return pass(importSpec, maybeMoreImports, maybeFrom); 746 761 } … … 763 778 if (type == "]") return cont(); 764 779 return pass(commasep(expressionNoComma, "]")); 780 } 781 function enumdef() { 782 return pass(pushlex("form"), pattern, expect("{"), pushlex("}"), commasep(enummember, "}"), poplex, poplex) 783 } 784 function enummember() { 785 return pass(pattern, maybeAssign); 765 786 } 766 787 … … 787 808 lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), 788 809 localVars: parserConfig.localVars, 789 context: parserConfig.localVars && {vars: parserConfig.localVars},810 context: parserConfig.localVars && new Context(null, null, false), 790 811 indented: basecolumn || 0 791 812 }; … … 828 849 var type = lexical.type, closing = firstChar == type; 829 850 830 if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);851 if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info.length + 1 : 0); 831 852 else if (type == "form" && firstChar == "{") return lexical.indented; 832 853 else if (type == "form") return lexical.indented + indentUnit; -
admin/js/codemirror/mode/xml/xml.js
r3617 r3758 164 164 } 165 165 return style; 166 }; 167 } 166 } 167 } 168 168 169 function doctype(depth) { 169 170 return function(stream, state) {
Note: See TracChangeset
for help on using the changeset viewer.