Skip to content

Commit

Permalink
Deal with static / non-static elements with same name
Browse files Browse the repository at this point in the history
Edge case of when a static method has the same name as a none-static method.
  • Loading branch information
aedart committed May 6, 2023
1 parent 65843e7 commit 31bec90
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 1 deletion.
12 changes: 11 additions & 1 deletion packages/support/src/reflections/reflect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,16 @@ export function reflect()
}

// Create a key for given target
const key: Key = [ META_REFLECTIONS, context.kind, context.name ?? 'undefined'];
const isStatic: string = (context.kind !== 'class' && context.static)
? 's' // static element
: 'n'; // non-static element

const key: Key = [
META_REFLECTIONS,
Encoder.encodeElementKind(context.kind).toString(),
isStatic, // Ensures that we do not overwrite static / none-static elements with same name!
context.name ?? 'undefined' // The "undefined" is for anonymous classes (they do not have a name)
];

// Encode parts of the given context...
const value:EncodedReflection = Encoder.encodeContext(context, owner);
Expand All @@ -42,6 +51,7 @@ export function reflect()
// In situations when a base class' method is reflected, but overwritten in a child
// class, we store another entry with the overwritten method as target in the internal
// registry. This allows to look up reflection for the overwritten method.
// NOTE: This will work for non-static methods only...
if (context.kind === 'method' && Reflect.has(owner, 'prototype')) {
// @ts-expect-error: TS2339 Owner has a prototype at this point...
const proto = owner.prototype;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,5 +366,84 @@ describe('@aedart/support/reflections', () => {
.withContext('Element owner incorrect')
.toEqual(C);
});

it('can reflect method and static method with same name', () => {

class A {

@reflect()
foo() {}

@reflect()
static foo() {}
}

const reflectionOfStatic = getReflection(A.foo);
const a = new A();
const reflection = getReflection(a.foo);


expect(reflectionOfStatic.static)
.withContext('(static foo) Element static declaration incorrect')
.toBeTrue();

expect(reflection.static)
.withContext('(foo) Element static declaration incorrect')
.toBeFalse();

expect(reflectionOfStatic.target)
.withContext('static Element target incorrect')
.toEqual(A.foo);

expect(reflection.target)
.withContext('Element target incorrect')
.toEqual(a.foo);

expect(reflectionOfStatic.owner)
.withContext('static Element owner incorrect')
.toEqual(A);
expect(reflection.owner)
.withContext('Element owner incorrect')
.toEqual(A);
});

// TODO: Not sure this can be resolved...
xit('inherits static method reflection even when overwritten', () => {

class A {

@reflect()
static foo() {}
}
class B extends A {

// Note: static method overwrite here...
static foo() {}
}
class C extends B {}

const reflection = getReflection(C.foo);

expect(reflection)
.withContext('No reflection found for target')
.not
.toBeUndefined();

expect(reflection.name)
.withContext('Element name incorrect')
.toEqual('foo');

expect(reflection.kind)
.withContext('Element kind incorrect')
.toEqual('method');

expect(reflection.target)
.withContext('Element target incorrect')
.toEqual(C.foo);

expect(reflection.owner)
.withContext('Element owner incorrect')
.toEqual(C);
});
});
});

0 comments on commit 31bec90

Please sign in to comment.