Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable package-private Getters/Setters/Constructors #251

Merged
merged 10 commits into from
Jun 27, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@ final class AdapterName {
} else {
shortName = name;
}
this.adapterPackage = "".equals(originPackage) ? "jsonb" : originPackage + ".jsonb";
if ("".equals(originPackage)) {
this.adapterPackage = "jsonb";
} else {
this.adapterPackage =
ProcessingContext.isImported(origin) ? originPackage + ".jsonb" : originPackage;
}
this.fullName = adapterPackage + "." + shortName + "JsonAdapter";
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ private void writeGetValue(Append writer, String varName, String suffix) {
} else if (publicField) {
writer.append("%s.%s%s", varName, fieldName, suffix);
} else {
throw new IllegalStateException("Field " + fieldName + " is inaccessible. Add a getter or make the field public.");
throw new IllegalStateException("Field " + fieldName + " is inaccessible. Add a getter or make the field public or package-private.");
}
}

Expand Down Expand Up @@ -278,6 +278,9 @@ void writeFromJsonSetter(Append writer, String varName, String prefix, String nu
writeFromJsonUnmapped(writer, varName);
return;
}
if (constructorParam) {
return;
}
if (setter != null && optional) {
writer.append("%s _$%s.%s(_val$%s);", prefix, varName, setter.getName(), fieldName + num).eol();
} else if (setter != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ final class FieldReader {
this.raw = RawPrism.isPresent(element);

final var fieldName = element.getSimpleName().toString();
final var publicField = !isMethod && !isParam && element.getModifiers().contains(Modifier.PUBLIC);
final var publicField = !isMethod && !isParam && Util.isPublic(element);
final var type = isMethod ? ((ExecutableElement) element).getReturnType() : element.asType();

this.property = new FieldProperty(type, raw, unmapped, genericTypeParams, publicField, fieldName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ private void writeAdaptersForMixInTypes(Set<? extends Element> mixInElements) {
final TypeMirror mirror = MixInPrism.getInstanceOn(mixin).value();
final String importType = mirror.toString();
final TypeElement element = asTypeElement(mirror);

ProcessingContext.addImportedType(mirror);
mixInImports.add(importType);
writeAdapterForMixInType(element, typeElement(mixin.asType().toString()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ List<MethodParam> getParams() {
}

boolean isPublic() {
return element.getModifiers().contains(Modifier.PUBLIC);
return Util.isPublic(element);
}

boolean isProtected() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
import javax.tools.FileObject;
import javax.tools.StandardLocation;

Expand All @@ -25,6 +26,7 @@ final class ProcessingContext {

private static final class Ctx {
private final Map<String, JsonPrism> importedJsonMap = new HashMap<>();
private final Set<String> importedTypes = new HashSet<>();
private final Map<String, List<SubTypePrism>> importedSubtypeMap = new HashMap<>();
private final Set<String> services = new TreeSet<>();
private final boolean injectPresent;
Expand Down Expand Up @@ -57,16 +59,25 @@ static void addImportedPrism(ImportPrism prism, Element element) {
final var json = CTX.get().importedJsonMap;
final var subtypes = CTX.get().importedSubtypeMap;
prism.value().forEach(m -> {
addImportedType(m);
final var type = m.toString();
json.put(type, prism.jsonSettings());
subtypes.put(type, prism.subtypes());
});
}

static void addImportedType(TypeMirror mirror) {
CTX.get().importedTypes.add(mirror.toString());
}

static Optional<JsonPrism> importedJson(TypeElement type) {
return Optional.ofNullable(CTX.get().importedJsonMap.get(type.asType().toString()));
}

static boolean isImported(TypeElement type) {
return CTX.get().importedTypes.contains(type.asType().toString());
}

static List<SubTypePrism> importedSubtypes(TypeElement type) {
return CTX.get().importedSubtypeMap.getOrDefault(type.asType().toString(), List.of());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,17 @@ final class TypeReader {

jsonCreator = jsonCreator.or(baseJsonCreator(baseType));
constructor = jsonCreator
.map(TypeReader::readJsonCreator)
.map(this::readJsonCreator)
.orElse(null);

this.hasJsonCreator = jsonCreator.isPresent();
}

private static MethodReader readJsonCreator(ExecutableElement ex) {
private MethodReader readJsonCreator(ExecutableElement ex) {
var mods = ex.getModifiers();
if (ex.getKind() != ElementKind.CONSTRUCTOR && !mods.contains(Modifier.STATIC) && !mods.contains(Modifier.PUBLIC)) {
if (ex.getKind() != ElementKind.CONSTRUCTOR
&& !mods.contains(Modifier.STATIC)
&& Util.isPublic(ex)) {
logError(ex, "@Json.Creator can only be placed on contructors and static factory methods");
}
return new MethodReader(ex).read();
Expand Down Expand Up @@ -263,7 +265,7 @@ private void readMethod(Element element, List<FieldReader> localFields) {
}

private boolean checkMethod2(ExecutableElement methodElement) {
if (!methodElement.getModifiers().contains(Modifier.PUBLIC)) {
if (!Util.isPublic(methodElement)) {
return false;
}
if (extendsThrowable) {
Expand Down
32 changes: 29 additions & 3 deletions jsonb-generator/src/main/java/io/avaje/jsonb/generator/Util.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package io.avaje.jsonb.generator;

import javax.lang.model.element.Element;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;

import static io.avaje.jsonb.generator.APContext.typeElement;
import static io.avaje.jsonb.generator.APContext.logError;
Expand Down Expand Up @@ -178,9 +181,7 @@ static String baseTypeOfAdapter(TypeElement element) {
.map(Util::extractTypeWithNest)
.orElseGet(
() -> {
logError(
element,
"Custom Adapters must implement JsonAdapter");
logError(element, "Custom Adapters must implement JsonAdapter");
return "Invalid";
});
}
Expand Down Expand Up @@ -208,4 +209,29 @@ static String extractTypeWithNest(String fullType) {
return result.toString();
}
}

static boolean isPublic(Element element) {
var mods = element.getModifiers();

if (mods.contains(Modifier.PUBLIC)) {
return true;
}
if (mods.contains(Modifier.PRIVATE) || mods.contains(Modifier.PROTECTED)) {
return false;
}
boolean isImported;
if (element instanceof TypeElement) {

isImported = ProcessingContext.isImported((TypeElement) element);
} else {
isImported = ProcessingContext.isImported((TypeElement) element.getEnclosingElement());
}

if (element instanceof VariableElement) {

return !isImported && !mods.contains(Modifier.FINAL);
}

return !isImported;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

class ProcessorTest {
class JsonbProcessorTest {

@AfterEach
void deleteGeneratedFiles() throws IOException {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.avaje.jsonb.generator.models.valid;

import io.avaje.jsonb.Json;

@Json
public class PackagePrivate {

Long id;
String street;
String suburb;
String city;
String funky;

PackagePrivate(Long id, String street, String suburb, String city) {
this.id = id;
this.street = street;
this.suburb = suburb;
this.city = city;
}
}
Loading