typeOf should always just return a union type if there are more types.
(just like getDeclaredTypes() call just above will do)
if 2 methods are found then try to map on the best one and return that
value (so that no union type is created for that if we know which method
wil be called)
diff --git a/plugins/org.eclipse.dltk.javascript.core/src/org/eclipse/dltk/internal/javascript/validation/JavaScriptValidations.java b/plugins/org.eclipse.dltk.javascript.core/src/org/eclipse/dltk/internal/javascript/validation/JavaScriptValidations.java
index dd977fe..8a4321b 100644
--- a/plugins/org.eclipse.dltk.javascript.core/src/org/eclipse/dltk/internal/javascript/validation/JavaScriptValidations.java
+++ b/plugins/org.eclipse.dltk.javascript.core/src/org/eclipse/dltk/internal/javascript/validation/JavaScriptValidations.java
@@ -76,10 +76,7 @@
if (declaredTypes.size() == 1) {
return declaredTypes.toRType();
}
- final JSTypeSet types = reference.getTypes();
- if (types.size() == 1) {
- return types.toRType();
- }
+ return reference.getTypes().toRType();
}
return null;
}
diff --git a/plugins/org.eclipse.dltk.javascript.core/src/org/eclipse/dltk/internal/javascript/validation/TypeInfoValidator.java b/plugins/org.eclipse.dltk.javascript.core/src/org/eclipse/dltk/internal/javascript/validation/TypeInfoValidator.java
index 9f78674..04d7dbc 100644
--- a/plugins/org.eclipse.dltk.javascript.core/src/org/eclipse/dltk/internal/javascript/validation/TypeInfoValidator.java
+++ b/plugins/org.eclipse.dltk.javascript.core/src/org/eclipse/dltk/internal/javascript/validation/TypeInfoValidator.java
@@ -985,6 +985,45 @@
pushExpressionValidator(new CallExpressionValidator(
peekFunctionScope(), node, reference, arguments,
methods));
+ if (methods != null && methods.size() > 1) {
+ // try to found the best match
+ IRMethod bestMatch = null;
+ outer: for (IRMethod method : methods) {
+ if (method.getParameterCount() == arguments.length) {
+ for (int i = 0; i < arguments.length; i++) {
+ TypeCompatibility tc = testArgumentType(method
+ .getParameters().get(i).getType(),
+ arguments[i]);
+ if (tc != TypeCompatibility.TRUE) {
+ continue outer;
+ }
+ }
+ // both match, which one is the more specific one
+ if (bestMatch != null) {
+ List<IRParameter> parameters = method
+ .getParameters();
+ for (int i = 0; i < parameters.size(); i++) {
+ IRType type = parameters.get(i).getType();
+ if (type != null) {
+ IRType bestMatchType = bestMatch
+ .getParameters().get(i)
+ .getType();
+ if (bestMatchType == null) {
+ break;
+ }
+ if (type.isAssignableFrom(bestMatchType) == TypeCompatibility.TRUE) {
+ continue outer;
+ }
+ }
+ }
+
+ }
+ bestMatch = method;
+ }
+ }
+ if (bestMatch != null)
+ return ConstantValue.of(bestMatch.getType());
+ }
final IRType expressionType = JavaScriptValidations
.typeOf(reference);
if (expressionType != null) {
@@ -1574,7 +1613,7 @@
sb.append(argument.getDeclaredType().getName());
} else {
final JSTypeSet types = argument.getTypes();
- if (types.size() == 1) {
+ if (types.size() > 0) {
sb.append(types.toRType().getName());
} else {
sb.append('?');
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 cbac402..8b93b8a 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
@@ -3915,4 +3915,15 @@
final List<IProblem> problems = validate(code.toString());
assertEquals(problems.toString(), 0, problems.size());
}
+
+ public void testUnionTypeAsArgument() {
+ final StringList code = new StringList();
+ code.add("var s = '== {{DATE}} ==';");
+ code.add("var x = 10;");
+ code.add("if (s)");
+ code.add(" x = ''");
+ code.add("s = s.replace('',x);");
+ final List<IProblem> problems = validate(code.toString());
+ assertEquals(problems.toString(), 1, problems.size());
+ }
}