in src/org/jetbrains/java/decompiler/main/ClassWriter.java [1016:1096]
private static RecordConstructorContext tryToDeleteRecordConstructor(@NotNull StructClass cl,
@NotNull StructMethod mt,
@NotNull MethodWrapper methodWrapper,
@NotNull MethodDescriptor md) {
GenericMethodDescriptor descriptor = mt.getSignature();
boolean hideMethod = false;
AnnotationContainer container = collectAllAnnotations(mt);
if (!container.memberAnnotation.isEmpty()) return new RecordConstructorContext(false, false);
boolean compact = false;
StringBuilder buf = new StringBuilder("(");
for (StructRecordComponent rec : cl.getRecordComponents()) {
buf.append(rec.getDescriptor());
}
String desc = buf.append(")V").toString();
if (desc.equals(mt.getDescriptor())) {
boolean[] found = new boolean[1];
boolean hideConstructorAndGetters = DecompilerContext.getOption(IFernflowerPreferences.HIDE_RECORD_CONSTRUCTOR_AND_GETTERS);
StructMethodParametersAttribute parameters = mt.getAttribute(ATTRIBUTE_METHOD_PARAMETERS);
if (parameters != null) {
final List<TypeAnnotation> typeAnnotations = TypeAnnotation.listFrom(mt);
List<StructMethodParametersAttribute.Entry> entries = parameters.getEntries();
compact = hideConstructorAndGetters && methodWrapper.getOrBuildGraph().iterateExprents((exprent) -> {
if (exprent.type == Exprent.EXPRENT_ASSIGNMENT) {
AssignmentExprent assignment = (AssignmentExprent)exprent;
if (assignment.getLeft() != null && assignment.getRight() != null &&
assignment.getLeft().type == Exprent.EXPRENT_FIELD &&
assignment.getRight().type == Exprent.EXPRENT_VAR) {
int index = -1;
for (StructRecordComponent component : cl.getRecordComponents()) {
index++;
if (component.getName() != null && component.getName().equals(((FieldExprent)assignment.getLeft()).getName())) {
break;
}
}
if (index == -1) return 1;
if (entries.size() <= index) return 1;
StructMethodParametersAttribute.Entry entry = entries.get(index);
if (entry.myName == null || !entry.myName.equals(((VarExprent)assignment.getRight()).getName())) {
return 1;
}
AnnotationContainer recordComponentAnnotations = collectAllAnnotations(cl.getRecordComponents().get(index));
VarType parameterType = descriptor != null ? descriptor.parameterTypes.get(index) : md.params[index];
List<AnnotationExprent> paramAnnotations = collectParameterAnnotations(mt, parameterType, index);
List<TypeAnnotation> typeParamAnnotations = TargetInfo.FormalParameterTarget.extract(typeAnnotations, index);
AnnotationContainer paramContainer = new AnnotationContainer(new HashSet<>(paramAnnotations),
typeParamAnnotations.stream()
.map(an -> new AnnotationContainer.TypeAnnotationModel(
an.getAnnotationExpr(), an.getPaths())).collect(Collectors.toSet()));
if (!recordComponentAnnotations.containsAll(paramContainer)) return 1;
found[0] = true;
return 0;
}
else if (assignment.getLeft().type == Exprent.EXPRENT_FIELD) {
return 1;
}
//not really necessary, but it is safer
else if (assignment.getLeft() instanceof VarExprent varExprent) {
if (entries.stream().anyMatch(entry -> entry.myName != null && entry.myName.equals(varExprent.getName()))) {
return 1;
}
}
}
return found[0] ? 1 : 0;
});
}
if (compact) {
methodWrapper.getOrBuildGraph().iterateExprents((exprent) -> {
if (exprent.type == Exprent.EXPRENT_ASSIGNMENT) {
AssignmentExprent assignment = (AssignmentExprent)exprent;
if (assignment.getLeft().type == Exprent.EXPRENT_FIELD) {
return 2;
}
}
return 0;
});
hideMethod = methodWrapper.getOrBuildGraph().iterateExprents((exprent) -> 1);
}
}
return new RecordConstructorContext(hideMethod, compact);
}