remove obsolete validation code

pull/1864/head
Rich Harris 7 years ago
parent 1638aec061
commit d704bac8e7

@ -1,16 +0,0 @@
import checkForDupes from '../utils/checkForDupes';
import checkForComputedKeys from '../utils/checkForComputedKeys';
import { Node } from '../../../../interfaces';
import Component from '../../../Component';
export default function actions(component: Component, prop: Node) {
if (prop.value.type !== 'ObjectExpression') {
component.error(prop, {
code: `invalid-actions`,
message: `The 'actions' property must be an object literal`
});
}
checkForDupes(component, prop.value.properties);
checkForComputedKeys(component, prop.value.properties);
}

@ -1,21 +0,0 @@
import checkForDupes from '../utils/checkForDupes';
import checkForComputedKeys from '../utils/checkForComputedKeys';
import { Node } from '../../../../interfaces';
import Component from '../../../Component';
export default function transitions(component: Component, prop: Node) {
if (prop.value.type !== 'ObjectExpression') {
component.error(prop, {
code: `invalid-transitions-property`,
message: `The 'transitions' property must be an object literal`
});
}
checkForDupes(component, prop.value.properties);
checkForComputedKeys(component, prop.value.properties);
prop.value.properties.forEach(() => {
// TODO probably some validation that can happen here...
// checking for use of `this` etc?
});
}

@ -1,36 +0,0 @@
import checkForDupes from '../utils/checkForDupes';
import checkForComputedKeys from '../utils/checkForComputedKeys';
import getName from '../../../../utils/getName';
import { Node } from '../../../../interfaces';
import Component from '../../../Component';
export default function components(component: Component, prop: Node) {
if (prop.value.type !== 'ObjectExpression') {
component.error(prop, {
code: `invalid-components-property`,
message: `The 'components' property must be an object literal`
});
}
checkForDupes(component, prop.value.properties);
checkForComputedKeys(component, prop.value.properties);
prop.value.properties.forEach((node: Node) => {
const name = getName(node.key);
if (name === 'state') {
// TODO is this still true?
component.error(node, {
code: `invalid-name`,
message: `Component constructors cannot be called 'state' due to technical limitations`
});
}
if (!/^[A-Z]/.test(name)) {
component.error(node, {
code: `component-lowercase`,
message: `Component names must be capitalised`
});
}
});
}

@ -1,84 +0,0 @@
import checkForDupes from '../utils/checkForDupes';
import checkForComputedKeys from '../utils/checkForComputedKeys';
import getName from '../../../../utils/getName';
import isValidIdentifier from '../../../../utils/isValidIdentifier';
import reservedNames from '../../../../utils/reservedNames';
import { Node } from '../../../../interfaces';
import walkThroughTopFunctionScope from '../../../../utils/walkThroughTopFunctionScope';
import isThisGetCallExpression from '../../../../utils/isThisGetCallExpression';
import Component from '../../../Component';
const isFunctionExpression = new Set([
'FunctionExpression',
'ArrowFunctionExpression',
]);
export default function computed(component: Component, prop: Node) {
if (prop.value.type !== 'ObjectExpression') {
component.error(prop, {
code: `invalid-computed-property`,
message: `The 'computed' property must be an object literal`
});
}
checkForDupes(component, prop.value.properties);
checkForComputedKeys(component, 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/, '_$&');
component.error(computation.key, {
code: `invalid-computed-name`,
message: `Computed property name '${name}' is invalid — must be a valid identifier such as ${suggestion}`
});
}
if (reservedNames.has(name)) {
component.error(computation.key, {
code: `invalid-computed-name`,
message: `Computed property name '${name}' is invalid — cannot be a JavaScript reserved word`
});
}
if (!isFunctionExpression.has(computation.value.type)) {
component.error(computation.value, {
code: `invalid-computed-value`,
message: `Computed properties can be function expressions or arrow function expressions`
});
}
const { body, params } = computation.value;
walkThroughTopFunctionScope(body, (node: Node) => {
if (isThisGetCallExpression(node) && !node.callee.property.computed) {
component.error(node, {
code: `impure-computed`,
message: `Cannot use this.get(...) — values must be passed into the function as arguments`
});
}
if (node.type === 'ThisExpression') {
component.error(node, {
code: `impure-computed`,
message: `Computed properties should be pure functions — they do not have access to the component instance and cannot use 'this'. Did you mean to put this in 'methods'?`
});
}
});
if (params.length === 0) {
component.error(computation.value, {
code: `impure-computed`,
message: `A computed value must depend on at least one property`
});
}
if (params.length > 1) {
component.error(computation.value, {
code: `invalid-computed-arguments`,
message: `Computed properties must take a single argument`
});
}
});
}

