| // Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| package com.android.tools.r8.graph; | |
| import java.util.Objects; | |
| import java.util.function.Function; | |
| import java.util.function.Predicate; | |
| import java.util.stream.Stream; | |
| /** | |
| * A common interface for {@link DexType}, {@link DexField}, and {@link DexMethod}. | |
| */ | |
| public abstract class DexReference extends IndexedDexItem { | |
| @Override | |
| public boolean isDexReference() { | |
| return true; | |
| } | |
| @Override | |
| public DexReference asDexReference() { | |
| return this; | |
| } | |
| public boolean isDexType() { | |
| return false; | |
| } | |
| public DexType asDexType() { | |
| return null; | |
| } | |
| public boolean isDescriptor() { | |
| return false; | |
| } | |
| public Descriptor asDescriptor() { | |
| return null; | |
| } | |
| public boolean isDexField() { | |
| return false; | |
| } | |
| public DexField asDexField() { | |
| return null; | |
| } | |
| public boolean isDexMethod() { | |
| return false; | |
| } | |
| public DexMethod asDexMethod() { | |
| return null; | |
| } | |
| public static Stream<DexReference> filterDexReference(Stream<DexItem> stream) { | |
| return DexItem.filter(stream, DexReference.class); | |
| } | |
| public DexDefinition toDefinition(AppInfo appInfo) { | |
| if (isDexType()) { | |
| return appInfo.definitionFor(asDexType()); | |
| } else if (isDexField()) { | |
| return appInfo.definitionFor(asDexField()); | |
| } else { | |
| assert isDexMethod(); | |
| return appInfo.definitionFor(asDexMethod()); | |
| } | |
| } | |
| public static Stream<DexDefinition> mapToDefinition( | |
| Stream<DexReference> references, AppInfo appInfo) { | |
| return references.map(r -> r.toDefinition(appInfo)).filter(Objects::nonNull); | |
| } | |
| private static <T extends DexReference> Stream<T> filter( | |
| Stream<DexReference> stream, | |
| Predicate<DexReference> pred, | |
| Function<DexReference, T> f) { | |
| return stream.filter(pred).map(f); | |
| } | |
| public static Stream<DexType> filterDexType(Stream<DexReference> stream) { | |
| return filter(stream, DexReference::isDexType, DexReference::asDexType); | |
| } | |
| public static Stream<DexField> filterDexField(Stream<DexReference> stream) { | |
| return filter(stream, DexReference::isDexField, DexReference::asDexField); | |
| } | |
| public static Stream<DexMethod> filterDexMethod(Stream<DexReference> stream) { | |
| return filter(stream, DexReference::isDexMethod, DexReference::asDexMethod); | |
| } | |
| } |