/******************************************************************************* * Copyright (c) 2000, 2011 IBM Corporation and others. * 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: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.che.ide.ext.java.jdt.internal.corext.refactoring.types; import org.eclipse.che.ide.ext.java.jdt.core.dom.ITypeBinding; import org.eclipse.che.ide.runtime.Assert; public final class ParameterizedType extends HierarchyType { private GenericType fTypeDeclaration; private TType[] fTypeArguments; protected ParameterizedType(TypeEnvironment environment) { super(environment); } @Override protected void initialize(ITypeBinding binding) { Assert.isTrue(binding.isParameterizedType()); super.initialize(binding); TypeEnvironment environment = getEnvironment(); fTypeDeclaration = (GenericType)environment.create(binding.getTypeDeclaration()); ITypeBinding[] typeArguments = binding.getTypeArguments(); fTypeArguments = new TType[typeArguments.length]; for (int i = 0; i < typeArguments.length; i++) { fTypeArguments[i] = environment.create(typeArguments[i]); } } @Override public int getKind() { return PARAMETERIZED_TYPE; } @Override public TType getTypeDeclaration() { return fTypeDeclaration; } @Override public TType getErasure() { return fTypeDeclaration; } public TType[] getTypeArguments() { return fTypeArguments; } @Override public boolean doEquals(TType type) { ParameterizedType other = (ParameterizedType)type; if (!getBindingKey().equals(other.getBindingKey())) return false; if (!getJavaTypeBinding().isEqualTo(other.getJavaTypeBinding())) return false; return true; } @Override public int hashCode() { return getBindingKey().hashCode(); } @Override protected boolean doCanAssignTo(TType lhs) { int targetType = lhs.getKind(); switch (targetType) { case NULL_TYPE: return false; case VOID_TYPE: return false; case PRIMITIVE_TYPE: return false; case ARRAY_TYPE: return false; case STANDARD_TYPE: return canAssignToStandardType((StandardType)lhs); case GENERIC_TYPE: return false; case PARAMETERIZED_TYPE: return canAssignToParameterizedType((ParameterizedType)lhs); case RAW_TYPE: return canAssignToRawType((RawType)lhs); case UNBOUND_WILDCARD_TYPE: case SUPER_WILDCARD_TYPE: case EXTENDS_WILDCARD_TYPE: return ((WildcardType)lhs).checkAssignmentBound(this); case TYPE_VARIABLE: return false; case CAPTURE_TYPE: return ((CaptureType)lhs).checkLowerBound(this); } return false; } @Override protected boolean isTypeEquivalentTo(TType other) { int otherElementType = other.getKind(); if (otherElementType == RAW_TYPE || otherElementType == GENERIC_TYPE) return getErasure().isTypeEquivalentTo(other.getErasure()); return super.isTypeEquivalentTo(other); } private boolean canAssignToRawType(RawType target) { return fTypeDeclaration.isSubType(target.getHierarchyType()); } private boolean canAssignToParameterizedType(ParameterizedType target) { GenericType targetDeclaration = target.fTypeDeclaration; ParameterizedType sameSourceType = findSameDeclaration(targetDeclaration); if (sameSourceType == null) return false; TType[] targetArguments = target.fTypeArguments; TType[] sourceArguments = sameSourceType.fTypeArguments; if (targetArguments.length != sourceArguments.length) return false; for (int i = 0; i < sourceArguments.length; i++) { if (!targetArguments[i].checkTypeArgument(sourceArguments[i])) return false; } return true; } private ParameterizedType findSameDeclaration(GenericType targetDeclaration) { if (fTypeDeclaration.equals(targetDeclaration)) return this; ParameterizedType result = null; TType type = getSuperclass(); if (type != null && type.getKind() == PARAMETERIZED_TYPE) { result = ((ParameterizedType)type).findSameDeclaration(targetDeclaration); if (result != null) return result; } TType[] interfaces = getInterfaces(); for (int i = 0; i < interfaces.length; i++) { type = interfaces[i]; if (type != null && type.getKind() == PARAMETERIZED_TYPE) { result = ((ParameterizedType)type).findSameDeclaration(targetDeclaration); if (result != null) return result; } } return null; } @Override public String getName() { StringBuffer result = new StringBuffer(getJavaTypeBinding().getName()); result.append("<"); //$NON-NLS-1$ result.append(fTypeArguments[0].getName()); for (int i = 1; i < fTypeArguments.length; i++) { result.append(", "); //$NON-NLS-1$ result.append(fTypeArguments[i].getName()); } result.append(">"); //$NON-NLS-1$ return result.toString(); } @Override protected String getPlainPrettySignature() { StringBuffer result = new StringBuffer(getJavaTypeBinding().getQualifiedName()); result.append("<"); //$NON-NLS-1$ result.append(fTypeArguments[0].getPlainPrettySignature()); for (int i = 1; i < fTypeArguments.length; i++) { result.append(", "); //$NON-NLS-1$ result.append(fTypeArguments[i].getPlainPrettySignature()); } result.append(">"); //$NON-NLS-1$ return result.toString(); } }