Merge branch 'master' into gh-1254

pull/1258/head
Rich Harris 7 years ago
commit 5b2e810fc2

@ -102,7 +102,7 @@ export default class Selector {
while (i-- > 1) {
const selector = block.selectors[i];
if (selector.type === 'PseudoClassSelector' && selector.name === 'global') {
validator.error(`:global(...) must be the first element in a compound selector`, selector.start);
validator.error(`:global(...) must be the first element in a compound selector`, selector);
}
}
});
@ -120,7 +120,7 @@ export default class Selector {
for (let i = start; i < end; i += 1) {
if (this.blocks[i].global) {
validator.error(`:global(...) can be at the start or end of a selector sequence, but not in the middle`, this.blocks[i].selectors[0].start);
validator.error(`:global(...) can be at the start or end of a selector sequence, but not in the middle`, this.blocks[i].selectors[0]);
}
}
}

@ -146,4 +146,4 @@ export function create(source: string, _options: CompileOptions = {}) {
}
}
export { parse, validate, version as VERSION };
export { parse, validate, Stylesheet, version as VERSION };

@ -29,6 +29,7 @@ export interface Parsed {
export interface Warning {
loc?: { line: number; column: number; pos?: number };
end?: { line: number; column: number; };
pos?: number;
message: string;
filename?: string;

@ -4,24 +4,28 @@ import getCodeFrame from '../utils/getCodeFrame';
export default class CompileError extends Error {
frame: string;
loc: { line: number; column: number };
end: { line: number; column: number };
pos: number;
filename: string;
constructor(
message: string,
template: string,
index: number,
filename: string
startPos: number,
filename: string,
endPos: number = startPos
) {
super(message);
const { line, column } = locate(template, index);
const start = locate(template, startPos);
const end = locate(template, endPos);
this.loc = { line: line + 1, column };
this.pos = index;
this.loc = { line: start.line + 1, column: start.column };
this.end = { line: end.line + 1, column: end.column };
this.pos = startPos;
this.filename = filename;
this.frame = getCodeFrame(template, line, column);
this.frame = getCodeFrame(template, start.line, start.column);
}
public toString = () => {

@ -33,7 +33,7 @@ export default function a11y(
if (name.startsWith('aria-')) {
if (invisibleElements.has(node.name)) {
// aria-unsupported-elements
validator.warn(`A11y: <${node.name}> should not have aria-* attributes`, attribute.start);
validator.warn(`A11y: <${node.name}> should not have aria-* attributes`, attribute);
}
const type = name.slice(5);
@ -42,7 +42,7 @@ export default function a11y(
let message = `A11y: Unknown aria attribute 'aria-${type}'`;
if (match) message += ` (did you mean '${match}'?)`;
validator.warn(message, attribute.start);
validator.warn(message, attribute);
}
}
@ -50,7 +50,7 @@ export default function a11y(
if (name === 'role') {
if (invisibleElements.has(node.name)) {
// aria-unsupported-elements
validator.warn(`A11y: <${node.name}> should not have role attribute`, attribute.start);
validator.warn(`A11y: <${node.name}> should not have role attribute`, attribute);
}
const value = getStaticAttributeValue(node, 'role');
@ -59,30 +59,30 @@ export default function a11y(
let message = `A11y: Unknown role '${value}'`;
if (match) message += ` (did you mean '${match}'?)`;
validator.warn(message, attribute.start);
validator.warn(message, attribute);
}
}
// no-access-key
if (name === 'accesskey') {
validator.warn(`A11y: Avoid using accesskey`, attribute.start);
validator.warn(`A11y: Avoid using accesskey`, attribute);
}
// no-autofocus
if (name === 'autofocus') {
validator.warn(`A11y: Avoid using autofocus`, attribute.start);
validator.warn(`A11y: Avoid using autofocus`, attribute);
}
// scope
if (name === 'scope' && node.name !== 'th') {
validator.warn(`A11y: The scope attribute should only be used with <th> elements`, attribute.start);
validator.warn(`A11y: The scope attribute should only be used with <th> elements`, attribute);
}
// tabindex-no-positive
if (name === 'tabindex') {
const value = getStaticAttributeValue(node, 'tabindex');
if (!isNaN(value) && +value > 0) {
validator.warn(`A11y: avoid tabindex values above zero`, attribute.start);
validator.warn(`A11y: avoid tabindex values above zero`, attribute);
}
}
@ -96,13 +96,13 @@ export default function a11y(
attributes.slice(0, -1).join(', ') + ` or ${attributes[attributes.length - 1]}` :
attributes[0];
validator.warn(`A11y: <${name}> element should have ${article} ${sequence} attribute`, node.start);
validator.warn(`A11y: <${name}> element should have ${article} ${sequence} attribute`, node);
}
}
function shouldHaveContent() {
if (node.children.length === 0) {
validator.warn(`A11y: <${node.name}> element should have child content`, node.start);
validator.warn(`A11y: <${node.name}> element should have child content`, node);
}
}
@ -110,7 +110,7 @@ export default function a11y(
const href = attributeMap.get(attribute);
const value = getStaticAttributeValue(node, attribute);
if (value === '' || value === '#') {
validator.warn(`A11y: '${value}' is not a valid ${attribute} attribute`, href.start);
validator.warn(`A11y: '${value}' is not a valid ${attribute} attribute`, href);
}
}
@ -122,7 +122,7 @@ export default function a11y(
// anchor-in-svg-is-valid
shouldHaveValidHref('xlink:href')
} else {
validator.warn(`A11y: <a> element should have an href attribute`, node.start);
validator.warn(`A11y: <a> element should have an href attribute`, node);
}
// anchor-has-content
@ -141,7 +141,7 @@ export default function a11y(
shouldHaveContent();
if (attributeMap.has('aria-hidden')) {
validator.warn(`A11y: <${node.name}> element should not be hidden`, attributeMap.get('aria-hidden').start);
validator.warn(`A11y: <${node.name}> element should not be hidden`, attributeMap.get('aria-hidden'));
}
}
@ -157,14 +157,14 @@ export default function a11y(
// no-distracting-elements
if (node.name === 'marquee' || node.name === 'blink') {
validator.warn(`A11y: Avoid <${node.name}> elements`, node.start);
validator.warn(`A11y: Avoid <${node.name}> elements`, node);
}
if (node.name === 'figcaption') {
const parent = elementStack[elementStack.length - 1];
if (parent) {
if (parent.name !== 'figure') {
validator.warn(`A11y: <figcaption> must be an immediate child of <figure>`, node.start);
validator.warn(`A11y: <figcaption> must be an immediate child of <figure>`, node);
} else {
const children = parent.children.filter(node => {
if (node.type === 'Comment') return false;
@ -175,7 +175,7 @@ export default function a11y(
const index = children.indexOf(node);
if (index !== 0 && index !== children.length - 1) {
validator.warn(`A11y: <figcaption> must be first or last child of <figure>`, node.start);
validator.warn(`A11y: <figcaption> must be first or last child of <figure>`, node);
}
}
}

@ -52,7 +52,7 @@ export default function validateHtml(validator: Validator, html: Node) {
else if (node.type === 'EachBlock') {
if (validator.helpers.has(node.context)) {
let c = node.expression.end;
let c: number = node.expression.end;
// find start of context
while (/\s/.test(validator.source[c])) c += 1;
@ -61,13 +61,13 @@ export default function validateHtml(validator: Validator, html: Node) {
validator.warn(
`Context clashes with a helper. Rename one or the other to eliminate any ambiguity`,
c
{ start: c, end: c + node.context.length }
);
}
}
if (validator.options.dev && isEmptyBlock(node)) {
validator.warn('Empty block', node.start);
validator.warn('Empty block', node);
}
if (node.children) {
@ -103,7 +103,7 @@ export default function validateHtml(validator: Validator, html: Node) {
let message = `'refs.${ref}' does not exist`;
if (match) message += ` (did you mean 'refs.${match}'?)`;
validator.error(message, callee.start);
validator.error(message, callee);
}
});
}

@ -20,13 +20,13 @@ export default function validateElement(
if (!isComponent && /^[A-Z]/.test(node.name[0])) {
// TODO upgrade to validator.error in v2
validator.warn(`${node.name} component is not defined`, node.start);
validator.warn(`${node.name} component is not defined`, node);
}
if (elementStack.length === 0 && validator.namespace !== namespaces.svg && svg.test(node.name)) {
validator.warn(
`<${node.name}> is an SVG element did you forget to add { namespace: 'svg' } ?`,
node.start
node
);
}
@ -34,12 +34,12 @@ export default function validateElement(
const nameAttribute = node.attributes.find((attribute: Node) => attribute.name === 'name');
if (nameAttribute) {
if (nameAttribute.value.length !== 1 || nameAttribute.value[0].type !== 'Text') {
validator.error(`<slot> name cannot be dynamic`, nameAttribute.start);
validator.error(`<slot> name cannot be dynamic`, nameAttribute);
}
const slotName = nameAttribute.value[0].data;
if (slotName === 'default') {
validator.error(`default is a reserved word — it cannot be used as a slot name`, nameAttribute.start);
validator.error(`default is a reserved word — it cannot be used as a slot name`, nameAttribute);
}
// TODO should duplicate slots be disallowed? Feels like it's more likely to be a
@ -63,7 +63,7 @@ export default function validateElement(
if (node.attributes.length > 0) {
validator.error(
`<title> cannot have attributes`,
node.attributes[0].start
node.attributes[0]
);
}
@ -71,7 +71,7 @@ export default function validateElement(
if (child.type !== 'Text' && child.type !== 'MustacheTag') {
validator.error(
`<title> can only contain text and {{tags}}`,
child.start
child
);
}
});
@ -98,7 +98,7 @@ export default function validateElement(
) {
validator.error(
`'value' is not a valid binding on <${node.name}> elements`,
attribute.start
attribute
);
}
@ -107,21 +107,21 @@ export default function validateElement(
if (node.name !== 'input') {
validator.error(
`'${name}' is not a valid binding on <${node.name}> elements`,
attribute.start
attribute
);
}
if (checkTypeAttribute(validator, node) !== 'checkbox') {
validator.error(
`'${name}' binding can only be used with <input type="checkbox">`,
attribute.start
attribute
);
}
} else if (name === 'group') {
if (node.name !== 'input') {
validator.error(
`'group' is not a valid binding on <${node.name}> elements`,
attribute.start
attribute
);
}
@ -130,7 +130,7 @@ export default function validateElement(
if (type !== 'checkbox' && type !== 'radio') {
validator.error(
`'checked' binding can only be used with <input type="checkbox"> or <input type="radio">`,
attribute.start
attribute
);
}
} else if (
@ -145,13 +145,13 @@ export default function validateElement(
if (node.name !== 'audio' && node.name !== 'video') {
validator.error(
`'${name}' binding can only be used with <audio> or <video>`,
attribute.start
attribute
);
}
} else {
validator.error(
`'${attribute.name}' is not a valid binding`,
attribute.start
attribute
);
}
} else if (attribute.type === 'EventHandler') {
@ -159,7 +159,7 @@ export default function validateElement(
validateEventHandler(validator, attribute, refCallees);
} else if (attribute.type === 'Transition') {
if (isComponent) {
validator.error(`Transitions can only be applied to DOM elements, not components`, attribute.start);
validator.error(`Transitions can only be applied to DOM elements, not components`, attribute);
}
validator.used.transitions.add(attribute.name);
@ -170,13 +170,13 @@ export default function validateElement(
if (bidi)
validator.error(
`An element can only have one 'transition' directive`,
attribute.start
attribute
);
validator.error(
`An element cannot have both a 'transition' directive and an '${attribute.intro
? 'in'
: 'out'}' directive`,
attribute.start
attribute
);
}
@ -186,11 +186,11 @@ export default function validateElement(
`An element cannot have both an '${hasIntro
? 'in'
: 'out'}' directive and a 'transition' directive`,
attribute.start
attribute
);
validator.error(
`An element can only have one '${hasIntro ? 'in' : 'out'}' directive`,
attribute.start
attribute
);
}
@ -201,7 +201,7 @@ export default function validateElement(
if (!validator.transitions.has(attribute.name)) {
validator.error(
`Missing transition '${attribute.name}'`,
attribute.start
attribute
);
}
} else if (attribute.type === 'Attribute') {
@ -209,7 +209,7 @@ export default function validateElement(
if (node.children.length) {
validator.error(
`A <textarea> can have either a value attribute or (equivalently) child content, but not both`,
attribute.start
attribute
);
}
}
@ -228,13 +228,13 @@ function checkTypeAttribute(validator: Validator, node: Node) {
if (!attribute) return null;
if (attribute.value === true) {
validator.error(`'type' attribute must be specified`, attribute.start);
validator.error(`'type' attribute must be specified`, attribute);
}
if (isDynamic(attribute)) {
validator.error(
`'type' attribute cannot be dynamic if input uses two-way binding`,
attribute.start
attribute
);
}
@ -245,7 +245,7 @@ function checkSlotAttribute(validator: Validator, node: Node, attribute: Node, s
if (isDynamic(attribute)) {
validator.error(
`slot attribute cannot have a dynamic value`,
attribute.start
attribute
);
}
@ -260,11 +260,11 @@ function checkSlotAttribute(validator: Validator, node: Node, attribute: Node, s
if (parent.type === 'IfBlock' || parent.type === 'EachBlock') {
const message = `Cannot place slotted elements inside an ${parent.type === 'IfBlock' ? 'if' : 'each'}-block`;
validator.error(message, attribute.start);
validator.error(message, attribute);
}
}
validator.error(`Element with a slot='...' attribute must be a descendant of a component or custom element`, attribute.start);
validator.error(`Element with a slot='...' attribute must be a descendant of a component or custom element`, attribute);
}
function isDynamic(attribute: Node) {

@ -13,10 +13,10 @@ export default function validateEventHandlerCallee(
) {
if (!attribute.expression) return;
const { callee, start, type } = attribute.expression;
const { callee, type } = attribute.expression;
if (type !== 'CallExpression') {
validator.error(`Expected a call expression`, start);
validator.error(`Expected a call expression`, attribute.expression);
}
const { name } = flattenReference(callee);
@ -30,7 +30,10 @@ export default function validateEventHandlerCallee(
if (name === 'store' && attribute.expression.callee.type === 'MemberExpression') {
if (!validator.options.store) {
validator.warn('compile with `store: true` in order to call store methods', attribute.expression.start);
validator.warn(
'compile with `store: true` in order to call store methods',
attribute.expression
);
}
return;
}
@ -56,5 +59,5 @@ export default function validateEventHandlerCallee(
message += `. '${callee.name}' exists on 'helpers', did you put it in the wrong place?`;
}
validator.warn(message, start);
validator.warn(message, attribute.expression);
}

@ -4,7 +4,7 @@ import { Node } from '../../interfaces';
export default function validateHead(validator: Validator, node: Node, refs: Map<string, Node[]>, refCallees: Node[]) {
if (node.attributes.length) {
validator.error(`<:Head> should not have any attributes or directives`, node.start);
validator.error(`<:Head> should not have any attributes or directives`, node);
}
// TODO ensure only valid elements are included here

@ -25,7 +25,7 @@ export default function validateWindow(validator: Validator, node: Node, refs: M
`Bindings on <:Window/> must be to top-level properties, e.g. '${parts[
parts.length - 1
]}' rather than '${parts.join('.')}'`,
attribute.value.start
attribute.value
);
}
@ -41,12 +41,12 @@ export default function validateWindow(validator: Validator, node: Node, refs: M
if (match) {
validator.error(
`${message} (did you mean '${match}'?)`,
attribute.start
attribute
);
} else {
validator.error(
`${message} — valid bindings are ${list(validBindings)}`,
attribute.start
attribute
);
}
}

@ -10,10 +10,10 @@ class ValidationError extends CompileError {
constructor(
message: string,
template: string,
index: number,
filename: string
pos: { start: number, end: number },
filename: string,
) {
super(message, template, index, filename);
super(message, template, pos.start, filename, pos.end);
this.name = 'ValidationError';
}
}
@ -66,23 +66,25 @@ export class Validator {
};
}
error(message: string, pos: number) {
error(message: string, pos: { start: number, end: number }) {
throw new ValidationError(message, this.source, pos, this.filename);
}
warn(message: string, pos: number) {
warn(message: string, pos: { start: number, end: number }) {
if (!this.locator) this.locator = getLocator(this.source);
const { line, column } = this.locator(pos);
const start = this.locator(pos.start);
const end = this.locator(pos.end);
const frame = getCodeFrame(this.source, line, column);
const frame = getCodeFrame(this.source, start.line, start.column);
this.onwarn({
message,
frame,
loc: { line: line + 1, column },
pos,
loc: { line: start.line + 1, column: start.column },
end: { line: end.line + 1, column: end.column },
pos: pos.start,
filename: this.filename,
toString: () => `${message} (${line + 1}:${column})\n${frame}`,
toString: () => `${message} (${start.line + 1}:${start.column})\n${frame}`,
});
}
}
@ -148,7 +150,7 @@ export default function validate(
if (!validator.used[category].has(name)) {
validator.warn(
`The '${name}' ${categories[category]} is unused`,
prop.start
prop
);
}
});

@ -13,14 +13,14 @@ export default function validateJs(validator: Validator, js: Node) {
js.content.body.forEach((node: Node) => {
// check there are no named exports
if (node.type === 'ExportNamedDeclaration') {
validator.error(`A component can only have a default export`, node.start);
validator.error(`A component can only have a default export`, node);
}
if (node.type === 'ExportDefaultDeclaration') {
if (node.declaration.type !== 'ObjectExpression') {
return validator.error(
`Default export must be an object literal`,
node.declaration.start
node.declaration
);
}
@ -37,14 +37,14 @@ export default function validateJs(validator: Validator, js: Node) {
if (props.has('oncreate') && props.has('onrender')) {
validator.error(
'Cannot have both oncreate and onrender',
props.get('onrender').start
props.get('onrender')
);
}
if (props.has('ondestroy') && props.has('onteardown')) {
validator.error(
'Cannot have both ondestroy and onteardown',
props.get('onteardown').start
props.get('onteardown')
);
}
@ -60,17 +60,17 @@ export default function validateJs(validator: Validator, js: Node) {
if (match) {
validator.error(
`Unexpected property '${name}' (did you mean '${match}'?)`,
prop.start
prop
);
} else if (/FunctionExpression/.test(prop.value.type)) {
validator.error(
`Unexpected property '${name}' (did you mean to include it in 'methods'?)`,
prop.start
prop
);
} else {
validator.error(
`Unexpected property '${name}'`,
prop.start
prop
);
}
}

@ -8,7 +8,7 @@ export default function components(validator: Validator, prop: Node) {
if (prop.value.type !== 'ObjectExpression') {
validator.error(
`The 'components' property must be an object literal`,
prop.start
prop
);
}
@ -21,12 +21,12 @@ export default function components(validator: Validator, prop: Node) {
if (name === 'state') {
validator.error(
`Component constructors cannot be called 'state' due to technical limitations`,
component.start
component
);
}
if (!/^[A-Z]/.test(name)) {
validator.warn(`Component names should be capitalised`, component.start);
validator.warn(`Component names should be capitalised`, component);
}
});
}

@ -17,7 +17,7 @@ export default function computed(validator: Validator, prop: Node) {
if (prop.value.type !== 'ObjectExpression') {
validator.error(
`The 'computed' property must be an object literal`,
prop.start
prop
);
}
@ -31,21 +31,21 @@ export default function computed(validator: Validator, prop: Node) {
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
computation
);
}
if (reservedNames.has(name)) {
validator.error(
`Computed property name '${name}' is invalid — cannot be a JavaScript reserved word`,
computation.start
computation
);
}
if (!isFunctionExpression.has(computation.value.type)) {
validator.error(
`Computed properties can be function expressions or arrow function expressions`,
computation.value.start
computation.value
);
}
@ -55,14 +55,14 @@ export default function computed(validator: Validator, prop: Node) {
if (isThisGetCallExpression(node) && !node.callee.property.computed) {
validator.error(
`Cannot use this.get(...) — values must be passed into the function as arguments`,
node.start
node
);
}
if (node.type === 'ThisExpression') {
validator.error(
`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'?`,
node.start
node
);
}
});
@ -70,7 +70,7 @@ export default function computed(validator: Validator, prop: Node) {
if (params.length === 0) {
validator.error(
`A computed value must depend on at least one property`,
computation.value.start
computation.value
);
}
@ -83,7 +83,7 @@ export default function computed(validator: Validator, prop: Node) {
if (!valid) {
validator.error(
`Computed properties cannot use destructuring in function parameters`,
param.start
param
);
}
});

@ -7,6 +7,6 @@ export default function data(validator: Validator, prop: Node) {
while (prop.type === 'ParenthesizedExpression') prop = prop.expression;
if (disallowed.has(prop.value.type)) {
validator.error(`'data' must be a function`, prop.value.start);
validator.error(`'data' must be a function`, prop.value);
}
}

@ -7,7 +7,7 @@ export default function events(validator: Validator, prop: Node) {
if (prop.value.type !== 'ObjectExpression') {
validator.error(
`The 'events' property must be an object literal`,
prop.start
prop
);
}

@ -10,7 +10,7 @@ export default function helpers(validator: Validator, prop: Node) {
if (prop.value.type !== 'ObjectExpression') {
validator.error(
`The 'helpers' property must be an object literal`,
prop.start
prop
);
}
@ -26,14 +26,14 @@ export default function helpers(validator: Validator, prop: Node) {
if (isThisGetCallExpression(node) && !node.callee.property.computed) {
validator.error(
`Cannot use this.get(...) — values must be passed into the helper function as arguments`,
node.start
node
);
}
if (node.type === 'ThisExpression') {
validator.error(
`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'?`,
node.start
node
);
} else if (node.type === 'Identifier' && node.name === 'arguments') {
usesArguments = true;
@ -43,7 +43,7 @@ export default function helpers(validator: Validator, prop: Node) {
if (prop.value.params.length === 0 && !usesArguments) {
validator.warn(
`Helpers should be pure functions, with at least one argument`,
prop.start
prop
);
}
});

@ -5,7 +5,7 @@ export default function immutable(validator: Validator, prop: Node) {
if (prop.value.type !== 'Literal' || typeof prop.value.value !== 'boolean') {
validator.error(
`'immutable' must be a boolean literal`,
prop.value.start
prop.value
);
}
}

@ -12,7 +12,7 @@ export default function methods(validator: Validator, prop: Node) {
if (prop.value.type !== 'ObjectExpression') {
validator.error(
`The 'methods' property must be an object literal`,
prop.start
prop
);
}
@ -26,7 +26,7 @@ export default function methods(validator: Validator, prop: Node) {
if (builtin.has(name)) {
validator.error(
`Cannot overwrite built-in method '${name}'`,
prop.start
prop
);
}
@ -35,7 +35,7 @@ export default function methods(validator: Validator, prop: Node) {
validator.error(
`Method '${prop.key
.name}' should be a function expression, not an arrow function expression`,
prop.start
prop
);
}
}

@ -11,7 +11,7 @@ export default function namespace(validator: Validator, prop: Node) {
if (prop.value.type !== 'Literal' || typeof ns !== 'string') {
validator.error(
`The 'namespace' property must be a string literal representing a valid namespace`,
prop.start
prop
);
}
@ -20,10 +20,10 @@ export default function namespace(validator: Validator, prop: Node) {
if (match) {
validator.error(
`Invalid namespace '${ns}' (did you mean '${match}'?)`,
prop.start
prop
);
} else {
validator.error(`Invalid namespace '${ns}'`, prop.start);
validator.error(`Invalid namespace '${ns}'`, prop);
}
}
}

@ -7,7 +7,7 @@ export default function oncreate(validator: Validator, prop: Node) {
if (usesThisOrArguments(prop.value.body)) {
validator.error(
`'oncreate' should be a function expression, not an arrow function expression`,
prop.start
prop
);
}
}

@ -7,7 +7,7 @@ export default function ondestroy(validator: Validator, prop: Node) {
if (usesThisOrArguments(prop.value.body)) {
validator.error(
`'ondestroy' should be a function expression, not an arrow function expression`,
prop.start
prop
);
}
}

@ -5,7 +5,7 @@ import { Node } from '../../../interfaces';
export default function onrender(validator: Validator, prop: Node) {
validator.warn(
`'onrender' has been deprecated in favour of 'oncreate', and will cause an error in Svelte 2.x`,
prop.start
prop
);
oncreate(validator, prop);
}

@ -5,7 +5,7 @@ import { Node } from '../../../interfaces';
export default function onteardown(validator: Validator, prop: Node) {
validator.warn(
`'onteardown' has been deprecated in favour of 'ondestroy', and will cause an error in Svelte 2.x`,
prop.start
prop
);
ondestroy(validator, prop);
}

@ -5,7 +5,7 @@ export default function props(validator: Validator, prop: Node) {
if (prop.value.type !== 'ArrayExpression') {
validator.error(
`'props' must be an array expression, if specified`,
prop.value.start
prop.value
);
}
@ -13,7 +13,7 @@ export default function props(validator: Validator, prop: Node) {
if (element.type !== 'Literal' || typeof element.value !== 'string') {
validator.error(
`'props' must be an array of string literals`,
element.start
element
);
}
});

@ -7,6 +7,6 @@ export default function setup(validator: Validator, prop: Node) {
while (prop.type === 'ParenthesizedExpression') prop = prop.expression;
if (disallowed.has(prop.value.type)) {
validator.error(`'setup' must be a function`, prop.value.start);
validator.error(`'setup' must be a function`, prop.value);
}
}

@ -5,7 +5,7 @@ export default function tag(validator: Validator, prop: Node) {
if (prop.value.type !== 'Literal' || typeof prop.value.value !== 'string') {
validator.error(
`'tag' must be a string literal`,
prop.value.start
prop.value
);
}
@ -13,7 +13,7 @@ export default function tag(validator: Validator, prop: Node) {
if (!/^[a-zA-Z][a-zA-Z0-9]*-[a-zA-Z0-9-]+$/.test(tag)) {
validator.error(
`tag name must be two or more words joined by the '-' character`,
prop.value.start
prop.value
);
}
}

@ -7,7 +7,7 @@ export default function transitions(validator: Validator, prop: Node) {
if (prop.value.type !== 'ObjectExpression') {
validator.error(
`The 'transitions' property must be an object literal`,
prop.start
prop
);
}

@ -8,7 +8,7 @@ export default function checkForAccessors(
) {
properties.forEach(prop => {
if (prop.kind !== 'init') {
validator.error(`${label} cannot use getters and setters`, prop.start);
validator.error(`${label} cannot use getters and setters`, prop);
}
});
}

@ -7,7 +7,7 @@ export default function checkForComputedKeys(
) {
properties.forEach(prop => {
if (prop.key.computed) {
validator.error(`Cannot use computed keys`, prop.start);
validator.error(`Cannot use computed keys`, prop);
}
});
}

@ -12,7 +12,7 @@ export default function checkForDupes(
const name = getName(prop.key);
if (seen.has(name)) {
validator.error(`Duplicate property '${name}'`, prop.start);
validator.error(`Duplicate property '${name}'`, prop);
}
seen.add(name);

@ -31,7 +31,8 @@ describe("validate", () => {
warnings.push({
message: warning.message,
pos: warning.pos,
loc: warning.loc
loc: warning.loc,
end: warning.end,
});
},
dev: config.dev
@ -55,6 +56,7 @@ describe("validate", () => {
assert.equal(error.message, expected.message);
assert.deepEqual(error.loc, expected.loc);
assert.deepEqual(error.end, expected.end);
assert.equal(error.pos, expected.pos);
}
});

@ -5,6 +5,10 @@
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 19
},
"pos": 0
},
@ -14,6 +18,10 @@
"line": 4,
"column": 1
},
"end": {
"line": 4,
"column": 7
},
"pos": 28
},
@ -23,6 +31,10 @@
"line": 7,
"column": 0
},
"end": {
"line": 7,
"column": 17
},
"pos": 43
},
@ -32,6 +44,10 @@
"line": 9,
"column": 0
},
"end": {
"line": 9,
"column": 20
},
"pos": 62
}
]

@ -4,5 +4,9 @@
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 19
},
"pos": 0
}]

@ -5,6 +5,10 @@
"line": 1,
"column": 11
},
"end": {
"line": 1,
"column": 37
},
"pos": 11
},
{
@ -13,6 +17,10 @@
"line": 2,
"column": 14
},
"end": {
"line": 2,
"column": 27
},
"pos": 65
},
{
@ -21,6 +29,10 @@
"line": 3,
"column": 14
},
"end": {
"line": 3,
"column": 28
},
"pos": 130
}
]

@ -5,6 +5,10 @@
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 26
},
"pos": 0
},
{
@ -13,6 +17,10 @@
"line": 2,
"column": 3
},
"end": {
"line": 2,
"column": 10
},
"pos": 30
},
{
@ -21,6 +29,10 @@
"line": 3,
"column": 3
},
"end": {
"line": 3,
"column": 11
},
"pos": 53
}
]

@ -5,6 +5,10 @@
"line": 1,
"column": 20
},
"end": {
"line": 1,
"column": 40
},
"pos": 20
},
@ -14,6 +18,10 @@
"column": 0,
"line": 1
},
"end": {
"line": 1,
"column": 41
},
"pos": 0
}
]

@ -5,6 +5,10 @@
"line": 1,
"column": 5
},
"end": {
"line": 1,
"column": 20
},
"pos": 5
}
]

