mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-05-06 13:20:53 +07:00
when parsing signatures, create GenericBoundUsage only for classes mentioned in signature bounds;
mark dependencies caused by GenericBoundUsage only in chunk being compiled and all chunks that depend on it recursively
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
Cleaning output files:
|
||||
out/production/ChangeExtends/Super.class
|
||||
out/production/ChangeExtends/Super2.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/Super.java
|
||||
src/Super2.java
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/ChangeExtends/Client.class
|
||||
@@ -13,4 +15,4 @@ Compiling files:
|
||||
src/Client.java
|
||||
src/Client2.java
|
||||
src/Client3.java
|
||||
End of files
|
||||
End of files
|
||||
@@ -0,0 +1,3 @@
|
||||
class Super2 {
|
||||
char s = 's';
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
class Client4 extends Hyper<Client4>{
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
class Super2 extends Hyper<Integer> {
|
||||
char s = 's';
|
||||
}
|
||||
@@ -217,61 +217,21 @@ class ClassfileAnalyzer {
|
||||
}
|
||||
}
|
||||
|
||||
private final SignatureVisitor mySignatureCrawler = new SignatureVisitor(Opcodes.ASM5) {
|
||||
public void visitFormalTypeParameter(String name) {
|
||||
}
|
||||
|
||||
private final SignatureVisitor mySignatureCrawler = new BaseSignatureVisitor() {
|
||||
public SignatureVisitor visitClassBound() {
|
||||
return this;
|
||||
return mySignatureWithGenericBoundUsageCrawler;
|
||||
}
|
||||
|
||||
public SignatureVisitor visitInterfaceBound() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public SignatureVisitor visitSuperclass() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public SignatureVisitor visitInterface() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public SignatureVisitor visitParameterType() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public SignatureVisitor visitReturnType() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public SignatureVisitor visitExceptionType() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public void visitBaseType(char descriptor) {
|
||||
}
|
||||
|
||||
public void visitTypeVariable(String name) {
|
||||
}
|
||||
|
||||
public SignatureVisitor visitArrayType() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public void visitInnerClassType(String name) {
|
||||
}
|
||||
|
||||
public void visitTypeArgument() {
|
||||
return mySignatureWithGenericBoundUsageCrawler;
|
||||
}
|
||||
|
||||
public SignatureVisitor visitTypeArgument(char wildcard) {
|
||||
return this;
|
||||
}
|
||||
|
||||
public void visitEnd() {
|
||||
return mySignatureWithGenericBoundUsageCrawler;
|
||||
}
|
||||
};
|
||||
|
||||
private final SignatureVisitor mySignatureWithGenericBoundUsageCrawler = new BaseSignatureVisitor() {
|
||||
public void visitClassType(String name) {
|
||||
final int className = myContext.get(name);
|
||||
myUsages.add(UsageRepr.createClassUsage(myContext, className));
|
||||
@@ -653,6 +613,72 @@ class ClassfileAnalyzer {
|
||||
myLocalClassFlag.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
private class BaseSignatureVisitor extends SignatureVisitor {
|
||||
|
||||
public BaseSignatureVisitor() {
|
||||
super(Opcodes.ASM5);
|
||||
}
|
||||
|
||||
public void visitFormalTypeParameter(String name) {
|
||||
}
|
||||
|
||||
public SignatureVisitor visitClassBound() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public SignatureVisitor visitInterfaceBound() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public SignatureVisitor visitSuperclass() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public SignatureVisitor visitInterface() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public SignatureVisitor visitParameterType() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public SignatureVisitor visitReturnType() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public SignatureVisitor visitExceptionType() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public void visitBaseType(char descriptor) {
|
||||
}
|
||||
|
||||
public void visitTypeVariable(String name) {
|
||||
}
|
||||
|
||||
public SignatureVisitor visitArrayType() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public void visitInnerClassType(String name) {
|
||||
}
|
||||
|
||||
public void visitTypeArgument() {
|
||||
}
|
||||
|
||||
public SignatureVisitor visitTypeArgument(char wildcard) {
|
||||
return this;
|
||||
}
|
||||
|
||||
public void visitEnd() {
|
||||
}
|
||||
|
||||
public void visitClassType(String name) {
|
||||
final int className = myContext.get(name);
|
||||
myUsages.add(UsageRepr.createClassUsage(myContext, className));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Pair<ClassRepr, Set<UsageRepr.Usage>> analyze(final int fileName, final ClassReader cr) {
|
||||
|
||||
@@ -716,6 +716,28 @@ public class Mappings {
|
||||
public abstract boolean checkResidence(final int residence);
|
||||
}
|
||||
|
||||
public class FileFilterConstraint extends UsageConstraint {
|
||||
@NotNull
|
||||
private final DependentFilesFilter myFilter;
|
||||
|
||||
public FileFilterConstraint(@NotNull DependentFilesFilter filter) {
|
||||
myFilter = filter;
|
||||
}
|
||||
|
||||
public boolean checkResidence(int residence) {
|
||||
final Collection<File> fNames = myClassToSourceFile.get(residence);
|
||||
if (fNames == null || fNames.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
for (File fName : fNames) {
|
||||
if (myFilter.accept(fName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public class PackageConstraint extends UsageConstraint {
|
||||
public final String packageName;
|
||||
|
||||
@@ -1132,6 +1154,11 @@ public class Mappings {
|
||||
debug("Class is annotation, skipping method analysis");
|
||||
return;
|
||||
}
|
||||
|
||||
assert myFuture != null;
|
||||
assert myPresent != null;
|
||||
assert myAffectedFiles != null;
|
||||
|
||||
Ref<ClassRepr> oldItRef = null;
|
||||
for (final MethodRepr m : added) {
|
||||
debug("Method: ", m.name);
|
||||
@@ -1256,6 +1283,10 @@ public class Mappings {
|
||||
if (removed.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
assert myFuture != null;
|
||||
assert myAffectedFiles != null;
|
||||
assert myCompiledFiles != null;
|
||||
|
||||
debug("Processing removed methods:");
|
||||
for (final MethodRepr m : removed) {
|
||||
debug("Method ", m.name);
|
||||
@@ -1362,6 +1393,10 @@ public class Mappings {
|
||||
return;
|
||||
}
|
||||
debug("Processing changed methods:");
|
||||
|
||||
assert myFuture != null;
|
||||
assert myAffectedFiles != null;
|
||||
|
||||
for (final Pair<MethodRepr, Difference> mr : changed) {
|
||||
final MethodRepr m = mr.first;
|
||||
final MethodRepr.Diff d = (MethodRepr.Diff)mr.second;
|
||||
@@ -1473,6 +1508,11 @@ public class Mappings {
|
||||
}
|
||||
debug("Processing added fields");
|
||||
|
||||
assert myFuture != null;
|
||||
assert myPresent != null;
|
||||
assert myCompiledFiles != null;
|
||||
assert myAffectedFiles != null;
|
||||
|
||||
for (final FieldRepr f : added) {
|
||||
debug("Field: ", f.name);
|
||||
|
||||
@@ -1535,23 +1575,23 @@ public class Mappings {
|
||||
// nothing
|
||||
}
|
||||
else {
|
||||
Util.UsageConstraint constaint;
|
||||
Util.UsageConstraint constraint;
|
||||
|
||||
if ((ff.isProtected() && f.isPublic()) || (f.isProtected() && ff.isPublic()) || (ff.isPackageLocal() && f.isProtected())) {
|
||||
constaint = myFuture.new NegationConstraint(myFuture.new InheritanceConstraint(cc.name));
|
||||
constraint = myFuture.new NegationConstraint(myFuture.new InheritanceConstraint(cc.name));
|
||||
}
|
||||
else if (ff.isPublic() && ff.isPackageLocal()) {
|
||||
constaint = myFuture.new NegationConstraint(myFuture.new PackageConstraint(cc.getPackageName()));
|
||||
constraint = myFuture.new NegationConstraint(myFuture.new PackageConstraint(cc.getPackageName()));
|
||||
}
|
||||
else {
|
||||
constaint =
|
||||
constraint =
|
||||
myFuture.new IntersectionConstraint(myFuture.new NegationConstraint(myFuture.new InheritanceConstraint(cc.name)),
|
||||
myFuture.new NegationConstraint(
|
||||
myFuture.new PackageConstraint(cc.getPackageName())));
|
||||
}
|
||||
|
||||
for (final UsageRepr.Usage usage : localUsages) {
|
||||
state.myUsageConstraints.put(usage, constaint);
|
||||
state.myUsageConstraints.put(usage, constraint);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1569,6 +1609,8 @@ public class Mappings {
|
||||
if (removed.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
assert myFuture != null;
|
||||
|
||||
debug("Processing removed fields:");
|
||||
|
||||
for (final FieldRepr f : removed) {
|
||||
@@ -1577,6 +1619,7 @@ public class Mappings {
|
||||
if (!f.isPrivate() && (f.access & DESPERATE_MASK) == DESPERATE_MASK && f.hasValue()) {
|
||||
debug("Field had value and was (non-private) final static => a switch to non-incremental mode requested");
|
||||
if (myConstantSearch != null) {
|
||||
assert myDelayedWorks != null;
|
||||
myDelayedWorks.addConstantWork(it.name, f, true, false);
|
||||
}
|
||||
else {
|
||||
@@ -1601,6 +1644,7 @@ public class Mappings {
|
||||
return true;
|
||||
}
|
||||
debug("Processing changed fields:");
|
||||
assert myFuture != null;
|
||||
|
||||
for (final Pair<FieldRepr, Difference> f : changed) {
|
||||
final Difference d = f.second;
|
||||
@@ -1619,6 +1663,7 @@ public class Mappings {
|
||||
if (harmful || valueChanged || becameLessAccessible) {
|
||||
debug("Inline field changed it's access or value => a switch to non-incremental mode requested");
|
||||
if (myConstantSearch != null) {
|
||||
assert myDelayedWorks != null;
|
||||
myDelayedWorks.addConstantWork(it.name, field, false, accessChanged);
|
||||
}
|
||||
else {
|
||||
@@ -1687,6 +1732,10 @@ public class Mappings {
|
||||
final Collection<Pair<ClassRepr, Difference>> changedClasses = state.myClassDiff.changed();
|
||||
if (!changedClasses.isEmpty()) {
|
||||
debug("Processing changed classes:");
|
||||
assert myFuture != null;
|
||||
assert myPresent != null;
|
||||
|
||||
final Util.FileFilterConstraint fileFilterConstraint = myFilter != null? myPresent.new FileFilterConstraint(myFilter) : null;
|
||||
|
||||
for (final Pair<ClassRepr, Difference> changed : changedClasses) {
|
||||
final ClassRepr changedClass = changed.first;
|
||||
@@ -1753,7 +1802,11 @@ public class Mappings {
|
||||
@Override
|
||||
public boolean execute(int className) {
|
||||
debug("Affecting usages in generic type parameter bounds of class: ", className);
|
||||
state.myAffectedUsages.add(UsageRepr.createClassAsGenericBoundUsage(myContext, className));
|
||||
final UsageRepr.Usage usage = UsageRepr.createClassAsGenericBoundUsage(myContext, className);
|
||||
state.myAffectedUsages.add(usage);
|
||||
if (fileFilterConstraint != null) {
|
||||
state.myUsageConstraints.put(usage, fileFilterConstraint);
|
||||
}
|
||||
|
||||
final TIntHashSet depClasses = myClassToClassDependency.get(className);
|
||||
if (depClasses != null) {
|
||||
@@ -1869,6 +1922,9 @@ public class Mappings {
|
||||
if (removed.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
assert myPresent != null;
|
||||
assert myDelta.myChangedFiles != null;
|
||||
|
||||
myDelta.myChangedFiles.add(fileName);
|
||||
|
||||
debug("Processing removed classes:");
|
||||
@@ -1896,6 +1952,9 @@ public class Mappings {
|
||||
|
||||
if (!myEasyMode && myFilter != null) {
|
||||
// checking if this newly added class duplicates already existing one
|
||||
assert myCompiledFiles != null;
|
||||
assert myAffectedFiles != null;
|
||||
|
||||
for (ClassRepr c : addedClasses) {
|
||||
if (!c.isLocal() && !c.isAnonymous() && isEmpty(c.getOuterClassName())) {
|
||||
final Set<File> candidates = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
|
||||
@@ -1976,6 +2035,8 @@ public class Mappings {
|
||||
}
|
||||
|
||||
private void affectCorrespondingSourceFiles(TIntHashSet toAffect) {
|
||||
assert myAffectedFiles != null;
|
||||
|
||||
toAffect.forEach(new TIntProcedure() {
|
||||
@Override
|
||||
public boolean execute(int depClass) {
|
||||
@@ -1995,6 +2056,8 @@ public class Mappings {
|
||||
|
||||
private void calculateAffectedFiles(final DiffState state) {
|
||||
debug("Checking dependent classes:");
|
||||
assert myAffectedFiles != null;
|
||||
assert myCompiledFiles != null;
|
||||
|
||||
state.myDependants.forEach(new TIntProcedure() {
|
||||
@Override
|
||||
@@ -2106,6 +2169,8 @@ public class Mappings {
|
||||
if (myEasyMode) {
|
||||
return false;
|
||||
}
|
||||
assert myAffectedFiles != null;
|
||||
assert myDelayedWorks != null;
|
||||
|
||||
final Collection<String> removed = myDelta.myRemovedFiles;
|
||||
if (removed != null) {
|
||||
@@ -2117,6 +2182,7 @@ public class Mappings {
|
||||
}
|
||||
finally {
|
||||
if (myFilesToCompile != null) {
|
||||
assert myDelta.myChangedFiles != null;
|
||||
// if some class is associated with several sources,
|
||||
// some of them may not have been compiled in this round, so such files should be considered unchanged
|
||||
myDelta.myChangedFiles.retainAll(myFilesToCompile);
|
||||
@@ -2463,7 +2529,9 @@ public class Mappings {
|
||||
}
|
||||
for (final String s : staticImports) {
|
||||
int i = s.length() - 1;
|
||||
for (; s.charAt(i) != '.'; i--) ;
|
||||
while (s.charAt(i) != '.') {
|
||||
i--;
|
||||
}
|
||||
final String anImport = s.substring(0, i);
|
||||
if (!anImport.endsWith("*")) {
|
||||
allImports.add(anImport); // filter out wildcard imports
|
||||
|
||||
Reference in New Issue
Block a user