diff --git a/lib/ast-converter.js b/lib/ast-converter.js index d99e09b..779c154 100644 --- a/lib/ast-converter.js +++ b/lib/ast-converter.js @@ -26,13 +26,7 @@ const convert = require("./convert"), * @returns {Object} converted error object */ function convertError(error) { - const loc = error.file.getLineAndCharacterOfPosition(error.start); - return { - index: error.start, - lineNumber: loc.line + 1, - column: loc.character, - message: error.message || error.messageText - }; + return nodeUtils.createError(error.file, error.start, error.message || error.messageText); } //------------------------------------------------------------------------------ diff --git a/lib/convert.js b/lib/convert.js index 5805707..2fa5d34 100644 --- a/lib/convert.js +++ b/lib/convert.js @@ -1397,8 +1397,14 @@ module.exports = function convert(config) { const openBrace = nodeUtils.findNextToken(lastClassToken, ast); const superClass = heritageClauses.find(clause => clause.token === SyntaxKind.ExtendsKeyword); - if (superClass && superClass.types[0] && superClass.types[0].typeArguments) { - result.superTypeParameters = convertTypeArgumentsToTypeParameters(superClass.types[0].typeArguments); + if (superClass) { + if (superClass.types.length > 1) { + throw nodeUtils.createError(ast, superClass.types[1].pos, "Classes can only extend a single class."); + } + + if (superClass.types[0] && superClass.types[0].typeArguments) { + result.superTypeParameters = convertTypeArgumentsToTypeParameters(superClass.types[0].typeArguments); + } } const implementsClause = heritageClauses.find(clause => clause.token === SyntaxKind.ImplementsKeyword); diff --git a/lib/node-utils.js b/lib/node-utils.js index ac22ce4..5c4ba9e 100644 --- a/lib/node-utils.js +++ b/lib/node-utils.js @@ -191,7 +191,8 @@ module.exports = { isWithinTypeAnnotation, isTypeKeyword, isComment, - isJSDocComment + isJSDocComment, + createError }; /* eslint-enable no-use-before-define */ @@ -767,3 +768,19 @@ function getNodeContainer(ast, start, end) { return container; } + +/** + * @param {Object} ast the AST object + * @param {int} start the index at which the error starts + * @param {string} message the error message + * @returns {Object} converted error object + */ +function createError(ast, start, message) { + const loc = ast.getLineAndCharacterOfPosition(start); + return { + index: start, + lineNumber: loc.line + 1, + column: loc.character, + message + }; +} diff --git a/tests/fixtures/ecma-features/classes/invalid-class-two-super-classes.src.js b/tests/fixtures/ecma-features/classes/invalid-class-two-super-classes.src.js new file mode 100644 index 0000000..dbac127 --- /dev/null +++ b/tests/fixtures/ecma-features/classes/invalid-class-two-super-classes.src.js @@ -0,0 +1 @@ +class A extends B, C {} \ No newline at end of file diff --git a/tests/lib/__snapshots__/ecma-features.js.snap b/tests/lib/__snapshots__/ecma-features.js.snap index 599c246..150dd17 100644 --- a/tests/lib/__snapshots__/ecma-features.js.snap +++ b/tests/lib/__snapshots__/ecma-features.js.snap @@ -22287,6 +22287,8 @@ Object { } `; +exports[`ecmaFeatures fixtures/classes/invalid-class-two-super-classes.src 1`] = `"Classes can only extend a single class."`; + exports[`ecmaFeatures fixtures/classes/named-class-expression.src 1`] = ` Object { "body": Array [