99public class AttrImplicitParameter {
1010
1111 public static OptExpr getImplicitParameter (ExprMemberVar e ) {
12- Expr result = getImplicitParameterUsingLeft (e );
12+ Expr result = getImplicitParameterUsingLeft (e , true ); // keep static refs
1313 if (result == null ) {
1414 return getImplicitParamterCaseNormalVar (e );
1515 } else {
@@ -18,7 +18,7 @@ public static OptExpr getImplicitParameter(ExprMemberVar e) {
1818 }
1919
2020 public static OptExpr getImplicitParameter (ExprMemberArrayVar e ) {
21- Expr result = getImplicitParameterUsingLeft (e );
21+ Expr result = getImplicitParameterUsingLeft (e , true ); // keep static refs
2222 if (result == null ) {
2323 return getImplicitParamterCaseNormalVar (e );
2424 } else {
@@ -40,7 +40,7 @@ public static OptExpr getImplicitParameter(ExprFunctionCall e) {
4040 }
4141
4242 public static OptExpr getImplicitParameter (ExprMemberMethod e ) {
43- Expr result = getImplicitParameterUsingLeft (e );
43+ Expr result = getImplicitParameterUsingLeft (e , false );
4444 if (result == null ) {
4545 return getImplicitParameterCaseNormalFunctionCall (e );
4646 } else {
@@ -55,14 +55,19 @@ public static OptExpr getImplicitParameter(ExprMemberMethod e) {
5555 }
5656 }
5757
58- private static @ Nullable Expr getImplicitParameterUsingLeft (HasReceiver e ) {
59- if (e .getLeft ().attrTyp ().isStaticRef ()) {
60- // we have a static ref like Math.sqrt()
61- // this will be handled like if we just have sqrt()
62- // if we have an implicit parameter depends on whether sqrt is static or not
58+ private static @ Nullable Expr getImplicitParameterUsingLeft (HasReceiver e , boolean keepStaticRef ) {
59+ Expr left = e .getLeft ();
60+
61+ if (left .attrTyp ().isStaticRef ()) {
62+ // Only keep typed refs like Box<int> so we can specialize generics.
63+ // Plain identifiers like BoxInt must NOT become runtime receivers.
64+ if (keepStaticRef && left instanceof ExprTypeRef ) {
65+ return left ;
66+ }
6367 return null ;
6468 }
65- return e .getLeft ();
69+
70+ return left ;
6671 }
6772
6873 private static OptExpr getImplicitParameterCaseNormalFunctionCall (FunctionCall e ) {
@@ -71,12 +76,19 @@ private static OptExpr getImplicitParameterCaseNormalFunctionCall(FunctionCall e
7176 }
7277
7378 static OptExpr getFunctionCallImplicitParameter (FunctionCall e , FuncLink calledFunc , boolean showError ) {
74- if (e instanceof HasReceiver ) {
75- HasReceiver hasReceiver = (HasReceiver ) e ;
76- Expr res = getImplicitParameterUsingLeft (hasReceiver );
77- if (res != null ) {
78- return res ;
79+ if (e instanceof HasReceiver hasReceiver ) {
80+ Expr left = hasReceiver .getLeft ();
81+
82+ if (left .attrTyp ().isStaticRef ()) {
83+ // Keep ONLY typed static refs to propagate type args (Box<int>.foo()).
84+ if (left instanceof ExprTypeRef ) {
85+ return left ; // type-only receiver
86+ }
87+ return Ast .NoExpr (); // plain BoxInt.foo() has no receiver
7988 }
89+
90+ // normal dynamic receiver
91+ return left ;
8092 }
8193 if (calledFunc == null ) {
8294 return Ast .NoExpr ();
0 commit comments