mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
affect lambda instantiations when an abstract method in a SAM interface becomes non-abstract (IDEA-263109)
GitOrigin-RevId: 882c034d0cd6afbc297dca1e59e940dd90f8c5a4
This commit is contained in:
committed by
intellij-monorepo-bot
parent
b7ff0afe73
commit
adfe648216
+14
@@ -0,0 +1,14 @@
|
||||
Cleaning output files:
|
||||
out/production/DeleteSAMInterfaceMethod/Service.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/Service.java
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/DeleteSAMInterfaceMethod/DerivedServiceClient.class
|
||||
out/production/DeleteSAMInterfaceMethod/ServiceClient.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/DerivedServiceClient.java
|
||||
src/ServiceClient.java
|
||||
End of files
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
interface DerivedService extends Service {
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
public class DerivedServiceClient {
|
||||
public void execute() {
|
||||
Util.invokeDerivedService(() -> System.out.println("Hello2"));
|
||||
}
|
||||
}
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
interface Service {
|
||||
void foo();
|
||||
void bar(int a);
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
interface Service {
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
public class ServiceClient {
|
||||
public void execute() {
|
||||
Util.invokeService(() -> System.out.println("Hello"));
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
public class Util {
|
||||
public static void invokeService(Service s) {
|
||||
}
|
||||
|
||||
public static void invokeDerivedService(DerivedService s) {
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
Cleaning output files:
|
||||
out/production/RenameSAMInterfaceMethod/Service.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/Service.java
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/RenameSAMInterfaceMethod/DerivedService.class
|
||||
out/production/RenameSAMInterfaceMethod/DerivedServiceClient.class
|
||||
out/production/RenameSAMInterfaceMethod/ServiceClient.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/DerivedService.java
|
||||
src/DerivedServiceClient.java
|
||||
src/ServiceClient.java
|
||||
End of files
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
interface DerivedService extends Service {
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
public class DerivedServiceClient {
|
||||
public void execute() {
|
||||
Util.invokeDerivedService(() -> System.out.println("Hello2"));
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
interface Service {
|
||||
void foo();
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
interface Service {
|
||||
void bar();
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
public class ServiceClient {
|
||||
public void execute() {
|
||||
Util.invokeService(() -> System.out.println("Hello"));
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
public class Util {
|
||||
public static void invokeService(Service s) {
|
||||
}
|
||||
|
||||
public static void invokeDerivedService(DerivedService s) {
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
Cleaning output files:
|
||||
out/production/UnsetAbstractForSAMInterface/Service.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/Service.java
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/UnsetAbstractForSAMInterface/DerivedServiceClient.class
|
||||
out/production/UnsetAbstractForSAMInterface/ServiceClient.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/DerivedServiceClient.java
|
||||
src/ServiceClient.java
|
||||
End of files
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
interface DerivedService extends Service {
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
public class DerivedServiceClient {
|
||||
public void execute() {
|
||||
Util.invokeDerivedService(() -> System.out.println("Hello2"));
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
interface Service {
|
||||
void foo();
|
||||
|
||||
default void bar() {}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
interface Service {
|
||||
default void foo() {}
|
||||
|
||||
default void bar() {}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
public class ServiceClient {
|
||||
public void execute() {
|
||||
Util.invokeService(() -> System.out.println("Hello"));
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
public class Util {
|
||||
public static void invokeService(Service s) {
|
||||
s.foo();
|
||||
}
|
||||
|
||||
public static void invokeDerivedService(DerivedService s) {
|
||||
s.foo();
|
||||
}
|
||||
}
|
||||
@@ -552,8 +552,10 @@ public class Mappings {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isSAMInterface(ClassRepr cls) {
|
||||
if (!cls.isInterface()) {
|
||||
// test if a ClassRepr is a SAM interface
|
||||
boolean isLambdaTarget(int name) {
|
||||
final ClassRepr cls = classReprByName(name);
|
||||
if (cls == null || !cls.isInterface()) {
|
||||
return false;
|
||||
}
|
||||
int amFound = 0;
|
||||
@@ -847,6 +849,18 @@ public class Mappings {
|
||||
}.perform(moduleName);
|
||||
}
|
||||
|
||||
void affectLambdaInstantiations(Differential.DiffState state, final int className) {
|
||||
getAllSubclasses(className).forEach(name -> {
|
||||
if (isLambdaTarget(name)) {
|
||||
debug("The interface could be not a SAM interface anymore or lambda target method name has changed => affecting lambda instantiations for ", name);
|
||||
if (state.myAffectedUsages.add(UsageRepr.createClassNewUsage(myContext, name))) {
|
||||
appendDependents(name, state.myDependants);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
public class FileFilterConstraint implements UsageConstraint {
|
||||
@NotNull
|
||||
private final DependentFilesFilter myFilter;
|
||||
@@ -1201,8 +1215,8 @@ public class Mappings {
|
||||
if (it.isInterface()) {
|
||||
for (final MethodRepr m : added) {
|
||||
if (!m.isPrivate() && m.isAbstract()) {
|
||||
debug("Method: ", m.name);
|
||||
affectLambdaInstantiations(state, it.name);
|
||||
debug("Added non-private abstract method: ", m.name);
|
||||
myPresent.affectLambdaInstantiations(state, it.name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1310,20 +1324,6 @@ public class Mappings {
|
||||
debug("End of added methods processing");
|
||||
}
|
||||
|
||||
private void affectLambdaInstantiations(DiffState state, final int className) {
|
||||
assert myPresent != null;
|
||||
|
||||
getAllSubclasses(className).forEach(name -> {
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
final ClassRepr cr = myPresent.classReprByName(name);
|
||||
if (cr != null && myPresent.isSAMInterface(cr)) {
|
||||
debug("Abstract method added to a SAM interface => affecting lambda instantiations for ", name);
|
||||
state.myAffectedUsages.add(UsageRepr.createClassNewUsage(myContext, name));
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private void processRemovedMethods(final DiffState state, final ClassRepr.Diff diff, final ClassRepr it) {
|
||||
final Collection<MethodRepr> removed = diff.methods().removed();
|
||||
if (removed.isEmpty()) {
|
||||
@@ -1445,9 +1445,20 @@ public class Mappings {
|
||||
}
|
||||
debug("Processing changed methods:");
|
||||
|
||||
assert myPresent != null;
|
||||
assert myFuture != null;
|
||||
assert myAffectedFiles != null;
|
||||
|
||||
if (it.isInterface()) {
|
||||
for (final Pair<MethodRepr, MethodRepr.Diff> mr : changed) {
|
||||
if ((mr.second.removedModifiers() & Opcodes.ACC_ABSTRACT) != 0) {
|
||||
debug("Method became non-abstract: ", mr.first.name);
|
||||
myPresent.affectLambdaInstantiations(state, it.name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (final Pair<MethodRepr, MethodRepr.Diff> mr : changed) {
|
||||
final MethodRepr m = mr.first;
|
||||
final MethodRepr.Diff d = mr.second;
|
||||
@@ -1550,7 +1561,7 @@ public class Mappings {
|
||||
debug("Added final, public or abstract specifier --- affecting subclasses");
|
||||
myFuture.affectSubclasses(it.name, myAffectedFiles, state.myAffectedUsages, state.myDependants, false, myCompiledFiles, null);
|
||||
if (it.isInterface() && (d.addedModifiers() & Opcodes.ACC_ABSTRACT) != 0) {
|
||||
affectLambdaInstantiations(state, it.name);
|
||||
myPresent.affectLambdaInstantiations(state, it.name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3036,18 +3047,13 @@ public class Mappings {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean addAll(final TIntHashSet whereToAdd, TIntHashSet whatToAdd) {
|
||||
if (whatToAdd.isEmpty()) {
|
||||
return false;
|
||||
private static void addAll(final TIntHashSet whereToAdd, TIntHashSet whatToAdd) {
|
||||
if (!whatToAdd.isEmpty()) {
|
||||
whatToAdd.forEach(value -> {
|
||||
whereToAdd.add(value);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
final Ref<Boolean> changed = new Ref<>(Boolean.FALSE);
|
||||
whatToAdd.forEach(value -> {
|
||||
if (whereToAdd.add(value)) {
|
||||
changed.set(Boolean.TRUE);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return changed.get();
|
||||
}
|
||||
|
||||
private static void addAllKeys(final TIntHashSet whereToAdd, final IntIntMultiMaplet maplet) {
|
||||
|
||||
@@ -31,6 +31,14 @@ public class MemberChangeTest extends IncrementalTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testDeleteSAMInterfaceMethod() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testRenameSAMInterfaceMethod() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testAddSAMInterfaceAbstractMethod() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@@ -51,11 +51,14 @@ public class MethodModifierTest extends IncrementalTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
|
||||
public void testUnsetFinal() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testUnsetAbstractForSAMInterface() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testUnsetStatic() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user