diff --git a/package.json b/package.json index 513e060..fded122 100644 --- a/package.json +++ b/package.json @@ -100,8 +100,7 @@ "@babel/preset-env", { "targets": { - "browsers": "last 2 versions", - "node": "8.0.0" + "node": "12.0.0" } } ] diff --git a/src/__tests__/inheritance.test.js b/src/__tests__/inheritance.test.js index 30bac0c..6fdc8e8 100644 --- a/src/__tests__/inheritance.test.js +++ b/src/__tests__/inheritance.test.js @@ -14,16 +14,10 @@ test('parses parent classes if there are no declared parameters', () => { } } - class Level2 extends Level1 { - constructor() { - super(...arguments) - } - } + class Level2 extends Level1 {} - class Level3 extends Level2 {} - - class Level4 extends Level2 { - constructor(level4Arg1) { + class Level3 extends Level2 { + constructor(level3Arg1) { super(...arguments) } } @@ -31,11 +25,10 @@ test('parses parent classes if there are no declared parameters', () => { container.register({ level1Arg1: asValue(1), level1Arg2: asValue(2), - level4Arg1: asValue(4), + level3Arg1: asValue(4), level1: asClass(Level1), level2: asClass(Level2), level3: asClass(Level3), - level4: asClass(Level4), }) expect(container.resolve('level1')).toEqual( @@ -53,13 +46,6 @@ test('parses parent classes if there are no declared parameters', () => { ) expect(container.resolve('level3')).toEqual( - expect.objectContaining({ - arg1: 1, - arg2: 2, - }) - ) - - expect(container.resolve('level4')).toEqual( expect.objectContaining({ arg1: 4, arg2: undefined, diff --git a/src/__tests__/param-parser.test.ts b/src/__tests__/param-parser.test.ts index 0f6bda8..0c6cb14 100644 --- a/src/__tests__/param-parser.test.ts +++ b/src/__tests__/param-parser.test.ts @@ -169,6 +169,20 @@ describe('parseParameterList', () => { ]) }) + it('returns null when no constructor is defined', () => { + class Test { + dep1: any + + method() { + /**/ + } + } + + expect(parseParameterList(Test.prototype.constructor.toString())).toBe(null) + + expect(parseParameterList('class Lol extends Wee {}')).toBe(null) + }) + it('supports carriage return in function signature', () => { expect(parseParameterList(`function (\r\ndep1,\r\ndep2\r\n) {}`)).toEqual([ { name: 'dep1', optional: false }, diff --git a/src/param-parser.ts b/src/param-parser.ts index 574b597..c16aae7 100644 --- a/src/param-parser.ts +++ b/src/param-parser.ts @@ -20,10 +20,11 @@ export interface Parameter { * @param {string} source * The source of a function to extract the parameter list from * - * @return {Array} - * Returns an array of parameters. + * @return {Array | null} + * Returns an array of parameters, or `null` if no + * constructor was found for a class. */ -export function parseParameterList(source: string): Array { +export function parseParameterList(source: string): Array | null { const { next: _next, done } = createTokenizer(source) const params: Array = [] @@ -33,6 +34,11 @@ export function parseParameterList(source: string): Array { switch (t.type) { case 'class': skipUntilConstructor() + // If we didn't find a constructor token, then we know that there + // are no dependencies in the defined class. + if (!isConstructorToken()) { + return null + } // Next token is the constructor identifier. nextToken() break diff --git a/src/resolvers.ts b/src/resolvers.ts index e40b02c..40f6009 100644 --- a/src/resolvers.ts +++ b/src/resolvers.ts @@ -488,18 +488,20 @@ function generateResolve(fn: Function, dependencyParseTarget?: Function) { /** * Parses the dependencies from the given function. - * If it's a class and has an extends clause, and no reported dependencies, attempt to parse it's super constructor. + * If it's a class that extends another class, and it does + * not have a defined constructor, attempt to parse it's super constructor. */ function parseDependencies(fn: Function): Array { const result = parseParameterList(fn.toString()) - if (result.length > 0) { - return result - } - - const parent = Object.getPrototypeOf(fn) - if (typeof parent === 'function' && parent !== Function.prototype) { - // Try to parse the parent - return parseDependencies(parent) + if (!result) { + // No defined constructor for a class, check if there is a parent + // we can parse. + const parent = Object.getPrototypeOf(fn) + if (typeof parent === 'function' && parent !== Function.prototype) { + // Try to parse the parent + return parseDependencies(parent) + } + return [] } return result