@ -1,15 +0,0 @@
import { Node } from '../../../../interfaces';
import Component from '../../../Component';
const disallowed = new Set(['Literal', 'ObjectExpression', 'ArrayExpression']);
export default function data(component: Component, prop: Node) {
while (prop.type === 'ParenthesizedExpression') prop = prop.expression;
if (disallowed.has(prop.value.type)) {
component.error(prop.value, {
code: `invalid-data-property`,
message: `'data' must be a function`
});
}
}

@ -1,16 +0,0 @@
import checkForDupes from '../utils/checkForDupes';
import checkForComputedKeys from '../utils/checkForComputedKeys';
import { Node } from '../../../../interfaces';
import Component from '../../../Component';
export default function events(component: Component, prop: Node) {
if (prop.value.type !== 'ObjectExpression') {
component.error(prop, {
code: `invalid-events-property`,
message: `The 'events' property must be an object literal`
});
}
checkForDupes(component, prop.value.properties);
checkForComputedKeys(component, prop.value.properties);
}

@ -1,49 +0,0 @@
import checkForDupes from '../utils/checkForDupes';
import checkForComputedKeys from '../utils/checkForComputedKeys';
import { Node } from '../../../../interfaces';
import walkThroughTopFunctionScope from '../../../../utils/walkThroughTopFunctionScope';
import isThisGetCallExpression from '../../../../utils/isThisGetCallExpression';
import Component from '../../../Component';
export default function helpers(component: Component, prop: Node) {
if (prop.value.type !== 'ObjectExpression') {
component.error(prop, {
code: `invalid-helpers-property`,
message: `The 'helpers' property must be an object literal`
});
}
checkForDupes(component, prop.value.properties);
checkForComputedKeys(component, prop.value.properties);
prop.value.properties.forEach((prop: Node) => {
if (!/FunctionExpression/.test(prop.value.type)) return;
let usesArguments = false;
walkThroughTopFunctionScope(prop.value.body, (node: Node) => {
if (isThisGetCallExpression(node) && !node.callee.property.computed) {
component.error(node, {
code: `impure-helper`,
message: `Cannot use this.get(...) — values must be passed into the helper function as arguments`
});
}
if (node.type === 'ThisExpression') {
component.error(node, {
code: `impure-helper`,
message: `Helpers should be pure functions — they do not have access to the component instance and cannot use 'this'. Did you mean to put this in 'methods'?`
});
} else if (node.type === 'Identifier' && node.name === 'arguments') {
usesArguments = true;
}
});
if (prop.value.params.length === 0 && !usesArguments) {
component.warn(prop, {
code: `impure-helper`,
message: `Helpers should be pure functions, with at least one argument`
});
}
});
}

@ -1,11 +0,0 @@
import { Node } from '../../../../interfaces';
import Component from '../../../Component';
export default function immutable(component: Component, prop: Node) {
if (prop.value.type !== 'Literal' || typeof prop.value.value !== 'boolean') {
component.error(prop.value, {
code: `invalid-immutable-property`,
message: `'immutable' must be a boolean literal`
});
}
}

@ -1,47 +0,0 @@
import data from './data';
import actions from './actions';
import animations from './animations';
import computed from './computed';
import oncreate from './oncreate';
import ondestroy from './ondestroy';
import onstate from './onstate';
import onupdate from './onupdate';
import onrender from './onrender';
import onteardown from './onteardown';
import helpers from './helpers';
import methods from './methods';
import components from './components';
import events from './events';
import namespace from './namespace';
import preload from './preload';
import props from './props';
import tag from './tag';
import transitions from './transitions';
import setup from './setup';
import store from './store';
import immutable from './immutable';
export default {
data,
actions,
animations,
computed,
oncreate,
ondestroy,
onstate,
onupdate,
onrender,
onteardown,
helpers,
methods,
components,
events,
namespace,
preload,
props,
tag,
transitions,
setup,
store,
immutable,
};

