Copyright (c) 2000, 2016 IBM Corporation and others. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/ SPDX-License-Identifier: EPL-2.0 Contributors: IBM Corporation - initial API and implementation
/******************************************************************************* * Copyright (c) 2000, 2016 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/
package org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types; import org.eclipse.core.runtime.Assert; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.dom.ITypeBinding; public final class ParameterizedType extends HierarchyType { private GenericType fTypeDeclaration; private TType[] fTypeArguments; protected ParameterizedType(TypeEnvironment environment) { super(environment); } @Override protected void initialize(ITypeBinding binding, IType javaElementType) { Assert.isTrue(binding.isParameterizedType()); super.initialize(binding, javaElementType); 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.clone(); } @Override public boolean doEquals(TType type) { ParameterizedType other= (ParameterizedType)type; if (! getBindingKey().equals(other.getBindingKey())) return false; if (! getJavaElementType().equals(other.getJavaElementType())) 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() { StringBuilder result= new StringBuilder(getJavaElementType().getElementName()); 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() { StringBuilder result= new StringBuilder(getJavaElementType().getFullyQualifiedName('.')); 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(); } }