aboutsummaryrefslogtreecommitdiff
path: root/src/delombok
diff options
context:
space:
mode:
authorReinier Zwitserloot <reinier@zwitserloot.com>2019-01-22 04:28:18 +0100
committerReinier Zwitserloot <reinier@zwitserloot.com>2019-01-22 04:30:02 +0100
commitccd802503d8aa578be3f1f956d97b06a803de0aa (patch)
tree53bee7018a6dd79664ee9b711b7ca36146acb8c1 /src/delombok
parentba4e69bf30bf1c761b84e78dbec1fa1e285b02b6 (diff)
downloadlombok-ccd802503d8aa578be3f1f956d97b06a803de0aa.tar.gz
lombok-ccd802503d8aa578be3f1f956d97b06a803de0aa.tar.bz2
lombok-ccd802503d8aa578be3f1f956d97b06a803de0aa.zip
[fixes #2019] Lombok now properly deals with `@NonNull` specifically on the ‘type use’ of a parameter (and, in case of arrays, on the outermost dimension which is actually the first one listed. Weird corner case of the JLS).
Diffstat (limited to 'src/delombok')
-rw-r--r--src/delombok/lombok/delombok/PrettyPrinter.java96
1 files changed, 87 insertions, 9 deletions
diff --git a/src/delombok/lombok/delombok/PrettyPrinter.java b/src/delombok/lombok/delombok/PrettyPrinter.java
index 69249cc9..84c342f0 100644
--- a/src/delombok/lombok/delombok/PrettyPrinter.java
+++ b/src/delombok/lombok/delombok/PrettyPrinter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Project Lombok Authors.
+ * Copyright (C) 2016-2019 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -378,6 +378,9 @@ public class PrettyPrinter extends JCTree.Visitor {
private int dims(JCExpression vartype) {
if (vartype instanceof JCArrayTypeTree) {
return 1 + dims(((JCArrayTypeTree) vartype).elemtype);
+ } else if (isJcAnnotatedType(vartype)) {
+ JCTree underlyingType = readObject(vartype, "underlyingType", (JCTree) null);
+ if (underlyingType instanceof JCArrayTypeTree) return 1 + dims (((JCArrayTypeTree) underlyingType).elemtype);
}
return 0;
@@ -625,13 +628,29 @@ public class PrettyPrinter extends JCTree.Visitor {
printVarDef0(tree);
}
+ private boolean innermostArrayBracketsAreVarargs = false;
private void printVarDef0(JCVariableDecl tree) {
boolean varargs = (tree.mods.flags & VARARGS) != 0;
- if (varargs && tree.vartype instanceof JCArrayTypeTree) {
- print(((JCArrayTypeTree) tree.vartype).elemtype);
- print("...");
- } else {
+
+ /* story time!
+
+ in 'new int[5][6];', the 5 is the outermost and the 6 is the innermost: That means: 5 int arrays, each capable of containing 6 elements.
+ But that's actually a crazy way to read it; you'd think that in FOO[], you should interpret that as 'an array of FOO', but that's not correct;
+ if FOO is for example 'int[]', it's: "Modify the component type of FOO to be an array of whatever it was before.. unless FOO isn't an array, in which case,
+ this is an array of FOO". Which is weird.
+
+ This is particularly poignant with vargs. In: "int[]... x", the ... are actually the _INNER_ type even though varargs by definition is a modification of
+ how to interpret the outer. The JLS just sort of lets that be: To indicate varargs, replace the lexically last [] with dots even though that's the wrong
+ [] to modify!
+
+ This becomes an utter shambles when annotations-on-arrays become involved. The annotation on the INNER most type is to be placed right before the ...;
+ and because of that, we have to do crazy stuff with this innermostArrayBracketsAreVarargs flag.
+ */
+ try {
+ innermostArrayBracketsAreVarargs = varargs;
print(tree.vartype);
+ } finally {
+ innermostArrayBracketsAreVarargs = false;
}
print(" ");
print(tree.name);
@@ -775,10 +794,7 @@ public class PrettyPrinter extends JCTree.Visitor {
}
@Override public void visitTypeArray(JCArrayTypeTree tree) {
- JCTree elem = tree.elemtype;
- while (elem instanceof JCWildcard) elem = ((JCWildcard) elem).inner;
- print(elem);
- print("[]");
+ printTypeArray0(tree);
}
@Override public void visitNewArray(JCNewArray tree) {
@@ -1457,6 +1473,21 @@ public class PrettyPrinter extends JCTree.Visitor {
}
}
+ private boolean jcAnnotatedTypeInit = false;
+ private Class<?> jcAnnotatedTypeClass = null;
+
+ private boolean isJcAnnotatedType(Object o) {
+ if (o == null) return false;
+ if (jcAnnotatedTypeInit) return jcAnnotatedTypeClass == o.getClass();
+ Class<?> c = o.getClass();
+ if (c.getSimpleName().equals("JCAnnotatedType")) {
+ jcAnnotatedTypeClass = c;
+ jcAnnotatedTypeInit = true;
+ return true;
+ }
+ return false;
+ }
+
private void printMemberReference0(JCTree tree) {
print(readObject(tree, "expr", (JCExpression) null));
print("::");
@@ -1515,10 +1546,57 @@ public class PrettyPrinter extends JCTree.Visitor {
print(readObject(tree, "annotations", List.<JCExpression>nil()), " ");
print(" ");
print(((JCFieldAccess) underlyingType).name);
+ } else if (underlyingType instanceof JCArrayTypeTree) {
+ printTypeArray0(tree);
} else {
print(readObject(tree, "annotations", List.<JCExpression>nil()), " ");
print(" ");
print(underlyingType);
}
}
+
+ private void printTypeArray0(JCTree tree) {
+ JCTree inner = tree;
+ int dimCount = 0;
+
+ while (true) {
+ if (inner instanceof JCArrayTypeTree) {
+ inner = ((JCArrayTypeTree) inner).elemtype;
+ dimCount++;
+ continue;
+ } else if (isJcAnnotatedType(inner)) {
+ JCTree underlyingType = readObject(inner, "underlyingType", (JCTree) null);
+ if (underlyingType instanceof JCArrayTypeTree) {
+ inner = ((JCArrayTypeTree) underlyingType).elemtype;
+ dimCount++;
+ continue;
+ }
+ }
+ break;
+ }
+
+ print(inner);
+
+ inner = tree;
+ while (true) {
+ if (inner instanceof JCArrayTypeTree) {
+ dimCount--;
+ print((dimCount == 0 && innermostArrayBracketsAreVarargs) ? "..." : "[]");
+ inner = ((JCArrayTypeTree) inner).elemtype;
+ continue;
+ } else if (isJcAnnotatedType(inner)) {
+ JCTree underlyingType = readObject(inner, "underlyingType", (JCTree) null);
+ if (underlyingType instanceof JCArrayTypeTree) {
+ dimCount--;
+ print(" ");
+ print(readObject(inner, "annotations", List.<JCExpression>nil()), " ");
+ print(" ");
+ print((dimCount == 0 && innermostArrayBracketsAreVarargs) ? "..." : "[]");
+ inner = ((JCArrayTypeTree) underlyingType).elemtype;
+ continue;
+ }
+ }
+ break;
+ }
+ }
}