[inspection] IDEA-257415 Warnings for value-based classes (Java 16)

This patch adds the inspection to detect usages of value-based classes' instances as monitors in the synchronize statement.

Signed-off-by: Nikita Eshkeev <nikita.eshkeev@jetbrains.com>

GitOrigin-RevId: 178533c1415b2a8f11d48db17c19baa7e6ff4d1a
This commit is contained in:
Nikita Eshkeev
2020-12-24 04:02:33 +03:00
committed by intellij-monorepo-bot
parent 82a8d2c010
commit 7760811391
14 changed files with 243 additions and 0 deletions

View File

@@ -0,0 +1,28 @@
import valuebased.classes.OpenValueBased;
class One extends OpenValueBased { }
class Two extends One { }
class Three extends Two { }
class ComplexVBHierarchy extends Three { }
class Main {
final ComplexVBHierarchy vb = new ComplexVBHierarchy();
{
final ComplexVBHierarchy localVb = new ComplexVBHierarchy();
final Object objectVb = new ComplexVBHierarchy();
synchronized (<warning descr="Attempt to synchronize on an instance of a value-based class">vb</warning>) {}
synchronized (<warning descr="Attempt to synchronize on an instance of a value-based class">localVb</warning>) {}
synchronized (<warning descr="Attempt to synchronize on an instance of a value-based class">objectVb</warning>) {}
synchronized (ComplexVBHierarchy.class) {}
f(vb);
g(vb);
}
void f(ComplexVBHierarchy vb) {
synchronized (<warning descr="Attempt to synchronize on an instance of a value-based class">vb</warning>) {}
}
void g(Object vb) {
synchronized (vb) {}
}
}

View File

@@ -0,0 +1,25 @@
import valuebased.classes.AbstractValueBased;
class AC extends AbstractValueBased {
final AC ac = new AC();
final Object objectAc = new AC();
{
final AC localAc = new AC();
synchronized (<warning descr="Attempt to synchronize on an instance of a value-based class">ac</warning>) {}
synchronized (<warning descr="Attempt to synchronize on an instance of a value-based class">objectAc</warning>) {}
synchronized (<warning descr="Attempt to synchronize on an instance of a value-based class">localAc</warning>) {}
synchronized (AC.class) {}
f(ac);
g(ac);
}
void f(AC ac) {
synchronized (<warning descr="Attempt to synchronize on an instance of a value-based class">ac</warning>) {}
}
void g(Object ac) {
synchronized (ac) {}
}
}

View File

@@ -0,0 +1,25 @@
import valuebased.classes.IValueBased;
class IVB implements IValueBased {
final IVB vb = new IVB();
{
final IVB localVb = new IVB();
final Object objectVb = new IVB();
synchronized (<warning descr="Attempt to synchronize on an instance of a value-based class">vb</warning>) {}
synchronized (<warning descr="Attempt to synchronize on an instance of a value-based class">localVb</warning>) {}
synchronized (<warning descr="Attempt to synchronize on an instance of a value-based class">objectVb</warning>) {}
synchronized (IValueBased.class) {}
synchronized (IVB.class) {}
f(vb);
g(vb);
}
void f(IVB vb) {
synchronized (<warning descr="Attempt to synchronize on an instance of a value-based class">vb</warning>) {}
}
void g(Object vb) {
synchronized (vb) {}
}
}

View File

@@ -0,0 +1,24 @@
import valuebased.classes.OpenValueBased;
class Main {
final OpenValueBased vb = new OpenValueBased();
{
final OpenValueBased localVb = new OpenValueBased();
final Object objectVb = new OpenValueBased();
synchronized (<warning descr="Attempt to synchronize on an instance of a value-based class">vb</warning>) {}
synchronized (<warning descr="Attempt to synchronize on an instance of a value-based class">localVb</warning>) {}
synchronized (<warning descr="Attempt to synchronize on an instance of a value-based class">objectVb</warning>) {}
synchronized (OpenValueBased.class) {}
f(vb);
g(vb);
}
void f(OpenValueBased vb) {
synchronized (<warning descr="Attempt to synchronize on an instance of a value-based class">vb</warning>) {}
}
void g(Object vb) {
synchronized (vb) {}
}
}

View File

@@ -0,0 +1,11 @@
package jdk.internal;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.TYPE;
@Retention(RetentionPolicy.RUNTIME)
@Target(value={TYPE})
public @interface ValueBased { }

View File

@@ -0,0 +1,4 @@
package valuebased.classes;
package valuebased.classes;
@jdk.internal.ValueBased
public abstract static class AbstractValueBased { }

View File

@@ -0,0 +1,3 @@
package valuebased.classes;
@jdk.internal.ValueBased
public interface IValueBased { }

View File

@@ -0,0 +1,4 @@
package valuebased.classes;
@jdk.internal.ValueBased
public class OpenValueBased { }