@ -1,42 +0,0 @@
import checkForAccessors from '../utils/checkForAccessors';
import checkForDupes from '../utils/checkForDupes';
import checkForComputedKeys from '../utils/checkForComputedKeys';
import usesThisOrArguments from '../utils/usesThisOrArguments';
import getName from '../../../../utils/getName';
import { Node } from '../../../../interfaces';
import Component from '../../../Component';
const builtin = new Set(['set', 'get', 'on', 'fire', 'destroy']);
export default function methods(component: Component, prop: Node) {
if (prop.value.type !== 'ObjectExpression') {
component.error(prop, {
code: `invalid-methods-property`,
message: `The 'methods' property must be an object literal`
});
}
checkForAccessors(component, prop.value.properties, 'Methods');
checkForDupes(component, prop.value.properties);
checkForComputedKeys(component, prop.value.properties);
prop.value.properties.forEach((prop: Node) => {
const name = getName(prop.key);
if (builtin.has(name)) {
component.error(prop, {
code: `invalid-method-name`,
message: `Cannot overwrite built-in method '${name}'`
});
}
if (prop.value.type === 'ArrowFunctionExpression') {
if (usesThisOrArguments(prop.value.body)) {
component.error(prop, {
code: `invalid-method-value`,
message: `Method '${prop.key.name}' should be a function expression, not an arrow function expression`
});
}
}
});
}

@ -1,33 +0,0 @@
import * as namespaces from '../../../../utils/namespaces';
import nodeToString from '../../../../utils/nodeToString'
import fuzzymatch from '../../utils/fuzzymatch';
import { Node } from '../../../../interfaces';
import Component from '../../../Component';
const valid = new Set(namespaces.validNamespaces);
export default function namespace(component: Component, prop: Node) {
const ns = nodeToString(prop.value);
if (typeof ns !== 'string') {
component.error(prop, {
code: `invalid-namespace-property`,
message: `The 'namespace' property must be a string literal representing a valid namespace`
});
}
if (!valid.has(ns)) {
const match = fuzzymatch(ns, namespaces.validNamespaces);
if (match) {
component.error(prop, {
code: `invalid-namespace-property`,
message: `Invalid namespace '${ns}' (did you mean '${match}'?)`
});
} else {
component.error(prop, {
code: `invalid-namespace-property`,
message: `Invalid namespace '${ns}'`
});
}
}
}

@ -1,14 +0,0 @@
import usesThisOrArguments from '../utils/usesThisOrArguments';
import { Node } from '../../../../interfaces';
import Component from '../../../Component';
export default function oncreate(component: Component, prop: Node) {
if (prop.value.type === 'ArrowFunctionExpression') {
if (usesThisOrArguments(prop.value.body)) {
component.error(prop, {
code: `invalid-oncreate-property`,
message: `'oncreate' should be a function expression, not an arrow function expression`
});
}
}
}

@ -1,14 +0,0 @@
import usesThisOrArguments from '../utils/usesThisOrArguments';
import { Node } from '../../../../interfaces';
import Component from '../../../Component';
export default function ondestroy(component: Component, prop: Node) {
if (prop.value.type === 'ArrowFunctionExpression') {
if (usesThisOrArguments(prop.value.body)) {
component.error(prop, {
code: `invalid-ondestroy-property`,
message: `'ondestroy' should be a function expression, not an arrow function expression`
});
}
}
}

@ -1,12 +0,0 @@
import oncreate from './oncreate';
import { Node } from '../../../../interfaces';
import Component from '../../../Component';
export default function onrender(component: Component, prop: Node) {
component.warn(prop, {
code: `deprecated-onrender`,
message: `'onrender' has been deprecated in favour of 'oncreate', and will cause an error in Svelte 2.x`
});
oncreate(component, prop);
}

