Here are the examples of the java api com.google.common.collect.ImmutableSet taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.
1197 Examples
19
Source : FindLimit0Visitor.java
with Apache License 2.0
from zpochen
with Apache License 2.0
from zpochen
/**
* Visitor that will identify whether the root portion of the RelNode tree contains a limit 0 pattern. In this case, we
* inform the planner settings that this plan should be run as a single node plan to reduce the overhead replacedociated with
* executing a schema-only query.
*/
public clreplaced FindLimit0Visitor extends RelShuttleImpl {
// private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(FindLimit0Visitor.clreplaced);
// Some types are excluded in this set:
// + DECIMAL type is not fully supported in general.
// + VARBINARY is not fully tested.
// + MAP, ARRAY are currently not exposed to the planner.
// + TINYINT, SMALLINT are defined in the Drill type system but have been turned off for now.
// + SYMBOL, MULTISET, DISTINCT, STRUCTURED, ROW, OTHER, CURSOR, COLUMN_LIST are Calcite types
// currently not supported by Drill, nor defined in the Drill type list.
// + ANY is the late binding type.
private static final ImmutableSet<SqlTypeName> TYPES = ImmutableSet.<SqlTypeName>builder().add(SqlTypeName.INTEGER, SqlTypeName.BIGINT, SqlTypeName.FLOAT, SqlTypeName.DOUBLE, SqlTypeName.VARCHAR, SqlTypeName.BOOLEAN, SqlTypeName.DATE, SqlTypeName.TIME, SqlTypeName.TIMESTAMP, SqlTypeName.INTERVAL_YEAR_MONTH, SqlTypeName.INTERVAL_DAY_TIME, SqlTypeName.CHAR).build();
/**
* If all field types of the given node are {@link #TYPES recognized types} and honored by execution, then this
* method returns the tree: DrillDirectScanRel(field types). Otherwise, the method returns null.
*
* @param rel calcite logical rel tree
* @return drill logical rel tree
*/
public static DrillRel getDirectScanRelIfFullySchemaed(RelNode rel) {
final List<RelDataTypeField> fieldList = rel.getRowType().getFieldList();
final List<TypeProtos.MajorType> columnTypes = Lists.newArrayList();
for (final RelDataTypeField field : fieldList) {
final SqlTypeName sqlTypeName = field.getType().getSqlTypeName();
if (!TYPES.contains(sqlTypeName)) {
return null;
} else {
final TypeProtos.MajorType.Builder builder = TypeProtos.MajorType.newBuilder().setMode(field.getType().isNullable() ? TypeProtos.DataMode.OPTIONAL : TypeProtos.DataMode.REQUIRED).setMinorType(TypeInferenceUtils.getDrillTypeFromCalciteType(sqlTypeName));
if (TypeInferenceUtils.isScalarStringType(sqlTypeName)) {
builder.setPrecision(field.getType().getPrecision());
}
columnTypes.add(builder.build());
}
}
final RelTraitSet traits = rel.getTraitSet().plus(DrillRel.DRILL_LOGICAL);
final RelDataTypeReader reader = new RelDataTypeReader(rel.getRowType().getFieldNames(), columnTypes);
return new DrillDirectScanRel(rel.getCluster(), traits, new DirectGroupScan(reader, ScanStats.ZERO_RECORD_TABLE), rel.getRowType());
}
/**
* Check if the root portion of the tree contains LIMIT(0).
*
* @param rel rel node tree
* @return true if the root portion of the tree contains LIMIT(0)
*/
public static boolean containsLimit0(final RelNode rel) {
FindLimit0Visitor visitor = new FindLimit0Visitor();
rel.accept(visitor);
return visitor.isContains();
}
private boolean contains = false;
private FindLimit0Visitor() {
}
boolean isContains() {
return contains;
}
private static boolean isLimit0(RexNode fetch) {
if (fetch != null && fetch.isA(SqlKind.LITERAL)) {
RexLiteral l = (RexLiteral) fetch;
switch(l.getTypeName()) {
case BIGINT:
case INTEGER:
case DECIMAL:
if (((long) l.getValue2()) == 0) {
return true;
}
}
}
return false;
}
@Override
public RelNode visit(LogicalSort sort) {
if (isLimit0(sort.fetch)) {
contains = true;
return sort;
}
return super.visit(sort);
}
@Override
public RelNode visit(RelNode other) {
if (other instanceof DrillLimitRel) {
if (isLimit0(((DrillLimitRel) other).getFetch())) {
contains = true;
return other;
}
}
return super.visit(other);
}
// The following set of RelNodes should terminate a search for the limit 0 pattern as they want convey its meaning.
@Override
public RelNode visit(LogicalAggregate aggregate) {
return aggregate;
}
@Override
public RelNode visit(LogicalIntersect intersect) {
return intersect;
}
@Override
public RelNode visit(LogicalJoin join) {
return join;
}
@Override
public RelNode visit(LogicalMinus minus) {
return minus;
}
@Override
public RelNode visit(LogicalUnion union) {
return union;
}
/**
* Reader for column names and types.
*/
public static clreplaced RelDataTypeReader extends AbstractRecordReader {
public final List<String> columnNames;
public final List<TypeProtos.MajorType> columnTypes;
public RelDataTypeReader(List<String> columnNames, List<TypeProtos.MajorType> columnTypes) {
Preconditions.checkArgument(columnNames.size() == columnTypes.size(), "Number of columns and their types should match");
this.columnNames = columnNames;
this.columnTypes = columnTypes;
}
@Override
public void setup(OperatorContext context, OutputMutator output) throws ExecutionSetupException {
for (int i = 0; i < columnNames.size(); i++) {
final TypeProtos.MajorType type = columnTypes.get(i);
final MaterializedField field = MaterializedField.create(columnNames.get(i), type);
final Clreplaced vvClreplaced = TypeHelper.getValueVectorClreplaced(type.getMinorType(), type.getMode());
try {
output.addField(field, vvClreplaced);
} catch (SchemaChangeException e) {
throw new ExecutionSetupException(e);
}
}
}
@Override
public int next() {
return 0;
}
@Override
public void close() throws Exception {
}
}
}
19
Source : ScalarReplacementTypes.java
with Apache License 2.0
from zpochen
with Apache License 2.0
from zpochen
/**
* Reference list of clreplacedes we will perform scalar replacement on.
*/
public clreplaced ScalarReplacementTypes {
// This clreplaced only has static utilities.
private ScalarReplacementTypes() {
}
static {
Clreplaced<?>[] clreplacedList = { BitHolder.clreplaced, IntHolder.clreplaced, BigIntHolder.clreplaced, Float4Holder.clreplaced, Float8Holder.clreplaced, Decimal9Holder.clreplaced, Decimal18Holder.clreplaced, Decimal28SparseHolder.clreplaced, Decimal28DenseHolder.clreplaced, Decimal38SparseHolder.clreplaced, Decimal38DenseHolder.clreplaced, IntervalHolder.clreplaced, IntervalDayHolder.clreplaced, IntervalYearHolder.clreplaced, DateHolder.clreplaced, TimeHolder.clreplaced, TimeStampHolder.clreplaced, VarCharHolder.clreplaced, VarBinaryHolder.clreplaced, NullableBitHolder.clreplaced, NullableIntHolder.clreplaced, NullableBigIntHolder.clreplaced, NullableFloat4Holder.clreplaced, NullableFloat8Holder.clreplaced, NullableVarCharHolder.clreplaced, NullableVarBinaryHolder.clreplaced, NullableDecimal9Holder.clreplaced, NullableDecimal18Holder.clreplaced, NullableDecimal28SparseHolder.clreplaced, NullableDecimal28DenseHolder.clreplaced, NullableDecimal38SparseHolder.clreplaced, NullableDecimal38DenseHolder.clreplaced, NullableIntervalHolder.clreplaced, NullableIntervalDayHolder.clreplaced, NullableIntervalYearHolder.clreplaced, NullableDateHolder.clreplaced, NullableTimeHolder.clreplaced, NullableTimeStampHolder.clreplaced };
CLreplacedES = ImmutableSet.copyOf(clreplacedList);
}
public static final ImmutableSet<Clreplaced<?>> CLreplacedES;
/**
* Determine if a clreplaced is a holder clreplaced.
*
* @param clreplacedName the name of the clreplaced
* @return true if the clreplaced belongs to the CLreplacedES set.
*/
public static boolean isHolder(final String clreplacedName) {
try {
final Clreplaced<?> clazz = Clreplaced.forName(clreplacedName);
return CLreplacedES.contains(clazz);
} catch (ClreplacedNotFoundException e) {
// do nothing
}
return false;
}
}
19
Source : MongoCompareFunctionProcessor.java
with Apache License 2.0
from zpochen
with Apache License 2.0
from zpochen
public clreplaced MongoCompareFunctionProcessor extends AbstractExprVisitor<Boolean, LogicalExpression, RuntimeException> {
private Object value;
private boolean success;
private boolean isEqualityFn;
private SchemaPath path;
private String functionName;
public static boolean isCompareFunction(String functionName) {
return COMPARE_FUNCTIONS_TRANSPOSE_MAP.keySet().contains(functionName);
}
public static MongoCompareFunctionProcessor process(FunctionCall call) {
String functionName = call.getName();
LogicalExpression nameArg = call.args.get(0);
LogicalExpression valueArg = call.args.size() == 2 ? call.args.get(1) : null;
MongoCompareFunctionProcessor evaluator = new MongoCompareFunctionProcessor(functionName);
if (valueArg != null) {
// binary function
if (VALUE_EXPRESSION_CLreplacedES.contains(nameArg.getClreplaced())) {
LogicalExpression swapArg = valueArg;
valueArg = nameArg;
nameArg = swapArg;
evaluator.functionName = COMPARE_FUNCTIONS_TRANSPOSE_MAP.get(functionName);
}
evaluator.success = nameArg.accept(evaluator, valueArg);
} else if (call.args.get(0) instanceof SchemaPath) {
evaluator.success = true;
evaluator.path = (SchemaPath) nameArg;
}
return evaluator;
}
public MongoCompareFunctionProcessor(String functionName) {
this.success = false;
this.functionName = functionName;
this.isEqualityFn = COMPARE_FUNCTIONS_TRANSPOSE_MAP.containsKey(functionName) && COMPARE_FUNCTIONS_TRANSPOSE_MAP.get(functionName).equals(functionName);
}
public Object getValue() {
return value;
}
public boolean isSuccess() {
return success;
}
public SchemaPath getPath() {
return path;
}
public String getFunctionName() {
return functionName;
}
@Override
public Boolean visitCastExpression(CastExpression e, LogicalExpression valueArg) throws RuntimeException {
if (e.getInput() instanceof CastExpression || e.getInput() instanceof SchemaPath) {
return e.getInput().accept(this, valueArg);
}
return false;
}
@Override
public Boolean visitConvertExpression(ConvertExpression e, LogicalExpression valueArg) throws RuntimeException {
if (e.getConvertFunction() == ConvertExpression.CONVERT_FROM && e.getInput() instanceof SchemaPath) {
String encodingType = e.getEncodingType();
switch(encodingType) {
case "INT_BE":
case "INT":
case "UINT_BE":
case "UINT":
case "UINT4_BE":
case "UINT4":
if (valueArg instanceof IntExpression && (isEqualityFn || encodingType.startsWith("U"))) {
this.value = ((IntExpression) valueArg).getInt();
}
break;
case "BIGINT_BE":
case "BIGINT":
case "UINT8_BE":
case "UINT8":
if (valueArg instanceof LongExpression && (isEqualityFn || encodingType.startsWith("U"))) {
this.value = ((LongExpression) valueArg).getLong();
}
break;
case "FLOAT":
if (valueArg instanceof FloatExpression && isEqualityFn) {
this.value = ((FloatExpression) valueArg).getFloat();
}
break;
case "DOUBLE":
if (valueArg instanceof DoubleExpression && isEqualityFn) {
this.value = ((DoubleExpression) valueArg).getDouble();
}
break;
case "TIME_EPOCH":
case "TIME_EPOCH_BE":
if (valueArg instanceof TimeExpression) {
this.value = ((TimeExpression) valueArg).getTime();
}
break;
case "DATE_EPOCH":
case "DATE_EPOCH_BE":
if (valueArg instanceof DateExpression) {
this.value = ((DateExpression) valueArg).getDate();
}
break;
case "BOOLEAN_BYTE":
if (valueArg instanceof BooleanExpression) {
this.value = ((BooleanExpression) valueArg).getBoolean();
}
break;
case "UTF8":
// let visitSchemaPath() handle this.
return e.getInput().accept(this, valueArg);
}
if (value != null) {
this.path = (SchemaPath) e.getInput();
return true;
}
}
return false;
}
@Override
public Boolean visitUnknown(LogicalExpression e, LogicalExpression valueArg) throws RuntimeException {
return false;
}
@Override
public Boolean visitSchemaPath(SchemaPath path, LogicalExpression valueArg) throws RuntimeException {
if (valueArg instanceof QuotedString) {
this.value = ((QuotedString) valueArg).value;
this.path = path;
return true;
}
if (valueArg instanceof IntExpression) {
this.value = ((IntExpression) valueArg).getInt();
this.path = path;
return true;
}
if (valueArg instanceof LongExpression) {
this.value = ((LongExpression) valueArg).getLong();
this.path = path;
return true;
}
if (valueArg instanceof FloatExpression) {
this.value = ((FloatExpression) valueArg).getFloat();
this.path = path;
return true;
}
if (valueArg instanceof DoubleExpression) {
this.value = ((DoubleExpression) valueArg).getDouble();
this.path = path;
return true;
}
if (valueArg instanceof BooleanExpression) {
this.value = ((BooleanExpression) valueArg).getBoolean();
this.path = path;
return true;
}
return false;
}
private static final ImmutableSet<Clreplaced<? extends LogicalExpression>> VALUE_EXPRESSION_CLreplacedES;
static {
ImmutableSet.Builder<Clreplaced<? extends LogicalExpression>> builder = ImmutableSet.builder();
VALUE_EXPRESSION_CLreplacedES = builder.add(BooleanExpression.clreplaced).add(DateExpression.clreplaced).add(DoubleExpression.clreplaced).add(FloatExpression.clreplaced).add(IntExpression.clreplaced).add(LongExpression.clreplaced).add(QuotedString.clreplaced).add(TimeExpression.clreplaced).build();
}
private static final ImmutableMap<String, String> COMPARE_FUNCTIONS_TRANSPOSE_MAP;
static {
ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
COMPARE_FUNCTIONS_TRANSPOSE_MAP = builder.put("isnotnull", "isnotnull").put("isNotNull", "isNotNull").put("is not null", "is not null").put("isnull", "isnull").put("isNull", "isNull").put("is null", "is null").put("equal", "equal").put("not_equal", "not_equal").put("greater_than_or_equal_to", "less_than_or_equal_to").put("greater_than", "less_than").put("less_than_or_equal_to", "greater_than_or_equal_to").put("less_than", "greater_than").build();
}
}
19
Source : CompareFunctionsProcessor.java
with Apache License 2.0
from zpochen
with Apache License 2.0
from zpochen
public clreplaced CompareFunctionsProcessor extends AbstractExprVisitor<Boolean, LogicalExpression, RuntimeException> {
private byte[] value;
private boolean success;
private boolean isEqualityFn;
private SchemaPath path;
private String functionName;
private boolean sortOrderAscending;
// Fields for row-key prefix comparison
// If the query is on row-key prefix, we cannot use a standard template to identify startRow, stopRow and filter
// Hence, we use these local variables(set depending upon the encoding type in user query)
private boolean isRowKeyPrefixComparison;
private byte[] rowKeyPrefixStartRow;
private byte[] rowKeyPrefixStopRow;
private Filter rowKeyPrefixFilter;
public static boolean isCompareFunction(String functionName) {
return COMPARE_FUNCTIONS_TRANSPOSE_MAP.keySet().contains(functionName);
}
public static CompareFunctionsProcessor createFunctionsProcessorInstance(FunctionCall call, boolean nullComparatorSupported) {
String functionName = call.getName();
CompareFunctionsProcessor evaluator = new CompareFunctionsProcessor(functionName);
return createFunctionsProcessorInstanceInternal(call, nullComparatorSupported, evaluator);
}
protected static <T extends CompareFunctionsProcessor> T createFunctionsProcessorInstanceInternal(FunctionCall call, boolean nullComparatorSupported, T evaluator) {
LogicalExpression nameArg = call.args.get(0);
LogicalExpression valueArg = call.args.size() >= 2 ? call.args.get(1) : null;
if (valueArg != null) {
// binary function
if (VALUE_EXPRESSION_CLreplacedES.contains(nameArg.getClreplaced())) {
LogicalExpression swapArg = valueArg;
valueArg = nameArg;
nameArg = swapArg;
evaluator.setFunctionName(COMPARE_FUNCTIONS_TRANSPOSE_MAP.get(evaluator.getFunctionName()));
}
evaluator.setSuccess(nameArg.accept(evaluator, valueArg));
} else if (nullComparatorSupported && call.args.get(0) instanceof SchemaPath) {
evaluator.setSuccess(true);
evaluator.setPath((SchemaPath) nameArg);
}
return evaluator;
}
public CompareFunctionsProcessor(String functionName) {
this.success = false;
this.functionName = functionName;
this.isEqualityFn = COMPARE_FUNCTIONS_TRANSPOSE_MAP.containsKey(functionName) && COMPARE_FUNCTIONS_TRANSPOSE_MAP.get(functionName).equals(functionName);
this.isRowKeyPrefixComparison = false;
this.sortOrderAscending = true;
}
public byte[] getValue() {
return value;
}
public boolean isSuccess() {
return success;
}
protected void setSuccess(boolean success) {
this.success = success;
}
public SchemaPath getPath() {
return path;
}
protected void setPath(SchemaPath path) {
this.path = path;
}
public String getFunctionName() {
return functionName;
}
protected void setFunctionName(String functionName) {
this.functionName = functionName;
}
public boolean isRowKeyPrefixComparison() {
return isRowKeyPrefixComparison;
}
public byte[] getRowKeyPrefixStartRow() {
return rowKeyPrefixStartRow;
}
public byte[] getRowKeyPrefixStopRow() {
return rowKeyPrefixStopRow;
}
public Filter getRowKeyPrefixFilter() {
return rowKeyPrefixFilter;
}
public boolean isSortOrderAscending() {
return sortOrderAscending;
}
protected void setSortOrderAscending(boolean sortOrderAscending) {
this.sortOrderAscending = sortOrderAscending;
}
@Override
public Boolean visitCastExpression(CastExpression e, LogicalExpression valueArg) throws RuntimeException {
if (e.getInput() instanceof CastExpression || e.getInput() instanceof SchemaPath) {
return e.getInput().accept(this, valueArg);
}
return false;
}
@Override
public Boolean visitConvertExpression(ConvertExpression e, LogicalExpression valueArg) throws RuntimeException {
if (ConvertExpression.CONVERT_FROM.equals(e.getConvertFunction())) {
String encodingType = e.getEncodingType();
int prefixLength;
// Handle scan pruning in the following scenario:
// The row-key is a composite key and the CONVERT_FROM() function has byte_substr() as input function which is
// querying for the first few bytes of the row-key(start-offset 1)
// Example WHERE clause:
// CONVERT_FROM(BYTE_SUBSTR(row_key, 1, 8), 'DATE_EPOCH_BE') < DATE '2015-06-17'
if (e.getInput() instanceof FunctionCall) {
// We can prune scan range only for big-endian encoded data
if (!encodingType.endsWith("_BE")) {
return false;
}
FunctionCall call = (FunctionCall) e.getInput();
String functionName = call.getName();
if (!functionName.equalsIgnoreCase("byte_substr")) {
return false;
}
LogicalExpression nameArg = call.args.get(0);
LogicalExpression valueArg1 = call.args.size() >= 2 ? call.args.get(1) : null;
LogicalExpression valueArg2 = call.args.size() >= 3 ? call.args.get(2) : null;
if (!(nameArg instanceof SchemaPath) || (valueArg1 == null) || !(valueArg1 instanceof IntExpression) || (valueArg2 == null) || !(valueArg2 instanceof IntExpression)) {
return false;
}
boolean isRowKey = ((SchemaPath) nameArg).getRootSegmentPath().equals(DrillHBaseConstants.ROW_KEY);
int offset = ((IntExpression) valueArg1).getInt();
if (!isRowKey || offset != 1) {
return false;
}
this.path = (SchemaPath) nameArg;
prefixLength = ((IntExpression) valueArg2).getInt();
this.isRowKeyPrefixComparison = true;
return visitRowKeyPrefixConvertExpression(e, prefixLength, valueArg);
}
if (e.getInput() instanceof SchemaPath) {
ByteBuf bb = null;
switch(encodingType) {
case "INT_BE":
case "INT":
case "UINT_BE":
case "UINT":
case "UINT4_BE":
case "UINT4":
if (valueArg instanceof IntExpression && (isEqualityFn || encodingType.startsWith("U"))) {
bb = newByteBuf(4, encodingType.endsWith("_BE"));
bb.writeInt(((IntExpression) valueArg).getInt());
}
break;
case "BIGINT_BE":
case "BIGINT":
case "UINT8_BE":
case "UINT8":
if (valueArg instanceof LongExpression && (isEqualityFn || encodingType.startsWith("U"))) {
bb = newByteBuf(8, encodingType.endsWith("_BE"));
bb.writeLong(((LongExpression) valueArg).getLong());
}
break;
case "FLOAT":
if (valueArg instanceof FloatExpression && isEqualityFn) {
bb = newByteBuf(4, true);
bb.writeFloat(((FloatExpression) valueArg).getFloat());
}
break;
case "DOUBLE":
if (valueArg instanceof DoubleExpression && isEqualityFn) {
bb = newByteBuf(8, true);
bb.writeDouble(((DoubleExpression) valueArg).getDouble());
}
break;
case "TIME_EPOCH":
case "TIME_EPOCH_BE":
if (valueArg instanceof TimeExpression) {
bb = newByteBuf(8, encodingType.endsWith("_BE"));
bb.writeLong(((TimeExpression) valueArg).getTime());
}
break;
case "DATE_EPOCH":
case "DATE_EPOCH_BE":
if (valueArg instanceof DateExpression) {
bb = newByteBuf(8, encodingType.endsWith("_BE"));
bb.writeLong(((DateExpression) valueArg).getDate());
}
break;
case "BOOLEAN_BYTE":
if (valueArg instanceof BooleanExpression) {
bb = newByteBuf(1, false);
bb.writeByte(((BooleanExpression) valueArg).getBoolean() ? 1 : 0);
}
break;
case "DOUBLE_OB":
case "DOUBLE_OBD":
if (valueArg instanceof DoubleExpression) {
bb = newByteBuf(9, true);
PositionedByteRange br = new SimplePositionedMutableByteRange(bb.array(), 0, 9);
if (encodingType.endsWith("_OBD")) {
org.apache.hadoop.hbase.util.OrderedBytes.encodeFloat64(br, ((DoubleExpression) valueArg).getDouble(), Order.DESCENDING);
this.sortOrderAscending = false;
} else {
org.apache.hadoop.hbase.util.OrderedBytes.encodeFloat64(br, ((DoubleExpression) valueArg).getDouble(), Order.ASCENDING);
}
}
break;
case "FLOAT_OB":
case "FLOAT_OBD":
if (valueArg instanceof FloatExpression) {
bb = newByteBuf(5, true);
PositionedByteRange br = new SimplePositionedMutableByteRange(bb.array(), 0, 5);
if (encodingType.endsWith("_OBD")) {
org.apache.hadoop.hbase.util.OrderedBytes.encodeFloat32(br, ((FloatExpression) valueArg).getFloat(), Order.DESCENDING);
this.sortOrderAscending = false;
} else {
org.apache.hadoop.hbase.util.OrderedBytes.encodeFloat32(br, ((FloatExpression) valueArg).getFloat(), Order.ASCENDING);
}
}
break;
case "BIGINT_OB":
case "BIGINT_OBD":
if (valueArg instanceof LongExpression) {
bb = newByteBuf(9, true);
PositionedByteRange br = new SimplePositionedMutableByteRange(bb.array(), 0, 9);
if (encodingType.endsWith("_OBD")) {
org.apache.hadoop.hbase.util.OrderedBytes.encodeInt64(br, ((LongExpression) valueArg).getLong(), Order.DESCENDING);
this.sortOrderAscending = false;
} else {
org.apache.hadoop.hbase.util.OrderedBytes.encodeInt64(br, ((LongExpression) valueArg).getLong(), Order.ASCENDING);
}
}
break;
case "INT_OB":
case "INT_OBD":
if (valueArg instanceof IntExpression) {
bb = newByteBuf(5, true);
PositionedByteRange br = new SimplePositionedMutableByteRange(bb.array(), 0, 5);
if (encodingType.endsWith("_OBD")) {
org.apache.hadoop.hbase.util.OrderedBytes.encodeInt32(br, ((IntExpression) valueArg).getInt(), Order.DESCENDING);
this.sortOrderAscending = false;
} else {
org.apache.hadoop.hbase.util.OrderedBytes.encodeInt32(br, ((IntExpression) valueArg).getInt(), Order.ASCENDING);
}
}
break;
case "UTF8":
// let visitSchemaPath() handle this.
return e.getInput().accept(this, valueArg);
default:
bb = getByteBuf(valueArg, encodingType);
}
if (bb != null) {
this.value = bb.array();
this.path = (SchemaPath) e.getInput();
return true;
}
}
}
return false;
}
protected ByteBuf getByteBuf(LogicalExpression valueArg, String encodingType) {
return null;
}
private Boolean visitRowKeyPrefixConvertExpression(ConvertExpression e, int prefixLength, LogicalExpression valueArg) {
String encodingType = e.getEncodingType();
rowKeyPrefixStartRow = HConstants.EMPTY_START_ROW;
rowKeyPrefixStopRow = HConstants.EMPTY_START_ROW;
rowKeyPrefixFilter = null;
if ((encodingType.compareTo("UINT4_BE") == 0) || (encodingType.compareTo("UINT_BE") == 0)) {
if (prefixLength != 4) {
throw new RuntimeException("Invalid length(" + prefixLength + ") of row-key prefix");
}
int val;
if (!(valueArg instanceof IntExpression)) {
return false;
}
val = ((IntExpression) valueArg).getInt();
// For TIME_EPOCH_BE/BIGINT_BE encoding, the operators that we push-down are =, <>, <, <=, >, >=
switch(functionName) {
case "equal":
rowKeyPrefixFilter = new PrefixFilter(ByteBuffer.allocate(4).putInt(val).array());
rowKeyPrefixStartRow = ByteBuffer.allocate(4).putInt(val).array();
rowKeyPrefixStopRow = ByteBuffer.allocate(4).putInt(val + 1).array();
return true;
case "greater_than_or_equal_to":
rowKeyPrefixStartRow = ByteBuffer.allocate(4).putInt(val).array();
return true;
case "greater_than":
rowKeyPrefixStartRow = ByteBuffer.allocate(4).putInt(val + 1).array();
return true;
case "less_than_or_equal_to":
rowKeyPrefixStopRow = ByteBuffer.allocate(4).putInt(val + 1).array();
return true;
case "less_than":
rowKeyPrefixStopRow = ByteBuffer.allocate(4).putInt(val).array();
return true;
}
return false;
}
if ((encodingType.compareTo("TIMESTAMP_EPOCH_BE") == 0) || (encodingType.compareTo("TIME_EPOCH_BE") == 0) || (encodingType.compareTo("UINT8_BE") == 0)) {
if (prefixLength != 8) {
throw new RuntimeException("Invalid length(" + prefixLength + ") of row-key prefix");
}
long val;
if (encodingType.compareTo("TIME_EPOCH_BE") == 0) {
if (!(valueArg instanceof TimeExpression)) {
return false;
}
val = ((TimeExpression) valueArg).getTime();
} else if (encodingType.compareTo("UINT8_BE") == 0) {
if (!(valueArg instanceof LongExpression)) {
return false;
}
val = ((LongExpression) valueArg).getLong();
} else if (encodingType.compareTo("TIMESTAMP_EPOCH_BE") == 0) {
if (!(valueArg instanceof TimeStampExpression)) {
return false;
}
val = ((TimeStampExpression) valueArg).getTimeStamp();
} else {
// Should not reach here.
return false;
}
// For TIME_EPOCH_BE/BIGINT_BE encoding, the operators that we push-down are =, <>, <, <=, >, >=
switch(functionName) {
case "equal":
rowKeyPrefixFilter = new PrefixFilter(ByteBuffer.allocate(8).putLong(val).array());
rowKeyPrefixStartRow = ByteBuffer.allocate(8).putLong(val).array();
rowKeyPrefixStopRow = ByteBuffer.allocate(8).putLong(val + 1).array();
return true;
case "greater_than_or_equal_to":
rowKeyPrefixStartRow = ByteBuffer.allocate(8).putLong(val).array();
return true;
case "greater_than":
rowKeyPrefixStartRow = ByteBuffer.allocate(8).putLong(val + 1).array();
return true;
case "less_than_or_equal_to":
rowKeyPrefixStopRow = ByteBuffer.allocate(8).putLong(val + 1).array();
return true;
case "less_than":
rowKeyPrefixStopRow = ByteBuffer.allocate(8).putLong(val).array();
return true;
}
return false;
}
if (encodingType.compareTo("DATE_EPOCH_BE") == 0) {
if (!(valueArg instanceof DateExpression)) {
return false;
}
if (prefixLength != 8) {
throw new RuntimeException("Invalid length(" + prefixLength + ") of row-key prefix");
}
final long MILLISECONDS_IN_A_DAY = 1000 * 60 * 60 * 24;
long dateToSet;
// For DATE encoding, the operators that we push-down are =, <>, <, <=, >, >=
switch(functionName) {
case "equal":
long startDate = ((DateExpression) valueArg).getDate();
rowKeyPrefixStartRow = ByteBuffer.allocate(8).putLong(startDate).array();
long stopDate = ((DateExpression) valueArg).getDate() + MILLISECONDS_IN_A_DAY;
rowKeyPrefixStopRow = ByteBuffer.allocate(8).putLong(stopDate).array();
return true;
case "greater_than_or_equal_to":
dateToSet = ((DateExpression) valueArg).getDate();
rowKeyPrefixStartRow = ByteBuffer.allocate(8).putLong(dateToSet).array();
return true;
case "greater_than":
dateToSet = ((DateExpression) valueArg).getDate() + MILLISECONDS_IN_A_DAY;
rowKeyPrefixStartRow = ByteBuffer.allocate(8).putLong(dateToSet).array();
return true;
case "less_than_or_equal_to":
dateToSet = ((DateExpression) valueArg).getDate() + MILLISECONDS_IN_A_DAY;
rowKeyPrefixStopRow = ByteBuffer.allocate(8).putLong(dateToSet).array();
return true;
case "less_than":
dateToSet = ((DateExpression) valueArg).getDate();
rowKeyPrefixStopRow = ByteBuffer.allocate(8).putLong(dateToSet).array();
return true;
}
return false;
}
return false;
}
@Override
public Boolean visitUnknown(LogicalExpression e, LogicalExpression valueArg) throws RuntimeException {
return false;
}
@Override
public Boolean visitSchemaPath(SchemaPath path, LogicalExpression valueArg) throws RuntimeException {
if (valueArg instanceof QuotedString) {
this.value = ((QuotedString) valueArg).value.getBytes(Charsets.UTF_8);
this.path = path;
return true;
}
return false;
}
protected static ByteBuf newByteBuf(int size, boolean bigEndian) {
return Unpooled.wrappedBuffer(new byte[size]).order(bigEndian ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN).writerIndex(0);
}
private static final ImmutableSet<Clreplaced<? extends LogicalExpression>> VALUE_EXPRESSION_CLreplacedES;
static {
ImmutableSet.Builder<Clreplaced<? extends LogicalExpression>> builder = ImmutableSet.builder();
VALUE_EXPRESSION_CLreplacedES = builder.add(BooleanExpression.clreplaced).add(DateExpression.clreplaced).add(DoubleExpression.clreplaced).add(FloatExpression.clreplaced).add(IntExpression.clreplaced).add(LongExpression.clreplaced).add(QuotedString.clreplaced).add(TimeExpression.clreplaced).build();
}
private static final ImmutableMap<String, String> COMPARE_FUNCTIONS_TRANSPOSE_MAP;
static {
ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
COMPARE_FUNCTIONS_TRANSPOSE_MAP = builder.put("isnotnull", "isnotnull").put("isNotNull", "isNotNull").put("is not null", "is not null").put("isnull", "isnull").put("isNull", "isNull").put("is null", "is null").put("like", "like").put("equal", "equal").put("not_equal", "not_equal").put("greater_than_or_equal_to", "less_than_or_equal_to").put("greater_than", "less_than").put("less_than_or_equal_to", "greater_than_or_equal_to").put("less_than", "greater_than").build();
}
}
19
Source : CompareFunctionsProcessor.java
with Apache License 2.0
from zpochen
with Apache License 2.0
from zpochen
clreplaced CompareFunctionsProcessor extends AbstractExprVisitor<Boolean, LogicalExpression, RuntimeException> {
private String functionName;
private Boolean success;
private Value value;
private SchemaPath path;
public CompareFunctionsProcessor(String functionName) {
this.functionName = functionName;
this.success = false;
this.value = null;
}
public static boolean isCompareFunction(String functionName) {
return COMPARE_FUNCTIONS_TRANSPOSE_MAP.keySet().contains(functionName);
}
@Override
public Boolean visitUnknown(LogicalExpression e, LogicalExpression valueArg) throws RuntimeException {
return false;
}
public static CompareFunctionsProcessor process(FunctionCall call) {
String functionName = call.getName();
LogicalExpression nameArg = call.args.get(0);
LogicalExpression valueArg = call.args.size() >= 2 ? call.args.get(1) : null;
CompareFunctionsProcessor evaluator = new CompareFunctionsProcessor(functionName);
// if (valueArg != null) {
if (VALUE_EXPRESSION_CLreplacedES.contains(nameArg.getClreplaced())) {
LogicalExpression swapArg = valueArg;
valueArg = nameArg;
nameArg = swapArg;
evaluator.functionName = COMPARE_FUNCTIONS_TRANSPOSE_MAP.get(functionName);
}
evaluator.success = nameArg.accept(evaluator, valueArg);
// }
return evaluator;
}
public boolean isSuccess() {
// TODO Auto-generated method stub
return success;
}
public SchemaPath getPath() {
return path;
}
public Value getValue() {
return value;
}
public String getFunctionName() {
return functionName;
}
@Override
public Boolean visitSchemaPath(SchemaPath path, LogicalExpression valueArg) throws RuntimeException {
// If valueArg is null, this might be a IS NULL/IS NOT NULL type of query
if (valueArg == null) {
this.path = path;
return true;
}
if (valueArg instanceof QuotedString) {
this.value = KeyValueBuilder.initFrom(((QuotedString) valueArg).value);
this.path = path;
return true;
}
if (valueArg instanceof IntExpression) {
this.value = KeyValueBuilder.initFrom(((IntExpression) valueArg).getInt());
this.path = path;
return true;
}
if (valueArg instanceof FloatExpression) {
this.value = KeyValueBuilder.initFrom(((FloatExpression) valueArg).getFloat());
this.path = path;
return true;
}
if (valueArg instanceof BooleanExpression) {
this.value = KeyValueBuilder.initFrom(((BooleanExpression) valueArg).getBoolean());
this.path = path;
return true;
}
if (valueArg instanceof Decimal28Expression) {
this.value = KeyValueBuilder.initFrom(((Decimal28Expression) valueArg).getBigDecimal());
this.path = path;
return true;
}
if (valueArg instanceof Decimal38Expression) {
this.value = KeyValueBuilder.initFrom(((Decimal38Expression) valueArg).getBigDecimal());
this.path = path;
return true;
}
if (valueArg instanceof DoubleExpression) {
this.value = KeyValueBuilder.initFrom(((DoubleExpression) valueArg).getDouble());
this.path = path;
return true;
}
if (valueArg instanceof LongExpression) {
this.value = KeyValueBuilder.initFrom(((LongExpression) valueArg).getLong());
this.path = path;
return true;
}
if (valueArg instanceof DateExpression) {
long d = ((DateExpression) valueArg).getDate();
final long MILLISECONDS_IN_A_DAY = (long) 1000 * 60 * 60 * 24;
int daysSinceEpoch = (int) (d / MILLISECONDS_IN_A_DAY);
this.value = KeyValueBuilder.initFrom(ODate.fromDaysSinceEpoch(daysSinceEpoch));
this.path = path;
return true;
}
if (valueArg instanceof TimeExpression) {
int t = ((TimeExpression) valueArg).getTime();
LocalTime lT = LocalTime.fromMillisOfDay(t);
this.value = KeyValueBuilder.initFrom(new OTime(lT.getHourOfDay(), lT.getMinuteOfHour(), lT.getSecondOfMinute(), lT.getMillisOfSecond()));
this.path = path;
return true;
}
if (valueArg instanceof TimeStampExpression) {
// disable pushdown of TimeStampExpression type until bug 22824 is fixed.
//
// this.value = KeyValueBuilder.initFrom(new OTimestamp(((TimeStampExpression)valueArg).getTimeStamp()));
// this.path = path;
// return true;
}
return false;
}
private static final ImmutableSet<Clreplaced<? extends LogicalExpression>> VALUE_EXPRESSION_CLreplacedES;
static {
ImmutableSet.Builder<Clreplaced<? extends LogicalExpression>> builder = ImmutableSet.builder();
VALUE_EXPRESSION_CLreplacedES = builder.add(BooleanExpression.clreplaced).add(DateExpression.clreplaced).add(DoubleExpression.clreplaced).add(FloatExpression.clreplaced).add(IntExpression.clreplaced).add(LongExpression.clreplaced).add(QuotedString.clreplaced).add(TimeExpression.clreplaced).build();
}
private static final ImmutableMap<String, String> COMPARE_FUNCTIONS_TRANSPOSE_MAP;
static {
ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
COMPARE_FUNCTIONS_TRANSPOSE_MAP = builder.put("isnotnull", "isnotnull").put("isNotNull", "isNotNull").put("is not null", "is not null").put("isnull", "isnull").put("isNull", "isNull").put("is null", "is null").put("like", "like").put("equal", "equal").put("not_equal", "not_equal").put("greater_than_or_equal_to", "less_than_or_equal_to").put("greater_than", "less_than").put("less_than_or_equal_to", "greater_than_or_equal_to").put("less_than", "greater_than").build();
}
}
19
Source : DrillProperties.java
with Apache License 2.0
from zpochen
with Apache License 2.0
from zpochen
public final clreplaced DrillProperties extends Properties {
private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DrillProperties.clreplaced);
// PROPERTY KEYS
// definitions should be in lowercase
public static final String ZOOKEEPER_CONNECTION = "zk";
public static final String DRILLBIT_CONNECTION = "drillbit";
// "tries" is max number of unique drillbits to try connecting
// until successfully connected to one of them
public static final String TRIES = "tries";
public static final String SCHEMA = "schema";
public static final String USER = "user";
public static final String PreplacedWORD = "preplacedword";
public static final String IMPERSONATION_TARGET = "impersonation_target";
public static final String AUTH_MECHANISM = "auth";
public static final String SERVICE_PRINCIPAL = "principal";
public static final String SERVICE_NAME = "service_name";
public static final String SERVICE_HOST = "service_host";
public static final String REALM = "realm";
public static final String KEYTAB = "keytab";
public static final String SASL_ENCRYPT = "sasl_encrypt";
// Should only be used for testing backward compatibility
@VisibleForTesting
public static final String TEST_SASL_LEVEL = "test_sasl_level";
// for subject that has pre-authenticated to KDC (AS) i.e. required credentials are populated in
// Subject's credentials set
public static final String KERBEROS_FROM_SUBJECT = "from_subject";
public static final String QUOTING_IDENTIFIERS = "quoting_identifiers";
// Although all properties from the application are sent to the server (from the client), the following
// sets of properties are used by the client and server respectively. These are reserved words.
public static final ImmutableSet<String> ALLOWED_BY_CLIENT = ImmutableSet.of(ZOOKEEPER_CONNECTION, DRILLBIT_CONNECTION, TRIES, SCHEMA, USER, PreplacedWORD, IMPERSONATION_TARGET, AUTH_MECHANISM, SERVICE_PRINCIPAL, SERVICE_NAME, SERVICE_HOST, REALM, KEYTAB, KERBEROS_FROM_SUBJECT);
public static final ImmutableSet<String> ACCEPTED_BY_SERVER = ImmutableSet.of(USER, /**
* deprecated
*/
PreplacedWORD, /**
* deprecated
*/
SCHEMA, IMPERSONATION_TARGET, QUOTING_IDENTIFIERS);
private DrillProperties() {
}
@Override
public Object setProperty(final String key, final String value) {
return super.setProperty(key.toLowerCase(), value);
}
@Override
public String getProperty(final String key) {
return super.getProperty(key.toLowerCase());
}
@Override
public String getProperty(final String key, final String defaultValue) {
return super.getProperty(key.toLowerCase(), defaultValue);
}
public void merge(final Properties overrides) {
if (overrides == null) {
return;
}
for (final String key : overrides.stringPropertyNames()) {
setProperty(key.toLowerCase(), overrides.getProperty(key));
}
}
public void merge(final Map<String, String> overrides) {
if (overrides == null) {
return;
}
for (final String key : overrides.keySet()) {
setProperty(key.toLowerCase(), overrides.get(key));
}
}
/**
* Returns a map of keys and values in this property list where the key and its corresponding value are strings,
* including distinct keys in the default property list if a key of the same name has not already been found from
* the main properties list. Properties whose key or value is not of type <tt>String</tt> are omitted.
* <p>
* The returned map is not backed by the <tt>Properties</tt> object. Changes to this <tt>Properties</tt> are not
* reflected in the map, or vice versa.
*
* @return a map of keys and values in this property list where the key and its corresponding value are strings,
* including the keys in the default property list.
*/
public Map<String, String> stringPropertiesAsMap() {
final Map<String, String> map = new HashMap<>();
for (final String property : stringPropertyNames()) {
map.put(property, getProperty(property));
}
return map;
}
/**
* Serializes properties into a protobuf message.
*
* @return the serialized properties
*/
public UserProperties serializeForServer() {
final UserProperties.Builder propsBuilder = UserProperties.newBuilder();
for (final String key : stringPropertyNames()) {
propsBuilder.addProperties(Property.newBuilder().setKey(key).setValue(getProperty(key)).build());
}
return propsBuilder.build();
}
/**
* Deserializes the given properties into DrillProperties.
*
* @param userProperties serialized user properties
* @param addOnlyKnownServerProperties add only properties known by server
* @return params
*/
public static DrillProperties createFromProperties(final UserProperties userProperties, final boolean addOnlyKnownServerProperties) {
final DrillProperties properties = new DrillProperties();
for (final Property property : userProperties.getPropertiesList()) {
final String key = property.getKey().toLowerCase();
if (!addOnlyKnownServerProperties || ACCEPTED_BY_SERVER.contains(key)) {
properties.setProperty(key, property.getValue());
} else {
logger.trace("Server does not recognize property: {}", key);
}
}
return properties;
}
/**
* Returns a new instance of DrillProperties from the given properties.
*
* @param properties user properties
* @return params
*/
public static DrillProperties createFromProperties(final Properties properties) {
final DrillProperties drillProperties = new DrillProperties();
if (properties != null) {
for (final String key : properties.stringPropertyNames()) {
final String lowerCaseKey = key.toLowerCase();
drillProperties.setProperty(lowerCaseKey, properties.getProperty(key));
}
}
return drillProperties;
}
public static DrillProperties createEmpty() {
return new DrillProperties();
}
}
19
Source : Property.java
with Apache License 2.0
from ZacSweers
with Apache License 2.0
from ZacSweers
public clreplaced Property {
public final String methodName;
public final String humanName;
public final ExecutableElement element;
public final TypeName type;
public final ImmutableSet<String> annotations;
public Property(String humanName, ExecutableElement element) {
this.methodName = element.getSimpleName().toString();
this.humanName = humanName;
this.element = element;
type = TypeName.get(element.getReturnType());
annotations = buildAnnotations(element);
}
@Nullable
static TypeMirror getAnnotationValue(Element foo, Clreplaced<?> annotation) {
AnnotationMirror am = getAnnotationMirror(foo, annotation);
if (am == null) {
return null;
}
AnnotationValue av = getAnnotationValue(am, "value");
return av == null ? null : (TypeMirror) av.getValue();
}
@Nullable
private static AnnotationMirror getAnnotationMirror(Element typeElement, Clreplaced<?> clazz) {
String clazzName = clazz.getName();
for (AnnotationMirror m : typeElement.getAnnotationMirrors()) {
if (m.getAnnotationType().toString().equals(clazzName)) {
return m;
}
}
return null;
}
@Nullable
private static AnnotationValue getAnnotationValue(AnnotationMirror annotationMirror, String key) {
Map<? extends ExecutableElement, ? extends AnnotationValue> values = annotationMirror.getElementValues();
for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : values.entrySet()) {
if (entry.getKey().getSimpleName().toString().equals(key)) {
return entry.getValue();
}
}
return null;
}
@Nullable
public <T extends Annotation> T annotation(Clreplaced<T> annotation) {
return element.getAnnotation(annotation);
}
@Nullable
public ValidatedBy validatedBy() {
return element.getAnnotation(ValidatedBy.clreplaced);
}
@Nullable
public AnnotationMirror validatedByMirror() {
return getAnnotationMirror(element, ValidatedBy.clreplaced);
}
public boolean shouldValidate() {
return element.getAnnotation(InspectorIgnored.clreplaced) == null && validatedBy() == null;
}
private ImmutableSet<String> buildAnnotations(ExecutableElement element) {
ImmutableSet.Builder<String> builder = ImmutableSet.builder();
List<? extends AnnotationMirror> annotations = element.getAnnotationMirrors();
for (AnnotationMirror annotation : annotations) {
builder.add(annotation.getAnnotationType().asElement().getSimpleName().toString());
}
return builder.build();
}
}
19
Source : ImmutableAnnotationEncodedValue.java
with GNU General Public License v3.0
from yuanxzhang
with GNU General Public License v3.0
from yuanxzhang
public clreplaced ImmutableAnnotationEncodedValue extends BaseAnnotationEncodedValue implements ImmutableEncodedValue {
@Nonnull
protected final String type;
@Nonnull
protected final ImmutableSet<? extends ImmutableAnnotationElement> elements;
public ImmutableAnnotationEncodedValue(@Nonnull String type, @Nullable Collection<? extends AnnotationElement> elements) {
this.type = type;
this.elements = ImmutableAnnotationElement.immutableSetOf(elements);
}
public ImmutableAnnotationEncodedValue(@Nonnull String type, @Nullable ImmutableSet<? extends ImmutableAnnotationElement> elements) {
this.type = type;
this.elements = ImmutableUtils.nullToEmptySet(elements);
}
public static ImmutableAnnotationEncodedValue of(AnnotationEncodedValue annotationEncodedValue) {
if (annotationEncodedValue instanceof ImmutableAnnotationEncodedValue) {
return (ImmutableAnnotationEncodedValue) annotationEncodedValue;
}
return new ImmutableAnnotationEncodedValue(annotationEncodedValue.getType(), annotationEncodedValue.getElements());
}
@Nonnull
@Override
public String getType() {
return type;
}
@Nonnull
@Override
public ImmutableSet<? extends ImmutableAnnotationElement> getElements() {
return elements;
}
}
19
Source : ImmutableAnnotation.java
with GNU General Public License v3.0
from yuanxzhang
with GNU General Public License v3.0
from yuanxzhang
public clreplaced ImmutableAnnotation extends BaseAnnotation {
protected final int visibility;
@Nonnull
protected final String type;
@Nonnull
protected final ImmutableSet<? extends ImmutableAnnotationElement> elements;
public ImmutableAnnotation(int visibility, @Nonnull String type, @Nullable Collection<? extends AnnotationElement> elements) {
this.visibility = visibility;
this.type = type;
this.elements = ImmutableAnnotationElement.immutableSetOf(elements);
}
public ImmutableAnnotation(int visibility, @Nonnull String type, @Nullable ImmutableSet<? extends ImmutableAnnotationElement> elements) {
this.visibility = visibility;
this.type = type;
this.elements = ImmutableUtils.nullToEmptySet(elements);
}
public static ImmutableAnnotation of(Annotation annotation) {
if (annotation instanceof ImmutableAnnotation) {
return (ImmutableAnnotation) annotation;
}
return new ImmutableAnnotation(annotation.getVisibility(), annotation.getType(), annotation.getElements());
}
@Override
public int getVisibility() {
return visibility;
}
@Nonnull
@Override
public String getType() {
return type;
}
@Nonnull
@Override
public ImmutableSet<? extends ImmutableAnnotationElement> getElements() {
return elements;
}
@Nonnull
public static ImmutableSet<ImmutableAnnotation> immutableSetOf(@Nullable Iterable<? extends Annotation> list) {
return CONVERTER.toSet(list);
}
private static final ImmutableConverter<ImmutableAnnotation, Annotation> CONVERTER = new ImmutableConverter<ImmutableAnnotation, Annotation>() {
@Override
protected boolean isImmutable(@Nonnull Annotation item) {
return item instanceof ImmutableAnnotation;
}
@Nonnull
@Override
protected ImmutableAnnotation makeImmutable(@Nonnull Annotation item) {
return ImmutableAnnotation.of(item);
}
};
}
19
Source : TypeCheckers.java
with Apache License 2.0
from yahoo
with Apache License 2.0
from yahoo
public final clreplaced TypeCheckers {
public static final TypeLiteral<List<String>> LIST_OF_STRING = new TypeLiteral<List<String>>() {
};
public static final TypeLiteral<List<List<String>>> LIST_OF_LIST_OF_STRING = new TypeLiteral<List<List<String>>>() {
};
public static final TypeLiteral<List<OperatorNode<SequenceOperator>>> SEQUENCES = new TypeLiteral<List<OperatorNode<SequenceOperator>>>() {
};
public static final TypeLiteral<List<OperatorNode<ExpressionOperator>>> EXPRS = new TypeLiteral<List<OperatorNode<ExpressionOperator>>>() {
};
public static final TypeLiteral<List<List<OperatorNode<ExpressionOperator>>>> LIST_OF_EXPRS = new TypeLiteral<List<List<OperatorNode<ExpressionOperator>>>>() {
};
public static final ImmutableSet<Clreplaced<?>> LITERAL_TYPES = ImmutableSet.<Clreplaced<?>>builder().add(String.clreplaced).add(Integer.clreplaced).add(Double.clreplaced).add(Boolean.clreplaced).add(Float.clreplaced).add(Byte.clreplaced).add(Long.clreplaced).add(List.clreplaced).add(Map.clreplaced).build();
private TypeCheckers() {
}
public static ArgumentsTypeChecker make(Operator target, Object... types) {
// Clreplaced<?> extends Operator -> NodeTypeChecker
if (types == null) {
types = new Object[0];
}
List<OperatorTypeChecker> checkers = Lists.newArrayListWithCapacity(types.length);
for (int i = 0; i < types.length; ++i) {
checkers.add(createChecker(target, i, types[i]));
}
return new ArgumentsTypeChecker(target, checkers);
}
// this is festooned with instance checkes before all the casting
@SuppressWarnings("unchecked")
private static OperatorTypeChecker createChecker(Operator parent, int idx, Object value) {
if (value instanceof TypeLiteral) {
TypeLiteral<?> lit = (TypeLiteral<?>) value;
Clreplaced<?> raw = lit.getRawType();
if (List.clreplaced.isreplacedignableFrom(raw)) {
Preconditions.checkArgument(lit.getType() instanceof ParameterizedType, "TypeLiteral without a ParameterizedType for List");
ParameterizedType type = (ParameterizedType) lit.getType();
TypeLiteral<?> arg = TypeLiteral.get(type.getActualTypeArguments()[0]);
if (OperatorNode.clreplaced.isreplacedignableFrom(arg.getRawType())) {
Preconditions.checkArgument(arg.getType() instanceof ParameterizedType, "Type spec must be List<OperatorNode<?>>");
Clreplaced<? extends Operator> optype = (Clreplaced<? extends Operator>) TypeLiteral.get(((ParameterizedType) arg.getType()).getActualTypeArguments()[0]).getRawType();
return new OperatorNodeListTypeChecker(parent, idx, optype, ImmutableSet.<Operator>of());
} else {
return new JavaListTypeChecker(parent, idx, arg.getRawType());
}
}
throw new IllegalArgumentException("don't know how to handle TypeLiteral " + value);
}
if (value instanceof Clreplaced) {
Clreplaced<?> clazz = (Clreplaced<?>) value;
if (Operator.clreplaced.isreplacedignableFrom(clazz)) {
return new NodeTypeChecker(parent, idx, (Clreplaced<? extends Operator>) clazz, ImmutableSet.<Operator>of());
} else {
return new JavaTypeChecker(parent, idx, clazz);
}
} else if (value instanceof Operator) {
Operator operator = (Operator) value;
Clreplaced<? extends Operator> clazz = operator.getClreplaced();
Set<? extends Operator> allowed;
if (Enum.clreplaced.isInstance(value)) {
Clreplaced<? extends Enum> enumClazz = (Clreplaced<? extends Enum>) clazz;
allowed = (Set<? extends Operator>) EnumSet.of(enumClazz.cast(value));
} else {
allowed = ImmutableSet.of(operator);
}
return new NodeTypeChecker(parent, idx, clazz, allowed);
} else if (value instanceof EnumSet) {
EnumSet<?> v = (EnumSet<?>) value;
Enum elt = Iterables.get(v, 0);
if (elt instanceof Operator) {
Clreplaced<? extends Operator> opclreplaced = (Clreplaced<? extends Operator>) elt.getClreplaced();
Set<? extends Operator> allowed = (Set<? extends Operator>) v;
return new NodeTypeChecker(parent, idx, opclreplaced, allowed);
}
} else if (value instanceof Set) {
// Set<Clreplaced<?>>
return new JavaUnionTypeChecker(parent, idx, (Set<Clreplaced<?>>) value);
}
throw new IllegalArgumentException("I don't know how to create a checker from " + value);
}
}
19
Source : NPCContainer.java
with GNU General Public License v3.0
from xKylee
with GNU General Public License v3.0
from xKylee
@Getter(AccessLevel.PACKAGE)
clreplaced NPCContainer {
@Getter(AccessLevel.PACKAGE)
private final NPC npc;
private final int npcIndex;
private final String npcName;
private final ImmutableSet<Integer> animations;
private final int attackSpeed;
@Getter(AccessLevel.PACKAGE)
private final BossMonsters monsterType;
private int npcSize;
@Setter(AccessLevel.PACKAGE)
private int ticksUntilAttack;
@Setter(AccessLevel.PACKAGE)
private Actor npcInteracting;
@Setter(AccessLevel.PACKAGE)
private AttackStyle attackStyle;
NPCContainer(final NPC npc, final int attackSpeed) {
this.npc = npc;
this.npcName = npc.getName();
this.npcIndex = npc.getIndex();
this.npcInteracting = npc.getInteracting();
this.attackStyle = AttackStyle.UNKNOWN;
this.attackSpeed = attackSpeed;
this.ticksUntilAttack = -1;
final NPCComposition composition = npc.getTransformedComposition();
BossMonsters monster = BossMonsters.of(npc.getId());
if (monster == null) {
throw new IllegalStateException();
}
this.monsterType = monster;
this.animations = monster.animations;
this.attackStyle = monster.attackStyle;
if (composition != null) {
this.npcSize = composition.getSize();
}
}
@Override
public int hashCode() {
return Objects.hash(npc);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClreplaced() != o.getClreplaced()) {
return false;
}
NPCContainer that = (NPCContainer) o;
return Objects.equals(npc, that.npc);
}
@RequiredArgsConstructor
enum BossMonsters {
SERGEANT_STRONGSTACK(NpcID.SERGEANT_STRONGSTACK, AttackStyle.MELEE, ImmutableSet.of(MINION_AUTO1, MINION_AUTO2, MINION_AUTO3)),
SERGEANT_STEELWILL(NpcID.SERGEANT_STEELWILL, AttackStyle.MAGE, ImmutableSet.of(MINION_AUTO1, MINION_AUTO2, MINION_AUTO3)),
SERGEANT_GRIMSPIKE(NpcID.SERGEANT_GRIMSPIKE, AttackStyle.RANGE, ImmutableSet.of(MINION_AUTO1, MINION_AUTO2, MINION_AUTO4)),
GENERAL_GRAARDOR(NpcID.GENERAL_GRAARDOR, AttackStyle.MELEE, ImmutableSet.of(GENERAL_AUTO1, GENERAL_AUTO2, GENERAL_AUTO3)),
TSTANON_KARLAK(NpcID.TSTANON_KARLAK, AttackStyle.MELEE, ImmutableSet.of(ZAMMY_GENERIC_AUTO)),
BALFRUG_KREEYATH(NpcID.BALFRUG_KREEYATH, AttackStyle.MAGE, ImmutableSet.of(ZAMMY_GENERIC_AUTO, BALFRUG_AUTO)),
ZAKLN_GRITCH(NpcID.ZAKLN_GRITCH, AttackStyle.RANGE, ImmutableSet.of(ZAMMY_GENERIC_AUTO, ZAKL_AUTO)),
KRIL_TSUTSAROTH(NpcID.KRIL_TSUTSAROTH, AttackStyle.UNKNOWN, ImmutableSet.of(KRIL_SPEC, KRIL_AUTO)),
STARLIGHT(NpcID.STARLIGHT, AttackStyle.MELEE, ImmutableSet.of(STARLIGHT_AUTO)),
GROWLER(NpcID.GROWLER, AttackStyle.MAGE, ImmutableSet.of(GROWLER_AUTO)),
BREE(NpcID.BREE, AttackStyle.RANGE, ImmutableSet.of(BREE_AUTO)),
COMMANDER_ZILYANA(NpcID.COMMANDER_ZILYANA, AttackStyle.UNKNOWN, ImmutableSet.of(ZILYANA_AUTO, ZILYANA_MELEE_AUTO, ZILYANA_SPEC)),
FLIGHT_KILISA(NpcID.FLIGHT_KILISA, AttackStyle.MELEE, ImmutableSet.of(KILISA_AUTO)),
FLOCKLEADER_GEERIN(NpcID.FLOCKLEADER_GEERIN, AttackStyle.RANGE, ImmutableSet.of(GEERIN_AUTO, GEERIN_FLINCH)),
WINGMAN_SKREE(NpcID.WINGMAN_SKREE, AttackStyle.MAGE, ImmutableSet.of(SKREE_AUTO)),
KREEARRA(NpcID.KREEARRA, AttackStyle.RANGE, ImmutableSet.of(KREE_RANGED));
private static final ImmutableMap<Integer, BossMonsters> idMap;
static {
ImmutableMap.Builder<Integer, BossMonsters> builder = ImmutableMap.builder();
for (BossMonsters monster : values()) {
builder.put(monster.npcID, monster);
}
idMap = builder.build();
}
private final int npcID;
private final AttackStyle attackStyle;
private final ImmutableSet<Integer> animations;
static BossMonsters of(int npcID) {
return idMap.get(npcID);
}
}
@AllArgsConstructor
@Getter
public enum AttackStyle {
MAGE("Mage", Color.CYAN, Prayer.PROTECT_FROM_MAGIC), RANGE("Range", Color.GREEN, Prayer.PROTECT_FROM_MISSILES), MELEE("Melee", Color.RED, Prayer.PROTECT_FROM_MELEE), UNKNOWN("Unknown", Color.WHITE, null);
private String name;
private Color color;
private Prayer prayer;
}
}
19
Source : FightCaveContainer.java
with GNU General Public License v3.0
from xKylee
with GNU General Public License v3.0
from xKylee
@Getter(AccessLevel.PACKAGE)
clreplaced FightCaveContainer {
private NPC npc;
private String npcName;
private int npcIndex;
private int npcSize;
private int attackSpeed;
private int priority;
private ImmutableSet<Integer> animations;
@Setter(AccessLevel.PACKAGE)
private int ticksUntilAttack;
@Setter(AccessLevel.PACKAGE)
private Actor npcInteracting;
@Setter(AccessLevel.PACKAGE)
private AttackStyle attackStyle;
FightCaveContainer(NPC npc, int attackSpeed) {
this.npc = npc;
this.npcName = npc.getName();
this.npcIndex = npc.getIndex();
this.npcInteracting = npc.getInteracting();
this.attackStyle = AttackStyle.UNKNOWN;
this.attackSpeed = attackSpeed;
this.ticksUntilAttack = -1;
final NPCComposition composition = npc.getTransformedComposition();
BossMonsters monster = BossMonsters.of(npc.getId());
if (monster == null) {
throw new IllegalStateException();
}
this.animations = monster.animations;
this.attackStyle = monster.attackStyle;
this.priority = monster.priority;
if (composition != null) {
this.npcSize = composition.getSize();
}
}
@RequiredArgsConstructor
enum BossMonsters {
TOK_XIL1(NpcID.TOKXIL_3121, AttackStyle.RANGE, ImmutableSet.of(TOK_XIL_RANGE_ATTACK, TOK_XIL_MELEE_ATTACK), 1),
TOK_XIL2(NpcID.TOKXIL_3122, AttackStyle.RANGE, ImmutableSet.of(TOK_XIL_RANGE_ATTACK, TOK_XIL_MELEE_ATTACK), 1),
KETZEK1(NpcID.KETZEK, AttackStyle.MAGE, ImmutableSet.of(KET_ZEK_MAGE_ATTACK, KET_ZEK_MELEE_ATTACK), 0),
KETZEK2(NpcID.KETZEK_3126, AttackStyle.MAGE, ImmutableSet.of(KET_ZEK_MAGE_ATTACK, KET_ZEK_MELEE_ATTACK), 0),
YTMEJKOT1(NpcID.YTMEJKOT, AttackStyle.MELEE, ImmutableSet.of(MEJ_KOT_HEAL_ATTACK, MEJ_KOT_MELEE_ATTACK), 2),
YTMEJKOT2(NpcID.YTMEJKOT_3124, AttackStyle.MELEE, ImmutableSet.of(MEJ_KOT_HEAL_ATTACK, MEJ_KOT_MELEE_ATTACK), 2),
TZTOKJAD1(NpcID.TZTOKJAD, AttackStyle.UNKNOWN, ImmutableSet.of(TZTOK_JAD_MAGIC_ATTACK, TZTOK_JAD_RANGE_ATTACK, TZTOK_JAD_MELEE_ATTACK), 0),
TZTOKJAD2(NpcID.TZTOKJAD_6506, AttackStyle.UNKNOWN, ImmutableSet.of(TZTOK_JAD_MAGIC_ATTACK, TZTOK_JAD_RANGE_ATTACK, TZTOK_JAD_MELEE_ATTACK), 0);
private static final ImmutableMap<Integer, BossMonsters> idMap;
static {
ImmutableMap.Builder<Integer, BossMonsters> builder = ImmutableMap.builder();
for (BossMonsters monster : values()) {
builder.put(monster.npcID, monster);
}
idMap = builder.build();
}
private final int npcID;
private final AttackStyle attackStyle;
private final ImmutableSet<Integer> animations;
private final int priority;
static BossMonsters of(int npcID) {
return idMap.get(npcID);
}
}
@Getter(AccessLevel.PACKAGE)
@AllArgsConstructor
enum AttackStyle {
MAGE("Mage", Color.CYAN, Prayer.PROTECT_FROM_MAGIC), RANGE("Range", Color.GREEN, Prayer.PROTECT_FROM_MISSILES), MELEE("Melee", Color.RED, Prayer.PROTECT_FROM_MELEE), UNKNOWN("Unknown", Color.WHITE, null);
private String name;
private Color color;
private Prayer prayer;
}
}
19
Source : PeepholeSubstituteAlternateSyntax.java
with GNU General Public License v2.0
from xgdsmileboy
with GNU General Public License v2.0
from xgdsmileboy
/**
* A peephole optimization that minimizes code by simplifying conditional
* expressions, replacing IFs with HOOKs, replacing object constructors
* with literals, and simplifying returns.
*/
public clreplaced PeepholeSubsreplaceduteAlternateSyntax extends AbstractPeepholeOptimization {
private static final int AND_PRECEDENCE = NodeUtil.precedence(Token.AND);
private static final int OR_PRECEDENCE = NodeUtil.precedence(Token.OR);
static final DiagnosticType INVALID_REGULAR_EXPRESSION_FLAGS = DiagnosticType.error("JSC_INVALID_REGULAR_EXPRESSION_FLAGS", "Invalid flags to RegExp constructor: {0}");
static final Predicate<Node> DONT_TRAVERSE_FUNCTIONS_PREDICATE = new Predicate<Node>() {
@Override
public boolean apply(Node input) {
return input.getType() != Token.FUNCTION;
}
};
/**
* Tries apply our various peephole minimizations on the preplaceded in node.
*/
@Override
@SuppressWarnings("fallthrough")
public Node optimizeSubtree(Node node) {
switch(node.getType()) {
case Token.RETURN:
return tryReduceReturn(node);
case Token.NOT:
tryMinimizeCondition(node.getFirstChild());
return tryMinimizeNot(node);
case Token.IF:
tryMinimizeCondition(node.getFirstChild());
return tryMinimizeIf(node);
case Token.EXPR_RESULT:
tryMinimizeCondition(node.getFirstChild());
return node;
case Token.HOOK:
tryMinimizeCondition(node.getFirstChild());
return node;
case Token.WHILE:
case Token.DO:
tryMinimizeCondition(NodeUtil.getConditionExpression(node));
return node;
case Token.FOR:
if (!NodeUtil.isForIn(node)) {
tryMinimizeCondition(NodeUtil.getConditionExpression(node));
}
return node;
case Token.NEW:
node = tryFoldStandardConstructors(node);
if (node.getType() != Token.CALL) {
return node;
}
// Fall through on purpose because tryFoldStandardConstructors() may
// convert a NEW node into a CALL node
case Token.CALL:
return tryFoldLiteralConstructor(node);
default:
// Nothing changed
return node;
}
}
/**
* Reduce "return undefined" or "return void 0" to simply "return".
*
* Returns the replacement for n, or the original if no change was made.
*/
private Node tryReduceReturn(Node n) {
Node result = n.getFirstChild();
boolean possibleException = result != null && ControlFlowreplacedysis.mayThrowException(result);
// Try to use a subsreplacedute that with a break because it is shorter.
// First lets pretend it is a break with no labels.
Node breakTarget = n;
boolean safe = true;
for (; !ControlFlowreplacedysis.isBreakTarget(breakTarget, null); breakTarget = breakTarget.getParent()) {
if (NodeUtil.isFunction(breakTarget) || breakTarget.getType() == Token.SCRIPT) {
// We can switch the return to a break if the return value has
// side effect and it must encounter a finally.
// example: return alert('a') -> finally { alert('b') } ->
// return alert('a')
// prints a then b. If the first return is a break,
// it prints b then a.
safe = false;
break;
}
}
Node follow = ControlFlowreplacedysis.computeFollowNode(breakTarget);
// Skip preplaced all the finally blocks because both the break and return will
// also trigger all the finally blocks. However, the order of execution is
// slightly changed. Consider:
//
// return a() -> finally { b() } -> return a()
//
// which would call a() first. However, changing the first return to a
// break will result in calling b().
while (follow != null && NodeUtil.isTryFinallyNode(follow.getParent(), follow)) {
if (result != null && // TODO(user): Use the new side effects API for more accuracy.
(NodeUtil.canBeSideEffected(result) || NodeUtil.mayHaveSideEffects(result))) {
safe = false;
break;
}
follow = ControlFlowreplacedysis.computeFollowNode(follow);
}
if (safe) {
if (follow == null) {
// When follow is null, this mean the follow of a break target is the
// end of a function. This means a break is same as return.
if (result == null) {
n.setType(Token.BREAK);
reportCodeChange();
return n;
}
} else if (follow.getType() == Token.RETURN && (result == follow.getFirstChild() || (result != null && follow.hasChildren() && result.checkTreeEqualsSilent(follow.getFirstChild())) && ControlFlowreplacedysis.getExceptionHandler(n) == ControlFlowreplacedysis.getExceptionHandler(follow))) {
// When the follow is a return, if both doesn't return anything
// or both returns the same thing. This mean we can replace it with a
// break.
n.removeChildren();
n.setType(Token.BREAK);
reportCodeChange();
return n;
}
// If any of the above is executed, we must return because n is no longer
// a "return" node.
}
// TODO(user): consider cases such as if (x) { return 1} return 1;
if (result != null) {
switch(result.getType()) {
case Token.VOID:
Node operand = result.getFirstChild();
if (!mayHaveSideEffects(operand)) {
n.removeFirstChild();
reportCodeChange();
}
break;
case Token.NAME:
String name = result.getString();
if (name.equals("undefined")) {
n.removeFirstChild();
reportCodeChange();
}
break;
default:
// Do nothing
break;
}
}
return n;
}
/**
* Try to minimize NOT nodes such as !(x==y).
*
* Returns the replacement for n or the original if no change was made
*/
private Node tryMinimizeNot(Node n) {
Node parent = n.getParent();
Node notChild = n.getFirstChild();
// negative operator of the current one : == -> != for instance.
int complementOperator;
switch(notChild.getType()) {
case Token.EQ:
complementOperator = Token.NE;
break;
case Token.NE:
complementOperator = Token.EQ;
break;
case Token.SHEQ:
complementOperator = Token.SHNE;
break;
case Token.SHNE:
complementOperator = Token.SHEQ;
break;
// GT, GE, LT, LE are not handled in this because !(x<NaN) != x>=NaN.
default:
return n;
}
Node newOperator = n.removeFirstChild();
newOperator.setType(complementOperator);
parent.replaceChild(n, newOperator);
reportCodeChange();
return newOperator;
}
/**
* Try turning IF nodes into smaller HOOKs
*
* Returns the replacement for n or the original if no replacement was
* necessary.
*/
private Node tryMinimizeIf(Node n) {
Node parent = n.getParent();
Node cond = n.getFirstChild();
/* If the condition is a literal, we'll let other
* optimizations try to remove useless code.
*/
if (NodeUtil.isLiteralValue(cond, true)) {
return n;
}
Node thenBranch = cond.getNext();
Node elseBranch = thenBranch.getNext();
if (elseBranch == null) {
if (isFoldableExpressBlock(thenBranch)) {
Node expr = getBlockExpression(thenBranch);
if (isPropertyreplacedignmentInExpression(expr)) {
// Keep opportunities for CollapseProperties such as
// a.longIdentifier || a.longIdentifier = ... -> var a = ...;
return n;
}
if (cond.getType() == Token.NOT) {
// if(!x)bar(); -> x||bar();
if (isLowerPrecedenceInExpression(cond, OR_PRECEDENCE) && isLowerPrecedenceInExpression(expr.getFirstChild(), OR_PRECEDENCE)) {
// It's not okay to add two sets of parentheses.
return n;
}
Node or = new Node(Token.OR, cond.removeFirstChild(), expr.removeFirstChild()).copyInformationFrom(n);
Node newExpr = NodeUtil.newExpr(or);
parent.replaceChild(n, newExpr);
reportCodeChange();
return newExpr;
}
// if(x)foo(); -> x&&foo();
if (isLowerPrecedenceInExpression(cond, AND_PRECEDENCE) || isLowerPrecedenceInExpression(expr.getFirstChild(), AND_PRECEDENCE)) {
// One additional set of parentheses isn't worth it.
return n;
}
n.removeChild(cond);
Node and = new Node(Token.AND, cond, expr.removeFirstChild()).copyInformationFrom(n);
Node newExpr = NodeUtil.newExpr(and);
parent.replaceChild(n, newExpr);
reportCodeChange();
return newExpr;
}
return n;
}
/* TODO(dcc) This modifies the siblings of n, which is undesirable for a
* peephole optimization. This should probably get moved to another preplaced.
*/
tryRemoveRepeatedStatements(n);
// if(!x)foo();else bar(); -> if(x)bar();else foo();
// An additional set of curly braces isn't worth it.
if (cond.getType() == Token.NOT && !consumesDanglingElse(elseBranch)) {
n.replaceChild(cond, cond.removeFirstChild());
n.removeChild(thenBranch);
n.addChildToBack(thenBranch);
reportCodeChange();
return n;
}
// if(x)return 1;else return 2; -> return x?1:2;
if (isReturnExpressBlock(thenBranch) && isReturnExpressBlock(elseBranch)) {
Node thenExpr = getBlockReturnExpression(thenBranch);
Node elseExpr = getBlockReturnExpression(elseBranch);
n.removeChild(cond);
thenExpr.detachFromParent();
elseExpr.detachFromParent();
// note - we ignore any cases with "return;", technically this
// can be converted to "return undefined;" or some variant, but
// that does not help code size.
Node hookNode = new Node(Token.HOOK, cond, thenExpr, elseExpr).copyInformationFrom(n);
Node returnNode = new Node(Token.RETURN, hookNode);
parent.replaceChild(n, returnNode);
reportCodeChange();
return returnNode;
}
boolean thenBranchIsExpressionBlock = isFoldableExpressBlock(thenBranch);
boolean elseBranchIsExpressionBlock = isFoldableExpressBlock(elseBranch);
if (thenBranchIsExpressionBlock && elseBranchIsExpressionBlock) {
Node thenOp = getBlockExpression(thenBranch).getFirstChild();
Node elseOp = getBlockExpression(elseBranch).getFirstChild();
if (thenOp.getType() == elseOp.getType()) {
// if(x)a=1;else a=2; -> a=x?1:2;
if (NodeUtil.isreplacedignmentOp(thenOp)) {
Node lhs = thenOp.getFirstChild();
if (areNodesEqualForInlining(lhs, elseOp.getFirstChild()) && // if LHS has side effects, don't proceed [since the optimization
// evaluates LHS before cond]
// NOTE - there are some cirreplacedstances where we can
// proceed even if there are side effects...
!mayEffectMutableState(lhs)) {
n.removeChild(cond);
Node replacedignName = thenOp.removeFirstChild();
Node thenExpr = thenOp.removeFirstChild();
Node elseExpr = elseOp.getLastChild();
elseOp.removeChild(elseExpr);
Node hookNode = new Node(Token.HOOK, cond, thenExpr, elseExpr).copyInformationFrom(n);
Node replacedign = new Node(thenOp.getType(), replacedignName, hookNode).copyInformationFrom(thenOp);
Node expr = NodeUtil.newExpr(replacedign);
parent.replaceChild(n, expr);
reportCodeChange();
return expr;
}
} else if (NodeUtil.isCall(thenOp)) {
// if(x)foo();else bar(); -> x?foo():bar()
n.removeChild(cond);
thenOp.detachFromParent();
elseOp.detachFromParent();
Node hookNode = new Node(Token.HOOK, cond, thenOp, elseOp).copyInformationFrom(n);
Node expr = NodeUtil.newExpr(hookNode);
parent.replaceChild(n, expr);
reportCodeChange();
return expr;
}
}
return n;
}
boolean thenBranchIsVar = isVarBlock(thenBranch);
boolean elseBranchIsVar = isVarBlock(elseBranch);
// if(x)var y=1;else y=2 -> var y=x?1:2
if (thenBranchIsVar && elseBranchIsExpressionBlock && NodeUtil.isreplacedign(getBlockExpression(elseBranch).getFirstChild())) {
Node var = getBlockVar(thenBranch);
Node elsereplacedign = getBlockExpression(elseBranch).getFirstChild();
Node name1 = var.getFirstChild();
Node maybeName2 = elsereplacedign.getFirstChild();
if (name1.hasChildren() && maybeName2.getType() == Token.NAME && name1.getString().equals(maybeName2.getString())) {
Node thenExpr = name1.removeChildren();
Node elseExpr = elsereplacedign.getLastChild().detachFromParent();
cond.detachFromParent();
Node hookNode = new Node(Token.HOOK, cond, thenExpr, elseExpr).copyInformationFrom(n);
var.detachFromParent();
name1.addChildrenToBack(hookNode);
parent.replaceChild(n, var);
reportCodeChange();
return var;
}
// if(x)y=1;else var y=2 -> var y=x?1:2
} else if (elseBranchIsVar && thenBranchIsExpressionBlock && NodeUtil.isreplacedign(getBlockExpression(thenBranch).getFirstChild())) {
Node var = getBlockVar(elseBranch);
Node thenreplacedign = getBlockExpression(thenBranch).getFirstChild();
Node maybeName1 = thenreplacedign.getFirstChild();
Node name2 = var.getFirstChild();
if (name2.hasChildren() && maybeName1.getType() == Token.NAME && maybeName1.getString().equals(name2.getString())) {
Node thenExpr = thenreplacedign.getLastChild().detachFromParent();
Node elseExpr = name2.removeChildren();
cond.detachFromParent();
Node hookNode = new Node(Token.HOOK, cond, thenExpr, elseExpr).copyInformationFrom(n);
var.detachFromParent();
name2.addChildrenToBack(hookNode);
parent.replaceChild(n, var);
reportCodeChange();
return var;
}
}
return n;
}
/**
* Try to remove duplicate statements from IF blocks. For example:
*
* if (a) {
* x = 1;
* return true;
* } else {
* x = 2;
* return true;
* }
*
* becomes:
*
* if (a) {
* x = 1;
* } else {
* x = 2;
* }
* return true;
*
* @param n The IF node to examine.
*/
private void tryRemoveRepeatedStatements(Node n) {
Preconditions.checkState(n.getType() == Token.IF);
Node parent = n.getParent();
if (!NodeUtil.isStatementBlock(parent)) {
// If the immediate parent is something like a label, we
// can't move the statement, so bail.
return;
}
Node cond = n.getFirstChild();
Node trueBranch = cond.getNext();
Node falseBranch = trueBranch.getNext();
Preconditions.checkNotNull(trueBranch);
Preconditions.checkNotNull(falseBranch);
while (true) {
Node lastTrue = trueBranch.getLastChild();
Node lastFalse = falseBranch.getLastChild();
if (lastTrue == null || lastFalse == null || !areNodesEqualForInlining(lastTrue, lastFalse)) {
break;
}
lastTrue.detachFromParent();
lastFalse.detachFromParent();
parent.addChildAfter(lastTrue, n);
reportCodeChange();
}
}
/**
* @return Whether the node is a block with a single statement that is
* an expression.
*/
private boolean isFoldableExpressBlock(Node n) {
if (n.getType() == Token.BLOCK) {
if (n.hasOneChild()) {
Node maybeExpr = n.getFirstChild();
if (maybeExpr.getType() == Token.EXPR_RESULT) {
// IE has a bug where event handlers behave differently when
// their return value is used vs. when their return value is in
// an EXPR_RESULT. It's pretty freaking weird. See:
// http://code.google.com/p/closure-compiler/issues/detail?id=291
// We try to detect this case, and not fold EXPR_RESULTs
// into other expressions.
if (maybeExpr.getFirstChild().getType() == Token.CALL) {
Node calledFn = maybeExpr.getFirstChild().getFirstChild();
// We only have to worry about methods with an implicit 'this'
// param, or this doesn't happen.
if (calledFn.getType() == Token.GETELEM) {
return false;
} else if (calledFn.getType() == Token.GETPROP && calledFn.getLastChild().getString().startsWith("on")) {
return false;
}
}
return true;
}
return false;
}
}
return false;
}
/**
* @return The expression node.
*/
private Node getBlockExpression(Node n) {
Preconditions.checkState(isFoldableExpressBlock(n));
return n.getFirstChild();
}
/**
* @return Whether the node is a block with a single statement that is
* an return.
*/
private boolean isReturnExpressBlock(Node n) {
if (n.getType() == Token.BLOCK) {
if (n.hasOneChild()) {
Node first = n.getFirstChild();
if (first.getType() == Token.RETURN) {
return first.hasOneChild();
}
}
}
return false;
}
/**
* @return The expression that is part of the return.
*/
private Node getBlockReturnExpression(Node n) {
Preconditions.checkState(isReturnExpressBlock(n));
return n.getFirstChild().getFirstChild();
}
/**
* @return Whether the node is a block with a single statement that is
* a VAR declaration of a single variable.
*/
private boolean isVarBlock(Node n) {
if (n.getType() == Token.BLOCK) {
if (n.hasOneChild()) {
Node first = n.getFirstChild();
if (first.getType() == Token.VAR) {
return first.hasOneChild();
}
}
}
return false;
}
/**
* @return The var node.
*/
private Node getBlockVar(Node n) {
Preconditions.checkState(isVarBlock(n));
return n.getFirstChild();
}
/**
* Does a statement consume a 'dangling else'? A statement consumes
* a 'dangling else' if an 'else' token following the statement
* would be considered by the parser to be part of the statement.
*/
private boolean consumesDanglingElse(Node n) {
while (true) {
switch(n.getType()) {
case Token.IF:
if (n.getChildCount() < 3) {
return true;
}
// This IF node has no else clause.
n = n.getLastChild();
continue;
case Token.WITH:
case Token.WHILE:
case Token.FOR:
n = n.getLastChild();
continue;
default:
return false;
}
}
}
/**
* Does the expression contain an operator with lower precedence than
* the argument?
*/
private boolean isLowerPrecedenceInExpression(Node n, final int precedence) {
Predicate<Node> isLowerPrecedencePredicate = new Predicate<Node>() {
@Override
public boolean apply(Node input) {
return NodeUtil.precedence(input.getType()) < precedence;
}
};
return NodeUtil.has(n, isLowerPrecedencePredicate, DONT_TRAVERSE_FUNCTIONS_PREDICATE);
}
/**
* Does the expression contain a property replacedignment?
*/
private boolean isPropertyreplacedignmentInExpression(Node n) {
Predicate<Node> isPropertyreplacedignmentInExpressionPredicate = new Predicate<Node>() {
@Override
public boolean apply(Node input) {
return (input.getType() == Token.GETPROP && input.getParent().getType() == Token.replacedIGN);
}
};
return NodeUtil.has(n, isPropertyreplacedignmentInExpressionPredicate, DONT_TRAVERSE_FUNCTIONS_PREDICATE);
}
/**
* Try to minimize conditions expressions, as there are additional
* replacedumptions that can be made when it is known that the final result
* is a boolean.
*
* The following transformations are done recursively:
* !(x||y) --> !x&&!y
* !(x&&y) --> !x||!y
* !!x --> x
* Thus:
* !(x&&!y) --> !x||!!y --> !x||y
*
* Returns the replacement for n, or the original if no change was made
*/
private Node tryMinimizeCondition(Node n) {
Node parent = n.getParent();
switch(n.getType()) {
case Token.NOT:
Node first = n.getFirstChild();
switch(first.getType()) {
case Token.NOT:
{
Node newRoot = first.removeFirstChild();
parent.replaceChild(n, newRoot);
reportCodeChange();
// No need to traverse, tryMinimizeCondition is called on the
// NOT children are handled below.
return newRoot;
}
case Token.AND:
case Token.OR:
{
Node leftParent = first.getFirstChild();
Node rightParent = first.getLastChild();
if (leftParent.getType() == Token.NOT && rightParent.getType() == Token.NOT) {
Node left = leftParent.removeFirstChild();
Node right = rightParent.removeFirstChild();
int newOp = (first.getType() == Token.AND) ? Token.OR : Token.AND;
Node newRoot = new Node(newOp, left, right);
parent.replaceChild(n, newRoot);
reportCodeChange();
// No need to traverse, tryMinimizeCondition is called on the
// AND and OR children below.
return newRoot;
}
}
break;
}
// No need to traverse, tryMinimizeCondition is called on the NOT
// children in the general case in the main post-order traversal.
return n;
case Token.OR:
case Token.AND:
{
Node left = n.getFirstChild();
Node right = n.getLastChild();
// Because the expression is in a boolean context minimize
// the children, this can't be done in the general case.
left = tryMinimizeCondition(left);
right = tryMinimizeCondition(right);
// Remove useless conditionals
// Handle four cases:
// x || false --> x
// x || true --> true
// x && true --> x
// x && false --> false
TernaryValue rightVal = NodeUtil.getBooleanValue(right);
if (NodeUtil.getBooleanValue(right) != TernaryValue.UNKNOWN) {
int type = n.getType();
Node replacement = null;
boolean rval = rightVal.toBoolean(true);
// (x || FALSE) => x
// (x && TRUE) => x
if (type == Token.OR && !rval || type == Token.AND && rval) {
replacement = left;
} else if (!mayHaveSideEffects(left)) {
replacement = right;
}
if (replacement != null) {
n.detachChildren();
parent.replaceChild(n, replacement);
reportCodeChange();
return replacement;
}
}
return n;
}
case Token.HOOK:
{
Node condition = n.getFirstChild();
Node trueNode = n.getFirstChild().getNext();
Node falseNode = n.getLastChild();
// Because the expression is in a boolean context minimize
// the result children, this can't be done in the general case.
// The condition is handled in the general case in #optimizeSubtree
trueNode = tryMinimizeCondition(trueNode);
falseNode = tryMinimizeCondition(falseNode);
// Handle four cases:
// x ? true : false --> x
// x ? false : true --> !x
// x ? true : y --> x || y
// x ? y : false --> x && y
Node replacement = null;
if (NodeUtil.getBooleanValue(trueNode) == TernaryValue.TRUE && NodeUtil.getBooleanValue(falseNode) == TernaryValue.FALSE) {
// Remove useless conditionals, keep the condition
condition.detachFromParent();
replacement = condition;
} else if (NodeUtil.getBooleanValue(trueNode) == TernaryValue.FALSE && NodeUtil.getBooleanValue(falseNode) == TernaryValue.TRUE) {
// Remove useless conditionals, keep the condition
condition.detachFromParent();
replacement = new Node(Token.NOT, condition);
} else if (NodeUtil.getBooleanValue(trueNode) == TernaryValue.TRUE) {
// Remove useless true case.
n.detachChildren();
replacement = new Node(Token.OR, condition, falseNode);
} else if (NodeUtil.getBooleanValue(falseNode) == TernaryValue.FALSE) {
// Remove useless false case
n.detachChildren();
replacement = new Node(Token.AND, condition, trueNode);
}
if (replacement != null) {
parent.replaceChild(n, replacement);
n = replacement;
reportCodeChange();
}
return n;
}
default:
// while(true) --> while(1)
TernaryValue nVal = NodeUtil.getBooleanValue(n);
if (nVal != TernaryValue.UNKNOWN) {
boolean result = nVal.toBoolean(true);
int equivalentResult = result ? 1 : 0;
return maybeReplaceChildWithNumber(n, parent, equivalentResult);
}
// We can't do anything else currently.
return n;
}
}
/**
* Replaces a node with a number node if the new number node is not equivalent
* to the current node.
*
* Returns the replacement for n if it was replaced, otherwise returns n.
*/
private Node maybeReplaceChildWithNumber(Node n, Node parent, int num) {
Node newNode = Node.newNumber(num);
if (!newNode.isEquivalentTo(n)) {
parent.replaceChild(n, newNode);
reportCodeChange();
return newNode;
}
return n;
}
private static final ImmutableSet<String> STANDARD_OBJECT_CONSTRUCTORS = // String, Number, and Boolean functions return non-object types, whereas
// new String, new Number, and new Boolean return object types, so don't
// include them here.
ImmutableSet.of("Object", "Array", "RegExp", "Error");
/**
* Fold "new Object()" to "Object()".
*/
private Node tryFoldStandardConstructors(Node n) {
Preconditions.checkState(n.getType() == Token.NEW);
// If name normalization has been run then we know that
// new Object() does in fact refer to what we think it is
// and not some custom-defined Object().
if (isASTNormalized()) {
if (n.getFirstChild().getType() == Token.NAME) {
String clreplacedName = n.getFirstChild().getString();
if (STANDARD_OBJECT_CONSTRUCTORS.contains(clreplacedName)) {
n.setType(Token.CALL);
reportCodeChange();
}
}
}
return n;
}
/**
* Replaces a new Array or Object node with an object literal, unless the
* call to Array or Object is to a local function with the same name.
*/
private Node tryFoldLiteralConstructor(Node n) {
Preconditions.checkArgument(n.getType() == Token.CALL || n.getType() == Token.NEW);
Node constructorNameNode = n.getFirstChild();
Node newLiteralNode = null;
// We require the AST to be normalized to ensure that, say,
// Object() really refers to the built-in Object constructor
// and not a user-defined constructor with the same name.
if (isASTNormalized() && Token.NAME == constructorNameNode.getType()) {
String clreplacedName = constructorNameNode.getString();
if ("RegExp".equals(clreplacedName)) {
// "RegExp("boo", "g")" --> /boo/g
return tryFoldRegularExpressionConstructor(n);
} else {
boolean constructorHasArgs = constructorNameNode.getNext() != null;
if ("Object".equals(clreplacedName) && !constructorHasArgs) {
// "Object()" --> "{}"
newLiteralNode = new Node(Token.OBJECTLIT);
} else if ("Array".equals(clreplacedName)) {
// "Array(arg0, arg1, ...)" --> "[arg0, arg1, ...]"
Node arg0 = constructorNameNode.getNext();
FoldArrayAction action = isSafeToFoldArrayConstructor(arg0);
if (action == FoldArrayAction.SAFE_TO_FOLD_WITH_ARGS || action == FoldArrayAction.SAFE_TO_FOLD_WITHOUT_ARGS) {
newLiteralNode = new Node(Token.ARRAYLIT);
n.removeChildren();
if (action == FoldArrayAction.SAFE_TO_FOLD_WITH_ARGS) {
newLiteralNode.addChildrenToFront(arg0);
}
}
}
if (newLiteralNode != null) {
n.getParent().replaceChild(n, newLiteralNode);
reportCodeChange();
return newLiteralNode;
}
}
}
return n;
}
private static enum FoldArrayAction {
NOT_SAFE_TO_FOLD, SAFE_TO_FOLD_WITH_ARGS, SAFE_TO_FOLD_WITHOUT_ARGS
}
/**
* Checks if it is safe to fold Array() constructor into []. It can be
* obviously done, if the initial constructor has either no arguments or
* at least two. The remaining case may be unsafe since Array(number)
* actually reserves memory for an empty array which contains number elements.
*/
private FoldArrayAction isSafeToFoldArrayConstructor(Node arg) {
FoldArrayAction action = FoldArrayAction.NOT_SAFE_TO_FOLD;
if (arg == null) {
action = FoldArrayAction.SAFE_TO_FOLD_WITHOUT_ARGS;
} else if (arg.getNext() != null) {
action = FoldArrayAction.SAFE_TO_FOLD_WITH_ARGS;
} else {
switch(arg.getType()) {
case (Token.STRING):
// "Array('a')" --> "['a']"
action = FoldArrayAction.SAFE_TO_FOLD_WITH_ARGS;
break;
case (Token.NUMBER):
// "Array(0)" --> "[]"
if (arg.getDouble() == 0) {
action = FoldArrayAction.SAFE_TO_FOLD_WITHOUT_ARGS;
}
break;
case (Token.ARRAYLIT):
// "Array([args])" --> "[[args]]"
action = FoldArrayAction.SAFE_TO_FOLD_WITH_ARGS;
break;
default:
}
}
return action;
}
private Node tryFoldRegularExpressionConstructor(Node n) {
Node parent = n.getParent();
Node constructor = n.getFirstChild();
// e.g. ^foobar$
Node pattern = constructor.getNext();
// e.g. gi
Node flags = null != pattern ? pattern.getNext() : null;
// Only run on normalized AST to make sure RegExp() is actually
// the RegExp we expect (if the AST has been normalized then
// other RegExp's will have been renamed to something like RegExp$1)
if (!isASTNormalized()) {
return n;
}
if (null == pattern || (null != flags && null != flags.getNext())) {
// too few or too many arguments
return n;
}
if (// is pattern folded
pattern.getType() == Token.STRING && // make sure empty pattern doesn't fold to //
!"".equals(pattern.getString()) && // NOTE(nicksantos): Make sure that the regexp isn't longer than
// 100 chars, or it blows up the regexp parser in Opera 9.2.
pattern.getString().length() < 100 && (null == flags || flags.getType() == Token.STRING) && // don't escape patterns with unicode escapes since Safari behaves badly
// (read can't parse or crashes) on regex literals with unicode escapes
!containsUnicodeEscape(pattern.getString())) {
// Make sure that / is escaped, so that it will fit safely in /brackets/.
// pattern is a string value with \\ and similar already escaped
pattern = makeForwardSlashBracketSafe(pattern);
Node regexLiteral;
if (null == flags || "".equals(flags.getString())) {
// fold to /foobar/
regexLiteral = new Node(Token.REGEXP, pattern);
} else {
// fold to /foobar/gi
if (!areValidRegexpFlags(flags.getString())) {
error(INVALID_REGULAR_EXPRESSION_FLAGS, flags);
return n;
}
if (!areSafeFlagsToFold(flags.getString())) {
return n;
}
n.removeChild(flags);
regexLiteral = new Node(Token.REGEXP, pattern, flags);
}
parent.replaceChild(n, regexLiteral);
reportCodeChange();
return regexLiteral;
}
return n;
}
private static final Pattern REGEXP_FLAGS_RE = Pattern.compile("^[gmi]*$");
/**
* are the given flags valid regular expression flags?
* Javascript recognizes several suffix flags for regular expressions,
* 'g' - global replace, 'i' - case insensitive, 'm' - multi-line.
* They are case insensitive, and javascript does not recognize the extended
* syntax mode, single-line mode, or expression replacement mode from perl5.
*/
private static boolean areValidRegexpFlags(String flags) {
return REGEXP_FLAGS_RE.matcher(flags).matches();
}
/**
* are the given flags safe to fold?
* We don't fold the regular expression if global ('g') flag is on,
* because in this case it isn't really a constant: its 'lastIndex'
* property contains the state of last execution, so replacing
* 'new RegExp('foobar','g')' with '/foobar/g' may change the behavior of
* the program if the RegExp is used inside a loop, for example.
*/
private static boolean areSafeFlagsToFold(String flags) {
return flags.indexOf('g') < 0;
}
/**
* returns a string node that can safely be rendered inside /brackets/.
*/
private static Node makeForwardSlashBracketSafe(Node n) {
String s = n.getString();
// sb contains everything in s[0:pos]
StringBuilder sb = null;
int pos = 0;
for (int i = 0; i < s.length(); ++i) {
switch(s.charAt(i)) {
case // skip over the next char after a '\\'.
'\\':
++i;
break;
case // escape it
'/':
if (null == sb) {
sb = new StringBuilder(s.length() + 16);
}
sb.append(s, pos, i).append('\\');
pos = i;
break;
}
}
// don't discard useful line-number info if there were no changes
if (null == sb) {
return n.cloneTree();
}
sb.append(s, pos, s.length());
return Node.newString(sb.toString()).copyInformationFrom(n);
}
/**
* true if the javascript string would contain a unicode escape when written
* out as the body of a regular expression literal.
*/
static boolean containsUnicodeEscape(String s) {
String esc = CodeGenerator.regexpEscape(s);
for (int i = -1; (i = esc.indexOf("\\u", i + 1)) >= 0; ) {
int nSlashes = 0;
while (i - nSlashes > 0 && '\\' == esc.charAt(i - nSlashes - 1)) {
++nSlashes;
}
// if there are an even number of slashes before the \ u then it is a
// unicode literal.
if (0 == (nSlashes & 1)) {
return true;
}
}
return false;
}
}
19
Source : PeepholeSubstituteAlternateSyntax.java
with GNU General Public License v2.0
from xgdsmileboy
with GNU General Public License v2.0
from xgdsmileboy
/**
* A peephole optimization that minimizes code by simplifying conditional
* expressions, replacing IFs with HOOKs, replacing object constructors
* with literals, and simplifying returns.
*/
public clreplaced PeepholeSubsreplaceduteAlternateSyntax extends AbstractPeepholeOptimization {
private static final int AND_PRECEDENCE = NodeUtil.precedence(Token.AND);
private static final int OR_PRECEDENCE = NodeUtil.precedence(Token.OR);
static final DiagnosticType INVALID_REGULAR_EXPRESSION_FLAGS = DiagnosticType.error("JSC_INVALID_REGULAR_EXPRESSION_FLAGS", "Invalid flags to RegExp constructor: {0}");
static final Predicate<Node> DONT_TRAVERSE_FUNCTIONS_PREDICATE = new Predicate<Node>() {
@Override
public boolean apply(Node input) {
return input.getType() != Token.FUNCTION;
}
};
/**
* Tries apply our various peephole minimizations on the preplaceded in node.
*/
@Override
@SuppressWarnings("fallthrough")
public Node optimizeSubtree(Node node) {
switch(node.getType()) {
case Token.RETURN:
return tryReduceReturn(node);
case Token.NOT:
tryMinimizeCondition(node.getFirstChild());
return tryMinimizeNot(node);
case Token.IF:
tryMinimizeCondition(node.getFirstChild());
return tryMinimizeIf(node);
case Token.EXPR_RESULT:
tryMinimizeCondition(node.getFirstChild());
return node;
case Token.HOOK:
tryMinimizeCondition(node.getFirstChild());
return node;
case Token.WHILE:
case Token.DO:
tryMinimizeCondition(NodeUtil.getConditionExpression(node));
return node;
case Token.FOR:
if (!NodeUtil.isForIn(node)) {
tryMinimizeCondition(NodeUtil.getConditionExpression(node));
}
return node;
case Token.NEW:
node = tryFoldStandardConstructors(node);
if (node.getType() != Token.CALL) {
return node;
}
// Fall through on purpose because tryFoldStandardConstructors() may
// convert a NEW node into a CALL node
case Token.CALL:
return tryFoldLiteralConstructor(node);
default:
// Nothing changed
return node;
}
}
/**
* Reduce "return undefined" or "return void 0" to simply "return".
*
* Returns the replacement for n, or the original if no change was made.
*/
private Node tryReduceReturn(Node n) {
Node result = n.getFirstChild();
boolean possibleException = result != null && ControlFlowreplacedysis.mayThrowException(result);
// Try to use a subsreplacedute that with a break because it is shorter.
// First lets pretend it is a break with no labels.
Node breakTarget = n;
boolean safe = true;
for (; !ControlFlowreplacedysis.isBreakTarget(breakTarget, null); breakTarget = breakTarget.getParent()) {
if (NodeUtil.isFunction(breakTarget) || breakTarget.getType() == Token.SCRIPT) {
// We can switch the return to a break if the return value has
// side effect and it must encounter a finally.
// example: return alert('a') -> finally { alert('b') } ->
// return alert('a')
// prints a then b. If the first return is a break,
// it prints b then a.
safe = false;
break;
}
}
Node follow = ControlFlowreplacedysis.computeFollowNode(breakTarget);
// Skip preplaced all the finally blocks because both the break and return will
// also trigger all the finally blocks. However, the order of execution is
// slightly changed. Consider:
//
// return a() -> finally { b() } -> return a()
//
// which would call a() first. However, changing the first return to a
// break will result in calling b().
while (follow != null && NodeUtil.isTryFinallyNode(follow.getParent(), follow)) {
if (result != null && // TODO(user): Use the new side effects API for more accuracy.
(NodeUtil.canBeSideEffected(result) || NodeUtil.mayHaveSideEffects(result))) {
safe = false;
break;
}
follow = ControlFlowreplacedysis.computeFollowNode(follow);
}
if (safe) {
if (follow == null) {
// When follow is null, this mean the follow of a break target is the
// end of a function. This means a break is same as return.
if (result == null) {
n.setType(Token.BREAK);
reportCodeChange();
return n;
}
} else if (follow.getType() == Token.RETURN && (result == follow.getFirstChild() || (result != null && follow.hasChildren() && result.checkTreeEqualsSilent(follow.getFirstChild())) && ControlFlowreplacedysis.getExceptionHandler(n) == ControlFlowreplacedysis.getExceptionHandler(follow))) {
// When the follow is a return, if both doesn't return anything
// or both returns the same thing. This mean we can replace it with a
// break.
n.removeChildren();
n.setType(Token.BREAK);
reportCodeChange();
return n;
}
// If any of the above is executed, we must return because n is no longer
// a "return" node.
}
// TODO(user): consider cases such as if (x) { return 1} return 1;
if (result != null) {
switch(result.getType()) {
case Token.VOID:
Node operand = result.getFirstChild();
if (!mayHaveSideEffects(operand)) {
n.removeFirstChild();
reportCodeChange();
}
break;
case Token.NAME:
String name = result.getString();
if (name.equals("undefined")) {
n.removeFirstChild();
reportCodeChange();
}
break;
default:
// Do nothing
break;
}
}
return n;
}
/**
* Try to minimize NOT nodes such as !(x==y).
*
* Returns the replacement for n or the original if no change was made
*/
private Node tryMinimizeNot(Node n) {
Node parent = n.getParent();
Node notChild = n.getFirstChild();
// negative operator of the current one : == -> != for instance.
int complementOperator;
switch(notChild.getType()) {
case Token.EQ:
complementOperator = Token.NE;
break;
case Token.NE:
complementOperator = Token.EQ;
break;
case Token.SHEQ:
complementOperator = Token.SHNE;
break;
case Token.SHNE:
complementOperator = Token.SHEQ;
break;
// GT, GE, LT, LE are not handled in this because !(x<NaN) != x>=NaN.
default:
return n;
}
Node newOperator = n.removeFirstChild();
newOperator.setType(complementOperator);
parent.replaceChild(n, newOperator);
reportCodeChange();
return newOperator;
}
/**
* Try turning IF nodes into smaller HOOKs
*
* Returns the replacement for n or the original if no replacement was
* necessary.
*/
private Node tryMinimizeIf(Node n) {
Node parent = n.getParent();
Node cond = n.getFirstChild();
/* If the condition is a literal, we'll let other
* optimizations try to remove useless code.
*/
if (NodeUtil.isLiteralValue(cond, true)) {
return n;
}
Node thenBranch = cond.getNext();
Node elseBranch = thenBranch.getNext();
if (elseBranch == null) {
if (isFoldableExpressBlock(thenBranch)) {
Node expr = getBlockExpression(thenBranch);
if (isPropertyreplacedignmentInExpression(expr)) {
// Keep opportunities for CollapseProperties such as
// a.longIdentifier || a.longIdentifier = ... -> var a = ...;
return n;
}
if (cond.getType() == Token.NOT) {
// if(!x)bar(); -> x||bar();
if (isLowerPrecedenceInExpression(cond, OR_PRECEDENCE) && isLowerPrecedenceInExpression(expr.getFirstChild(), OR_PRECEDENCE)) {
// It's not okay to add two sets of parentheses.
return n;
}
Node or = new Node(Token.OR, cond.removeFirstChild(), expr.removeFirstChild()).copyInformationFrom(n);
Node newExpr = NodeUtil.newExpr(or);
parent.replaceChild(n, newExpr);
reportCodeChange();
return newExpr;
}
// if(x)foo(); -> x&&foo();
if (isLowerPrecedenceInExpression(cond, AND_PRECEDENCE) || isLowerPrecedenceInExpression(expr.getFirstChild(), AND_PRECEDENCE)) {
// One additional set of parentheses isn't worth it.
return n;
}
n.removeChild(cond);
Node and = new Node(Token.AND, cond, expr.removeFirstChild()).copyInformationFrom(n);
Node newExpr = NodeUtil.newExpr(and);
parent.replaceChild(n, newExpr);
reportCodeChange();
return newExpr;
}
return n;
}
/* TODO(dcc) This modifies the siblings of n, which is undesirable for a
* peephole optimization. This should probably get moved to another preplaced.
*/
tryRemoveRepeatedStatements(n);
// if(!x)foo();else bar(); -> if(x)bar();else foo();
// An additional set of curly braces isn't worth it.
if (cond.getType() == Token.NOT && !consumesDanglingElse(elseBranch)) {
n.replaceChild(cond, cond.removeFirstChild());
n.removeChild(thenBranch);
n.addChildToBack(thenBranch);
reportCodeChange();
return n;
}
// if(x)return 1;else return 2; -> return x?1:2;
if (isReturnExpressBlock(thenBranch) && isReturnExpressBlock(elseBranch)) {
Node thenExpr = getBlockReturnExpression(thenBranch);
Node elseExpr = getBlockReturnExpression(elseBranch);
n.removeChild(cond);
thenExpr.detachFromParent();
elseExpr.detachFromParent();
// note - we ignore any cases with "return;", technically this
// can be converted to "return undefined;" or some variant, but
// that does not help code size.
Node hookNode = new Node(Token.HOOK, cond, thenExpr, elseExpr).copyInformationFrom(n);
Node returnNode = new Node(Token.RETURN, hookNode);
parent.replaceChild(n, returnNode);
reportCodeChange();
return returnNode;
}
boolean thenBranchIsExpressionBlock = isFoldableExpressBlock(thenBranch);
boolean elseBranchIsExpressionBlock = isFoldableExpressBlock(elseBranch);
if (thenBranchIsExpressionBlock && elseBranchIsExpressionBlock) {
Node thenOp = getBlockExpression(thenBranch).getFirstChild();
Node elseOp = getBlockExpression(elseBranch).getFirstChild();
if (thenOp.getType() == elseOp.getType()) {
// if(x)a=1;else a=2; -> a=x?1:2;
if (NodeUtil.isreplacedignmentOp(thenOp)) {
Node lhs = thenOp.getFirstChild();
if (areNodesEqualForInlining(lhs, elseOp.getFirstChild()) && // if LHS has side effects, don't proceed [since the optimization
// evaluates LHS before cond]
// NOTE - there are some cirreplacedstances where we can
// proceed even if there are side effects...
!mayEffectMutableState(lhs)) {
n.removeChild(cond);
Node replacedignName = thenOp.removeFirstChild();
Node thenExpr = thenOp.removeFirstChild();
Node elseExpr = elseOp.getLastChild();
elseOp.removeChild(elseExpr);
Node hookNode = new Node(Token.HOOK, cond, thenExpr, elseExpr).copyInformationFrom(n);
Node replacedign = new Node(thenOp.getType(), replacedignName, hookNode).copyInformationFrom(thenOp);
Node expr = NodeUtil.newExpr(replacedign);
parent.replaceChild(n, expr);
reportCodeChange();
return expr;
}
} else if (NodeUtil.isCall(thenOp)) {
// if(x)foo();else bar(); -> x?foo():bar()
n.removeChild(cond);
thenOp.detachFromParent();
elseOp.detachFromParent();
Node hookNode = new Node(Token.HOOK, cond, thenOp, elseOp).copyInformationFrom(n);
Node expr = NodeUtil.newExpr(hookNode);
parent.replaceChild(n, expr);
reportCodeChange();
return expr;
}
}
return n;
}
boolean thenBranchIsVar = isVarBlock(thenBranch);
boolean elseBranchIsVar = isVarBlock(elseBranch);
// if(x)var y=1;else y=2 -> var y=x?1:2
if (thenBranchIsVar && elseBranchIsExpressionBlock && NodeUtil.isreplacedign(getBlockExpression(elseBranch).getFirstChild())) {
Node var = getBlockVar(thenBranch);
Node elsereplacedign = getBlockExpression(elseBranch).getFirstChild();
Node name1 = var.getFirstChild();
Node maybeName2 = elsereplacedign.getFirstChild();
if (name1.hasChildren() && maybeName2.getType() == Token.NAME && name1.getString().equals(maybeName2.getString())) {
Node thenExpr = name1.removeChildren();
Node elseExpr = elsereplacedign.getLastChild().detachFromParent();
cond.detachFromParent();
Node hookNode = new Node(Token.HOOK, cond, thenExpr, elseExpr).copyInformationFrom(n);
var.detachFromParent();
name1.addChildrenToBack(hookNode);
parent.replaceChild(n, var);
reportCodeChange();
return var;
}
// if(x)y=1;else var y=2 -> var y=x?1:2
} else if (elseBranchIsVar && thenBranchIsExpressionBlock && NodeUtil.isreplacedign(getBlockExpression(thenBranch).getFirstChild())) {
Node var = getBlockVar(elseBranch);
Node thenreplacedign = getBlockExpression(thenBranch).getFirstChild();
Node maybeName1 = thenreplacedign.getFirstChild();
Node name2 = var.getFirstChild();
if (name2.hasChildren() && maybeName1.getType() == Token.NAME && maybeName1.getString().equals(name2.getString())) {
Node thenExpr = thenreplacedign.getLastChild().detachFromParent();
Node elseExpr = name2.removeChildren();
cond.detachFromParent();
Node hookNode = new Node(Token.HOOK, cond, thenExpr, elseExpr).copyInformationFrom(n);
var.detachFromParent();
name2.addChildrenToBack(hookNode);
parent.replaceChild(n, var);
reportCodeChange();
return var;
}
}
return n;
}
/**
* Try to remove duplicate statements from IF blocks. For example:
*
* if (a) {
* x = 1;
* return true;
* } else {
* x = 2;
* return true;
* }
*
* becomes:
*
* if (a) {
* x = 1;
* } else {
* x = 2;
* }
* return true;
*
* @param n The IF node to examine.
*/
private void tryRemoveRepeatedStatements(Node n) {
Preconditions.checkState(n.getType() == Token.IF);
Node parent = n.getParent();
if (!NodeUtil.isStatementBlock(parent)) {
// If the immediate parent is something like a label, we
// can't move the statement, so bail.
return;
}
Node cond = n.getFirstChild();
Node trueBranch = cond.getNext();
Node falseBranch = trueBranch.getNext();
Preconditions.checkNotNull(trueBranch);
Preconditions.checkNotNull(falseBranch);
while (true) {
Node lastTrue = trueBranch.getLastChild();
Node lastFalse = falseBranch.getLastChild();
if (lastTrue == null || lastFalse == null || !areNodesEqualForInlining(lastTrue, lastFalse)) {
break;
}
lastTrue.detachFromParent();
lastFalse.detachFromParent();
parent.addChildAfter(lastTrue, n);
reportCodeChange();
}
}
/**
* @return Whether the node is a block with a single statement that is
* an expression.
*/
private boolean isFoldableExpressBlock(Node n) {
if (n.getType() == Token.BLOCK) {
if (n.hasOneChild()) {
Node maybeExpr = n.getFirstChild();
// IE has a bug where event handlers behave differently when
// their return value is used vs. when their return value is in
// an EXPR_RESULT. It's pretty freaking weird. See:
// http://code.google.com/p/closure-compiler/issues/detail?id=291
// We try to detect this case, and not fold EXPR_RESULTs
// into other expressions.
// We only have to worry about methods with an implicit 'this'
// param, or this doesn't happen.
return NodeUtil.isExpressionNode(maybeExpr);
}
}
return false;
}
/**
* @return The expression node.
*/
private Node getBlockExpression(Node n) {
Preconditions.checkState(isFoldableExpressBlock(n));
return n.getFirstChild();
}
/**
* @return Whether the node is a block with a single statement that is
* an return.
*/
private boolean isReturnExpressBlock(Node n) {
if (n.getType() == Token.BLOCK) {
if (n.hasOneChild()) {
Node first = n.getFirstChild();
if (first.getType() == Token.RETURN) {
return first.hasOneChild();
}
}
}
return false;
}
/**
* @return The expression that is part of the return.
*/
private Node getBlockReturnExpression(Node n) {
Preconditions.checkState(isReturnExpressBlock(n));
return n.getFirstChild().getFirstChild();
}
/**
* @return Whether the node is a block with a single statement that is
* a VAR declaration of a single variable.
*/
private boolean isVarBlock(Node n) {
if (n.getType() == Token.BLOCK) {
if (n.hasOneChild()) {
Node first = n.getFirstChild();
if (first.getType() == Token.VAR) {
return first.hasOneChild();
}
}
}
return false;
}
/**
* @return The var node.
*/
private Node getBlockVar(Node n) {
Preconditions.checkState(isVarBlock(n));
return n.getFirstChild();
}
/**
* Does a statement consume a 'dangling else'? A statement consumes
* a 'dangling else' if an 'else' token following the statement
* would be considered by the parser to be part of the statement.
*/
private boolean consumesDanglingElse(Node n) {
while (true) {
switch(n.getType()) {
case Token.IF:
if (n.getChildCount() < 3) {
return true;
}
// This IF node has no else clause.
n = n.getLastChild();
continue;
case Token.WITH:
case Token.WHILE:
case Token.FOR:
n = n.getLastChild();
continue;
default:
return false;
}
}
}
/**
* Does the expression contain an operator with lower precedence than
* the argument?
*/
private boolean isLowerPrecedenceInExpression(Node n, final int precedence) {
Predicate<Node> isLowerPrecedencePredicate = new Predicate<Node>() {
@Override
public boolean apply(Node input) {
return NodeUtil.precedence(input.getType()) < precedence;
}
};
return NodeUtil.has(n, isLowerPrecedencePredicate, DONT_TRAVERSE_FUNCTIONS_PREDICATE);
}
/**
* Does the expression contain a property replacedignment?
*/
private boolean isPropertyreplacedignmentInExpression(Node n) {
Predicate<Node> isPropertyreplacedignmentInExpressionPredicate = new Predicate<Node>() {
@Override
public boolean apply(Node input) {
return (input.getType() == Token.GETPROP && input.getParent().getType() == Token.replacedIGN);
}
};
return NodeUtil.has(n, isPropertyreplacedignmentInExpressionPredicate, DONT_TRAVERSE_FUNCTIONS_PREDICATE);
}
/**
* Try to minimize conditions expressions, as there are additional
* replacedumptions that can be made when it is known that the final result
* is a boolean.
*
* The following transformations are done recursively:
* !(x||y) --> !x&&!y
* !(x&&y) --> !x||!y
* !!x --> x
* Thus:
* !(x&&!y) --> !x||!!y --> !x||y
*
* Returns the replacement for n, or the original if no change was made
*/
private Node tryMinimizeCondition(Node n) {
Node parent = n.getParent();
switch(n.getType()) {
case Token.NOT:
Node first = n.getFirstChild();
switch(first.getType()) {
case Token.NOT:
{
Node newRoot = first.removeFirstChild();
parent.replaceChild(n, newRoot);
reportCodeChange();
// No need to traverse, tryMinimizeCondition is called on the
// NOT children are handled below.
return newRoot;
}
case Token.AND:
case Token.OR:
{
Node leftParent = first.getFirstChild();
Node rightParent = first.getLastChild();
if (leftParent.getType() == Token.NOT && rightParent.getType() == Token.NOT) {
Node left = leftParent.removeFirstChild();
Node right = rightParent.removeFirstChild();
int newOp = (first.getType() == Token.AND) ? Token.OR : Token.AND;
Node newRoot = new Node(newOp, left, right);
parent.replaceChild(n, newRoot);
reportCodeChange();
// No need to traverse, tryMinimizeCondition is called on the
// AND and OR children below.
return newRoot;
}
}
break;
}
// No need to traverse, tryMinimizeCondition is called on the NOT
// children in the general case in the main post-order traversal.
return n;
case Token.OR:
case Token.AND:
{
Node left = n.getFirstChild();
Node right = n.getLastChild();
// Because the expression is in a boolean context minimize
// the children, this can't be done in the general case.
left = tryMinimizeCondition(left);
right = tryMinimizeCondition(right);
// Remove useless conditionals
// Handle four cases:
// x || false --> x
// x || true --> true
// x && true --> x
// x && false --> false
TernaryValue rightVal = NodeUtil.getBooleanValue(right);
if (NodeUtil.getBooleanValue(right) != TernaryValue.UNKNOWN) {
int type = n.getType();
Node replacement = null;
boolean rval = rightVal.toBoolean(true);
// (x || FALSE) => x
// (x && TRUE) => x
if (type == Token.OR && !rval || type == Token.AND && rval) {
replacement = left;
} else if (!mayHaveSideEffects(left)) {
replacement = right;
}
if (replacement != null) {
n.detachChildren();
parent.replaceChild(n, replacement);
reportCodeChange();
return replacement;
}
}
return n;
}
case Token.HOOK:
{
Node condition = n.getFirstChild();
Node trueNode = n.getFirstChild().getNext();
Node falseNode = n.getLastChild();
// Because the expression is in a boolean context minimize
// the result children, this can't be done in the general case.
// The condition is handled in the general case in #optimizeSubtree
trueNode = tryMinimizeCondition(trueNode);
falseNode = tryMinimizeCondition(falseNode);
// Handle four cases:
// x ? true : false --> x
// x ? false : true --> !x
// x ? true : y --> x || y
// x ? y : false --> x && y
Node replacement = null;
if (NodeUtil.getBooleanValue(trueNode) == TernaryValue.TRUE && NodeUtil.getBooleanValue(falseNode) == TernaryValue.FALSE) {
// Remove useless conditionals, keep the condition
condition.detachFromParent();
replacement = condition;
} else if (NodeUtil.getBooleanValue(trueNode) == TernaryValue.FALSE && NodeUtil.getBooleanValue(falseNode) == TernaryValue.TRUE) {
// Remove useless conditionals, keep the condition
condition.detachFromParent();
replacement = new Node(Token.NOT, condition);
} else if (NodeUtil.getBooleanValue(trueNode) == TernaryValue.TRUE) {
// Remove useless true case.
n.detachChildren();
replacement = new Node(Token.OR, condition, falseNode);
} else if (NodeUtil.getBooleanValue(falseNode) == TernaryValue.FALSE) {
// Remove useless false case
n.detachChildren();
replacement = new Node(Token.AND, condition, trueNode);
}
if (replacement != null) {
parent.replaceChild(n, replacement);
n = replacement;
reportCodeChange();
}
return n;
}
default:
// while(true) --> while(1)
TernaryValue nVal = NodeUtil.getBooleanValue(n);
if (nVal != TernaryValue.UNKNOWN) {
boolean result = nVal.toBoolean(true);
int equivalentResult = result ? 1 : 0;
return maybeReplaceChildWithNumber(n, parent, equivalentResult);
}
// We can't do anything else currently.
return n;
}
}
/**
* Replaces a node with a number node if the new number node is not equivalent
* to the current node.
*
* Returns the replacement for n if it was replaced, otherwise returns n.
*/
private Node maybeReplaceChildWithNumber(Node n, Node parent, int num) {
Node newNode = Node.newNumber(num);
if (!newNode.isEquivalentTo(n)) {
parent.replaceChild(n, newNode);
reportCodeChange();
return newNode;
}
return n;
}
private static final ImmutableSet<String> STANDARD_OBJECT_CONSTRUCTORS = // String, Number, and Boolean functions return non-object types, whereas
// new String, new Number, and new Boolean return object types, so don't
// include them here.
ImmutableSet.of("Object", "Array", "RegExp", "Error");
/**
* Fold "new Object()" to "Object()".
*/
private Node tryFoldStandardConstructors(Node n) {
Preconditions.checkState(n.getType() == Token.NEW);
// If name normalization has been run then we know that
// new Object() does in fact refer to what we think it is
// and not some custom-defined Object().
if (isASTNormalized()) {
if (n.getFirstChild().getType() == Token.NAME) {
String clreplacedName = n.getFirstChild().getString();
if (STANDARD_OBJECT_CONSTRUCTORS.contains(clreplacedName)) {
n.setType(Token.CALL);
reportCodeChange();
}
}
}
return n;
}
/**
* Replaces a new Array or Object node with an object literal, unless the
* call to Array or Object is to a local function with the same name.
*/
private Node tryFoldLiteralConstructor(Node n) {
Preconditions.checkArgument(n.getType() == Token.CALL || n.getType() == Token.NEW);
Node constructorNameNode = n.getFirstChild();
Node newLiteralNode = null;
// We require the AST to be normalized to ensure that, say,
// Object() really refers to the built-in Object constructor
// and not a user-defined constructor with the same name.
if (isASTNormalized() && Token.NAME == constructorNameNode.getType()) {
String clreplacedName = constructorNameNode.getString();
if ("RegExp".equals(clreplacedName)) {
// "RegExp("boo", "g")" --> /boo/g
return tryFoldRegularExpressionConstructor(n);
} else {
boolean constructorHasArgs = constructorNameNode.getNext() != null;
if ("Object".equals(clreplacedName) && !constructorHasArgs) {
// "Object()" --> "{}"
newLiteralNode = new Node(Token.OBJECTLIT);
} else if ("Array".equals(clreplacedName)) {
// "Array(arg0, arg1, ...)" --> "[arg0, arg1, ...]"
Node arg0 = constructorNameNode.getNext();
FoldArrayAction action = isSafeToFoldArrayConstructor(arg0);
if (action == FoldArrayAction.SAFE_TO_FOLD_WITH_ARGS || action == FoldArrayAction.SAFE_TO_FOLD_WITHOUT_ARGS) {
newLiteralNode = new Node(Token.ARRAYLIT);
n.removeChildren();
if (action == FoldArrayAction.SAFE_TO_FOLD_WITH_ARGS) {
newLiteralNode.addChildrenToFront(arg0);
}
}
}
if (newLiteralNode != null) {
n.getParent().replaceChild(n, newLiteralNode);
reportCodeChange();
return newLiteralNode;
}
}
}
return n;
}
private static enum FoldArrayAction {
NOT_SAFE_TO_FOLD, SAFE_TO_FOLD_WITH_ARGS, SAFE_TO_FOLD_WITHOUT_ARGS
}
/**
* Checks if it is safe to fold Array() constructor into []. It can be
* obviously done, if the initial constructor has either no arguments or
* at least two. The remaining case may be unsafe since Array(number)
* actually reserves memory for an empty array which contains number elements.
*/
private FoldArrayAction isSafeToFoldArrayConstructor(Node arg) {
FoldArrayAction action = FoldArrayAction.NOT_SAFE_TO_FOLD;
if (arg == null) {
action = FoldArrayAction.SAFE_TO_FOLD_WITHOUT_ARGS;
} else if (arg.getNext() != null) {
action = FoldArrayAction.SAFE_TO_FOLD_WITH_ARGS;
} else {
switch(arg.getType()) {
case (Token.STRING):
// "Array('a')" --> "['a']"
action = FoldArrayAction.SAFE_TO_FOLD_WITH_ARGS;
break;
case (Token.NUMBER):
// "Array(0)" --> "[]"
if (arg.getDouble() == 0) {
action = FoldArrayAction.SAFE_TO_FOLD_WITHOUT_ARGS;
}
break;
case (Token.ARRAYLIT):
// "Array([args])" --> "[[args]]"
action = FoldArrayAction.SAFE_TO_FOLD_WITH_ARGS;
break;
default:
}
}
return action;
}
private Node tryFoldRegularExpressionConstructor(Node n) {
Node parent = n.getParent();
Node constructor = n.getFirstChild();
// e.g. ^foobar$
Node pattern = constructor.getNext();
// e.g. gi
Node flags = null != pattern ? pattern.getNext() : null;
// Only run on normalized AST to make sure RegExp() is actually
// the RegExp we expect (if the AST has been normalized then
// other RegExp's will have been renamed to something like RegExp$1)
if (!isASTNormalized()) {
return n;
}
if (null == pattern || (null != flags && null != flags.getNext())) {
// too few or too many arguments
return n;
}
if (// is pattern folded
pattern.getType() == Token.STRING && // make sure empty pattern doesn't fold to //
!"".equals(pattern.getString()) && // NOTE(nicksantos): Make sure that the regexp isn't longer than
// 100 chars, or it blows up the regexp parser in Opera 9.2.
pattern.getString().length() < 100 && (null == flags || flags.getType() == Token.STRING) && // don't escape patterns with unicode escapes since Safari behaves badly
// (read can't parse or crashes) on regex literals with unicode escapes
!containsUnicodeEscape(pattern.getString())) {
// Make sure that / is escaped, so that it will fit safely in /brackets/.
// pattern is a string value with \\ and similar already escaped
pattern = makeForwardSlashBracketSafe(pattern);
Node regexLiteral;
if (null == flags || "".equals(flags.getString())) {
// fold to /foobar/
regexLiteral = new Node(Token.REGEXP, pattern);
} else {
// fold to /foobar/gi
if (!areValidRegexpFlags(flags.getString())) {
error(INVALID_REGULAR_EXPRESSION_FLAGS, flags);
return n;
}
if (!areSafeFlagsToFold(flags.getString())) {
return n;
}
n.removeChild(flags);
regexLiteral = new Node(Token.REGEXP, pattern, flags);
}
parent.replaceChild(n, regexLiteral);
reportCodeChange();
return regexLiteral;
}
return n;
}
private static final Pattern REGEXP_FLAGS_RE = Pattern.compile("^[gmi]*$");
/**
* are the given flags valid regular expression flags?
* Javascript recognizes several suffix flags for regular expressions,
* 'g' - global replace, 'i' - case insensitive, 'm' - multi-line.
* They are case insensitive, and javascript does not recognize the extended
* syntax mode, single-line mode, or expression replacement mode from perl5.
*/
private static boolean areValidRegexpFlags(String flags) {
return REGEXP_FLAGS_RE.matcher(flags).matches();
}
/**
* are the given flags safe to fold?
* We don't fold the regular expression if global ('g') flag is on,
* because in this case it isn't really a constant: its 'lastIndex'
* property contains the state of last execution, so replacing
* 'new RegExp('foobar','g')' with '/foobar/g' may change the behavior of
* the program if the RegExp is used inside a loop, for example.
*/
private static boolean areSafeFlagsToFold(String flags) {
return flags.indexOf('g') < 0;
}
/**
* returns a string node that can safely be rendered inside /brackets/.
*/
private static Node makeForwardSlashBracketSafe(Node n) {
String s = n.getString();
// sb contains everything in s[0:pos]
StringBuilder sb = null;
int pos = 0;
for (int i = 0; i < s.length(); ++i) {
switch(s.charAt(i)) {
case // skip over the next char after a '\\'.
'\\':
++i;
break;
case // escape it
'/':
if (null == sb) {
sb = new StringBuilder(s.length() + 16);
}
sb.append(s, pos, i).append('\\');
pos = i;
break;
}
}
// don't discard useful line-number info if there were no changes
if (null == sb) {
return n.cloneTree();
}
sb.append(s, pos, s.length());
return Node.newString(sb.toString()).copyInformationFrom(n);
}
/**
* true if the javascript string would contain a unicode escape when written
* out as the body of a regular expression literal.
*/
static boolean containsUnicodeEscape(String s) {
String esc = CodeGenerator.regexpEscape(s);
for (int i = -1; (i = esc.indexOf("\\u", i + 1)) >= 0; ) {
int nSlashes = 0;
while (i - nSlashes > 0 && '\\' == esc.charAt(i - nSlashes - 1)) {
++nSlashes;
}
// if there are an even number of slashes before the \ u then it is a
// unicode literal.
if (0 == (nSlashes & 1)) {
return true;
}
}
return false;
}
}
19
Source : EventQueue.java
with GNU General Public License v3.0
from wizards-of-lua
with GNU General Public License v3.0
from wizards-of-lua
public clreplaced EventQueue {
public interface Context {
void stop(EventQueue eventQueue);
long getCurrentTime();
}
private final ImmutableSet<String> names;
private final Context context;
private Deque<Event> elements = new ArrayDeque<>();
private long waitUntil = -1;
public EventQueue(Iterable<String> names, Context context) {
this.names = ImmutableSet.copyOf(names);
this.context = checkNotNull(context, "context==null!");
}
public ImmutableSet<String> getNames() {
return names;
}
public void stop() {
context.stop(this);
}
public long getWaitUntil() {
return waitUntil;
}
public void waitForEvents(@Nullable Long timeout) {
if (timeout != null) {
waitUntil = context.getCurrentTime() + timeout;
} else {
waitUntil = Long.MAX_VALUE;
}
}
public boolean isEmpty() {
return elements.isEmpty();
}
public void clear() {
elements.clear();
}
public Event latest() {
return elements.peekLast();
}
public Event pop() {
Event result = elements.pop();
stopWaitingForEvents();
return result;
}
public void add(Event event) {
elements.addLast(event);
}
private void stopWaitingForEvents() {
waitUntil = -1;
}
}
19
Source : MultipleProcessingExceptions.java
with GNU General Public License v3.0
from wizards-of-lua
with GNU General Public License v3.0
from wizards-of-lua
public clreplaced MultipleProcessingExceptions extends Exception {
private static final long serialVersionUID = 1L;
private final ImmutableSet<ProcessingException> exceptions;
public MultipleProcessingExceptions(Iterable<ProcessingException> exceptions) {
this.exceptions = ImmutableSet.copyOf(exceptions);
}
/**
* @return the value of {@link #exceptions}
*/
public ImmutableSet<ProcessingException> getExceptions() {
return exceptions;
}
}
19
Source : ActiveExecutors.java
with Apache License 2.0
from WeBankFinTech
with Apache License 2.0
from WeBankFinTech
/**
* Loads executors. Can be also used to reload executors if there have been changes in the DB.
*
* @throws ExecutorManagerException if no active executors are found or if loading executors
* fails.
*/
public void setupExecutors() throws ExecutorManagerException {
final ImmutableSet<Executor> newExecutors = loadExecutors();
if (newExecutors.isEmpty()) {
final String error = "No active executors found";
logger.error(error);
throw new ExecutorManagerException(error);
} else {
this.activeExecutors = newExecutors;
}
}
19
Source : WellKnownTypes.java
with MIT License
from warmuuh
with MIT License
from warmuuh
/**
* Central place to store information about the protobuf well-known-types.
*/
public clreplaced WellKnownTypes {
private static final ImmutableSet<FileDescriptorProto> DESCRIPTORS = ImmutableSet.of(AnyProto.getDescriptor().getFile().toProto(), ApiProto.getDescriptor().getFile().toProto(), DescriptorProto.getDescriptor().getFile().toProto(), DurationProto.getDescriptor().getFile().toProto(), EmptyProto.getDescriptor().getFile().toProto(), FieldMaskProto.getDescriptor().getFile().toProto(), SourceContextProto.getDescriptor().getFile().toProto(), StructProto.getDescriptor().getFile().toProto(), TimestampProto.getDescriptor().getFile().toProto(), TypeProto.getDescriptor().getFile().toProto(), WrappersProto.getDescriptor().getFile().toProto());
private static final ImmutableSet<String> FILES = ImmutableSet.of("any.proto", "api.proto", "descriptor.proto", "duration.proto", "empty.proto", "field_mask.proto", "source_context.proto", "struct.proto", "timestamp.proto", "type.proto", "wrappers.proto");
public static ImmutableSet<FileDescriptorProto> descriptors() {
return DESCRIPTORS;
}
public static ImmutableSet<String> fileNames() {
return FILES;
}
}
19
Source : Protocol1_8TO1_9.java
with MIT License
from ViaVersion
with MIT License
from ViaVersion
public clreplaced Protocol1_8TO1_9 extends Protocol {
public static final Timer TIMER = new Timer("ViaRewind-1_8TO1_9", true);
public static final ImmutableSet<Object> VALID_ATTRIBUTES;
static {
ImmutableSet.Builder<Object> builder = ImmutableSet.builder();
builder.add("generic.maxHealth");
builder.add("generic.followRange");
builder.add("generic.knockbackResistance");
builder.add("generic.movementSpeed");
builder.add("generic.attackDamage");
builder.add("horse.jumpStrength");
builder.add("zombie.spawnReinforcements");
VALID_ATTRIBUTES = builder.build();
}
public static final ValueTransformer<Double, Integer> TO_OLD_INT = new ValueTransformer<Double, Integer>(Type.INT) {
public Integer transform(PacketWrapper wrapper, Double inputValue) {
return (int) (inputValue * 32.0D);
}
};
public static final ValueTransformer<Float, Byte> DEGREES_TO_ANGLE = new ValueTransformer<Float, Byte>(Type.BYTE) {
@Override
public Byte transform(PacketWrapper packetWrapper, Float degrees) throws Exception {
return (byte) ((degrees / 360F) * 256);
}
};
@Override
protected void registerPackets() {
EnreplacedyPackets.register(this);
InventoryPackets.register(this);
PlayerPackets.register(this);
ScoreboardPackets.register(this);
SpawnPackets.register(this);
WorldPackets.register(this);
// Keep Alive
this.registerOutgoing(State.PLAY, 0x1F, 0x00);
// Keep Alive
this.registerIncoming(State.PLAY, 0x0B, 0x00);
}
@Override
public void init(UserConnection userConnection) {
Ticker.init();
userConnection.put(new Windows(userConnection));
userConnection.put(new EnreplacedyTracker(userConnection));
userConnection.put(new Levitation(userConnection));
userConnection.put(new PlayerPosition(userConnection));
userConnection.put(new Cooldown(userConnection));
userConnection.put(new BlockPlaceDestroyTracker(userConnection));
userConnection.put(new BossBarStorage(userConnection));
userConnection.put(new ClientWorld(userConnection));
}
}
19
Source : DimensionRegistry.java
with MIT License
from VelocityPowered
with MIT License
from VelocityPowered
public final clreplaced DimensionRegistry {
private final Map<String, DimensionData> registeredDimensions;
private final ImmutableSet<String> levelNames;
/**
* Initializes a new {@link DimensionRegistry} instance.
* This registry is required for 1.16+ clients/servers to communicate,
* it constrains the dimension types and names the client can be sent
* in a Respawn action (dimension change).
* This WILL raise an IllegalArgumentException if the following is not met:
* - At least one valid DimensionData instance is provided
* - At least one valid world name is provided
* @param registeredDimensions a populated {@link ImmutableSet} containing dimension data types
* @param levelNames a populated {@link ImmutableSet} of the level (world) names the server offers
*/
public DimensionRegistry(ImmutableSet<DimensionData> registeredDimensions, ImmutableSet<String> levelNames) {
Preconditions.checkNotNull(registeredDimensions, "registeredDimensions cannot be null");
Preconditions.checkNotNull(levelNames, "levelNames cannot be null");
Preconditions.checkArgument(registeredDimensions.size() > 0, "registeredDimensions needs to be populated");
Preconditions.checkArgument(levelNames.size() > 0, "levelNames needs to populated");
this.registeredDimensions = Maps.uniqueIndex(registeredDimensions, DimensionData::getRegistryIdentifier);
this.levelNames = levelNames;
}
public Map<String, DimensionData> getRegisteredDimensions() {
return registeredDimensions;
}
public Set<String> getLevelNames() {
return levelNames;
}
/**
* Returns the internal dimension data type as used by the game.
* @param dimensionIdentifier how the dimension is identified by the connection
* @return game dimension data or null if not registered
*/
@Nullable
public DimensionData getDimensionData(String dimensionIdentifier) {
return registeredDimensions.get(dimensionIdentifier);
}
/**
* Checks a {@link DimensionInfo} against this registry.
* @param toValidate the {@link DimensionInfo} to validate
* @return true: the dimension information is valid for this registry
*/
public boolean isValidFor(DimensionInfo toValidate) {
if (toValidate == null) {
return false;
}
return registeredDimensions.containsKey(toValidate.getRegistryIdentifier()) && levelNames.contains(toValidate.getLevelName());
}
/**
* Encodes the stored Dimension registry as CompoundTag.
* @return the CompoundTag containing identifier:type mappings
*/
public ListBinaryTag encodeRegistry(ProtocolVersion version) {
ListBinaryTag.Builder<CompoundBinaryTag> listBuilder = ListBinaryTag.builder(BinaryTagTypes.COMPOUND);
for (DimensionData iter : registeredDimensions.values()) {
listBuilder.add(iter.encodeAsCompoundTag(version));
}
return listBuilder.build();
}
/**
* Decodes a CompoundTag storing a dimension registry.
* @param toParse CompoundTag containing a dimension registry
*/
public static ImmutableSet<DimensionData> fromGameData(ListBinaryTag toParse, ProtocolVersion version) {
Preconditions.checkNotNull(toParse, "ListTag cannot be null");
ImmutableSet.Builder<DimensionData> mappings = ImmutableSet.builder();
for (BinaryTag iter : toParse) {
if (iter instanceof CompoundBinaryTag) {
mappings.add(DimensionData.decodeRegistryEntry((CompoundBinaryTag) iter, version));
}
}
return mappings.build();
}
}
19
Source : VerbHelper.java
with Apache License 2.0
from uwnlp
with Apache License 2.0
from uwnlp
/**
* Created by luheng on 12/9/15.
*/
public clreplaced VerbHelper {
private static VerbInflectionDictionary s_inflectionDictionary;
static {
try {
final String verbInflFile = PropertyUtil.resourcesProperties.getProperty("inflection_dict");
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(verbInflFile));
s_inflectionDictionary = (VerbInflectionDictionary) ois.readObject();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static final VerbHelper trainingSetVerbHelper = new VerbHelper(s_inflectionDictionary);
private static final ImmutableSet<String> doVerbs = new ImmutableSet.Builder<String>().add("do").add("does").add("did").add("done").build();
private static ImmutableSet<String> beVerbs = new ImmutableSet.Builder<String>().add("be").add("being").add("been").add("am").add("'m").add("is").add("'s").add(// as in ai n't
"ai").add("are").add("'re").add("was").add("were").build();
private static final ImmutableSet<String> willVerbs = new ImmutableSet.Builder<String>().add("will").add("'ll").add(// as in wo n't
"wo").build();
private static final ImmutableSet<String> haveVerbs = new ImmutableSet.Builder<String>().add("have").add("having").add("'ve").add("has").add("had").add("'d").build();
private static final ImmutableSet<String> modalVerbs = new ImmutableSet.Builder<String>().add("would").add("'d").add("can").add("ca").add("could").add("may").add("might").add("must").add("shall").add("should").add("ought").build();
private static final ImmutableSet<String> auxiliaryVerbs = new ImmutableSet.Builder<String>().addAll(doVerbs).addAll(beVerbs).addAll(willVerbs).addAll(haveVerbs).addAll(modalVerbs).build();
private VerbInflectionDictionary inflectionDictionary;
public VerbHelper(VerbInflectionDictionary inflectionDictionary) {
this.inflectionDictionary = inflectionDictionary;
}
public Optional<String> getCopulaNegation(List<String> words, List<Category> categories, int index) {
for (int i = index + 1; i < words.size(); i++) {
if (isNegationWord(words, categories, i)) {
return Optional.of(words.get(i));
} else if (!isModifierWord(words, categories, i)) {
return Optional.empty();
}
}
return Optional.empty();
}
public List<Integer> getAuxiliaryChain(List<String> words, List<Category> categories, int index) {
List<Integer> auxliaryIndices = new ArrayList<>();
for (int i = index - 1; i >= 0; i--) {
boolean isAux = isAuxiliaryVerb(words, categories, i);
boolean isNeg = isNegationWord(words, categories, i);
boolean isAdv = isModifierWord(words, categories, i);
if (!isAux && !isNeg && !isAdv) {
break;
}
if (isAux || isNeg) {
auxliaryIndices.add(i);
}
}
if (auxliaryIndices.size() > 0) {
Collections.sort(auxliaryIndices);
}
return auxliaryIndices;
}
public boolean isAuxiliaryVerb(List<String> words, List<Category> categories, int index) {
return index < words.size() && auxiliaryVerbs.contains(words.get(index).toLowerCase()) && categories.get(index).isFunctionInto(Category.valueOf("(S\\NP)|(S\\NP)"));
}
public static boolean isAuxiliaryVerb(String word, Category category) {
return auxiliaryVerbs.contains(word.toLowerCase()) && category.isFunctionInto(Category.valueOf("(S\\NP)|(S\\NP)"));
}
public boolean isNegationWord(List<String> words, List<Category> categories, int index) {
if (index < words.size()) {
String word = words.get(index);
return word.equalsIgnoreCase("n\'t") || word.equalsIgnoreCase("not");
}
return false;
}
public static boolean isNegationWord(String word) {
return word.equalsIgnoreCase("n\'t") || word.equalsIgnoreCase("not") || word.equalsIgnoreCase("no");
}
public boolean isModifierWord(List<String> words, List<Category> categories, int index) {
return index < words.size() && categories.get(index).isFunctionInto(Category.ADVERB);
}
public static boolean isCopulaVerb(String word) {
return beVerbs.contains(word.toLowerCase());
}
/**
* approved -> List { did, approve }
*/
public Optional<String[]> getAuxiliaryAndVerbStrings(List<String> words, List<Category> categories, int index) {
String verbStr = words.get(index).toLowerCase();
String[] infl = inflectionDictionary.getBestInflections(verbStr.toLowerCase());
if (infl == null) {
// System.err.println("Can't find inflections for: " + words.get(index) + " " + categories.get(index));
return Optional.empty();
}
// eat
if (verbStr.equals(infl[0])) {
return Optional.of(new String[] { "would", infl[0] });
}
// eats
if (verbStr.equals(infl[1])) {
return Optional.of(new String[] { "does", infl[0] });
}
// eating
if (verbStr.equals(infl[2])) {
return Optional.of(new String[] { "would", "be " + infl[2] });
}
// ate
if (verbStr.equals(infl[3])) {
return Optional.of(new String[] { "did", infl[0] });
}
// eaten
return Optional.of(new String[] { "have", infl[4] });
}
public boolean hasInflectedForms(String word) {
return inflectionDictionary.getBestInflections(word.toLowerCase()) != null;
}
public Optional<String> getUninflected(String word) {
if (isCopulaVerb(word)) {
return Optional.of("be");
}
Optional<String[]> inflections = Optional.ofNullable(inflectionDictionary.getBestInflections(word.toLowerCase()));
return inflections.map(infl -> infl[0]);
}
public boolean isUninflected(List<String> words, List<Category> categories, int index) {
String verbStr = words.get(index).toLowerCase();
String[] infl = inflectionDictionary.getBestInflections(verbStr.toLowerCase());
return infl != null && verbStr.equals(infl[0]);
}
public static boolean isModal(String verb) {
return modalVerbs.contains(verb.toLowerCase());
}
public static String getNormalizedModal(String word) {
if (word.equalsIgnoreCase("ca")) {
return "can";
} else {
return word;
}
}
public static boolean isFutureTense(String verb) {
return willVerbs.contains(verb.toLowerCase());
}
public static boolean isPastTense(String verb) {
return verb.equalsIgnoreCase("was") || verb.equalsIgnoreCase("were") || Optional.ofNullable(s_inflectionDictionary.getBestInflections(verb.toLowerCase())).map(infl -> verb.equalsIgnoreCase(infl[3])).orElse(false);
}
public static String getPastTense(String verb, Noun subject) {
if (isCopulaVerb(verb)) {
Noun.Number num = subject.getNumber().orElse(Noun.Number.SINGULAR);
switch(num) {
case PLURAL:
return "were";
case SINGULAR:
switch(subject.getPerson()) {
case FIRST:
return "was";
case SECOND:
return "were";
case THIRD:
return "was";
default:
replacedert false;
return null;
}
default:
replacedert false;
return null;
}
} else {
return Optional.ofNullable(s_inflectionDictionary.getBestInflections(verb.toLowerCase())).map(infl -> infl[3]).orElse(verb);
}
}
// if the number of the subject is not known, allows for the "do" form (as opposed to "does" form) long as subj is third person
// public static boolean isPresentTense(String verb, Noun subject) {
// return Optional.ofNullable(s_inflectionDictionary.getBestInflections(verb.toLowerCase()))
// .map(infl -> verb.equalsIgnoreCase(infl[1]) ||
// (!(subject.getNumber().map(num -> num == Noun.Number.SINGULAR).orElse(true) && subject.getPerson() == Noun.Person.THIRD) &&
// verb.equalsIgnoreCase(infl[0])))
// .orElse(false);
// }
// relaxed present tense test that looks for either case
public static boolean isPresentTense(String verb) {
return verb.equalsIgnoreCase("am") || verb.equalsIgnoreCase("are") || verb.equalsIgnoreCase("is") || verb.equalsIgnoreCase("'s") || verb.equalsIgnoreCase("'re") || verb.equalsIgnoreCase("'m") || verb.equalsIgnoreCase("'ve") || verb.equalsIgnoreCase("ai") || Optional.ofNullable(s_inflectionDictionary.getBestInflections(verb.toLowerCase())).map(infl -> verb.equalsIgnoreCase(infl[1]) || verb.equalsIgnoreCase(infl[0])).orElse(false);
}
public static String getPresentTense(String verb, Noun subject) {
if (isCopulaVerb(verb)) {
Noun.Number num = subject.getNumber().orElse(Noun.Number.SINGULAR);
switch(num) {
case PLURAL:
return "are";
case SINGULAR:
switch(subject.getPerson()) {
case FIRST:
return "am";
case SECOND:
return "are";
case THIRD:
return "is";
default:
replacedert false;
return null;
}
default:
replacedert false;
return null;
}
} else {
return Optional.ofNullable(s_inflectionDictionary.getBestInflections(verb.toLowerCase())).map(infl -> ((subject.getNumber().map(num -> num == Noun.Number.SINGULAR).orElse(true)) && subject.getPerson() == Noun.Person.THIRD) ? infl[1] : infl[0]).orElse(verb);
}
}
// aka progressive form
public static boolean isPresentParticiple(String verb) {
return verb.equalsIgnoreCase("being") || Optional.ofNullable(s_inflectionDictionary.getBestInflections(verb.toLowerCase())).map(infl -> verb.equalsIgnoreCase(infl[2])).orElse(false);
}
public static String getPresentParticiple(String verb) {
if (isCopulaVerb(verb)) {
return "being";
} else {
return Optional.ofNullable(s_inflectionDictionary.getBestInflections(verb.toLowerCase())).map(infl -> infl[2]).orElse(verb);
}
}
// aka participle
public static boolean isPastParticiple(String verb) {
return verb.equalsIgnoreCase("been") || Optional.ofNullable(s_inflectionDictionary.getBestInflections(verb.toLowerCase())).map(infl -> verb.equalsIgnoreCase(infl[4])).orElse(false);
}
public static String getPastParticiple(String verb) {
if (isCopulaVerb(verb)) {
return "been";
} else {
return Optional.ofNullable(s_inflectionDictionary.getBestInflections(verb.toLowerCase())).map(infl -> infl[4]).orElse(verb);
}
}
public static boolean isStem(String verb) {
return verb.equalsIgnoreCase("be") || Optional.ofNullable(s_inflectionDictionary.getBestInflections(verb.toLowerCase())).map(infl -> verb.equalsIgnoreCase(infl[0])).orElse(// replacedume it's the stem if we don't know
true);
}
public static String getStem(String verb) {
if (isCopulaVerb(verb)) {
return "be";
} else {
return Optional.ofNullable(s_inflectionDictionary.getBestInflections(verb.toLowerCase())).map(infl -> infl[0]).orElse(verb);
}
}
/**
* replacedysis code.
*/
private static void seh() {
Iterator<ParallelCorpusReader.Sentence> sentenceIterator = null;
try {
sentenceIterator = ParallelCorpusReader.READER.readCorpus(false);
} catch (IOException e) {
}
while (sentenceIterator.hasNext()) {
ParallelCorpusReader.Sentence sentence = sentenceIterator.next();
List<String> words = sentence.getWords();
List<Category> categories = sentence.getLexicalCategories();
for (int i = 0; i < words.size(); i++) {
/*
if (isVerb(words, categories, i) { // && isPreplacedive(words, categories, i)) {
List<Integer> aux = getAuxiliaryChain(words, categories, i);
aux.add(i);
for (int j = 0; j < words.size(); j++) {
System.out.printWithGoldDependency((j == 0 ? "" : " ") + (j == i ? "*" : "") + words.get(j));
}
System.out.println();
aux.forEach(id -> System.out.printWithGoldDependency(words.get(id) + " "));
System.out.println();
aux.forEach(id -> System.out.printWithGoldDependency(categories.get(id) + " "));
System.out.println("\n");
}
if (isAuxiliaryVerb(sentence.getWords(), sentence.getLexicalCategories(), i)) {
System.out.println();
for (int j = 0; j < words.size(); j++) {
System.out.printWithGoldDependency((j == 0 ? "" : " ") + (j == i ? "*" : "") + words.get(j));
}
System.out.println();
System.out.println(sentence.getWords().get(i) + "\t" + sentence.getLexicalCategories().get(i));
}
*/
Category category = sentence.getLexicalCategories().get(i);
if (category.isFunctionInto(Category.valueOf("(S\\NP)|(S\\NP)")) && !category.isFunctionInto(Category.valueOf("(S\\NP)|(S\\NP)|NP"))) {
System.out.println(sentence.getWords().get(i) + "\t" + category);
}
}
}
}
public static void main(String[] args) {
seh();
}
}
19
Source : Prepositions.java
with Apache License 2.0
from uwnlp
with Apache License 2.0
from uwnlp
/**
* Created by luheng on 4/11/16.
*/
public clreplaced Prepositions {
public static final ImmutableSet<Category> prepositionCategories = ImmutableSet.of(Category.valueOf("((S\\NP)\\(S\\NP))/NP"), Category.valueOf("(NP\\NP)/NP"), Category.valueOf("((S\\NP)\\(S\\NP))/S[dcl]"), Category.valueOf("PP\\NP"));
public static final ImmutableSet<String> prepositionWords = ImmutableSet.of("aboard", "about", "above", "across", "afore", "after", "against", "ahead", "along", "alongside", "amid", "amidst", "among", "amongst", "around", "as", "aside", "astride", "at", "atop", "before", "behind", "below", "beneath", "beside", "besides", "between", "beyond", "by", "despite", "down", "during", "except", "for", "from", "given", "in", "inside", "into", "near", "next", "of", "off", "on", "onto", "opposite", "out", "outside", "over", "pace", "per", "round", "since", "than", "through", "throughout", "till", "times", "to", "toward", "towards", "under", "underneath", "until", "unto", "up", "upon", "versus", "via", "with", "within", "without");
}
19
Source : Preposition.java
with Apache License 2.0
from uwnlp
with Apache License 2.0
from uwnlp
public final clreplaced Preposition extends Predication {
public static final ImmutableSet<String> prepositionWords = ImmutableSet.of("aboard", "about", "above", "across", "afore", "after", "against", "ahead", "along", "alongside", "amid", "amidst", "among", "amongst", "around", "as", "aside", "astride", "at", "atop", "before", "behind", "below", "beneath", "beside", "besides", "between", "beyond", "by", "despite", "down", "during", "except", "for", "from", "given", "in", "inside", "into", "near", "next", "of", "off", "on", "onto", "opposite", "out", "outside", "over", "pace", "per", "round", "since", "than", "through", "throughout", "till", "times", "to", "toward", "towards", "under", "underneath", "until", "unto", "up", "upon", "versus", "via", "with", "within", "without");
private static Set<Category> prepositionCategories = new HashSet<>();
public static Preposition makeSimplePP(String predicate, Noun object) {
return new Preposition(predicate, Category.valueOf("PP/NP"), new ImmutableMap.Builder<Integer, ImmutableList<Argument>>().put(1, ImmutableList.of(Argument.withNoDependency(object))).build());
}
public static Preposition getFromParse(Integer headIndex, PredicateCache preds, Parse parse) {
final SyntaxTreeNode tree = parse.syntaxTree;
final SyntaxTreeNodeLeaf headLeaf = tree.getLeaves().get(headIndex);
final String predicate = TextGenerationHelper.renderString(TextGenerationHelper.getNodeWords(headLeaf));
final Category predicateCategory = parse.categories.get(headIndex);
final ImmutableMap<Integer, ImmutableList<Argument>> args = IntStream.range(1, predicateCategory.getNumberOfArguments() + 1).boxed().collect(toImmutableMap(argNum -> argNum, argNum -> parse.dependencies.stream().filter(dep -> dep.getHead() == headIndex && dep.getArgument() != headIndex && argNum == dep.getArgNumber()).flatMap(argDep -> Stream.of(Predication.Type.getTypeForArgCategory(predicateCategory.getArgument(argDep.getArgNumber()))).filter(Optional::isPresent).map(Optional::get).map(predType -> new Argument(Optional.of(argDep), preds.getPredication(argDep.getArgument(), predType)))).collect(toImmutableList())));
if (!prepositionCategories.contains(predicateCategory)) {
// System.err.println(String.format("new preposition category: %s (e.g., %s)",
// predicateCategory, predicate));
prepositionCategories.add(predicateCategory);
}
return new Preposition(predicate, predicateCategory, args);
}
@Override
public ImmutableList<String> getPhrase(Category desiredCategory) {
// replacedert getPredicateCategory().isFunctionInto(desiredCategory)
// : "can only make prepositional phrases or functions into them with preposition. " +
// "predicate: " + getPredicate() + " (" + getPredicateCategory() + "); " +
// "desired category: " + desiredCategory;
replacedert getArgs().entrySet().stream().allMatch(e -> e.getValue().size() >= 1) : "can only get phrase for preposition with at least one arg in each slot";
ImmutableMap<Integer, Argument> args = getArgs().entrySet().stream().collect(toImmutableMap(e -> e.getKey(), e -> e.getValue().get(0)));
if (!getPredicateCategory().isFunctionInto(desiredCategory)) {
// System.err.println("can only make prepositional phrases or functions into them with preposition. " +
// "predicate: " + getPredicate() + " (" + getPredicateCategory() + "); " +
// "desired category: " + desiredCategory);
// System.err.println(args.get(1).getPredication().getPhrase(getPredicateCategory().getArgument(1)));
}
ImmutableList<String> leftArgs = ImmutableList.of();
ImmutableList<String> rightArgs = ImmutableList.of();
Category curCat = getPredicateCategory();
// sadness
// while(!desiredCategory.matches(curCat)) {
while (curCat.getNumberOfArguments() > desiredCategory.getNumberOfArguments()) {
Predication curArg = args.get(curCat.getNumberOfArguments()).getPredication();
Category curArgCat = curCat.getArgument(curCat.getNumberOfArguments());
Slash slash = curCat.getSlash();
switch(slash) {
case BWD:
leftArgs = new ImmutableList.Builder<String>().addAll(curArg.getPhrase(curArgCat)).addAll(leftArgs).build();
break;
case FWD:
rightArgs = new ImmutableList.Builder<String>().addAll(rightArgs).addAll(curArg.getPhrase(curArgCat)).build();
break;
default:
replacedert false;
}
curCat = curCat.getLeft();
}
return new ImmutableList.Builder<String>().addAll(leftArgs).add(getPredicate()).addAll(rightArgs).build();
}
@Override
public ImmutableSet<ResolvedDependency> getLocalDependencies() {
return ImmutableSet.of();
}
@Override
public Preposition transformArgs(BiFunction<Integer, ImmutableList<Argument>, ImmutableList<Argument>> transform) {
return new Preposition(getPredicate(), getPredicateCategory(), transformArgsAux(transform));
}
private Preposition(String predicate, Category predicateCategory, ImmutableMap<Integer, ImmutableList<Argument>> args) {
super(predicate, predicateCategory, args);
}
}
19
Source : Predication.java
with Apache License 2.0
from uwnlp
with Apache License 2.0
from uwnlp
/* protected methods and fields */
protected static ImmutableMap<Integer, ImmutableList<Argument>> extractArgs(int headIndex, Category headCategory, Parse parse, PredicateCache preds) {
return IntStream.range(1, headCategory.getNumberOfArguments() + 1).boxed().collect(toImmutableMap(argNum -> argNum, argNum -> {
ImmutableSet<ResolvedDependency> outgoingDeps = parse.dependencies.stream().filter(dep -> dep.getHead() == headIndex && dep.getArgument() != headIndex && argNum == dep.getArgNumber()).collect(toImmutableSet());
if (headCategory.getArgument(argNum).matches(Category.NP)) {
return outgoingDeps.stream().collect(groupingBy(dep -> {
return TextGenerationHelper.getLowestAncestorSatisfyingPredicate(parse.syntaxTree.getLeaves().get(dep.getArgument()), node -> node.getCategory().matches(Category.NP), parse.syntaxTree);
})).entrySet().stream().flatMap(e -> {
if (e.getValue().size() > 1) {
ResolvedDependency lastDep = e.getValue().stream().collect(maxBy((dep1, dep2) -> Integer.compare(dep1.getArgument(), dep2.getArgument()))).get();
return Stream.of(new Argument(Optional.of(lastDep), Noun.getFromParse(lastDep.getArgument(), parse, e.getKey())));
} else {
ResolvedDependency argDep = e.getValue().get(0);
return Stream.of(Predication.Type.getTypeForArgCategory(headCategory.getArgument(argDep.getArgNumber()))).filter(Optional::isPresent).map(Optional::get).map(predType -> new Argument(Optional.of(argDep), preds.getPredication(argDep.getArgument(), predType)));
}
}).collect(toImmutableList());
} else {
return outgoingDeps.stream().flatMap(argDep -> Stream.of(Predication.Type.getTypeForArgCategory(headCategory.getArgument(argDep.getArgNumber()))).filter(Optional::isPresent).map(Optional::get).map(predType -> new Argument(Optional.of(argDep), preds.getPredication(argDep.getArgument(), predType)))).collect(toImmutableList());
}
}));
}
19
Source : Partitive.java
with Apache License 2.0
from uwnlp
with Apache License 2.0
from uwnlp
/**
* Parreplacedive genitive words from the paper Rebanking CCGbank for improved NP interpretation.
* missing "many"
* Created by luheng on 5/5/16.
*/
public clreplaced Parreplacedive {
public static final ImmutableSet<String> tokens = ImmutableSet.of("all", "another", "average", "both", "each", "another", "any", "anything", "both", "certain", "each", "either", "enough", "few", "little", "many", "most", "much", "neither", "nothing", "other", "part", "plenty", "several", "some", "something", "that", "those");
}
19
Source : BasicNoun.java
with Apache License 2.0
from uwnlp
with Apache License 2.0
from uwnlp
public clreplaced BasicNoun extends Noun {
/* public API */
// overrides
@Override
public ImmutableList<String> getPhrase(Category desiredCategory) {
// TODO verify that we want an NP out of it.
if (isElided()) {
return ImmutableList.of();
} else {
return words;
}
}
@Override
public ImmutableSet<ResolvedDependency> getLocalDependencies() {
return deps;
}
@Override
public BasicNoun transformArgs(BiFunction<Integer, ImmutableList<Argument>, ImmutableList<Argument>> transform) {
return this;
}
// transformers -- subclreplacedes should override
@Override
public BasicNoun withCase(Case caseMarking) {
return this.withCase(Optional.of(caseMarking));
}
@Override
public BasicNoun withCase(Optional<Case> caseMarking) {
return new BasicNoun(getPredicate(), getPredicateCategory(), getArgs(), getCase(), getNumber(), getGender(), getPerson(), getDefiniteness(), words, deps, isElided());
}
@Override
public BasicNoun withNumber(Number number) {
return this.withNumber(Optional.of(number));
}
@Override
public BasicNoun withNumber(Optional<Number> number) {
return new BasicNoun(getPredicate(), getPredicateCategory(), getArgs(), getCase(), number, getGender(), getPerson(), getDefiniteness(), words, deps, isElided());
}
@Override
public BasicNoun withGender(Gender gender) {
return this.withGender(Optional.of(gender));
}
@Override
public BasicNoun withGender(Optional<Gender> gender) {
return new BasicNoun(getPredicate(), getPredicateCategory(), getArgs(), getCase(), getNumber(), gender, getPerson(), getDefiniteness(), words, deps, isElided());
}
@Override
public BasicNoun withPerson(Person person) {
return new BasicNoun(getPredicate(), getPredicateCategory(), getArgs(), getCase(), getNumber(), getGender(), person, getDefiniteness(), words, deps, isElided());
}
@Override
public BasicNoun withDefiniteness(Definiteness definiteness) {
return new BasicNoun(getPredicate(), getPredicateCategory(), getArgs(), getCase(), getNumber(), getGender(), getPerson(), definiteness, words, deps, isElided());
}
@Override
public boolean isPronoun() {
return false;
}
@Override
public Pronoun getPronoun() {
return new Pronoun(getCase(), getNumber(), getGender(), getPerson(), getDefiniteness(), isElided());
}
@Override
public Noun getPronounOrExpletive() {
return getPronoun();
}
@Override
public BasicNoun withElision(boolean shouldElide) {
return new BasicNoun(getPredicate(), getPredicateCategory(), getArgs(), getCase(), getNumber(), getGender(), getPerson(), getDefiniteness(), words, deps, shouldElide);
}
/* protected methods and fields */
protected BasicNoun(String predicate, Category predicateCategory, ImmutableMap<Integer, ImmutableList<Argument>> args, Optional<Case> caseMarking, Optional<Number> number, Optional<Gender> gender, Person person, Definiteness definiteness, ImmutableList<String> words, ImmutableSet<ResolvedDependency> deps, boolean isElided) {
super(predicate, predicateCategory, args, caseMarking, number, gender, person, definiteness, isElided);
this.words = words;
this.deps = deps;
}
/* private fields */
private final ImmutableList<String> words;
private final ImmutableSet<ResolvedDependency> deps;
}
19
Source : AnswerStructure.java
with Apache License 2.0
from uwnlp
with Apache License 2.0
from uwnlp
/**
* Contains information about the answer spans.
* Created by luheng on 3/19/16.
*/
public clreplaced AnswerStructure {
public final ImmutableList<Integer> argumentIndices;
public final ImmutableSet<ResolvedDependency> adjunctDependencies;
// For non-checkbox version, this an answer structure is non-singled headed. This changes the logic of containedIn.
public final boolean singleHeaded;
public final boolean headIsVP;
public AnswerStructure(Collection<Integer> argIds, boolean singleHeaded) {
this.argumentIndices = ImmutableList.copyOf(argIds.stream().sorted().collect(Collectors.toList()));
this.adjunctDependencies = ImmutableSet.of();
this.singleHeaded = singleHeaded;
this.headIsVP = false;
}
public AnswerStructure(Collection<Integer> argIds, final ImmutableSet<ResolvedDependency> adjunctDependencies, boolean headIsVP) {
this.argumentIndices = ImmutableList.copyOf(argIds.stream().sorted().collect(Collectors.toList()));
this.adjunctDependencies = adjunctDependencies;
this.singleHeaded = true;
this.headIsVP = headIsVP;
}
// FIXME
public boolean equals(final Object other) {
return AnswerStructure.clreplaced.isInstance(other) && argumentIndices.equals(((AnswerStructure) other).argumentIndices) && adjunctDependencies.equals(((AnswerStructure) other).adjunctDependencies);
}
/**
* Return all the dependencies that's relevant to this structure.
* @param dependencies
* @return
*/
public ImmutableSet<ResolvedDependency> filter(Collection<ResolvedDependency> dependencies) {
if (!singleHeaded) {
return dependencies.stream().collect(Collectors.groupingBy(ResolvedDependency::getHead)).values().stream().filter(deps -> {
ImmutableList<Integer> argList = deps.stream().map(ResolvedDependency::getArgument).distinct().collect(GuavaCollectors.toImmutableList());
return argList.size() == argumentIndices.size() && argList.containsAll(argumentIndices) && argumentIndices.containsAll(argList);
}).flatMap(Collection::stream).collect(GuavaCollectors.toImmutableSet());
}
if (!headIsVP) {
return dependencies.stream().filter(d -> d.getArgument() == argumentIndices.get(0)).collect(GuavaCollectors.toImmutableSet());
}
return dependencies.stream().filter(d -> d.getHead() == argumentIndices.get(0)).collect(GuavaCollectors.toImmutableSet());
}
public String toString(final ImmutableList<String> words) {
String argIdsStr = argumentIndices.stream().map(String::valueOf).collect(Collectors.joining(","));
String argHeadsStr = argumentIndices.stream().map(words::get).collect(Collectors.joining(","));
String adjDepsStr = adjunctDependencies.stream().map(dep -> String.format("%s->%s", words.get(dep.getHead()), words.get(dep.getArgument()))).collect(Collectors.joining(";"));
return argIdsStr + ":" + argHeadsStr + "," + adjDepsStr;
}
}
19
Source : IntProperty.java
with Apache License 2.0
from UnknownDomainGames
with Apache License 2.0
from UnknownDomainGames
public clreplaced IntProperty extends Property<Integer> {
private final ImmutableSet<Integer> availableValues;
public IntProperty(String propertyName, int min, int max) {
super(Integer.clreplaced, propertyName);
availableValues = ImmutableSet.<Integer>builder().addAll(IntStream.rangeClosed(min, max).iterator()).build();
}
@Override
public Collection<Integer> getPossibleValues() {
return availableValues;
}
@Override
public String valueToString(Integer value) {
return value.toString();
}
@Override
public Optional<Integer> stringToValue(String s) {
try {
var value = Integer.valueOf(s);
return availableValues.contains(value) ? Optional.of(value) : Optional.empty();
} catch (NumberFormatException e) {
return Optional.empty();
}
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof IntProperty))
return false;
if (!super.equals(o))
return false;
IntProperty that = (IntProperty) o;
return availableValues.equals(that.availableValues);
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + availableValues.hashCode();
return result;
}
}
19
Source : ID3Frames.java
with GNU General Public License v3.0
from umerov1999
with GNU General Public License v3.0
from umerov1999
/**
* Subclreplacedes Defines ID3 frames for their Tag Version
* <p>
* Here we specify how frames are mapped between different Tag Versions
*
* @author Paul Taylor
* @version $Id$
*/
public abstract clreplaced ID3Frames {
private volatile ImmutableSet<String> multipleFrames;
private volatile ImmutableSet<String> discardIfFileAlteredFrames;
private volatile ImmutableSet<String> supportedFrames;
private volatile ImmutableSet<String> binaryFrames;
private volatile ImmutableSet<String> commonFrames;
private volatile ImmutableSet<String> extensionFrames;
/**
* If file changes discard these frames
*
* @param frameID frame id to check
* @return true if can discard
*/
public boolean isDiscardIfFileAltered(String frameID) {
return getDiscardIfFileAlteredFrames().contains(frameID);
}
private ImmutableSet<String> getDiscardIfFileAlteredFrames() {
if (discardIfFileAlteredFrames == null) {
synchronized (this) {
if (discardIfFileAlteredFrames == null) {
discardIfFileAlteredFrames = makeDiscardIfFileAlteredFrames();
}
}
}
return discardIfFileAlteredFrames;
}
protected abstract ImmutableSet<String> makeDiscardIfFileAlteredFrames();
/**
* Are multiple occurrences of frame allowed
*
* @param frameID frame id to check
* @return true if multiple allowed
*/
public boolean isMultipleAllowed(String frameID) {
return getMultipleFrames().contains(frameID);
}
private ImmutableSet<String> getMultipleFrames() {
if (multipleFrames == null) {
synchronized (this) {
if (multipleFrames == null) {
multipleFrames = makeMultipleFrames();
}
}
}
return multipleFrames;
}
protected abstract ImmutableSet<String> makeMultipleFrames();
/**
* @param frameID is this frame id supported
* @return true if frames with this id are part of the specification
*/
public boolean isSupportedFrames(String frameID) {
return getSupportedFrames().contains(frameID);
}
@VisibleForTesting
public final ImmutableSet<String> getSupportedFrames() {
if (supportedFrames == null) {
synchronized (this) {
if (supportedFrames == null) {
supportedFrames = makeSupportedFrames();
}
}
}
return supportedFrames;
}
protected abstract ImmutableSet<String> makeSupportedFrames();
/**
* @param frameID frame id to check
* @return true if frames with this id are considered common
*/
public boolean isCommon(String frameID) {
return getCommonFrames().contains(frameID);
}
private ImmutableSet<String> getCommonFrames() {
if (commonFrames == null) {
synchronized (this) {
if (commonFrames == null) {
commonFrames = makeCommonFrames();
}
}
}
return commonFrames;
}
protected abstract ImmutableSet<String> makeCommonFrames();
/**
* @param frameID frame id to check
* @return true if frames with this id are binary (non textual data)
*/
public boolean isBinary(String frameID) {
return getBinaryFrames().contains(frameID);
}
private ImmutableSet<String> getBinaryFrames() {
if (binaryFrames == null) {
synchronized (this) {
if (binaryFrames == null) {
binaryFrames = makeBinaryFrames();
}
}
}
return binaryFrames;
}
protected abstract ImmutableSet<String> makeBinaryFrames();
/**
* @param frameID frame id to check
* @return true if frame is a known extension
*/
public boolean isExtensionFrames(String frameID) {
return getExtensionFrames().contains(frameID);
}
private ImmutableSet<String> getExtensionFrames() {
if (extensionFrames == null) {
synchronized (this) {
if (extensionFrames == null) {
extensionFrames = makeExtensionFrames();
}
}
}
return extensionFrames;
}
protected abstract ImmutableSet<String> makeExtensionFrames();
}
19
Source : GenericTag.java
with GNU General Public License v3.0
from umerov1999
with GNU General Public License v3.0
from umerov1999
/**
* This is a complete example implementation of {@link AbstractTag}
*
* @author Raphaël Slinckx
*/
public abstract clreplaced GenericTag extends AbstractTag {
private static final byte[] EMPTY_BYTE_ARRAY = {};
final private static ImmutableSet<FieldKey> supportedKeys = ImmutableSet.of(FieldKey.ALBUM, FieldKey.ARTIST, FieldKey.replacedLE, FieldKey.TRACK, FieldKey.GENRE, FieldKey.COMMENT, FieldKey.YEAR);
protected GenericTag() {
super(false);
}
public static ImmutableSet<FieldKey> getSupportedTagKeys() {
return supportedKeys;
}
@Override
protected boolean isAllowedEncoding(Charset enc) {
return true;
}
@Override
public TagField createField(FieldKey genericKey, String... values) throws IllegalArgumentException, UnsupportedFieldException, FieldDataInvalidException {
checkArgNotNull(genericKey, CANNOT_BE_NULL, "genericKey");
if (getSupportedFields().contains(genericKey)) {
return new GenericTagTextField(genericKey.name(), checkVarArg0NotNull(values));
} else {
throw new UnsupportedFieldException(genericKey.name());
}
}
@Override
public String getFirst(FieldKey genericKey) throws IllegalArgumentException, UnsupportedFieldException {
return getValue(genericKey, 0).or("");
}
@Override
public Optional<String> getValue(FieldKey genericKey, int index) throws IllegalArgumentException {
checkArgNotNull(genericKey, CANNOT_BE_NULL, "genericKey");
return getValue(genericKey.name(), index);
}
@Override
public String getFieldAt(FieldKey genericKey, int index) throws IllegalArgumentException, UnsupportedFieldException {
return getValue(genericKey, index).or("");
}
@Override
public List<String> getAll(FieldKey genericKey) throws IllegalArgumentException, UnsupportedFieldException {
checkArgNotNull(genericKey, CANNOT_BE_NULL, "genericKey");
if (!getSupportedFields().contains(genericKey)) {
throw new UnsupportedFieldException(genericKey.name());
}
return getAll(genericKey.name());
}
@Override
public Tag deleteField(FieldKey genericKey) throws IllegalArgumentException, UnsupportedFieldException {
checkArgNotNull(genericKey, CANNOT_BE_NULL, "genericKey");
if (getSupportedFields().contains(genericKey)) {
deleteField(genericKey.name());
} else {
throw new UnsupportedFieldException(genericKey.name());
}
return this;
}
@Override
public Optional<TagField> getFirstField(FieldKey genericKey) throws IllegalArgumentException, UnsupportedFieldException {
checkArgNotNull(genericKey, CANNOT_BE_NULL, genericKey);
if (getSupportedFields().contains(genericKey)) {
return getFirstField(genericKey.name());
} else {
throw new UnsupportedFieldException(genericKey.name());
}
}
@Override
public List<Artwork> getArtworkList() throws UnsupportedFieldException {
return Collections.emptyList();
}
@Override
public TagField createArtwork(Artwork artwork) throws UnsupportedFieldException, FieldDataInvalidException {
throw new UnsupportedFieldException(FieldKey.COVER_ART.name());
}
@Override
public ImmutableSet<FieldKey> getSupportedFields() {
return supportedKeys;
}
/**
* Implementations of {@link TagTextField} for use with
* "ISO-8859-1" strings.
*
* @author Raphaël Slinckx
*/
protected static clreplaced GenericTagTextField implements TagTextField {
/**
* Stores the identifier.
*/
private final String id;
/**
* Stores the string.
*/
private String content;
/**
* Creates an instance.
*
* @param fieldId The identifier.
* @param initialContent The string.
*/
public GenericTagTextField(String fieldId, String initialContent) {
id = fieldId;
content = initialContent;
}
@Override
public void copyContent(TagField field) {
if (field instanceof TagTextField) {
content = ((TagTextField) field).getContent();
}
}
@Override
public String getContent() {
return content;
}
@Override
public void setContent(String s) {
content = s;
}
@Override
public Charset getEncoding() {
return StandardCharsets.ISO_8859_1;
}
@Override
public void setEncoding(Charset s) {
/* Not allowed */
}
@Override
public String getId() {
return id;
}
@Override
public byte[] getRawContent() {
return content == null ? EMPTY_BYTE_ARRAY : content.getBytes(getEncoding());
}
@Override
public boolean isBinary() {
return false;
}
@Override
public void isBinary(boolean b) {
/* not supported */
}
@Override
public boolean isCommon() {
return true;
}
@Override
public boolean isEmpty() {
return "".equals(content);
}
@NotNull
@Override
public String toString() {
return getContent();
}
}
}
19
Source : ImmutableExample3.java
with Apache License 2.0
from ukihsoroy
with Apache License 2.0
from ukihsoroy
public clreplaced ImmutableExample3 {
private final static ImmutableList<Integer> list = ImmutableList.of(1, 2, 3);
private final static ImmutableSet<Integer> set = ImmutableSet.copyOf(list);
private final static ImmutableMap<Integer, Integer> map = ImmutableMap.of(1, 2, 3, 4);
private final static ImmutableMap<Integer, Integer> map2 = ImmutableMap.<Integer, Integer>builder().put(1, 2).put(3, 4).put(5, 6).build();
public static void main(String[] args) {
// list.add(4);
// set.add(5);
// map.put(1, 2);
map2.put(1, 2);
}
}
19
Source : StreamTypeRecord.java
with MIT License
from uber
with MIT License
from uber
/**
* An immutable model describing a clreplaced from a stream-based API such as RxJava.
*/
public clreplaced StreamTypeRecord {
private final TypePredicate typePredicate;
// Names of all the methods of this type that behave like .filter(...) (must take exactly 1
// argument)
private final ImmutableSet<String> filterMethodSigs;
private final ImmutableSet<String> filterMethodSimpleNames;
// Names and relevant arguments of all the methods of this type that behave like .map(...) for
// the purposes of this checker (the listed arguments are those that take the potentially
// filtered objects from the stream)
private final ImmutableMap<String, MaplikeMethodRecord> mapMethodSigToRecord;
private final ImmutableMap<String, MaplikeMethodRecord> mapMethodSimpleNameToRecord;
// List of methods of java.util.stream.Stream through which we just propagate the nullability
// information of the last call, e.g. m() in Observable.filter(...).m().map(...) means the
// nullability information from filter(...) should still be propagated to map(...), ignoring the
// interleaving call to m().
// We replacedume that if m() is a preplaced-through method for Observable, so are m(a1), m(a1,a2), etc.
// If that is ever not the case, we can use a more complex method subsignature her.
private final ImmutableSet<String> preplacedthroughMethodSigs;
private final ImmutableSet<String> preplacedthroughMethodSimpleNames;
public StreamTypeRecord(TypePredicate typePredicate, ImmutableSet<String> filterMethodSigs, ImmutableSet<String> filterMethodSimpleNames, ImmutableMap<String, MaplikeMethodRecord> mapMethodSigToRecord, ImmutableMap<String, MaplikeMethodRecord> mapMethodSimpleNameToRecord, ImmutableSet<String> preplacedthroughMethodSigs, ImmutableSet<String> preplacedthroughMethodSimpleNames) {
this.typePredicate = typePredicate;
this.filterMethodSigs = filterMethodSigs;
this.filterMethodSimpleNames = filterMethodSimpleNames;
this.mapMethodSigToRecord = mapMethodSigToRecord;
this.mapMethodSimpleNameToRecord = mapMethodSimpleNameToRecord;
this.preplacedthroughMethodSigs = preplacedthroughMethodSigs;
this.preplacedthroughMethodSimpleNames = preplacedthroughMethodSimpleNames;
}
public boolean matchesType(Type type, VisitorState state) {
return typePredicate.apply(type, state);
}
public boolean isFilterMethod(Symbol.MethodSymbol methodSymbol) {
return filterMethodSigs.contains(methodSymbol.toString()) || filterMethodSimpleNames.contains(methodSymbol.getQualifiedName().toString());
}
public boolean isMapMethod(Symbol.MethodSymbol methodSymbol) {
return mapMethodSigToRecord.containsKey(methodSymbol.toString()) || mapMethodSimpleNameToRecord.containsKey(methodSymbol.getQualifiedName().toString());
}
public MaplikeMethodRecord getMaplikeMethodRecord(Symbol.MethodSymbol methodSymbol) {
MaplikeMethodRecord record = mapMethodSigToRecord.get(methodSymbol.toString());
if (record == null) {
record = mapMethodSimpleNameToRecord.get(methodSymbol.getQualifiedName().toString());
}
return record;
}
public boolean isPreplacedthroughMethod(Symbol.MethodSymbol methodSymbol) {
return preplacedthroughMethodSigs.contains(methodSymbol.toString()) || preplacedthroughMethodSimpleNames.contains(methodSymbol.getQualifiedName().toString());
}
}
19
Source : ErrorProneCLIFlagsConfig.java
with MIT License
from uber
with MIT License
from uber
/**
* provides nullability configuration based on additional flags preplaceded to ErrorProne via
* "-XepOpt:[Namespace:]FlagName[=Value]". See. http://errorprone.info/docs/flags
*/
final clreplaced ErrorProneCLIFlagsConfig extends AbstractConfig {
private static final String BASENAME_REGEX = ".*/([^/]+)\\.[ja]ar$";
static final String EP_FL_NAMESPACE = "NullAway";
static final String FL_ANNOTATED_PACKAGES = EP_FL_NAMESPACE + ":AnnotatedPackages";
static final String FL_replacedERTS_ENABLED = EP_FL_NAMESPACE + ":replacedertsEnabled";
static final String FL_UNANNOTATED_SUBPACKAGES = EP_FL_NAMESPACE + ":UnannotatedSubPackages";
static final String FL_CLreplacedES_TO_EXCLUDE = EP_FL_NAMESPACE + ":ExcludedClreplacedes";
static final String FL_EXHAUSTIVE_OVERRIDE = EP_FL_NAMESPACE + ":ExhaustiveOverride";
static final String FL_KNOWN_INITIALIZERS = EP_FL_NAMESPACE + ":KnownInitializers";
static final String FL_CLreplaced_ANNOTATIONS_TO_EXCLUDE = EP_FL_NAMESPACE + ":ExcludedClreplacedAnnotations";
static final String FL_SUGGEST_SUPPRESSIONS = EP_FL_NAMESPACE + ":SuggestSuppressions";
static final String FL_GENERATED_UNANNOTATED = EP_FL_NAMESPACE + ":TreatGeneratedAsUnannotated";
static final String FL_ACKNOWLEDGE_ANDROID_RECENT = EP_FL_NAMESPACE + ":AcknowledgeAndroidRecent";
static final String FL_EXCLUDED_FIELD_ANNOT = EP_FL_NAMESPACE + ":ExcludedFieldAnnotations";
static final String FL_INITIALIZER_ANNOT = EP_FL_NAMESPACE + ":CustomInitializerAnnotations";
static final String FL_CTNN_METHOD = EP_FL_NAMESPACE + ":CastToNonNullMethod";
static final String FL_EXTERNAL_INIT_ANNOT = EP_FL_NAMESPACE + ":ExternalInitAnnotations";
static final String FL_UNANNOTATED_CLreplacedES = EP_FL_NAMESPACE + ":UnannotatedClreplacedes";
static final String FL_ACKNOWLEDGE_RESTRICTIVE = EP_FL_NAMESPACE + ":AcknowledgeRestrictiveAnnotations";
static final String FL_CHECK_OPTIONAL_EMPTINESS = EP_FL_NAMESPACE + ":CheckOptionalEmptiness";
static final String FL_CHECK_CONTRACTS = EP_FL_NAMESPACE + ":CheckContracts";
static final String FL_HANDLE_TEST_replacedERTION_LIBRARIES = EP_FL_NAMESPACE + ":HandleTestreplacedertionLibraries";
static final String FL_OPTIONAL_CLreplaced_PATHS = EP_FL_NAMESPACE + ":CheckOptionalEmptinessCustomClreplacedes";
static final String FL_SUPPRESS_COMMENT = EP_FL_NAMESPACE + ":AutoFixSuppressionComment";
/**
* --- JarInfer configs ---
*/
static final String FL_JI_ENABLED = EP_FL_NAMESPACE + ":JarInferEnabled";
static final String FL_JI_USE_RETURN = EP_FL_NAMESPACE + ":JarInferUseReturnAnnotations";
static final String FL_JI_REGEX_MODEL_PATH = EP_FL_NAMESPACE + ":JarInferRegexStripModelJar";
static final String FL_JI_REGEX_CODE_PATH = EP_FL_NAMESPACE + ":JarInferRegexStripCodeJar";
static final String FL_ERROR_URL = EP_FL_NAMESPACE + ":ErrorURL";
private static final String DELIMITER = ",";
static final ImmutableSet<String> DEFAULT_CLreplaced_ANNOTATIONS_TO_EXCLUDE = ImmutableSet.of("lombok.Generated");
static final ImmutableSet<String> DEFAULT_KNOWN_INITIALIZERS = ImmutableSet.of("android.view.View.onFinishInflate", "android.app.Service.onCreate", "android.app.Activity.onCreate", "android.app.Fragment.onCreate", "android.app.Fragment.onAttach", "android.app.Fragment.onCreateView", "android.app.Fragment.onViewCreated", "android.app.Application.onCreate", "javax.annotation.processing.Processor.init", // Support Library v4 - can be removed once AndroidX becomes more popular
"android.support.v4.app.ActivityCompat.onCreate", "android.support.v4.app.Fragment.onCreate", "android.support.v4.app.Fragment.onAttach", "android.support.v4.app.Fragment.onCreateView", "android.support.v4.app.Fragment.onViewCreated", // Support Library v4 - can be removed once AndroidX becomes more popular
"androidx.core.app.ActivityCompat.onCreate", "androidx.fragment.app.Fragment.onCreate", "androidx.fragment.app.Fragment.onAttach", "androidx.fragment.app.Fragment.onCreateView", "androidx.fragment.app.Fragment.onActivityCreated", "androidx.fragment.app.Fragment.onViewCreated", // Multidex app
"android.support.multidex.Application.onCreate");
static final ImmutableSet<String> DEFAULT_INITIALIZER_ANNOT = ImmutableSet.of("org.junit.Before", "org.junit.BeforeClreplaced", "org.junit.jupiter.api.BeforeAll", // + Anything with @Initializer as its "simple name"
"org.junit.jupiter.api.BeforeEach");
static final ImmutableSet<String> DEFAULT_EXTERNAL_INIT_ANNOT = ImmutableSet.of("lombok.Builder");
static final ImmutableSet<String> DEFAULT_EXCLUDED_FIELD_ANNOT = ImmutableSet.of(// no explicit initialization when there is dependency injection
"jakarta.inject.Inject", // no explicit initialization when there is dependency injection
"javax.inject.Inject", "com.google.errorprone.annotations.concurrent.LazyInit", "org.checkerframework.checker.nullness.qual.MonotonicNonNull");
private static final String DEFAULT_URL = "http://t.uber.com/nullaway";
ErrorProneCLIFlagsConfig(ErrorProneFlags flags) {
if (!flags.get(FL_ANNOTATED_PACKAGES).isPresent()) {
throw new IllegalStateException("DO NOT report an issue to Error Prone for this crash! NullAway configuration is " + "incorrect. " + "Must specify annotated packages, using the " + "-XepOpt:" + FL_ANNOTATED_PACKAGES + "=[...] flag. If you feel you have gotten this message in error report an issue" + " at https://github.com/uber/NullAway/issues.");
}
annotatedPackages = getPackagePattern(getFlagStringSet(flags, FL_ANNOTATED_PACKAGES));
unannotatedSubPackages = getPackagePattern(getFlagStringSet(flags, FL_UNANNOTATED_SUBPACKAGES));
sourceClreplacedesToExclude = getFlagStringSet(flags, FL_CLreplacedES_TO_EXCLUDE);
unannotatedClreplacedes = getFlagStringSet(flags, FL_UNANNOTATED_CLreplacedES);
knownInitializers = getKnownInitializers(getFlagStringSet(flags, FL_KNOWN_INITIALIZERS, DEFAULT_KNOWN_INITIALIZERS));
excludedClreplacedAnnotations = getFlagStringSet(flags, FL_CLreplaced_ANNOTATIONS_TO_EXCLUDE, DEFAULT_CLreplaced_ANNOTATIONS_TO_EXCLUDE);
initializerAnnotations = getFlagStringSet(flags, FL_INITIALIZER_ANNOT, DEFAULT_INITIALIZER_ANNOT);
externalInitAnnotations = getFlagStringSet(flags, FL_EXTERNAL_INIT_ANNOT, DEFAULT_EXTERNAL_INIT_ANNOT);
isExhaustiveOverride = flags.getBoolean(FL_EXHAUSTIVE_OVERRIDE).orElse(false);
isSuggestSuppressions = flags.getBoolean(FL_SUGGEST_SUPPRESSIONS).orElse(false);
isAcknowledgeRestrictive = flags.getBoolean(FL_ACKNOWLEDGE_RESTRICTIVE).orElse(false);
checkOptionalEmptiness = flags.getBoolean(FL_CHECK_OPTIONAL_EMPTINESS).orElse(false);
checkContracts = flags.getBoolean(FL_CHECK_CONTRACTS).orElse(false);
handleTestreplacedertionLibraries = flags.getBoolean(FL_HANDLE_TEST_replacedERTION_LIBRARIES).orElse(false);
treatGeneratedAsUnannotated = flags.getBoolean(FL_GENERATED_UNANNOTATED).orElse(false);
acknowledgeAndroidRecent = flags.getBoolean(FL_ACKNOWLEDGE_ANDROID_RECENT).orElse(false);
replacedertsEnabled = flags.getBoolean(FL_replacedERTS_ENABLED).orElse(false);
fieldAnnotPattern = getPackagePattern(getFlagStringSet(flags, FL_EXCLUDED_FIELD_ANNOT, DEFAULT_EXCLUDED_FIELD_ANNOT));
castToNonNullMethod = flags.get(FL_CTNN_METHOD).orElse(null);
autofixSuppressionComment = flags.get(FL_SUPPRESS_COMMENT).orElse("");
optionalClreplacedPaths = new ImmutableSet.Builder<String>().addAll(getFlagStringSet(flags, FL_OPTIONAL_CLreplaced_PATHS)).add("java.util.Optional").build();
if (autofixSuppressionComment.contains("\n")) {
throw new IllegalStateException("Invalid -XepOpt:" + FL_SUPPRESS_COMMENT + " value. Comment must be single line.");
}
/**
* --- JarInfer configs ---
*/
jarInferEnabled = flags.getBoolean(FL_JI_ENABLED).orElse(false);
jarInferUseReturnAnnotations = flags.getBoolean(FL_JI_USE_RETURN).orElse(false);
// The defaults of these two options translate to: remove .aar/.jar from the file name, and also
// implicitly mean that NullAway will search for jarinfer models in the same jar which contains
// the replacedyzed clreplacedes.
jarInferRegexStripModelJarName = flags.get(FL_JI_REGEX_MODEL_PATH).orElse(BASENAME_REGEX);
jarInferRegexStripCodeJarName = flags.get(FL_JI_REGEX_CODE_PATH).orElse(BASENAME_REGEX);
errorURL = flags.get(FL_ERROR_URL).orElse(DEFAULT_URL);
if (acknowledgeAndroidRecent && !isAcknowledgeRestrictive) {
throw new IllegalStateException("-XepOpt:" + FL_ACKNOWLEDGE_ANDROID_RECENT + " should only be set when -XepOpt:" + FL_ACKNOWLEDGE_RESTRICTIVE + " is also set");
}
}
private static ImmutableSet<String> getFlagStringSet(ErrorProneFlags flags, String flagName) {
Optional<String> flagValue = flags.get(flagName);
if (flagValue.isPresent()) {
return ImmutableSet.copyOf(flagValue.get().split(DELIMITER));
}
return ImmutableSet.of();
}
private static ImmutableSet<String> getFlagStringSet(ErrorProneFlags flags, String flagName, ImmutableSet<String> defaults) {
Set<String> combined = new LinkedHashSet<>(defaults);
Optional<String> flagValue = flags.get(flagName);
if (flagValue.isPresent()) {
Collections.addAll(combined, flagValue.get().split(DELIMITER));
}
return ImmutableSet.copyOf(combined);
}
}
19
Source : ErrorBuilder.java
with MIT License
from uber
with MIT License
from uber
private boolean symbolIsExcludedClreplacedSymbol(Symbol symbol) {
if (symbol instanceof Symbol.ClreplacedSymbol) {
ImmutableSet<String> excludedClreplacedAnnotations = config.getExcludedClreplacedAnnotations();
return ((Symbol.ClreplacedSymbol) symbol).getAnnotationMirrors().stream().map(anno -> anno.getAnnotationType().toString()).anyMatch(excludedClreplacedAnnotations::contains);
}
return false;
}
19
Source : CoreNullnessStoreInitializer.java
with MIT License
from uber
with MIT License
from uber
private static NullnessStore lambdaInitialStore(UnderlyingAST.CFGLambda underlyingAST, List<LocalVariableNode> parameters, Handler handler, Context context, Types types, Config config) {
// include nullness info for locals from enclosing environment
EnclosingEnvironmentNullness environmentNullness = EnclosingEnvironmentNullness.instance(context);
NullnessStore environmentMapping = Objects.requireNonNull(environmentNullness.getEnvironmentMapping(underlyingAST.getLambdaTree()), "no environment stored for lambda");
NullnessStore.Builder result = environmentMapping.toBuilder();
LambdaExpressionTree code = underlyingAST.getLambdaTree();
// need to check annotation for i'th parameter of functional interface declaration
Symbol.MethodSymbol fiMethodSymbol = NullabilityUtil.getFunctionalInterfaceMethod(code, types);
com.sun.tools.javac.util.List<Symbol.VarSymbol> fiMethodParameters = fiMethodSymbol.getParameters();
ImmutableSet<Integer> nullableParamsFromHandler = handler.onUnannotatedInvocationGetExplicitlyNullablePositions(context, fiMethodSymbol, ImmutableSet.of());
for (int i = 0; i < parameters.size(); i++) {
LocalVariableNode param = parameters.get(i);
VariableTree variableTree = code.getParameters().get(i);
Element element = param.getElement();
Nullness replacedumed;
// we treat lambda parameters differently; they "inherit" the nullability of the
// corresponding functional interface parameter, unless they are explicitly annotated
if (Nullness.hasNullableAnnotation((Symbol) element, config)) {
replacedumed = NULLABLE;
} else if (!NullabilityUtil.lambdaParamIsImplicitlyTyped(variableTree)) {
// the parameter has a declared type with no @Nullable annotation
// treat as non-null
replacedumed = NONNULL;
} else {
if (NullabilityUtil.isUnannotated(fiMethodSymbol, config)) {
// replacedume parameter is non-null unless handler tells us otherwise
replacedumed = nullableParamsFromHandler.contains(i) ? NULLABLE : NONNULL;
} else {
replacedumed = Nullness.hasNullableAnnotation(fiMethodParameters.get(i), config) ? NULLABLE : NONNULL;
}
}
result.setInformation(AccessPath.fromLocal(param), replacedumed);
}
result = handler.onDataflowInitialStore(underlyingAST, parameters, result);
return result.build();
}
19
Source : MethodAnnotationsRecord.java
with MIT License
from uber
with MIT License
from uber
/**
* A record describing the annotations replacedociated with a java method and its arguments.
*/
final clreplaced MethodAnnotationsRecord {
private final ImmutableSet<String> methodAnnotations;
// 0 means receiver
private final ImmutableMap<Integer, ImmutableSet<String>> argumentAnnotations;
MethodAnnotationsRecord(ImmutableSet<String> methodAnnotations, ImmutableMap<Integer, ImmutableSet<String>> argumentAnnotations) {
this.methodAnnotations = methodAnnotations;
this.argumentAnnotations = argumentAnnotations;
}
ImmutableSet<String> getMethodAnnotations() {
return methodAnnotations;
}
ImmutableMap<Integer, ImmutableSet<String>> getArgumentAnnotations() {
return argumentAnnotations;
}
}
19
Source : BytecodeAnnotator.java
with MIT License
from uber
with MIT License
from uber
/**
* Annotates the given methods and method parameters with the specified annotations using ASM.
*/
public final clreplaced BytecodeAnnotator {
private static boolean debug = false;
private static void LOG(boolean cond, String tag, String msg) {
if (cond)
System.out.println("[" + tag + "] " + msg);
}
public static final String javaxNullableDesc = "Ljavax/annotation/Nullable;";
public static final String javaxNonnullDesc = "Ljavax/annotation/Nonnull;";
// Consider android.support.annotation.* as a configuration option for older code?
public static final String androidNullableDesc = "Landroidx/annotation/Nullable;";
public static final String androidNonnullDesc = "Landroidx/annotation/NonNull;";
public static final ImmutableSet<String> NULLABLE_ANNOTATIONS = ImmutableSet.of(javaxNullableDesc, androidNullableDesc, // We don't support adding the annotations below, but they would still be redundant,
// specially when converted by tools which rewrite these sort of annotation (often
// to their androidx.* variant)
"Landroid/support/annotation/Nullable;", "Lorg/jetbrains/annotations/Nullable;");
public static final ImmutableSet<String> NONNULL_ANNOTATIONS = ImmutableSet.of(javaxNonnullDesc, androidNonnullDesc, // See above
"Landroid/support/annotation/NonNull;", "Lorg/jetbrains/annotations/NotNull;");
public static final Sets.SetView<String> NULLABILITY_ANNOTATIONS = Sets.union(NULLABLE_ANNOTATIONS, NONNULL_ANNOTATIONS);
// Constants used for signed jar processing
private static final String SIGNED_JAR_ERROR_MESSAGE = "JarInfer will not process signed jars by default. " + "Please take one of the following actions:\n" + "\t1) Remove the signature from the original jar before preplaceding it to jarinfer,\n" + "\t2) Preplaced the --strip-jar-signatures flag to JarInfer and the tool will remove signature " + "metadata for you, or\n" + "\t3) Exclude this jar from those being processed by JarInfer.";
private static final String BASE64_PATTERN = "(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?";
private static final String DIGEST_ENTRY_PATTERN = "Name: [A-Za-z0-9/\\$\\n\\s\\-\\.]+[A-Za-z0-9]\\nSHA-256-Digest: " + BASE64_PATTERN;
private static boolean annotationsShouldBeVisible(String nullableDesc) {
if (nullableDesc.equals(javaxNullableDesc)) {
return true;
} else if (nullableDesc.equals(androidNullableDesc)) {
return false;
} else {
throw new Error("Unknown nullness annotation visibility");
}
}
private static boolean listHasNullnessAnnotations(List<AnnotationNode> annotationList) {
if (annotationList != null) {
for (AnnotationNode node : annotationList) {
if (NULLABILITY_ANNOTATIONS.contains(node.desc)) {
return true;
}
}
}
return false;
}
/**
* Returns true if any part of this method already has @Nullable/@NonNull annotations, in which
* case we skip it, replaceduming that the developer already captured the desired spec.
*
* @param method The method node.
* @return true iff either the return or any parameter formal has a nullness annotation.
*/
private static boolean hasNullnessAnnotations(MethodNode method) {
if (listHasNullnessAnnotations(method.visibleAnnotations) || listHasNullnessAnnotations(method.invisibleAnnotations)) {
return true;
}
if (method.visibleParameterAnnotations != null) {
for (List<AnnotationNode> annotationList : method.visibleParameterAnnotations) {
if (listHasNullnessAnnotations(annotationList)) {
return true;
}
}
}
if (method.invisibleParameterAnnotations != null) {
for (List<AnnotationNode> annotationList : method.invisibleParameterAnnotations) {
if (listHasNullnessAnnotations(annotationList)) {
return true;
}
}
}
return false;
}
private static void annotateBytecode(InputStream is, OutputStream os, MethodParamAnnotations nonnullParams, MethodReturnAnnotations nullableReturns, String nullableDesc, String nonnullDesc) throws IOException {
ClreplacedReader cr = new ClreplacedReader(is);
ClreplacedWriter cw = new ClreplacedWriter(0);
ClreplacedNode cn = new ClreplacedNode(Opcodes.ASM7);
cr.accept(cn, 0);
String clreplacedName = cn.name.replace('/', '.');
List<MethodNode> methods = cn.methods;
for (MethodNode method : methods) {
// Skip methods that already have nullability annotations anywhere in their signature
if (hasNullnessAnnotations(method)) {
continue;
}
boolean visible = annotationsShouldBeVisible(nullableDesc);
String methodSignature = clreplacedName + "." + method.name + method.desc;
if (nullableReturns.contains(methodSignature)) {
// Add a @Nullable annotation on this method to indicate that the method can return null.
method.visitAnnotation(nullableDesc, visible);
LOG(debug, "DEBUG", "Added nullable return annotation for " + methodSignature);
}
Set<Integer> params = nonnullParams.get(methodSignature);
if (params != null) {
boolean isStatic = (method.access & Opcodes.ACC_STATIC) != 0;
for (Integer param : params) {
int paramNum = isStatic ? param : param - 1;
// Add a @Nonnull annotation on this parameter.
method.visitParameterAnnotation(paramNum, nonnullDesc, visible);
LOG(debug, "DEBUG", "Added nonnull parameter annotation for #" + param + " in " + methodSignature);
}
}
}
cn.accept(cw);
os.write(cw.toByteArray());
}
/**
* Annotates the methods and method parameters in the given clreplaced with the specified annotations.
*
* @param is InputStream for the input clreplaced.
* @param os OutputStream for the output clreplaced.
* @param nonnullParams Map from methods to their nonnull params.
* @param nullableReturns List of methods that return nullable.
* @param debug flag to output debug logs.
* @throws IOException if an error happens when reading or writing to clreplaced streams.
*/
public static void annotateBytecodeInClreplaced(InputStream is, OutputStream os, MethodParamAnnotations nonnullParams, MethodReturnAnnotations nullableReturns, boolean debug) throws IOException {
BytecodeAnnotator.debug = debug;
LOG(debug, "DEBUG", "nullableReturns: " + nullableReturns);
LOG(debug, "DEBUG", "nonnullParams: " + nonnullParams);
annotateBytecode(is, os, nonnullParams, nullableReturns, javaxNullableDesc, javaxNonnullDesc);
}
private static void copyAndAnnotateJarEntry(JarEntry jarEntry, InputStream is, JarOutputStream jarOS, MethodParamAnnotations nonnullParams, MethodReturnAnnotations nullableReturns, String nullableDesc, String nonnullDesc, boolean stripJarSignatures) throws IOException {
String entryName = jarEntry.getName();
if (entryName.endsWith(".clreplaced")) {
jarOS.putNextEntry(new ZipEntry(jarEntry.getName()));
annotateBytecode(is, jarOS, nonnullParams, nullableReturns, nullableDesc, nonnullDesc);
} else if (entryName.equals("META-INF/MANIFEST.MF")) {
// Read full file
StringBuilder stringBuilder = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
String currentLine;
while ((currentLine = br.readLine()) != null) {
stringBuilder.append(currentLine + "\n");
}
String manifestText = stringBuilder.toString();
// Check for evidence of jar signing, note that lines can be split if too long so regex
// matching line by line will have false negatives.
String manifestMinusDigests = manifestText.replaceAll(DIGEST_ENTRY_PATTERN, "");
if (!manifestText.equals(manifestMinusDigests) && !stripJarSignatures) {
throw new SignedJarException(SIGNED_JAR_ERROR_MESSAGE);
}
jarOS.putNextEntry(new ZipEntry(jarEntry.getName()));
jarOS.write(manifestMinusDigests.getBytes("UTF-8"));
} else if (entryName.startsWith("META-INF/") && (entryName.endsWith(".DSA") || entryName.endsWith(".RSA") || entryName.endsWith(".SF"))) {
if (!stripJarSignatures) {
throw new SignedJarException(SIGNED_JAR_ERROR_MESSAGE);
}
// the case where stripJarSignatures==true is handled by default by skipping these files
} else {
jarOS.putNextEntry(new ZipEntry(jarEntry.getName()));
jarOS.write(IOUtils.toByteArray(is));
}
jarOS.closeEntry();
}
/**
* Annotates the methods and method parameters in the clreplacedes in the given jar with the specified
* annotations.
*
* @param inputJar JarFile to annotate.
* @param jarOS OutputStream of the output jar file.
* @param nonnullParams Map from methods to their nonnull params.
* @param nullableReturns List of methods that return nullable.
* @param debug flag to output debug logs.
* @throws IOException if an error happens when reading or writing to jar or clreplaced streams.
*/
public static void annotateBytecodeInJar(JarFile inputJar, JarOutputStream jarOS, MethodParamAnnotations nonnullParams, MethodReturnAnnotations nullableReturns, boolean stripJarSignatures, boolean debug) throws IOException {
BytecodeAnnotator.debug = debug;
LOG(debug, "DEBUG", "nullableReturns: " + nullableReturns);
LOG(debug, "DEBUG", "nonnullParams: " + nonnullParams);
// Do not use JarInputStream in place of JarFile/JarEntry. JarInputStream misses MANIFEST.MF
// while iterating over the entries in the stream.
// Reference: https://bugs.openjdk.java.net/browse/JDK-8215788
// Note: we can't just put the code below inside stream().forach(), because it can throw
// IOException.
for (JarEntry jarEntry : (Iterable<JarEntry>) inputJar.stream()::iterator) {
InputStream is = inputJar.getInputStream(jarEntry);
copyAndAnnotateJarEntry(jarEntry, is, jarOS, nonnullParams, nullableReturns, javaxNullableDesc, javaxNonnullDesc, stripJarSignatures);
}
}
/**
* Annotates the methods and method parameters in the clreplacedes in "clreplacedes.jar" in the given aar
* file with the specified annotations.
*
* @param inputZip AarFile to annotate.
* @param zipOS OutputStream of the output aar file.
* @param nonnullParams Map from methods to their nonnull params.
* @param nullableReturns List of methods that return nullable.
* @param debug flag to output debug logs.
* @throws IOException if an error happens when reading or writing to AAR/JAR/clreplaced streams.
*/
public static void annotateBytecodeInAar(ZipFile inputZip, ZipOutputStream zipOS, MethodParamAnnotations nonnullParams, MethodReturnAnnotations nullableReturns, boolean stripJarSignatures, boolean debug) throws IOException {
BytecodeAnnotator.debug = debug;
LOG(debug, "DEBUG", "nullableReturns: " + nullableReturns);
LOG(debug, "DEBUG", "nonnullParams: " + nonnullParams);
// Error Prone doesn't like usages of the old Java Enumerator APIs. ZipFile does not implement
// Iterable, and likely never will (see https://bugs.openjdk.java.net/browse/JDK-6581715).
// Additionally, inputZip.stream() returns a Stream<? extends ZipEntry>, and a for-each loop
// has trouble handling the corresponding ::iterator method reference. So this seems like the
// best remaining way:
Iterator<? extends ZipEntry> zipIterator = inputZip.stream().iterator();
while (zipIterator.hasNext()) {
ZipEntry zipEntry = zipIterator.next();
InputStream is = inputZip.getInputStream(zipEntry);
zipOS.putNextEntry(new ZipEntry(zipEntry.getName()));
if (zipEntry.getName().equals("clreplacedes.jar")) {
JarInputStream jarIS = new JarInputStream(is);
JarEntry inputJarEntry = jarIS.getNextJarEntry();
ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
JarOutputStream jarOS = new JarOutputStream(byteArrayOS);
while (inputJarEntry != null) {
copyAndAnnotateJarEntry(inputJarEntry, jarIS, jarOS, nonnullParams, nullableReturns, androidNullableDesc, androidNonnullDesc, stripJarSignatures);
inputJarEntry = jarIS.getNextJarEntry();
}
jarOS.flush();
jarOS.close();
zipOS.write(byteArrayOS.toByteArray());
} else {
zipOS.write(IOUtils.toByteArray(is));
}
zipOS.closeEntry();
}
}
}
19
Source : UseAutoDispose.java
with Apache License 2.0
from uber
with Apache License 2.0
from uber
/**
* Checker for subscriptions not binding to lifecycle in components with lifecycle. Use
* -XepOpt:TypesWithScope flag to add support for custom types with scope. Use
* -XepOpt:OverrideScopes to only run the EP check on your custom types with scope. The sample
* configuration for Conductor:
*
* <pre><code>
* -XepOpt:TypesWithScope=com.bluelinelabs.conductor.Controller,android.app.Activity
* -XepOpt:OverrideScopes=<true|false>
* </code></pre>
*/
@AutoService(BugChecker.clreplaced)
@BugPattern(name = "AutoDispose", summary = "Missing Disposable handling: Apply AutoDispose or cache " + "the Disposable instance manually and enable lenient mode.", tags = CONCURRENCY, severity = ERROR)
public final clreplaced UseAutoDispose extends AbstractReturnValueIgnored implements MethodInvocationTreeMatcher {
private static final String SUBSCRIBE = "subscribe";
private static final String SUBSCRIBE_WITH = "subscribeWith";
private static final ImmutableSet<String> DEFAULT_CLreplacedES_WITH_LIFECYCLE = new ImmutableSet.Builder<String>().add("android.app.Activity").add("android.app.Fragment").add("androidx.fragment.app.Fragment").add("androidx.lifecycle.LifecycleOwner").add("autodispose2.ScopeProvider").build();
private static final Matcher<ExpressionTree> SUBSCRIBE_METHOD = anyOf(instanceMethod().onDescendantOf("io.reactivex.rxjava3.core.Single").namedAnyOf(SUBSCRIBE, SUBSCRIBE_WITH), instanceMethod().onDescendantOf("io.reactivex.rxjava3.core.Observable").namedAnyOf(SUBSCRIBE, SUBSCRIBE_WITH), instanceMethod().onDescendantOf("io.reactivex.rxjava3.core.Completable").namedAnyOf(SUBSCRIBE, SUBSCRIBE_WITH), instanceMethod().onDescendantOf("io.reactivex.rxjava3.core.Flowable").namedAnyOf(SUBSCRIBE, SUBSCRIBE_WITH), instanceMethod().onDescendantOf("io.reactivex.rxjava3.core.Maybe").namedAnyOf(SUBSCRIBE, SUBSCRIBE_WITH), instanceMethod().onDescendantOf("io.reactivex.rxjava3.parallel.ParallelFlowable").named(SUBSCRIBE));
private final Matcher<ExpressionTree> matcher;
private final boolean lenient;
// Default constructor used for SPI
@SuppressWarnings("unused")
public UseAutoDispose() {
this(ErrorProneFlags.empty());
}
// Public for ErrorProne
@SuppressWarnings("WeakerAccess")
public UseAutoDispose(ErrorProneFlags flags) {
Optional<ImmutableSet<String>> inputClreplacedes = flags.getList("TypesWithScope").map(ImmutableSet::copyOf);
Optional<Boolean> overrideScopes = flags.getBoolean("OverrideScopes");
ImmutableSet<String> clreplacedesWithScope = getClreplacedesWithScope(inputClreplacedes, overrideScopes);
matcher = allOf(SUBSCRIBE_METHOD, matcher(clreplacedesWithScope));
lenient = flags.getBoolean("Lenient").orElse(false);
}
@Override
boolean lenient() {
return lenient;
}
@Override
public Matcher<? super ExpressionTree> specializedMatcher() {
return matcher;
}
@Override
protected boolean capturedTypeAllowed(Type type, VisitorState state) {
return isSubtype(type, state.getTypeFromString("io.reactivex.rxjava3.disposables.Disposable"), state) || isSubtype(type, state.getTypeFromString("org.reactivestreams.Subscription"), state);
}
@Override
public String linkUrl() {
return "https://github.com/uber/AutoDispose/wiki/Error-Prone-Checker";
}
/**
* Return the lifecycle clreplacedes on which to apply the Error-Prone check.
*
* @param inputClreplacedes the custom scopes defined by user.
* @param overrideScopes whether the custom scopes are exclusive.
* @return the clreplacedes on which to apply the error-prone check.
*/
private static ImmutableSet<String> getClreplacedesWithScope(Optional<ImmutableSet<String>> inputClreplacedes, Optional<Boolean> overrideScopes) {
if (inputClreplacedes.isPresent()) {
if (overrideScopes.isPresent() && overrideScopes.get()) {
// The custom scopes are exclusive, just return that.
return inputClreplacedes.get();
} else {
// The custom scopes aren't exclusive, so bundle them together with default scopes.
return ImmutableSet.<String>builder().addAll(DEFAULT_CLreplacedES_WITH_LIFECYCLE).addAll(inputClreplacedes.get()).build();
}
} else {
// No custom scopes. Return default scopes.
return DEFAULT_CLreplacedES_WITH_LIFECYCLE;
}
}
private static Matcher<ExpressionTree> matcher(Set<String> clreplacedesWithLifecycle) {
return (Matcher<ExpressionTree>) (tree, state) -> {
ClreplacedTree enclosingClreplaced = findEnclosingNode(state.getPath(), ClreplacedTree.clreplaced);
Type.ClreplacedType enclosingClreplacedType = getType(enclosingClreplaced);
return clreplacedesWithLifecycle.stream().map(clreplacedWithLifecycle -> {
Type lifecycleType = state.getTypeFromString(clreplacedWithLifecycle);
return isSubtype(enclosingClreplacedType, lifecycleType, state);
}).filter(Boolean::booleanValue).findFirst().orElse(false);
};
}
}
19
Source : AbstractReturnValueIgnored.java
with Apache License 2.0
from uber
with Apache License 2.0
from uber
/**
* An abstract base clreplaced to match method invocations in which the return value is not used.
*
* <p>Adapted from https://github
* .com/google/error-prone/blob/976ab7c62771d54dfe11bde9b01dc301d364957b/core/src/main/java/com
* /google/errorprone/bugpatterns/AbstractReturnValueIgnored.java
*
* @author [email protected] (Eddie Aftandilian)
*/
abstract clreplaced AbstractReturnValueIgnored extends BugChecker implements MethodInvocationTreeMatcher, MemberReferenceTreeMatcher {
@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
return matchMethodInvocationNew(tree, state);
}
private Description matchMethodInvocationNew(MethodInvocationTree tree, VisitorState state) {
boolean matches = specializedMatcher().matches(tree, state);
if (!matches) {
return Description.NO_MATCH;
}
if (lenient()) {
boolean isUnusedReturnValue = allOf(parentNode(anyOf(AbstractReturnValueIgnored::isVoidReturningLambdaExpression, Matchers.kindIs(Kind.EXPRESSION_STATEMENT))), not(methodSelect(toType(IdentifierTree.clreplaced, identifierHasName("super")))), not((t, s) -> isVoidType(getType(t), s)), not(AbstractReturnValueIgnored::expectedExceptionTest)).matches(tree, state);
if (!isUnusedReturnValue) {
if (isValidReturnValueType(tree, state)) {
return Description.NO_MATCH;
}
}
}
return describe(tree, state);
}
@Override
public Description matchMemberReference(MemberReferenceTree tree, VisitorState state) {
boolean matches = specializedMatcher().matches(tree, state);
if (!matches) {
return Description.NO_MATCH;
}
if (lenient()) {
boolean isUnusedReturnValue = allOf(AbstractReturnValueIgnored::isNotConstructorReference, AbstractReturnValueIgnored::isVoidReturningMethodReferenceExpression, // Skip cases where the method we're referencing really does return void. We're
// only
// looking for cases where the referenced method does not return void, but it's
// being
// used on a void-returning functional interface.
not((t, s) -> isVoidType(getSymbol(tree).getReturnType(), s)), not((t, s) -> isThrowingFunctionalInterface(s, ((JCMemberReference) t).type))).matches(tree, state);
if (!isUnusedReturnValue) {
if (isValidReturnValueType(tree, state)) {
return Description.NO_MATCH;
}
}
}
return describeMatch(tree);
}
private static boolean isNotConstructorReference(MemberReferenceTree tree, VisitorState state) {
return tree.getMode() == ReferenceMode.INVOKE;
}
private static boolean isVoidReturningMethodReferenceExpression(MemberReferenceTree tree, VisitorState state) {
return functionalInterfaceReturnsExactlyVoid(((JCMemberReference) tree).type, state);
}
private static boolean isVoidReturningLambdaExpression(Tree tree, VisitorState state) {
if (!(tree instanceof LambdaExpressionTree)) {
return false;
}
return functionalInterfaceReturnsExactlyVoid(((JCLambda) tree).type, state);
}
/**
* Checks that the return value of a functional interface is void. Note, we do not use
* ASTHelpers.isVoidType here, return values of Void are actually type-checked. Only
* void-returning functions silently ignore return values of any type.
*/
private static boolean functionalInterfaceReturnsExactlyVoid(Type interfaceType, VisitorState state) {
return state.getTypes().findDescriptorType(interfaceType).getReturnType().getKind() == TypeKind.VOID;
}
private static boolean methodCallInDeclarationOfThrowingRunnable(VisitorState state) {
// Find the nearest definitional context for this method invocation
// (i.e.: the nearest surrounding clreplaced or lambda)
Tree tree = null;
out: for (Tree t : state.getPath()) {
switch(t.getKind()) {
case LAMBDA_EXPRESSION:
case CLreplaced:
tree = t;
break out;
// fall out, to loop again
default:
}
}
if (tree == null) {
// Huh. Shouldn't happen.
return false;
}
return isThrowingFunctionalInterface(state, getType(tree));
}
private static boolean isThrowingFunctionalInterface(VisitorState state, Type clazzType) {
return CLreplacedES_CONSIDERED_THROWING.stream().anyMatch(t -> ASTHelpers.isSubtype(clazzType, state.getTypeFromString(t), state));
}
/**
* {@code @FunctionalInterface}'s that are generally used as a lambda expression for 'a block of
* code that's going to fail', e.g.:
*
* <p>{@code replacedertThrows(FooException.clreplaced, () -> myCodeThatThrowsAnException());
* errorCollector.checkThrows(FooException.clreplaced, () -> myCodeThatThrowsAnException()); }
*
* <p>// TODO(glorioso): Consider a meta-annotation like @LikelyToThrow instead/in addition?
*/
private static final ImmutableSet<String> CLreplacedES_CONSIDERED_THROWING = ImmutableSet.of("org.junit.function.ThrowingRunnable", "org.junit.jupiter.api.function.Executable", "org.replacedertj.core.api.Throwablereplacedert$ThrowingCallable", "com.google.truth.ExpectFailure.replacedertionCallback", "com.google.truth.ExpectFailure.DelegatedreplacedertionCallback", "com.google.truth.ExpectFailure.StandardSubjectBuilderCallback", "com.google.truth.ExpectFailure.SimpleSubjectBuilderCallback");
/**
* Match whatever additional conditions concrete subclreplacedes want to match (a list of known
* side-effect-free methods, has a @OptionalCheckReturnValue annotation, etc.).
*/
public abstract Matcher<? super ExpressionTree> specializedMatcher();
/**
* @return {@code true} if this should be lenient and only run the checks if the return value is
* ignored, {@code false} if it should always check {@link #specializedMatcher()}.
*/
abstract boolean lenient();
/**
* Extracts the {@link Type} of the return value for {@link MethodInvocationTree} or {@link
* MemberReferenceTree}, then checks it against {@link #capturedTypeAllowed(Type, VisitorState)}.
*/
private boolean isValidReturnValueType(ExpressionTree tree, VisitorState state) {
Type returnType = null;
if (tree instanceof MethodInvocationTree) {
returnType = getReturnType(((JCMethodInvocation) tree).getMethodSelect());
} else if (tree instanceof MemberReferenceTree) {
// Get the return type of the target referenced interface
returnType = state.getTypes().findDescriptorType(((JCMemberReference) tree).type).getReturnType();
}
if (returnType != null) {
return capturedTypeAllowed(returnType, state);
}
return true;
}
/**
* Called only when lenient and return type is captured.
*
* @param type the {@link Type}
* @param state the {@link VisitorState}
* @return {@code true} if the captured return type is allowed in lenient cases, {@code false} if
* not.
*/
protected boolean capturedTypeAllowed(Type type, VisitorState state) {
return true;
}
private static Matcher<IdentifierTree> identifierHasName(final String name) {
return (item, state) -> item.getName().contentEquals(name);
}
/**
* Fixes the error by replacedigning the result of the call to the receiver reference, or deleting the
* method call.
*/
private Description describe(MethodInvocationTree methodInvocationTree, VisitorState state) {
// Find the root of the field access chain, i.e. a.intern().trim() ==> a.
ExpressionTree identifierExpr = ASTHelpers.getRootreplacedignable(methodInvocationTree);
String identifierStr = null;
Type identifierType = null;
if (identifierExpr != null) {
identifierStr = state.getSourceForNode(identifierExpr);
if (identifierExpr instanceof JCIdent) {
identifierType = ((JCIdent) identifierExpr).sym.type;
} else if (identifierExpr instanceof JCFieldAccess) {
identifierType = ((JCFieldAccess) identifierExpr).sym.type;
} else {
throw new IllegalStateException("Expected a JCIdent or a JCFieldAccess");
}
}
Type returnType = getReturnType(((JCMethodInvocation) methodInvocationTree).getMethodSelect());
Fix fix;
if (identifierStr != null && !"this".equals(identifierStr) && returnType != null && state.getTypes().isreplacedignable(returnType, identifierType)) {
// Fix by replacedigning the replacedigning the result of the call to the root receiver reference.
fix = SuggestedFix.prefixWith(methodInvocationTree, identifierStr + " = ");
} else {
// Unclear what the programmer intended. Delete since we don't know what else to do.
Tree parent = state.getPath().getParentPath().getLeaf();
fix = SuggestedFix.delete(parent);
}
return describeMatch(methodInvocationTree, fix);
}
/**
* Allow return values to be ignored in tests that expect an exception to be thrown.
*/
private static boolean expectedExceptionTest(Tree tree, VisitorState state) {
if (mockitoInvocation(tree, state)) {
return true;
}
// Allow unused return values in tests that check for thrown exceptions, e.g.:
//
// try {
// Foo.newFoo(-1);
// fail();
// } catch (IllegalArgumentException expected) {
// }
//
StatementTree statement = ASTHelpers.findEnclosingNode(state.getPath(), StatementTree.clreplaced);
if (statement != null && EXPECTED_EXCEPTION_MATCHER.matches(statement, state)) {
return true;
}
return false;
}
private static final Matcher<ExpressionTree> FAIL_METHOD = anyOf(instanceMethod().onDescendantOf("com.google.common.truth.AbstractVerb").named("fail"), instanceMethod().onDescendantOf("com.google.common.truth.StandardSubjectBuilder").named("fail"), staticMethod().onClreplaced("org.junit.replacedert").named("fail"), staticMethod().onClreplaced("junit.framework.replacedert").named("fail"), staticMethod().onClreplaced("junit.framework.TestCase").named("fail"));
private static final Matcher<StatementTree> EXPECTED_EXCEPTION_MATCHER = anyOf(// expectedException.expect(Foo.clreplaced); me();
allOf(isLastStatementInBlock(), previousStatement(expressionStatement(anyOf(instanceMethod().onExactClreplaced("org.junit.rules.ExpectedException"))))), // try { me(); fail(); } catch (Throwable t) {}
allOf(enclosingNode(kindIs(Kind.TRY)), nextStatement(expressionStatement(FAIL_METHOD))), // replacedertThrows(Throwable.clreplaced, () => { me(); })
allOf(anyOf(isLastStatementInBlock(), parentNode(kindIs(Kind.LAMBDA_EXPRESSION))), // Within the context of a ThrowingRunnable/Executable:
(t, s) -> methodCallInDeclarationOfThrowingRunnable(s)));
private static final Matcher<ExpressionTree> MOCKITO_MATCHER = anyOf(staticMethod().onClreplaced("org.mockito.Mockito").named("verify"), instanceMethod().onDescendantOf("org.mockito.stubbing.Stubber").named("when"), instanceMethod().onDescendantOf("org.mockito.InOrder").named("verify"));
/**
* Don't match the method that is invoked through {@code Mockito.verify(t)} or {@code
* doReturn(val).when(t)}.
*/
private static boolean mockitoInvocation(Tree tree, VisitorState state) {
if (!(tree instanceof JCMethodInvocation)) {
return false;
}
JCMethodInvocation invocation = (JCMethodInvocation) tree;
if (!(invocation.getMethodSelect() instanceof JCFieldAccess)) {
return false;
}
ExpressionTree receiver = ASTHelpers.getReceiver(invocation);
return MOCKITO_MATCHER.matches(receiver, state);
}
}
19
Source : TestFileBasedAccessControl.java
with Apache License 2.0
from trinodb
with Apache License 2.0
from trinodb
@Test
public void testFilterSchemas() {
ConnectorAccessControl accessControl = createAccessControl("visibility.json");
ImmutableSet<String> allSchemas = ImmutableSet.of("specific-schema", "alice-schema", "bob-schema", "unknown");
replacedertEquals(accessControl.filterSchemas(ADMIN, allSchemas), allSchemas);
replacedertEquals(accessControl.filterSchemas(ALICE, allSchemas), ImmutableSet.of("specific-schema", "alice-schema"));
replacedertEquals(accessControl.filterSchemas(BOB, allSchemas), ImmutableSet.of("specific-schema", "bob-schema"));
replacedertEquals(accessControl.filterSchemas(CHARLIE, allSchemas), ImmutableSet.of("specific-schema"));
}
19
Source : TestFunctionRegistry.java
with Apache License 2.0
from trinodb
with Apache License 2.0
from trinodb
private static SignatureBuilder functionSignature(List<String> arguments, String returnType, List<TypeVariableConstraint> typeVariableConstraints) {
ImmutableSet<String> literalParameters = ImmutableSet.of("p", "s", "p1", "s1", "p2", "s2", "p3", "s3");
List<TypeSignature> argumentSignatures = arguments.stream().map((signature) -> parseTypeSignature(signature, literalParameters)).collect(toImmutableList());
return new SignatureBuilder().returnType(parseTypeSignature(returnType, literalParameters)).argumentTypes(argumentSignatures).typeVariableConstraints(typeVariableConstraints);
}
19
Source : StreamPreferredProperties.java
with Apache License 2.0
from trinodb
with Apache License 2.0
from trinodb
public StreamPreferredProperties constrainTo(Iterable<Symbol> symbols) {
if (parreplacedioningColumns.isEmpty()) {
return this;
}
ImmutableSet<Symbol> availableSymbols = ImmutableSet.copyOf(symbols);
if (exactColumnOrder) {
if (availableSymbols.containsAll(parreplacedioningColumns.get())) {
return this;
}
return any();
}
List<Symbol> common = parreplacedioningColumns.get().stream().filter(availableSymbols::contains).collect(toImmutableList());
if (common.isEmpty()) {
return any();
}
return new StreamPreferredProperties(distribution, Optional.of(common), false);
}
19
Source : Newlines.java
with GNU General Public License v3.0
from tranleduy2000
with GNU General Public License v3.0
from tranleduy2000
/**
* Platform-independent newline handling.
*/
public clreplaced Newlines {
private static final ImmutableSet<String> BREAKS = ImmutableSet.of("\r\n", "\n", "\r");
/**
* Returns the number of line breaks in the input.
*/
public static int count(String input) {
return Iterators.size(lineOffsereplacederator(input)) - 1;
}
/**
* Returns the index of the first break in the input, or {@code -1}.
*/
public static int firstBreak(String input) {
Iterator<Integer> it = lineOffsereplacederator(input);
it.next();
return it.hasNext() ? it.next() : -1;
}
/**
* Returns true if the entire input string is a recognized line break.
*/
public static boolean isNewline(String input) {
return BREAKS.contains(input);
}
/**
* Returns the length of the newline sequence at the current offset, or {@code -1}.
*/
public static int hasNewlineAt(String input, int idx) {
for (String b : BREAKS) {
if (input.startsWith(b, idx)) {
return b.length();
}
}
return -1;
}
/**
* Returns the terminating line break in the input, or {@code null} if the input does not end in a
* break.
*/
public static String getLineEnding(String input) {
for (String b : BREAKS) {
if (input.endsWith(b)) {
return b;
}
}
return null;
}
/**
* Returns the first line separator in the text, or {@code "\n"} if the text does not contain a
* single line separator.
*/
public static String guessLineSeparator(String text) {
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
switch(c) {
case '\r':
if (i + 1 < text.length() && text.charAt(i + 1) == '\n') {
return "\r\n";
}
return "\r";
case '\n':
return "\n";
default:
break;
}
}
return "\n";
}
/**
* Returns true if the input contains any line breaks.
*/
public static boolean containsBreaks(String text) {
return CharMatcher.anyOf("\n\r").matchesAnyOf(text);
}
/**
* Returns an iterator over the start offsets of lines in the input.
*/
public static Iterator<Integer> lineOffsereplacederator(String input) {
return new LineOffsereplacederator(input);
}
/**
* Returns an iterator over lines in the input, including trailing whitespace.
*/
public static Iterator<String> lineIterator(String input) {
return new LineIterator(input);
}
private static clreplaced LineOffsereplacederator implements Iterator<Integer> {
private final String input;
private int curr = 0;
private int idx = 0;
private LineOffsereplacederator(String input) {
this.input = input;
}
@Override
public boolean hasNext() {
return curr != -1;
}
@Override
public Integer next() {
if (curr == -1) {
throw new NoSuchElementException();
}
int result = curr;
advance();
return result;
}
private void advance() {
for (; idx < input.length(); idx++) {
char c = input.charAt(idx);
switch(c) {
case '\r':
if (idx + 1 < input.length() && input.charAt(idx + 1) == '\n') {
idx++;
}
// falls through
case '\n':
idx++;
curr = idx;
return;
default:
break;
}
}
curr = -1;
}
@Override
public void remove() {
throw new UnsupportedOperationException("remove");
}
}
private static clreplaced LineIterator implements Iterator<String> {
private final String input;
private final Iterator<Integer> indices;
int idx;
String curr;
private LineIterator(String input) {
this.input = input;
this.indices = lineOffsereplacederator(input);
// read leading 0
idx = indices.next();
}
private void advance() {
int last = idx;
if (indices.hasNext()) {
idx = indices.next();
} else if (hasNext()) {
// no terminal line break
idx = input.length();
} else {
throw new NoSuchElementException();
}
curr = input.substring(last, idx);
}
@Override
public boolean hasNext() {
return idx < input.length();
}
@Override
public String next() {
advance();
return curr;
}
@Override
public void remove() {
throw new UnsupportedOperationException("remove");
}
}
}
19
Source : ImportOrderer.java
with GNU General Public License v3.0
from tranleduy2000
with GNU General Public License v3.0
from tranleduy2000
/**
* Orders imports in Java source code.
*/
public clreplaced ImportOrderer {
/**
* {@link TokenKind}s that indicate the start of a type definition. We use this to avoid scanning
* the whole file, since we know that imports must precede any type definition.
*/
private static final ImmutableSet<TokenKind> CLreplaced_START = ImmutableSet.of(TokenKind.CLreplaced, TokenKind.INTERFACE, TokenKind.ENUM);
/**
* We use this set to find the first import, and again to check that there are no imports after
* the place we stopped gathering them. An annotation definition ({@code @interface}) is two
* tokens, the second which is {@code interface}, so we don't need a separate entry for that.
*/
private static final ImmutableSet<String> IMPORT_OR_CLreplaced_START = ImmutableSet.of("import", "clreplaced", "interface", "enum");
private final String text;
private final ImmutableList<Tok> toks;
private final String lineSeparator;
private ImportOrderer(String text, ImmutableList<Tok> toks) throws FormatterException {
this.text = text;
this.toks = toks;
this.lineSeparator = Newlines.guessLineSeparator(text);
}
/**
* Reorder the inputs in {@code text}, a complete Java program. On success, another complete Java
* program is returned, which is the same as the original except the imports are in order.
*
* @throws FormatterException if the input could not be parsed.
*/
public static String reorderImports(String text) throws FormatterException {
ImmutableList<Tok> toks = JavaInput.buildToks(text, CLreplaced_START);
return new ImportOrderer(text, toks).reorderImports();
}
private String reorderImports() throws FormatterException {
int firstImportStart;
Optional<Integer> maybeFirstImport = findIdentifier(0, IMPORT_OR_CLreplaced_START);
if (!maybeFirstImport.isPresent() || !tokenAt(maybeFirstImport.get()).equals("import")) {
// No imports, so nothing to do.
return text;
}
firstImportStart = maybeFirstImport.get();
int unindentedFirstImportStart = unindent(firstImportStart);
ImportsAndIndex imports = scanImports(firstImportStart);
int afterLastImport = imports.index;
// Make sure there are no more imports before the next clreplaced (etc) definition.
Optional<Integer> maybeLaterImport = findIdentifier(afterLastImport, IMPORT_OR_CLreplaced_START);
if (maybeLaterImport.isPresent() && tokenAt(maybeLaterImport.get()).equals("import")) {
throw new FormatterException("Imports not contiguous (perhaps a comment separates them?)");
}
StringBuilder result = new StringBuilder();
result.append(CharMatcher.whitespace().trimTrailingFrom(tokString(0, unindentedFirstImportStart)));
if (result.length() > 0) {
result.append(lineSeparator).append(lineSeparator);
}
result.append(reorderedImportsString(imports.imports));
List<String> tail = new ArrayList<>();
tail.add(CharMatcher.whitespace().trimLeadingFrom(tokString(afterLastImport, toks.size())));
if (!toks.isEmpty()) {
Tok lastTok = getLast(toks);
int tailStart = lastTok.getPosition() + lastTok.length();
tail.add(text.substring(tailStart));
}
// if (tail.stream().anyMatch(s -> !s.isEmpty())) {
// result.append(lineSeparator);
// tail.forEach(result::append);
// }
for (String s : tail) {
if (!s.isEmpty()) {
result.append(lineSeparator);
for (String s1 : tail) {
result.append(s1);
}
break;
}
}
return result.toString();
}
private String tokString(int start, int end) {
StringBuilder sb = new StringBuilder();
for (int i = start; i < end; i++) {
sb.append(toks.get(i).getOriginalText());
}
return sb.toString();
}
/**
* Scans a sequence of import lines. The parsing uses this approximate grammar:
* <p>
* <pre>{@code
* <imports> -> (<end-of-line> | <import>)*
* <import> -> "import" <whitespace> ("static" <whitespace>)?
* <identifier> ("." <identifier>)* ("." "*")? <whitespace>? ";"
* <whitespace>? <line-comment>? <end-of-line>
* }</pre>
*
* @param i the index to start parsing at.
* @return the result of parsing the imports.
* @throws FormatterException if imports could not parsed according to the grammar.
*/
private ImportsAndIndex scanImports(int i) throws FormatterException {
int afterLastImport = i;
ImmutableSortedSet.Builder<Import> imports = ImmutableSortedSet.naturalOrder();
// JavaInput.buildToks appends a zero-width EOF token after all tokens. It won't match any
// of our tests here and protects us from running off the end of the toks list. Since it is
// zero-width it doesn't matter if we include it in our string concatenation at the end.
while (i < toks.size() && tokenAt(i).equals("import")) {
i++;
if (isSpaceToken(i)) {
i++;
}
boolean isStatic = tokenAt(i).equals("static");
if (isStatic) {
i++;
if (isSpaceToken(i)) {
i++;
}
}
if (!isIdentifierToken(i)) {
throw new FormatterException("Unexpected token after import: " + tokenAt(i));
}
StringAndIndex imported = scanImported(i);
String importedName = imported.string;
i = imported.index;
if (isSpaceToken(i)) {
i++;
}
if (!tokenAt(i).equals(";")) {
throw new FormatterException("Expected ; after import");
}
while (tokenAt(i).equals(";")) {
// Extra semicolons are not allowed by the JLS but are accepted by javac.
i++;
}
StringBuilder trailing = new StringBuilder();
if (isSpaceToken(i)) {
trailing.append(tokenAt(i));
i++;
}
if (isSlashSlashCommentToken(i)) {
trailing.append(tokenAt(i));
i++;
}
if (!isNewlineToken(i)) {
throw new FormatterException("Extra tokens after import: " + tokenAt(i));
}
trailing.append(tokenAt(i));
i++;
imports.add(new Import(importedName, trailing.toString(), isStatic));
// Remember the position just after the import we just saw, before skipping blank lines.
// If the next thing after the blank lines is not another import then we don't want to
// include those blank lines in the text to be replaced.
afterLastImport = i;
while (isNewlineToken(i) || isSpaceToken(i)) {
i++;
}
}
return new ImportsAndIndex(imports.build(), afterLastImport);
}
// Produces the sorted output based on the imports we have scanned.
private String reorderedImportsString(ImmutableSortedSet<Import> imports) {
replacedert !imports.isEmpty();
Import firstImport = imports.iterator().next();
// Pretend that the first import was preceded by another import of the same kind
// (static or non-static), so we don't insert a newline there.
boolean lastWreplacedtatic = firstImport.isStatic;
StringBuilder sb = new StringBuilder();
for (Import thisImport : imports) {
if (lastWreplacedtatic && !thisImport.isStatic) {
// Blank line between static and non-static imports.
sb.append(lineSeparator);
}
lastWreplacedtatic = thisImport.isStatic;
sb.append(thisImport);
}
return sb.toString();
}
/**
* Scans the imported thing, the dot-separated name that comes after import [static] and before
* the semicolon. We don't allow spaces inside the dot-separated name. Wildcard imports are
* supported: if the input is {@code import java.util.*;} then the returned string will be {@code
* java.util.*}.
*
* @param start the index of the start of the identifier. If the import is {@code import
* java.util.List;} then this index points to the token {@code java}.
* @return the parsed import ({@code java.util.List} in the example) and the index of the first
* token after the imported thing ({@code ;} in the example).
* @throws FormatterException if the imported name could not be parsed.
*/
private StringAndIndex scanImported(int start) throws FormatterException {
int i = start;
StringBuilder imported = new StringBuilder();
// At the start of each iteration of this loop, i points to an identifier.
// On exit from the loop, i points to a token after an identifier or after *.
while (true) {
replacedert isIdentifierToken(i);
imported.append(tokenAt(i));
i++;
if (!tokenAt(i).equals(".")) {
return new StringAndIndex(imported.toString(), i);
}
imported.append('.');
i++;
if (tokenAt(i).equals("*")) {
imported.append('*');
return new StringAndIndex(imported.toString(), i + 1);
} else if (!isIdentifierToken(i)) {
throw new FormatterException("Could not parse imported name, at: " + tokenAt(i));
}
}
}
/**
* Returns the index of the first place where one of the given identifiers occurs, or {@code
* Optional.absent()} if there is none.
*
* @param start the index to start looking at
* @param identifiers the identifiers to look for
*/
private Optional<Integer> findIdentifier(int start, ImmutableSet<String> identifiers) {
for (int i = start; i < toks.size(); i++) {
if (isIdentifierToken(i)) {
String id = tokenAt(i);
if (identifiers.contains(id)) {
return Optional.of(i);
}
}
}
return Optional.absent();
}
/**
* Returns the given token, or the preceding token if it is a whitespace token.
*/
private int unindent(int i) {
if (i > 0 && isSpaceToken(i - 1)) {
return i - 1;
} else {
return i;
}
}
private String tokenAt(int i) {
return toks.get(i).getOriginalText();
}
private boolean isIdentifierToken(int i) {
String s = tokenAt(i);
return !s.isEmpty() && Character.isJavaIdentifierStart(s.codePointAt(0));
}
private boolean isSpaceToken(int i) {
String s = tokenAt(i);
if (s.isEmpty()) {
return false;
} else {
return " \t\f".indexOf(s.codePointAt(0)) >= 0;
}
}
private boolean isSlashSlashCommentToken(int i) {
return toks.get(i).isSlashSlashComment();
}
private boolean isNewlineToken(int i) {
return toks.get(i).isNewline();
}
/**
* An import statement.
*/
private static clreplaced Import implements Comparable<Import> {
/**
* The name being imported, for example {@code java.util.List}.
*/
final String imported;
/**
* The characters after the final {@code ;}, up to and including the line terminator.
*/
final String trailing;
/**
* True if this is {@code import static}.
*/
final boolean isStatic;
Import(String imported, String trailing, boolean isStatic) {
this.imported = imported;
this.trailing = trailing;
this.isStatic = isStatic;
}
// This is how the sorting happens, including sorting static imports before non-static ones.
@Override
public int compareTo(Import that) {
if (this.isStatic != that.isStatic) {
return this.isStatic ? -1 : +1;
}
return this.imported.compareTo(that.imported);
}
// This is a complete line to be output for this import, including the line terminator.
@Override
public String toString() {
String staticString = isStatic ? "static " : "";
return "import " + staticString + imported + ";" + trailing;
}
}
private static clreplaced ImportsAndIndex {
final ImmutableSortedSet<Import> imports;
final int index;
ImportsAndIndex(ImmutableSortedSet<Import> imports, int index) {
this.imports = imports;
this.index = index;
}
}
private static clreplaced StringAndIndex {
private final String string;
private final int index;
StringAndIndex(String string, int index) {
this.string = string;
this.index = index;
}
}
}
19
Source : SplitOptions.java
with GNU General Public License v3.0
from tranleduy2000
with GNU General Public License v3.0
from tranleduy2000
/**
* Base data representing how an APK should be split for a given dimension (density, abi).
*/
public abstract clreplaced SplitOptions {
@NonNull
private final Set<String> values;
@NonNull
private final ImmutableSet<String> allowedValues;
private boolean enable = false;
protected SplitOptions() {
this.values = getDefaultValues();
this.allowedValues = getAllowedValues();
}
protected abstract Set<String> getDefaultValues();
protected abstract ImmutableSet<String> getAllowedValues();
/**
* Whether to split in this dimension.
*/
public boolean isEnable() {
return enable;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
/**
* excludes some values
*/
public void exclude(@NonNull String... excludes) {
values.removeAll(Arrays.asList(excludes));
}
/**
* includes some values
*/
public void include(@NonNull String... includes) {
values.addAll(Arrays.asList(includes));
}
/**
* Resets the list of included split configuration.
* <p>
* <p>Use this before calling include, in order to manually configure the list of configuration
* to split on, rather than excluding from the default list.
*/
public void reset() {
values.clear();
}
/**
* Returns a list of all applicable filters for this dimension.
* <p>
* <p>The list can return null, indicating that the no-filter option must also be used.
*
* @return the filters to use.
*/
@NonNull
public Set<String> getApplicableFilters() {
if (!enable) {
return Collections.emptySet();
}
Set<String> results = Sets.newHashSetWithExpectedSize(values.size());
for (String value : values) {
if (allowedValues.contains(value)) {
results.add(value);
}
}
return results;
}
}
19
Source : GraphTest.java
with Apache License 2.0
from TNG
with Apache License 2.0
from TNG
@Test
public void graph_which_causes_error_when_dependently_blocked_nodes_are_not_cleared_after_unblocking() {
ImmutableSet<Integer> nodes = ImmutableSet.of(0, 1, 2, 3, 4, 5);
Graph<Integer, Object> graph = new Graph<>();
graph.addNodes(nodes);
graph.addEdges(ImmutableSet.of(newEdge(0, 4), newEdge(1, 0), newEdge(1, 5), newEdge(2, 1), newEdge(3, 1), newEdge(3, 5), newEdge(4, 3), newEdge(5, 1), newEdge(5, 2)));
replacedertThat(graph.findCycles()).isNotEmpty();
}
19
Source : JavaClassesTest.java
with Apache License 2.0
from TNG
with Apache License 2.0
from TNG
@Test
public void javaClreplacedes_of_iterable() {
ImmutableSet<JavaClreplaced> iterable = ImmutableSet.of(importClreplacedWithContext(JavaClreplacedesTest.clreplaced), importClreplacedWithContext(JavaClreplaced.clreplaced));
JavaClreplacedes clreplacedes = JavaClreplacedes.of(iterable);
replacedertThat(ImmutableSet.copyOf(clreplacedes)).isEqualTo(iterable);
}
19
Source : ImportedClasses.java
with Apache License 2.0
from TNG
with Apache License 2.0
from TNG
clreplaced ImportedClreplacedes {
private static final ImmutableSet<JavaModifier> PRIMITIVE_AND_ARRAY_TYPE_MODIFIERS = Sets.immutableEnumSet(PUBLIC, ABSTRACT, FINAL);
private final ImmutableMap<String, JavaClreplaced> directlyImported;
private final Map<String, JavaClreplaced> allClreplacedes = new HashMap<>();
private final ClreplacedResolver resolver;
ImportedClreplacedes(Map<String, JavaClreplaced> directlyImported, ClreplacedResolver resolver) {
this.directlyImported = ImmutableMap.copyOf(directlyImported);
allClreplacedes.putAll(directlyImported);
this.resolver = resolver;
}
Map<String, JavaClreplaced> getDirectlyImported() {
return directlyImported;
}
JavaClreplaced getOrResolve(String typeName) {
JavaClreplaced javaClreplaced = allClreplacedes.get(typeName);
if (javaClreplaced == null) {
Optional<JavaClreplaced> resolved = resolver.tryResolve(typeName);
javaClreplaced = resolved.isPresent() ? resolved.get() : simpleClreplacedOf(typeName);
allClreplacedes.put(typeName, javaClreplaced);
}
return javaClreplaced;
}
boolean isPresent(String typeName) {
return allClreplacedes.containsKey(typeName);
}
void ensurePresent(String typeName) {
getOrResolve(typeName);
}
Collection<JavaClreplaced> getAllWithOuterClreplacedesSortedBeforeInnerClreplacedes() {
return ImmutableSortedMap.copyOf(allClreplacedes).values();
}
ClreplacedesByTypeName byTypeName() {
return new ClreplacedesByTypeName() {
@Override
public JavaClreplaced get(String typeName) {
return ImportedClreplacedes.this.getOrResolve(typeName);
}
};
}
private static JavaClreplaced simpleClreplacedOf(String typeName) {
JavaClreplacedDescriptor descriptor = JavaClreplacedDescriptor.From.name(typeName);
DomainBuilders.JavaClreplacedBuilder builder = new DomainBuilders.JavaClreplacedBuilder().withDescriptor(descriptor);
addModifiersIfPossible(builder, descriptor);
return builder.build();
}
private static void addModifiersIfPossible(DomainBuilders.JavaClreplacedBuilder builder, JavaClreplacedDescriptor descriptor) {
if (descriptor.isPrimitive() || descriptor.isArray()) {
builder.withModifiers(PRIMITIVE_AND_ARRAY_TYPE_MODIFIERS);
}
}
}
19
Source : MultiIndexedVoxelShape.java
with GNU Lesser General Public License v2.1
from TheCBProject
with GNU Lesser General Public License v2.1
from TheCBProject
/**
* A VoxelShape implementation, produces a {@link VoxelShapeRayTraceResult} when ray traced.
* Whilst similar to {@link IndexedVoxelShape}, will ray trace each sub-component provided, returning the closest.
* <p>
* The sub-component will have its outline automatically rendered appropriately.
* <p>
* Created by covers1624 on 5/12/20.
*/
public clreplaced MultiIndexedVoxelShape extends VoxelShape {
private final VoxelShape merged;
private final ImmutableSet<IndexedVoxelShape> shapes;
/**
* Construct a MultiIndexedVoxelShape, using the combination of all the sub-components
* as this VoxelShape.
*
* @param shapes The sub-components.
*/
public MultiIndexedVoxelShape(ImmutableSet<IndexedVoxelShape> shapes) {
// Generics die in a hole pls, kthx.
this(VoxelShapeCache.merge(unsafeCast(shapes)), shapes);
}
/**
* Constructs a MultiIndexedVoxelShape, using the provided VoxelShape as this shape,
* whilst still RayTracing against all the sub-components.
*
* @param merged The base shape.
* @param shapes The sub-components.
*/
public MultiIndexedVoxelShape(VoxelShape merged, ImmutableSet<IndexedVoxelShape> shapes) {
super(merged.part);
this.merged = merged;
this.shapes = shapes;
}
@Override
public DoubleList getValues(Direction.Axis axis) {
return merged.getValues(axis);
}
@Nullable
@Override
public VoxelShapeRayTraceResult rayTrace(Vector3d start, Vector3d end, BlockPos pos) {
VoxelShapeRayTraceResult closest = null;
double dist = Double.MAX_VALUE;
for (IndexedVoxelShape shape : shapes) {
VoxelShapeRayTraceResult hit = shape.rayTrace(start, end, pos);
if (hit != null && dist >= hit.dist) {
closest = hit;
dist = hit.dist;
}
}
return closest;
}
}
19
Source : CoreAccount.java
with Apache License 2.0
from tedyoung
with Apache License 2.0
from tedyoung
public clreplaced CoreAccount implements Account {
private final TransactionRepository transactionRepository;
private final GoalRepository goalRepository;
private BalanceChangedNotifier balanceChangedNotifier;
private ImmutableSet<Transaction> transactions;
public CoreAccount(TransactionRepository transactionRepository, GoalRepository goalRepository, BalanceChangedNotifier balanceChangedNotifier) {
this.transactionRepository = transactionRepository;
this.transactions = ImmutableSet.<Transaction>builder().addAll(transactionRepository.findAll()).build();
this.goalRepository = goalRepository;
this.balanceChangedNotifier = balanceChangedNotifier;
}
@Override
public int balance() {
return balanceUpTo(LocalDateTime.MAX);
}
@Override
public int interestEarned() {
throw new UnsupportedOperationException("Core Account does not support querying interest earned because it's not intended to be called in production, it's always wrapped bu the InterestEarningAccount decorator.");
}
@Override
public void deposit(LocalDateTime transactionDateTime, int amount, String source, UserProfile userProfile) {
Transaction deposit = Transaction.createDeposit(transactionDateTime, amount, source, userProfile);
addNewTransaction(deposit);
balanceChangedNotifier.balanceChanged(amount, transactions.stream().mapToInt(Transaction::signedAmount).sum());
}
@Override
public void spend(LocalDateTime transactionDateTime, int amount, String description, UserProfile userProfile) {
Transaction spend = Transaction.createSpend(transactionDateTime, amount, description, userProfile);
addNewTransaction(spend);
balanceChangedNotifier.balanceChanged(-amount, transactions.stream().mapToInt(Transaction::signedAmount).sum());
}
private void addNewTransaction(Transaction transaction) {
Transaction savedTransaction = transactionRepository.save(transaction);
transactions = ImmutableSet.<Transaction>builder().addAll(transactions).add(savedTransaction).build();
}
@Override
public ImmutableList<Transaction> transactions() {
return ImmutableList.copyOf(transactions);
}
@Override
public void load(List<Transaction> transactionsToLoad) {
List<Transaction> savedTransactions = transactionRepository.saveAll(transactionsToLoad);
transactions = ImmutableSet.<Transaction>builder().addAll(transactions).addAll(savedTransactions).build();
}
/**
* Calculates Balance just prior to (exclusive) the given date
*/
@Override
public int balanceUpTo(LocalDateTime localDateTime) {
return transactions.stream().filter(t -> t.dateTime().isBefore(localDateTime)).mapToInt(Transaction::signedAmount).sum();
}
@Override
public Set<Goal> goals() {
return ImmutableSet.copyOf(goalRepository.findAll());
}
@Override
public void createGoal(String description, int targetAmount) {
Goal goal = new Goal(description, targetAmount);
goalRepository.save(goal);
}
}
See More Examples