Skip to content

Commit 79fc70b

Browse files
authored
Cleanup a number of warnings in the code. (#137)
* Eliminate 'badimport' warning It was already reasonably obvious what this is, so the warning is mostly spurious. But it's easier and less boilerplate to just add the extra qualifier than to suppress the warning. https://errorprone.info/bugpattern/BadImport * Suppress EqualsGetClass warnings for public classes These are effectively final and are documented as not being final only to allow mocking within tests. https://errorprone.info/bugpattern/EqualsGetClass * Mark a number of classes final Mostly to avoid a warning, though it's generally recommended to do this anyways. (Note that this makes mocking impossible; if any of these classes need to be mocked, we might be better of just suppressing the warning or using instanceof.) https://errorprone.info/bugpattern/EqualsGetClass * Switch .getClass() to instanceof in some .equals() methods This is for cases where we're dealing with a non-leaf node in the inheritance hierarchy. (Leaf nodes in the heirarchy can just mark the entire class as final.) In order to preserve symmetry of .equals(), also mark the .equals() methods themselves as final. In this case, "non-leaf" nodes also counts effectively final classes which are mocked. (i.e. ViewSnapshot.) https://errorprone.info/bugpattern/EqualsGetClass * Provide toString on FieldMask Since it's used by PatchMutation https://errorprone.info/bugpattern/ObjectToString * Fix a 'missing override' warning https://errorprone.info/bugpattern/MissingOverride * Rework FieldMask to use a Set of FieldPaths rather than a Collection. FieldMask uses .equals() on the container, and that's not well defined for a Collection. The fix is to switch to either a Set or a List. Set seems more appropriate. https://errorprone.info/bugpattern/UndefinedEquals * Add TestUtil.fieldMask(String...) to simplify creating FieldMasks.
1 parent 9fa8f23 commit 79fc70b

File tree

20 files changed

+69
-49
lines changed

20 files changed

+69
-49
lines changed

firebase-firestore/src/main/java/com/google/firebase/firestore/DocumentReference.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,7 @@ public boolean equals(Object o) {
555555
if (this == o) {
556556
return true;
557557
}
558-
if (o == null || getClass() != o.getClass()) {
558+
if (!(o instanceof DocumentReference)) {
559559
return false;
560560
}
561561

firebase-firestore/src/main/java/com/google/firebase/firestore/Query.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -905,7 +905,7 @@ public boolean equals(Object o) {
905905
if (this == o) {
906906
return true;
907907
}
908-
if (o == null || getClass() != o.getClass()) {
908+
if (!(o instanceof Query)) {
909909
return false;
910910
}
911911

firebase-firestore/src/main/java/com/google/firebase/firestore/SetOptions.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@
2020
import android.support.annotation.Nullable;
2121
import com.google.firebase.annotations.PublicApi;
2222
import com.google.firebase.firestore.model.mutation.FieldMask;
23-
import java.util.ArrayList;
23+
import java.util.HashSet;
2424
import java.util.List;
25+
import java.util.Set;
2526

2627
/**
2728
* An options object that configures the behavior of set() calls. By providing one of the SetOptions
@@ -78,13 +79,13 @@ public static SetOptions merge() {
7879
@NonNull
7980
@PublicApi
8081
public static SetOptions mergeFields(List<String> fields) {
81-
List<com.google.firebase.firestore.model.FieldPath> fieldPaths = new ArrayList<>();
82+
Set<com.google.firebase.firestore.model.FieldPath> fieldPaths = new HashSet<>();
8283

8384
for (String field : fields) {
8485
fieldPaths.add(FieldPath.fromDotSeparatedPath(field).getInternalPath());
8586
}
8687

87-
return new SetOptions(true, FieldMask.fromCollection(fieldPaths));
88+
return new SetOptions(true, FieldMask.fromSet(fieldPaths));
8889
}
8990

9091
/**
@@ -100,13 +101,13 @@ public static SetOptions mergeFields(List<String> fields) {
100101
@NonNull
101102
@PublicApi
102103
public static SetOptions mergeFields(String... fields) {
103-
List<com.google.firebase.firestore.model.FieldPath> fieldPaths = new ArrayList<>();
104+
Set<com.google.firebase.firestore.model.FieldPath> fieldPaths = new HashSet<>();
104105

105106
for (String field : fields) {
106107
fieldPaths.add(FieldPath.fromDotSeparatedPath(field).getInternalPath());
107108
}
108109

109-
return new SetOptions(true, FieldMask.fromCollection(fieldPaths));
110+
return new SetOptions(true, FieldMask.fromSet(fieldPaths));
110111
}
111112

112113
/**
@@ -121,13 +122,13 @@ public static SetOptions mergeFields(String... fields) {
121122
@NonNull
122123
@PublicApi
123124
public static SetOptions mergeFieldPaths(List<FieldPath> fields) {
124-
List<com.google.firebase.firestore.model.FieldPath> fieldPaths = new ArrayList<>();
125+
Set<com.google.firebase.firestore.model.FieldPath> fieldPaths = new HashSet<>();
125126

126127
for (FieldPath field : fields) {
127128
fieldPaths.add(field.getInternalPath());
128129
}
129130

130-
return new SetOptions(true, FieldMask.fromCollection(fieldPaths));
131+
return new SetOptions(true, FieldMask.fromSet(fieldPaths));
131132
}
132133

133134
@Override

firebase-firestore/src/main/java/com/google/firebase/firestore/core/EventManager.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ public void onError(Query query, Status error) {
137137
queries.remove(query);
138138
}
139139

140+
@Override
140141
public void handleOnlineStateChange(OnlineState onlineState) {
141142
this.onlineState = onlineState;
142143
for (QueryListenersInfo info : queries.values()) {

firebase-firestore/src/main/java/com/google/firebase/firestore/core/UserData.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@
2929
import com.google.firebase.firestore.model.value.ObjectValue;
3030
import com.google.firebase.firestore.util.Assert;
3131
import java.util.ArrayList;
32+
import java.util.HashSet;
3233
import java.util.List;
33-
import java.util.SortedSet;
34-
import java.util.TreeSet;
34+
import java.util.Set;
3535
import java.util.regex.Pattern;
3636
import javax.annotation.Nullable;
3737

@@ -72,16 +72,16 @@ public static class ParseAccumulator {
7272
*/
7373
private final Source dataSource;
7474

75-
/** Accumulates a list of the field paths found while parsing the data. */
76-
private final SortedSet<FieldPath> fieldMask;
75+
/** Accumulates a set of the field paths found while parsing the data. */
76+
private final Set<FieldPath> fieldMask;
7777

7878
/** Accumulates a list of field transforms found while parsing the data. */
7979
private final ArrayList<FieldTransform> fieldTransforms;
8080

8181
/** @param dataSource Indicates what kind of API method this data came from. */
8282
public ParseAccumulator(Source dataSource) {
8383
this.dataSource = dataSource;
84-
this.fieldMask = new TreeSet<>();
84+
this.fieldMask = new HashSet<>();
8585
this.fieldTransforms = new ArrayList<>();
8686
}
8787

@@ -135,7 +135,7 @@ void addToFieldTransforms(FieldPath fieldPath, TransformOperation transformOpera
135135
*/
136136
public ParsedSetData toMergeData(ObjectValue data) {
137137
return new ParsedSetData(
138-
data, FieldMask.fromCollection(fieldMask), unmodifiableList(fieldTransforms));
138+
data, FieldMask.fromSet(fieldMask), unmodifiableList(fieldTransforms));
139139
}
140140

141141
/**
@@ -181,7 +181,7 @@ public ParsedSetData toSetData(ObjectValue data) {
181181
*/
182182
public ParsedUpdateData toUpdateData(ObjectValue data) {
183183
return new ParsedUpdateData(
184-
data, FieldMask.fromCollection(fieldMask), unmodifiableList(fieldTransforms));
184+
data, FieldMask.fromSet(fieldMask), unmodifiableList(fieldTransforms));
185185
}
186186
}
187187

firebase-firestore/src/main/java/com/google/firebase/firestore/core/ViewSnapshot.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,11 @@ public boolean excludesMetadataChanges() {
118118
}
119119

120120
@Override
121-
public boolean equals(Object o) {
121+
public final boolean equals(Object o) {
122122
if (this == o) {
123123
return true;
124124
}
125-
if (o == null || getClass() != o.getClass()) {
125+
if (!(o instanceof ViewSnapshot)) {
126126
return false;
127127
}
128128

firebase-firestore/src/main/java/com/google/firebase/firestore/local/IndexedQueryEngine.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import com.google.firebase.firestore.core.Filter;
2323
import com.google.firebase.firestore.core.Filter.Operator;
2424
import com.google.firebase.firestore.core.IndexRange;
25-
import com.google.firebase.firestore.core.IndexRange.Builder;
2625
import com.google.firebase.firestore.core.NaNFilter;
2726
import com.google.firebase.firestore.core.NullFilter;
2827
import com.google.firebase.firestore.core.Query;
@@ -216,7 +215,7 @@ static IndexRange extractBestIndexRange(Query query) {
216215
* filter. The determined {@code IndexRange} is likely overselective and requires post-filtering.
217216
*/
218217
private static IndexRange convertFilterToIndexRange(Filter filter) {
219-
Builder indexRange = IndexRange.builder().setFieldPath(filter.getField());
218+
IndexRange.Builder indexRange = IndexRange.builder().setFieldPath(filter.getField());
220219
if (filter instanceof RelationFilter) {
221220
RelationFilter relationFilter = (RelationFilter) filter;
222221
FieldValue filterValue = relationFilter.getValue();

firebase-firestore/src/main/java/com/google/firebase/firestore/model/BasePath.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -161,13 +161,11 @@ public int length() {
161161
}
162162

163163
@Override
164-
@SuppressWarnings("unchecked")
165-
public boolean equals(Object o) {
166-
if (o == null) {
167-
return false;
164+
public final boolean equals(Object o) {
165+
if (this == o) {
166+
return true;
168167
}
169-
// The cast is not unchecked because of the class equality check.
170-
return getClass() == o.getClass() && compareTo((B) o) == 0;
168+
return (o instanceof BasePath) && compareTo((B) o) == 0;
171169
}
172170

173171
@Override

firebase-firestore/src/main/java/com/google/firebase/firestore/model/Document.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
* Represents a document in Firestore with a key, version, data and whether the data has local
2424
* mutations applied to it.
2525
*/
26-
public class Document extends MaybeDocument {
26+
public final class Document extends MaybeDocument {
2727

2828
/** Describes the `hasPendingWrites` state of a document. */
2929
public enum DocumentState {

firebase-firestore/src/main/java/com/google/firebase/firestore/model/DocumentKey.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
import java.util.List;
2424

2525
/** DocumentKey represents the location of a document in the Firestore database. */
26-
public class DocumentKey implements Comparable<DocumentKey> {
26+
public final class DocumentKey implements Comparable<DocumentKey> {
2727

2828
public static final String KEY_FIELD_NAME = "__name__";
2929

firebase-firestore/src/main/java/com/google/firebase/firestore/model/DocumentSet.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
* An immutable set of documents (unique by key) ordered by the given comparator or ordered by key
3131
* by default if no document is present.
3232
*/
33-
public class DocumentSet implements Iterable<Document> {
33+
public final class DocumentSet implements Iterable<Document> {
3434

3535
/** Returns an empty DocumentSet sorted by the given comparator, then by keys. */
3636
public static DocumentSet emptySet(final Comparator<Document> comparator) {

firebase-firestore/src/main/java/com/google/firebase/firestore/model/NoDocument.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
package com.google.firebase.firestore.model;
1616

1717
/** Represents that no documents exists for the key at the given version. */
18-
public class NoDocument extends MaybeDocument {
18+
public final class NoDocument extends MaybeDocument {
1919

2020
private boolean hasCommittedMutations;
2121

firebase-firestore/src/main/java/com/google/firebase/firestore/model/UnknownDocument.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
* A class representing an existing document whose data is unknown (e.g. a document that was updated
1919
* without a known base document).
2020
*/
21-
public class UnknownDocument extends MaybeDocument {
21+
public final class UnknownDocument extends MaybeDocument {
2222
public UnknownDocument(DocumentKey key, SnapshotVersion version) {
2323
super(key, version);
2424
}

firebase-firestore/src/main/java/com/google/firebase/firestore/model/mutation/ArrayTransformOperation.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public FieldValue applyToRemoteDocument(FieldValue previousValue, FieldValue tra
5151
}
5252

5353
@Override
54+
@SuppressWarnings("EqualsGetClass") // subtype-sensitive equality is intended.
5455
public boolean equals(Object o) {
5556
if (this == o) {
5657
return true;

firebase-firestore/src/main/java/com/google/firebase/firestore/model/mutation/FieldMask.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
package com.google.firebase.firestore.model.mutation;
1616

1717
import com.google.firebase.firestore.model.FieldPath;
18-
import java.util.Collection;
18+
import java.util.Set;
1919

2020
/**
2121
* Provides a set of fields that can be used to partially patch a document. The FieldMask is used in
@@ -25,14 +25,14 @@
2525
* companion ObjectValue, the field is deleted. foo.bar - Overwrites only the field bar of the
2626
* object foo. If foo is not an object, foo is replaced with an object containing foo.
2727
*/
28-
public class FieldMask {
29-
public static FieldMask fromCollection(Collection<FieldPath> mask) {
28+
public final class FieldMask {
29+
public static FieldMask fromSet(Set<FieldPath> mask) {
3030
return new FieldMask(mask);
3131
}
3232

33-
private final Collection<FieldPath> mask;
33+
private final Set<FieldPath> mask;
3434

35-
private FieldMask(Collection<FieldPath> mask) {
35+
private FieldMask(Set<FieldPath> mask) {
3636
this.mask = mask;
3737
}
3838

@@ -49,6 +49,11 @@ public boolean equals(Object o) {
4949
return mask.equals(fieldMask.mask);
5050
}
5151

52+
@Override
53+
public String toString() {
54+
return "FieldMask{mask=" + mask.toString() + "}";
55+
}
56+
5257
/**
5358
* Verifies that 'fieldPath' is included by at least one field in this field mask.
5459
*
@@ -69,7 +74,7 @@ public int hashCode() {
6974
return mask.hashCode();
7075
}
7176

72-
public Collection<FieldPath> getMask() {
77+
public Set<FieldPath> getMask() {
7378
return mask;
7479
}
7580
}

firebase-firestore/src/main/java/com/google/firebase/firestore/remote/RemoteSerializer.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,10 @@
9898
import java.util.Arrays;
9999
import java.util.Collections;
100100
import java.util.HashMap;
101+
import java.util.HashSet;
101102
import java.util.List;
102103
import java.util.Map;
104+
import java.util.Set;
103105

104106
/** Serializer that converts to and from Firestore API protos. */
105107
public final class RemoteSerializer {
@@ -532,11 +534,11 @@ private DocumentMask encodeDocumentMask(FieldMask mask) {
532534

533535
private FieldMask decodeDocumentMask(DocumentMask mask) {
534536
int count = mask.getFieldPathsCount();
535-
List<FieldPath> paths = new ArrayList<>(count);
537+
Set<FieldPath> paths = new HashSet<>(count);
536538
for (int i = 0; i < count; i++) {
537539
paths.add(FieldPath.fromServerFormat(mask.getFieldPaths(i)));
538540
}
539-
return FieldMask.fromCollection(paths);
541+
return FieldMask.fromSet(paths);
540542
}
541543

542544
private DocumentTransform.FieldTransform encodeFieldTransform(FieldTransform fieldTransform) {

firebase-firestore/src/main/java/com/google/firebase/firestore/remote/WatchChange.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ private WatchChange() {
3838
* A document change represents a change document and a list of target ids to which this change
3939
* applies. If the document has been deleted, the deleted document will be provided.
4040
*/
41-
public static class DocumentChange extends WatchChange {
41+
public static final class DocumentChange extends WatchChange {
4242
// TODO: figure out if we can actually use arrays here for efficiency
4343
/** The new document applies to all of these targets. */
4444
private final List<Integer> updatedTargetIds;
@@ -137,7 +137,7 @@ public int hashCode() {
137137
* An ExistenceFilterWatchChange applies to the targets and is required to verify the current
138138
* client state against expected state sent from the server.
139139
*/
140-
public static class ExistenceFilterWatchChange extends WatchChange {
140+
public static final class ExistenceFilterWatchChange extends WatchChange {
141141
private final int targetId;
142142

143143
private final ExistenceFilter existenceFilter;
@@ -177,7 +177,7 @@ public enum WatchTargetChangeType {
177177
}
178178

179179
/** The state of a target has changed. This can mean removal, addition, current or reset. */
180-
public static class WatchTargetChange extends WatchChange {
180+
public static final class WatchTargetChange extends WatchChange {
181181
private final WatchTargetChangeType changeType;
182182
private final List<Integer> targetIds;
183183
private final ByteString resumeToken;

firebase-firestore/src/test/java/com/google/firebase/firestore/local/LocalSerializerTest.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import static com.google.firebase.firestore.testutil.TestUtil.deleteMutation;
1818
import static com.google.firebase.firestore.testutil.TestUtil.deletedDoc;
1919
import static com.google.firebase.firestore.testutil.TestUtil.doc;
20-
import static com.google.firebase.firestore.testutil.TestUtil.field;
20+
import static com.google.firebase.firestore.testutil.TestUtil.fieldMask;
2121
import static com.google.firebase.firestore.testutil.TestUtil.key;
2222
import static com.google.firebase.firestore.testutil.TestUtil.map;
2323
import static com.google.firebase.firestore.testutil.TestUtil.setMutation;
@@ -33,7 +33,6 @@
3333
import com.google.firebase.firestore.model.NoDocument;
3434
import com.google.firebase.firestore.model.SnapshotVersion;
3535
import com.google.firebase.firestore.model.UnknownDocument;
36-
import com.google.firebase.firestore.model.mutation.FieldMask;
3736
import com.google.firebase.firestore.model.mutation.Mutation;
3837
import com.google.firebase.firestore.model.mutation.MutationBatch;
3938
import com.google.firebase.firestore.model.mutation.PatchMutation;
@@ -71,7 +70,7 @@ public void testEncodesMutationBatch() {
7170
new PatchMutation(
7271
key("bar/baz"),
7372
TestUtil.wrapObject(map("a", "b", "num", 1)),
74-
FieldMask.fromCollection(asList(field("a"))),
73+
fieldMask("a"),
7574
com.google.firebase.firestore.model.mutation.Precondition.exists(true));
7675
Mutation del = deleteMutation("baz/quux");
7776
Timestamp writeTime = Timestamp.now();

firebase-firestore/src/test/java/com/google/firebase/firestore/model/MutationTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import static com.google.firebase.firestore.testutil.TestUtil.deletedDoc;
1919
import static com.google.firebase.firestore.testutil.TestUtil.doc;
2020
import static com.google.firebase.firestore.testutil.TestUtil.field;
21+
import static com.google.firebase.firestore.testutil.TestUtil.fieldMask;
2122
import static com.google.firebase.firestore.testutil.TestUtil.key;
2223
import static com.google.firebase.firestore.testutil.TestUtil.map;
2324
import static com.google.firebase.firestore.testutil.TestUtil.mutationResult;
@@ -110,7 +111,7 @@ public void testDeletesValuesFromTheFieldMask() {
110111
Document baseDoc = doc("collection/key", 0, data);
111112

112113
DocumentKey key = key("collection/key");
113-
FieldMask mask = FieldMask.fromCollection(Arrays.asList(field("foo.bar")));
114+
FieldMask mask = fieldMask("foo.bar");
114115
Mutation patch = new PatchMutation(key, ObjectValue.emptyObject(), mask, Precondition.NONE);
115116

116117
MaybeDocument patchDoc = patch.applyToLocalView(baseDoc, baseDoc, Timestamp.now());

0 commit comments

Comments
 (0)