@ -5,6 +5,10 @@
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 25
},
"pos": 6
},
@ -14,6 +18,10 @@
"line": 2,
"column": 6
},
"end": {
"line": 2,
"column": 20
},
"pos": 33
}
]

@ -5,6 +5,10 @@
"line": 4,
"column": 1
},
"end": {
"line": 6,
"column": 14
},
"pos": 57
},
{
@ -13,6 +17,10 @@
"line": 15,
"column": 2
},
"end": {
"line": 17,
"column": 15
},
"pos": 252
}
]

@ -5,6 +5,10 @@
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 9
},
"pos": 0
},
@ -14,6 +18,10 @@
"line": 2,
"column": 4
},
"end": {
"line": 2,
"column": 15
},
"pos": 14
}
]

@ -4,6 +4,10 @@
"column": 0,
"line": 5
},
"end": {
"line": 5,
"column": 13
},
"message": "A11y: <html> element should have a lang attribute",
"pos": 84
}

@ -5,6 +5,10 @@
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 31
},
"pos": 0
}
]

@ -4,5 +4,9 @@
"line": 1,
"column": 5
},
"end": {
"line": 1,
"column": 18
},
"pos": 5
}]

@ -4,5 +4,9 @@
"line": 1,
"column": 5
},
"end": {
"line": 1,
"column": 14
},
"pos": 5
}]

