3232import com .sun .tools .javac .code .Kinds ;
3333import com .sun .tools .javac .code .Kinds .Kind ;
3434
35- import static com .sun .tools .javac .code .TypeTag .*;
36-
3735import com .sun .tools .javac .code .Preview ;
3836import com .sun .tools .javac .code .Source ;
3937import com .sun .tools .javac .code .Symbol ;
@@ -410,13 +408,31 @@ private UnrolledRecordPattern unrollRecordPattern(JCRecordPattern recordPattern)
410408 Assert .check (recordPattern .patternDeclaration != null );
411409
412410 if (allowPatternDeclarations ) {
411+ // Generate:
412+ // 1. calculate the returnType MethodType as Constant_MethodType_info
413+ // 2. generate factory code on carrier for the types we want (e.g., Object carrier = Carriers.initializingConstructor(returnType);)
414+ // 3. generate invoke call to pass the bindings (e.g, return carrier.invoke(x, y);)
415+ MethodSymbol factoryMethodSym =
416+ rs .resolveInternalMethod (recordPattern .pos (),
417+ env ,
418+ syms .carriersType ,
419+ names .fromString ("initializingConstructor" ),
420+ List .of (syms .methodTypeType ),
421+ List .nil ());
422+ DynamicVarSymbol factoryMethodDynamicVar =
423+ (DynamicVarSymbol ) invokeMethodWrapper (
424+ names .fromString ("carrier" ),
425+ recordPattern .pos (),
426+ factoryMethodSym .asHandle (),
427+ new MethodType (recordPattern .patternDeclaration .type .getBindingTypes (), syms .objectType , List .nil (), syms .methodClass ));
428+
413429 mSymbol = new BindingSymbol (Flags .SYNTHETIC ,
414430 names .fromString (target .syntheticNameChar () + "m" + target .syntheticNameChar () + variableIndex ++), syms .objectType ,
415431 currentMethodSym );
416432 JCVariableDecl mVar = make .VarDef (mSymbol , null );
417433
418434 firstLevelChecks = make .TypeTest (
419- generatePatternCall (recordPattern , tempBind ),
435+ generatePatternCall (recordPattern , tempBind , factoryMethodDynamicVar ),
420436 make .BindingPattern (mVar ).setType (mSymbol .type )).setType (syms .booleanType );
421437
422438 // Resolve Carriers.component(methodType, index) for subsequent constant dynamic call results
@@ -534,7 +550,7 @@ private UnrolledRecordPattern unrollRecordPattern(JCRecordPattern recordPattern)
534550 return new UnrolledRecordPattern ((JCBindingPattern ) make .BindingPattern (recordBindingVar ).setType (recordBinding .type ), guard );
535551 }
536552
537- private JCMethodInvocation generatePatternCall (JCRecordPattern recordPattern , BindingSymbol matchCandidate ) {
553+ private JCMethodInvocation generatePatternCall (JCRecordPattern recordPattern , BindingSymbol matchCandidate , DynamicVarSymbol factoryMethodDynamicVar ) {
538554 List <Type > staticArgTypes = List .of (syms .methodHandleLookupType ,
539555 syms .stringType ,
540556 syms .methodTypeType ,
@@ -549,16 +565,16 @@ private JCMethodInvocation generatePatternCall(JCRecordPattern recordPattern, Bi
549565
550566 // deconstructors, instance patterns and static patterns
551567 if (recordPattern .deconstructor instanceof JCFieldAccess acc && !TreeInfo .isStaticSelector (acc .selected , names )) {
552- /*receiver , match candidate */
553- invocationParamTypes = List .of (acc .selected .type , recordPattern .type );
554- invocationParams = List .of (acc .selected , make .Ident (matchCandidate ));
568+ /*receiver , match candidate carrier method handle */
569+ invocationParamTypes = List .of (acc .selected .type , recordPattern .type , factoryMethodDynamicVar . type );
570+ invocationParams = List .of (acc .selected , make .Ident (matchCandidate ), make . Ident ( factoryMethodDynamicVar ) );
555571 } else if (!recordPattern .patternDeclaration .isStatic () && !recordPattern .patternDeclaration .isDeconstructor ()) {
556- invocationParamTypes = List .of (recordPattern .type , recordPattern .type );
557- invocationParams = List .of (make .Ident (matchCandidate ), make .Ident (matchCandidate ));
572+ invocationParamTypes = List .of (recordPattern .type , recordPattern .type , factoryMethodDynamicVar . type );
573+ invocationParams = List .of (make .Ident (matchCandidate ), make .Ident (matchCandidate ), make . Ident ( factoryMethodDynamicVar ) );
558574 }
559575 else {
560- invocationParams = List .of (make . Ident ( matchCandidate ) );
561- invocationParamTypes = List .of (recordPattern . type );
576+ invocationParamTypes = List .of (recordPattern . type , factoryMethodDynamicVar . type );
577+ invocationParams = List .of (make . Ident ( matchCandidate ), make . Ident ( factoryMethodDynamicVar ) );
562578 }
563579 MethodType indyType = new MethodType (
564580 invocationParamTypes ,
@@ -1006,7 +1022,6 @@ private Symbol.DynamicVarSymbol makeBooleanConstant(DiagnosticPosition pos, int
10061022 * <pre>{@code
10071023 * binding1 = arg1;
10081024 * binding2 = arg2;
1009- * return carrier.invoke(binding1, binding2);
10101025 * }</pre>
10111026 *
10121027 */
@@ -1019,27 +1034,10 @@ public void visitMatch(JCMatch tree) {
10191034
10201035 ListBuffer <JCStatement > stats = new ListBuffer <>();
10211036
1022- // Generate:
1023- // 1. calculate the returnType MethodType as Constant_MethodType_info
1024- // 2. generate factory code on carrier for the types we want (e.g., Object carrier = Carriers.initializingConstructor(returnType);)
1025- // 3. generate invoke call to pass the bindings (e.g, return carrier.invoke(x, y);)
1026- MethodSymbol factoryMethodSym =
1027- rs .resolveInternalMethod (tree .pos (),
1028- env ,
1029- syms .carriersType ,
1030- names .fromString ("initializingConstructor" ),
1031- List .of (syms .methodTypeType ),
1032- List .nil ());
1033-
1034- DynamicVarSymbol factoryMethodDynamicVar =
1035- (DynamicVarSymbol ) invokeMethodWrapper (
1036- names .fromString ("carrier" ),
1037- tree .pos (),
1038- factoryMethodSym .asHandle (),
1039- new MethodType (tree .meth .type .getBindingTypes (), syms .objectType , List .nil (), syms .methodClass ));
1040-
1037+ // force the evaluation of each parameter to match
10411038 // Generate:
10421039 // parameter1 = arg1;
1040+ // ...
10431041 while (matchArguments .nonEmpty () && bindings .nonEmpty () && bindingTypes .nonEmpty ()) {
10441042 JCExpressionStatement stat =
10451043 make .Exec (make .Assign (make .Ident (bindings .head ),
@@ -1053,12 +1051,10 @@ public void visitMatch(JCMatch tree) {
10531051 matchArguments = matchArguments .tail ;
10541052 }
10551053
1056- JCIdent factoryMethodCall = make .Ident (factoryMethodDynamicVar );
1054+ // the same parameters must be passed to the carrier.invoke(<carrier arguments>)
1055+ // that is emitted in Lower:visitMethodDef
1056+ tree .meth .carrierArguments = invokeMethodParam ;
10571057
1058- JCMethodInvocation invokeMethodCall =
1059- makeApply (factoryMethodCall , names .fromString ("invoke" ), invokeMethodParam );
1060-
1061- stats = stats .append (make .Return (invokeMethodCall ));
10621058 result = make .at (tree .pos ).Block (0 , stats .toList ());
10631059 }
10641060
@@ -1456,10 +1452,6 @@ public void visitMethodDef(JCMethodDecl tree) {
14561452 currentMethodSym = tree .sym ;
14571453 variableIndex = 0 ;
14581454 deconstructorCalls = null ;
1459- if (tree .sym .isPattern ()) {
1460- tree .body .stats = tree .body .stats .append (
1461- make .Throw (makeNewClass (syms .matchExceptionType , List .of (makeNull (), makeNull ()))));
1462- }
14631455 super .visitMethodDef (tree );
14641456 preparePatternMatchingCatchIfNeeded (tree .body );
14651457 } finally {
0 commit comments