blob: 5716e748f4a9f12f2dd860d88a376f32da6e4ca7 [file] [log] [blame]
// Copyright (c) 2024, 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.shaking.rules;
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.shaking.Enqueuer;
import com.android.tools.r8.shaking.MinimumKeepInfoCollection;
import java.util.ArrayList;
import java.util.List;
public abstract class PendingConditionalRuleBase<T> {
private final List<T> outstandingPreconditions;
private final List<DexReference> satisfiedPreconditions;
private final MinimumKeepInfoCollection consequences;
PendingConditionalRuleBase(List<T> preconditions, MinimumKeepInfoCollection consequences) {
this.outstandingPreconditions = preconditions;
this.satisfiedPreconditions = new ArrayList<>(preconditions.size());
this.consequences = consequences;
}
abstract DexReference getReference(T item);
abstract boolean isSatisfied(T item, Enqueuer enqueuer);
MinimumKeepInfoCollection getConsequences() {
return consequences;
}
MaterializedConditionalRule asMaterialized() {
assert !isOutstanding();
return new MaterializedConditionalRule(satisfiedPreconditions, consequences);
}
final boolean isOutstanding() {
return !outstandingPreconditions.isEmpty();
}
final boolean isSatisfiedAfterUpdate(Enqueuer enqueuer) {
assert isOutstanding();
int newlySatisfied = 0;
for (T precondition : outstandingPreconditions) {
if (isSatisfied(precondition, enqueuer)) {
++newlySatisfied;
satisfiedPreconditions.add(getReference(precondition));
}
}
// Not satisfied and nothing changed.
if (newlySatisfied == 0) {
return false;
}
// The rule is satisfied in full.
if (newlySatisfied == outstandingPreconditions.size()) {
outstandingPreconditions.clear();
return true;
}
// Partially satisfied.
// This is expected to be the uncommon case so the update to outstanding is delayed to here.
outstandingPreconditions.removeIf(
outstanding -> satisfiedPreconditions.contains(getReference(outstanding)));
assert isOutstanding();
return false;
}
}