From 7f302bfc2f329642f207e08cf6d06bd793ba07db Mon Sep 17 00:00:00 2001 From: ukyo Date: Sun, 30 Sep 2012 17:04:01 +0900 Subject: [PATCH 1/6] update coffeescript highlight rules --- lib/ace/mode/coffee_highlight_rules.js | 70 ++++++++++++++++++++------ 1 file changed, 55 insertions(+), 15 deletions(-) diff --git a/lib/ace/mode/coffee_highlight_rules.js b/lib/ace/mode/coffee_highlight_rules.js index 98ba0659..62200d97 100644 --- a/lib/ace/mode/coffee_highlight_rules.js +++ b/lib/ace/mode/coffee_highlight_rules.js @@ -45,25 +45,28 @@ define(function(require, exports, module) { }; var keywords = ( - "this|throw|then|try|typeof|super|switch|return|break|by)|continue|" + + "this|throw|then|try|typeof|super|switch|return|break|by|continue|" + "catch|class|in|instanceof|is|isnt|if|else|extends|for|forown|" + "finally|function|while|when|new|no|not|delete|debugger|do|loop|of|off|" + "or|on|unless|until|and|yes" ); var langConstant = ( - "true|false|null|undefined" + "true|false|null|undefined|NaN|Infinity" ); var illegal = ( "case|const|default|function|var|void|with|enum|export|implements|" + "interface|let|package|private|protected|public|static|yield|" + - "__hasProp|extends|slice|bind|indexOf" + "__hasProp|slice|bind|indexOf" ); var supportClass = ( - "Array|Boolean|Date|Function|Number|Object|RegExp|ReferenceError|" + - "String|RangeError|SyntaxError|Error|EvalError|TypeError|URIError" + "Array|Boolean|Date|Function|Number|Object|RegExp|ReferenceError|String|" + + "Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|" + + "SyntaxError|TypeError|URIError|" + + "ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|" + + "Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray" ); var supportFunction = ( @@ -71,26 +74,22 @@ define(function(require, exports, module) { "encodeURIComponent|decodeURI|decodeURIComponent|String|" ); + var variableLanguage = ( + "window|arguments|prototype|document" + ); + var keywordMapper = this.createKeywordMapper({ "keyword": keywords, "constant.language": langConstant, "invalid.illegal": illegal, "language.support.class": supportClass, "language.support.function": supportFunction, + "variable.language": variableLanguage }, "identifier"); this.$rules = { start : [ { - token : "identifier", - regex : "(?:(?:\\.|::)\\s*)" + identifier - }, { - token : "variable", - regex : "@(?:" + identifier + ")?" - }, { - token: keywordMapper, - regex : identifier - }, { token : "constant.numeric", regex : "(?:0x[\\da-fA-F]+|(?:\\d+(?:\\.\\d+)?|\\.\\d+)(?:[eE][+-]?\\d+)?)" }, { @@ -134,12 +133,53 @@ define(function(require, exports, module) { }, { token : "comment", regex : "#.*" + }, { + token : "punctuation.operator", + regex : "\\." + }, { + //class A extends B + token : [ + "keyword", "text", "language.support.class", "text", "keyword", "text", "language.support.class" + ], + regex : "(class)(\\s+)(" + identifier + ")(\\s+)(extends)(\\s+)(" + identifier + ")" + }, { + //class A + token : [ + "keyword", "text", "language.support.class" + ], + regex : "(class)(\\s+)(" + identifier + ")" + }, { + //play = (args) -> + //play : (args) -> + token : [ + "entity.name.function", "text", "keyword.operator", "text", + "paren.lparen", "variable.parameter", "paren.rparen", "text", "storage.type" + ], + regex : "(" + identifier + ")(\\s*)(=|:)(\\s*)(\\(?)([^)]*)(\\)?)(\\s*)([-=]>)" + }, { + //(args) -> + token : [ + "paren.lparen", "variable.parameter", "paren.rparen", "text", "storage.type" + ], + regex : "(\\()([^)]*)(\\))(\\s*)([\\-=]>)" + }, { + token : "identifier", + regex : "(?:(?:\\.|::)\\s*)" + identifier + }, { + token : "variable", + regex : "@(?:" + identifier + ")?" + }, { + token: keywordMapper, + regex : identifier }, { token : "punctuation.operator", regex : "\\?|\\:|\\,|\\." + }, { + token : "storage.type", + regex : "[\\-=]>" }, { token : "keyword.operator", - regex : "(?:[\\-=]>|[-+*/%<>&|^!?=]=|>>>=?|\\-\\-|\\+\\+|::|&&=|\\|\\|=|<<=|>>=|\\?\\.|\\.{2,3}|[!*+-=><])" + regex : "(?:[-+*/%<>&|^!?=]=|>>>=?|\\-\\-|\\+\\+|::|&&=|\\|\\|=|<<=|>>=|\\?\\.|\\.{2,3}|[!*+-=><])" }, { token : "paren.lparen", regex : "[({[]" From 663fae408eacaadc24112f379faff8ce32a6c021 Mon Sep 17 00:00:00 2001 From: ukyo Date: Sun, 30 Sep 2012 17:39:35 +0900 Subject: [PATCH 2/6] small fix about illegal keywords --- lib/ace/mode/coffee_highlight_rules.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/ace/mode/coffee_highlight_rules.js b/lib/ace/mode/coffee_highlight_rules.js index 62200d97..c0aab565 100644 --- a/lib/ace/mode/coffee_highlight_rules.js +++ b/lib/ace/mode/coffee_highlight_rules.js @@ -133,6 +133,11 @@ define(function(require, exports, module) { }, { token : "comment", regex : "#.*" + }, { + token : [ + "punctuation.operator", "identifier" + ], + regex : "(\\.)(" + illegal + ")" }, { token : "punctuation.operator", regex : "\\." From 706652048f6f64a8eea292fb4e73cc6eed9922f9 Mon Sep 17 00:00:00 2001 From: ukyo Date: Sun, 30 Sep 2012 18:58:45 +0900 Subject: [PATCH 3/6] small fix and add tests --- lib/ace/mode/coffee_highlight_rules.js | 9 +- lib/ace/mode/coffee_highlight_rules_test.js | 106 ++++++++++++++++++++ 2 files changed, 114 insertions(+), 1 deletion(-) diff --git a/lib/ace/mode/coffee_highlight_rules.js b/lib/ace/mode/coffee_highlight_rules.js index c0aab565..7921c486 100644 --- a/lib/ace/mode/coffee_highlight_rules.js +++ b/lib/ace/mode/coffee_highlight_rules.js @@ -160,7 +160,14 @@ define(function(require, exports, module) { "entity.name.function", "text", "keyword.operator", "text", "paren.lparen", "variable.parameter", "paren.rparen", "text", "storage.type" ], - regex : "(" + identifier + ")(\\s*)(=|:)(\\s*)(\\(?)([^)]*)(\\)?)(\\s*)([-=]>)" + regex : "(" + identifier + ")(\\s*)(=|:)(\\s*)(\\()([^)]*)(\\))(\\s*)([\\-=]>)" + }, { + //play = -> + //play : -> + token : [ + "entity.name.function", "text", "keyword.operator", "text", "storage.type" + ], + regex : "(" + identifier + ")(\\s*)(=|:)(\\s*)([\\-=]>)" }, { //(args) -> token : [ diff --git a/lib/ace/mode/coffee_highlight_rules_test.js b/lib/ace/mode/coffee_highlight_rules_test.js index eaf85531..b8ac39c5 100644 --- a/lib/ace/mode/coffee_highlight_rules_test.js +++ b/lib/ace/mode/coffee_highlight_rules_test.js @@ -48,7 +48,113 @@ module.exports = { assert.equal(tokens.length, 1); assert.equal(tokens[0].type, "keyword"); }, + + "test: tokenize function: 'foo = (args) ->'": function() { + var tokens = this.tokenizer.getLineTokens("foo = (args) ->", "start").tokens; + console.log(tokens); + assert.equal(tokens.length, 9); + [ + "entity.name.function", "text", "keyword.operator", "text", + "paren.lparen", "variable.parameter", "paren.rparen", "text", "storage.type" + ].forEach(function(type, i) { + assert.equal(tokens[i].type, type); + }); + }, + "test: tokenize function: 'window.foo = (args) ->'": function() { + var tokens = this.tokenizer.getLineTokens("window.foo = (args) ->", "start").tokens; + console.log(tokens); + assert.equal(tokens.length, 11); + [ + "variable.language", "punctuation.operator", "entity.name.function", "text", "keyword.operator", "text", + "paren.lparen", "variable.parameter", "paren.rparen", "text", "storage.type" + ].forEach(function(type, i) { + assert.equal(tokens[i].type, type); + }); + }, + + "test: tokenize function: 'foo : (args) ->'": function() { + var tokens = this.tokenizer.getLineTokens("foo : (args) ->", "start").tokens; + assert.equal(tokens.length, 9); + [ + "entity.name.function", "text", "keyword.operator", "text", + "paren.lparen", "variable.parameter", "paren.rparen", "text", "storage.type" + ].forEach(function(type, i) { + assert.equal(tokens[i].type, type); + }); + }, + + "test: tokenize function: 'foo = ->'": function() { + var tokens = this.tokenizer.getLineTokens("foo = ->", "start").tokens; + assert.equal(tokens.length, 5); + [ + "entity.name.function", "text", "keyword.operator", "text", "storage.type" + ].forEach(function(type, i) { + assert.equal(tokens[i].type, type); + }); + }, + + "test: tokenize function: 'foo : ->'": function() { + var tokens = this.tokenizer.getLineTokens("foo : ->", "start").tokens; + assert.equal(tokens.length, 5); + [ + "entity.name.function", "text", "keyword.operator", "text", "storage.type" + ].forEach(function(type, i) { + assert.equal(tokens[i].type, type); + }); + }, + + "test: tokenize function: '(args) ->'": function() { + var tokens = this.tokenizer.getLineTokens("(args) ->", "start").tokens; + assert.equal(tokens.length, 5); + [ + "paren.lparen", "variable.parameter", "paren.rparen", "text", "storage.type" + ].forEach(function(type, i) { + assert.equal(tokens[i].type, type); + }); + }, + + "test: tokenize function(callback): 'foo bar: 1, (args) ->'": function() { + var tokens = this.tokenizer.getLineTokens("foo bar: 1, (args) ->", "start").tokens; + assert.equal(tokens.length, 13); + [ + "identifier", "text", "identifier", "punctuation.operator", "text", "constant.numeric", "punctuation.operator", "text", + "paren.lparen", "variable.parameter", "paren.rparen", "text", "storage.type" + ].forEach(function(type, i) { + assert.equal(tokens[i].type, type); + }); + }, + + "test: tokenize class: 'class Foo'": function() { + var tokens = this.tokenizer.getLineTokens("class Foo", "start").tokens; + assert.equal(tokens.length, 3); + [ + "keyword", "text", "language.support.class" + ].forEach(function(type, i) { + assert.equal(tokens[i].type, type); + }); + }, + + "test: tokenize class 'class Foo extends Bar'": function() { + var tokens = this.tokenizer.getLineTokens("class Foo extends Bar", "start").tokens; + assert.equal(tokens.length, 7); + [ + "keyword", "text", "language.support.class", "text", "keyword", "text", "language.support.class" + ].forEach(function(type, i) { + assert.equal(tokens[i].type, type); + }); + }, + + "test: tokenize illegal name property: 'foo.static.function'": function() { + var tokens = this.tokenizer.getLineTokens("foo.static.function", "start").tokens; + assert.equal(tokens.length, 5); + [ + "identifier", "punctuation.operator", "identifier", "punctuation.operator", "identifier" + ].forEach(function(type, i) { + assert.equal(tokens[i].type, type); + }); + }, + // TODO: disable. not yet implemented "!test tokenize string with interpolation": function() { var tokens = this.tokenizer.getLineTokens('"#{ 22 / 7 } is a decent approximation of π"', "start").tokens; From ffa03315424a8cd3cc0d8912182f545e943b8130 Mon Sep 17 00:00:00 2001 From: ukyo Date: Sun, 30 Sep 2012 20:20:36 +0900 Subject: [PATCH 4/6] fix function regexp --- lib/ace/mode/coffee_highlight_rules.js | 6 ++++-- lib/ace/mode/coffee_highlight_rules_test.js | 11 +++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/ace/mode/coffee_highlight_rules.js b/lib/ace/mode/coffee_highlight_rules.js index 7921c486..a6732a9e 100644 --- a/lib/ace/mode/coffee_highlight_rules.js +++ b/lib/ace/mode/coffee_highlight_rules.js @@ -87,6 +87,8 @@ define(function(require, exports, module) { "variable.language": variableLanguage }, "identifier"); + var functionRe = "(\\()([^)#]*)(\\))(\\s*)([\\-=]>)" + this.$rules = { start : [ { @@ -160,7 +162,7 @@ define(function(require, exports, module) { "entity.name.function", "text", "keyword.operator", "text", "paren.lparen", "variable.parameter", "paren.rparen", "text", "storage.type" ], - regex : "(" + identifier + ")(\\s*)(=|:)(\\s*)(\\()([^)]*)(\\))(\\s*)([\\-=]>)" + regex : "(" + identifier + ")(\\s*)(=|:)(\\s*)" + functionRe }, { //play = -> //play : -> @@ -173,7 +175,7 @@ define(function(require, exports, module) { token : [ "paren.lparen", "variable.parameter", "paren.rparen", "text", "storage.type" ], - regex : "(\\()([^)]*)(\\))(\\s*)([\\-=]>)" + regex : functionRe }, { token : "identifier", regex : "(?:(?:\\.|::)\\s*)" + identifier diff --git a/lib/ace/mode/coffee_highlight_rules_test.js b/lib/ace/mode/coffee_highlight_rules_test.js index b8ac39c5..e1afa251 100644 --- a/lib/ace/mode/coffee_highlight_rules_test.js +++ b/lib/ace/mode/coffee_highlight_rules_test.js @@ -104,6 +104,17 @@ module.exports = { }); }, + + "test: tokenize function(invalid code): 'foo:(args#) ->'": function() { + var tokens = this.tokenizer.getLineTokens("foo:(args#) ->", "start").tokens; + assert.equal(tokens.length, 5); + [ + "identifier", "punctuation.operator", "paren.lparen", "identifier", "comment" + ].forEach(function(type, i) { + assert.equal(tokens[i].type, type); + }); + }, + "test: tokenize function: '(args) ->'": function() { var tokens = this.tokenizer.getLineTokens("(args) ->", "start").tokens; assert.equal(tokens.length, 5); From 1510119e7f4c658d05d66f2d1829d89aebc91d2a Mon Sep 17 00:00:00 2001 From: ukyo Date: Mon, 1 Oct 2012 00:18:47 +0900 Subject: [PATCH 5/6] add function regexps and tests --- lib/ace/mode/coffee_highlight_rules.js | 63 ++++- lib/ace/mode/coffee_highlight_rules_test.js | 249 +++++++++++++------- 2 files changed, 220 insertions(+), 92 deletions(-) diff --git a/lib/ace/mode/coffee_highlight_rules.js b/lib/ace/mode/coffee_highlight_rules.js index a6732a9e..2da2c1d9 100644 --- a/lib/ace/mode/coffee_highlight_rules.js +++ b/lib/ace/mode/coffee_highlight_rules.js @@ -87,7 +87,27 @@ define(function(require, exports, module) { "variable.language": variableLanguage }, "identifier"); - var functionRe = "(\\()([^)#]*)(\\))(\\s*)([\\-=]>)" + var headRe = "[$A-Za-z_\\x7f-\\uffff]"; + + var functionRe = { + "({args})->": { + token: ["paren.lparen", "text", "paren.lparen", "text", "variable.parameter", "text", "paren.rparen", "text", "paren.rparen", "text", "storage.type"], + regex: "(\\()(\\s*)(\\{)(\\s*)(" + [headRe, headRe + "[$\\w\\s,\\x7f-\\uffff]*"].join("|") + ")(\\s*)(\\})(\\s*)(\\))(\\s*)([\\-=]>)" + }, + "({})->": { + token: ["paren.lparen", "text", "paren.lparen", "text", "paren.rparen", "text", "paren.rparen", "text", "storage.type"], + regex: "(\\()(\\s*)(\\{)(\\s*)(\\})(\\s*)(\\))(\\s*)([\\-=]>)" + }, + "(args)->": { + token: ["paren.lparen", "text", "variable.parameter", "text", "paren.rparen", "text", "storage.type"], + regex: "(\\()(\\s*)(" + [headRe, headRe + "[$\\w\\x7f-\\uffff]", headRe + "[^#)]*[^#(){}=,\\/\\\\]"].join("|") + ")(\\s*)(\\))(\\s*)([\\-=]>)" + }, + "()->": { + token: ["paren.lparen", "text", "paren.rparen", "text", "storage.type"], + regex: "(\\()(\\s*)(\\))(\\s*)([\\-=]>)" + } + }; + this.$rules = { start : [ @@ -155,14 +175,34 @@ define(function(require, exports, module) { "keyword", "text", "language.support.class" ], regex : "(class)(\\s+)(" + identifier + ")" + }, { + //play = ({args}) -> + //play : ({args}) -> + token : [ + "entity.name.function", "text", "keyword.operator", "text" + ].concat(functionRe["({args})->"].token), + regex : "(" + identifier + ")(\\s*)(=|:)(\\s*)" + functionRe["({args})->"].regex + }, { + //play = ({}) -> + //play : ({}) -> + token : [ + "entity.name.function", "text", "keyword.operator", "text" + ].concat(functionRe["({})->"].token), + regex : "(" + identifier + ")(\\s*)(=|:)(\\s*)" + functionRe["({})->"].regex }, { //play = (args) -> //play : (args) -> token : [ - "entity.name.function", "text", "keyword.operator", "text", - "paren.lparen", "variable.parameter", "paren.rparen", "text", "storage.type" - ], - regex : "(" + identifier + ")(\\s*)(=|:)(\\s*)" + functionRe + "entity.name.function", "text", "keyword.operator", "text" + ].concat(functionRe["(args)->"].token), + regex : "(" + identifier + ")(\\s*)(=|:)(\\s*)" + functionRe["(args)->"].regex + }, { + //play = () -> + //play : () -> + token : [ + "entity.name.function", "text", "keyword.operator", "text" + ].concat(functionRe["()->"].token), + regex : "(" + identifier + ")(\\s*)(=|:)(\\s*)" + functionRe["()->"].regex }, { //play = -> //play : -> @@ -170,13 +210,12 @@ define(function(require, exports, module) { "entity.name.function", "text", "keyword.operator", "text", "storage.type" ], regex : "(" + identifier + ")(\\s*)(=|:)(\\s*)([\\-=]>)" - }, { - //(args) -> - token : [ - "paren.lparen", "variable.parameter", "paren.rparen", "text", "storage.type" - ], - regex : functionRe - }, { + }, + functionRe["({args})->"], + functionRe["({})->"], + functionRe["(args)->"], + functionRe["()->"] + , { token : "identifier", regex : "(?:(?:\\.|::)\\s*)" + identifier }, { diff --git a/lib/ace/mode/coffee_highlight_rules_test.js b/lib/ace/mode/coffee_highlight_rules_test.js index e1afa251..d3914f02 100644 --- a/lib/ace/mode/coffee_highlight_rules_test.js +++ b/lib/ace/mode/coffee_highlight_rules_test.js @@ -41,6 +41,11 @@ var assert = require("../test/assertions"); module.exports = { setUp : function() { this.tokenizer = new Mode().getTokenizer(); + this.testTokens = function(tokens, correct) { + correct.forEach(function(type, i) { + assert.equal(tokens[i].type, type); + }); + }; }, "test: tokenize keyword": function() { @@ -49,121 +54,205 @@ module.exports = { assert.equal(tokens[0].type, "keyword"); }, - "test: tokenize function: 'foo = (args) ->'": function() { - var tokens = this.tokenizer.getLineTokens("foo = (args) ->", "start").tokens; - console.log(tokens); - assert.equal(tokens.length, 9); - [ + "test: tokenize function: 'foo = ({args}) ->'": function() { + var tokens = this.tokenizer.getLineTokens("foo = ({args}) ->", "start").tokens; + var correct = [ "entity.name.function", "text", "keyword.operator", "text", - "paren.lparen", "variable.parameter", "paren.rparen", "text", "storage.type" - ].forEach(function(type, i) { - assert.equal(tokens[i].type, type); - }); - }, - - "test: tokenize function: 'window.foo = (args) ->'": function() { - var tokens = this.tokenizer.getLineTokens("window.foo = (args) ->", "start").tokens; - console.log(tokens); + "paren.lparen", "paren.lparen", "variable.parameter", "paren.rparen", "paren.rparen", "text", "storage.type" + ]; + assert.equal(tokens.length, 11); - [ - "variable.language", "punctuation.operator", "entity.name.function", "text", "keyword.operator", "text", - "paren.lparen", "variable.parameter", "paren.rparen", "text", "storage.type" - ].forEach(function(type, i) { - assert.equal(tokens[i].type, type); - }); + this.testTokens(tokens, correct); + + tokens = this.tokenizer.getLineTokens("foo = ({arg1, arg2}) ->", "start").tokens; + assert.equal(tokens.length, 11); + this.testTokens(tokens, correct); + + tokens = this.tokenizer.getLineTokens("foo : ({arg1, arg2}) ->", "start").tokens; + assert.equal(tokens.length, 11); + this.testTokens(tokens, correct); }, - "test: tokenize function: 'foo : (args) ->'": function() { - var tokens = this.tokenizer.getLineTokens("foo : (args) ->", "start").tokens; - assert.equal(tokens.length, 9); - [ + "test: tokenize function: invalid case: 'foo = ({args}) ->'": function() { + var tokens = this.tokenizer.getLineTokens("foo = ({0abc}) ->", "start").tokens; + assert.notEqual(tokens[0].type, "entity.name.function"); + + tokens = this.tokenizer.getLineTokens("foo = ({/abc}) ->", "start").tokens; + assert.notEqual(tokens[0].type, "entity.name.function"); + + tokens = this.tokenizer.getLineTokens("foo = ({abc/}) ->", "start").tokens; + assert.notEqual(tokens[0].type, "entity.name.function"); + + tokens = this.tokenizer.getLineTokens("foo = ({#abc}) ->", "start").tokens; + assert.notEqual(tokens[0].type, "entity.name.function"); + + tokens = this.tokenizer.getLineTokens("foo = ({abc#}) ->", "start").tokens; + assert.notEqual(tokens[0].type, "entity.name.function"); + + tokens = this.tokenizer.getLineTokens("foo = ({)abc}) ->", "start").tokens; + assert.notEqual(tokens[0].type, "entity.name.function"); + + tokens = this.tokenizer.getLineTokens("foo = ({abc)}) ->", "start").tokens; + assert.notEqual(tokens[0].type, "entity.name.function"); + + tokens = this.tokenizer.getLineTokens("foo = ({a{bc}) ->", "start").tokens; + assert.notEqual(tokens[0].type, "entity.name.function"); + }, + + "test: tokenize function: 'foo = ({}) ->'": function() { + var tokens = this.tokenizer.getLineTokens("foo = ({}) ->", "start").tokens; + var correct = [ + "entity.name.function", "text", "keyword.operator", "text", + "paren.lparen", "paren.lparen", "paren.rparen", "paren.rparen", "text", "storage.type" + ]; + + assert.equal(tokens.length, 10); + this.testTokens(tokens, correct); + + tokens = this.tokenizer.getLineTokens("foo : ({}) ->", "start").tokens; + assert.equal(tokens.length, 10); + this.testTokens(tokens, correct); + + tokens = this.tokenizer.getLineTokens("foo = ({ }) ->", "start").tokens; + correct = [ + "entity.name.function", "text", "keyword.operator", "text", + "paren.lparen", "paren.lparen", "text", "paren.rparen", "paren.rparen", "text", "storage.type" + ]; + assert.equal(tokens.length, 11); + this.testTokens(tokens, correct); + }, + + "test: tokenize function: 'foo = (args) ->'": function() { + var tokens = this.tokenizer.getLineTokens("foo = (args) ->", "start").tokens; + var correct = [ "entity.name.function", "text", "keyword.operator", "text", "paren.lparen", "variable.parameter", "paren.rparen", "text", "storage.type" - ].forEach(function(type, i) { - assert.equal(tokens[i].type, type); - }); + ]; + assert.equal(tokens.length, 9); + this.testTokens(tokens, correct); + + tokens = this.tokenizer.getLineTokens("foo = (arg1, arg2) ->", "start").tokens; + assert.equal(tokens.length, 9); + this.testTokens(tokens, correct); + + tokens = this.tokenizer.getLineTokens("foo = (arg1 = 1, arg2 = 'name') ->", "start").tokens; + assert.equal(tokens.length, 9); + this.testTokens(tokens, correct); + }, + + "test: tokenize function: invalid case: 'foo=(args) ->'": function() { + var tokens = this.tokenizer.getLineTokens("foo=(args#) ->", "start").tokens; + assert.notEqual(tokens[0].type, "entity.name.function"); + + tokens = this.tokenizer.getLineTokens("foo=(args=) ->", "start").tokens; + assert.notEqual(tokens[0].type, "entity.name.function"); + + tokens = this.tokenizer.getLineTokens("foo=(args{) ->", "start").tokens; + assert.notEqual(tokens[0].type, "entity.name.function"); + + tokens = this.tokenizer.getLineTokens("foo=(args}) ->", "start").tokens; + assert.notEqual(tokens[0].type, "entity.name.function"); + + tokens = this.tokenizer.getLineTokens("foo=(}args) ->", "start").tokens; + assert.notEqual(tokens[0].type, "entity.name.function"); + + tokens = this.tokenizer.getLineTokens("foo=(a)rgs) ->", "start").tokens; + assert.notEqual(tokens[0].type, "entity.name.function"); + + tokens = this.tokenizer.getLineTokens("foo=(args/) ->", "start").tokens; + assert.notEqual(tokens[0].type, "entity.name.function"); + + tokens = this.tokenizer.getLineTokens("foo=(args\\) ->", "start").tokens; + assert.notEqual(tokens[0].type, "entity.name.function"); + }, + + "test: tokenize function: 'foo = () ->'": function() { + var tokens = this.tokenizer.getLineTokens("foo = () ->", "start").tokens; + var correct = [ + "entity.name.function", "text", "keyword.operator", "text", + "paren.lparen", "paren.rparen", "text", "storage.type" + ]; + + assert.equal(tokens.length, 8); + this.testTokens(tokens, correct); + + tokens = this.tokenizer.getLineTokens("foo : ( ) ->", "start").tokens; + correct = [ + "entity.name.function", "text", "keyword.operator", "text", + "paren.lparen", "text", "paren.rparen", "text", "storage.type" + ]; + assert.equal(tokens.length, 9); + this.testTokens(tokens, correct); + }, + + "test: tokenize function: 'window.foo = (args) ->'": function() { + var tokens = this.tokenizer.getLineTokens("window.foo = (args) ->", "start").tokens; + var correct = [ + "variable.language", "punctuation.operator", "entity.name.function", "text", "keyword.operator", "text", + "paren.lparen", "variable.parameter", "paren.rparen", "text", "storage.type" + ]; + + assert.equal(tokens.length, 11); + this.testTokens(tokens, correct); + + this.tokenizer.getLineTokens("window.foo = (args) ->", "start").tokens; + assert.equal(tokens.length, 11); + this.testTokens(tokens, correct); }, "test: tokenize function: 'foo = ->'": function() { var tokens = this.tokenizer.getLineTokens("foo = ->", "start").tokens; - assert.equal(tokens.length, 5); - [ + var correct = [ "entity.name.function", "text", "keyword.operator", "text", "storage.type" - ].forEach(function(type, i) { - assert.equal(tokens[i].type, type); - }); - }, + ]; - "test: tokenize function: 'foo : ->'": function() { - var tokens = this.tokenizer.getLineTokens("foo : ->", "start").tokens; assert.equal(tokens.length, 5); - [ - "entity.name.function", "text", "keyword.operator", "text", "storage.type" - ].forEach(function(type, i) { - assert.equal(tokens[i].type, type); - }); - }, + this.testTokens(tokens, correct); - - "test: tokenize function(invalid code): 'foo:(args#) ->'": function() { - var tokens = this.tokenizer.getLineTokens("foo:(args#) ->", "start").tokens; + this.tokenizer.getLineTokens("foo : ->", "start").tokens; assert.equal(tokens.length, 5); - [ - "identifier", "punctuation.operator", "paren.lparen", "identifier", "comment" - ].forEach(function(type, i) { - assert.equal(tokens[i].type, type); - }); + this.testTokens(tokens, correct); }, - "test: tokenize function: '(args) ->'": function() { - var tokens = this.tokenizer.getLineTokens("(args) ->", "start").tokens; - assert.equal(tokens.length, 5); - [ - "paren.lparen", "variable.parameter", "paren.rparen", "text", "storage.type" - ].forEach(function(type, i) { - assert.equal(tokens[i].type, type); - }); - }, - - "test: tokenize function(callback): 'foo bar: 1, (args) ->'": function() { + "test: tokenize callback function: 'foo bar: 1, (args) ->'": function() { var tokens = this.tokenizer.getLineTokens("foo bar: 1, (args) ->", "start").tokens; - assert.equal(tokens.length, 13); - [ + var correct = [ "identifier", "text", "identifier", "punctuation.operator", "text", "constant.numeric", "punctuation.operator", "text", "paren.lparen", "variable.parameter", "paren.rparen", "text", "storage.type" - ].forEach(function(type, i) { - assert.equal(tokens[i].type, type); - }); + ]; + + assert.equal(tokens.length, 13); + this.testTokens(tokens, correct); }, "test: tokenize class: 'class Foo'": function() { var tokens = this.tokenizer.getLineTokens("class Foo", "start").tokens; - assert.equal(tokens.length, 3); - [ + var correct = [ "keyword", "text", "language.support.class" - ].forEach(function(type, i) { - assert.equal(tokens[i].type, type); - }); + ]; + + assert.equal(tokens.length, 3); + this.testTokens(tokens, correct); }, "test: tokenize class 'class Foo extends Bar'": function() { var tokens = this.tokenizer.getLineTokens("class Foo extends Bar", "start").tokens; - assert.equal(tokens.length, 7); - [ + var correct = [ "keyword", "text", "language.support.class", "text", "keyword", "text", "language.support.class" - ].forEach(function(type, i) { - assert.equal(tokens[i].type, type); - }); + ]; + + assert.equal(tokens.length, 7); + this.testTokens(tokens, correct); }, "test: tokenize illegal name property: 'foo.static.function'": function() { var tokens = this.tokenizer.getLineTokens("foo.static.function", "start").tokens; - assert.equal(tokens.length, 5); - [ + var correct = [ "identifier", "punctuation.operator", "identifier", "punctuation.operator", "identifier" - ].forEach(function(type, i) { - assert.equal(tokens[i].type, type); - }); + ]; + + assert.equal(tokens.length, 5); + this.testTokens(tokens, correct); }, // TODO: disable. not yet implemented From 4d91fac145637c9e92c14d7fb9273a698a47e4dc Mon Sep 17 00:00:00 2001 From: ukyo Date: Mon, 1 Oct 2012 15:58:18 +0900 Subject: [PATCH 6/6] fix regexp --- lib/ace/mode/coffee_highlight_rules.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ace/mode/coffee_highlight_rules.js b/lib/ace/mode/coffee_highlight_rules.js index 2da2c1d9..98253f49 100644 --- a/lib/ace/mode/coffee_highlight_rules.js +++ b/lib/ace/mode/coffee_highlight_rules.js @@ -92,7 +92,7 @@ define(function(require, exports, module) { var functionRe = { "({args})->": { token: ["paren.lparen", "text", "paren.lparen", "text", "variable.parameter", "text", "paren.rparen", "text", "paren.rparen", "text", "storage.type"], - regex: "(\\()(\\s*)(\\{)(\\s*)(" + [headRe, headRe + "[$\\w\\s,\\x7f-\\uffff]*"].join("|") + ")(\\s*)(\\})(\\s*)(\\))(\\s*)([\\-=]>)" + regex: "(\\()(\\s*)(\\{)(\\s*)(" + headRe + "[$\\w\\s,\\x7f-\\uffff]*" + ")(\\s*)(\\})(\\s*)(\\))(\\s*)([\\-=]>)" }, "({})->": { token: ["paren.lparen", "text", "paren.lparen", "text", "paren.rparen", "text", "paren.rparen", "text", "storage.type"],