@ -5,6 +5,10 @@
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 10
},
"pos": 0
},
@ -14,6 +18,10 @@
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 8
},
"pos": 11
}
]

@ -5,6 +5,10 @@
"column": 8,
"line": 2
},
"end": {
"line": 2,
"column": 17
},
"pos": 29
}
]

@ -5,6 +5,10 @@
"line": 1,
"column": 5
},
"end": {
"line": 1,
"column": 10
},
"pos": 5
}
]

@ -5,6 +5,10 @@
"line": 3,
"column": 5
},
"end": {
"line": 3,
"column": 17
},
"pos": 46
}
]

@ -4,5 +4,9 @@
"line": 1,
"column": 7
},
"end": {
"line": 1,
"column": 25
},
"pos": 7
}]

@ -4,5 +4,9 @@
"line": 1,
"column": 24
},
"end": {
"line": 1,
"column": 28
},
"pos": 24
}]

@ -4,5 +4,9 @@
"line": 1,
"column": 24
},
"end": {
"line": 1,
"column": 44
},
"pos": 24
}]

@ -4,5 +4,9 @@
"loc": {
"line": 1,
"column": 5
},
"end": {
"line": 1,
"column": 15
}
}]

@ -4,5 +4,9 @@
"loc": {
"line": 1,
"column": 5
},
"end": {
"line": 1,
"column": 18
}
}]

