1010import com .sun .source .tree .AnnotatedTypeTree ;
1111import com .sun .source .tree .AnnotationTree ;
1212import com .sun .source .tree .AssignmentTree ;
13+ import com .sun .source .tree .ClassTree ;
1314import com .sun .source .tree .ConditionalExpressionTree ;
1415import com .sun .source .tree .ExpressionTree ;
1516import com .sun .source .tree .IdentifierTree ;
@@ -366,6 +367,7 @@ private void reportInvalidOverridingMethodParamTypeError(
366367 * @return Type of the tree with preserved annotations.
367368 */
368369 private @ Nullable Type getTreeType (Tree tree ) {
370+ tree = ASTHelpers .stripParentheses (tree );
369371 if (tree instanceof NewClassTree
370372 && ((NewClassTree ) tree ).getIdentifier () instanceof ParameterizedTypeTree ) {
371373 ParameterizedTypeTree paramTypedTree =
@@ -842,36 +844,18 @@ public void compareGenericTypeParameterNullabilityForCall(
842844 return ;
843845 }
844846 Type invokedMethodType = methodSymbol .type ;
845- // substitute class-level type arguments for instance methods
846- if (!methodSymbol .isStatic () && tree instanceof MethodInvocationTree ) {
847- ExpressionTree methodSelect = ((MethodInvocationTree ) tree ).getMethodSelect ();
848- Type enclosingType ;
849- if (methodSelect instanceof MemberSelectTree ) {
850- enclosingType = getTreeType (((MemberSelectTree ) methodSelect ).getExpression ());
851- } else {
852- // implicit this parameter
853- enclosingType = methodSymbol .owner .type ;
854- }
855- if (enclosingType != null ) {
856- invokedMethodType =
857- TypeSubstitutionUtils .memberType (state .getTypes (), enclosingType , methodSymbol , config );
858- }
859- }
860-
861- // substitute type arguments for constructor call
862- if (tree instanceof NewClassTree ) {
863- // get the type arguments from the NewClassTree itself
864- Type enclosingType = getTreeType (tree );
865- if (enclosingType != null ) {
866- invokedMethodType =
867- TypeSubstitutionUtils .memberType (state .getTypes (), enclosingType , methodSymbol , config );
868- }
847+ Type enclosingType = getEnclosingTypeForCallExpression (methodSymbol , tree , state );
848+ if (enclosingType != null ) {
849+ invokedMethodType =
850+ TypeSubstitutionUtils .memberType (state .getTypes (), enclosingType , methodSymbol , config );
869851 }
870852
871853 // substitute type arguments for generic methods with explicit type arguments
872- if (tree instanceof MethodInvocationTree && methodSymbol .type instanceof Type .ForAll ) {
873- invokedMethodType = substituteTypeArgsInGenericMethodType (tree , methodSymbol , state );
854+ if (tree instanceof MethodInvocationTree && invokedMethodType instanceof Type .ForAll ) {
855+ invokedMethodType =
856+ substituteTypeArgsInGenericMethodType (tree , (Type .ForAll ) invokedMethodType , state );
874857 }
858+
875859 List <Type > formalParamTypes = invokedMethodType .getParameterTypes ();
876860 int n = formalParamTypes .size ();
877861 if (isVarArgs ) {
@@ -1071,8 +1055,9 @@ public Nullness getGenericReturnNullnessAtInvocation(
10711055 // If generic method invocation
10721056 if (!invokedMethodSymbol .getTypeParameters ().isEmpty ()) {
10731057 // Substitute type arguments inside the return type
1058+ Type .ForAll forAllType = (Type .ForAll ) invokedMethodSymbol .type ;
10741059 Type substitutedReturnType =
1075- substituteTypeArgsInGenericMethodType (tree , invokedMethodSymbol , state ).getReturnType ();
1060+ substituteTypeArgsInGenericMethodType (tree , forAllType , state ).getReturnType ();
10761061 // If this condition evaluates to false, we fall through to the subsequent logic, to handle
10771062 // type variables declared on the enclosing class
10781063 if (substitutedReturnType != null
@@ -1081,15 +1066,11 @@ public Nullness getGenericReturnNullnessAtInvocation(
10811066 }
10821067 }
10831068
1084- if (!(tree .getMethodSelect () instanceof MemberSelectTree ) || invokedMethodSymbol .isStatic ()) {
1085- return Nullness .NONNULL ;
1086- }
1087- Type methodReceiverType =
1088- getTreeType (((MemberSelectTree ) tree .getMethodSelect ()).getExpression ());
1089- if (methodReceiverType == null ) {
1069+ Type enclosingType = getEnclosingTypeForCallExpression (invokedMethodSymbol , tree , state );
1070+ if (enclosingType == null ) {
10901071 return Nullness .NONNULL ;
10911072 } else {
1092- return getGenericMethodReturnTypeNullness (invokedMethodSymbol , methodReceiverType , state );
1073+ return getGenericMethodReturnTypeNullness (invokedMethodSymbol , enclosingType , state );
10931074 }
10941075 }
10951076
@@ -1108,33 +1089,31 @@ private static com.sun.tools.javac.util.List<Type> convertTreesToTypes(
11081089 /**
11091090 * Substitutes the type arguments from a generic method invocation into the method's type.
11101091 *
1111- * @param tree the method invocation or new class tree
1112- * @param methodSymbol symbol for the invoked generic method
1092+ * @param tree the method invocation tree
1093+ * @param forAllType the generic method type
11131094 * @param state the visitor state
11141095 * @return the substituted method type for the generic method
11151096 */
11161097 private Type substituteTypeArgsInGenericMethodType (
1117- Tree tree , Symbol .MethodSymbol methodSymbol , VisitorState state ) {
1098+ Tree tree , Type .ForAll forAllType , VisitorState state ) {
1099+ Type .MethodType methodType = forAllType .asMethodType ();
11181100
11191101 List <? extends Tree > typeArgumentTrees =
11201102 (tree instanceof MethodInvocationTree )
11211103 ? ((MethodInvocationTree ) tree ).getTypeArguments ()
11221104 : ((NewClassTree ) tree ).getTypeArguments ();
11231105 com .sun .tools .javac .util .List <Type > explicitTypeArgs = convertTreesToTypes (typeArgumentTrees );
11241106
1125- Type .ForAll forAllType = (Type .ForAll ) methodSymbol .type ;
1126- Type .MethodType underlyingMethodType = (Type .MethodType ) forAllType .qtype ;
1127-
11281107 // There are no explicit type arguments, so use the inferred types
11291108 if (explicitTypeArgs .isEmpty ()) {
11301109 if (inferredTypeVarNullabilityForGenericCalls .containsKey (tree )
11311110 && tree instanceof MethodInvocationTree ) {
11321111 return getTypeWithInferredNullability (
1133- state , underlyingMethodType , inferredTypeVarNullabilityForGenericCalls .get (tree ));
1112+ state , methodType , inferredTypeVarNullabilityForGenericCalls .get (tree ));
11341113 }
11351114 }
11361115 return TypeSubstitutionUtils .subst (
1137- state .getTypes (), underlyingMethodType , forAllType .tvars , explicitTypeArgs , config );
1116+ state .getTypes (), methodType , forAllType .tvars , explicitTypeArgs , config );
11381117 }
11391118
11401119 /**
@@ -1178,8 +1157,9 @@ public Nullness getGenericParameterNullnessAtInvocation(
11781157 // If generic method invocation
11791158 if (!invokedMethodSymbol .getTypeParameters ().isEmpty ()) {
11801159 // Substitute the argument types within the MethodType
1181- Type substituted = substituteTypeArgsInGenericMethodType (tree , invokedMethodSymbol , state );
1182- List <Type > substitutedParamTypes = substituted .getParameterTypes ();
1160+ Type .ForAll forAllType = (Type .ForAll ) invokedMethodSymbol .type ;
1161+ List <Type > substitutedParamTypes =
1162+ substituteTypeArgsInGenericMethodType (tree , forAllType , state ).getParameterTypes ();
11831163 // If this condition evaluates to false, we fall through to the subsequent logic, to handle
11841164 // type variables declared on the enclosing class
11851165 if (substitutedParamTypes != null
@@ -1190,27 +1170,51 @@ public Nullness getGenericParameterNullnessAtInvocation(
11901170 }
11911171 }
11921172
1193- if (tree instanceof MethodInvocationTree ) {
1194- if (!(((MethodInvocationTree ) tree ).getMethodSelect () instanceof MemberSelectTree )
1195- || invokedMethodSymbol .isStatic ()) {
1196- return Nullness .NONNULL ;
1197- }
1173+ Type enclosingType = getEnclosingTypeForCallExpression (invokedMethodSymbol , tree , state );
1174+ if (enclosingType == null ) {
1175+ return Nullness .NONNULL ;
11981176 }
11991177
1178+ return getGenericMethodParameterNullness (paramIndex , invokedMethodSymbol , enclosingType , state );
1179+ }
1180+
1181+ /**
1182+ * Gets the enclosing type for a non-static method call expression, which is either the type of
1183+ * the enclosing class (for implicit this calls) or the type of the receiver expression. For a
1184+ * constructor call, we treat the type being allocated as the enclosing type.
1185+ *
1186+ * @param invokedMethodSymbol symbol for the invoked method
1187+ * @param tree the tree for the invocation
1188+ * @param state the visitor state
1189+ * @return the enclosing type for the method call, or null if it cannot be determined
1190+ */
1191+ private @ Nullable Type getEnclosingTypeForCallExpression (
1192+ Symbol .MethodSymbol invokedMethodSymbol , Tree tree , VisitorState state ) {
12001193 Type enclosingType = null ;
12011194 if (tree instanceof MethodInvocationTree ) {
1202- enclosingType =
1203- getTreeType (
1204- ((MemberSelectTree ) ((MethodInvocationTree ) tree ).getMethodSelect ()).getExpression ());
1205-
1195+ if (invokedMethodSymbol .isStatic ()) {
1196+ return null ;
1197+ }
1198+ ExpressionTree methodSelect =
1199+ ASTHelpers .stripParentheses (((MethodInvocationTree ) tree ).getMethodSelect ());
1200+ if (methodSelect instanceof IdentifierTree ) {
1201+ // implicit this parameter, or a super call. in either case, use the type of the enclosing
1202+ // class.
1203+ ClassTree enclosingClassTree =
1204+ ASTHelpers .findEnclosingNode (state .getPath (), ClassTree .class );
1205+ if (enclosingClassTree != null ) {
1206+ enclosingType = castToNonNull (ASTHelpers .getType (enclosingClassTree ));
1207+ }
1208+ } else if (methodSelect instanceof MemberSelectTree ) {
1209+ enclosingType = getTreeType (((MemberSelectTree ) methodSelect ).getExpression ());
1210+ }
12061211 } else {
12071212 Verify .verify (tree instanceof NewClassTree );
12081213 // for a constructor invocation, the type from the invocation itself is the "enclosing type"
12091214 // for the purposes of determining type arguments
12101215 enclosingType = getTreeType (tree );
12111216 }
1212-
1213- return getGenericMethodParameterNullness (paramIndex , invokedMethodSymbol , enclosingType , state );
1217+ return enclosingType ;
12141218 }
12151219
12161220 /**
0 commit comments