Skip to content

Commit 76adbd7

Browse files
committed
Different fix for mozilla#48
1 parent 5259780 commit 76adbd7

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

src/org/mozilla/javascript/ScriptableObject.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,6 +1294,15 @@ static <T extends Scriptable> BaseFunction buildClassCtor(
12941294
Scriptable proto = (Scriptable) protoCtor.newInstance(ScriptRuntime.emptyArgs);
12951295
String className = proto.getClassName();
12961296

1297+
// check for possible redefinition
1298+
Object existing = getProperty(getTopLevelScope(scope), className);
1299+
if (existing instanceof BaseFunction) {
1300+
Object existingProto = ((BaseFunction)existing).getPrototypeProperty();
1301+
if (clazz.isInstance(existingProto)) {
1302+
return (BaseFunction)existing;
1303+
}
1304+
}
1305+
12971306
// Set the prototype's prototype, trying to map Java inheritance to JS
12981307
// prototype-based inheritance if requested to do so.
12991308
Scriptable superProto = null;
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package org.mozilla.javascript.tests;
2+
3+
import static org.junit.Assert.*;
4+
5+
import java.lang.reflect.InvocationTargetException;
6+
7+
import org.junit.Test;
8+
import org.mozilla.javascript.Context;
9+
import org.mozilla.javascript.ScriptableObject;
10+
11+
@SuppressWarnings("serial")
12+
public class DefineClassMapInheritance {
13+
14+
public static class Food extends ScriptableObject {
15+
@Override
16+
public String getClassName() {
17+
return getClass().getSimpleName();
18+
}
19+
}
20+
21+
public static class Fruit extends Food {
22+
}
23+
24+
public static class Vegetable extends Food {
25+
}
26+
27+
@Test
28+
public void test() throws IllegalAccessException, InstantiationException,
29+
InvocationTargetException {
30+
Context cx = Context.enter();
31+
try {
32+
ScriptableObject scope = cx.initStandardObjects();
33+
34+
// define two classes that share a parent prototype
35+
ScriptableObject.defineClass(scope, Fruit.class, false, true);
36+
ScriptableObject.defineClass(scope, Vegetable.class, false, true);
37+
38+
assertEquals(Boolean.TRUE,
39+
evaluate(cx, scope, "(new Fruit instanceof Food)"));
40+
assertEquals(Boolean.TRUE,
41+
evaluate(cx, scope, "(new Vegetable instanceof Food)"));
42+
} finally {
43+
Context.exit();
44+
}
45+
}
46+
47+
private static Object evaluate(Context cx, ScriptableObject scope,
48+
String source) {
49+
return cx.evaluateString(scope, source, "<eval>", 1, null);
50+
}
51+
}

0 commit comments

Comments
 (0)