@ -4,5 +4,9 @@
"loc": {
"line": 6,
"column": 3
},
"end": {
"line": 6,
"column": 8
}
}]

@ -4,5 +4,9 @@
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 20
},
"pos": 6
}]

@ -4,5 +4,9 @@
"line": 2,
"column": 9
},
"end": {
"line": 2,
"column": 23
},
"pos": 18
}]

@ -4,5 +4,9 @@
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 20
},
"pos": 6
}]

@ -4,5 +4,9 @@
"line": 2,
"column": 1
},
"end": {
"line": 2,
"column": 1
},
"pos": 27
}]

@ -4,5 +4,9 @@
"line": 3,
"column": 7
},
"end": {
"line": 3,
"column": 17
},
"pos": 43
}]

@ -4,5 +4,9 @@
"line": 3,
"column": 7
},
"end": {
"line": 3,
"column": 17
},
"pos": 31
}]

@ -4,5 +4,9 @@
"loc": {
"line": 7,
"column": 4
},
"end": {
"line": 7,
"column": 8
}
}]

@ -4,5 +4,9 @@
"loc": {
"line": 7,
"column": 11
},
"end": {
"line": 7,
"column": 28
}
}]

@ -4,5 +4,9 @@
"line": 2,
"column": 6
},
"end": {
"line": 2,
"column": 19
},
"pos": 14
}]

