@CompilerDirectives.TruffleBoundary public RubyConstant removeConstant(Node currentNode, String name) { checkFrozen(currentNode); RubyConstant oldConstant = constants.remove(name); newLexicalVersion(); return oldConstant; }
@CompilerDirectives.TruffleBoundary public void addMethod(Node currentNode, InternalMethod method) { assert method != null; if (getContext().getCoreLibrary().isLoadingRubyCore()) { final InternalMethod currentMethod = methods.get(method.getName()); if (currentMethod != null && currentMethod.getSharedMethodInfo().getSourceSection() instanceof CoreSourceSection) { return; } } checkFrozen(currentNode); methods.put(method.getName(), method.withDeclaringModule(rubyModuleObject)); newVersion(); if (context.getCoreLibrary().isLoaded() && !method.isUndefined()) { context.send( rubyModuleObject, "method_added", null, context.getSymbolTable().getSymbol(method.getName())); } }
@CompilerDirectives.TruffleBoundary public void prepend(Node currentNode, DynamicObject module) { assert RubyGuards.isRubyModule(module); checkFrozen(currentNode); // If the module we want to prepend already includes us, it is cyclic if (ModuleOperations.includesModule(module, rubyModuleObject)) { throw new RaiseException( getContext().getCoreLibrary().argumentError("cyclic prepend detected", currentNode)); } ModuleChain mod = Layouts.MODULE.getFields(module).start; ModuleChain cur = start; while (mod != null && !(RubyGuards.isRubyModule(mod) && RubyGuards.isRubyClass(((ModuleFields) mod).rubyModuleObject))) { if (!(mod instanceof PrependMarker)) { if (!ModuleOperations.includesModule(rubyModuleObject, mod.getActualModule())) { cur.insertAfter(mod.getActualModule()); Layouts.MODULE.getFields(mod.getActualModule()).addDependent(rubyModuleObject); cur = cur.getParentModule(); } } mod = mod.getParentModule(); } newVersion(); }
@CompilerDirectives.TruffleBoundary public Object removeClassVariable(Node currentNode, String name) { checkFrozen(currentNode); final Object found = classVariables.remove(name); if (found == null) { CompilerDirectives.transferToInterpreter(); throw new RaiseException( context .getCoreLibrary() .nameErrorClassVariableNotDefined(name, rubyModuleObject, currentNode)); } return found; }
@CompilerDirectives.TruffleBoundary public void changeConstantVisibility(Node currentNode, String name, boolean isPrivate) { checkFrozen(currentNode); RubyConstant rubyConstant = constants.get(name); if (rubyConstant != null) { rubyConstant.setPrivate(isPrivate); newLexicalVersion(); } else { throw new RaiseException( context .getCoreLibrary() .nameErrorUninitializedConstant(rubyModuleObject, name, currentNode)); } }
public void setConstantInternal(Node currentNode, String name, Object value, boolean autoload) { checkFrozen(currentNode); RubyConstant previous = constants.get(name); if (previous == null) { constants.put(name, new RubyConstant(rubyModuleObject, value, false, autoload)); } else { // TODO(CS): warn when redefining a constant // TODO (nirvdrum 18-Feb-15): But don't warn when redefining an autoloaded constant. constants.put( name, new RubyConstant(rubyModuleObject, value, previous.isPrivate(), autoload)); } newLexicalVersion(); }
@CompilerDirectives.TruffleBoundary public void include(Node currentNode, DynamicObject module) { assert RubyGuards.isRubyModule(module); checkFrozen(currentNode); // If the module we want to include already includes us, it is cyclic if (ModuleOperations.includesModule(module, rubyModuleObject)) { throw new RaiseException( getContext().getCoreLibrary().argumentError("cyclic include detected", currentNode)); } // We need to include the module ancestors in reverse order for a given inclusionPoint ModuleChain inclusionPoint = this; Deque<DynamicObject> modulesToInclude = new ArrayDeque<>(); for (DynamicObject ancestor : Layouts.MODULE.getFields(module).ancestors()) { if (ModuleOperations.includesModule(rubyModuleObject, ancestor)) { if (isIncludedModuleBeforeSuperClass(ancestor)) { // Include the modules at the appropriate inclusionPoint performIncludes(inclusionPoint, modulesToInclude); assert modulesToInclude.isEmpty(); // We need to include the others after that module inclusionPoint = parentModule; while (inclusionPoint.getActualModule() != ancestor) { inclusionPoint = inclusionPoint.getParentModule(); } } else { // Just ignore this module, as it is included above the superclass } } else { modulesToInclude.push(ancestor); } } performIncludes(inclusionPoint, modulesToInclude); newVersion(); }
@CompilerDirectives.TruffleBoundary public void setClassVariable(Node currentNode, String variableName, Object value) { checkFrozen(currentNode); classVariables.put(variableName, value); }