From 7fc1a47630c10341d08fc996b39b89dadb55fd30 Mon Sep 17 00:00:00 2001 From: Soney Mathew Date: Mon, 13 Dec 2021 04:13:26 +0000 Subject: [PATCH] Add JQL Parser/AST --- README.md | 4 ++ website/CACHE_BREAKER | 2 +- website/package.json | 2 + .../src/components/buttons/CategoryButton.js | 2 + website/src/parsers/jql-ast/codeExample.txt | 3 + website/src/parsers/jql-ast/index.js | 6 ++ website/src/parsers/jql-ast/jql-ast.js | 9 +++ .../utils/defaultJqlAstParserInterface.js | 29 +++++++++ .../src/parsers/jql-parser/codeExample.txt | 3 + website/src/parsers/jql-parser/index.js | 6 ++ website/src/parsers/jql-parser/jql-parser.js | 62 +++++++++++++++++++ website/yarn.lock | 35 +++++++++++ 12 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 website/src/parsers/jql-ast/codeExample.txt create mode 100644 website/src/parsers/jql-ast/index.js create mode 100644 website/src/parsers/jql-ast/jql-ast.js create mode 100644 website/src/parsers/jql-ast/utils/defaultJqlAstParserInterface.js create mode 100644 website/src/parsers/jql-parser/codeExample.txt create mode 100644 website/src/parsers/jql-parser/index.js create mode 100644 website/src/parsers/jql-parser/jql-parser.js diff --git a/README.md b/README.md index 4c63caa24..b6958bc3f 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,9 @@ The AST explorer provides following code parsers: - YAML: - [yaml][] - [yaml-ast-parser][] +- JQL: + - [jql-parser][] + - [jql-ast][] ### Experimental / custom syntax @@ -195,6 +198,7 @@ are included so you can prototype your own plugins: [svelte]: https://github.com/sveltejs/svelte [hyntax]: https://github.com/nik-garmash/hyntax [java-parser]: https://github.com/jhipster/prettier-java/tree/master/packages/java-parser +[jql-parser]: https://www.npmjs.com/package/@atlassianlabs/jql-parser ### Contributions diff --git a/website/CACHE_BREAKER b/website/CACHE_BREAKER index f64f5d8d8..9902f1784 100644 --- a/website/CACHE_BREAKER +++ b/website/CACHE_BREAKER @@ -1 +1 @@ -27 +28 diff --git a/website/package.json b/website/package.json index 79c8bc2fe..6e0e1ae27 100644 --- a/website/package.json +++ b/website/package.json @@ -44,6 +44,8 @@ "dependencies": { "@angular-eslint/template-parser": "^12.3.0", "@angular/compiler": "^12.1.0", + "@atlassianlabs/jql-ast": "^0.0.1", + "@atlassianlabs/jql-parser": "^0.0.1", "@babel/eslint-parser": "^7.12.0", "@babel/runtime": "^7.15.3", "@creditkarma/thrift-parser": "^1.2.0", diff --git a/website/src/components/buttons/CategoryButton.js b/website/src/components/buttons/CategoryButton.js index cd04463f5..edcc222c1 100644 --- a/website/src/components/buttons/CategoryButton.js +++ b/website/src/components/buttons/CategoryButton.js @@ -18,6 +18,8 @@ const categoryIcon = { sql: 'fa-database', webidl: 'fa-th-list', yaml: 'fa-yc', + 'jql-ast': 'fa-database', + 'jql-parser': 'fa-database', }; export default class CategoryButton extends React.Component { diff --git a/website/src/parsers/jql-ast/codeExample.txt b/website/src/parsers/jql-ast/codeExample.txt new file mode 100644 index 000000000..a75fc067d --- /dev/null +++ b/website/src/parsers/jql-ast/codeExample.txt @@ -0,0 +1,3 @@ +project = JQL and +developer in ("Soney Mathew", "Kyle Painter", "Cristian Casais") +ORDER BY created ASC, duedate DESC diff --git a/website/src/parsers/jql-ast/index.js b/website/src/parsers/jql-ast/index.js new file mode 100644 index 000000000..ccd9dad65 --- /dev/null +++ b/website/src/parsers/jql-ast/index.js @@ -0,0 +1,6 @@ +import 'codemirror/mode/sql/sql'; + +export const id = 'jql-ast'; +export const displayName = 'JQL AST'; +export const mimeTypes = ['application/json']; +export const fileExtension = 'jql'; diff --git a/website/src/parsers/jql-ast/jql-ast.js b/website/src/parsers/jql-ast/jql-ast.js new file mode 100644 index 000000000..b8f662242 --- /dev/null +++ b/website/src/parsers/jql-ast/jql-ast.js @@ -0,0 +1,9 @@ +import defaultParserInterface from './utils/defaultJqlAstParserInterface'; +import pkg from '@atlassianlabs/jql-ast/package.json'; + +export default { + ...defaultParserInterface(pkg), + loadParser(callback) { + require(['@atlassianlabs/jql-ast'], callback); + }, +} diff --git a/website/src/parsers/jql-ast/utils/defaultJqlAstParserInterface.js b/website/src/parsers/jql-ast/utils/defaultJqlAstParserInterface.js new file mode 100644 index 000000000..258e6dbd4 --- /dev/null +++ b/website/src/parsers/jql-ast/utils/defaultJqlAstParserInterface.js @@ -0,0 +1,29 @@ +import defaultParserInterface from '../../utils/defaultParserInterface'; + +export default (pkg) => ({ + ...defaultParserInterface, + id: pkg.name+pkg.version, + displayName: pkg.name+'@'+pkg.version, + version: '', + locationProps: new Set(['positions','position']), + homepage: "https://www.npmjs.com/package/@atlassianlabs/jql-ast", + + parse(jqlParser, code) { + return new jqlParser.JastBuilder().build(code); + }, + + opensByDefault(node, key) { + return key === 'query'; + }, + + getNodeName(node) { + return node.type; + }, + + nodeToRange({ position }) { + if (!position) { + return; + } + return [position[0], position[1]]; + }, +}); diff --git a/website/src/parsers/jql-parser/codeExample.txt b/website/src/parsers/jql-parser/codeExample.txt new file mode 100644 index 000000000..a75fc067d --- /dev/null +++ b/website/src/parsers/jql-parser/codeExample.txt @@ -0,0 +1,3 @@ +project = JQL and +developer in ("Soney Mathew", "Kyle Painter", "Cristian Casais") +ORDER BY created ASC, duedate DESC diff --git a/website/src/parsers/jql-parser/index.js b/website/src/parsers/jql-parser/index.js new file mode 100644 index 000000000..5829ec45b --- /dev/null +++ b/website/src/parsers/jql-parser/index.js @@ -0,0 +1,6 @@ +import 'codemirror/mode/sql/sql'; + +export const id = 'jql-parser'; +export const displayName = 'JQL Parser'; +export const mimeTypes = ['application/json']; +export const fileExtension = 'jql'; diff --git a/website/src/parsers/jql-parser/jql-parser.js b/website/src/parsers/jql-parser/jql-parser.js new file mode 100644 index 000000000..23a341e78 --- /dev/null +++ b/website/src/parsers/jql-parser/jql-parser.js @@ -0,0 +1,62 @@ +import defaultParserInterface from '../utils/defaultParserInterface'; +import pkg from '@atlassianlabs/jql-parser/package.json'; +import { CharStreams, CommonTokenStream } from 'antlr4ts'; + +const ID = 'jql-parser'; +function traverse(tree, map, lexer) { + const name = tree.constructor.name; + if (name === "TerminalNode") { + const token = tree.symbol; + map["type"] = lexer.vocabulary.getSymbolicName(token.type); + map["text"] = token.text; + map["position"] = { startIndex: token.startIndex, stopIndex: token.stopIndex }; + } + else { + const children = []; + map[name] = children; + + if (tree.children) { + for (var i = 0; i < tree.children.length; i++) { + const nested = {}; + children.push(nested); + traverse(tree.children[i], nested, lexer); + } + } + } +} + +export default { + ...defaultParserInterface, + + id: ID, + displayName: pkg.name, + version: pkg.version, + homepage: 'https://www.npmjs.com/package/@atlassianlabs/jql-parser', + locationProps: new Set(['position']), + typeProps: new Set(['type']), + + loadParser(callback) { + require(['@atlassianlabs/jql-parser'], callback); + }, + + parse(jqlParser, code) { + const chars = CharStreams.fromString(code); + const lexer = new jqlParser.JQLLexer(chars); + const tokenStream = new CommonTokenStream(lexer); + const parser = new jqlParser.JQLParser(tokenStream); + const map = {}; + traverse(parser.jqlQuery(), map, lexer) + return map; + }, + + getNodeName(node) { + return node.type; + }, + + nodeToRange({ position }) { + if (!position) { + return; + } + return [position.startIndex, position.stopIndex]; + }, +}; diff --git a/website/yarn.lock b/website/yarn.lock index a5d0747e0..8bcea1bbc 100644 --- a/website/yarn.lock +++ b/website/yarn.lock @@ -16,6 +16,24 @@ dependencies: tslib "^2.2.0" +"@atlassianlabs/jql-ast@^0.0.1": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@atlassianlabs/jql-ast/-/jql-ast-0.0.1.tgz#22116f4b58a69117a74c5e382bb97305bd9b3afb" + integrity sha512-MTU/ibDIqdKNQKN1QeEXI26RIaPydlCeb4RBLRehaFiqny8ToPwIFIcmn60asUS/dRdPzum07oPIufjEFh/40g== + dependencies: + "@atlassianlabs/jql-parser" "^0.0.1" + "@babel/runtime" "^7.15.4" + antlr4ts "^0.5.0-alpha.3" + memoize-one "^5.1.1" + +"@atlassianlabs/jql-parser@^0.0.1": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@atlassianlabs/jql-parser/-/jql-parser-0.0.1.tgz#529bb5b05062f8e1953885e97b5b2de7a0804098" + integrity sha512-ukuR58r6jNUSUiQ3F0rypVHPeYSwuLaLtjOcopWP8tRIPg65vLbTPbg3v1YSsKarx56m175UKJoN6y3QcZA+9A== + dependencies: + "@babel/runtime" "^7.15.4" + antlr4ts "^0.5.0-alpha.3" + "@babel/code-frame@7.0.0-beta.44": version "7.0.0-beta.44" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.44.tgz#2a02643368de80916162be70865c97774f3adbd9" @@ -1082,6 +1100,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.15.4": + version "7.16.3" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.3.tgz#b86f0db02a04187a3c17caa77de69840165d42d5" + integrity sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7": version "7.14.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.0.tgz#46794bc20b612c5f75e62dd071e24dfd95f1cbe6" @@ -1860,6 +1885,11 @@ ansi-styles@^4.1.0: "@types/color-name" "^1.1.1" color-convert "^2.0.1" +antlr4ts@^0.5.0-alpha.3: + version "0.5.0-alpha.4" + resolved "https://registry.yarnpkg.com/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz#71702865a87478ed0b40c0709f422cf14d51652a" + integrity sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ== + anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -7473,6 +7503,11 @@ mem@^4.0.0: mimic-fn "^2.0.0" p-is-promise "^2.0.0" +memoize-one@^5.1.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e" + integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== + memory-fs@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.2.0.tgz#f2bb25368bc121e391c2520de92969caee0a0290"