@ -1,14 +0,0 @@
import usesThisOrArguments from '../utils/usesThisOrArguments';
import { Node } from '../../../../interfaces';
import Component from '../../../Component';
export default function onstate(component: Component, prop: Node) {
if (prop.value.type === 'ArrowFunctionExpression') {
if (usesThisOrArguments(prop.value.body)) {
component.error(prop, {
code: `invalid-onstate-property`,
message: `'onstate' should be a function expression, not an arrow function expression`
});
}
}
}

@ -1,12 +0,0 @@
import ondestroy from './ondestroy';
import { Node } from '../../../../interfaces';
import Component from '../../../Component';
export default function onteardown(component: Component, prop: Node) {
component.warn(prop, {
code: `deprecated-onteardown`,
message: `'onteardown' has been deprecated in favour of 'ondestroy', and will cause an error in Svelte 2.x`
});
ondestroy(component, prop);
}

@ -1,14 +0,0 @@
import usesThisOrArguments from '../utils/usesThisOrArguments';
import { Node } from '../../../../interfaces';
import Component from '../../../Component';
export default function onupdate(component: Component, prop: Node) {
if (prop.value.type === 'ArrowFunctionExpression') {
if (usesThisOrArguments(prop.value.body)) {
component.error(prop, {
code: `invalid-onupdate-property`,
message: `'onupdate' should be a function expression, not an arrow function expression`
});
}
}
}

@ -1,6 +0,0 @@
import { Node } from '../../../../interfaces';
import Component from '../../../Component';
export default function preload(component: Component, prop: Node) {
// not sure there's anything we need to check here...
}

@ -1,21 +0,0 @@
import { Node } from '../../../../interfaces';
import nodeToString from '../../../../utils/nodeToString';
import Component from '../../../Component';
export default function props(component: Component, prop: Node) {
if (prop.value.type !== 'ArrayExpression') {
component.error(prop.value, {
code: `invalid-props-property`,
message: `'props' must be an array expression, if specified`
});
}
prop.value.elements.forEach((element: Node) => {
if (typeof nodeToString(element) !== 'string') {
component.error(element, {
code: `invalid-props-property`,
message: `'props' must be an array of string literals`
});
}
});
}

@ -1,15 +0,0 @@
import { Node } from '../../../../interfaces';
import Component from '../../../Component';
const disallowed = new Set(['Literal', 'ObjectExpression', 'ArrayExpression']);
export default function setup(component: Component, prop: Node) {
while (prop.type === 'ParenthesizedExpression') prop = prop.expression;
if (disallowed.has(prop.value.type)) {
component.error(prop.value, {
code: `invalid-setup-property`,
message: `'setup' must be a function`
});
}
}

@ -1,6 +0,0 @@
import { Node } from '../../../../interfaces';
import Component from '../../../Component';
export default function store(component: Component, prop: Node) {
// not sure there's anything we need to check here...
}

@ -1,20 +0,0 @@
import { Node } from '../../../../interfaces';
import nodeToString from '../../../../utils/nodeToString';
import Component from '../../../Component';
export default function tag(component: Component, prop: Node) {
const tag = nodeToString(prop.value);
if (typeof tag !== 'string') {
component.error(prop.value, {
code: `invalid-tag-property`,
message: `'tag' must be a string literal`
});
}
if (!/^[a-zA-Z][a-zA-Z0-9]*-[a-zA-Z0-9-]+$/.test(tag)) {
component.error(prop.value, {
code: `invalid-tag-property`,
message: `tag name must be two or more words joined by the '-' character`
});
}
}

@ -1,21 +0,0 @@
import checkForDupes from '../utils/checkForDupes';
import checkForComputedKeys from '../utils/checkForComputedKeys';
import { Node } from '../../../../interfaces';
import Component from '../../../Component';
export default function transitions(component: Component, prop: Node) {
if (prop.value.type !== 'ObjectExpression') {
component.error(prop, {
code: `invalid-transitions-property`,
message: `The 'transitions' property must be an object literal`
});
}
checkForDupes(component, prop.value.properties);
checkForComputedKeys(component, prop.value.properties);
prop.value.properties.forEach(() => {
// TODO probably some validation that can happen here...
// checking for use of `this` etc?
});
}
Loading…
Cancel
Save