Skip to content

Commit

Permalink
Create ThreadSafeTypeParameter to replace ThreadSafe.TypeParameter.
Browse files Browse the repository at this point in the history
This is the first step in open sourcing the threadsafe equivalent of `ImmutableTypeParameter`. After this an LSC will be performed to replace all usages of `ThreadSafe.TypeParameter` with `ThreadSafeTypeParameter` after which and remaining references to the former (e.g. in messages) will be removed.

```
Startblock:
  has LGTM
  b/352709884 is fixed
```
PiperOrigin-RevId: 653005735
  • Loading branch information
java-team-github-bot authored and Error Prone Team committed Jul 16, 2024
1 parent 6bd568d commit 2656f48
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,7 @@
public class ThreadSafeCheckerTest {

private final CompilationTestHelper compilationHelper =
CompilationTestHelper.newInstance(ThreadSafeChecker.class, getClass())
// TODO: b/339025111 - Remove this once ThreadSafeTypeParameter actually exists.
.addSourceLines(
"ThreadSafeTypeParameter.java",
"package com.google.errorprone.annotations;",
"@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE_PARAMETER)",
"@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)",
"public @interface ThreadSafeTypeParameter {}");
CompilationTestHelper.newInstance(ThreadSafeChecker.class, getClass());

private final BugCheckerRefactoringTestHelper refactoringHelper =
BugCheckerRefactoringTestHelper.newInstance(ThreadSafeChecker.class, getClass());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright 2018 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.annotations;

import static java.lang.annotation.ElementType.TYPE_PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

/**
* When a {@link ThreadSafe} class has type parameters, annotating a parameter with {@code
* ThreadSafeTypeParameter} enforces that declarations of this class must, for that type parameter,
* use a type that is itself thread-safe.
*
* <p>Additionally, only type parameters that are annotated with {@code ThreadSafeTypeParameter} can
* be used as field types that are not {@link
* com.google.errorprone.annotations.concurrent.GuardedBy @GuardedBy}.
*
* <p>In more detail, consider this (valid) class:
*
* <pre>{@code
* @ThreadSafe class MyThreadSafeClass<A, B, @ThreadSafeTypeParameter C> {
*
* @GuardedBy("this") B b;
*
* final C c;
*
* MyThreadSafeClass(B b, C c) {
* this.b = b;
* this.c = c;
* }
* }
* }</pre>
*
* Each of these three type parameters is valid for a different reason: type parameter {@code A} is
* ok because it is simply not used as the type of a field; type parameter {@code B} is ok because
* it is used as the type of a field that is declared to be {@code @GuardedBy}; finally, type
* parameter {@code C} is ok because it is annotated with {@code ThreadSafeTypeParameter}.
* Furthermore, the declaration {@code MyThreadSafeClass<Object, Object, String>} is valid, since
* the type parameter {@code C} (i.e., {@code String}) is thread-safe, whereas a declaration {@code
* MyThreadSafeClass<Object, Object, Object>} would result in a compiler error.
*
* <p>Note: the {@code ThreadSafeTypeParameter} annotation has a secondary use case. If you annotate
* a type parameter of a method, then callers to that method are only allowed to pass in a type that
* is deemed thread-safe. For example, given the method declaration {@code static
* <@ThreadSafeTypeParameter T> void foo(T foo) {}}, a call to {@code foo} must pass a parameter
* that is deemed thread-safe.
*/
@Documented
@Target(TYPE_PARAMETER)
@Retention(RUNTIME)
public @interface ThreadSafeTypeParameter {}

0 comments on commit 2656f48

Please sign in to comment.