@@ -150,8 +150,7 @@ public static ConstantLookupResult lookupConstant(RubyContext context, RubyModul
150
150
private static ConstantLookupResult lookupConstant (RubyContext context , RubyModule module , String name ,
151
151
ArrayList <Assumption > assumptions ) {
152
152
// Look in the current module
153
- ModuleFields fields = module .fields ;
154
- ConstantEntry constantEntry = fields .getOrComputeConstantEntry (name );
153
+ ConstantEntry constantEntry = module .fields .getOrComputeConstantEntry (name );
155
154
assumptions .add (constantEntry .getAssumption ());
156
155
if (constantExists (constantEntry , assumptions )) {
157
156
return new ConstantLookupResult (constantEntry .getConstant (), toArray (assumptions ));
@@ -162,8 +161,7 @@ private static ConstantLookupResult lookupConstant(RubyContext context, RubyModu
162
161
if (ancestor == module ) {
163
162
continue ;
164
163
}
165
- fields = ancestor .fields ;
166
- constantEntry = fields .getOrComputeConstantEntry (name );
164
+ constantEntry = ancestor .fields .getOrComputeConstantEntry (name );
167
165
assumptions .add (constantEntry .getAssumption ());
168
166
if (constantExists (constantEntry , assumptions )) {
169
167
return new ConstantLookupResult (constantEntry .getConstant (), toArray (assumptions ));
@@ -179,16 +177,14 @@ public static ConstantLookupResult lookupConstantInObject(RubyContext context, S
179
177
ArrayList <Assumption > assumptions ) {
180
178
final RubyClass objectClass = context .getCoreLibrary ().objectClass ;
181
179
182
- ModuleFields fields = objectClass .fields ;
183
- ConstantEntry constantEntry = fields .getOrComputeConstantEntry (name );
180
+ ConstantEntry constantEntry = objectClass .fields .getOrComputeConstantEntry (name );
184
181
assumptions .add (constantEntry .getAssumption ());
185
182
if (constantExists (constantEntry , assumptions )) {
186
183
return new ConstantLookupResult (constantEntry .getConstant (), toArray (assumptions ));
187
184
}
188
185
189
186
for (RubyModule ancestor : objectClass .fields .prependedAndIncludedModules ()) {
190
- fields = ancestor .fields ;
191
- constantEntry = fields .getOrComputeConstantEntry (name );
187
+ constantEntry = ancestor .fields .getOrComputeConstantEntry (name );
192
188
assumptions .add (constantEntry .getAssumption ());
193
189
if (constantExists (constantEntry , assumptions )) {
194
190
return new ConstantLookupResult (constantEntry .getConstant (), toArray (assumptions ));
@@ -202,15 +198,13 @@ public static ConstantLookupResult lookupConstantInObject(RubyContext context, S
202
198
public static RubyConstant lookupConstantInObjectUncached (RubyContext context , String name ) {
203
199
final RubyClass objectClass = context .getCoreLibrary ().objectClass ;
204
200
205
- ModuleFields fields = objectClass .fields ;
206
- RubyConstant constant = fields .getConstant (name );
201
+ RubyConstant constant = objectClass .fields .getConstant (name );
207
202
if (constantExists (constant , null )) {
208
203
return constant ;
209
204
}
210
205
211
206
for (RubyModule ancestor : objectClass .fields .prependedAndIncludedModules ()) {
212
- fields = ancestor .fields ;
213
- constant = fields .getConstant (name );
207
+ constant = ancestor .fields .getConstant (name );
214
208
if (constantExists (constant , null )) {
215
209
return constant ;
216
210
}
@@ -243,8 +237,7 @@ public static ConstantLookupResult lookupConstantWithLexicalScope(RubyContext co
243
237
244
238
// Look in lexical scope
245
239
while (lexicalScope != context .getRootLexicalScope ()) {
246
- final ModuleFields fields = lexicalScope .getLiveModule ().fields ;
247
- final ConstantEntry constantEntry = fields .getOrComputeConstantEntry (name );
240
+ final ConstantEntry constantEntry = lexicalScope .getLiveModule ().fields .getOrComputeConstantEntry (name );
248
241
assumptions .add (constantEntry .getAssumption ());
249
242
if (constantExists (constantEntry , assumptions )) {
250
243
return new ConstantLookupResult (constantEntry .getConstant (), toArray (assumptions ));
@@ -328,8 +321,7 @@ public static ConstantLookupResult lookupConstantWithInherit(RubyContext context
328
321
return ModuleOperations .lookupConstant (context , module , name , assumptions );
329
322
}
330
323
} else {
331
- final ModuleFields fields = module .fields ;
332
- final ConstantEntry constantEntry = fields .getOrComputeConstantEntry (name );
324
+ final ConstantEntry constantEntry = module .fields .getOrComputeConstantEntry (name );
333
325
assumptions .add (constantEntry .getAssumption ());
334
326
if (constantExists (constantEntry , assumptions )) {
335
327
return new ConstantLookupResult (constantEntry .getConstant (), toArray (assumptions ));
@@ -426,49 +418,25 @@ public static Map<String, InternalMethod> withoutUndefinedMethods(Map<String, In
426
418
return definedMethods ;
427
419
}
428
420
429
- public static MethodLookupResult lookupMethodCached (RubyModule module , String name ,
430
- DeclarationContext declarationContext ) {
431
- return lookupMethodCached (module , null , name , declarationContext );
432
- }
433
-
434
421
@ TruffleBoundary
435
- private static MethodLookupResult lookupMethodCached (RubyModule module , RubyModule lookupTo , String name ,
422
+ public static MethodLookupResult lookupMethodCached (RubyModule module , String name ,
436
423
DeclarationContext declarationContext ) {
437
- final ArrayList < Assumption > assumptions = new ArrayList <>();
424
+ var assumptions = new ArrayList <Assumption >();
438
425
439
426
// Look in ancestors
440
427
for (RubyModule ancestor : module .fields .ancestors ()) {
441
- if (ancestor == lookupTo ) {
442
- return new MethodLookupResult (null , toArray (assumptions ));
443
- }
444
- final RubyModule [] refinements = getRefinementsFor (declarationContext , ancestor );
445
-
428
+ var refinements = getRefinementsFor (declarationContext , ancestor );
446
429
if (refinements != null ) {
447
430
for (RubyModule refinement : refinements ) {
448
- // If we have more then one active refinement for C (where C is refined module):
449
- // R1.ancestors = [R1, A, C, ...]
450
- // R2.ancestors = [R2, B, C, ...]
451
- // R3.ancestors = [R3, D, C, ...]
452
- // we are only looking up to C
453
- // R3 -> D -> R2 -> B -> R1 -> A
454
- final MethodLookupResult refinedMethod = lookupMethodCached (
455
- refinement ,
456
- ancestor ,
457
- name ,
458
- null );
459
- for (Assumption assumption : refinedMethod .getAssumptions ()) {
460
- assumptions .add (assumption );
461
- }
462
- if (refinedMethod .isDefined ()) {
463
- InternalMethod method = rememberUsedRefinements (refinedMethod .getMethod (), declarationContext );
431
+ var refinedMethod = refinement .fields .getMethodAndAssumption (name , assumptions );
432
+ if (refinedMethod != null ) {
433
+ InternalMethod method = rememberUsedRefinements (refinedMethod , declarationContext );
464
434
return new MethodLookupResult (method , toArray (assumptions ));
465
435
}
466
436
}
467
437
}
468
438
469
- final ModuleFields fields = ancestor .fields ;
470
- final InternalMethod method = fields .getMethodAndAssumption (name , assumptions );
471
-
439
+ var method = ancestor .fields .getMethodAndAssumption (name , assumptions );
472
440
if (method != null ) {
473
441
return new MethodLookupResult (method , toArray (assumptions ));
474
442
}
@@ -478,37 +446,22 @@ private static MethodLookupResult lookupMethodCached(RubyModule module, RubyModu
478
446
return new MethodLookupResult (null , toArray (assumptions ));
479
447
}
480
448
481
- public static InternalMethod lookupMethodUncached (RubyModule module , String name ,
482
- DeclarationContext declarationContext ) {
483
- return lookupMethodUncached (module , null , name , declarationContext );
484
- }
485
-
486
449
@ TruffleBoundary
487
- private static InternalMethod lookupMethodUncached (RubyModule module , RubyModule lookupTo , String name ,
450
+ public static InternalMethod lookupMethodUncached (RubyModule module , String name ,
488
451
DeclarationContext declarationContext ) {
489
-
452
+ // Look in ancestors
490
453
for (RubyModule ancestor : module .fields .ancestors ()) {
491
- if (ancestor == lookupTo ) {
492
- return null ;
493
- }
494
- final RubyModule [] refinements = getRefinementsFor (declarationContext , ancestor );
495
-
454
+ var refinements = getRefinementsFor (declarationContext , ancestor );
496
455
if (refinements != null ) {
497
456
for (RubyModule refinement : refinements ) {
498
- final InternalMethod refinedMethod = lookupMethodUncached (
499
- refinement ,
500
- ancestor ,
501
- name ,
502
- null );
457
+ var refinedMethod = refinement .fields .getMethod (name );
503
458
if (refinedMethod != null ) {
504
459
return rememberUsedRefinements (refinedMethod , declarationContext );
505
460
}
506
461
}
507
462
}
508
463
509
- final ModuleFields fields = ancestor .fields ;
510
- final InternalMethod method = fields .getMethod (name );
511
-
464
+ var method = ancestor .fields .getMethod (name );
512
465
if (method != null ) {
513
466
return method ;
514
467
}
@@ -518,82 +471,62 @@ private static InternalMethod lookupMethodUncached(RubyModule module, RubyModule
518
471
return null ;
519
472
}
520
473
474
+ @ TruffleBoundary
521
475
public static MethodLookupResult lookupSuperMethod (InternalMethod currentMethod , RubyModule objectMetaClass ) {
522
- final String name = currentMethod .getSharedMethodInfo ().getMethodNameForNotBlock (); // use the original name
476
+ var name = currentMethod .getSharedMethodInfo ().getMethodNameForNotBlock (); // use the original name
523
477
524
- Memo <Boolean > foundDeclaringModule = new Memo <>(false );
525
- return lookupSuperMethod (
526
- currentMethod .getDeclaringModule (),
527
- null ,
528
- name ,
529
- objectMetaClass ,
530
- foundDeclaringModule ,
531
- currentMethod .getDeclarationContext (),
532
- currentMethod .getActiveRefinements ());
533
- }
534
-
535
-
536
- @ TruffleBoundary
537
- private static MethodLookupResult lookupSuperMethod (RubyModule declaringModule , RubyModule lookupTo ,
538
- String name , RubyModule objectMetaClass , Memo <Boolean > foundDeclaringModule ,
539
- DeclarationContext declarationContext , DeclarationContext callerDeclaringContext ) {
540
- final ArrayList <Assumption > assumptions = new ArrayList <>();
541
- final boolean isRefinedMethod = declaringModule .fields .isRefinement ();
478
+ var foundDeclaringModule = new Memo <>(false );
479
+ var declaringModule = currentMethod .getDeclaringModule ();
480
+ var declarationContext = currentMethod .getDeclarationContext ();
481
+ var assumptions = new ArrayList <Assumption >();
542
482
483
+ // First we need to skip all ancestors until we find declaringModule,
484
+ // and then we return the first ancestor after declaringModule which has the method defined.
543
485
for (RubyModule ancestor : objectMetaClass .fields .ancestors ()) {
544
- if (ancestor == lookupTo ) {
545
- return new MethodLookupResult (null , toArray (assumptions ));
546
- }
547
-
548
- final RubyModule [] refinements = getRefinementsFor (declarationContext , callerDeclaringContext , ancestor );
549
-
486
+ var refinements = getRefinementsFor (declarationContext , currentMethod .getActiveRefinements (), ancestor );
550
487
if (refinements != null ) {
551
488
for (RubyModule refinement : refinements ) {
552
- final MethodLookupResult superMethodInRefinement = lookupSuperMethod (
553
- declaringModule ,
554
- ancestor ,
555
- name ,
556
- refinement ,
557
- foundDeclaringModule ,
558
- null ,
559
- null );
560
- for (Assumption assumption : superMethodInRefinement .getAssumptions ()) {
561
- assumptions .add (assumption );
562
- }
563
- if (superMethodInRefinement .isDefined ()) {
564
- InternalMethod method = superMethodInRefinement .getMethod ();
489
+ var refinedMethod = lookupSuperMethodInModule (declaringModule , name , foundDeclaringModule ,
490
+ refinement , assumptions );
491
+ if (refinedMethod != null ) {
565
492
return new MethodLookupResult (
566
- rememberUsedRefinements (method , declarationContext , refinements , ancestor ),
493
+ rememberUsedRefinements (refinedMethod , declarationContext , refinements , ancestor ),
567
494
toArray (assumptions ));
568
495
}
569
- if (foundDeclaringModule .get () && isRefinedMethod ) {
496
+ if (foundDeclaringModule .get () && declaringModule . fields . isRefinement () ) {
570
497
// if method is defined in refinement module (R)
571
- // we should lookup only in this active refinement and skip other
498
+ // we should lookup only in this active refinement and skip others
572
499
break ;
573
500
}
574
501
}
575
502
}
576
503
577
- if (!foundDeclaringModule .get ()) {
578
- if (ancestor == declaringModule ) {
579
- // The declaring module's assumption needs to appended for cases where a newly included module
580
- // should invalidate previous super lookups.
581
- ancestor .fields .getMethodAndAssumption (name , assumptions );
582
- foundDeclaringModule .set (true );
583
- }
584
- } else {
585
- final ModuleFields fields = ancestor .fields ;
586
- final InternalMethod method = fields .getMethodAndAssumption (name , assumptions );
587
- if (method != null ) {
588
- return new MethodLookupResult (method , toArray (assumptions ));
589
- }
504
+ var method = lookupSuperMethodInModule (declaringModule , name , foundDeclaringModule , ancestor , assumptions );
505
+ if (method != null ) {
506
+ return new MethodLookupResult (method , toArray (assumptions ));
590
507
}
591
508
}
592
509
593
510
// Nothing found
594
511
return new MethodLookupResult (null , toArray (assumptions ));
595
512
}
596
513
514
+
515
+ private static InternalMethod lookupSuperMethodInModule (RubyModule declaringModule , String name ,
516
+ Memo <Boolean > foundDeclaringModule , RubyModule module , ArrayList <Assumption > assumptions ) {
517
+ if (!foundDeclaringModule .get ()) {
518
+ if (module == declaringModule ) {
519
+ // The declaring module's assumption needs to appended for cases where a newly included module
520
+ // should invalidate previous super lookups.
521
+ module .fields .getMethodAndAssumption (name , assumptions );
522
+ foundDeclaringModule .set (true );
523
+ }
524
+ return null ;
525
+ } else {
526
+ return module .fields .getMethodAndAssumption (name , assumptions );
527
+ }
528
+ }
529
+
597
530
private static InternalMethod rememberUsedRefinements (InternalMethod method ,
598
531
DeclarationContext declarationContext ) {
599
532
return method .withActiveRefinements (declarationContext );
@@ -603,8 +536,7 @@ private static InternalMethod rememberUsedRefinements(InternalMethod method,
603
536
DeclarationContext declarationContext , RubyModule [] refinements , RubyModule ancestor ) {
604
537
assert refinements != null ;
605
538
606
- final Map <RubyModule , RubyModule []> currentRefinements = new HashMap <>(
607
- declarationContext .getRefinements ());
539
+ final Map <RubyModule , RubyModule []> currentRefinements = new HashMap <>(declarationContext .getRefinements ());
608
540
currentRefinements .put (ancestor , refinements );
609
541
610
542
return method .withActiveRefinements (declarationContext .withRefinements (currentRefinements ));
0 commit comments