Skip to content

Commit

Permalink
Add more information to AST
Browse files Browse the repository at this point in the history
  • Loading branch information
ota-meshi committed Apr 7, 2022
1 parent 3c99390 commit 1a4d0ff
Show file tree
Hide file tree
Showing 60 changed files with 454 additions and 17 deletions.
22 changes: 21 additions & 1 deletion src/ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,30 @@ export interface YAMLDocument extends BaseYAMLNode {
anchors: { [key: string]: YAMLAnchor[] }
}

export interface YAMLDirective extends BaseYAMLNode {
interface BaseYAMLDirective extends BaseYAMLNode {
type: "YAMLDirective"
value: string
kind: "YAML" | "TAG" | null
parent: YAMLDocument
}
export interface YAMLDirectiveForYAML extends BaseYAMLDirective {
kind: "YAML"
version: string
}
export interface YAMLDirectiveForTAG extends BaseYAMLDirective {
kind: "TAG"
handle: string
prefix: string
}

export interface YAMLDirectiveForUnknown extends BaseYAMLDirective {
kind: null
}

export type YAMLDirective =
| YAMLDirectiveForYAML
| YAMLDirectiveForTAG
| YAMLDirectiveForUnknown

export interface YAMLWithMeta extends BaseYAMLNode {
type: "YAMLWithMeta"
Expand All @@ -90,6 +109,7 @@ export interface YAMLAnchor extends BaseYAMLNode {
export interface YAMLTag extends BaseYAMLNode {
type: "YAMLTag"
tag: string
raw: string
parent: YAMLWithMeta
}

Expand Down
63 changes: 52 additions & 11 deletions src/convert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,17 @@ import type {
YAMLMap,
YAMLSeq,
} from "yaml"
import { isDocument } from "yaml"
import { isPair as isBasePair, isAlias, isScalar, isSeq, isMap } from "yaml"
import {
isDocument,
isPair as isBasePair,
isAlias,
isScalar,
isSeq,
isMap,
} from "yaml"

type PairParsed = BasePair<ParsedNode, ParsedNode | null>
type Directives = Document.Parsed["directives"]

const isPair = isBasePair as (node: any) => node is PairParsed

Expand Down Expand Up @@ -225,7 +232,9 @@ function convertDocument(
...loc,
}

ast.directives.push(...convertDocumentHead(directives, ctx, ast))
ast.directives.push(
...convertDocumentHead(node.directives, directives, ctx, ast),
)
let last: Locations | undefined = ast.directives[ast.directives.length - 1]

const startTokens = [...doc.start]
Expand Down Expand Up @@ -275,30 +284,61 @@ function convertDocument(
* Convert YAML.Document.Parsed to YAMLDirective[]
*/
function* convertDocumentHead(
node: Directives,
directives: CST.Directive[],
ctx: Context,
parent: YAMLDocument,
): IterableIterator<YAMLDirective> {
for (const n of directives) {
yield convertDirective(n, ctx, parent)
yield convertDirective(node, n, ctx, parent)
}
}

/**
* Convert CSTDirective to YAMLDirective
*/
function convertDirective(
node: CST.Directive,
node: Directives,
cst: CST.Directive,
ctx: Context,
parent: YAMLDocument,
): YAMLDirective {
const loc = ctx.getConvertLocation(...toRange(node))
const loc = ctx.getConvertLocation(...toRange(cst))

const value = ctx.code.slice(...loc.range)
const ast: YAMLDirective = {
type: "YAMLDirective",
value,
parent,
...loc,

const parts = cst.source.trim().split(/[\t ]+/)
const name = parts.shift()

let ast: YAMLDirective
if (name === "%YAML") {
ast = {
type: "YAMLDirective",
value,
kind: "YAML",
version: node.yaml.version,
parent,
...loc,
}
} else if (name === "%TAG") {
const [handle, prefix] = parts
ast = {
type: "YAMLDirective",
value,
kind: "TAG",
handle,
prefix,
parent,
...loc,
}
} else {
ast = {
type: "YAMLDirective",
value,
kind: null,
parent,
...loc,
}
}
ctx.addToken("Directive", loc.range)
return ast
Expand Down Expand Up @@ -1489,6 +1529,7 @@ function convertTag(
const ast: YAMLTag = {
type: "YAMLTag",
tag: resolvedTag,
raw: cst.source,
parent,
...loc,
}
Expand Down
9 changes: 4 additions & 5 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,15 +211,14 @@ ${tagText} ${text}`).toJSON()
*/
export function getYAMLVersion(document: YAMLDocument): YAMLVersion {
for (const dir of document.directives) {
const yamlVer = /^%YAML\s+(\d\.\d)$/.exec(dir.value)?.[1]
if (yamlVer) {
if (yamlVer === "1.1") {
if (dir.kind === "YAML") {
if (dir.version === "1.1") {
return "1.1"
}
if (yamlVer === "1.2") {
if (dir.version === "1.2") {
return "1.2"
}
if (yamlVer === "1.3") {
if (dir.version === "1.3") {
return "1.3"
}
// Other versions are not supported
Expand Down
15 changes: 15 additions & 0 deletions tests/fixtures/parser/ast/astexplorer-output.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
"tag": {
"type": "YAMLTag",
"tag": "tag:yaml.org,2002:map",
"raw": "!!map",
"range": [
308,
313
Expand Down Expand Up @@ -335,6 +336,7 @@
"tag": {
"type": "YAMLTag",
"tag": "tag:yaml.org,2002:map",
"raw": "!!map",
"range": [
387,
392
Expand Down Expand Up @@ -664,6 +666,7 @@
"tag": {
"type": "YAMLTag",
"tag": "tag:yaml.org,2002:omap",
"raw": "!!omap",
"range": [
589,
595
Expand Down Expand Up @@ -995,6 +998,7 @@
"tag": {
"type": "YAMLTag",
"tag": "tag:yaml.org,2002:omap",
"raw": "!!omap",
"range": [
795,
801
Expand Down Expand Up @@ -1384,6 +1388,7 @@
"tag": {
"type": "YAMLTag",
"tag": "tag:yaml.org,2002:pairs",
"raw": "!!pairs",
"range": [
965,
972
Expand Down Expand Up @@ -1794,6 +1799,7 @@
"tag": {
"type": "YAMLTag",
"tag": "tag:yaml.org,2002:pairs",
"raw": "!!pairs",
"range": [
1087,
1094
Expand Down Expand Up @@ -2104,6 +2110,7 @@
"tag": {
"type": "YAMLTag",
"tag": "tag:yaml.org,2002:set",
"raw": "!!set",
"range": [
1272,
1277
Expand Down Expand Up @@ -2315,6 +2322,7 @@
"tag": {
"type": "YAMLTag",
"tag": "tag:yaml.org,2002:set",
"raw": "!!set",
"range": [
1365,
1370
Expand Down Expand Up @@ -2584,6 +2592,7 @@
"tag": {
"type": "YAMLTag",
"tag": "tag:yaml.org,2002:seq",
"raw": "!!seq",
"range": [
1557,
1562
Expand Down Expand Up @@ -2867,6 +2876,7 @@
"tag": {
"type": "YAMLTag",
"tag": "tag:yaml.org,2002:seq",
"raw": "!!seq",
"range": [
1891,
1896
Expand Down Expand Up @@ -6554,6 +6564,7 @@
"tag": {
"type": "YAMLTag",
"tag": "tag:yaml.org,2002:js/regexp",
"raw": "!!js/regexp",
"range": [
4356,
4367
Expand Down Expand Up @@ -6649,6 +6660,7 @@
"tag": {
"type": "YAMLTag",
"tag": "tag:yaml.org,2002:js/regexp",
"raw": "!!js/regexp",
"range": [
4393,
4404
Expand Down Expand Up @@ -6775,6 +6787,7 @@
"tag": {
"type": "YAMLTag",
"tag": "tag:yaml.org,2002:js/undefined",
"raw": "!!js/undefined",
"range": [
4512,
4526
Expand Down Expand Up @@ -6870,6 +6883,7 @@
"tag": {
"type": "YAMLTag",
"tag": "tag:yaml.org,2002:js/function",
"raw": "!!js/function",
"range": [
4621,
4634
Expand Down Expand Up @@ -6965,6 +6979,7 @@
"tag": {
"type": "YAMLTag",
"tag": "!sexy",
"raw": "!sexy",
"range": [
5356,
5361
Expand Down
3 changes: 3 additions & 0 deletions tests/fixtures/parser/ast/directive01-output.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
{
"type": "YAMLDirective",
"value": "%YAML 1.2",
"kind": "YAML",
"version": "1.2",
"range": [
0,
9
Expand All @@ -29,6 +31,7 @@
"tag": {
"type": "YAMLTag",
"tag": "tag:yaml.org,2002:str",
"raw": "!!str",
"range": [
14,
19
Expand Down
3 changes: 3 additions & 0 deletions tests/fixtures/parser/ast/directive02-input.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
%TAG !yaml! tag:yaml.org,2002:
---
!yaml!str 123
Loading

0 comments on commit 1a4d0ff

Please sign in to comment.