blob: 32fa61d905b17b34f1d259ec715f44248b152a79 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013, 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.compiler.lookup;
import org.eclipse.jdt.internal.compiler.ast.Wildcard;
import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
public class TypeBindingVisitor {
private SimpleLookupTable visitedCache;
public void reset() {
this.visitedCache = null;
}
public boolean visit(BaseTypeBinding baseTypeBinding) {
return true; // continue traversal.
}
public boolean visit(ArrayBinding arrayBinding) {
return true; // continue traversal.
}
public boolean visit(TypeVariableBinding typeVariable) {
return true; // continue traversal.
}
public boolean visit(ReferenceBinding referenceBinding) {
return true; // continue traversal.
}
public boolean visit(WildcardBinding wildcardBinding) {
return true; // continue traversal.
}
public boolean visit(ParameterizedTypeBinding parameterizedTypeBinding) {
return true; // continue traversal.
}
public boolean visit(IntersectionTypeBinding18 intersectionTypeBinding18) {
return true; // continue traversal.
}
public boolean visit(RawTypeBinding rawTypeBinding) {
return true; // continue traversal.
}
public boolean visit(PolyTypeBinding polyTypeBinding) {
return true; // continue traversal.
}
public static void visit(TypeBindingVisitor visitor, ReferenceBinding[] types) {
for (int i = 0, length = types == null ? 0 : types.length; i < length; i++) {
visit(visitor, types[i]);
}
}
public static void visit(TypeBindingVisitor visitor, TypeBinding type) {
if (type == null)
return;
SimpleLookupTable visitedCache = visitor.visitedCache;
if (visitedCache == null) {
visitor.visitedCache = new SimpleLookupTable(3);
visitedCache = visitor.visitedCache;
}
Object result = visitedCache.get(type);
if (result == Boolean.TRUE)
return;
visitedCache.put(type, Boolean.TRUE);
switch (type.kind()) {
case Binding.TYPE_PARAMETER:
TypeVariableBinding typeVariableBinding = (TypeVariableBinding) type;
if (visitor.visit(typeVariableBinding)) {
visit(visitor, typeVariableBinding.firstBound);
visit(visitor, typeVariableBinding.superclass);
visit(visitor, typeVariableBinding.superInterfaces);
}
break;
case Binding.PARAMETERIZED_TYPE:
ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBinding) type;
if (visitor.visit(parameterizedTypeBinding)) {
visit(visitor, parameterizedTypeBinding.enclosingType());
visit(visitor, parameterizedTypeBinding.arguments);
}
break;
case Binding.ARRAY_TYPE:
ArrayBinding arrayBinding = (ArrayBinding) type;
if (visitor.visit(arrayBinding))
visit(visitor, arrayBinding.leafComponentType);
break;
case Binding.WILDCARD_TYPE:
case Binding.INTERSECTION_TYPE:
WildcardBinding wildcard = (WildcardBinding) type;
if (visitor.visit(wildcard)) {
if (wildcard.boundKind != Wildcard.UNBOUND) {
visit(visitor, wildcard.bound);
visit(visitor, wildcard.otherBounds);
}
}
break;
case Binding.BASE_TYPE:
visitor.visit((BaseTypeBinding) type);
break;
case Binding.RAW_TYPE:
//{ObjectTeams: relax the type to include half-raw dependent types:
if (type.isRoleType())
type = ((ParameterizedTypeBinding) type).genericType();
// SH}
visitor.visit((RawTypeBinding) type);
break;
case Binding.TYPE:
case Binding.GENERIC_TYPE:
ReferenceBinding referenceBinding = (ReferenceBinding) type;
if (visitor.visit(referenceBinding)) {
visit(visitor, referenceBinding.enclosingType());
visit(visitor, referenceBinding.typeVariables());
}
break;
case Binding.INTERSECTION_TYPE18:
IntersectionTypeBinding18 intersectionTypeBinding18 = (IntersectionTypeBinding18) type;
if (visitor.visit(intersectionTypeBinding18))
visit(visitor, intersectionTypeBinding18.intersectingTypes);
break;
case Binding.POLY_TYPE:
visitor.visit((PolyTypeBinding) type);
break;
default:
throw new InternalError("Unexpected binding type"); //$NON-NLS-1$
}
}
public static void visit(TypeBindingVisitor visitor, TypeBinding[] types) {
for (int i = 0, length = types == null ? 0 : types.length; i < length; i++) {
visit(visitor, types[i]);
}
}
}