|  | // 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 com.android.tools.r8.shaking.AnnotationRemover; | 
|  | import com.android.tools.r8.shaking.AppInfoWithLiveness; | 
|  | import java.util.function.Function; | 
|  | import java.util.function.Predicate; | 
|  | import java.util.stream.Stream; | 
|  |  | 
|  | /** | 
|  | * A common interface for {@link DexClass}, {@link DexEncodedField}, and {@link DexEncodedMethod}. | 
|  | */ | 
|  | public abstract class DexDefinition extends DexItem { | 
|  |  | 
|  | private DexAnnotationSet annotations; | 
|  |  | 
|  | public DexDefinition(DexAnnotationSet annotations) { | 
|  | assert annotations != null : "Should use DexAnnotationSet.THE_EMPTY_ANNOTATIONS_SET"; | 
|  | this.annotations = annotations; | 
|  | } | 
|  |  | 
|  | public boolean hasAnnotations() { | 
|  | return !annotations().isEmpty(); | 
|  | } | 
|  |  | 
|  | public DexAnnotationSet annotations() { | 
|  | return annotations; | 
|  | } | 
|  |  | 
|  | public abstract AccessFlags<?> getAccessFlags(); | 
|  |  | 
|  | public DexAnnotationSet liveAnnotations(AppView<AppInfoWithLiveness> appView) { | 
|  | return annotations.keepIf( | 
|  | annotation -> AnnotationRemover.shouldKeepAnnotation(appView, this, annotation)); | 
|  | } | 
|  |  | 
|  | public void clearAnnotations() { | 
|  | setAnnotations(DexAnnotationSet.empty()); | 
|  | } | 
|  |  | 
|  | public void setAnnotations(DexAnnotationSet annotations) { | 
|  | this.annotations = annotations; | 
|  | } | 
|  |  | 
|  | public void removeAnnotations(Predicate<DexAnnotation> predicate) { | 
|  | setAnnotations(annotations().removeIf(predicate)); | 
|  | } | 
|  |  | 
|  | public boolean isDexClass() { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | public DexClass asDexClass() { | 
|  | return null; | 
|  | } | 
|  |  | 
|  | public boolean isProgramClass() { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | public DexProgramClass asProgramClass() { | 
|  | return null; | 
|  | } | 
|  |  | 
|  | public boolean isDexEncodedMember() { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | public DexEncodedMember<?, ?> asDexEncodedMember() { | 
|  | return null; | 
|  | } | 
|  |  | 
|  | public boolean isDexEncodedField() { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | public DexEncodedField asDexEncodedField() { | 
|  | return null; | 
|  | } | 
|  |  | 
|  | public boolean isDexEncodedMethod() { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | public DexEncodedMethod asDexEncodedMethod() { | 
|  | return null; | 
|  | } | 
|  |  | 
|  | public abstract DexReference getReference(); | 
|  |  | 
|  | private static <T extends DexDefinition> Stream<T> filter( | 
|  | Stream<DexDefinition> stream, | 
|  | Predicate<DexDefinition> pred, | 
|  | Function<DexDefinition, T> f) { | 
|  | return stream.filter(pred).map(f); | 
|  | } | 
|  |  | 
|  | public static Stream<DexEncodedField> filterDexEncodedField(Stream<DexDefinition> stream) { | 
|  | return filter(stream, DexDefinition::isDexEncodedField, DexDefinition::asDexEncodedField); | 
|  | } | 
|  |  | 
|  | public static Stream<DexEncodedMethod> filterDexEncodedMethod(Stream<DexDefinition> stream) { | 
|  | return filter(stream, DexDefinition::isDexEncodedMethod, DexDefinition::asDexEncodedMethod); | 
|  | } | 
|  |  | 
|  | public abstract boolean isStatic(); | 
|  |  | 
|  | public abstract boolean isStaticMember(); | 
|  |  | 
|  | public boolean isNotProgramDefinition(AppView<?> appView) { | 
|  | if (isDexClass()) { | 
|  | return asDexClass().isNotProgramClass(); | 
|  | } | 
|  | DexClass clazz = appView.definitionFor(asDexEncodedMember().getHolderType()); | 
|  | return clazz == null || clazz.isNotProgramClass(); | 
|  | } | 
|  |  | 
|  | public DexType getContextType() { | 
|  | return isDexClass() ? asDexClass().type : asDexEncodedMember().getHolderType(); | 
|  | } | 
|  | } |