blob: b6cb8e5406ac36b89c853d877c78e10312aaab96 [file] [log] [blame]
// 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.shaking;
import com.android.tools.r8.errors.Unreachable;
public abstract class ProguardWildcard {
abstract void setCaptured(String captured);
abstract void clearCaptured();
abstract String getCaptured();
abstract ProguardWildcard materialize();
boolean isPattern() {
return false;
}
Pattern asPattern() {
return null;
}
boolean isBackReference() {
return false;
}
BackReference asBackReference() {
return null;
}
static class Pattern extends ProguardWildcard {
final String pattern;
private String captured = null;
Pattern(String pattern) {
this.pattern = pattern;
}
@Override
synchronized void setCaptured(String captured) {
this.captured = captured;
}
@Override
synchronized void clearCaptured() {
captured = null;
}
@Override
synchronized String getCaptured() {
return captured;
}
@Override
Pattern materialize() {
if (captured == null) {
return this;
}
Pattern copy = new Pattern(pattern);
copy.setCaptured(captured);
return copy;
}
@Override
boolean isPattern() {
return true;
}
@Override
Pattern asPattern() {
return this;
}
@Override
public String toString() {
return pattern;
}
}
static class BackReference extends ProguardWildcard {
// Back-reference is not referable, hence the other type, Pattern, here.
Pattern reference;
final int referenceIndex;
BackReference(int referenceIndex) {
this.referenceIndex = referenceIndex;
}
void setReference(Pattern reference) {
this.reference = reference;
}
@Override
void setCaptured(String captured) {
throw new Unreachable("A back reference refers back to a previously matched wildcard.");
}
@Override
void clearCaptured() {
// no-op
}
@Override
String getCaptured() {
return reference != null ? reference.getCaptured() : null;
}
@Override
BackReference materialize() {
if (reference == null || reference.getCaptured() == null) {
return this;
}
BackReference copy = new BackReference(referenceIndex);
copy.setReference(reference.materialize());
return copy;
}
@Override
boolean isBackReference() {
return true;
}
@Override
BackReference asBackReference() {
return this;
}
@Override
public String toString() {
return "<" + referenceIndex + ">";
}
}
}