Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
23cdb66
install moo
inferrinizzard Jan 17, 2022
db38b66
basic word, operator lexer
inferrinizzard Jan 19, 2022
bc88e99
add babel plugin to inline import sql
inferrinizzard Jan 19, 2022
a9dd035
update regex functions for word, string to moo
inferrinizzard Jan 20, 2022
a80cfc8
update comments, case/end, operators, numbers for moo
inferrinizzard Jan 20, 2022
9473e19
add moo support for keywords
inferrinizzard Jan 20, 2022
39e4989
add support for placeholders
inferrinizzard Jan 20, 2022
755ffb0
rename mooRegex functions
inferrinizzard Jan 20, 2022
9117964
Merge branch 'master' into 'moo/lexer'
inferrinizzard May 30, 2022
7a8cc4d
update tsconfig to allow absolute imports
inferrinizzard May 30, 2022
e863898
update import paths for src
inferrinizzard May 30, 2022
79ed1f7
update import paths for test
inferrinizzard May 30, 2022
c1d4150
update typescript version
inferrinizzard May 30, 2022
dca3a8f
update partial type imports
inferrinizzard May 30, 2022
5509e31
add webpack alias for absolute imports
inferrinizzard May 30, 2022
bbeb179
update jest config to alias absolute path
inferrinizzard May 31, 2022
ba2d7a8
:recycle:
inferrinizzard May 31, 2022
f63f78d
Merge branch 'repo/hooks'
inferrinizzard Jun 1, 2022
c7ce114
Merge branch 'repo/absolute-imports'
inferrinizzard Jun 1, 2022
bec0ac7
Merge branch 'master' into moo/lexer
inferrinizzard Jun 1, 2022
5201f7c
get moo test working with ts-jest
inferrinizzard Jun 4, 2022
a2f4e05
remove ^ and \b on moo regex
inferrinizzard Jun 4, 2022
cb5a6c9
replace spread with concat
inferrinizzard Jun 4, 2022
87f786f
move regexFactory to lexer
inferrinizzard Jun 4, 2022
436c162
add converter between moo tokens and bespoke tokens
inferrinizzard Jun 5, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .babelrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
{
"presets": ["@babel/preset-env", "@babel/preset-typescript"],
"plugins": ["@babel/plugin-proposal-class-properties", "add-module-exports"]
"plugins": [
"@babel/plugin-proposal-class-properties",
"add-module-exports",
["babel-plugin-inline-import", { "extensions": [".sql"] }]
]
}
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"no-useless-concat": "off",
"no-restricted-syntax": "off",
"no-constant-condition": "off",
"no-unused-expressions": "warn",
"prefer-template": "off",
"default-case": "off",
"prettier/prettier": ["error"],
Expand All @@ -36,7 +37,7 @@
"@typescript-eslint/indent": "off",
"@typescript-eslint/lines-between-class-members": "off",
"@typescript-eslint/naming-convention": "error",
"@typescript-eslint/no-unused-vars": "error",
"@typescript-eslint/no-unused-vars": "warn",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why warnings instead of errors?

I have found that it's better to not have the middle-ground that "warn" provides. It raises a question of if it's only a warning then should it be fixed or not?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this rule in particular blocks tests from being run if lines are partially commented, it should eventually be addressed before being merged in but while work is in progress, it's mostly a hindrance

