1 /*******************************************************************************
2  * Copyright (c) 2000, 2016 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.jdt.internal.corext.refactoring.typeconstraints.types;
15 
16 import java.util.Map;
17 
18 import org.eclipse.core.runtime.Assert;
19 
20 import org.eclipse.jdt.core.IType;
21 import org.eclipse.jdt.core.dom.ITypeBinding;
22 
23 
24 public abstract class HierarchyType extends TType {
25 	private HierarchyType fSuperclass;
26 	private HierarchyType[] fInterfaces;
27 	private IType fJavaElementType;
28 
HierarchyType(TypeEnvironment environment)29 	protected HierarchyType(TypeEnvironment environment) {
30 		super(environment);
31 	}
32 
initialize(ITypeBinding binding, IType javaElementType)33 	protected void initialize(ITypeBinding binding, IType javaElementType) {
34 		super.initialize(binding);
35 		Assert.isNotNull(javaElementType);
36 		fJavaElementType= javaElementType;
37 		TypeEnvironment environment= getEnvironment();
38 		ITypeBinding superclass= binding.getSuperclass();
39 		if (superclass != null) {
40 			fSuperclass= (HierarchyType)environment.create(superclass);
41 		}
42 		ITypeBinding[] interfaces= binding.getInterfaces();
43 		fInterfaces= new HierarchyType[interfaces.length];
44 		for (int i= 0; i < interfaces.length; i++) {
45 			fInterfaces[i]= (HierarchyType)environment.create(interfaces[i]);
46 		}
47 	}
48 
49 	@Override
getSuperclass()50 	public TType getSuperclass() {
51 		return fSuperclass;
52 	}
53 
54 	@Override
getInterfaces()55 	public TType[] getInterfaces() {
56 		return fInterfaces;
57 	}
58 
getJavaElementType()59 	public IType getJavaElementType() {
60 		return fJavaElementType;
61 	}
62 
isSubType(HierarchyType other)63 	public boolean isSubType(HierarchyType other) {
64 		if (getEnvironment() == other.getEnvironment()) {
65 			Map<TypeTuple, Boolean> cache= getEnvironment().getSubTypeCache();
66 			TypeTuple key= new TypeTuple(this, other);
67 			Boolean value= cache.get(key);
68 			if (value != null)
69 				return value.booleanValue();
70 			boolean isSub= doIsSubType(other);
71 			value= Boolean.valueOf(isSub);
72 			cache.put(key, value);
73 			return isSub;
74 		}
75 		return doIsSubType(other);
76 	}
77 
doIsSubType(HierarchyType other)78 	private boolean doIsSubType(HierarchyType other) {
79 		if (fSuperclass != null && (other.isTypeEquivalentTo(fSuperclass) || fSuperclass.doIsSubType(other)))
80 			return true;
81 		for (HierarchyType intf : fInterfaces) {
82 			if (other.isTypeEquivalentTo(intf) || intf.doIsSubType(other)) {
83 				return true;
84 			}
85 		}
86 		return false;
87 	}
88 
canAssignToStandardType(StandardType target)89 	protected boolean canAssignToStandardType(StandardType target) {
90 		if (target.isJavaLangObject())
91 			return true;
92 		return isSubType(target);
93 	}
94 }
95