@ -4,5 +4,9 @@
"line": 2,
"column": 5
},
"end": {
"line": 2,
"column": 18
},
"pos": 13
}]

@ -4,5 +4,9 @@
"line": 1,
"column": 18
},
"end": {
"line": 1,
"column": 18
},
"pos": 18
}]

@ -4,5 +4,9 @@
"line": 1,
"column": 17
},
"end": {
"line": 1,
"column": 17
},
"pos": 17
}]

@ -5,6 +5,10 @@
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 9
},
"pos": 0
},
{
@ -13,6 +17,10 @@
"line": 5,
"column": 0
},
"end": {
"line": 5,
"column": 34
},
"pos": 38
}
]

@ -4,5 +4,9 @@
"loc": {
"line": 2,
"column": 18
},
"end": {
"line": 2,
"column": 35
}
}]

@ -4,5 +4,9 @@
"loc": {
"line": 3,
"column": 8
},
"end": {
"line": 3,
"column": 8
}
}]

@ -4,5 +4,9 @@
"loc": {
"line": 2,
"column": 16
},
"end": {
"line": 2,
"column": 22
}
}]

@ -4,5 +4,9 @@
"line": 1,
"column": 18
},
"end": {
"line": 1,
"column": 23
},
"pos": 18
}]

@ -4,5 +4,9 @@
"loc": {
"line": 6,
"column": 3
},
"end": {
"line": 8,
"column": 4
}
}]

