mirror of https://github.com/sveltejs/svelte
parent
c1d230d625
commit
0698525f1b
@ -0,0 +1,31 @@
|
|||||||
|
import spaces from './spaces.js';
|
||||||
|
|
||||||
|
function tabsToSpaces ( str ) {
|
||||||
|
return str.replace( /^\t+/, match => match.split( '\t' ).join( ' ' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function getCodeFrame ( source, line, column ) {
|
||||||
|
const lines = source.split( '\n' );
|
||||||
|
|
||||||
|
const frameStart = Math.max( 0, line - 2 );
|
||||||
|
const frameEnd = Math.min( line + 3, lines.length );
|
||||||
|
|
||||||
|
const digits = String( frameEnd + 1 ).length;
|
||||||
|
|
||||||
|
return lines
|
||||||
|
.slice( frameStart, frameEnd )
|
||||||
|
.map( ( str, i ) => {
|
||||||
|
const isErrorLine = frameStart + i === line;
|
||||||
|
|
||||||
|
let lineNum = String( i + frameStart + 1 );
|
||||||
|
while ( lineNum.length < digits ) lineNum = ` ${lineNum}`;
|
||||||
|
|
||||||
|
if ( isErrorLine ) {
|
||||||
|
const indicator = spaces( digits + 2 + tabsToSpaces( str.slice( 0, column ) ).length ) + '^';
|
||||||
|
return `${lineNum}: ${tabsToSpaces( str )}\n${indicator}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${lineNum}: ${tabsToSpaces( str )}`;
|
||||||
|
})
|
||||||
|
.join( '\n' );
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
import validateJs from './js/index.js';
|
||||||
|
import { getLocator } from 'locate-character';
|
||||||
|
|
||||||
|
export default function validate ( parsed, source ) {
|
||||||
|
const locator = getLocator( source );
|
||||||
|
|
||||||
|
const validator = {
|
||||||
|
error: ( message, pos ) => {
|
||||||
|
const { line, column } = locator( pos );
|
||||||
|
|
||||||
|
validator.errors.push({
|
||||||
|
message,
|
||||||
|
pos,
|
||||||
|
loc: { line: line + 1, column }
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
warn: ( message, pos ) => {
|
||||||
|
const { line, column } = locator( pos );
|
||||||
|
|
||||||
|
validator.warnings.push({
|
||||||
|
message,
|
||||||
|
pos,
|
||||||
|
loc: { line: line + 1, column }
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
templateProperties: {},
|
||||||
|
|
||||||
|
errors: [],
|
||||||
|
warnings: []
|
||||||
|
};
|
||||||
|
|
||||||
|
if ( parsed.js ) {
|
||||||
|
validateJs( validator, parsed.js, source );
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
errors: validator.errors,
|
||||||
|
warnings: validator.warnings
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
import propValidators from './propValidators/index.js';
|
||||||
|
import FuzzySet from './utils/FuzzySet.js';
|
||||||
|
import checkForDupes from './utils/checkForDupes.js';
|
||||||
|
import checkForComputedKeys from './utils/checkForComputedKeys.js';
|
||||||
|
|
||||||
|
const validPropList = Object.keys( propValidators );
|
||||||
|
|
||||||
|
const fuzzySet = new FuzzySet( validPropList );
|
||||||
|
|
||||||
|
export default function validateJs ( validator, js, source ) {
|
||||||
|
js.content.body.forEach( node => {
|
||||||
|
// check there are no named exports
|
||||||
|
if ( node.type === 'ExportNamedDeclaration' ) {
|
||||||
|
validator.error( `A component can only have a default export`, node.start );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( node.type === 'ExportDefaultDeclaration' ) {
|
||||||
|
if ( validator.defaultExport ) {
|
||||||
|
validator.error( `Duplicate default export`, node.start );
|
||||||
|
}
|
||||||
|
|
||||||
|
validator.defaultExport = node;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// ensure all exported props are valid
|
||||||
|
if ( validator.defaultExport ) {
|
||||||
|
checkForComputedKeys( validator, validator.defaultExport.declaration.properties );
|
||||||
|
checkForDupes( validator, validator.defaultExport.declaration.properties );
|
||||||
|
|
||||||
|
validator.defaultExport.declaration.properties.forEach( prop => {
|
||||||
|
validator.templateProperties[ prop.key.value ] = prop;
|
||||||
|
});
|
||||||
|
|
||||||
|
validator.defaultExport.declaration.properties.forEach( prop => {
|
||||||
|
const propValidator = propValidators[ prop.key.name ];
|
||||||
|
|
||||||
|
if ( propValidator ) {
|
||||||
|
propValidator( validator, prop );
|
||||||
|
} else {
|
||||||
|
const matches = fuzzySet.get( prop.key.name );
|
||||||
|
if ( matches && matches[0] && matches[0][0] > 0.7 ) {
|
||||||
|
validator.error( `Unexpected property '${prop.key.name}' (did you mean '${matches[0][1]}'?)`, prop.start );
|
||||||
|
} else if ( /FunctionExpression/.test( prop.value.type ) ) {
|
||||||
|
validator.error( `Unexpected property '${prop.key.name}' (did you mean to include it in 'methods'?)`, prop.start );
|
||||||
|
} else {
|
||||||
|
validator.error( `Unexpected property '${prop.key.name}'`, prop.start );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
export default function components ( validator, prop ) {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
import checkForDupes from '../utils/checkForDupes.js';
|
||||||
|
import checkForComputedKeys from '../utils/checkForComputedKeys.js';
|
||||||
|
|
||||||
|
const isFunctionExpression = {
|
||||||
|
FunctionExpression: true,
|
||||||
|
ArrowFunctionExpression: true
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function computed ( validator, prop ) {
|
||||||
|
if ( prop.value.type !== 'ObjectExpression' ) {
|
||||||
|
validator.error( `The 'computed' property must be an object literal`, prop.start );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkForDupes( validator, prop.value.properties );
|
||||||
|
checkForComputedKeys( validator, prop.value.properties );
|
||||||
|
|
||||||
|
prop.value.properties.forEach( computation => {
|
||||||
|
if ( !isFunctionExpression[ computation.value.type ] ) {
|
||||||
|
validator.error( `Computed properties can be function expressions or arrow function expressions`, computation.value.start );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
computation.value.params.forEach( param => {
|
||||||
|
const valid = param.type === 'Identifier' || param.type === 'AssignmentPattern' && param.left.type === 'Identifier';
|
||||||
|
|
||||||
|
if ( !valid ) {
|
||||||
|
validator.error( `Computed properties cannot use destructuring in function parameters`, param.start );
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
export default function data ( validator, prop ) {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
export default function events ( validator, prop ) {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
export default function helpers ( validator, prop ) {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
import data from './data.js';
|
||||||
|
import computed from './computed.js';
|
||||||
|
import onrender from './onrender.js';
|
||||||
|
import onteardown from './onteardown.js';
|
||||||
|
import helpers from './helpers.js';
|
||||||
|
import methods from './methods.js';
|
||||||
|
import components from './components.js';
|
||||||
|
import events from './events.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data,
|
||||||
|
computed,
|
||||||
|
onrender,
|
||||||
|
onteardown,
|
||||||
|
helpers,
|
||||||
|
methods,
|
||||||
|
components,
|
||||||
|
events
|
||||||
|
};
|
@ -0,0 +1,3 @@
|
|||||||
|
export default function methods ( validator, prop ) {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
export default function onrender ( validator, prop ) {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
export default function onteardown ( validator, prop ) {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,290 @@
|
|||||||
|
// adapted from https://github.com/Glench/this.js/blob/master/lib/this.js
|
||||||
|
// BSD Licensed
|
||||||
|
|
||||||
|
export default function FuzzySet (arr, useLevenshtein, gramSizeLower, gramSizeUpper) {
|
||||||
|
// default options
|
||||||
|
arr = arr || [];
|
||||||
|
this.gramSizeLower = gramSizeLower || 2;
|
||||||
|
this.gramSizeUpper = gramSizeUpper || 3;
|
||||||
|
this.useLevenshtein = (typeof useLevenshtein !== 'boolean') ? true : useLevenshtein;
|
||||||
|
|
||||||
|
// define all the object functions and attributes
|
||||||
|
this.exactSet = {};
|
||||||
|
this.matchDict = {};
|
||||||
|
this.items = {};
|
||||||
|
|
||||||
|
// helper functions
|
||||||
|
function levenshtein ( str1, str2 ) {
|
||||||
|
const current = [];
|
||||||
|
let prev;
|
||||||
|
let value;
|
||||||
|
|
||||||
|
for (let i = 0; i <= str2.length; i++) {
|
||||||
|
for (let j = 0; j <= str1.length; j++) {
|
||||||
|
if (i && j) {
|
||||||
|
if (str1.charAt(j - 1) === str2.charAt(i - 1)) {
|
||||||
|
value = prev;
|
||||||
|
} else {
|
||||||
|
value = Math.min(current[j], current[j - 1], prev) + 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value = i + j;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev = current[j];
|
||||||
|
current[j] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return current.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// return an edit distance from 0 to 1
|
||||||
|
function _distance (str1, str2) {
|
||||||
|
if (str1 === null && str2 === null) throw 'Trying to compare two null values';
|
||||||
|
if (str1 === null || str2 === null) return 0;
|
||||||
|
str1 = String(str1); str2 = String(str2);
|
||||||
|
|
||||||
|
const distance = levenshtein(str1, str2);
|
||||||
|
if (str1.length > str2.length) {
|
||||||
|
return 1 - distance / str1.length;
|
||||||
|
} else {
|
||||||
|
return 1 - distance / str2.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const _nonWordRe = /[^\w, ]+/;
|
||||||
|
|
||||||
|
function _iterateGrams (value, gramSize) {
|
||||||
|
gramSize = gramSize || 2;
|
||||||
|
const simplified = '-' + value.toLowerCase().replace(_nonWordRe, '') + '-';
|
||||||
|
const lenDiff = gramSize - simplified.length;
|
||||||
|
const results = [];
|
||||||
|
|
||||||
|
if (lenDiff > 0) {
|
||||||
|
for (let i = 0; i < lenDiff; ++i) {
|
||||||
|
value += '-';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let i = 0; i < simplified.length - gramSize + 1; ++i) {
|
||||||
|
results.push(simplified.slice(i, i + gramSize));
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _gramCounter (value, gramSize) {
|
||||||
|
// return an object where key=gram, value=number of occurrences
|
||||||
|
gramSize = gramSize || 2;
|
||||||
|
const result = {};
|
||||||
|
const grams = _iterateGrams(value, gramSize);
|
||||||
|
let i = 0;
|
||||||
|
|
||||||
|
for (i; i < grams.length; ++i) {
|
||||||
|
if (grams[i] in result) {
|
||||||
|
result[grams[i]] += 1;
|
||||||
|
} else {
|
||||||
|
result[grams[i]] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the main functions
|
||||||
|
this.get = function (value, defaultValue) {
|
||||||
|
// check for value in set, returning defaultValue or null if none found
|
||||||
|
const result = this._get(value);
|
||||||
|
if (!result && typeof defaultValue !== 'undefined') {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
this._get = function (value) {
|
||||||
|
const normalizedValue = this._normalizeStr(value);
|
||||||
|
const result = this.exactSet[normalizedValue];
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
return [[1, result]];
|
||||||
|
}
|
||||||
|
|
||||||
|
let results = [];
|
||||||
|
// start with high gram size and if there are no results, go to lower gram sizes
|
||||||
|
for (let gramSize = this.gramSizeUpper; gramSize >= this.gramSizeLower; --gramSize) {
|
||||||
|
results = this.__get(value, gramSize);
|
||||||
|
if (results) {
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.__get = function (value, gramSize) {
|
||||||
|
const normalizedValue = this._normalizeStr(value);
|
||||||
|
const matches = {};
|
||||||
|
const gramCounts = _gramCounter(normalizedValue, gramSize);
|
||||||
|
const items = this.items[gramSize];
|
||||||
|
let sumOfSquareGramCounts = 0;
|
||||||
|
let gram;
|
||||||
|
let gramCount;
|
||||||
|
let i;
|
||||||
|
let index;
|
||||||
|
let otherGramCount;
|
||||||
|
|
||||||
|
for (gram in gramCounts) {
|
||||||
|
gramCount = gramCounts[gram];
|
||||||
|
sumOfSquareGramCounts += Math.pow(gramCount, 2);
|
||||||
|
if (gram in this.matchDict) {
|
||||||
|
for (i = 0; i < this.matchDict[gram].length; ++i) {
|
||||||
|
index = this.matchDict[gram][i][0];
|
||||||
|
otherGramCount = this.matchDict[gram][i][1];
|
||||||
|
if (index in matches) {
|
||||||
|
matches[index] += gramCount * otherGramCount;
|
||||||
|
} else {
|
||||||
|
matches[index] = gramCount * otherGramCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isEmptyObject ( obj ) {
|
||||||
|
for ( const prop in obj ) {
|
||||||
|
if ( obj.hasOwnProperty( prop ) )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isEmptyObject(matches)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const vectorNormal = Math.sqrt(sumOfSquareGramCounts);
|
||||||
|
let results = [];
|
||||||
|
let matchScore;
|
||||||
|
|
||||||
|
// build a results list of [score, str]
|
||||||
|
for (const matchIndex in matches) {
|
||||||
|
matchScore = matches[matchIndex];
|
||||||
|
results.push([matchScore / (vectorNormal * items[matchIndex][0]), items[matchIndex][1]]);
|
||||||
|
}
|
||||||
|
function sortDescending (a, b) {
|
||||||
|
if (a[0] < b[0]) {
|
||||||
|
return 1;
|
||||||
|
} else if (a[0] > b[0]) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
results.sort(sortDescending);
|
||||||
|
if (this.useLevenshtein) {
|
||||||
|
const newResults = [];
|
||||||
|
const endIndex = Math.min(50, results.length);
|
||||||
|
// truncate somewhat arbitrarily to 50
|
||||||
|
for (let i = 0; i < endIndex; ++i) {
|
||||||
|
newResults.push([_distance(results[i][1], normalizedValue), results[i][1]]);
|
||||||
|
}
|
||||||
|
results = newResults;
|
||||||
|
results.sort(sortDescending);
|
||||||
|
}
|
||||||
|
const newResults = [];
|
||||||
|
for (let i = 0; i < results.length; ++i) {
|
||||||
|
if (results[i][0] == results[0][0]) {
|
||||||
|
newResults.push([results[i][0], this.exactSet[results[i][1]]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newResults;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.add = function (value) {
|
||||||
|
const normalizedValue = this._normalizeStr(value);
|
||||||
|
if (normalizedValue in this.exactSet) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let i = this.gramSizeLower;
|
||||||
|
for (i; i < this.gramSizeUpper + 1; ++i) {
|
||||||
|
this._add(value, i);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this._add = function (value, gramSize) {
|
||||||
|
const normalizedValue = this._normalizeStr(value);
|
||||||
|
const items = this.items[gramSize] || [];
|
||||||
|
const index = items.length;
|
||||||
|
|
||||||
|
items.push(0);
|
||||||
|
const gramCounts = _gramCounter(normalizedValue, gramSize);
|
||||||
|
let sumOfSquareGramCounts = 0;
|
||||||
|
let gram;
|
||||||
|
let gramCount;
|
||||||
|
|
||||||
|
for (gram in gramCounts) {
|
||||||
|
gramCount = gramCounts[gram];
|
||||||
|
sumOfSquareGramCounts += Math.pow(gramCount, 2);
|
||||||
|
if (gram in this.matchDict) {
|
||||||
|
this.matchDict[gram].push([index, gramCount]);
|
||||||
|
} else {
|
||||||
|
this.matchDict[gram] = [[index, gramCount]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const vectorNormal = Math.sqrt(sumOfSquareGramCounts);
|
||||||
|
items[index] = [vectorNormal, normalizedValue];
|
||||||
|
this.items[gramSize] = items;
|
||||||
|
this.exactSet[normalizedValue] = value;
|
||||||
|
};
|
||||||
|
|
||||||
|
this._normalizeStr = function (str) {
|
||||||
|
if (Object.prototype.toString.call(str) !== '[object String]') throw 'Must use a string as argument to FuzzySet functions';
|
||||||
|
return str.toLowerCase();
|
||||||
|
};
|
||||||
|
|
||||||
|
// return length of items in set
|
||||||
|
this.length = function () {
|
||||||
|
let count = 0;
|
||||||
|
let prop;
|
||||||
|
|
||||||
|
for (prop in this.exactSet) {
|
||||||
|
if (this.exactSet.hasOwnProperty(prop)) {
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
};
|
||||||
|
|
||||||
|
// return is set is empty
|
||||||
|
this.isEmpty = function () {
|
||||||
|
for (const prop in this.exactSet) {
|
||||||
|
if (this.exactSet.hasOwnProperty(prop)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// return list of values loaded into set
|
||||||
|
this.values = function () {
|
||||||
|
const values = [];
|
||||||
|
|
||||||
|
for (const prop in this.exactSet) {
|
||||||
|
if (this.exactSet.hasOwnProperty(prop)) {
|
||||||
|
values.push(this.exactSet[prop]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// initialization
|
||||||
|
let i = this.gramSizeLower;
|
||||||
|
for (i; i < this.gramSizeUpper + 1; ++i) {
|
||||||
|
this.items[i] = [];
|
||||||
|
}
|
||||||
|
// add all the items to the set
|
||||||
|
for (i = 0; i < arr.length; ++i) {
|
||||||
|
this.add(arr[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
export default function checkForComputedKeys ( validator, properties ) {
|
||||||
|
properties.forEach( prop => {
|
||||||
|
if ( prop.key.computed ) {
|
||||||
|
validator.error( `Cannot use computed keys`, prop.start );
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
export default function checkForDupes ( validator, properties ) {
|
||||||
|
const seen = Object.create( null );
|
||||||
|
|
||||||
|
properties.forEach( prop => {
|
||||||
|
if ( seen[ prop.key.name ] ) {
|
||||||
|
validator.error( `Duplicate property '${prop.key.name}'`, prop.start );
|
||||||
|
}
|
||||||
|
|
||||||
|
seen[ prop.key.name ] = true;
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
[{
|
||||||
|
"message": "A component can only have a default export",
|
||||||
|
"pos": 10,
|
||||||
|
"loc": {
|
||||||
|
"line": 2,
|
||||||
|
"column": 1
|
||||||
|
}
|
||||||
|
}]
|
@ -0,0 +1,3 @@
|
|||||||
|
<script>
|
||||||
|
export var foo = 42;
|
||||||
|
</script>
|
@ -0,0 +1,8 @@
|
|||||||
|
[{
|
||||||
|
"message": "The 'computed' property must be an object literal",
|
||||||
|
"loc": {
|
||||||
|
"line": 5,
|
||||||
|
"column": 2
|
||||||
|
},
|
||||||
|
"pos": 42
|
||||||
|
}]
|
@ -0,0 +1,7 @@
|
|||||||
|
<div></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
computed: notAnObject
|
||||||
|
};
|
||||||
|
</script>
|
@ -0,0 +1,8 @@
|
|||||||
|
[{
|
||||||
|
"message": "Computed properties can be function expressions or arrow function expressions",
|
||||||
|
"loc": {
|
||||||
|
"line": 6,
|
||||||
|
"column": 8
|
||||||
|
},
|
||||||
|
"pos": 62
|
||||||
|
}]
|
@ -0,0 +1,9 @@
|
|||||||
|
<div></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
foo: notAFunction
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
@ -0,0 +1,8 @@
|
|||||||
|
[{
|
||||||
|
"message": "Computed properties cannot use destructuring in function parameters",
|
||||||
|
"loc": {
|
||||||
|
"line": 6,
|
||||||
|
"column": 8
|
||||||
|
},
|
||||||
|
"pos": 62
|
||||||
|
}]
|
@ -0,0 +1,9 @@
|
|||||||
|
<div></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
foo ({ a, b }) {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
@ -0,0 +1,8 @@
|
|||||||
|
[{
|
||||||
|
"message": "Duplicate property 'methods'",
|
||||||
|
"loc": {
|
||||||
|
"line": 9,
|
||||||
|
"column": 2
|
||||||
|
},
|
||||||
|
"pos": 74
|
||||||
|
}]
|
@ -0,0 +1,13 @@
|
|||||||
|
<div></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
methods: {
|
||||||
|
foo () {}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
bar () {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
@ -0,0 +1,8 @@
|
|||||||
|
[{
|
||||||
|
"message": "Unexpected property 'doSomething' (did you mean to include it in 'methods'?)",
|
||||||
|
"loc": {
|
||||||
|
"line": 5,
|
||||||
|
"column": 2
|
||||||
|
},
|
||||||
|
"pos": 42
|
||||||
|
}]
|
@ -0,0 +1,9 @@
|
|||||||
|
<div></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
doSomething () {
|
||||||
|
alert( 'boo' );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
@ -0,0 +1,8 @@
|
|||||||
|
[{
|
||||||
|
"message": "Unexpected property 'dada' (did you mean 'data'?)",
|
||||||
|
"loc": {
|
||||||
|
"line": 5,
|
||||||
|
"column": 2
|
||||||
|
},
|
||||||
|
"pos": 42
|
||||||
|
}]
|
@ -0,0 +1,11 @@
|
|||||||
|
<div></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
dada () {
|
||||||
|
return {
|
||||||
|
foo: 42
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
Loading…
Reference in new issue