@@ -46726,14 +46726,15 @@ function makeParserClass (Parser) {
46726
46726
let target = this.ctx
46727
46727
let finalKey = kv.key.pop()
46728
46728
for (let kw of kv.key) {
46729
- if (hasKey(target, kw) && ( !isTable(target[kw]) || target[kw][_declared ])) {
46729
+ if (hasKey(target, kw) && !isTable(target[kw])) {
46730
46730
throw this.error(new TomlError("Can't redefine existing key"))
46731
46731
}
46732
46732
target = target[kw] = target[kw] || Table()
46733
46733
}
46734
46734
if (hasKey(target, finalKey)) {
46735
46735
throw this.error(new TomlError("Can't redefine existing key"))
46736
46736
}
46737
+ target[_declared] = true
46737
46738
// unbox our numbers
46738
46739
if (isInteger(kv.value) || isFloat(kv.value)) {
46739
46740
target[finalKey] = kv.value.valueOf()
@@ -46791,6 +46792,8 @@ function makeParserClass (Parser) {
46791
46792
do {
46792
46793
if (this.char === Parser.END || this.char === CTRL_J) {
46793
46794
return this.return()
46795
+ } else if (this.char === CHAR_DEL || (this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I)) {
46796
+ throw this.errorControlCharIn('comments')
46794
46797
}
46795
46798
} while (this.nextChar())
46796
46799
}
@@ -47004,7 +47007,7 @@ function makeParserClass (Parser) {
47004
47007
} else if (this.atEndOfLine()) {
47005
47008
throw this.error(new TomlError('Unterminated string'))
47006
47009
} else if (this.char === CHAR_DEL || (this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I)) {
47007
- throw this.errorControlCharInString( )
47010
+ throw this.errorControlCharIn('strings' )
47008
47011
} else {
47009
47012
this.consume()
47010
47013
}
@@ -47033,7 +47036,7 @@ function makeParserClass (Parser) {
47033
47036
} else if (this.char === Parser.END) {
47034
47037
throw this.error(new TomlError('Unterminated multi-line string'))
47035
47038
} else if (this.char === CHAR_DEL || (this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I && this.char !== CTRL_J && this.char !== CTRL_M)) {
47036
- throw this.errorControlCharInString( )
47039
+ throw this.errorControlCharIn('strings' )
47037
47040
} else {
47038
47041
this.consume()
47039
47042
}
@@ -47049,12 +47052,28 @@ function makeParserClass (Parser) {
47049
47052
}
47050
47053
parseLiteralMultiEnd2 () {
47051
47054
if (this.char === CHAR_APOS) {
47052
- return this.return( )
47055
+ return this.next(this.parseLiteralMultiEnd3 )
47053
47056
} else {
47054
47057
this.state.buf += "''"
47055
47058
return this.goto(this.parseLiteralMultiStringContent)
47056
47059
}
47057
47060
}
47061
+ parseLiteralMultiEnd3 () {
47062
+ if (this.char === CHAR_APOS) {
47063
+ this.state.buf += "'"
47064
+ return this.next(this.parseLiteralMultiEnd4)
47065
+ } else {
47066
+ return this.returnNow()
47067
+ }
47068
+ }
47069
+ parseLiteralMultiEnd4 () {
47070
+ if (this.char === CHAR_APOS) {
47071
+ this.state.buf += "'"
47072
+ return this.return()
47073
+ } else {
47074
+ return this.returnNow()
47075
+ }
47076
+ }
47058
47077
47059
47078
/* STRINGS double quoted */
47060
47079
parseDoubleString () {
@@ -47073,7 +47092,7 @@ function makeParserClass (Parser) {
47073
47092
} else if (this.atEndOfLine()) {
47074
47093
throw this.error(new TomlError('Unterminated string'))
47075
47094
} else if (this.char === CHAR_DEL || (this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I)) {
47076
- throw this.errorControlCharInString( )
47095
+ throw this.errorControlCharIn('strings' )
47077
47096
} else {
47078
47097
this.consume()
47079
47098
}
@@ -47108,20 +47127,20 @@ function makeParserClass (Parser) {
47108
47127
} else if (this.char === Parser.END) {
47109
47128
throw this.error(new TomlError('Unterminated multi-line string'))
47110
47129
} else if (this.char === CHAR_DEL || (this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I && this.char !== CTRL_J && this.char !== CTRL_M)) {
47111
- throw this.errorControlCharInString( )
47130
+ throw this.errorControlCharIn('strings' )
47112
47131
} else {
47113
47132
this.consume()
47114
47133
}
47115
47134
} while (this.nextChar())
47116
47135
}
47117
- errorControlCharInString ( ) {
47136
+ errorControlCharIn (type ) {
47118
47137
let displayCode = '\\u00'
47119
47138
if (this.char < 16) {
47120
47139
displayCode += '0'
47121
47140
}
47122
47141
displayCode += this.char.toString(16)
47123
47142
47124
- return this.error(new TomlError(`Control characters (codes < 0x1f and 0x7f) are not allowed in strings , use ${displayCode} instead`))
47143
+ return this.error(new TomlError(`Control characters (codes < 0x1f and 0x7f) are not allowed in ${type} , use ${displayCode} instead`))
47125
47144
}
47126
47145
recordMultiEscapeReplacement (replacement) {
47127
47146
this.state.buf += replacement
@@ -47137,12 +47156,28 @@ function makeParserClass (Parser) {
47137
47156
}
47138
47157
parseMultiEnd2 () {
47139
47158
if (this.char === CHAR_QUOT) {
47140
- return this.return( )
47159
+ return this.next(this.parseMultiEnd3 )
47141
47160
} else {
47142
47161
this.state.buf += '""'
47143
47162
return this.goto(this.parseMultiStringContent)
47144
47163
}
47145
47164
}
47165
+ parseMultiEnd3 () {
47166
+ if (this.char === CHAR_QUOT) {
47167
+ this.state.buf += '"'
47168
+ return this.next(this.parseMultiEnd4)
47169
+ } else {
47170
+ return this.returnNow()
47171
+ }
47172
+ }
47173
+ parseMultiEnd4 () {
47174
+ if (this.char === CHAR_QUOT) {
47175
+ this.state.buf += '"'
47176
+ return this.return()
47177
+ } else {
47178
+ return this.returnNow()
47179
+ }
47180
+ }
47146
47181
parseMultiEscape () {
47147
47182
if (this.char === CTRL_M || this.char === CTRL_J) {
47148
47183
return this.next(this.parseMultiTrim)
@@ -47704,13 +47739,7 @@ function makeParserClass (Parser) {
47704
47739
}
47705
47740
}
47706
47741
recordInlineListValue (value) {
47707
- if (this.state.resultArr) {
47708
- const listType = this.state.resultArr[_contentType]
47709
- const valueType = tomlType(value)
47710
- if (listType !== valueType) {
47711
- throw this.error(new TomlError(`Inline lists must be a single type, not a mix of ${listType} and ${valueType}`))
47712
- }
47713
- } else {
47742
+ if (!this.state.resultArr) {
47714
47743
this.state.resultArr = InlineList(tomlType(value))
47715
47744
}
47716
47745
if (isFloat(value) || isInteger(value)) {
@@ -47773,13 +47802,26 @@ function makeParserClass (Parser) {
47773
47802
} else if (this.char === Parser.END || this.char === CHAR_NUM || this.char === CTRL_J || this.char === CTRL_M) {
47774
47803
throw this.error(new TomlError('Unterminated inline array'))
47775
47804
} else if (this.char === CHAR_COMMA) {
47776
- return this.next(this.parseInlineTable )
47805
+ return this.next(this.parseInlineTablePostComma )
47777
47806
} else if (this.char === CHAR_RCUB) {
47778
47807
return this.goto(this.parseInlineTable)
47779
47808
} else {
47780
47809
throw this.error(new TomlError('Invalid character, expected whitespace, comma (,) or close bracket (])'))
47781
47810
}
47782
47811
}
47812
+ parseInlineTablePostComma () {
47813
+ if (this.char === CHAR_SP || this.char === CTRL_I) {
47814
+ return null
47815
+ } else if (this.char === Parser.END || this.char === CHAR_NUM || this.char === CTRL_J || this.char === CTRL_M) {
47816
+ throw this.error(new TomlError('Unterminated inline array'))
47817
+ } else if (this.char === CHAR_COMMA) {
47818
+ throw this.error(new TomlError('Empty elements in inline tables are not permitted'))
47819
+ } else if (this.char === CHAR_RCUB) {
47820
+ throw this.error(new TomlError('Trailing commas in inline tables are not permitted'))
47821
+ } else {
47822
+ return this.goto(this.parseInlineTable)
47823
+ }
47824
+ }
47783
47825
}
47784
47826
return TOMLParser
47785
47827
}
@@ -48017,10 +48059,6 @@ function typeError (type) {
48017
48059
return new Error('Can only stringify objects, not ' + type)
48018
48060
}
48019
48061
48020
- function arrayOneTypeError () {
48021
- return new Error("Array values can't have mixed types")
48022
- }
48023
-
48024
48062
function getInlineKeys (obj) {
48025
48063
return Object.keys(obj).filter(key => isInline(obj[key]))
48026
48064
}
@@ -48042,20 +48080,20 @@ function toJSON (obj) {
48042
48080
48043
48081
function stringifyObject (prefix, indent, obj) {
48044
48082
obj = toJSON(obj)
48045
- var inlineKeys
48046
- var complexKeys
48083
+ let inlineKeys
48084
+ let complexKeys
48047
48085
inlineKeys = getInlineKeys(obj)
48048
48086
complexKeys = getComplexKeys(obj)
48049
- var result = []
48050
- var inlineIndent = indent || ''
48087
+ const result = []
48088
+ const inlineIndent = indent || ''
48051
48089
inlineKeys.forEach(key => {
48052
48090
var type = tomlType(obj[key])
48053
48091
if (type !== 'undefined' && type !== 'null') {
48054
48092
result.push(inlineIndent + stringifyKey(key) + ' = ' + stringifyAnyInline(obj[key], true))
48055
48093
}
48056
48094
})
48057
48095
if (result.length > 0) result.push('')
48058
- var complexIndent = prefix && inlineKeys.length > 0 ? indent + ' ' : ''
48096
+ const complexIndent = prefix && inlineKeys.length > 0 ? indent + ' ' : ''
48059
48097
complexKeys.forEach(key => {
48060
48098
result.push(stringifyComplex(prefix, complexIndent, key, obj[key]))
48061
48099
})
@@ -48107,7 +48145,7 @@ function tomlType (value) {
48107
48145
}
48108
48146
48109
48147
function stringifyKey (key) {
48110
- var keyStr = String(key)
48148
+ const keyStr = String(key)
48111
48149
if (/^[-A-Za-z0-9_]+$/.test(keyStr)) {
48112
48150
return keyStr
48113
48151
} else {
@@ -48203,9 +48241,7 @@ function stringifyFloat (value) {
48203
48241
} else if (Object.is(value, -0)) {
48204
48242
return '-0.0'
48205
48243
}
48206
- var chunks = String(value).split('.')
48207
- var int = chunks[0]
48208
- var dec = chunks[1] || 0
48244
+ const [int, dec] = String(value).split('.')
48209
48245
return stringifyInteger(int) + '.' + dec
48210
48246
}
48211
48247
@@ -48217,29 +48253,10 @@ function stringifyDatetime (value) {
48217
48253
return value.toISOString()
48218
48254
}
48219
48255
48220
- function isNumber (type) {
48221
- return type === 'float' || type === 'integer'
48222
- }
48223
- function arrayType (values) {
48224
- var contentType = tomlType(values[0])
48225
- if (values.every(_ => tomlType(_) === contentType)) return contentType
48226
- // mixed integer/float, emit as floats
48227
- if (values.every(_ => isNumber(tomlType(_)))) return 'float'
48228
- return 'mixed'
48229
- }
48230
- function validateArray (values) {
48231
- const type = arrayType(values)
48232
- if (type === 'mixed') {
48233
- throw arrayOneTypeError()
48234
- }
48235
- return type
48236
- }
48237
-
48238
48256
function stringifyInlineArray (values) {
48239
48257
values = toJSON(values)
48240
- const type = validateArray(values)
48241
- var result = '['
48242
- var stringified = values.map(_ => stringifyInline(_, type))
48258
+ let result = '['
48259
+ const stringified = values.map(_ => stringifyInline(_))
48243
48260
if (stringified.join(', ').length > 60 || /\n/.test(stringified)) {
48244
48261
result += '\n ' + stringified.join(',\n ') + '\n'
48245
48262
} else {
@@ -48250,15 +48267,15 @@ function stringifyInlineArray (values) {
48250
48267
48251
48268
function stringifyInlineTable (value) {
48252
48269
value = toJSON(value)
48253
- var result = []
48270
+ const result = []
48254
48271
Object.keys(value).forEach(key => {
48255
48272
result.push(stringifyKey(key) + ' = ' + stringifyAnyInline(value[key], false))
48256
48273
})
48257
48274
return '{ ' + result.join(', ') + (result.length > 0 ? ' ' : '') + '}'
48258
48275
}
48259
48276
48260
48277
function stringifyComplex (prefix, indent, key, value) {
48261
- var valueType = tomlType(value)
48278
+ const valueType = tomlType(value)
48262
48279
/* istanbul ignore else */
48263
48280
if (valueType === 'array') {
48264
48281
return stringifyArrayOfTables(prefix, indent, key, value)
@@ -48271,12 +48288,11 @@ function stringifyComplex (prefix, indent, key, value) {
48271
48288
48272
48289
function stringifyArrayOfTables (prefix, indent, key, values) {
48273
48290
values = toJSON(values)
48274
- validateArray(values)
48275
- var firstValueType = tomlType(values[0])
48291
+ const firstValueType = tomlType(values[0])
48276
48292
/* istanbul ignore if */
48277
48293
if (firstValueType !== 'table') throw typeError(firstValueType)
48278
- var fullKey = prefix + stringifyKey(key)
48279
- var result = ''
48294
+ const fullKey = prefix + stringifyKey(key)
48295
+ let result = ''
48280
48296
values.forEach(table => {
48281
48297
if (result.length > 0) result += '\n'
48282
48298
result += indent + '[[' + fullKey + ']]\n'
@@ -48286,8 +48302,8 @@ function stringifyArrayOfTables (prefix, indent, key, values) {
48286
48302
}
48287
48303
48288
48304
function stringifyComplexTable (prefix, indent, key, value) {
48289
- var fullKey = prefix + stringifyKey(key)
48290
- var result = ''
48305
+ const fullKey = prefix + stringifyKey(key)
48306
+ let result = ''
48291
48307
if (getInlineKeys(value).length > 0) {
48292
48308
result += indent + '[' + fullKey + ']\n'
48293
48309
}
0 commit comments