/** * @param lexicalScope The surrounding LexicalScope (as in Constant), or null if it is ignored (as * in Mod::Constant or ::Constant) * @param module The receiver of the constant lookup. Must be identical to * lexicalScope.getLiveModule() if lexicalScope != null. */ @TruffleBoundary public static RubyConstant lookupConstant( RubyContext context, LexicalScope lexicalScope, RubyModule module, String name) { CompilerAsserts.neverPartOfCompilation(); assert lexicalScope == null || lexicalScope.getLiveModule() == module; RubyConstant constant; // Look in the current module constant = module.getConstants().get(name); if (constant != null) { return constant; } // Look in lexical scope if (lexicalScope != null) { if (lexicalScope != context.getRootLexicalScope()) { // Already looked in the top lexical scope, which is module. lexicalScope = lexicalScope.getParent(); } while (lexicalScope != context.getRootLexicalScope()) { constant = lexicalScope.getLiveModule().getConstants().get(name); if (constant != null) { return constant; } lexicalScope = lexicalScope.getParent(); } } // Look in ancestors for (RubyModule ancestor : module.parentAncestors()) { constant = ancestor.getConstants().get(name); if (constant != null) { return constant; } } // Look in Object and its included modules if (module.isOnlyAModule()) { final RubyClass objectClass = context.getCoreLibrary().getObjectClass(); constant = objectClass.getConstants().get(name); if (constant != null) { return constant; } for (RubyModule ancestor : objectClass.includedModules()) { constant = ancestor.getConstants().get(name); if (constant != null) { return constant; } } } // Nothing found return null; }