Support aliased paths in parsePath

This commit is contained in:
Zaid Abdulla committed 2016-04-21 14:43:46 +03:00
1 parent 4187b812f3
commit 1f7fa7f1b3
1 file changed
+94 -5
+94 -5
View File
@@ -162,12 +162,101 @@ pathOverlap = (a, b, start) ->
return res return res
parsePath = (path) -> parseAlias = (pattern, start, res) ->
parts = if path == '' then [] else path.split('.') aliases = []
for p, i in parts i = start
parts[i] = null if p == '*' while i < pattern.length and pattern[i] != ']'
alias = []
i = j = parsePath(pattern, i, alias) + 1
return parts while pattern[j] not in [']', ',']
if pattern[j] == '"' and i == j
++ j
while pattern[j] != '"' or pattern[j - 1] == '\\'
if ++ j >= pattern.length
throw new Error('Invalid alias expression')
if ++ j >= pattern.length
throw new Error('Invalid alias expression')
value = pattern[i...j].trim()
i = j
if value[0] == '"'
try
value = JSON.parse(value)
catch err
throw new Error('Invalid alias expression')
alias.push(value)
aliases.push(alias)
++ i if pattern[i] == ','
# Need to sort to ensure identical expressions have idential string representation
srt = (a, b) ->
for j in [0...Math.min(a.length, b.length)] by 2
for k in [0...Math.min(a[j].length, b[j].length)] by 1
if Array.isArray(a[j][k])
if Array.isArray(b[j][k])
return srt(a[j][k], b[j][k])
else if not b[j][k]?
return -1
else
return 1
else if not a[j][k]?
if not b[j][k]?
return 0
else
return 1
else if not b[j][k]? or Array.isArray(b[j][k])
return -1
else if a[j][k] > b[j][k]
return 1
else if a[j][k] < b[j][k]
return -1
if a[j].length > b[j].length
return -1
else if a[j].length < b[j].length
return 1
if a[j + 1] > b[j + 1]
return -1
else if a[j + 1] < b[j + 1]
return 1
if a.length > b.length
return -1
else if a.length < b.length
return 1
return 0
aliases.sort(srt)
res.push([].concat.apply([], aliases))
return i
parsePath = (pattern, start, res) ->
path = []
i = j = start ? 0
# Colon separator is needed for parseAlias
while j < pattern.length and pattern[j] != ':'
if pattern[j] == '.'
n = pattern.slice(i, j)
path.push(if n == '*' then null else n)
i = j + 1
else if pattern[j] == '[' and i == j
j = parseAlias(pattern, j + 1, path) + 1
i = j + 1
++ j
if j > 0
n = pattern.slice(i, j)
path.push(if n == '*' then null else n)
if not res?
return path
res.push(path)
return j
exports.UNDEFINED_TYPE = UNDEFINED_TYPE exports.UNDEFINED_TYPE = UNDEFINED_TYPE