/******************************************************************************* * 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.Collections; import java.util.LinkedList; import java.util.List; import org.axdt.avm.model.AvmDeclaredType; import org.axdt.avm.model.AvmType; import org.axdt.avm.model.AvmTypeReference; import com.google.common.base.Function; public class SuperTypeCollector { public List<AvmType> collectSuperTypes(AvmType type) { Function<AvmType, AvmType> function = new Function<AvmType, AvmType>() { public AvmType apply(AvmType from) { return from; } }; return doCollectSupertypeData(type, function); } public List<String> collectSuperTypeNames(AvmType type) { Function<AvmType, String> function = new Function<AvmType, String>() { public String apply(AvmType from) { return from.getCanonicalName(); } }; return doCollectSupertypeData(type, function); } public <Result> List<Result> doCollectSupertypeData(AvmType type, Function<AvmType, Result> function) { if (type != null) return new Collector<Result>(function).collect(type); return Collections.emptyList(); } public static class Collector<Result> { public final Function<AvmType, Result> transformation; public Collector(Function<AvmType, Result> transformation) { this.transformation = transformation; } public List<Result> collect(AvmType type) { return collect(type, new LinkedList<Result>()); } public List<Result> collect(AvmType type, List<Result> result) { Result res = transformation.apply(type); if (res != null) result.add(res); if (type instanceof AvmDeclaredType) { for(AvmTypeReference superType: ((AvmDeclaredType) type).getSuperTypes()) collect(superType.getType(), result); } return result; } } public static class Implementation<Result> extends AvmESwitch<Void> { private final Function<AvmType, Result> transformation; private List<Result> result; public Implementation(Function<AvmType, Result> transformation) { this.transformation = transformation; result = new LinkedList<Result>(); } public List<Result> getResult() { return result; } @Override public Void caseAvmType(AvmType object) { return null; } @Override public Void caseAvmDeclaredType(AvmDeclaredType object) { if (!object.eIsProxy()) { if (result.add(transformation.apply(object))) { for(AvmTypeReference superType: object.getSuperTypes()) doSwitch(superType.getType()); } } return null; } } }