blob: 6dfe7e411c76f3d54899a2382ab66ef96f611ab0 [file] [log] [blame]
// Copyright (c) 2022, 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.keepanno.ast;
import java.util.Collection;
import java.util.Objects;
import java.util.function.Predicate;
/**
* A pattern for matching items in the program.
*
* <p>An item pattern can be any item, or it can describe a family of classes or a family of members
* on a classes.
*
* <p>A pattern cannot describe both a class *and* a member of a class. Either it is a pattern on
* classes or it is a pattern on members. The distinction is defined by having a "none" member
* pattern.
*/
public class KeepItemPattern {
public static KeepItemPattern any() {
return builder().any().build();
}
public static Builder builder() {
return new Builder();
}
public boolean isClassItemPattern() {
return memberPattern.isNone();
}
public boolean isMemberItemPattern() {
return !memberPattern.isNone();
}
public static class Builder {
private KeepClassReference classReference =
KeepClassReference.fromClassNamePattern(KeepQualifiedClassNamePattern.any());
private KeepExtendsPattern extendsPattern = KeepExtendsPattern.any();
private KeepMemberPattern memberPattern = KeepMemberPattern.none();
private Builder() {}
public Builder copyFrom(KeepItemPattern pattern) {
return setClassReference(pattern.getClassReference())
.setExtendsPattern(pattern.getExtendsPattern())
.setMemberPattern(pattern.getMemberPattern());
}
public Builder any() {
classReference = KeepClassReference.fromClassNamePattern(KeepQualifiedClassNamePattern.any());
extendsPattern = KeepExtendsPattern.any();
memberPattern = KeepMemberPattern.all();
return this;
}
public Builder setClassReference(KeepClassReference classReference) {
this.classReference = classReference;
return this;
}
public Builder setClassPattern(KeepQualifiedClassNamePattern qualifiedClassNamePattern) {
return setClassReference(KeepClassReference.fromClassNamePattern(qualifiedClassNamePattern));
}
public Builder setExtendsPattern(KeepExtendsPattern extendsPattern) {
this.extendsPattern = extendsPattern;
return this;
}
public Builder setMemberPattern(KeepMemberPattern memberPattern) {
this.memberPattern = memberPattern;
return this;
}
public KeepItemPattern build() {
return new KeepItemPattern(classReference, extendsPattern, memberPattern);
}
}
private final KeepClassReference classReference;
private final KeepExtendsPattern extendsPattern;
private final KeepMemberPattern memberPattern;
// TODO: class annotations
private KeepItemPattern(
KeepClassReference classReference,
KeepExtendsPattern extendsPattern,
KeepMemberPattern memberPattern) {
assert classReference != null;
assert extendsPattern != null;
assert memberPattern != null;
this.classReference = classReference;
this.extendsPattern = extendsPattern;
this.memberPattern = memberPattern;
}
public boolean isAny(Predicate<String> onReference) {
return extendsPattern.isAny() && memberPattern.isAll() && classReference.isAny(onReference);
}
public KeepClassReference getClassReference() {
return classReference;
}
public KeepExtendsPattern getExtendsPattern() {
return extendsPattern;
}
public KeepMemberPattern getMemberPattern() {
return memberPattern;
}
public Collection<String> getBindingReferences() {
return classReference.getBindingReferences();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
KeepItemPattern that = (KeepItemPattern) obj;
return classReference.equals(that.classReference)
&& extendsPattern.equals(that.extendsPattern)
&& memberPattern.equals(that.memberPattern);
}
@Override
public int hashCode() {
return Objects.hash(classReference, extendsPattern, memberPattern);
}
@Override
public String toString() {
return "KeepClassPattern{"
+ "classReference="
+ classReference
+ ", extendsPattern="
+ extendsPattern
+ ", memberPattern="
+ memberPattern
+ '}';
}
}