@ -4,5 +4,9 @@
"loc": {
"line": 7,
"column": 4
},
"end": {
"line": 7,
"column": 8
}
}]

@ -4,5 +4,9 @@
"loc": {
"line": 7,
"column": 11
},
"end": {
"line": 7,
"column": 28
}
}]

@ -4,5 +4,9 @@
"loc": {
"line": 6,
"column": 3
},
"end": {
"line": 8,
"column": 4
}
}]

@ -4,5 +4,9 @@
"loc": {
"line": 1,
"column": 18
},
"end": {
"line": 1,
"column": 23
}
}]

@ -4,5 +4,9 @@
"loc": {
"line": 1,
"column": 18
},
"end": {
"line": 1,
"column": 23
}
}]

@ -4,5 +4,9 @@
"line": 2,
"column": 1
},
"end": {
"line": 2,
"column": 10
},
"pos": 7
}]

@ -4,5 +4,9 @@
"loc": {
"line": 2,
"column": 1
},
"end": {
"line": 2,
"column": 21
}
}]

@ -4,5 +4,9 @@
"loc": {
"line": 3,
"column": 2
},
"end": {
"line": 3,
"column": 18
}
}]

@ -4,5 +4,9 @@
"loc": {
"line": 3,
"column": 2
},
"end": {
"line": 3,
"column": 41
}
}]

