diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/ClassRepr.java b/jps/model/src/org/jetbrains/ether/dependencyView/ClassRepr.java index 7243b484fca3..9463e1f6fdc0 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/ClassRepr.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/ClassRepr.java @@ -136,6 +136,11 @@ public class ClassRepr extends Proto { public boolean hadValue() { return false; } + + @Override + public boolean weakedAccess() { + return diff.weakedAccess(); + } }; } diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/Difference.java b/jps/model/src/org/jetbrains/ether/dependencyView/Difference.java index a761581b7a39..38f875f33d92 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/Difference.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/Difference.java @@ -1,6 +1,7 @@ package org.jetbrains.ether.dependencyView; import com.intellij.openapi.util.Pair; +import org.jetbrains.asm4.Opcodes; import java.util.*; @@ -12,6 +13,16 @@ import java.util.*; * To change this template use File | Settings | File Templates. */ abstract class Difference { + public static boolean isPackageLocal(final int access) { + return (access & (Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED | Opcodes.ACC_PUBLIC)) == 0; + } + + public static boolean weakerAccess(final int me, final int then) { + return ((me & Opcodes.ACC_PRIVATE) > 0 && (then & Opcodes.ACC_PRIVATE) == 0) || + ((me & Opcodes.ACC_PROTECTED) > 0 && (then & Opcodes.ACC_PUBLIC) > 0) || + (isPackageLocal(me) && (then & Opcodes.ACC_PROTECTED) > 0); + } + public static final int NONE = 0; public static final int ACCESS = 1; public static final int TYPE = 2; @@ -21,8 +32,11 @@ abstract class Difference { public interface Specifier { Collection added(); + Collection removed(); + Collection> changed(); + boolean unchanged(); } @@ -105,11 +119,13 @@ abstract class Difference { public abstract boolean no(); + public abstract boolean weakedAccess(); + public abstract int addedModifiers(); public abstract int removedModifiers(); public abstract boolean packageLocalOn(); - public abstract boolean hadValue (); + public abstract boolean hadValue(); } diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java index 9f306aab8caa..1b8630e83fd8 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java @@ -733,19 +733,9 @@ public class Mappings { } } - private static boolean isPackageLocal(final int access) { - return (access & (Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED | Opcodes.ACC_PUBLIC)) == 0; - } - - private static boolean weakerAccess(final int me, final int then) { - return ((me & Opcodes.ACC_PRIVATE) > 0 && (then & Opcodes.ACC_PRIVATE) == 0) || - ((me & Opcodes.ACC_PROTECTED) > 0 && (then & Opcodes.ACC_PUBLIC) > 0) || - (isPackageLocal(me) && (then & Opcodes.ACC_PROTECTED) > 0); - } - private static boolean isVisibleIn(final ClassRepr c, final ProtoMember m, final ClassRepr scope) { final boolean privacy = ((m.access & Opcodes.ACC_PRIVATE) > 0) && c.name != scope.name; - final boolean packageLocality = isPackageLocal(m.access) && !c.getPackageName().equals(scope.getPackageName()); + final boolean packageLocality = Difference.isPackageLocal(m.access) && !c.getPackageName().equals(scope.getPackageName()); return !privacy && !packageLocality; } @@ -1080,7 +1070,7 @@ public class Mappings { final Option subtypeOf = u.isSubtypeOf(mm.type, m.type); - if (weakerAccess(mm.access, m.access) || + if (Difference.weakerAccess(mm.access, m.access) || ((m.access & Opcodes.ACC_STATIC) > 0 && (mm.access & Opcodes.ACC_STATIC) == 0) || ((m.access & Opcodes.ACC_STATIC) == 0 && (mm.access & Opcodes.ACC_STATIC) > 0) || ((m.access & Opcodes.ACC_FINAL) > 0) || @@ -1382,7 +1372,7 @@ public class Mappings { final boolean ffPrivate = (ff.access & Opcodes.ACC_PRIVATE) > 0; final boolean ffProtected = (ff.access & Opcodes.ACC_PROTECTED) > 0; final boolean ffPublic = (ff.access & Opcodes.ACC_PUBLIC) > 0; - final boolean ffPLocal = isPackageLocal(ff.access); + final boolean ffPLocal = Difference.isPackageLocal(ff.access); if (!ffPrivate) { final TIntHashSet propagated = o.propagateFieldAccess(ff.name, cc.name); @@ -1444,12 +1434,17 @@ public class Mappings { debug("Field: ", it.name); if ((field.access & Opcodes.ACC_PRIVATE) == 0 && (field.access & mask) == mask) { - if ((d.base() & Difference.ACCESS) > 0 || ((d.base() & Difference.VALUE) > 0 && d.hadValue())) { - debug("Inline field changed its access or value => a switch to non-incremental mode requested"); - if (!incrementalDecision(it.name, field, affectedFiles, filter)) { - debug("End of Differentiate, returning false"); - return false; - } + final int changedModifiers = d.addedModifiers() | d.removedModifiers(); + final boolean harmful = (changedModifiers & (Opcodes.ACC_STATIC | Opcodes.ACC_FINAL)) > 0; + final boolean accessChanged = (changedModifiers & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED)) > 0; + final boolean valueChanged = (d.base() & Difference.VALUE) > 0 && d.hadValue(); + + if (harmful || valueChanged || (accessChanged && !d.weakedAccess())) { + debug("Inline field changed it's access or value => a switch to non-incremental mode requested"); + if (!incrementalDecision(it.name, field, affectedFiles, filter)) { + debug("End of Differentiate, returning false"); + return false; + } } } diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/MethodRepr.java b/jps/model/src/org/jetbrains/ether/dependencyView/MethodRepr.java index 357807351b75..64641c47b5f6 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/MethodRepr.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/MethodRepr.java @@ -85,6 +85,11 @@ class MethodRepr extends ProtoMember { public boolean hadValue() { return ((MethodRepr)past).hasValue(); } + + @Override + public boolean weakedAccess() { + return diff.weakedAccess(); + } }; } diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/Proto.java b/jps/model/src/org/jetbrains/ether/dependencyView/Proto.java index 0c4dbf18e50a..39aaf0b36ed2 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/Proto.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/Proto.java @@ -1,6 +1,6 @@ package org.jetbrains.ether.dependencyView; -import groovyjarjarasm.asm.Opcodes; +import org.jetbrains.asm4.Opcodes; import org.jetbrains.ether.RW; import java.io.DataInput; @@ -86,17 +86,19 @@ class Proto implements RW.Savable { public boolean packageLocalOn() { return ((past.access & Opcodes.ACC_PRIVATE) != 0 || (past.access & Opcodes.ACC_PUBLIC) != 0 || - (past.access & Opcodes.ACC_PROTECTED) != 0) - - && - - ((access & Opcodes.ACC_PRIVATE) == 0 && (access & Opcodes.ACC_PROTECTED) == 0 && (access & Opcodes.ACC_PUBLIC) == 0); + (past.access & Opcodes.ACC_PROTECTED) != 0) && + Difference.isPackageLocal(access); } @Override public boolean hadValue() { return false; } + + @Override + public boolean weakedAccess() { + return Difference.weakerAccess(past.access, access); + } }; } } diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/ProtoMember.java b/jps/model/src/org/jetbrains/ether/dependencyView/ProtoMember.java index bdfee422d6bd..ed1e350a2ec4 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/ProtoMember.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/ProtoMember.java @@ -172,6 +172,11 @@ abstract class ProtoMember extends Proto { public boolean hadValue() { return ((ProtoMember)past).hasValue(); } + + @Override + public boolean weakedAccess() { + return diff.weakedAccess(); + } }; } }