forked from yndx-shri-reviewer/shri-2020-task-2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
61 lines (52 loc) · 1.98 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import jsonToAst from 'json-to-ast'
import linters from './linters'
import { initLogs } from './constants.js'
import { createLog, copy, hasLog } from './methods.js'
function lint (jsonString) {
const ast = jsonToAst(jsonString)
const logs = parse(ast)
const errors = logs && logs.reduce((acc, { errors }) => [...acc, ...errors], [])
return errors || []
}
if (global) {
global.lint = lint
} else {
window.lint = lint
}
function parse (ast, logs = initLogs, parent) {
const { loc, children, type } = ast
if (type === 'Array') {
return children.reduce((acc, child) => parse(child, acc, parent), copy(logs))
}
const block = children && children.find(node => node.key.value === 'block')
const content = children && children.find(node => node.key.value === 'content')
const elem = children && children.find(node => node.key.value === 'elem')
const mods = children && children.find(node => node.key.value === 'mods')
const elemMods = children && children.find(node => node.key.value === 'elemMods')
const node = elem || block
const relevantLinters = linters
.filter(({ nodeName }) => logs.some(log => log.nodeName === nodeName))
if (node && node.value && node.value.value === 'warning') {
parent = 'warning'
}
const lintedLogs = relevantLinters.reduce((acc, { validator }) => {
return acc.map(log => validator({ log, content, node, mods, ast, elemMods, parent }))
}, copy(logs))
if (content && !hasLog(lintedLogs, loc)) {
const log = createLog({ nodeName: node && node.value && node.value.value, loc, mods })
if (content.value.type === 'Object') {
return parse(content.value, copy([...lintedLogs, log]), parent)
}
try {
const newLogs = copy([...lintedLogs, log])
if (content.value.children && content.value.children.length) {
return content.value.children.reduce((acc, child) => {
return parse(child, acc, parent)
}, newLogs)
}
} catch {
return lintedLogs
}
}
return lintedLogs
}