diff options
Diffstat (limited to 'jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/internal/types/TypeComparator.java')
-rw-r--r-- | jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/internal/types/TypeComparator.java | 292 |
1 files changed, 0 insertions, 292 deletions
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/internal/types/TypeComparator.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/internal/types/TypeComparator.java deleted file mode 100644 index a57a94bed..000000000 --- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/internal/types/TypeComparator.java +++ /dev/null @@ -1,292 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006 Oracle Corporation. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Cameron Bateman/Oracle - initial API and implementation - * - ********************************************************************************/ - -package org.eclipse.jst.jsf.common.internal.types; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.eclipse.emf.common.util.Diagnostic; -import org.eclipse.jdt.core.Signature; - -/** - * Static utility class used to compare two CompositeTypes for compatability - * - * @author cbateman - * - */ -public final class TypeComparator { - private static class SignatureTestResult { - /** - * the diagnostic - */ - private final Diagnostic diagnostic; - /** - * Measure of the probability that the tested signatures were meant to - * match. Larger value means higher probability. - */ - private final int matchQuality; - - /** - * @param diagnostic - * @param matchQuality - - * Measure of the probability that the tested signatures were - * meant to match. Larger value means higher probability. - */ - public SignatureTestResult(final Diagnostic diagnostic, - final int matchQuality) { - super(); - this.diagnostic = diagnostic; - this.matchQuality = matchQuality; - } - } - - private final TypeComparatorDiagnosticFactory _factory; - - /** - * Default Constructor - * @param factory - */ - public TypeComparator(final TypeComparatorDiagnosticFactory factory) - { - _factory = factory; - } - - /** - * @param firstType - * @param secondType - * @return true if firstType is assignable to secondType or vice-versa, - * depending on their assignment and runtime types - */ - public Diagnostic calculateTypeCompatibility( - final CompositeType firstType, final CompositeType secondType) { - // first, box all primitives - final CompositeType boxedFirstType = TypeTransformer - .transformBoxPrimitives(firstType); - final CompositeType boxedSecondType = TypeTransformer - .transformBoxPrimitives(secondType); - - final String[] mustBeSatisfied = boxedFirstType.getSignatures(); - final String[] testSignatures = boxedSecondType.getSignatures(); - List<String> mustbeMethods = Collections.emptyList(); - List<String> mustbeTypes = Collections.emptyList(); - for (final String mustbeSignature : mustBeSatisfied) { - if (TypeUtil.isMethodSignature(mustbeSignature)) { - if (mustbeMethods.isEmpty()) { - mustbeMethods = new ArrayList<String>(mustbeSignature - .length()); - } - mustbeMethods.add(mustbeSignature); - } else { - if (mustbeTypes.isEmpty()) { - mustbeTypes = new ArrayList<String>(mustbeSignature - .length()); - } - mustbeTypes.add(mustbeSignature); - } - } - final boolean mustbeWriteable = firstType.isLHS(); - SignatureTestResult bestResult = null; - for (final String isSignature : testSignatures) { - SignatureTestResult testResult; - if (TypeUtil.isMethodSignature(isSignature)) { - testResult = checkMethodSignature(isSignature, mustbeTypes, - mustbeMethods); - if (testResult.diagnostic.getSeverity() == Diagnostic.OK) { - return testResult.diagnostic; - } - } else { - testResult = checkTypeSignature(isSignature, mustbeTypes, - mustbeMethods, mustbeWriteable); - if (testResult.diagnostic.getSeverity() == Diagnostic.OK) { - return checkAssignability(firstType, secondType); - } - } - if (bestResult == null - || bestResult.matchQuality < testResult.matchQuality) { - bestResult = testResult; - } - } - // TODO: bestResult empty? (should not happen, but who knows... - return bestResult.diagnostic; - } - - private SignatureTestResult checkTypeSignature( - final String isSignature, final List<String> mustbeTypes, - final List<String> mustbeMethods, final boolean mustbeWriteable) { - if (mustbeTypes.isEmpty()) { - final Diagnostic diag = _factory.create_METHOD_EXPRESSION_EXPECTED(); - return new SignatureTestResult(diag, 0); - } - for (final String mustbeSignature : mustbeTypes) { - if (mustbeSignature.equals(isSignature) - || canCoerce(isSignature, mustbeSignature, mustbeWriteable)) { - final Diagnostic diag = Diagnostic.OK_INSTANCE; - return new SignatureTestResult(diag, 5); - } - } - final String[] params = new String[2]; - params[0] = readableSignatures(mustbeTypes); - params[1] = Signature.toString(isSignature); - final Diagnostic diag = _factory.create_INCOMPATIBLE_TYPES(params); - return new SignatureTestResult(diag, 1); - } - - private SignatureTestResult checkMethodSignature( - final String isSignature, final List<String> mustbeTypes, - final List<String> mustbeMethods) { - if (mustbeMethods.isEmpty()) { - final Diagnostic diag = _factory.create_VALUE_EXPRESSION_EXPECTED(); - return new SignatureTestResult(diag, 0); - } - for (final String mustbeSignature : mustbeMethods) { - if (methodSignaturesMatch(mustbeSignature, isSignature)) { - final Diagnostic diag = Diagnostic.OK_INSTANCE; - return new SignatureTestResult(diag, 5); - } - } - final String[] params = new String[2]; - params[0] = readableSignatures(mustbeMethods); - params[1] = Signature - .toString(isSignature, "method", null, false, true); //$NON-NLS-1$ - final Diagnostic diag = _factory.create_INCOMPATIBLE_METHOD_TYPES(params); - return new SignatureTestResult(diag, 1); - } - - private static String readableSignatures(final List<String> signatures) { - StringBuilder res = null; - for (final String sig : signatures) { - String sigText; - if (TypeUtil.isMethodSignature(sig)) { - sigText = Signature.toString(sig, "method", null, false, true); //$NON-NLS-1$ - } else { - sigText = Signature.toString(sig); - } - if (res == null) { - res = new StringBuilder(sigText); - } else { - res.append(", ").append(sigText); //$NON-NLS-1$ - } - } - return res != null ? res.toString() : "[no signature]"; //$NON-NLS-1$ - } - - private static boolean canCoerce(final String testType, - final String checkType, final 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(final String testType, - final String checkType) { - // can always to coerce to string or object - if (TypeCoercer.typeIsString(checkType)/* - || TypeConstants.TYPE_JAVAOBJECT.equals(checkType)*/) - { - return true; - } else if (TypeCoercer.typeIsNumeric(checkType)) { - return canCoerceNumeric(testType); - } else if (TypeCoercer.typeIsBoolean(checkType)) { - return TypeCoercer.canCoerceToBoolean(testType); - } - - // otherwise, no type coercion available - return false; - } - - private static boolean canCoerceNumeric(final String testType) { - try { - TypeCoercer.coerceToNumber(testType); - // TODO: there is a case when coerceToNumber returns - // null meaning "not sure", that we may want to handle - // differently, with a warning - return true; - } catch (final TypeCoercionException tce) { - // outright failure -- can't coerce - return false; - } - } - - private static boolean methodSignaturesMatch(final String firstMethodSig, - final String secondMethodSig) { - // TODO: need to account for primitive type coercions - if (firstMethodSig.equals(secondMethodSig)) { - return true; - } - final String[] firstMethodParams = Signature - .getParameterTypes(firstMethodSig); - final String[] secondMethodParams = Signature - .getParameterTypes(secondMethodSig); - - // fail fast if param count doesn't match - if (firstMethodParams.length != secondMethodParams.length) { - return false; - } - - // now check each parameter - for (int i = 0; i < firstMethodParams.length; i++) { - // need to box primitives before comparing - final String firstMethodParam = TypeTransformer - .transformBoxPrimitives(firstMethodParams[i]); - final String secondMethodParam = TypeTransformer - .transformBoxPrimitives(secondMethodParams[i]); - - if (!firstMethodParam.equals(secondMethodParam)) { - return false; - } - } - - // if we get to here then we need only check the return type - final String firstReturn = TypeTransformer - .transformBoxPrimitives(Signature.getReturnType(firstMethodSig)); - final String secondReturn = TypeTransformer - .transformBoxPrimitives(Signature - .getReturnType(secondMethodSig)); - - if (!firstReturn.equals(secondReturn)) { - return false; - } - - // if we get to here, then everything checks out - return true; - } - - /** - * 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 Diagnostic checkAssignability(final CompositeType firstType, - final CompositeType secondType) { - if (firstType.isRHS() && !secondType.isRHS()) { - return _factory.create_PROPERTY_NOT_READABLE(); - } - - if (firstType.isLHS() && !secondType.isLHS()) { - return _factory.create_PROPERTY_NOT_WRITABLE(); - } - - return Diagnostic.OK_INSTANCE; - } -} |