@ -4,5 +4,9 @@
"loc": {
"line": 5,
"column": 2
},
"end": {
"line": 5,
"column": 11
}
}]

@ -4,5 +4,9 @@
"line": 3,
"column": 2
},
"end": {
"line": 3,
"column": 37
},
"pos": 29
}]

@ -4,5 +4,9 @@
"line": 3,
"column": 2
},
"end": {
"line": 3,
"column": 33
},
"pos": 29
}]

@ -4,5 +4,9 @@
"line": 3,
"column": 2
},
"end": {
"line": 3,
"column": 34
},
"pos": 29
}]

@ -4,5 +4,9 @@
"line": 3,
"column": 2
},
"end": {
"line": 3,
"column": 34
},
"pos": 29
}]

@ -4,5 +4,9 @@
"line": 3,
"column": 2
},
"end": {
"line": 3,
"column": 38
},
"pos": 29
}]

@ -4,5 +4,9 @@
"loc": {
"line": 3,
"column": 2
},
"end": {
"line": 5,
"column": 3
}
}]

@ -4,5 +4,9 @@
"loc": {
"line": 3,
"column": 2
},
"end": {
"line": 5,
"column": 3
}
}]

@ -4,5 +4,9 @@
"line": 6,
"column": 3
},
"end": {
"line": 6,
"column": 6
},
"pos": 59
}]