"@typescript-eslint/quotes": [
"error",
"single",
Expand Down
12 changes: 9 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@
"url": "https://github.com/zeroturnaround/sql-formatter/issues"
},
"dependencies": {
"argparse": "^2.0.1"
"argparse": "^2.0.1",
"moo": "^0.5.1"
},
"devDependencies": {
"@babel/cli": "^7.10.4",
Expand All @@ -109,12 +110,14 @@
"@jest/globals": "^28.0.2",
"@types/babel__core": "^7.1.15",
"@types/jest": "^27.5.0",
"@types/moo": "^0.5.5",
"@typescript-eslint/eslint-plugin": "^5.21.0",
"@typescript-eslint/parser": "^5.21.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^28.0.2",
"babel-loader": "^8.1.0",
"babel-plugin-add-module-exports": "^1.0.2",
"babel-plugin-inline-import": "^3.0.0",
"dedent-js": "^1.0.1",
"eslint": "^8.14.0",
"eslint-config-airbnb-base": "^15.0.0",
Expand All @@ -131,7 +134,7 @@
"rimraf": "^3.0.2",
"ts-jest": "^28.0.0",
"ts-loader": "^9.2.6",
"typescript": "^4.3.5",
"typescript": "^4.7.2",
"webpack": "^5.64.1",
"webpack-cli": "^4.9.1",
"webpack-merge": "^5.8.0"
Expand All @@ -144,6 +147,9 @@
"collectCoverage": true,
"collectCoverageFrom": [
"src/**/*.ts"
]
],
"moduleNameMapper": {
"src/(.*)": "<rootDir>/src/$1"
}
}
}
5 changes: 3 additions & 2 deletions src/core/AliasAs.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { AliasMode } from '../types';
import { isCommand, isToken, Token, TokenType } from './token';
import type { AliasMode } from 'src/types';

import { isCommand, isToken, type Token, TokenType } from './token';

