| "use strict"; |
| |
| Object.defineProperty(exports, "__esModule", { |
| value: true |
| }); |
| exports.default = nameTokenizer; |
| const util_js_1 = require("../../util.cjs"); |
| const isQuoted = s => s && s.startsWith('"') && s.endsWith('"'); |
| /** |
| * Splits remaining `spec.lines[].tokens.description` into `name` and `descriptions` tokens, |
| * and populates the `spec.name` |
| */ |
| function nameTokenizer() { |
| const typeEnd = (num, { |
| tokens |
| }, i) => tokens.type === '' ? num : i; |
| return spec => { |
| // look for the name starting in the line where {type} ends |
| let finalTypeLine = spec.source.reduce(typeEnd, 0); |
| let tokens; |
| if (spec.type) { |
| do { |
| ({ |
| tokens |
| } = spec.source[finalTypeLine]); |
| if (tokens.description.trim()) { |
| break; |
| } |
| finalTypeLine++; |
| } while (spec.source[finalTypeLine]); |
| } else { |
| ({ |
| tokens |
| } = spec.source[finalTypeLine]); |
| } |
| const source = tokens.description.trimStart(); |
| const quotedGroups = source.split('"'); |
| // if it starts with quoted group, assume it is a literal |
| if (quotedGroups.length > 1 && quotedGroups[0] === '' && quotedGroups.length % 2 === 1) { |
| spec.name = quotedGroups[1]; |
| tokens.name = `"${quotedGroups[1]}"`; |
| [tokens.postName, tokens.description] = (0, util_js_1.splitSpace)(source.slice(tokens.name.length)); |
| return spec; |
| } |
| let brackets = 0; |
| let name = ''; |
| let optional = false; |
| let defaultValue; |
| // assume name is non-space string or anything wrapped into brackets |
| for (const ch of source) { |
| if (brackets === 0 && (0, util_js_1.isSpace)(ch)) break; |
| if (ch === '[') brackets++; |
| if (ch === ']') brackets--; |
| name += ch; |
| } |
| if (brackets !== 0) { |
| spec.problems.push({ |
| code: 'spec:name:unpaired-brackets', |
| message: 'unpaired brackets', |
| line: spec.source[0].number, |
| critical: true |
| }); |
| return spec; |
| } |
| const nameToken = name; |
| if (name[0] === '[' && name[name.length - 1] === ']') { |
| optional = true; |
| name = name.slice(1, -1); |
| const parts = name.split('='); |
| name = parts[0].trim(); |
| if (parts[1] !== undefined) defaultValue = parts.slice(1).join('=').trim(); |
| if (name === '') { |
| spec.problems.push({ |
| code: 'spec:name:empty-name', |
| message: 'empty name', |
| line: spec.source[0].number, |
| critical: true |
| }); |
| return spec; |
| } |
| if (defaultValue === '') { |
| spec.problems.push({ |
| code: 'spec:name:empty-default', |
| message: 'empty default value', |
| line: spec.source[0].number, |
| critical: true |
| }); |
| return spec; |
| } |
| // has "=" and is not a string, except for "=>" |
| if (!isQuoted(defaultValue) && /=(?!>)/.test(defaultValue)) { |
| spec.problems.push({ |
| code: 'spec:name:invalid-default', |
| message: 'invalid default value syntax', |
| line: spec.source[0].number, |
| critical: true |
| }); |
| return spec; |
| } |
| } |
| if (!optional) { |
| const eqIndex = name.search(/=(?!>)/); |
| if (eqIndex !== -1) { |
| const preEqual = name.slice(0, eqIndex).trim(); |
| const postEqual = name.slice(eqIndex + 1).trim(); |
| if (preEqual === '') { |
| spec.problems.push({ |
| code: 'spec:name:empty-name', |
| message: 'empty name', |
| line: spec.source[0].number, |
| critical: true |
| }); |
| return spec; |
| } |
| if (postEqual === '') { |
| spec.problems.push({ |
| code: 'spec:name:empty-default', |
| message: 'empty default value', |
| line: spec.source[0].number, |
| critical: true |
| }); |
| return spec; |
| } |
| // Only match with JS identifier (or dots) before "=" |
| if (/^[\p{ID_Start}$_\.][\p{ID_Continue}$_\u200c\u200d\.]*=/u.test(name)) { |
| if (!isQuoted(postEqual) && /=(?!>)/.test(postEqual)) { |
| spec.problems.push({ |
| code: 'spec:name:invalid-default', |
| message: 'invalid default value syntax', |
| line: spec.source[0].number, |
| critical: true |
| }); |
| return spec; |
| } |
| name = preEqual; |
| defaultValue = postEqual; |
| } |
| } |
| } |
| spec.optional = optional; |
| spec.name = name; |
| tokens.name = nameToken; |
| if (defaultValue !== undefined) spec.default = defaultValue; |
| [tokens.postName, tokens.description] = (0, util_js_1.splitSpace)(source.slice(tokens.name.length)); |
| return spec; |
| }; |
| } |
| //# sourceMappingURL=name.cjs.map |