Skip to content

Commit 56a47df

Browse files
authored
Merge branch 'typetools:master' into patch-1
2 parents be399a6 + f86ebde commit 56a47df

File tree

10 files changed

+465
-113
lines changed

10 files changed

+465
-113
lines changed

checker/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ dependencies {
6565
// For the Resource Leak Checker's support for JavaEE.
6666
testImplementation 'javax.servlet:javax.servlet-api:4.0.1'
6767
// For the Resource Leak Checker's support for IOUtils.
68-
testImplementation 'commons-io:commons-io:2.18.0'
68+
testImplementation 'commons-io:commons-io:2.19.0'
6969
// To test for an obscure crash in CFG construction for try-with-resources;
7070
// see https://github.com/typetools/checker-framework/issues/6396
7171
testImplementation 'org.apache.spark:spark-sql_2.12:3.3.2'

checker/src/main/java/org/checkerframework/checker/calledmethods/CalledMethodsAnnotatedTypeFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ filterTree, collectionsSingletonList, getProcessingEnv())) {
293293
* At a fluent method call (which returns {@code this}), add the method to the type of the return
294294
* value.
295295
*/
296-
private class CalledMethodsTreeAnnotator extends AccumulationTreeAnnotator {
296+
private class CalledMethodsTreeAnnotator extends TreeAnnotator {
297297
/**
298298
* Creates an instance of this tree annotator for the given type factory.
299299
*
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package open.crash;
2+
3+
import java.util.Collection;
4+
import java.util.Map;
5+
import java.util.stream.Collectors;
6+
import java.util.stream.Stream;
7+
import org.checkerframework.checker.initialization.qual.Initialized;
8+
import org.checkerframework.checker.nullness.qual.Nullable;
9+
10+
// @below-java17-jdk-skip-test
11+
public class Issue7029Nullness {
12+
13+
private record Item(@Nullable String id) {}
14+
15+
Map<String, Item> test(Collection<Item> source) {
16+
return source.stream()
17+
.flatMap(
18+
item -> {
19+
@Initialized String id = item.id();
20+
return id == null ? Stream.empty() : Stream.of(Map.entry(id, item));
21+
})
22+
.collect(Collectors.toUnmodifiableMap(entry -> entry.getKey(), entry -> entry.getValue()));
23+
}
24+
}
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
// Earlier versions of the Checker Framework exhibited exponentially-long run time on this code due
2+
// to the long chain of `@This` methods.
3+
4+
import org.checkerframework.common.returnsreceiver.qual.*;
5+
6+
class ReturnsReceiverPerformance {
7+
8+
static class Builder {
9+
@This Builder m01() {
10+
return this;
11+
}
12+
13+
@This Builder m02() {
14+
return this;
15+
}
16+
17+
@This Builder m03() {
18+
return this;
19+
}
20+
21+
@This Builder m04() {
22+
return this;
23+
}
24+
25+
@This Builder m05() {
26+
return this;
27+
}
28+
29+
@This Builder m06() {
30+
return this;
31+
}
32+
33+
@This Builder m07() {
34+
return this;
35+
}
36+
37+
@This Builder m08() {
38+
return this;
39+
}
40+
41+
@This Builder m09() {
42+
return this;
43+
}
44+
45+
@This Builder m10() {
46+
return this;
47+
}
48+
49+
@This Builder m11() {
50+
return this;
51+
}
52+
53+
@This Builder m12() {
54+
return this;
55+
}
56+
57+
@This Builder m13() {
58+
return this;
59+
}
60+
61+
@This Builder m14() {
62+
return this;
63+
}
64+
65+
@This Builder m15() {
66+
return this;
67+
}
68+
69+
@This Builder m16() {
70+
return this;
71+
}
72+
73+
@This Builder m17() {
74+
return this;
75+
}
76+
77+
@This Builder m18() {
78+
return this;
79+
}
80+
81+
@This Builder m19() {
82+
return this;
83+
}
84+
85+
@This Builder m20() {
86+
return this;
87+
}
88+
89+
@This Builder m21() {
90+
return this;
91+
}
92+
93+
@This Builder m22() {
94+
return this;
95+
}
96+
97+
@This Builder m23() {
98+
return this;
99+
}
100+
101+
@This Builder m24() {
102+
return this;
103+
}
104+
105+
@This Builder m25() {
106+
return this;
107+
}
108+
109+
@This Builder m26() {
110+
return this;
111+
}
112+
113+
@This Builder m27() {
114+
return this;
115+
}
116+
117+
@This Builder m28() {
118+
return this;
119+
}
120+
121+
@This Builder m29() {
122+
return this;
123+
}
124+
125+
Object build() {
126+
return new Object();
127+
}
128+
}
129+
130+
Object go() {
131+
return new Builder()
132+
.m01()
133+
.m02()
134+
.m03()
135+
.m04()
136+
.m05()
137+
.m06()
138+
.m07()
139+
.m08()
140+
.m09()
141+
.m10()
142+
.m11()
143+
.m12()
144+
.m13()
145+
.m14()
146+
.m15()
147+
.m16()
148+
.m17()
149+
.m18()
150+
.m19()
151+
.m20()
152+
.m21()
153+
.m22()
154+
.m23()
155+
.m24()
156+
.m25()
157+
.m26()
158+
.m27()
159+
.m28()
160+
.m29()
161+
.build();
162+
}
163+
}

docs/manual/signature-checker.tex

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,25 @@
176176
\end{description}
177177
178178
179+
\subsectionAndLabel{How to choose which annotation to use}{signature-choosing-annotation}
180+
181+
Sometimes, there are multiple valid annotations for a value. As an
182+
example, a non-primitive non-array type is represented identically by
183+
\<@BinaryName>, \<@ClassGetName>, and \<@FqBinaryName>. Using the lowest
184+
type in the type hierarchy (in this case, \<@BinaryName>) has two
185+
advantages. First, it acts as documentation that the value is never a
186+
primitive or array. Second, it permits the value to be used in any of the
187+
three contexts: as a \<@BinaryName>, a \<@ClassGetName>, or a
188+
\<@FqBinaryName>.
189+
190+
Casting to \<@BinaryName> from one of the other types adds clutter if it is not
191+
necessary. Suppose that a method returns a \<@ClassGetName> and the value will
192+
only be used in contexts that require a \<@ClassGetName> (say, it is passed to a
193+
method that requires an argument of that type). Then there is no point in
194+
casting to \<@BinaryName> in between, even if you know the type being
195+
represented is not a primitive or an array.
196+
197+
179198
\sectionAndLabel{What the Signature Checker checks}{signature-checks}
180199
181200
Certain methods in the JDK, such as \<Class.forName>, are annotated
@@ -196,4 +215,5 @@
196215
% LocalWords: jls getName ClassGetName ClassLoader LMyClass Ljava jvms
197216
% LocalWords: DotSeparatedIdentifiers CharSequence Lmypackage mypackage
198217
% LocalWords: FieldDescriptorWithoutPackage InternalForm getSimpleName
199-
% LocalWords: ClassGetSimpleName FqBinaryName CanonicalName
218+
% LocalWords: ClassGetSimpleName FqBinaryName CanonicalName checkers''
219+
% LocalWords: Lpkg

framework/src/main/java/org/checkerframework/framework/util/typeinference8/util/CheckedExceptionsUtil.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
import com.sun.source.tree.TryTree;
99
import com.sun.source.util.TreeScanner;
1010
import java.util.ArrayList;
11+
import java.util.Collections;
1112
import java.util.List;
1213
import javax.lang.model.type.TypeKind;
1314
import javax.lang.model.type.TypeMirror;
1415
import javax.lang.model.type.UnionType;
16+
import org.checkerframework.checker.nullness.qual.Nullable;
1517
import org.checkerframework.framework.type.AnnotatedTypeMirror;
1618
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType;
1719
import org.checkerframework.javacutil.TreeUtils;
@@ -31,14 +33,16 @@ private CheckedExceptionsUtil() {}
3133
*/
3234
public static List<TypeMirror> thrownCheckedExceptions(
3335
LambdaExpressionTree lambda, Java8InferenceContext context) {
34-
return new CheckedExceptionVisitor(context).scan(lambda, null);
36+
@Nullable List<TypeMirror> result = new CheckedExceptionVisitor(context).scan(lambda, null);
37+
return result != null ? result : Collections.emptyList();
3538
}
3639

3740
/**
3841
* Helper class for gathering the types of checked exceptions in a lambda. See
3942
* https://docs.oracle.com/javase/specs/jls/se9/html/jls-11.html#jls-11.2.2
4043
*/
41-
private static class CheckedExceptionVisitor extends TreeScanner<List<TypeMirror>, Void> {
44+
private static class CheckedExceptionVisitor
45+
extends TreeScanner<@Nullable List<TypeMirror>, Void> {
4246

4347
/** the context. */
4448
private final Java8InferenceContext context;
@@ -70,7 +74,7 @@ public List<TypeMirror> visitThrow(ThrowTree node, Void aVoid) {
7074
if (result == null) {
7175
result = new ArrayList<>();
7276
}
73-
TypeMirror type = TreeUtils.typeOf(node);
77+
TypeMirror type = TreeUtils.typeOf(node.getExpression());
7478
if (isCheckedException(type, context)) {
7579
result.add(type);
7680
}
@@ -171,15 +175,17 @@ private static boolean isCheckedException(TypeMirror type, Java8InferenceContext
171175
*/
172176
public static List<AnnotatedTypeMirror> thrownCheckedExceptionsATM(
173177
LambdaExpressionTree lambda, Java8InferenceContext context) {
174-
return new CheckedExceptionATMVisitor(context).scan(lambda, null);
178+
@Nullable List<AnnotatedTypeMirror> result =
179+
new CheckedExceptionATMVisitor(context).scan(lambda, null);
180+
return result != null ? result : Collections.emptyList();
175181
}
176182

177183
/**
178184
* Helper class for gathering the types of checked exceptions in a lambda. See
179185
* https://docs.oracle.com/javase/specs/jls/se9/html/jls-11.html#jls-11.2.2
180186
*/
181187
private static class CheckedExceptionATMVisitor
182-
extends TreeScanner<List<AnnotatedTypeMirror>, Void> {
188+
extends TreeScanner<@Nullable List<AnnotatedTypeMirror>, Void> {
183189

184190
/** The context. */
185191
private final Java8InferenceContext context;
@@ -212,7 +218,7 @@ public List<AnnotatedTypeMirror> visitThrow(ThrowTree node, Void aVoid) {
212218
if (result == null) {
213219
result = new ArrayList<>();
214220
}
215-
AnnotatedTypeMirror type = context.typeFactory.getAnnotatedType(node);
221+
AnnotatedTypeMirror type = context.typeFactory.getAnnotatedType(node.getExpression());
216222
if (isCheckedException(type, context)) {
217223
result.add(type);
218224
}

0 commit comments

Comments
 (0)