@Override public Label interpret(InterpreterContext interp) { RubyModule clazz = (RubyModule) getArg().retrieve(interp); String name = method.getName(); ThreadContext context = interp.getContext(); Visibility visibility = context.getCurrentVisibility(); if (name == "initialize" || name == "initialize_copy" || visibility == Visibility.MODULE_FUNCTION) { visibility = Visibility.PRIVATE; } DynamicMethod newMethod = new InterpretedIRMethod(method, visibility, clazz); clazz.addMethod(name, newMethod); if (visibility == Visibility.MODULE_FUNCTION) { clazz .getSingletonClass() .addMethod( name, new WrapperMethod(clazz.getSingletonClass(), newMethod, Visibility.PUBLIC)); clazz.callMethod(context, "singleton_method_added", interp.getRuntime().fastNewSymbol(name)); } // 'class << state.self' and 'class << obj' uses defn as opposed to defs if (clazz.isSingleton()) { ((MetaClass) clazz) .getAttached() .callMethod(context, "singleton_method_added", interp.getRuntime().fastNewSymbol(name)); } else { clazz.callMethod(context, "method_added", interp.getRuntime().fastNewSymbol(name)); } return null; }
// Look through all mappings to find a match entry for this field private static void installField( ThreadContext context, Map<String, String> fieldMap, Field field, RubyModule module, boolean asReader, boolean asWriter) { boolean isFinal = Modifier.isFinal(field.getModifiers()); for (Iterator<Map.Entry<String, String>> iter = fieldMap.entrySet().iterator(); iter.hasNext(); ) { Map.Entry<String, String> entry = iter.next(); String key = entry.getKey(); if (key.equals(field.getName())) { if (Ruby.isSecurityRestricted() && !Modifier.isPublic(field.getModifiers())) { throw context .getRuntime() .newSecurityError( "Cannot change accessibility on fields in a restricted mode: field '" + field.getName() + "'"); } String asName = entry.getValue(); if (Modifier.isStatic(field.getModifiers())) { if (asReader) module.getSingletonClass().addMethod(asName, new StaticFieldGetter(key, module, field)); if (asWriter) { if (isFinal) throw context .getRuntime() .newSecurityError("Cannot change final field '" + field.getName() + "'"); module .getSingletonClass() .addMethod(asName + "=", new StaticFieldSetter(key, module, field)); } } else { if (asReader) module.addMethod(asName, new InstanceFieldGetter(key, module, field)); if (asWriter) { if (isFinal) throw context .getRuntime() .newSecurityError("Cannot change final field '" + field.getName() + "'"); module.addMethod(asName + "=", new InstanceFieldSetter(key, module, field)); } } iter.remove(); break; } } }
@Override public void load(Ruby ruby, boolean wrap) throws IOException { RubyModule pg = ruby.defineModule("PG"); ruby.defineClassUnder( "Error", ruby.getStandardError(), ruby.getStandardError().getAllocator(), pg); RubyModule pgConstants = ruby.defineModuleUnder("Constants", pg); // create the connection status constants for (ConnectionState status : ConnectionState.values()) pgConstants.defineConstant(status.name(), ruby.newFixnum(status.ordinal())); for (TransactionStatus status : TransactionStatus.values()) pgConstants.defineConstant(status.name(), ruby.newFixnum(status.ordinal())); for (ResultStatus status : ResultStatus.values()) pgConstants.defineConstant(status.name(), ruby.newFixnum(status.ordinal())); // create the large object constants pgConstants.defineConstant("INV_READ", new RubyFixnum(ruby, LargeObjectAPI.READ)); pgConstants.defineConstant("INV_WRITE", new RubyFixnum(ruby, LargeObjectAPI.WRITE)); pgConstants.defineConstant("SEEK_SET", new RubyFixnum(ruby, LargeObjectAPI.SEEK_SET)); pgConstants.defineConstant("SEEK_END", new RubyFixnum(ruby, LargeObjectAPI.SEEK_END)); pgConstants.defineConstant("SEEK_CUR", new RubyFixnum(ruby, LargeObjectAPI.SEEK_CUR)); // create error fields objects for (ErrorField field : ErrorResponse.ErrorField.values()) pgConstants.defineConstant(field.name(), ruby.newFixnum(field.getCode())); pg.getSingletonClass().defineAnnotatedMethods(Postgresql.class); try { for (java.lang.reflect.Field field : Oid.class.getDeclaredFields()) { String name = field.getName(); int value = field.getInt(null); pgConstants.defineConstant("OID_" + name, ruby.newFixnum(value)); } } catch (Exception e) { ruby.newRuntimeError(e.getLocalizedMessage()); } pgConstants.defineConstant("INVALID_OID", ruby.newFixnum(Oid.UNSPECIFIED)); pg.includeModule(pgConstants); Connection.define(ruby, pg, pgConstants); Result.define(ruby, pg, pgConstants); }
public static DynamicMethod populateModuleMethod(RubyModule cls, DynamicMethod javaMethod) { DynamicMethod moduleMethod = javaMethod.dup(); moduleMethod.setImplementationClass(cls.getSingletonClass()); moduleMethod.setVisibility(Visibility.PUBLIC); return moduleMethod; }