From 992b5b4e3cd206ae3453db957e00301c5f7b48a8 Mon Sep 17 00:00:00 2001 From: YasithD Date: Tue, 22 Aug 2023 12:59:23 +0530 Subject: [PATCH 1/6] Add Ballerina grammar --- src/languages/ballerina.js | 420 +++++++++++++++++++++++++++++++++++++ 1 file changed, 420 insertions(+) create mode 100644 src/languages/ballerina.js diff --git a/src/languages/ballerina.js b/src/languages/ballerina.js new file mode 100644 index 0000000000..302033c1f6 --- /dev/null +++ b/src/languages/ballerina.js @@ -0,0 +1,420 @@ +/* +Language: Ballerina +Description: Open source, cloud-native programming language optimized for integration +Requires: xml.js +Author: Yasith Deelaka +Website: https://ballerina.io +*/ + +/** @type LanguageFn **/ +export default function (hljs) { + // variables + const KEYWORD_CONTROL = [ + "fork", + "join", + "while", + "returns", + "transaction", + "transactional", + "retry", + "commit", + "rollback", + "typeof", + "enum", + "wait", + "match", + ]; + + const CONTROL_STATEMENTS = ["if", "else"]; + + const ITERATION = ["for", "foreach"]; + + const KEYWORD_CONTROL_FLOW = [ + "return", + "break", + "continue", + "check", + "checkpanic", + "panic", + "trap", + "from", + "where", + ]; + + const KEYWORD_OTHER = [ + "public", + "private", + "external", + "return", + "record", + "object", + "remote", + "abstract", + "client", + "true", + "false", + "fail", + "import", + "version", + "as", + "on", + "function", + "resource", + "listener", + "const", + "final", + "is", + "null", + "lock", + "annotation", + "source", + "worker", + "parameter", + "field", + "isolated", + "in", + "xmlns", + "table", + "key", + "let", + "new", + "select", + "start", + "flush", + "default", + "do", + "base16", + "base64", + "conflict", + "limit", + "outer", + "equals", + "order", + "by", + "ascending", + "descending", + "class", + "configurable", + "variable", + "module", + "service", + "group", + "collect", + ]; + + const TYPES = [ + "handle", + "any", + "future", + "typedesc", + "boolean", + "int", + "string", + "float", + "decimal", + "byte", + "json", + "xml", + "anydata", + "map", + "error", + "never", + "readonly", + "distinct", + "stream", + "type", + "var", + ]; + + const BUILT_INS = ["self"]; + + const LITERALS = ["true", "false"]; + + const BAL_KEYWORDS = [ + ...KEYWORD_CONTROL, + ...CONTROL_STATEMENTS, + ...ITERATION, + ...KEYWORD_CONTROL_FLOW, + ...KEYWORD_OTHER, + ]; + + const KEYWORDS = { + keyword: BAL_KEYWORDS, + literals: LITERALS, + type: TYPES, + built_in: BUILT_INS, + }; + + // regexes + const KEYWORD_RE = new RegExp("(?:" + BAL_KEYWORDS.join("|") + ")"); + const TYPE_RE = new RegExp("(?:" + TYPES.join("|") + ")"); + const C_NUMBER_RE = + /(-?)(\b0[xX][a-fA-F0-9]+|(\b\d+((?|&|\||\?:|\.\.\.|<=|>=|&&|\|\||~|>>|>>>)/, + relevance: 0, + }; + + const VARIABLE_MODE = { + variants: [ + { + begin: [ + TYPE_RE.source, + /(?:\[[\w\*]*\])*\s+/, // arrays + /(?:\w|\\.\w)+\b(?!\))/, + /\s*/, + /=?/, + /;?/, + ], + beginScope: { + 1: "keyword", + 3: "variable", + 5: "operator", + }, + }, + { + scope: "variable", + match: /'/, + contains: [ + { + match: KEYWORD_RE, + }, + ], + }, + ], + relevance: 0, + }; + + const TYPE_MODE = { + variants: [ + { + begin: [/type/, /\s+/, /\w+/, /\s+/, /(?:\w|\&)+/, /\{/], + end: /\}/, + beginScope: { + 1: "keyword", + 3: "title.class", + 5: "keyword", + }, + contains: [ + { + match: /\&/, + relevance: 0, + }, + ], + }, + { + begin: [/=/, /\s*\{/], + beginScope: { + 1: "operator", + }, + end: "\\}", + contains: [ + { + match: /:/, + scope: "keyword", + }, + hljs.C_LINE_COMMENT_MODE, + STRING_MODE, + NUMBER_MODE, + ], + }, + ], + keywords: KEYWORDS, + contains: [ + "self", + hljs.C_LINE_COMMENT_MODE, + VARIABLE_MODE, + NUMBER_MODE, + STRING_MODE, + ], + }; + + const XML_MODE = { + begin: /xml\s*`/, + end: /`/, + excludeBegin: true, + excludeEnd: true, + subLanguage: "xml", + relevance: 2, + }; + + const PARAMS = { + scope: "params", + keywords: KEYWORDS, + variants: [ + { + match: /'/, + contains: [ + { + match: KEYWORD_RE, + }, + ], + }, + C_NUMBER_MODE, + hljs.BINARY_NUMBER_MODE, + APOS_STRING_MODE, + QUOTE_STRING_MODE, + TEMPLATE_STRING_MODE, + OPERATOR_MODE, + { + begin: /\w+/, + }, + ], + relevance: 0, + }; + + const TAG_MODE = { + variants: [ + { + begin: [/@/, /\w+/, /:/, /\w+/, /\s*\{/], + contains: [ + STRING_MODE, + { + match: ":", + scope: "keyword", + }, + ], + end: /\}/, + }, + { + begin: [/@/, /test/, /:/, /\w+/], + }, + ], + beginScope: { + 2: "title.class", + 3: "keyword", + 4: "title.function", + }, + relevance: 0, + }; + + return { + name: "Ballerina", + aliases: ["bal"], + keywords: KEYWORDS, + contains: [ + { + // classes + match: [/class/, /\s+/, /\w+/, /\s*{/], + scope: { + 1: "keyword", + 3: "title.class", + }, + relevance: 0, + }, + { + // functions + begin: [/function/, /\s+/, /\w+/, /\s*/, /\(/], + beginScope: { + 1: "keyword", + 3: "title.function", + }, + end: /\)/, + variants: [ + { + // anonymous function + begin: [/function/, /\s+/, /\(/], + beginScope: { + 1: "keyword", + }, + end: /\)/, + }, + { + begin: [/:?/, /\b(?!while\b)\w+\b/, /\s*/, /\(/], + beginScope: { + 1: "keyword", + 2: "title.function", + }, + end: /\)/, + }, + ], + contains: ["self", PARAMS], + relevance: 0, + }, + TYPE_MODE, + VARIABLE_MODE, + hljs.C_LINE_COMMENT_MODE, + NUMBER_MODE, + STRING_MODE, + TAG_MODE, + { + scope: "meta.arrow.ballerina storage.type.function.arrow.ballerina", + match: /(=>)/, + }, + OPERATOR_MODE, + XML_MODE, + + // relevance boost + { + begin: /import (?:ballerina|ballerinax)\/[a-z]+/, + keywords: "import", + relevance: 4, + }, + ], + }; +} From 05d7bfef1f5d31f63cb2772de48cf3ea285d6e0b Mon Sep 17 00:00:00 2001 From: YasithD Date: Tue, 22 Aug 2023 13:00:27 +0530 Subject: [PATCH 2/6] Add tests for Ballerina --- test/detect/ballerina/default.txt | 9 +++ .../ballerina/error_handling.expect.txt | 29 ++++++++ test/markup/ballerina/error_handling.txt | 29 ++++++++ .../ballerina/hello_world_service.expect.txt | 9 +++ test/markup/ballerina/hello_world_service.txt | 9 +++ test/markup/ballerina/maps.expect.txt | 32 +++++++++ test/markup/ballerina/maps.txt | 32 +++++++++ .../ballerina/variables_and_types.expect.txt | 12 ++++ test/markup/ballerina/variables_and_types.txt | 12 ++++ .../ballerina/xml_data_model.expect.txt | 66 +++++++++++++++++++ test/markup/ballerina/xml_data_model.txt | 66 +++++++++++++++++++ 11 files changed, 305 insertions(+) create mode 100644 test/detect/ballerina/default.txt create mode 100644 test/markup/ballerina/error_handling.expect.txt create mode 100644 test/markup/ballerina/error_handling.txt create mode 100644 test/markup/ballerina/hello_world_service.expect.txt create mode 100644 test/markup/ballerina/hello_world_service.txt create mode 100644 test/markup/ballerina/maps.expect.txt create mode 100644 test/markup/ballerina/maps.txt create mode 100644 test/markup/ballerina/variables_and_types.expect.txt create mode 100644 test/markup/ballerina/variables_and_types.txt create mode 100644 test/markup/ballerina/xml_data_model.expect.txt create mode 100644 test/markup/ballerina/xml_data_model.txt diff --git a/test/detect/ballerina/default.txt b/test/detect/ballerina/default.txt new file mode 100644 index 0000000000..7a591fba0f --- /dev/null +++ b/test/detect/ballerina/default.txt @@ -0,0 +1,9 @@ +import ballerina/http; + +service / on new http:Listener(9090) { + + // This function responds with `string` value `Hello, World!` to HTTP GET requests. + resource function get greeting() returns string { + return "Hello, World!"; + } +} \ No newline at end of file diff --git a/test/markup/ballerina/error_handling.expect.txt b/test/markup/ballerina/error_handling.expect.txt new file mode 100644 index 0000000000..9b05de07a8 --- /dev/null +++ b/test/markup/ballerina/error_handling.expect.txt @@ -0,0 +1,29 @@ +import ballerina/io; + +// Converts `bytes` to a `string` value and then to an `int` value. +function intFromBytes(byte[] bytes) returns int|error { + + string|error ret = string:fromBytes(bytes); + + // The `is` operator can be used to distinguish errors from other values. + if ret is error { + return ret; + } else { + return int:fromString(ret); + } +} + +// The `main` function can return an `error` value. +public function main() returns error? { + + int|error res = intFromBytes([104, 101, 108, 108, 111]); + + if res is error { + // The `check` expression is the shorthand for this pattern of + // checking if a value is an `error` value and it is returning that value. + return res; + } else { + io:println("result: ", res); + return; + } +} \ No newline at end of file diff --git a/test/markup/ballerina/error_handling.txt b/test/markup/ballerina/error_handling.txt new file mode 100644 index 0000000000..5760840938 --- /dev/null +++ b/test/markup/ballerina/error_handling.txt @@ -0,0 +1,29 @@ +import ballerina/io; + +// Converts `bytes` to a `string` value and then to an `int` value. +function intFromBytes(byte[] bytes) returns int|error { + + string|error ret = string:fromBytes(bytes); + + // The `is` operator can be used to distinguish errors from other values. + if ret is error { + return ret; + } else { + return int:fromString(ret); + } +} + +// The `main` function can return an `error` value. +public function main() returns error? { + + int|error res = intFromBytes([104, 101, 108, 108, 111]); + + if res is error { + // The `check` expression is the shorthand for this pattern of + // checking if a value is an `error` value and it is returning that value. + return res; + } else { + io:println("result: ", res); + return; + } +} \ No newline at end of file diff --git a/test/markup/ballerina/hello_world_service.expect.txt b/test/markup/ballerina/hello_world_service.expect.txt new file mode 100644 index 0000000000..c3d717071c --- /dev/null +++ b/test/markup/ballerina/hello_world_service.expect.txt @@ -0,0 +1,9 @@ +import ballerina/http; + +service / on new http:Listener(9090) { + + // This function responds with `string` value `Hello, World!` to HTTP GET requests. + resource function get greeting() returns string { + return "Hello, World!"; + } +} \ No newline at end of file diff --git a/test/markup/ballerina/hello_world_service.txt b/test/markup/ballerina/hello_world_service.txt new file mode 100644 index 0000000000..7a591fba0f --- /dev/null +++ b/test/markup/ballerina/hello_world_service.txt @@ -0,0 +1,9 @@ +import ballerina/http; + +service / on new http:Listener(9090) { + + // This function responds with `string` value `Hello, World!` to HTTP GET requests. + resource function get greeting() returns string { + return "Hello, World!"; + } +} \ No newline at end of file diff --git a/test/markup/ballerina/maps.expect.txt b/test/markup/ballerina/maps.expect.txt new file mode 100644 index 0000000000..4edc2e4df5 --- /dev/null +++ b/test/markup/ballerina/maps.expect.txt @@ -0,0 +1,32 @@ +import ballerina/io; + +public function main() { + // Creates a `map` constrained by the `int` type. + map<int> ages = { + "Tom": 23, + "Jack": 34 + }; + + // Gets the entry for `Tom`. + int? v = ages["Tom"]; + io:println(v); + + // As there exists an entry for `Tom`, it can be accessed using the `map:get()` method. + // Using `ages["Tom"]` wouldn't work here because its type would be `int?` and not `int`. + int age = ages.get("Tom"); + io:println(age); + + // Adds a new entry for `Anne`. + ages["Anne"] = 19; + + // The `map:hasKey()` method checks whether the map `age` has a member with `Jack` as the key. + if ages.hasKey("Jack") { + // The member with the key `Jack` can be removed using `map:remove()`. + _ = ages.remove("Jack"); + } + + // `map:keys()` returns the keys as an array of strings. + foreach string name in ages.keys() { + io:println(name, " : ", ages[name]); + } +} \ No newline at end of file diff --git a/test/markup/ballerina/maps.txt b/test/markup/ballerina/maps.txt new file mode 100644 index 0000000000..cea2c86f02 --- /dev/null +++ b/test/markup/ballerina/maps.txt @@ -0,0 +1,32 @@ +import ballerina/io; + +public function main() { + // Creates a `map` constrained by the `int` type. + map ages = { + "Tom": 23, + "Jack": 34 + }; + + // Gets the entry for `Tom`. + int? v = ages["Tom"]; + io:println(v); + + // As there exists an entry for `Tom`, it can be accessed using the `map:get()` method. + // Using `ages["Tom"]` wouldn't work here because its type would be `int?` and not `int`. + int age = ages.get("Tom"); + io:println(age); + + // Adds a new entry for `Anne`. + ages["Anne"] = 19; + + // The `map:hasKey()` method checks whether the map `age` has a member with `Jack` as the key. + if ages.hasKey("Jack") { + // The member with the key `Jack` can be removed using `map:remove()`. + _ = ages.remove("Jack"); + } + + // `map:keys()` returns the keys as an array of strings. + foreach string name in ages.keys() { + io:println(name, " : ", ages[name]); + } +} \ No newline at end of file diff --git a/test/markup/ballerina/variables_and_types.expect.txt b/test/markup/ballerina/variables_and_types.expect.txt new file mode 100644 index 0000000000..577fef6168 --- /dev/null +++ b/test/markup/ballerina/variables_and_types.expect.txt @@ -0,0 +1,12 @@ +import ballerina/io; + +// Modules and functions can declare variables. You can see both in this example. +// Here we declare a variable `greeting` of type `string` and initialize it to `"Hello"`. +string greeting = "Hello"; + +public function main() { + // Assignments are statements not expressions. + string name = "Ballerina"; + + io:println(greeting, " ", name); +} \ No newline at end of file diff --git a/test/markup/ballerina/variables_and_types.txt b/test/markup/ballerina/variables_and_types.txt new file mode 100644 index 0000000000..967d143ebc --- /dev/null +++ b/test/markup/ballerina/variables_and_types.txt @@ -0,0 +1,12 @@ +import ballerina/io; + +// Modules and functions can declare variables. You can see both in this example. +// Here we declare a variable `greeting` of type `string` and initialize it to `"Hello"`. +string greeting = "Hello"; + +public function main() { + // Assignments are statements not expressions. + string name = "Ballerina"; + + io:println(greeting, " ", name); +} \ No newline at end of file diff --git a/test/markup/ballerina/xml_data_model.expect.txt b/test/markup/ballerina/xml_data_model.expect.txt new file mode 100644 index 0000000000..88422269f5 --- /dev/null +++ b/test/markup/ballerina/xml_data_model.expect.txt @@ -0,0 +1,66 @@ +import ballerina/io; + +public function main() returns error? { + // An XML element. There can be only one root element. + xml x1 = xml `<book>The Lost World</book>`; + io:println(x1); + + // An XML processing instruction. + xml x2 = xml `<?target data?>`; + io:println(x2); + + // An XML comment. + xml x3 = xml `<!--I am a comment-->`; + io:println(x3); + + // An XML text. + xml x4 = xml `Hello, world!`; + io:println(x4); + + // `xml:createText` can be used to convert a string to `xmlText`. + string hello = "Hello"; + string world = "World"; + xml:Text xmlString = xml:createText(hello + " " + world); + io:println(xmlString); + + // Creates an XML value. + xml xmlValue = xml `<name>Sherlock Holmes</name> + <details> + <author>Sir Arthur Conan Doyle</author> + <language>English</language> + </details>`; + + // `x[i]` or `x.get(i)` gives the `i`-th item. + io:println(xmlValue[0]); + + // `x.id` accesses a required attribute named `id`. The result is an `error` if there is no such + // attribute or if `x` is not a singleton. + xml xmlHello = xml `<para id="greeting">Hello</para>`; + string id = check xmlHello.id; + io:println(id); + + // `x?.id` accesses an optional attribute named `id`. The result is `()` if there is no such + // attribute. + string? name = check xmlHello?.name; + io:println(name); + + xml xmlItems = xml + `<items> + <!--Contents--> + <book> + <name>A Study in Scarlet</name> + <author><name>Arthur Conan Doyle</name></author> + </book> + <planner>Daily Planner<kind>day</kind><pages>365</pages></planner> + <book> + <name>The Sign of Four</name> + <author><name>Arthur Conan Doyle</name></author> + </book> + <pen><kind>marker</kind><color>blue</color></pen> + </items>`; + + // `x.<items>` - retrieves every element in `x` named `items`. + xml items = xmlItems.<items>; + io:println(items); + +} \ No newline at end of file diff --git a/test/markup/ballerina/xml_data_model.txt b/test/markup/ballerina/xml_data_model.txt new file mode 100644 index 0000000000..529e563857 --- /dev/null +++ b/test/markup/ballerina/xml_data_model.txt @@ -0,0 +1,66 @@ +import ballerina/io; + +public function main() returns error? { + // An XML element. There can be only one root element. + xml x1 = xml `The Lost World`; + io:println(x1); + + // An XML processing instruction. + xml x2 = xml ``; + io:println(x2); + + // An XML comment. + xml x3 = xml ``; + io:println(x3); + + // An XML text. + xml x4 = xml `Hello, world!`; + io:println(x4); + + // `xml:createText` can be used to convert a string to `xmlText`. + string hello = "Hello"; + string world = "World"; + xml:Text xmlString = xml:createText(hello + " " + world); + io:println(xmlString); + + // Creates an XML value. + xml xmlValue = xml `Sherlock Holmes +
+ Sir Arthur Conan Doyle + English +
`; + + // `x[i]` or `x.get(i)` gives the `i`-th item. + io:println(xmlValue[0]); + + // `x.id` accesses a required attribute named `id`. The result is an `error` if there is no such + // attribute or if `x` is not a singleton. + xml xmlHello = xml `Hello`; + string id = check xmlHello.id; + io:println(id); + + // `x?.id` accesses an optional attribute named `id`. The result is `()` if there is no such + // attribute. + string? name = check xmlHello?.name; + io:println(name); + + xml xmlItems = xml + ` + + + A Study in Scarlet + Arthur Conan Doyle + + Daily Plannerday365 + + The Sign of Four + Arthur Conan Doyle + + markerblue + `; + + // `x.` - retrieves every element in `x` named `items`. + xml items = xmlItems.; + io:println(items); + +} \ No newline at end of file From 97db3e8b0caa8d86f1a71e2136459ff152f52a6e Mon Sep 17 00:00:00 2001 From: YasithD Date: Tue, 22 Aug 2023 13:00:54 +0530 Subject: [PATCH 3/6] Update changelog --- CHANGES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 854ab1ed60..79b55aa79a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,7 @@ New Grammars: - added 3rd party x86asmatt grammar to SUPPORTED_LANGUAGES [gondow][] - added 3rd party riscv64 grammar to SUPPORTED_LANGUAGES [aana-h2][] +- added 3rd party Ballerina grammar to SUPPORTED_LANGUAGES [Yasith Deelaka][] Core Grammars: @@ -60,6 +61,7 @@ Dev tool: [jchavarri]: https://github.com/jchavarri [aana-h2]: https://github.com/aana-h2 [Nicholas Thompson]: https://github.com/NAThompson +[Yasith Deelaka]: https://github.com/YasithD ## Version 11.8.0 From d53919553bd437aa73c194e6a445214033cdf8e4 Mon Sep 17 00:00:00 2001 From: YasithD Date: Tue, 22 Aug 2023 13:01:12 +0530 Subject: [PATCH 4/6] Update SUPPORTED_LANGUAGES.md --- SUPPORTED_LANGUAGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/SUPPORTED_LANGUAGES.md b/SUPPORTED_LANGUAGES.md index a5108e4741..a44c5e033d 100644 --- a/SUPPORTED_LANGUAGES.md +++ b/SUPPORTED_LANGUAGES.md @@ -29,6 +29,7 @@ The table below shows the full list of languages (and corresponding classes/alia | AutoHotkey | autohotkey | | | AutoIt | autoit | | | Awk | awk, mawk, nawk, gawk | | +| Ballerina | ballerina, bal | [highlightjs-ballerina](https://github.com/YasithD/highlightjs-ballerina) | | Bash | bash, sh, zsh | | | Basic | basic | | | BBCode | bbcode | [highlightjs-bbcode](https://github.com/RedGuy12/highlightjs-bbcode) | From bf645db2bc6520d3699cb9b51e952796cfe4135c Mon Sep 17 00:00:00 2001 From: YasithD Date: Sat, 2 Sep 2023 13:14:19 +0530 Subject: [PATCH 5/6] Update Ballerina package repository --- SUPPORTED_LANGUAGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SUPPORTED_LANGUAGES.md b/SUPPORTED_LANGUAGES.md index a44c5e033d..d82b15801a 100644 --- a/SUPPORTED_LANGUAGES.md +++ b/SUPPORTED_LANGUAGES.md @@ -29,7 +29,7 @@ The table below shows the full list of languages (and corresponding classes/alia | AutoHotkey | autohotkey | | | AutoIt | autoit | | | Awk | awk, mawk, nawk, gawk | | -| Ballerina | ballerina, bal | [highlightjs-ballerina](https://github.com/YasithD/highlightjs-ballerina) | +| Ballerina | ballerina, bal | [highlightjs-ballerina](https://github.com/highlightjs/highlightjs-ballerina) | | Bash | bash, sh, zsh | | | Basic | basic | | | BBCode | bbcode | [highlightjs-bbcode](https://github.com/RedGuy12/highlightjs-bbcode) | From 82212a1307eed6de28de991686d1a8863f002a40 Mon Sep 17 00:00:00 2001 From: YasithD Date: Fri, 8 Sep 2023 09:26:22 +0530 Subject: [PATCH 6/6] Remove source code and tests --- src/languages/ballerina.js | 420 ------------------ test/detect/ballerina/default.txt | 9 - .../ballerina/error_handling.expect.txt | 29 -- test/markup/ballerina/error_handling.txt | 29 -- .../ballerina/hello_world_service.expect.txt | 9 - test/markup/ballerina/hello_world_service.txt | 9 - test/markup/ballerina/maps.expect.txt | 32 -- test/markup/ballerina/maps.txt | 32 -- .../ballerina/variables_and_types.expect.txt | 12 - test/markup/ballerina/variables_and_types.txt | 12 - .../ballerina/xml_data_model.expect.txt | 66 --- test/markup/ballerina/xml_data_model.txt | 66 --- 12 files changed, 725 deletions(-) delete mode 100644 src/languages/ballerina.js delete mode 100644 test/detect/ballerina/default.txt delete mode 100644 test/markup/ballerina/error_handling.expect.txt delete mode 100644 test/markup/ballerina/error_handling.txt delete mode 100644 test/markup/ballerina/hello_world_service.expect.txt delete mode 100644 test/markup/ballerina/hello_world_service.txt delete mode 100644 test/markup/ballerina/maps.expect.txt delete mode 100644 test/markup/ballerina/maps.txt delete mode 100644 test/markup/ballerina/variables_and_types.expect.txt delete mode 100644 test/markup/ballerina/variables_and_types.txt delete mode 100644 test/markup/ballerina/xml_data_model.expect.txt delete mode 100644 test/markup/ballerina/xml_data_model.txt diff --git a/src/languages/ballerina.js b/src/languages/ballerina.js deleted file mode 100644 index 302033c1f6..0000000000 --- a/src/languages/ballerina.js +++ /dev/null @@ -1,420 +0,0 @@ -/* -Language: Ballerina -Description: Open source, cloud-native programming language optimized for integration -Requires: xml.js -Author: Yasith Deelaka -Website: https://ballerina.io -*/ - -/** @type LanguageFn **/ -export default function (hljs) { - // variables - const KEYWORD_CONTROL = [ - "fork", - "join", - "while", - "returns", - "transaction", - "transactional", - "retry", - "commit", - "rollback", - "typeof", - "enum", - "wait", - "match", - ]; - - const CONTROL_STATEMENTS = ["if", "else"]; - - const ITERATION = ["for", "foreach"]; - - const KEYWORD_CONTROL_FLOW = [ - "return", - "break", - "continue", - "check", - "checkpanic", - "panic", - "trap", - "from", - "where", - ]; - - const KEYWORD_OTHER = [ - "public", - "private", - "external", - "return", - "record", - "object", - "remote", - "abstract", - "client", - "true", - "false", - "fail", - "import", - "version", - "as", - "on", - "function", - "resource", - "listener", - "const", - "final", - "is", - "null", - "lock", - "annotation", - "source", - "worker", - "parameter", - "field", - "isolated", - "in", - "xmlns", - "table", - "key", - "let", - "new", - "select", - "start", - "flush", - "default", - "do", - "base16", - "base64", - "conflict", - "limit", - "outer", - "equals", - "order", - "by", - "ascending", - "descending", - "class", - "configurable", - "variable", - "module", - "service", - "group", - "collect", - ]; - - const TYPES = [ - "handle", - "any", - "future", - "typedesc", - "boolean", - "int", - "string", - "float", - "decimal", - "byte", - "json", - "xml", - "anydata", - "map", - "error", - "never", - "readonly", - "distinct", - "stream", - "type", - "var", - ]; - - const BUILT_INS = ["self"]; - - const LITERALS = ["true", "false"]; - - const BAL_KEYWORDS = [ - ...KEYWORD_CONTROL, - ...CONTROL_STATEMENTS, - ...ITERATION, - ...KEYWORD_CONTROL_FLOW, - ...KEYWORD_OTHER, - ]; - - const KEYWORDS = { - keyword: BAL_KEYWORDS, - literals: LITERALS, - type: TYPES, - built_in: BUILT_INS, - }; - - // regexes - const KEYWORD_RE = new RegExp("(?:" + BAL_KEYWORDS.join("|") + ")"); - const TYPE_RE = new RegExp("(?:" + TYPES.join("|") + ")"); - const C_NUMBER_RE = - /(-?)(\b0[xX][a-fA-F0-9]+|(\b\d+((?|&|\||\?:|\.\.\.|<=|>=|&&|\|\||~|>>|>>>)/, - relevance: 0, - }; - - const VARIABLE_MODE = { - variants: [ - { - begin: [ - TYPE_RE.source, - /(?:\[[\w\*]*\])*\s+/, // arrays - /(?:\w|\\.\w)+\b(?!\))/, - /\s*/, - /=?/, - /;?/, - ], - beginScope: { - 1: "keyword", - 3: "variable", - 5: "operator", - }, - }, - { - scope: "variable", - match: /'/, - contains: [ - { - match: KEYWORD_RE, - }, - ], - }, - ], - relevance: 0, - }; - - const TYPE_MODE = { - variants: [ - { - begin: [/type/, /\s+/, /\w+/, /\s+/, /(?:\w|\&)+/, /\{/], - end: /\}/, - beginScope: { - 1: "keyword", - 3: "title.class", - 5: "keyword", - }, - contains: [ - { - match: /\&/, - relevance: 0, - }, - ], - }, - { - begin: [/=/, /\s*\{/], - beginScope: { - 1: "operator", - }, - end: "\\}", - contains: [ - { - match: /:/, - scope: "keyword", - }, - hljs.C_LINE_COMMENT_MODE, - STRING_MODE, - NUMBER_MODE, - ], - }, - ], - keywords: KEYWORDS, - contains: [ - "self", - hljs.C_LINE_COMMENT_MODE, - VARIABLE_MODE, - NUMBER_MODE, - STRING_MODE, - ], - }; - - const XML_MODE = { - begin: /xml\s*`/, - end: /`/, - excludeBegin: true, - excludeEnd: true, - subLanguage: "xml", - relevance: 2, - }; - - const PARAMS = { - scope: "params", - keywords: KEYWORDS, - variants: [ - { - match: /'/, - contains: [ - { - match: KEYWORD_RE, - }, - ], - }, - C_NUMBER_MODE, - hljs.BINARY_NUMBER_MODE, - APOS_STRING_MODE, - QUOTE_STRING_MODE, - TEMPLATE_STRING_MODE, - OPERATOR_MODE, - { - begin: /\w+/, - }, - ], - relevance: 0, - }; - - const TAG_MODE = { - variants: [ - { - begin: [/@/, /\w+/, /:/, /\w+/, /\s*\{/], - contains: [ - STRING_MODE, - { - match: ":", - scope: "keyword", - }, - ], - end: /\}/, - }, - { - begin: [/@/, /test/, /:/, /\w+/], - }, - ], - beginScope: { - 2: "title.class", - 3: "keyword", - 4: "title.function", - }, - relevance: 0, - }; - - return { - name: "Ballerina", - aliases: ["bal"], - keywords: KEYWORDS, - contains: [ - { - // classes - match: [/class/, /\s+/, /\w+/, /\s*{/], - scope: { - 1: "keyword", - 3: "title.class", - }, - relevance: 0, - }, - { - // functions - begin: [/function/, /\s+/, /\w+/, /\s*/, /\(/], - beginScope: { - 1: "keyword", - 3: "title.function", - }, - end: /\)/, - variants: [ - { - // anonymous function - begin: [/function/, /\s+/, /\(/], - beginScope: { - 1: "keyword", - }, - end: /\)/, - }, - { - begin: [/:?/, /\b(?!while\b)\w+\b/, /\s*/, /\(/], - beginScope: { - 1: "keyword", - 2: "title.function", - }, - end: /\)/, - }, - ], - contains: ["self", PARAMS], - relevance: 0, - }, - TYPE_MODE, - VARIABLE_MODE, - hljs.C_LINE_COMMENT_MODE, - NUMBER_MODE, - STRING_MODE, - TAG_MODE, - { - scope: "meta.arrow.ballerina storage.type.function.arrow.ballerina", - match: /(=>)/, - }, - OPERATOR_MODE, - XML_MODE, - - // relevance boost - { - begin: /import (?:ballerina|ballerinax)\/[a-z]+/, - keywords: "import", - relevance: 4, - }, - ], - }; -} diff --git a/test/detect/ballerina/default.txt b/test/detect/ballerina/default.txt deleted file mode 100644 index 7a591fba0f..0000000000 --- a/test/detect/ballerina/default.txt +++ /dev/null @@ -1,9 +0,0 @@ -import ballerina/http; - -service / on new http:Listener(9090) { - - // This function responds with `string` value `Hello, World!` to HTTP GET requests. - resource function get greeting() returns string { - return "Hello, World!"; - } -} \ No newline at end of file diff --git a/test/markup/ballerina/error_handling.expect.txt b/test/markup/ballerina/error_handling.expect.txt deleted file mode 100644 index 9b05de07a8..0000000000 --- a/test/markup/ballerina/error_handling.expect.txt +++ /dev/null @@ -1,29 +0,0 @@ -import ballerina/io; - -// Converts `bytes` to a `string` value and then to an `int` value. -function intFromBytes(byte[] bytes) returns int|error { - - string|error ret = string:fromBytes(bytes); - - // The `is` operator can be used to distinguish errors from other values. - if ret is error { - return ret; - } else { - return int:fromString(ret); - } -} - -// The `main` function can return an `error` value. -public function main() returns error? { - - int|error res = intFromBytes([104, 101, 108, 108, 111]); - - if res is error { - // The `check` expression is the shorthand for this pattern of - // checking if a value is an `error` value and it is returning that value. - return res; - } else { - io:println("result: ", res); - return; - } -} \ No newline at end of file diff --git a/test/markup/ballerina/error_handling.txt b/test/markup/ballerina/error_handling.txt deleted file mode 100644 index 5760840938..0000000000 --- a/test/markup/ballerina/error_handling.txt +++ /dev/null @@ -1,29 +0,0 @@ -import ballerina/io; - -// Converts `bytes` to a `string` value and then to an `int` value. -function intFromBytes(byte[] bytes) returns int|error { - - string|error ret = string:fromBytes(bytes); - - // The `is` operator can be used to distinguish errors from other values. - if ret is error { - return ret; - } else { - return int:fromString(ret); - } -} - -// The `main` function can return an `error` value. -public function main() returns error? { - - int|error res = intFromBytes([104, 101, 108, 108, 111]); - - if res is error { - // The `check` expression is the shorthand for this pattern of - // checking if a value is an `error` value and it is returning that value. - return res; - } else { - io:println("result: ", res); - return; - } -} \ No newline at end of file diff --git a/test/markup/ballerina/hello_world_service.expect.txt b/test/markup/ballerina/hello_world_service.expect.txt deleted file mode 100644 index c3d717071c..0000000000 --- a/test/markup/ballerina/hello_world_service.expect.txt +++ /dev/null @@ -1,9 +0,0 @@ -import ballerina/http; - -service / on new http:Listener(9090) { - - // This function responds with `string` value `Hello, World!` to HTTP GET requests. - resource function get greeting() returns string { - return "Hello, World!"; - } -} \ No newline at end of file diff --git a/test/markup/ballerina/hello_world_service.txt b/test/markup/ballerina/hello_world_service.txt deleted file mode 100644 index 7a591fba0f..0000000000 --- a/test/markup/ballerina/hello_world_service.txt +++ /dev/null @@ -1,9 +0,0 @@ -import ballerina/http; - -service / on new http:Listener(9090) { - - // This function responds with `string` value `Hello, World!` to HTTP GET requests. - resource function get greeting() returns string { - return "Hello, World!"; - } -} \ No newline at end of file diff --git a/test/markup/ballerina/maps.expect.txt b/test/markup/ballerina/maps.expect.txt deleted file mode 100644 index 4edc2e4df5..0000000000 --- a/test/markup/ballerina/maps.expect.txt +++ /dev/null @@ -1,32 +0,0 @@ -import ballerina/io; - -public function main() { - // Creates a `map` constrained by the `int` type. - map<int> ages = { - "Tom": 23, - "Jack": 34 - }; - - // Gets the entry for `Tom`. - int? v = ages["Tom"]; - io:println(v); - - // As there exists an entry for `Tom`, it can be accessed using the `map:get()` method. - // Using `ages["Tom"]` wouldn't work here because its type would be `int?` and not `int`. - int age = ages.get("Tom"); - io:println(age); - - // Adds a new entry for `Anne`. - ages["Anne"] = 19; - - // The `map:hasKey()` method checks whether the map `age` has a member with `Jack` as the key. - if ages.hasKey("Jack") { - // The member with the key `Jack` can be removed using `map:remove()`. - _ = ages.remove("Jack"); - } - - // `map:keys()` returns the keys as an array of strings. - foreach string name in ages.keys() { - io:println(name, " : ", ages[name]); - } -} \ No newline at end of file diff --git a/test/markup/ballerina/maps.txt b/test/markup/ballerina/maps.txt deleted file mode 100644 index cea2c86f02..0000000000 --- a/test/markup/ballerina/maps.txt +++ /dev/null @@ -1,32 +0,0 @@ -import ballerina/io; - -public function main() { - // Creates a `map` constrained by the `int` type. - map ages = { - "Tom": 23, - "Jack": 34 - }; - - // Gets the entry for `Tom`. - int? v = ages["Tom"]; - io:println(v); - - // As there exists an entry for `Tom`, it can be accessed using the `map:get()` method. - // Using `ages["Tom"]` wouldn't work here because its type would be `int?` and not `int`. - int age = ages.get("Tom"); - io:println(age); - - // Adds a new entry for `Anne`. - ages["Anne"] = 19; - - // The `map:hasKey()` method checks whether the map `age` has a member with `Jack` as the key. - if ages.hasKey("Jack") { - // The member with the key `Jack` can be removed using `map:remove()`. - _ = ages.remove("Jack"); - } - - // `map:keys()` returns the keys as an array of strings. - foreach string name in ages.keys() { - io:println(name, " : ", ages[name]); - } -} \ No newline at end of file diff --git a/test/markup/ballerina/variables_and_types.expect.txt b/test/markup/ballerina/variables_and_types.expect.txt deleted file mode 100644 index 577fef6168..0000000000 --- a/test/markup/ballerina/variables_and_types.expect.txt +++ /dev/null @@ -1,12 +0,0 @@ -import ballerina/io; - -// Modules and functions can declare variables. You can see both in this example. -// Here we declare a variable `greeting` of type `string` and initialize it to `"Hello"`. -string greeting = "Hello"; - -public function main() { - // Assignments are statements not expressions. - string name = "Ballerina"; - - io:println(greeting, " ", name); -} \ No newline at end of file diff --git a/test/markup/ballerina/variables_and_types.txt b/test/markup/ballerina/variables_and_types.txt deleted file mode 100644 index 967d143ebc..0000000000 --- a/test/markup/ballerina/variables_and_types.txt +++ /dev/null @@ -1,12 +0,0 @@ -import ballerina/io; - -// Modules and functions can declare variables. You can see both in this example. -// Here we declare a variable `greeting` of type `string` and initialize it to `"Hello"`. -string greeting = "Hello"; - -public function main() { - // Assignments are statements not expressions. - string name = "Ballerina"; - - io:println(greeting, " ", name); -} \ No newline at end of file diff --git a/test/markup/ballerina/xml_data_model.expect.txt b/test/markup/ballerina/xml_data_model.expect.txt deleted file mode 100644 index 88422269f5..0000000000 --- a/test/markup/ballerina/xml_data_model.expect.txt +++ /dev/null @@ -1,66 +0,0 @@ -import ballerina/io; - -public function main() returns error? { - // An XML element. There can be only one root element. - xml x1 = xml `<book>The Lost World</book>`; - io:println(x1); - - // An XML processing instruction. - xml x2 = xml `<?target data?>`; - io:println(x2); - - // An XML comment. - xml x3 = xml `<!--I am a comment-->`; - io:println(x3); - - // An XML text. - xml x4 = xml `Hello, world!`; - io:println(x4); - - // `xml:createText` can be used to convert a string to `xmlText`. - string hello = "Hello"; - string world = "World"; - xml:Text xmlString = xml:createText(hello + " " + world); - io:println(xmlString); - - // Creates an XML value. - xml xmlValue = xml `<name>Sherlock Holmes</name> - <details> - <author>Sir Arthur Conan Doyle</author> - <language>English</language> - </details>`; - - // `x[i]` or `x.get(i)` gives the `i`-th item. - io:println(xmlValue[0]); - - // `x.id` accesses a required attribute named `id`. The result is an `error` if there is no such - // attribute or if `x` is not a singleton. - xml xmlHello = xml `<para id="greeting">Hello</para>`; - string id = check xmlHello.id; - io:println(id); - - // `x?.id` accesses an optional attribute named `id`. The result is `()` if there is no such - // attribute. - string? name = check xmlHello?.name; - io:println(name); - - xml xmlItems = xml - `<items> - <!--Contents--> - <book> - <name>A Study in Scarlet</name> - <author><name>Arthur Conan Doyle</name></author> - </book> - <planner>Daily Planner<kind>day</kind><pages>365</pages></planner> - <book> - <name>The Sign of Four</name> - <author><name>Arthur Conan Doyle</name></author> - </book> - <pen><kind>marker</kind><color>blue</color></pen> - </items>`; - - // `x.<items>` - retrieves every element in `x` named `items`. - xml items = xmlItems.<items>; - io:println(items); - -} \ No newline at end of file diff --git a/test/markup/ballerina/xml_data_model.txt b/test/markup/ballerina/xml_data_model.txt deleted file mode 100644 index 529e563857..0000000000 --- a/test/markup/ballerina/xml_data_model.txt +++ /dev/null @@ -1,66 +0,0 @@ -import ballerina/io; - -public function main() returns error? { - // An XML element. There can be only one root element. - xml x1 = xml `The Lost World`; - io:println(x1); - - // An XML processing instruction. - xml x2 = xml ``; - io:println(x2); - - // An XML comment. - xml x3 = xml ``; - io:println(x3); - - // An XML text. - xml x4 = xml `Hello, world!`; - io:println(x4); - - // `xml:createText` can be used to convert a string to `xmlText`. - string hello = "Hello"; - string world = "World"; - xml:Text xmlString = xml:createText(hello + " " + world); - io:println(xmlString); - - // Creates an XML value. - xml xmlValue = xml `Sherlock Holmes -
- Sir Arthur Conan Doyle - English -
`; - - // `x[i]` or `x.get(i)` gives the `i`-th item. - io:println(xmlValue[0]); - - // `x.id` accesses a required attribute named `id`. The result is an `error` if there is no such - // attribute or if `x` is not a singleton. - xml xmlHello = xml `Hello`; - string id = check xmlHello.id; - io:println(id); - - // `x?.id` accesses an optional attribute named `id`. The result is `()` if there is no such - // attribute. - string? name = check xmlHello?.name; - io:println(name); - - xml xmlItems = xml - ` - - - A Study in Scarlet - Arthur Conan Doyle - - Daily Plannerday365 - - The Sign of Four - Arthur Conan Doyle - - markerblue - `; - - // `x.` - retrieves every element in `x` named `items`. - xml items = xmlItems.; - io:println(items); - -} \ No newline at end of file