@ -5,5 +5,9 @@
"line": 9,
"column": 3
},
"end": {
"line": 9,
"column": 18
},
"pos": 87
}]

@ -4,5 +4,9 @@
"line": 5,
"column": 2
},
"end": {
"line": 5,
"column": 23
},
"pos": 42
}]

@ -4,5 +4,9 @@
"line": 6,
"column": 8
},
"end": {
"line": 6,
"column": 20
},
"pos": 62
}]

@ -4,5 +4,9 @@
"line": 9,
"column": 3
},
"end": {
"line": 9,
"column": 28
},
"pos": 87
}]

@ -4,5 +4,9 @@
"line": 6,
"column": 8
},
"end": {
"line": 6,
"column": 16
},
"pos": 62
}]

@ -4,5 +4,9 @@
"loc": {
"line": 4,
"column": 8
},
"end": {
"line": 4,
"column": 16
}
}]

@ -4,5 +4,9 @@
"line": 5,
"column": 8
},
"end": {
"line": 7,
"column": 3
},
"pos": 48
}]

@ -4,5 +4,9 @@
"line": 9,
"column": 2
},
"end": {
"line": 11,
"column": 3
},
"pos": 74
}]

@ -4,5 +4,9 @@
"line": 4,
"column": 3
},
"end": {
"line": 6,
"column": 4
},
"pos": 43
}]

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save