Local Type Sub class instance as an argument that is defined as a Base
local type
diff --git a/plugins/org.eclipse.dltk.javascript.core/src/org/eclipse/dltk/javascript/typeinfo/RLocalType.java b/plugins/org.eclipse.dltk.javascript.core/src/org/eclipse/dltk/javascript/typeinfo/RLocalType.java
index 785a72d..440c50c 100644
--- a/plugins/org.eclipse.dltk.javascript.core/src/org/eclipse/dltk/javascript/typeinfo/RLocalType.java
+++ b/plugins/org.eclipse.dltk.javascript.core/src/org/eclipse/dltk/javascript/typeinfo/RLocalType.java
@@ -128,12 +128,25 @@
if (argument == null)
return TypeCompatibility.TRUE;
Set<IRType> types = JavaScriptValidations.getTypes(argument);
+ return testLocation(types, new HashSet<IRType>());
+ }
+
+ /**
+ * @param types
+ */
+ private IValidationStatus testLocation(Iterable<IRType> types,
+ HashSet<IRType> set) {
for (IRType irType : types) {
- if (irType instanceof IRLocalType) {
+ if (irType instanceof IRLocalType && set.add(irType)) {
if (getReferenceLocation().equals(
((IRLocalType) irType).getReferenceLocation())) {
return TypeCompatibility.TRUE;
}
+
+ IValidationStatus status = testLocation(((IRLocalType) irType)
+ .getValue().getDeclaredTypes(), set);
+ if (status == TypeCompatibility.TRUE)
+ return status;
}
}
return TypeCompatibility.FALSE;
diff --git a/tests/org.eclipse.dltk.javascript.core.tests/src/org/eclipse/dltk/javascript/core/tests/validation/TypeInfoValidationTests.java b/tests/org.eclipse.dltk.javascript.core.tests/src/org/eclipse/dltk/javascript/core/tests/validation/TypeInfoValidationTests.java
index d7919f2..8424d27 100644
--- a/tests/org.eclipse.dltk.javascript.core.tests/src/org/eclipse/dltk/javascript/core/tests/validation/TypeInfoValidationTests.java
+++ b/tests/org.eclipse.dltk.javascript.core.tests/src/org/eclipse/dltk/javascript/core/tests/validation/TypeInfoValidationTests.java
@@ -3176,4 +3176,61 @@
assertEquals(problems.toString(), 0, problems.size());
}
+
+ public void testExtendsSubAsArgumentForBaseParam() {
+ final StringList code = new StringList();
+
+ code.add("/**");
+ code.add(" * @constructor");
+ code.add(" */");
+ code.add("function BaseBase() {}");
+ code.add("/**");
+ code.add(" * @constructor");
+ code.add(" * @extends {BaseBase}");
+ code.add(" */");
+ code.add("function Base(){}");
+ code.add("/**");
+ code.add(" * @constructor");
+ code.add(" * @extends {Base}");
+ code.add(" */");
+ code.add("function Sub() {}");
+ code.add("function test() {");
+ code.add(" amethod(new Sub());");
+ code.add(" amethod(new Base());");
+ code.add("}");
+ code.add("/**");
+ code.add(" * @param {BaseBase} a");
+ code.add(" */");
+ code.add("function amethod(a) {}");
+
+ final List<IProblem> problems = validate(code.toString());
+ assertEquals(problems.toString(), 0, problems.size());
+
+ }
+
+ public void testExtendsBaseAsArgumentForSubParam() {
+ final StringList code = new StringList();
+
+ code.add("/**");
+ code.add(" * @constructor");
+ code.add(" */");
+ code.add("function Base(){}");
+ code.add("/**");
+ code.add(" * @constructor");
+ code.add(" * @extends {Base}");
+ code.add(" */");
+ code.add("function Sub() {}");
+ code.add("function test() {");
+ code.add(" amethod(new Base());");
+ code.add("}");
+ code.add("/**");
+ code.add(" * @param {Sub} a");
+ code.add(" */");
+ code.add("function amethod(a) {}");
+
+ final List<IProblem> problems = validate(code.toString());
+ assertEquals(problems.toString(), 1, problems.size());
+ assertEquals(JavaScriptProblems.WRONG_PARAMETERS, problems.get(0)
+ .getID());
+ }
}