use acorn.isIdentifierStart and isIdentifierChar to determine validity

pull/1106/head
Rich Harris 7 years ago
parent b19303679d
commit 1833bc194f

@ -0,0 +1,11 @@
import { isIdentifierStart, isIdentifierChar } from 'acorn';
export default function isValidIdentifier(str) {
if (!isIdentifierStart(str.charCodeAt(0), true)) return false;
for (let i = 0; i < str.length; i += 1) {
if (!isIdentifierChar(str.charCodeAt(i), true)) return false;
}
return true;
}

@ -1,6 +1,8 @@
import checkForDupes from '../utils/checkForDupes';
import checkForComputedKeys from '../utils/checkForComputedKeys';
import checkForValidIdentifiers from '../utils/checkForValidIdentifiers';
import getName from '../../../utils/getName';
import isValidIdentifier from '../../../utils/isValidIdentifier';
import reservedNames from '../../../utils/reservedNames';
import { Validator } from '../../';
import { Node } from '../../../interfaces';
import walkThroughTopFunctionScope from '../../../utils/walkThroughTopFunctionScope';
@ -21,9 +23,25 @@ export default function computed(validator: Validator, prop: Node) {
checkForDupes(validator, prop.value.properties);
checkForComputedKeys(validator, prop.value.properties);
checkForValidIdentifiers(validator, prop.value.properties);
prop.value.properties.forEach((computation: Node) => {
const name = getName(computation.key);
if (!isValidIdentifier(name)) {
const suggestion = name.replace(/[^_$a-z0-9]/ig, '_').replace(/^\d/, '_$&');
validator.error(
`Computed property name '${name}' is invalid — must be a valid identifier such as ${suggestion}`,
computation.start
);
}
if (reservedNames.has(name)) {
validator.error(
`Computed property name '${name}' is invalid — cannot be a JavaScript reserved word`,
computation.start
);
}
if (!isFunctionExpression.has(computation.value.type)) {
validator.error(
`Computed properties can be function expressions or arrow function expressions`,

@ -1,25 +0,0 @@
import { Validator } from '../../';
import { Node } from '../../../interfaces';
import getName from '../../../utils/getName';
import { parse } from 'acorn';
export default function checkForValidIdentifiers(
validator: Validator,
properties: Node[]
) {
properties.forEach(prop => {
const name = getName(prop.key);
const functionDefinitionString = `function ${name}() {}`;
try {
parse(functionDefinitionString);
} catch (exception) {
const invalidCharacter = functionDefinitionString[exception.pos];
validator.error(
`Computed property name "${name}" is invalid. Character '${
invalidCharacter
}' at position ${exception.pos} is illegal in function identifiers`,
prop.start
);
}
});
}
Loading…
Cancel
Save