/******************************************************************************* * Copyright (c) 2010 Martin Schnabel <mb0@mb0.org>. * 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 ******************************************************************************/ package org.axdt.avm.util; import java.util.List; import org.axdt.avm.model.AvmDeclaredType; import org.axdt.avm.model.AvmType; import org.axdt.avm.model.AvmTypeReference; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.InternalEObject; public class AssignabilityComputer implements IAssignabilityComputer{ private SuperTypeCollector superTypeCollector; public AssignabilityComputer(SuperTypeCollector superTypeCollector) { super(); this.superTypeCollector = superTypeCollector; } public boolean isAssignableFrom(AvmTypeReference left, AvmTypeReference right) { AvmType typeA = left.getType(); AvmType typeB = right.getType(); if (typeA == typeB) { return true; } if (typeA instanceof AvmDeclaredType) { if (superTypeCollector.collectSuperTypes(typeB).contains(typeA)) { return true; } } return false; } protected String getCanonicalName(AvmDeclaredType type) { if (type == null) return null; if (type.eIsProxy()) { // compare type if proxy URI uri = ((InternalEObject) type).eProxyURI(); return uri.toString().substring(11); } return type.getCanonicalName(); } public AvmType commonSuperType(AvmDeclaredType left, AvmDeclaredType right) { if (left.equals(right)) return left; String leftName = getCanonicalName(left); String rightName = getCanonicalName(right); if (leftName == null || rightName == null) return null; // case 0 same type // special case object if (leftName.equals(rightName) || "Object".equals(leftName)) return left; if ("Object".equals(rightName)) return right; // try to collect super types List<AvmType> rtypes = superTypeCollector.collectSuperTypes(right); // case 1 left is super type of right if (rtypes.contains(left)) return left; List<AvmType> ltypes = superTypeCollector.collectSuperTypes(left); // case 2 right is super type of left - checked in first iteration in case 3 // if (ltypes.contains(right)) return right; // case 3 first intersections in the type hierarchy for (AvmType rtype:rtypes) if (ltypes.contains(rtype)) return rtype; // is probably Object but we have not checked proxy hierarchy return null; } }