Skip to content

Commit

Permalink
feat: experimental support for TOML v1.1 (#163)
Browse files Browse the repository at this point in the history
* WIP support for TOML v1.1

* update

* update

* Create rude-pots-leave.md

* add tests

* support for new escapes

* support other unicode key

* update test case

* support for omit seconds

* support for new inline-table

* update doc

* Update rude-pots-leave.md

* refactor

* update

* update

* fix

* support for comment char

* update
  • Loading branch information
ota-meshi committed Nov 8, 2023
1 parent 3201736 commit e0f8378
Show file tree
Hide file tree
Showing 1,407 changed files with 517,434 additions and 331 deletions.
5 changes: 5 additions & 0 deletions .changeset/rude-pots-leave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"toml-eslint-parser": minor
---

feat: experimental support for TOML v1.1
63 changes: 48 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ A TOML parser that produces output [compatible with ESLint](https://eslint.org/d
## Features

- Converts TOML text to [AST](./docs/AST.md).
- Support for [TOML 1.0.0](https://toml.io/en/v1.0.0)
- Support for [TOML 1.0.0](https://toml.io/en/v1.0.0).
- Experimental support for TOML 1.1.0. (Specifications for November 2023)

## Installation

Expand All @@ -32,15 +33,47 @@ Example **.eslintrc.js**:

```js
module.exports = {
"overrides": [
{
"files": ["*.toml"],
"parser": "toml-eslint-parser"
}
]
}
overrides: [
{
files: ["*.toml"],
parser: "toml-eslint-parser",
},
],
};
```

### Advanced Configuration

The following additional configuration options are available by specifying them in [parserOptions](https://eslint.org/docs/latest/user-guide/configuring/language-options#specifying-parser-options) in your ESLint configuration file.

Example **.eslintrc.js**:

```js
module.exports = {
overrides: [
{
files: ["*.toml"],
parser: "toml-eslint-parser",
// Additional configuration options
parserOptions: {
tomlVersion: "1.0.0",
},
},
],
};
```

#### `parserOptions.tomlVersion`

Select the TOML version by setting `"1.0.0"`, `"1.1.0"`, `"1.0"`, `"1.1"`, `"latest"`, or `"next"`. By default `"1.0.0"` is used.

- `"1.0.0"` ... Parsed using [TOML v1.0.0 specifications](https://toml.io/en/v1.0.0).
- `"1.0"` ... Alias for `"1.0.0"`.
- `"1.1.0"` ... Parsed using the TOML v1.1.0 specification, which is currently [under development](https://github.com/toml-lang/toml/issues/928). TOML 1.1.0 has not been released yet, so `"1.1.0"` is still an experimental feature. Please note that this may be subject to breaking changes in minor version releases of this parser.
- `"1.1"` ... Alias for `"1.1.0"`.
- `"latest"` ... Currently an alias for `"1.0.0"`. When a new version of TOML is released, we plan to change to that version in a minor version release of this parser.
- `"next"` ... Currently an alias for `"1.1.0"`.

## Usage for Custom Rules / Plugins

- [AST.md](./docs/AST.md) is AST specification.
Expand All @@ -52,8 +85,8 @@ module.exports = {
Example:

```ts
import type { AST } from "toml-eslint-parser"
import { parseTOML, getStaticTOMLValue } from "toml-eslint-parser"
import type { AST } from "toml-eslint-parser";
import { parseTOML, getStaticTOMLValue } from "toml-eslint-parser";

const code = `
# This is a TOML document
Expand All @@ -79,10 +112,10 @@ role = "frontend"
[servers.beta]
ip = "10.0.0.2"
role = "backend"
`
`;

const ast: AST.TOMLProgram = parseTOML(code)
console.log(ast)
const ast: AST.TOMLProgram = parseTOML(code);
console.log(ast);
// {
// type: 'Program',
// body: [
Expand Down Expand Up @@ -117,8 +150,8 @@ console.log(ast)
// ],
// }

const value = getStaticTOMLValue(ast)
console.log(value)
const value = getStaticTOMLValue(ast);
console.log(value);
// {
// title: 'TOML Example',
// owner: { name: 'Tom Preston-Werner', dob: 1979-05-27T15:32:00.000Z },
Expand Down
1 change: 1 addition & 0 deletions src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const MESSAGES = {
"unexpected-token": "Unexpected token",
"invalid-control-character":
"Control characters (codes < 0x1f and 0x7f) are not allowed",
"invalid-comment-character": "Invalid code point {{cp}} within comments",
"invalid-key-value-newline":
"The key, equals sign, and value must be on the same line",
"invalid-inline-table-newline":
Expand Down
51 changes: 51 additions & 0 deletions src/parser-options.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,54 @@
export type TOMLVersionOption =
| "1.0"
| "1.1"
| "1.0.0"
| "1.1.0"
| "latest"
| "next";
export interface TOMLVer {
lt(major: number, minor: number): boolean;
// lte(major:number,minor:number): boolean;
// gt(major:number,minor:number): boolean;
gte(major: number, minor: number): boolean;
// eq(major:number,minor:number): boolean;
}
class TOMLVerImpl implements TOMLVer {
private readonly major: number;

private readonly minor: number;

public constructor(major: number, minor: number) {
this.major = major;
this.minor = minor;
}

public lt(major: number, minor: number): boolean {
return this.major < major || (this.major === major && this.minor < minor);
}

public gte(major: number, minor: number): boolean {
return this.major > major || (this.major === major && this.minor >= minor);
}
}
const TOML_VERSION_1_0 = new TOMLVerImpl(1, 0);
const TOML_VERSION_1_1 = new TOMLVerImpl(1, 1);
const DEFAULT_TOML_VERSION: TOMLVer = TOML_VERSION_1_0;
const SUPPORTED_TOML_VERSIONS: Record<TOMLVersionOption, TOMLVer> = {
"1.0": TOML_VERSION_1_0,
"1.0.0": TOML_VERSION_1_0,
"1.1": TOML_VERSION_1_1,
"1.1.0": TOML_VERSION_1_1,
latest: TOML_VERSION_1_0,
next: TOML_VERSION_1_1,
};
export interface ParserOptions {
filePath?: string;
tomlVersion?: TOMLVersionOption;
}

/**
* Get TOML version object from given TOML version string.
*/
export function getTOMLVer(v: TOMLVersionOption | undefined | null): TOMLVer {
return SUPPORTED_TOML_VERSIONS[v || "latest"] || DEFAULT_TOML_VERSION;
}
38 changes: 37 additions & 1 deletion src/tokenizer/code-point.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
export const EOF = -1;
export const NULL = 0x00;
export const SOH = 0x01;
export const BACKSPACE = 0x08;
export const TABULATION = 0x09;
export const LINE_FEED = 0x0a;
export const FORM_FEED = 0x0c;
export const CARRIAGE_RETURN = 0x0d;
export const ESCAPE = 0x1b;
export const SO = 0x0e;
export const US = 0x1f;
export const SPACE = 0x20;
export const QUOTATION_MARK = 0x22;
Expand Down Expand Up @@ -48,8 +51,41 @@ export const LATIN_SMALL_X = 0x78;
export const LATIN_SMALL_Z = 0x7a;
export const LEFT_BRACE = 0x7b; // {
export const RIGHT_BRACE = 0x7d; // }

export const DELETE = 0x7f;
export const PAD = 0x80;
export const SUPERSCRIPT_TWO = 0xb2;
export const SUPERSCRIPT_THREE = 0xb3;
export const SUPERSCRIPT_ONE = 0xb9;
export const VULGAR_FRACTION_ONE_QUARTER = 0xbc;
export const VULGAR_FRACTION_THREE_QUARTERS = 0xbe;
export const LATIN_CAPITAL_LETTER_A_WITH_GRAVE = 0xc0;
export const LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS = 0xd6;
export const LATIN_CAPITAL_LETTER_O_WITH_STROKE = 0xd8;
export const LATIN_SMALL_LETTER_O_WITH_DIAERESIS = 0xf6;
export const LATIN_SMALL_LETTER_O_WITH_STROKE = 0xf8;
export const GREEK_SMALL_REVERSED_DOTTED_LUNATE_SIGMA_SYMBOL = 0x37b;
export const GREEK_CAPITAL_LETTER_YOT = 0x37f;
export const CP_1FFF = 0x1fff;
export const ZERO_WIDTH_NON_JOINER = 0x200c;
export const ZERO_WIDTH_JOINER = 0x200d;
export const UNDERTIE = 0x203f;
export const CHARACTER_TIE = 0x2040;
export const SUPERSCRIPT_ZERO = 0x2070;
export const CP_218F = 0x218f;
export const CIRCLED_DIGIT_ONE = 0x2460;
export const NEGATIVE_CIRCLED_DIGIT_ZERO = 0x24ff;
export const GLAGOLITIC_CAPITAL_LETTER_AZU = 0x2c00;
export const CP_2FEF = 0x2fef;
export const IDEOGRAPHIC_COMMA = 0x3001;
export const CP_D7FF = 0xd7ff;
export const CP_E000 = 0xe000;
export const CJK_COMPATIBILITY_IDEOGRAPH_F900 = 0xf900;
export const ARABIC_LIGATURE_SALAAMUHU_ALAYNAA = 0xfdcf;
export const ARABIC_LIGATURE_SALLA_USED_AS_KORANIC_STOP_SIGN_ISOLATED_FORM = 0xfdf0;
export const REPLACEMENT_CHARACTER = 0xfffd;
export const LINEAR_B_SYLLABLE_B008_A = 0x10000;
export const CP_EFFFF = 0xeffff;
export const CP_10FFFF = 0x10ffff;

/**
* Check whether the code point is a control character.
Expand Down

0 comments on commit e0f8378

Please sign in to comment.