Skip to content

Commit

Permalink
Create a separate target for WellKnownThreadSafety and WellKnownMutab…
Browse files Browse the repository at this point in the history
…ility

PiperOrigin-RevId: 673048715
  • Loading branch information
cushon authored and Error Prone Team committed Sep 12, 2024
1 parent fcd3939 commit c35a66d
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,9 @@
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.common.collect.Sets.SetView;
import com.google.common.collect.Streams;
import com.google.errorprone.VisitorState;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
Expand Down Expand Up @@ -58,7 +56,6 @@
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import java.lang.reflect.TypeVariable;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
Expand All @@ -78,7 +75,7 @@
public final class ThreadSafety {
private final VisitorState state;
private final Purpose purpose;
private final KnownTypes knownTypes;
private final ThreadSafetyKnownTypes knownTypes;
private final ImmutableSet<String> markerAnnotations;
private final ImmutableSet<String> acceptedAnnotations;
private final ImmutableSet<String> containerOfAnnotation;
Expand Down Expand Up @@ -153,7 +150,7 @@ public static class Builder {
private Builder() {}

private Purpose purpose = Purpose.FOR_IMMUTABLE_CHECKER;
private KnownTypes knownTypes;
private ThreadSafetyKnownTypes knownTypes;
private ImmutableSet<String> markerAnnotations;
private ImmutableSet<String> acceptedAnnotations = ImmutableSet.of();
private ImmutableSet<String> containerOfAnnotation = ImmutableSet.of();
Expand All @@ -169,7 +166,7 @@ public Builder setPurpose(Purpose purpose) {

/** Information about known types and whether they're known to be safe or unsafe. */
@CanIgnoreReturnValue
public Builder knownTypes(KnownTypes knownTypes) {
public Builder knownTypes(ThreadSafetyKnownTypes knownTypes) {
this.knownTypes = knownTypes;
return this;
}
Expand Down Expand Up @@ -275,7 +272,7 @@ public ThreadSafety build(VisitorState state) {
private ThreadSafety(
VisitorState state,
Purpose purpose,
KnownTypes knownTypes,
ThreadSafetyKnownTypes knownTypes,
Set<String> markerAnnotations,
Set<String> acceptedAnnotations,
Set<String> containerOfAnnotation,
Expand All @@ -291,71 +288,6 @@ private ThreadSafety(
this.typeParameterAnnotation = ImmutableSet.copyOf(checkNotNull(typeParameterAnnotation));
}

/** Information about known types and whether they're known to be safe or unsafe. */
public interface KnownTypes {
/**
* Types that are known to be safe even if they're not annotated with an expected annotation.
*/
ImmutableMap<String, AnnotationInfo> getKnownSafeClasses();

/** Types that are known to be unsafe and don't need testing. */
ImmutableSet<String> getKnownUnsafeClasses();

/** Helper for building maps of classes to {@link AnnotationInfo}. */
final class MapBuilder {
final ImmutableMap.Builder<String, AnnotationInfo> mapBuilder = ImmutableMap.builder();

@CanIgnoreReturnValue
public MapBuilder addClasses(Set<Class<?>> clazzs) {
clazzs.forEach(this::add);
return this;
}

@CanIgnoreReturnValue
public MapBuilder addStrings(List<String> classNames) {
classNames.forEach(this::add);
return this;
}

@CanIgnoreReturnValue
public MapBuilder addAll(ImmutableMap<String, AnnotationInfo> map) {
mapBuilder.putAll(map);
return this;
}

@CanIgnoreReturnValue
public MapBuilder add(Class<?> clazz, String... containerOf) {
ImmutableSet<String> containerTyParams = ImmutableSet.copyOf(containerOf);
HashSet<String> actualTyParams = new HashSet<>();
for (TypeVariable<?> x : clazz.getTypeParameters()) {
actualTyParams.add(x.getName());
}
SetView<String> difference = Sets.difference(containerTyParams, actualTyParams);
if (!difference.isEmpty()) {
throw new AssertionError(
String.format(
"For %s, please update the type parameter(s) from %s to %s",
clazz, difference, actualTyParams));
}
mapBuilder.put(
clazz.getName(),
AnnotationInfo.create(clazz.getName(), ImmutableList.copyOf(containerOf)));
return this;
}

@CanIgnoreReturnValue
public MapBuilder add(String className, String... containerOf) {
mapBuilder.put(
className, AnnotationInfo.create(className, ImmutableList.copyOf(containerOf)));
return this;
}

public ImmutableMap<String, AnnotationInfo> build() {
return mapBuilder.buildKeepingLast();
}
}
}

/**
* A human-friendly explanation of a thread safety violations.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright 2024 The Error Prone Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.errorprone.bugpatterns.threadsafety;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.common.collect.Sets.SetView;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.lang.reflect.TypeVariable;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/** Information about known types and whether they're known to be safe or unsafe. */
public interface ThreadSafetyKnownTypes {
/** Types that are known to be safe even if they're not annotated with an expected annotation. */
ImmutableMap<String, AnnotationInfo> getKnownSafeClasses();

/** Types that are known to be unsafe and don't need testing. */
ImmutableSet<String> getKnownUnsafeClasses();

/** Helper for building maps of classes to {@link AnnotationInfo}. */
final class MapBuilder {
final ImmutableMap.Builder<String, AnnotationInfo> mapBuilder = ImmutableMap.builder();

@CanIgnoreReturnValue
public MapBuilder addClasses(Set<Class<?>> clazzs) {
clazzs.forEach(this::add);
return this;
}

@CanIgnoreReturnValue
public MapBuilder addStrings(List<String> classNames) {
classNames.forEach(this::add);
return this;
}

@CanIgnoreReturnValue
public MapBuilder addAll(ImmutableMap<String, AnnotationInfo> map) {
mapBuilder.putAll(map);
return this;
}

@CanIgnoreReturnValue
public MapBuilder add(Class<?> clazz, String... containerOf) {
ImmutableSet<String> containerTyParams = ImmutableSet.copyOf(containerOf);
HashSet<String> actualTyParams = new HashSet<>();
for (TypeVariable<?> x : clazz.getTypeParameters()) {
actualTyParams.add(x.getName());
}
SetView<String> difference = Sets.difference(containerTyParams, actualTyParams);
if (!difference.isEmpty()) {
throw new AssertionError(
String.format(
"For %s, please update the type parameter(s) from %s to %s",
clazz, difference, actualTyParams));
}
mapBuilder.put(
clazz.getName(),
AnnotationInfo.create(clazz.getName(), ImmutableList.copyOf(containerOf)));
return this;
}

@CanIgnoreReturnValue
public MapBuilder add(String className, String... containerOf) {
mapBuilder.put(
className, AnnotationInfo.create(className, ImmutableList.copyOf(containerOf)));
return this;
}

public ImmutableMap<String, AnnotationInfo> build() {
return mapBuilder.buildKeepingLast();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@

/** A collection of types with known mutability. */
@Immutable
public final class WellKnownMutability implements ThreadSafety.KnownTypes {
public final class WellKnownMutability implements ThreadSafetyKnownTypes {

/** Types that are known to be immutable. */
private final ImmutableMap<String, AnnotationInfo> knownImmutableClasses;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import javax.inject.Inject;

/** A collection of types with known thread safety. */
public final class WellKnownThreadSafety implements ThreadSafety.KnownTypes {
public final class WellKnownThreadSafety implements ThreadSafetyKnownTypes {
@Inject
WellKnownThreadSafety(ErrorProneFlags flags, WellKnownMutability wellKnownMutability) {
ImmutableList<String> knownThreadSafe = flags.getListOrEmpty("ThreadSafe:KnownThreadSafe");
Expand Down

0 comments on commit c35a66d

Please sign in to comment.