export interface TokenStream {
isWithinSelect(): boolean;
Expand Down
5 changes: 3 additions & 2 deletions src/core/AsTokenFactory.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { KeywordCase } from '../types';
import { isToken, Token, TokenType } from './token';
import type { KeywordCase } from 'src/types';

import { isToken, type Token, TokenType } from './token';

export default class AsTokenFactory {
private detectedCase: KeywordCase;
Expand Down
6 changes: 3 additions & 3 deletions src/core/Formatter.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { FormatOptions } from 'src/types';
import Params from './Params';
import Tokenizer from './Tokenizer';
import { FormatOptions } from '../types';
import formatCommaPositions from './formatCommaPositions';
import formatAliasPositions from './formatAliasPositions';
import AsTokenFactory from './AsTokenFactory';
import Parser, { Statement } from './Parser';
import Parser, { type Statement } from './Parser';
import StatementFormatter from './StatementFormatter';
import { Token } from './token';
import { type Token } from './token';
import { indentString } from './config';

/** Main formatter class that produces a final output string from list of tokens */
Expand Down
2 changes: 1 addition & 1 deletion src/core/Indentation.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { last } from '../utils';
import { last } from 'src/utils';

const INDENT_TYPE_TOP_LEVEL = 'top-level';
const INDENT_TYPE_BLOCK_LEVEL = 'block-level';
Expand Down
2 changes: 1 addition & 1 deletion src/core/InlineBlock.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isToken, Token, TokenType } from './token';
import { isToken, type Token, TokenType } from './token';

/**
* Bookkeeper for inline blocks.
Expand Down
2 changes: 1 addition & 1 deletion src/core/Params.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Token } from './token';
import { type Token } from './token';

export type ParamItems = { [k: string]: string };

Expand Down
2 changes: 1 addition & 1 deletion src/core/Parser.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EOF_TOKEN, Token, TokenType } from './token';
import { EOF_TOKEN, type Token, TokenType } from './token';
/* eslint-disable no-cond-assign */

export type Statement = {
Expand Down
9 changes: 5 additions & 4 deletions src/core/StatementFormatter.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import type { FormatOptions } from 'src/types';
import { equalizeWhitespace } from 'src/utils';

import Indentation from './Indentation';
import InlineBlock from './InlineBlock';
import Params from './Params';
import { equalizeWhitespace } from '../utils';
import { isReserved, isCommand, isToken, Token, TokenType, EOF_TOKEN } from './token';
import { FormatOptions } from '../types';
import { isReserved, isCommand, isToken, type Token, TokenType, EOF_TOKEN } from './token';
import toTabularFormat from './tabularStyle';
import AliasAs from './AliasAs';
import AsTokenFactory from './AsTokenFactory';
import { Statement } from './Parser';
import { type Statement } from './Parser';
import { indentString, isTabularStyle } from './config';
import WhitespaceBuilder, { WS } from './WhitespaceBuilder';

Expand Down
11 changes: 6 additions & 5 deletions src/core/Tokenizer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { equalizeWhitespace, escapeRegExp, id } from 'src/utils';

import * as regexFactory from './regexFactory';
import { equalizeWhitespace, escapeRegExp, id } from '../utils';
import { Token, TokenType } from './token'; // convert to partial type import in TS 4.5
import { type Token, TokenType } from './token';

export const WHITESPACE_REGEX = /^(\s+)/u;
const NULL_REGEX = /(?!)/; // zero-width negative lookahead, matches nothing
Expand Down Expand Up @@ -28,7 +29,7 @@ interface TokenizerOptions {

/** Converts SQL language string into a token stream */
export default class Tokenizer {
REGEX_MAP: { [tokenType in TokenType]: RegExp };
REGEX_MAP: Partial<{ [tokenType in TokenType]: RegExp }>;

INDEXED_PLACEHOLDER_REGEX?: RegExp;
IDENT_NAMED_PLACEHOLDER_REGEX?: RegExp;
Expand Down Expand Up @@ -165,7 +166,7 @@ export default class Tokenizer {
this.getTokenOnFirstMatch({
input,
type: tokenType,
regex: this.REGEX_MAP[tokenType],
regex: this.REGEX_MAP[tokenType]!,
transform: id,
});

Expand Down Expand Up @@ -253,7 +254,7 @@ export default class Tokenizer {
this.getTokenOnFirstMatch({
input,
type: tokenType,
regex: this.REGEX_MAP[tokenType],
regex: this.REGEX_MAP[tokenType]!,
transform: toCanonicalKeyword,
}),
undefined
Expand Down
3 changes: 2 additions & 1 deletion src/core/WhitespaceBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { last } from '../utils';
import { last } from 'src/utils';

import Indentation from './Indentation';

/** Whitespace modifiers to be used with add() method */
Expand Down
2 changes: 1 addition & 1 deletion src/core/config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FormatOptions } from '../types';
import type { FormatOptions } from 'src/types';

// Utility functions for config options

Expand Down
2 changes: 1 addition & 1 deletion src/core/formatAliasPositions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { maxLength } from '../utils';
import { maxLength } from 'src/utils';

/**
* Handles select alias placement - tabulates if enabled
Expand Down
5 changes: 3 additions & 2 deletions src/core/formatCommaPositions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { CommaPosition } from '../types';
import { maxLength } from '../utils';
import type { CommaPosition } from 'src/types';
import { maxLength } from 'src/utils';

import { WHITESPACE_REGEX } from './Tokenizer';

/**
Expand Down
2 changes: 1 addition & 1 deletion src/core/regexFactory.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { escapeRegExp, isEmpty, sortByLengthDesc } from '../utils';
import { escapeRegExp, isEmpty, sortByLengthDesc } from 'src/utils';

/**
* Builds a RegExp containing all operators for a SQL dialect
Expand Down
2 changes: 1 addition & 1 deletion src/core/tabularStyle.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IndentStyle } from '../types';
import type { IndentStyle } from 'src/types';

/**
* When tabular style enabled,
Expand Down
1 change: 1 addition & 0 deletions src/core/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export enum TokenType {
RESERVED_CASE_START = 'RESERVED_CASE_START',
RESERVED_CASE_END = 'RESERVED_CASE_END',
OPERATOR = 'OPERATOR',
COMMA = 'COMMA',
BLOCK_START = 'BLOCK_START',
BLOCK_END = 'BLOCK_END',
LINE_COMMENT = 'LINE_COMMENT',
Expand Down
14 changes: 7 additions & 7 deletions src/languages/bigquery.formatter.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import Formatter from '../core/Formatter';
import Tokenizer from '../core/Tokenizer';
import type { StringPatternType } from '../core/regexFactory';
import { EOF_TOKEN, Token } from '../core/token';
import { dedupe } from '../utils';
import Formatter from 'src/core/Formatter';
import Tokenizer from 'src/core/Tokenizer';
import { type StringPatternType } from 'src/core/regexFactory';
import { EOF_TOKEN, type Token } from 'src/core/token';
import { dedupe } from 'src/utils';

/**
* Priority 5 (last)
Expand Down Expand Up @@ -835,8 +835,8 @@ export default class BigQueryFormatter extends Formatter {
reservedBinaryCommands,
reservedDependentClauses,
reservedKeywords: dedupe([
...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []),
...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []),
...Object.values(reservedFunctions).reduce((acc, arr) => acc.concat(arr), []),
...Object.values(reservedKeywords).reduce((acc, arr) => acc.concat(arr), []),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this whole "replace spread with concat"?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • faster for large lists

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whether there's any speed difference really comes down to how does a browser or NodeJS implement the spread operator. Ideally these run at the exact same speed, like Babel will compile the spread to concat when targeting platforms without spread support.

As always with performance, we should actually measure to see whether there is any practical difference in our case.

IMHO a larger problem is that we're repeating this .reduce((acc, arr) => acc.concat(arr), []) snippet all over. Essentially it's a flatten() function. Extracting a separate function for this would also provide better optimization opportunities if needed - like one could instead use a for loop instead of reduce.

]),
stringTypes: BigQueryFormatter.stringTypes,
indexedPlaceholderTypes: ['?'],
Expand Down
12 changes: 6 additions & 6 deletions src/languages/db2.formatter.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Formatter from '../core/Formatter';
import Tokenizer from '../core/Tokenizer';
import type { StringPatternType } from '../core/regexFactory';
import { dedupe } from '../utils';
import Formatter from 'src/core/Formatter';
import Tokenizer from 'src/core/Tokenizer';
import { type StringPatternType } from 'src/core/regexFactory';
import { dedupe } from 'src/utils';

/**
* Priority 5 (last)
Expand Down Expand Up @@ -868,8 +868,8 @@ export default class Db2Formatter extends Formatter {
reservedBinaryCommands,
reservedDependentClauses,
reservedKeywords: dedupe([
...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []),
...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []),
...Object.values(reservedFunctions).reduce((acc, arr) => acc.concat(arr), []),
...Object.values(reservedKeywords).reduce((acc, arr) => acc.concat(arr), []),
]),
stringTypes: Db2Formatter.stringTypes,
indexedPlaceholderTypes: ['?'],
Expand Down
12 changes: 6 additions & 6 deletions src/languages/hive.formatter.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Formatter from '../core/Formatter';
import Tokenizer from '../core/Tokenizer';
import type { StringPatternType } from '../core/regexFactory';
import { dedupe } from '../utils';
import Formatter from 'src/core/Formatter';
import Tokenizer from 'src/core/Tokenizer';
import { type StringPatternType } from 'src/core/regexFactory';
import { dedupe } from 'src/utils';

/**
* Priority 5 (last)
Expand Down Expand Up @@ -623,8 +623,8 @@ export default class HiveFormatter extends Formatter {
reservedBinaryCommands,
reservedDependentClauses,
reservedKeywords: dedupe([
...Object.values(reservedFunctions).reduce((acc, arr) => [...acc, ...arr], []),
...Object.values(reservedKeywords).reduce((acc, arr) => [...acc, ...arr], []),
...Object.values(reservedFunctions).reduce((acc, arr) => acc.concat(arr), []),
...Object.values(reservedKeywords).reduce((acc, arr) => acc.concat(arr), []),
]),
stringTypes: HiveFormatter.stringTypes,
indexedPlaceholderTypes: ['?'],
Expand Down
12 changes: 6 additions & 6 deletions src/languages/mariadb.formatter.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import Formatter from '../core/Formatter';
import Tokenizer from '../core/Tokenizer';
import { EOF_TOKEN, isToken, Token, TokenType } from '../core/token';
import type { StringPatternType } from '../core/regexFactory';
import { dedupe } from '../utils';
import Formatter from 'src/core/Formatter';
import Tokenizer from 'src/core/Tokenizer';
import { EOF_TOKEN, isToken, type Token, TokenType } from 'src/core/token';
import { type StringPatternType } from 'src/core/regexFactory';
import { dedupe } from 'src/utils';

/**
* Priority 5 (last)
Expand Down Expand Up @@ -1165,7 +1165,7 @@ export default class MariaDbFormatter extends Formatter {
reservedBinaryCommands,
reservedDependentClauses,
reservedLogicalOperators: ['AND', 'OR', 'XOR'],
reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]),
reservedKeywords: dedupe(reservedKeywords.concat(reservedFunctions)),
stringTypes: MariaDbFormatter.stringTypes,
indexedPlaceholderTypes: ['?'],
lineCommentTypes: ['--', '#'],
Expand Down
12 changes: 6 additions & 6 deletions src/languages/mysql.formatter.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import Formatter from '../core/Formatter';
import Tokenizer from '../core/Tokenizer';
import { EOF_TOKEN, isToken, Token, TokenType } from '../core/token';
import type { StringPatternType } from '../core/regexFactory';
import { dedupe } from '../utils';
import Formatter from 'src/core/Formatter';
import Tokenizer from 'src/core/Tokenizer';
import { EOF_TOKEN, isToken, type Token, TokenType } from 'src/core/token';
import { type StringPatternType } from 'src/core/regexFactory';
import { dedupe } from 'src/utils';

// TODO: split this into object with function categories
/**
Expand Down Expand Up @@ -1328,7 +1328,7 @@ export default class MySqlFormatter extends Formatter {
reservedBinaryCommands,
reservedDependentClauses,
reservedLogicalOperators: ['AND', 'OR', 'XOR'],
reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]),
reservedKeywords: dedupe(reservedKeywords.concat(reservedFunctions)),
stringTypes: MySqlFormatter.stringTypes,
indexedPlaceholderTypes: ['?'],
lineCommentTypes: ['--', '#'],
Expand Down
10 changes: 5 additions & 5 deletions src/languages/n1ql.formatter.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Formatter from '../core/Formatter';
import Tokenizer from '../core/Tokenizer';
import type { StringPatternType } from '../core/regexFactory';
import { dedupe } from '../utils';
import Formatter from 'src/core/Formatter';
import Tokenizer from 'src/core/Tokenizer';
import { type StringPatternType } from 'src/core/regexFactory';
import { dedupe } from 'src/utils';

// TODO: split this into object with function categories
/**
Expand Down Expand Up @@ -521,7 +521,7 @@ export default class N1qlFormatter extends Formatter {
reservedBinaryCommands,
reservedDependentClauses,
reservedLogicalOperators: ['AND', 'OR', 'XOR'],
reservedKeywords: dedupe([...reservedKeywords, ...reservedFunctions]),
reservedKeywords: dedupe(reservedKeywords.concat(reservedFunctions)),
stringTypes: N1qlFormatter.stringTypes,
blockStart: ['(', '[', '{'],
blockEnd: [')', ']', '}'],
Expand Down
10 changes: 5 additions & 5 deletions src/languages/plsql.formatter.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import Formatter from '../core/Formatter';
import Tokenizer from '../core/Tokenizer';
import { EOF_TOKEN, isReserved, isToken, Token, TokenType } from '../core/token'; // convert to partial type import in TS 4.5
import type { StringPatternType } from '../core/regexFactory';
import { dedupe } from '../utils';
import Formatter from 'src/core/Formatter';
import Tokenizer from 'src/core/Tokenizer';
import { EOF_TOKEN, isReserved, isToken, type Token, TokenType } from 'src/core/token';
import { type StringPatternType } from 'src/core/regexFactory';
import { dedupe } from 'src/utils';

/**
* Priority 5 (last)
Expand Down
Loading