@TruffleBoundary
  public static Object lookupClassVariable(RubyModule module, String name) {
    CompilerAsserts.neverPartOfCompilation();

    Object value;

    // Look in the current module
    value = module.getClassVariables().get(name);

    if (value != null) {
      return value;
    }

    // Look in ancestors
    for (RubyModule ancestor : module.parentAncestors()) {
      value = ancestor.getClassVariables().get(name);

      if (value != null) {
        return value;
      }
    }

    // Nothing found

    return null;
  }
  @TruffleBoundary
  public static InternalMethod lookupMethod(RubyModule module, String name) {
    CompilerAsserts.neverPartOfCompilation();

    InternalMethod method;

    // Look in the current module
    method = module.getMethods().get(name);

    if (method != null) {
      return method;
    }

    // Look in ancestors
    for (RubyModule ancestor : module.parentAncestors()) {
      method = ancestor.getMethods().get(name);

      if (method != null) {
        return method;
      }
    }

    // Nothing found

    return null;
  }
示例#3
0
  @Override
  public RubySymbol execute(VirtualFrame frame) {
    notDesignedForCompilation();

    final Object receiverObject = receiver.execute(frame);

    final RubyMethod methodObject = (RubyMethod) method.execute(frame);

    RubyModule module;

    if (receiverObject instanceof RubyModule) {
      module = (RubyModule) receiverObject;
    } else {
      module = ((RubyBasicObject) receiverObject).getSingletonClass(this);
    }

    final RubyMethod methodWithDeclaringModule = methodObject.withDeclaringModule(module);

    if (moduleFunctionFlag(frame)) {
      module.addMethod(this, methodWithDeclaringModule.withVisibility(Visibility.PRIVATE));
      module
          .getSingletonClass(this)
          .addMethod(this, methodWithDeclaringModule.withVisibility(Visibility.PUBLIC));
    } else {
      module.addMethod(this, methodWithDeclaringModule);
    }

    return getContext().newSymbol(method.getName());
  }
示例#4
0
  @Override
  public Object execute(VirtualFrame frame) {
    // TODO(cs): can module ever not evaluate to a RubyModule?

    final RubyModule moduleObject = (RubyModule) module.execute(frame);

    final Object rhsValue = rhs.execute(frame);

    assert rhsValue != null;
    assert !(rhsValue instanceof String);

    moduleObject.setModuleConstant(name, rhsValue);

    return rhsValue;
  }
示例#5
0
  public boolean isVisibleTo(RubyContext context, LexicalScope lexicalScope, RubyModule module) {
    CompilerAsserts.neverPartOfCompilation();
    assert lexicalScope == null || lexicalScope.getLiveModule() == module;

    if (!isPrivate) {
      return true;
    }

    // Look in lexical scope
    if (lexicalScope != null) {
      while (lexicalScope != context.getRootLexicalScope()) {
        if (lexicalScope.getLiveModule() == declaringModule) {
          return true;
        }
        lexicalScope = lexicalScope.getParent();
      }
    }

    // Look in ancestors
    if (module instanceof RubyClass) {
      for (RubyModule included : module.parentAncestors()) {
        if (included == declaringModule) {
          return true;
        }
      }
    }

    // Allow Object constants if looking with lexical scope.
    if (lexicalScope != null && context.getCoreLibrary().getObjectClass() == declaringModule) {
      return true;
    }

    return false;
  }
  @TruffleBoundary
  public static void setClassVariable(
      RubyModule module, String name, Object value, RubyNode currentNode) {
    CompilerAsserts.neverPartOfCompilation();

    // Look in the current module

    if (module.getClassVariables().containsKey(name)) {
      module.setClassVariable(currentNode, name, value);
      return;
    }

    // Look in ancestors

    for (RubyModule ancestor : module.parentAncestors()) {
      if (ancestor.getClassVariables().containsKey(name)) {
        ancestor.setClassVariable(currentNode, name, value);
        return;
      }
    }

    // Not existing class variable - set in the current module

    module.setClassVariable(currentNode, name, value);
  }
  public static boolean includesModule(RubyModule module, RubyModule other) {
    for (RubyModule ancestor : module.ancestors()) {
      if (ancestor == other) {
        return true;
      }
    }

    return false;
  }
  @TruffleBoundary
  public static Map<String, Object> getAllClassVariables(RubyModule module) {
    CompilerAsserts.neverPartOfCompilation();

    final Map<String, Object> classVariables = new HashMap<>();

    // Look in the current module
    classVariables.putAll(module.getClassVariables());

    // Look in ancestors
    for (RubyModule ancestor : module.parentAncestors()) {
      for (Map.Entry<String, Object> classVariable : ancestor.getClassVariables().entrySet()) {
        if (!classVariables.containsKey(classVariable.getKey())) {
          classVariables.put(classVariable.getKey(), classVariable.getValue());
        }
      }
    }

    return classVariables;
  }
  @TruffleBoundary
  public static Map<String, InternalMethod> getAllMethods(RubyModule module) {
    CompilerAsserts.neverPartOfCompilation();

    final Map<String, InternalMethod> methods = new HashMap<>();

    // Look in the current module
    methods.putAll(module.getMethods());

    // Look in ancestors
    for (RubyModule ancestor : module.parentAncestors()) {
      for (Map.Entry<String, InternalMethod> method : ancestor.getMethods().entrySet()) {
        if (!methods.containsKey(method.getKey())) {
          methods.put(method.getKey(), method.getValue());
        }
      }
    }

    return methods;
  }
  @TruffleBoundary
  public static Map<String, RubyConstant> getAllConstants(RubyModule module) {
    CompilerAsserts.neverPartOfCompilation();

    final Map<String, RubyConstant> constants = new HashMap<>();

    // Look in the current module
    constants.putAll(module.getConstants());

    // TODO(eregon): Look in lexical scope?

    // Look in ancestors
    for (RubyModule ancestor : module.parentAncestors()) {
      for (Map.Entry<String, RubyConstant> constant : ancestor.getConstants().entrySet()) {
        if (!constants.containsKey(constant.getKey())) {
          constants.put(constant.getKey(), constant.getValue());
        }
      }
    }

    return constants;
  }
  @TruffleBoundary
  public static InternalMethod lookupSuperMethod(
      RubyModule declaringModule, String name, RubyClass objectMetaClass) {
    CompilerAsserts.neverPartOfCompilation();

    boolean foundDeclaringModule = false;
    for (RubyModule module : objectMetaClass.ancestors()) {
      if (module == declaringModule) {
        foundDeclaringModule = true;
      } else if (foundDeclaringModule) {
        InternalMethod method = module.getMethods().get(name);

        if (method != null) {
          return method;
        }
      }
    }
    assert foundDeclaringModule
        : "Did not find the declaring module in " + objectMetaClass.getName() + " ancestors";

    return null;
  }
示例#12
0
  public boolean isVisibleTo(Node currentNode, RubyClass callerClass) {
    switch (visibility) {
      case PUBLIC:
        return true;

      case PROTECTED:
        for (RubyModule ancestor : callerClass.ancestors()) {
          if (ancestor == declaringModule || ancestor.getMetaClass() == declaringModule) {
            return true;
          }
        }

        return false;

      case PRIVATE:
        // A private method may only be called with an implicit receiver,
        // in which case the visibility must not be checked.
        return false;

      default:
        return false;
    }
  }
  /**
   * @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;
  }