Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/types/TypeComparator.java')
-rw-r--r--jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/types/TypeComparator.java56
1 files changed, 53 insertions, 3 deletions
diff --git a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/types/TypeComparator.java b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/types/TypeComparator.java
index acd108532..efe7dc341 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/types/TypeComparator.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.core/src/org/eclipse/jst/jsf/core/internal/types/TypeComparator.java
@@ -59,7 +59,9 @@ public final class TypeComparator
// simplest success is an exact match
if (curSatisfyType.equals(testType))
{
- result = Diagnostic.OK_INSTANCE;
+ // check assignability mask
+ // returns Diagnostic.OK if okay
+ result = checkAssignability(firstType, secondType);
break MAIN_LOOP;
}
@@ -89,9 +91,9 @@ public final class TypeComparator
}
// or, can we coerce testType to curSatisfyType
- if (canCoerce(testType, curSatisfyType))
+ if (canCoerce(testType, curSatisfyType, firstType.isLHS()))
{
- result = Diagnostic.OK_INSTANCE;
+ result = checkAssignability(firstType, secondType);
break MAIN_LOOP;
}
}
@@ -100,11 +102,29 @@ public final class TypeComparator
return result;
}
+ private static boolean canCoerce(String testType, String checkType,
+ boolean checkTypeIsWritable)
+ {
+ boolean canCoerce = canCoerce(testType, checkType);
+
+ // if the check type is writable, we need to be sure that the
+ // coercion can work in both directions
+ if (canCoerce && checkTypeIsWritable)
+ {
+ // reverse roles: can checkType assign back to test type?
+ canCoerce &= canCoerce(checkType, testType);
+ }
+
+ return canCoerce;
+ }
+
private static boolean canCoerce(String testType, String checkType)
{
// can always to coerce to string
if (TypeCoercer.typeIsString(checkType))
{
+ // if check type expects writability, need to ensure that
+ // coercability is reversible
return true;
}
else if (TypeCoercer.typeIsNumeric(checkType))
@@ -183,4 +203,34 @@ public final class TypeComparator
// if we get to here, then everything checks out
return Diagnostic.OK_INSTANCE;
}
+
+ /**
+ * Precond: both firstType and secondType must represent value bindings.
+ *
+ * @param firstType
+ * @param secondType
+ * @return a diagnostic validating that the two composite have compatible
+ * assignability
+ */
+ private static Diagnostic checkAssignability(CompositeType firstType, CompositeType secondType)
+ {
+ if (firstType.isRHS() && !secondType.isRHS())
+ {
+ return new BasicDiagnostic(Diagnostic.ERROR, "", 0,
+ "Expression is not gettable", null);
+ }
+
+ if (firstType.isLHS() && !secondType.isLHS())
+ {
+ return new BasicDiagnostic(Diagnostic.WARNING, "", 0,
+ "Attribute expects settable value, but expression is not settable", null);
+ }
+
+ return Diagnostic.OK_INSTANCE;
+ }
+
+ private TypeComparator()
+ {
+ // static utility class; not instantiable
+ }
}

Back to the top