From 5f7884657a76db6ca98fbdd891c6ee05654b1953 Mon Sep 17 00:00:00 2001 From: Garen Torikian Date: Sat, 10 Nov 2012 14:59:53 -0800 Subject: [PATCH] Add Dart support --- demo/kitchen-sink/doclist.js | 1 + demo/kitchen-sink/docs/dart.dart | 58 ++++++++ demo/kitchen-sink/modelist.js | 1 + lib/ace/mode/dart.js | 60 +++++++++ lib/ace/mode/dart_highlight_rules.js | 192 +++++++++++++++++++++++++++ lib/ace/tokenizer.js | 2 +- tool/mode_highlight_rules.tmpl.js | 2 +- tool/tmlanguage.js | 5 +- 8 files changed, 317 insertions(+), 4 deletions(-) create mode 100644 demo/kitchen-sink/docs/dart.dart create mode 100644 lib/ace/mode/dart.js create mode 100644 lib/ace/mode/dart_highlight_rules.js diff --git a/demo/kitchen-sink/doclist.js b/demo/kitchen-sink/doclist.js index 70b23e0d..68ffeb42 100644 --- a/demo/kitchen-sink/doclist.js +++ b/demo/kitchen-sink/doclist.js @@ -72,6 +72,7 @@ var docs = { "docs/cpp.cpp": "C/C++", "docs/csharp.cs": "C#", "docs/css.css": "CSS", + "docs/dart.dart": "Dart", "docs/diff.diff": "Diff", "docs/glsl.glsl": "Glsl", "docs/golang.go": "Go", diff --git a/demo/kitchen-sink/docs/dart.dart b/demo/kitchen-sink/docs/dart.dart new file mode 100644 index 00000000..8700c8cd --- /dev/null +++ b/demo/kitchen-sink/docs/dart.dart @@ -0,0 +1,58 @@ +main() { + print('Hello World!'); +} + + +int fib(int n) => (n > 1) ? (fib(n - 1) + fib(n - 2)) : n; +main() { + print('fib(20) = ${fib(20)}'); +} +/*asd +asdad +*/ +0.67 +77 +.86 + +#import("http://dartwatch.com/myOtherLibrary.dart"); +#import("myOtherLibrary.dart", prefix:"lib1"); + +"""asdasdads +asdadsadsasd +asdasdasdad""" + +'23424' + +0x234 + +foo is bar + +int x = 4 << 10 +// Create a class for Point. +class Point { + + // Final variables cannot be changed once they are assigned. + // Create two instance variables. + final num x, y; + + // A constructor, with syntactic sugar for setting instance variables. + Point(this.x, this.y); + + // A named constructor with an initializer list. + Point.origin() : x = 0, y = 0; + + // A method. + num distanceTo(Point other) { + var dx = x - other.x; + var dy = y - other.y; + return sqrt(dx * dx + dy * dy); + } +} + + // Check for null. +var unicorn; +assert(unicorn == null); + +// Check for NaN. +var iMeantToDoThis = 0/0; +assert(iMeantToDoThis.isNaN()); diff --git a/demo/kitchen-sink/modelist.js b/demo/kitchen-sink/modelist.js index 06c62362..cf67a267 100644 --- a/demo/kitchen-sink/modelist.js +++ b/demo/kitchen-sink/modelist.js @@ -41,6 +41,7 @@ var modesByName = { coldfusion: ["ColdFusion" , "cfm"], csharp: ["C#" , "cs"], css: ["CSS" , "css"], + dart: ["Dart" , "dart"], diff: ["Diff" , "diff|patch"], glsl: ["Glsl" , "glsl|frag|vert"], golang: ["Go" , "go"], diff --git a/lib/ace/mode/dart.js b/lib/ace/mode/dart.js new file mode 100644 index 00000000..9f1aa48a --- /dev/null +++ b/lib/ace/mode/dart.js @@ -0,0 +1,60 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2012, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Ajax.org B.V. nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * Contributor(s): + * + * + * + * ***** END LICENSE BLOCK ***** */ + +/* + THIS FILE WAS AUTOGENERATED BY mode.tmpl.js +*/ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var Tokenizer = require("../tokenizer").Tokenizer; +var DartHighlightRules = require("./dart_highlight_rules").DartHighlightRules; + +var Mode = function() { + var highlighter = new DartHighlightRules(); + + this.$tokenizer = new Tokenizer(highlighter.getRules()); +}; +oop.inherits(Mode, TextMode); + +(function() { + // Extra logic goes here. +}).call(Mode.prototype); + +exports.Mode = Mode; +}); \ No newline at end of file diff --git a/lib/ace/mode/dart_highlight_rules.js b/lib/ace/mode/dart_highlight_rules.js new file mode 100644 index 00000000..4d618086 --- /dev/null +++ b/lib/ace/mode/dart_highlight_rules.js @@ -0,0 +1,192 @@ +/* + THIS FILE WAS AUTOGENERATED BY mode_highlight_rules.tmpl.js (UUID: 958518BC-799F-477A-99F9-5B28EBF230F6) */ + + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var DartHighlightRules = function() { + + var constantLanguage = "true|false|null"; + var variableLanguage = "this|super"; + var keywordControl = "try|catch|finally|throw|break|case|continue|default|do|else|for|if|in|return|switch|while|new"; + var keywordDeclaration = "abstract|class|extends|external|factory|implements|interface|get|native|operator|set|typedef"; + var storageModifier = "static|final|const"; + var storageType = "void|bool|num|int|double|Dynamic|var|String"; + + var keywordMapper = this.createKeywordMapper({ + "constant.language.dart": constantLanguage, + "variable.language.dart": variableLanguage, + "keyword.control.dart": keywordControl, + "keyword.declaration.dart": keywordDeclaration, + "storage.modifier.dart": storageModifier, + "storage.type.primitive.dart": storageType + }, "identifier"); + + var stringfill = { + token : "string", + merge : true, + regex : ".+" + }; + + // regexp must not have capturing parentheses. Use (?:) instead. + // regexps are ordered -> the first match is used + + this.$rules = + { + "start": [ + { + "token" : "comment", + "regex" : /\/\/.*$/ + }, + { + "token" : "comment", // multi line comment + "merge" : true, + "regex" : /\/\*/, + "next" : "comment" + }, + { + "token": ["meta.preprocessor.script.dart"], + "regex": "^(#!.*)$" + }, + { + "token": [ "keyword.other.import.dart", "meta.declaration.dart"], + "regex": "#(?:\\b)(?:library|import|source|resource)(?:\\b)" + }, + { + "token" : ["keyword.other.import.dart", "text"], + "regex" : "(?:\\b)(prefix)(\\s*:)" + }, + { + "regex": "\\bas\\b", + "token": "keyword.cast.dart" + }, + { + "regex": "\\?|:", + "token": "keyword.control.ternary.dart" + }, + { + "regex": "(?:\\b)(is\\!?)(?:\\b)", + "token": ["keyword.operator.dart"] + }, + { + "regex": "(<<|>>>?|~|\\^|\\||&)", + "token": ["keyword.operator.bitwise.dart"] + }, + { + "regex": "((?:&|\\^|\\||<<|>>>?)=)", + "token": ["keyword.operator.assignment.bitwise.dart"] + }, + { + "regex": "(===?|!==?|<=?|>=?)", + "token": ["keyword.operator.comparison.dart"] + }, + { + "regex": "((?:[+*/%-]|\\~)=)", + "token": ["keyword.operator.assignment.arithmetic.dart"] + }, + { + "regex": "=", + "token": "keyword.operator.assignment.dart" + }, + { + "token" : "string", + "merge" : true, + "regex" : "'''", + "next" : "qdoc" + }, + { + "token" : "string", + "merge" : true, + "regex" : '"""', + "next" : "qqdoc" + }, + { + "token" : "string", + "merge" : true, + "regex" : "'", + "next" : "qstring" + }, + { + "token" : "string", + "merge" : true, + "regex" : '"', + "next" : "qqstring" + }, + { + "regex": "(\\-\\-|\\+\\+)", + "token": ["keyword.operator.increment-decrement.dart"] + }, + { + "regex": "(\\-|\\+|\\*|\\/|\\~\\/|%)", + "token": ["keyword.operator.arithmetic.dart"] + }, + { + "regex": "(!|&&|\\|\\|)", + "token": ["keyword.operator.logical.dart"] + }, + { + "token" : "constant.numeric", // hex + "regex" : "0[xX][0-9a-fA-F]+\\b" + }, + { + "token" : "constant.numeric", // float + "regex" : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" + }, + { + "token" : keywordMapper, + "regex" : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b" + } + ], + "comment" : [ + { + token : "comment", // closing comment + regex : ".*?\\*\\/", + merge : true, + next : "start" + }, { + token : "comment", // comment spanning whole line + merge : true, + regex : ".+" + } + ], + "qdoc" : [ + { + "token" : "string", + "regex" : ".*?'''", + "next" : "start" + }, stringfill], + + "qqdoc" : [ + { + "token" : "string", + "regex" : '.*?"""', + "next" : "start" + }, stringfill], + + "qstring" : [ + { + "token" : "string", + "regex" : "[^\\\\']*(?:\\\\.[^\\\\']*)*'", + "merge" : true, + "next" : "start" + }, stringfill], + + "qqstring" : [ + { + "token" : "string", + "regex" : '[^\\\\"]*(?:\\\\.[^\\\\"]*)*"', + "merge" : true, + "next" : "start" + }, stringfill] +} + +}; + +oop.inherits(DartHighlightRules, TextHighlightRules); + +exports.DartHighlightRules = DartHighlightRules; +}); diff --git a/lib/ace/tokenizer.js b/lib/ace/tokenizer.js index 955e8772..565e2cde 100644 --- a/lib/ace/tokenizer.js +++ b/lib/ace/tokenizer.js @@ -74,7 +74,7 @@ var Tokenizer = function(rules, flag) { }); if (matchcount > 1 && state[i].token.length !== matchcount-1) - throw new Error("For " + state[i].regex + " the matching groups and length of the token array don't match (rule #" + i + " of state " + key + ")"); + throw new Error("For " + state[i].regex + " the matching groups (" +(matchcount-1) + ") and length of the token array (" + state[i].token.length + ") don't match (rule #" + i + " of state " + key + ")"); mapping[matchTotal] = { rule: i, diff --git a/tool/mode_highlight_rules.tmpl.js b/tool/mode_highlight_rules.tmpl.js index e6d99137..94c6cdfa 100644 --- a/tool/mode_highlight_rules.tmpl.js +++ b/tool/mode_highlight_rules.tmpl.js @@ -34,7 +34,7 @@ * ***** END LICENSE BLOCK ***** */ /* - THIS FILE WAS AUTOGENERATED BY mode_highlight_rules.tmpl.js (UUID: %uuid%) */ + THIS FILE WAS AUTOGENERATED BY %name% (UUID: %uuid%) */ /******* diff --git a/tool/tmlanguage.js b/tool/tmlanguage.js index 988409c3..c286b2ac 100644 --- a/tool/tmlanguage.js +++ b/tool/tmlanguage.js @@ -270,8 +270,9 @@ function convertLanguage(name) { var languageHighlightRules = fillTemplate(modeHighlightTemplate, { language: languageNameSanitized, languageTokens: patterns, - respositoryRules: "/*** START REPOSITORY RULES\n" + (Object.keys(repository).length === 0 ? "" : repository) + "\nEND REPOSITORY RULES ***/", - uuid: language.uuid + respositoryRules: "/*** START REPOSITORY RULES\n" + repository + "\nEND REPOSITORY RULES ***/", + uuid: language.uuid, + name: name }); if (devMode) {