diff --git a/java/src/json/ext/Generator.java b/java/src/json/ext/Generator.java index 2b3cd581..18d46f18 100644 --- a/java/src/json/ext/Generator.java +++ b/java/src/json/ext/Generator.java @@ -5,7 +5,6 @@ */ package json.ext; -import org.jcodings.Encoding; import org.jcodings.specific.UTF8Encoding; import org.jruby.Ruby; import org.jruby.RubyArray; @@ -15,7 +14,6 @@ import org.jruby.RubyFixnum; import org.jruby.RubyFloat; import org.jruby.RubyHash; -import org.jruby.RubyIO; import org.jruby.RubyString; import org.jruby.runtime.Helpers; import org.jruby.runtime.ThreadContext; @@ -29,7 +27,8 @@ import java.io.IOException; import java.io.OutputStream; import java.math.BigInteger; -import java.nio.charset.StandardCharsets; + +import static java.nio.charset.StandardCharsets.*; public final class Generator { @@ -44,12 +43,12 @@ private Generator() { */ static RubyString generateJson(ThreadContext context, T object, Handler handler) { Session session = new Session(null); - return session.infect(handler.generateNew(context, session, object)); + return handler.generateNew(context, session, object); } static RubyString generateJson(ThreadContext context, T object, Handler handler, IRubyObject arg0) { Session session = new Session(arg0); - return session.infect(handler.generateNew(context, session, object)); + return handler.generateNew(context, session, object); } /** @@ -93,21 +92,21 @@ static RubyString generateJson(ThreadContext context, T @SuppressWarnings("unchecked") private static Handler getHandlerFor(Ruby runtime, T object) { switch (((RubyBasicObject) object).getNativeClassIndex()) { - case NIL : return (Handler) NIL_HANDLER; - case TRUE : return (Handler) TRUE_HANDLER; - case FALSE : return (Handler) FALSE_HANDLER; - case FLOAT : return (Handler) FLOAT_HANDLER; - case FIXNUM : return (Handler) FIXNUM_HANDLER; - case BIGNUM : return (Handler) BIGNUM_HANDLER; + case NIL : return NIL_HANDLER; + case TRUE : return (Handler) TRUE_HANDLER; + case FALSE : return (Handler) FALSE_HANDLER; + case FLOAT : return (Handler) FLOAT_HANDLER; + case FIXNUM : return (Handler) FIXNUM_HANDLER; + case BIGNUM : return (Handler) BIGNUM_HANDLER; case STRING : - if (((RubyBasicObject) object).getMetaClass() != runtime.getString()) break; - return (Handler) STRING_HANDLER; + if (Helpers.metaclass(object) != runtime.getString()) break; + return (Handler) STRING_HANDLER; case ARRAY : - if (((RubyBasicObject) object).getMetaClass() != runtime.getArray()) break; - return (Handler) ARRAY_HANDLER; + if (Helpers.metaclass(object) != runtime.getArray()) break; + return (Handler) ARRAY_HANDLER; case HASH : - if (((RubyBasicObject) object).getMetaClass() != runtime.getHash()) break; - return (Handler) HASH_HANDLER; + if (Helpers.metaclass(object) != runtime.getHash()) break; + return (Handler) HASH_HANDLER; } return GENERIC_HANDLER; } @@ -132,9 +131,6 @@ static class Session { private RuntimeInfo info; private StringEncoder stringEncoder; - private boolean tainted = false; - private boolean untrusted = false; - Session(GeneratorState state) { this.state = state; } @@ -163,17 +159,6 @@ public StringEncoder getStringEncoder(ThreadContext context) { } return stringEncoder; } - - public void infectBy(IRubyObject object) { - if (object.isTaint()) tainted = true; - if (object.isUntrusted()) untrusted = true; - } - - public T infect(T object) { - if (tainted) object.setTaint(true); - if (untrusted) object.setUntrusted(true); - return object; - } } @@ -212,10 +197,10 @@ void generateToBuffer(ThreadContext context, Session session, T object, OutputSt */ private static class KeywordHandler extends Handler { - private byte[] keyword; + private final byte[] keyword; private KeywordHandler(String keyword) { - this.keyword = keyword.getBytes(StandardCharsets.UTF_8); + this.keyword = keyword.getBytes(UTF_8); } @Override @@ -242,7 +227,7 @@ void generate(ThreadContext context, Session session, T object, OutputStream buf @Override void generate(ThreadContext context, Session session, RubyBignum object, OutputStream buffer) throws IOException { BigInteger bigInt = object.getValue(); - buffer.write(bigInt.toString().getBytes(StandardCharsets.UTF_8)); + buffer.write(bigInt.toString().getBytes(UTF_8)); } }; @@ -266,15 +251,15 @@ void generate(ThreadContext context, Session session, RubyFloat object, OutputSt } } - buffer.write(Double.toString(value).getBytes(StandardCharsets.UTF_8)); + buffer.write(Double.toString(value).getBytes(UTF_8)); } }; private static final byte[] EMPTY_ARRAY_BYTES = "[]".getBytes(); - static final Handler ARRAY_HANDLER = - new Handler() { + static final Handler> ARRAY_HANDLER = + new Handler>() { @Override - int guessSize(ThreadContext context, Session session, RubyArray object) { + int guessSize(ThreadContext context, Session session, RubyArray object) { GeneratorState state = session.getState(context); int depth = state.getDepth(); int perItem = @@ -285,9 +270,9 @@ int guessSize(ThreadContext context, Session session, RubyArray object) { } @Override - void generate(ThreadContext context, Session session, RubyArray object, OutputStream buffer) throws IOException { + void generate(ThreadContext context, Session session, RubyArray object, OutputStream buffer) throws IOException { GeneratorState state = session.getState(context); - int depth = state.increaseDepth(); + int depth = state.increaseDepth(context); if (object.isEmpty()) { buffer.write(EMPTY_ARRAY_BYTES); @@ -306,27 +291,24 @@ void generate(ThreadContext context, Session session, RubyArray object, OutputSt System.arraycopy(arrayNl.unsafeBytes(), arrayNl.begin(), delim, 1, arrayNl.length()); - session.infectBy(object); - buffer.write((byte)'['); buffer.write(arrayNl.bytes()); boolean firstItem = true; for (int i = 0, t = object.getLength(); i < t; i++) { IRubyObject element = object.eltInternal(i); - session.infectBy(element); if (firstItem) { firstItem = false; } else { buffer.write(delim); } buffer.write(shift); - Handler handler = (Handler) getHandlerFor(runtime, element); + Handler handler = getHandlerFor(runtime, element); handler.generate(context, session, element, buffer); } state.decreaseDepth(); - if (arrayNl.length() != 0) { + if (!arrayNl.isEmpty()) { buffer.write(arrayNl.bytes()); buffer.write(shift, 0, state.getDepth() * indentUnit.length()); } @@ -352,7 +334,7 @@ int guessSize(ThreadContext context, Session session, RubyHash object) { @Override void generate(ThreadContext context, final Session session, RubyHash object, final OutputStream buffer) throws IOException { final GeneratorState state = session.getState(context); - final int depth = state.increaseDepth(); + final int depth = state.increaseDepth(context); if (object.isEmpty()) { buffer.write(EMPTY_HASH_BYTES); @@ -360,54 +342,53 @@ void generate(ThreadContext context, final Session session, RubyHash object, fin return; } - final Ruby runtime = context.runtime; - final ByteList objectNl = state.getObjectNl(); + byte[] objectNLBytes = objectNl.unsafeBytes(); final byte[] indent = Utils.repeat(state.getIndent(), depth); final ByteList spaceBefore = state.getSpaceBefore(); final ByteList space = state.getSpace(); buffer.write((byte)'{'); - buffer.write(objectNl.bytes()); + buffer.write(objectNLBytes); final boolean[] firstPair = new boolean[]{true}; - object.visitAll(new RubyHash.Visitor() { + object.visitAll(context, new RubyHash.VisitorWithState() { @Override - public void visit(IRubyObject key, IRubyObject value) { + public void visit(ThreadContext context, RubyHash self, IRubyObject key, IRubyObject value, int index, boolean[] firstPair) { try { if (firstPair[0]) { firstPair[0] = false; } else { buffer.write((byte) ','); - buffer.write(objectNl.bytes()); + buffer.write(objectNLBytes); } - if (objectNl.length() != 0) buffer.write(indent); + if (!objectNl.isEmpty()) buffer.write(indent); + + Ruby runtime = context.runtime; IRubyObject keyStr = key.callMethod(context, "to_s"); if (keyStr.getMetaClass() == runtime.getString()) { STRING_HANDLER.generate(context, session, (RubyString) keyStr, buffer); } else { Utils.ensureString(keyStr); - Handler keyHandler = (Handler) getHandlerFor(runtime, keyStr); + Handler keyHandler = getHandlerFor(runtime, keyStr); keyHandler.generate(context, session, keyStr, buffer); } - session.infectBy(key); - buffer.write(spaceBefore.bytes()); + buffer.write(spaceBefore.unsafeBytes()); buffer.write((byte) ':'); - buffer.write(space.bytes()); + buffer.write(space.unsafeBytes()); - Handler valueHandler = (Handler) getHandlerFor(runtime, value); + Handler valueHandler = getHandlerFor(runtime, value); valueHandler.generate(context, session, value, buffer); - session.infectBy(value); } catch (Throwable t) { Helpers.throwException(t); } } - }); + }, firstPair); state.decreaseDepth(); - if (!firstPair[0] && objectNl.length() != 0) { - buffer.write(objectNl.bytes()); + if (!firstPair[0] && !objectNl.isEmpty()) { + buffer.write(objectNLBytes); } buffer.write(Utils.repeat(state.getIndent(), state.getDepth())); buffer.write((byte)'}'); @@ -445,11 +426,11 @@ void generate(ThreadContext context, Session session, RubyString object, OutputS }; static final Handler TRUE_HANDLER = - new KeywordHandler("true"); + new KeywordHandler<>("true"); static final Handler FALSE_HANDLER = - new KeywordHandler("false"); + new KeywordHandler<>("false"); static final Handler NIL_HANDLER = - new KeywordHandler("null"); + new KeywordHandler<>("null"); /** * The default handler (Object#to_json): coerces the object diff --git a/java/src/json/ext/GeneratorMethods.java b/java/src/json/ext/GeneratorMethods.java index ec44f4b3..81f01162 100644 --- a/java/src/json/ext/GeneratorMethods.java +++ b/java/src/json/ext/GeneratorMethods.java @@ -12,7 +12,6 @@ import org.jruby.RubyFixnum; import org.jruby.RubyFloat; import org.jruby.RubyHash; -import org.jruby.RubyInteger; import org.jruby.RubyModule; import org.jruby.RubyNumeric; import org.jruby.RubyString; @@ -30,8 +29,8 @@ class GeneratorMethods { /** * Populates the given module with all modules and their methods - * @param info - * @param generatorMethodsModule The module to populate + * @param info The current RuntimeInfo + * @param module The module to populate * (normally JSON::Generator::GeneratorMethods) */ static void populate(RuntimeInfo info, RubyModule module) { @@ -45,19 +44,18 @@ static void populate(RuntimeInfo info, RubyModule module) { defineMethods(module, "String", RbString.class); defineMethods(module, "TrueClass", RbTrue.class); - info.stringExtendModule = new WeakReference(module.defineModuleUnder("String") - .defineModuleUnder("Extend")); + info.stringExtendModule = new WeakReference<>(module.defineModuleUnder("String").defineModuleUnder("Extend")); info.stringExtendModule.get().defineAnnotatedMethods(StringExtend.class); } /** * Convenience method for defining methods on a submodule. - * @param parentModule - * @param submoduleName - * @param klass + * @param parentModule the parent module + * @param submoduleName the submodule + * @param klass the class from which to define methods */ private static void defineMethods(RubyModule parentModule, - String submoduleName, Class klass) { + String submoduleName, Class klass) { RubyModule submodule = parentModule.defineModuleUnder(submoduleName); submodule.defineAnnotatedMethods(klass); } @@ -77,12 +75,12 @@ public static IRubyObject to_json(ThreadContext context, IRubyObject vSelf, IRub public static class RbArray { @JRubyMethod public static IRubyObject to_json(ThreadContext context, IRubyObject vSelf) { - return Generator.generateJson(context, (RubyArray)vSelf, Generator.ARRAY_HANDLER); + return Generator.generateJson(context, (RubyArray)vSelf, Generator.ARRAY_HANDLER); } @JRubyMethod public static IRubyObject to_json(ThreadContext context, IRubyObject vSelf, IRubyObject arg0) { - return Generator.generateJson(context, (RubyArray)vSelf, Generator.ARRAY_HANDLER, arg0); + return Generator.generateJson(context, (RubyArray)vSelf, Generator.ARRAY_HANDLER, arg0); } } @@ -154,7 +152,7 @@ public static IRubyObject to_json_raw_object(ThreadContext context, IRubyObject private static RubyHash toJsonRawObject(ThreadContext context, RubyString self) { - Ruby runtime = context.getRuntime(); + Ruby runtime = context.runtime; RubyHash result = RubyHash.newHash(runtime); IRubyObject createId = RuntimeInfo.forRuntime(runtime) @@ -174,7 +172,7 @@ private static RubyHash toJsonRawObject(ThreadContext context, @JRubyMethod(module=true) public static IRubyObject included(ThreadContext context, IRubyObject vSelf, IRubyObject module) { - RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime()); + RuntimeInfo info = RuntimeInfo.forRuntime(context.runtime); return module.callMethod(context, "extend", info.stringExtendModule.get()); } } @@ -190,7 +188,7 @@ public static class StringExtend { @JRubyMethod public static IRubyObject json_create(ThreadContext context, IRubyObject vSelf, IRubyObject vHash) { - Ruby runtime = context.getRuntime(); + Ruby runtime = context.runtime; RubyHash o = vHash.convertToHash(); IRubyObject rawData = o.fastARef(runtime.newString("raw")); if (rawData == null) { diff --git a/java/src/json/ext/GeneratorState.java b/java/src/json/ext/GeneratorState.java index 977444aa..34a3f9b8 100644 --- a/java/src/json/ext/GeneratorState.java +++ b/java/src/json/ext/GeneratorState.java @@ -108,11 +108,7 @@ public class GeneratorState extends RubyObject { */ private int depth = 0; - static final ObjectAllocator ALLOCATOR = new ObjectAllocator() { - public IRubyObject allocate(Ruby runtime, RubyClass klazz) { - return new GeneratorState(runtime, klazz); - } - }; + static final ObjectAllocator ALLOCATOR = GeneratorState::new; public GeneratorState(Ruby runtime, RubyClass metaClass) { super(runtime, metaClass); @@ -126,15 +122,13 @@ public GeneratorState(Ruby runtime, RubyClass metaClass) { * configured by opts, something else to create an * unconfigured instance. If opts is a State * object, it is just returned. - * @param clazzParam The receiver of the method call - * ({@link RubyClass} State) + * @param context The current thread context + * @param klass The receiver of the method call ({@link RubyClass} State) * @param opts The object to use as a base for the new State - * @param block The block passed to the method * @return A GeneratorState as determined above */ @JRubyMethod(meta=true) - public static IRubyObject from_state(ThreadContext context, - IRubyObject klass, IRubyObject opts) { + public static IRubyObject from_state(ThreadContext context, IRubyObject klass, IRubyObject opts) { return fromState(context, opts); } @@ -144,7 +138,7 @@ public static IRubyObject generate(ThreadContext context, IRubyObject klass, IRu } static GeneratorState fromState(ThreadContext context, IRubyObject opts) { - return fromState(context, RuntimeInfo.forRuntime(context.getRuntime()), opts); + return fromState(context, RuntimeInfo.forRuntime(context.runtime), opts); } static GeneratorState fromState(ThreadContext context, RuntimeInfo info, @@ -155,7 +149,7 @@ static GeneratorState fromState(ThreadContext context, RuntimeInfo info, if (klass.isInstance(opts)) return (GeneratorState)opts; // if the given parameter is a Hash, pass it to the instantiator - if (context.getRuntime().getHash().isInstance(opts)) { + if (context.runtime.getHash().isInstance(opts)) { return (GeneratorState)klass.newInstance(context, opts, Block.NULL_BLOCK); } } @@ -166,9 +160,9 @@ static GeneratorState fromState(ThreadContext context, RuntimeInfo info, /** * State#initialize(opts = {}) - * + *

* Instantiates a new State object, configured by opts. - * + *

* opts can have the following keys: * *

@@ -207,7 +201,7 @@ public IRubyObject initialize(ThreadContext context, IRubyObject arg0) { @JRubyMethod public IRubyObject initialize_copy(ThreadContext context, IRubyObject vOrig) { - Ruby runtime = context.getRuntime(); + Ruby runtime = context.runtime; if (!(vOrig instanceof GeneratorState)) { throw runtime.newTypeError(vOrig, getType()); } @@ -236,7 +230,7 @@ public IRubyObject initialize_copy(ThreadContext context, IRubyObject vOrig) { @JRubyMethod(visibility = Visibility.PRIVATE) public IRubyObject _generate(ThreadContext context, IRubyObject obj, IRubyObject io) { IRubyObject result = Generator.generateJson(context, obj, this, io); - RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime()); + RuntimeInfo info = RuntimeInfo.forRuntime(context.runtime); if (!(result instanceof RubyString)) { return result; } @@ -244,7 +238,7 @@ public IRubyObject _generate(ThreadContext context, IRubyObject obj, IRubyObject RubyString resultString = result.convertToString(); if (resultString.getEncoding() != UTF8Encoding.INSTANCE) { if (resultString.isFrozen()) { - resultString = resultString.strDup(context.getRuntime()); + resultString = resultString.strDup(context.runtime); } resultString.force_encoding(context, info.utf8.get()); } @@ -252,17 +246,7 @@ public IRubyObject _generate(ThreadContext context, IRubyObject obj, IRubyObject return resultString; } - private static boolean matchClosingBrace(ByteList bl, int pos, int len, - int brace) { - for (int endPos = len - 1; endPos > pos; endPos--) { - int b = bl.get(endPos); - if (Character.isWhitespace(b)) continue; - return b == brace; - } - return false; - } - - @JRubyMethod(name="[]", required=1) + @JRubyMethod(name="[]") public IRubyObject op_aref(ThreadContext context, IRubyObject vName) { String name = vName.asJavaString(); if (getMetaClass().isMethodBound(name, true)) { @@ -273,16 +257,16 @@ public IRubyObject op_aref(ThreadContext context, IRubyObject vName) { } } - @JRubyMethod(name="[]=", required=2) + @JRubyMethod(name="[]=") public IRubyObject op_aset(ThreadContext context, IRubyObject vName, IRubyObject value) { String name = vName.asJavaString(); String nameWriter = name + "="; if (getMetaClass().isMethodBound(nameWriter, true)) { - return send(context, context.getRuntime().newString(nameWriter), value, Block.NULL_BLOCK); + return send(context, context.runtime.newString(nameWriter), value, Block.NULL_BLOCK); } else { getInstanceVariables().setInstanceVariable("@" + name, value); } - return context.getRuntime().getNil(); + return context.nil; } public ByteList getIndent() { @@ -291,7 +275,7 @@ public ByteList getIndent() { @JRubyMethod(name="indent") public RubyString indent_get(ThreadContext context) { - return context.getRuntime().newString(indent); + return context.runtime.newString(indent); } @JRubyMethod(name="indent=") @@ -306,7 +290,7 @@ public ByteList getSpace() { @JRubyMethod(name="space") public RubyString space_get(ThreadContext context) { - return context.getRuntime().newString(space); + return context.runtime.newString(space); } @JRubyMethod(name="space=") @@ -321,7 +305,7 @@ public ByteList getSpaceBefore() { @JRubyMethod(name="space_before") public RubyString space_before_get(ThreadContext context) { - return context.getRuntime().newString(spaceBefore); + return context.runtime.newString(spaceBefore); } @JRubyMethod(name="space_before=") @@ -337,7 +321,7 @@ public ByteList getObjectNl() { @JRubyMethod(name="object_nl") public RubyString object_nl_get(ThreadContext context) { - return context.getRuntime().newString(objectNl); + return context.runtime.newString(objectNl); } @JRubyMethod(name="object_nl=") @@ -353,7 +337,7 @@ public ByteList getArrayNl() { @JRubyMethod(name="array_nl") public RubyString array_nl_get(ThreadContext context) { - return context.getRuntime().newString(arrayNl); + return context.runtime.newString(arrayNl); } @JRubyMethod(name="array_nl=") @@ -365,19 +349,12 @@ public IRubyObject array_nl_set(ThreadContext context, @JRubyMethod(name="check_circular?") public RubyBoolean check_circular_p(ThreadContext context) { - return context.getRuntime().newBoolean(maxNesting != 0); - } - - /** - * Returns the maximum level of nesting configured for this state. - */ - public int getMaxNesting() { - return maxNesting; + return RubyBoolean.newBoolean(context, maxNesting != 0); } @JRubyMethod(name="max_nesting") public RubyInteger max_nesting_get(ThreadContext context) { - return context.getRuntime().newFixnum(maxNesting); + return context.runtime.newFixnum(maxNesting); } @JRubyMethod(name="max_nesting=") @@ -395,7 +372,7 @@ public boolean scriptSafe() { @JRubyMethod(name="script_safe", alias="escape_slash") public RubyBoolean script_safe_get(ThreadContext context) { - return context.getRuntime().newBoolean(scriptSafe); + return RubyBoolean.newBoolean(context, scriptSafe); } @JRubyMethod(name="script_safe=", alias="escape_slash=") @@ -406,7 +383,7 @@ public IRubyObject script_safe_set(IRubyObject script_safe) { @JRubyMethod(name="script_safe?", alias="escape_slash?") public RubyBoolean script_safe_p(ThreadContext context) { - return context.getRuntime().newBoolean(scriptSafe); + return RubyBoolean.newBoolean(context, scriptSafe); } /** @@ -418,7 +395,7 @@ public boolean strict() { @JRubyMethod(name={"strict","strict?"}) public RubyBoolean strict_get(ThreadContext context) { - return context.getRuntime().newBoolean(strict); + return RubyBoolean.newBoolean(context, strict); } @JRubyMethod(name="strict=") @@ -433,7 +410,7 @@ public boolean allowNaN() { @JRubyMethod(name="allow_nan?") public RubyBoolean allow_nan_p(ThreadContext context) { - return context.getRuntime().newBoolean(allowNaN); + return RubyBoolean.newBoolean(context, allowNaN); } public boolean asciiOnly() { @@ -442,12 +419,12 @@ public boolean asciiOnly() { @JRubyMethod(name="ascii_only?") public RubyBoolean ascii_only_p(ThreadContext context) { - return context.getRuntime().newBoolean(asciiOnly); + return RubyBoolean.newBoolean(context, asciiOnly); } @JRubyMethod(name="buffer_initial_length") public RubyInteger buffer_initial_length_get(ThreadContext context) { - return context.getRuntime().newFixnum(bufferInitialLength); + return context.runtime.newFixnum(bufferInitialLength); } @JRubyMethod(name="buffer_initial_length=") @@ -463,7 +440,7 @@ public int getDepth() { @JRubyMethod(name="depth") public RubyInteger depth_get(ThreadContext context) { - return context.getRuntime().newFixnum(depth); + return context.runtime.newFixnum(depth); } @JRubyMethod(name="depth=") @@ -474,7 +451,7 @@ public IRubyObject depth_set(IRubyObject vDepth) { private ByteList prepareByteList(ThreadContext context, IRubyObject value) { RubyString str = value.convertToString(); - RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime()); + RuntimeInfo info = RuntimeInfo.forRuntime(context.runtime); if (str.encoding(context) != info.utf8.get()) { str = (RubyString)str.encode(context, info.utf8.get()); } @@ -532,7 +509,7 @@ public IRubyObject _configure(ThreadContext context, IRubyObject vOpts) { */ @JRubyMethod(alias = "to_hash") public RubyHash to_h(ThreadContext context) { - Ruby runtime = context.getRuntime(); + Ruby runtime = context.runtime; RubyHash result = RubyHash.newHash(runtime); result.op_aset(context, runtime.newSymbol("indent"), indent_get(context)); @@ -553,26 +530,24 @@ public RubyHash to_h(ThreadContext context) { return result; } - public int increaseDepth() { + public int increaseDepth(ThreadContext context) { depth++; - checkMaxNesting(); + checkMaxNesting(context); return depth; } - public int decreaseDepth() { - return --depth; + public void decreaseDepth() { + --depth; } /** * Checks if the current depth is allowed as per this state's options. - * @param context - * @param depth The current depth + * @param context The current context */ - private void checkMaxNesting() { + private void checkMaxNesting(ThreadContext context) { if (maxNesting != 0 && depth > maxNesting) { depth--; - throw Utils.newException(getRuntime().getCurrentContext(), - Utils.M_NESTING_ERROR, "nesting of " + depth + " is too deep"); + throw Utils.newException(context, Utils.M_NESTING_ERROR, "nesting of " + depth + " is too deep"); } } } diff --git a/java/src/json/ext/OptionsReader.java b/java/src/json/ext/OptionsReader.java index 70426d42..be19e609 100644 --- a/java/src/json/ext/OptionsReader.java +++ b/java/src/json/ext/OptionsReader.java @@ -22,7 +22,7 @@ final class OptionsReader { OptionsReader(ThreadContext context, IRubyObject vOpts) { this.context = context; - this.runtime = context.getRuntime(); + this.runtime = context.runtime; if (vOpts == null || vOpts.isNil()) { opts = null; } else if (vOpts.respondsTo("to_hash")) { @@ -41,7 +41,7 @@ private RuntimeInfo getRuntimeInfo() { } /** - * Efficiently looks up items with a {@link RubySymbol Symbol} key + * Efficiently looks up items with a {@link org.jruby.RubySymbol Symbol} key * @param key The Symbol name to look up for * @return The item in the {@link RubyHash Hash}, or null * if not found @@ -69,7 +69,7 @@ int getInt(String key, int defaultValue) { * @param key The Symbol name to look up for * @return null if the key is not in the Hash or if * its value evaluates to false - * @throws RaiseException TypeError if the value does not + * @throws org.jruby.exceptions.RaiseException TypeError if the value does not * evaluate to false and can't be * converted to string */ diff --git a/java/src/json/ext/Parser.java b/java/src/json/ext/Parser.java index f21897d4..4988db0c 100644 --- a/java/src/json/ext/Parser.java +++ b/java/src/json/ext/Parser.java @@ -71,11 +71,7 @@ public class Parser extends RubyObject { private static final String CONST_INFINITY = "Infinity"; private static final String CONST_MINUS_INFINITY = "MinusInfinity"; - static final ObjectAllocator ALLOCATOR = new ObjectAllocator() { - public IRubyObject allocate(Ruby runtime, RubyClass klazz) { - return new Parser(runtime, klazz); - } - }; + static final ObjectAllocator ALLOCATOR = Parser::new; /** * Multiple-value return for internal parser methods. @@ -119,7 +115,7 @@ public Parser(Ruby runtime, RubyClass metaClass) { *
The maximum depth of nesting allowed in the parsed data * structures. Disable depth checking with :max_nesting => false|nil|0, * it defaults to 100. - * + *

*

:allow_nan *
If set to true, allow NaN, * Infinity and -Infinity in defiance of RFC 4627 @@ -252,34 +248,6 @@ private RubyString convertEncoding(ThreadContext context, RubyString source) { return source; } - /** - * Checks the first four bytes of the given ByteList to infer its encoding, - * using the principle demonstrated on section 3 of RFC 4627 (JSON). - */ - private static String sniffByteList(ByteList bl) { - if (bl.length() < 4) return null; - if (bl.get(0) == 0 && bl.get(2) == 0) { - return bl.get(1) == 0 ? "utf-32be" : "utf-16be"; - } - if (bl.get(1) == 0 && bl.get(3) == 0) { - return bl.get(2) == 0 ? "utf-32le" : "utf-16le"; - } - return null; - } - - /** - * Assumes the given (binary) RubyString to be in the given encoding, then - * converts it to UTF-8. - */ - private RubyString reinterpretEncoding(ThreadContext context, - RubyString str, String sniffedEncoding) { - RubyEncoding actualEncoding = info.getEncoding(context, sniffedEncoding); - RubyEncoding targetEncoding = info.utf8.get(); - RubyString dup = (RubyString)str.dup(); - dup.force_encoding(context, actualEncoding); - return (RubyString)dup.encode_bang(context, targetEncoding); - } - /** * Parser#parse() * @@ -351,11 +319,6 @@ private static class ParserSession { private final byte[] data; private final StringDecoder decoder; private int currentNesting = 0; - private final DoubleConverter dc; - - // initialization value for all state variables. - // no idea about the origins of this value, ask Flori ;) - private static final int EVIL = 0x666; private ParserSession(Parser parser, ThreadContext context, RuntimeInfo info) { this.parser = parser; @@ -364,7 +327,6 @@ private ParserSession(Parser parser, ThreadContext context, RuntimeInfo info) { this.data = byteList.unsafeBytes(); this.view = new ByteList(data, false); this.decoder = new StringDecoder(); - this.dc = new DoubleConverter(); } private RaiseException unexpectedToken(ThreadContext context, int absStart, int absEnd) { @@ -497,7 +459,7 @@ private static byte[] init__JSON_value_from_state_actions_0() void parseValue(ThreadContext context, ParserResult res, int p, int pe) { - int cs = EVIL; + int cs; IRubyObject result = null; @@ -848,18 +810,17 @@ private static byte[] init__JSON_integer_trans_actions_0() void parseInteger(ThreadContext context, ParserResult res, int p, int pe) { - int new_p = parseIntegerInternal(context, p, pe); + int new_p = parseIntegerInternal(p, pe); if (new_p == -1) { res.update(null, p); return; } RubyInteger number = createInteger(context, p, new_p); res.update(number, new_p + 1); - return; } - int parseIntegerInternal(ThreadContext context, int p, int pe) { - int cs = EVIL; + int parseIntegerInternal(int p, int pe) { + int cs; // line 866 "Parser.java" @@ -1103,7 +1064,7 @@ private static byte[] init__JSON_float_trans_actions_0() void parseFloat(ThreadContext context, ParserResult res, int p, int pe) { - int new_p = parseFloatInternal(context, p, pe); + int new_p = parseFloatInternal(p, pe); if (new_p == -1) { res.update(null, p); return; @@ -1114,8 +1075,8 @@ void parseFloat(ThreadContext context, ParserResult res, int p, int pe) { res.update(number, new_p + 1); } - int parseFloatInternal(ThreadContext context, int p, int pe) { - int cs = EVIL; + int parseFloatInternal(int p, int pe) { + int cs; // line 1122 "Parser.java" @@ -1349,7 +1310,7 @@ private static byte[] init__JSON_string_trans_actions_0() void parseString(ThreadContext context, ParserResult res, int p, int pe) { - int cs = EVIL; + int cs; IRubyObject result = null; @@ -1694,7 +1655,7 @@ private static byte[] init__JSON_array_trans_actions_0() void parseArray(ThreadContext context, ParserResult res, int p, int pe) { - int cs = EVIL; + int cs; if (parser.maxNesting > 0 && currentNesting > parser.maxNesting) { throw newException(context, Utils.M_NESTING_ERROR, @@ -2064,7 +2025,7 @@ private static byte[] init__JSON_object_trans_actions_0() void parseObject(ThreadContext context, ParserResult res, int p, int pe) { - int cs = EVIL; + int cs; IRubyObject lastName = null; boolean objectDefault = true; @@ -2409,7 +2370,7 @@ private static byte[] init__JSON_trans_actions_0() public IRubyObject parseImplementation(ThreadContext context) { - int cs = EVIL; + int cs; int p, pe; IRubyObject result = null; ParserResult res = new ParserResult(); @@ -2577,10 +2538,6 @@ private RaiseException newException(ThreadContext context, String className, Rub return Utils.newException(context, className, message); } - private RaiseException newException(ThreadContext context, String className, String messageBegin, ByteList messageEnd) { - return newException(context, className, context.runtime.newString(messageBegin).cat(messageEnd)); - } - RubyHash.VisitorWithState MATCH_VISITOR = new RubyHash.VisitorWithState() { @Override public void visit(ThreadContext context, RubyHash self, IRubyObject pattern, IRubyObject klass, int index, IRubyObject[] state) { diff --git a/java/src/json/ext/Parser.rl b/java/src/json/ext/Parser.rl index 14451fab..f40b94e2 100644 --- a/java/src/json/ext/Parser.rl +++ b/java/src/json/ext/Parser.rl @@ -69,11 +69,7 @@ public class Parser extends RubyObject { private static final String CONST_INFINITY = "Infinity"; private static final String CONST_MINUS_INFINITY = "MinusInfinity"; - static final ObjectAllocator ALLOCATOR = new ObjectAllocator() { - public IRubyObject allocate(Ruby runtime, RubyClass klazz) { - return new Parser(runtime, klazz); - } - }; + static final ObjectAllocator ALLOCATOR = Parser::new; /** * Multiple-value return for internal parser methods. @@ -111,42 +107,42 @@ public class Parser extends RubyObject { * source. * It will be configured by the opts Hash. * opts can have the following keys: - * + *

*

*
:max_nesting *
The maximum depth of nesting allowed in the parsed data * structures. Disable depth checking with :max_nesting => false|nil|0, * it defaults to 100. - * + *

*

:allow_nan *
If set to true, allow NaN, * Infinity and -Infinity in defiance of RFC 4627 * to be parsed by the Parser. This option defaults to false. - * + *

*

:allow_trailing_comma *
If set to true, allow arrays and objects with a trailing * comma in defiance of RFC 4627 to be parsed by the Parser. * This option defaults to false. - * + *

*

:symbolize_names *
If set to true, returns symbols for the names (keys) in * a JSON object. Otherwise strings are returned, which is also the default. - * + *

*

:create_additions *
If set to false, the Parser doesn't create additions * even if a matching class and create_id was found. This option * defaults to true. - * + *

*

:object_class *
Defaults to Hash. If another type is provided, it will be used * instead of Hash to represent JSON objects. The type must respond to * new without arguments, and return an object that respond to []=. - * + *

*

:array_class *
Defaults to Array. If another type is provided, it will be used * instead of Hash to represent JSON arrays. The type must respond to * new without arguments, and return an object that respond to <<. - * + *

*

:decimal_class *
Specifies which class to use instead of the default (Float) when * parsing decimal numbers. This class must accept a single string argument @@ -250,34 +246,6 @@ public class Parser extends RubyObject { return source; } - /** - * Checks the first four bytes of the given ByteList to infer its encoding, - * using the principle demonstrated on section 3 of RFC 4627 (JSON). - */ - private static String sniffByteList(ByteList bl) { - if (bl.length() < 4) return null; - if (bl.get(0) == 0 && bl.get(2) == 0) { - return bl.get(1) == 0 ? "utf-32be" : "utf-16be"; - } - if (bl.get(1) == 0 && bl.get(3) == 0) { - return bl.get(2) == 0 ? "utf-32le" : "utf-16le"; - } - return null; - } - - /** - * Assumes the given (binary) RubyString to be in the given encoding, then - * converts it to UTF-8. - */ - private RubyString reinterpretEncoding(ThreadContext context, - RubyString str, String sniffedEncoding) { - RubyEncoding actualEncoding = info.getEncoding(context, sniffedEncoding); - RubyEncoding targetEncoding = info.utf8.get(); - RubyString dup = (RubyString)str.dup(); - dup.force_encoding(context, actualEncoding); - return (RubyString)dup.encode_bang(context, targetEncoding); - } - /** * Parser#parse() * @@ -349,11 +317,6 @@ public class Parser extends RubyObject { private final byte[] data; private final StringDecoder decoder; private int currentNesting = 0; - private final DoubleConverter dc; - - // initialization value for all state variables. - // no idea about the origins of this value, ask Flori ;) - private static final int EVIL = 0x666; private ParserSession(Parser parser, ThreadContext context, RuntimeInfo info) { this.parser = parser; @@ -362,7 +325,6 @@ public class Parser extends RubyObject { this.data = byteList.unsafeBytes(); this.view = new ByteList(data, false); this.decoder = new StringDecoder(); - this.dc = new DoubleConverter(); } private RaiseException unexpectedToken(ThreadContext context, int absStart, int absEnd) { @@ -507,7 +469,7 @@ public class Parser extends RubyObject { }%% void parseValue(ThreadContext context, ParserResult res, int p, int pe) { - int cs = EVIL; + int cs; IRubyObject result = null; %% write init; @@ -537,18 +499,17 @@ public class Parser extends RubyObject { }%% void parseInteger(ThreadContext context, ParserResult res, int p, int pe) { - int new_p = parseIntegerInternal(context, p, pe); + int new_p = parseIntegerInternal(p, pe); if (new_p == -1) { res.update(null, p); return; } RubyInteger number = createInteger(context, p, new_p); res.update(number, new_p + 1); - return; } - int parseIntegerInternal(ThreadContext context, int p, int pe) { - int cs = EVIL; + int parseIntegerInternal(int p, int pe) { + int cs; %% write init; int memo = p; @@ -589,7 +550,7 @@ public class Parser extends RubyObject { }%% void parseFloat(ThreadContext context, ParserResult res, int p, int pe) { - int new_p = parseFloatInternal(context, p, pe); + int new_p = parseFloatInternal(p, pe); if (new_p == -1) { res.update(null, p); return; @@ -600,8 +561,8 @@ public class Parser extends RubyObject { res.update(number, new_p + 1); } - int parseFloatInternal(ThreadContext context, int p, int pe) { - int cs = EVIL; + int parseFloatInternal(int p, int pe) { + int cs; %% write init; int memo = p; @@ -648,7 +609,7 @@ public class Parser extends RubyObject { }%% void parseString(ThreadContext context, ParserResult res, int p, int pe) { - int cs = EVIL; + int cs; IRubyObject result = null; %% write init; @@ -734,7 +695,7 @@ public class Parser extends RubyObject { }%% void parseArray(ThreadContext context, ParserResult res, int p, int pe) { - int cs = EVIL; + int cs; if (parser.maxNesting > 0 && currentNesting > parser.maxNesting) { throw newException(context, Utils.M_NESTING_ERROR, @@ -815,7 +776,7 @@ public class Parser extends RubyObject { }%% void parseObject(ThreadContext context, ParserResult res, int p, int pe) { - int cs = EVIL; + int cs; IRubyObject lastName = null; boolean objectDefault = true; @@ -894,7 +855,7 @@ public class Parser extends RubyObject { }%% public IRubyObject parseImplementation(ThreadContext context) { - int cs = EVIL; + int cs; int p, pe; IRubyObject result = null; ParserResult res = new ParserResult(); @@ -942,10 +903,6 @@ public class Parser extends RubyObject { return Utils.newException(context, className, message); } - private RaiseException newException(ThreadContext context, String className, String messageBegin, ByteList messageEnd) { - return newException(context, className, context.runtime.newString(messageBegin).cat(messageEnd)); - } - RubyHash.VisitorWithState MATCH_VISITOR = new RubyHash.VisitorWithState() { @Override public void visit(ThreadContext context, RubyHash self, IRubyObject pattern, IRubyObject klass, int index, IRubyObject[] state) { diff --git a/java/src/json/ext/RuntimeInfo.java b/java/src/json/ext/RuntimeInfo.java index 2323bd94..fcfaee3e 100644 --- a/java/src/json/ext/RuntimeInfo.java +++ b/java/src/json/ext/RuntimeInfo.java @@ -6,7 +6,6 @@ package json.ext; import java.lang.ref.WeakReference; -import java.util.HashMap; import java.util.Map; import java.util.WeakHashMap; import org.jruby.Ruby; @@ -20,7 +19,7 @@ final class RuntimeInfo { // since the vast majority of cases runs just one runtime, // we optimize for that - private static WeakReference runtime1 = new WeakReference(null); + private static WeakReference runtime1 = new WeakReference<>(null); private static RuntimeInfo info1; // store remaining runtimes here (does not include runtime1) private static Map runtimes; @@ -39,22 +38,18 @@ final class RuntimeInfo { final WeakReference utf8; final WeakReference ascii8bit; - // other encodings - private final Map> encodings; private RuntimeInfo(Ruby runtime) { RubyClass encodingClass = runtime.getEncoding(); if (encodingClass == null) { // 1.8 mode utf8 = ascii8bit = null; - encodings = null; } else { ThreadContext context = runtime.getCurrentContext(); - utf8 = new WeakReference((RubyEncoding)RubyEncoding.find(context, + utf8 = new WeakReference<>((RubyEncoding) RubyEncoding.find(context, encodingClass, runtime.newString("utf-8"))); - ascii8bit = new WeakReference((RubyEncoding)RubyEncoding.find(context, + ascii8bit = new WeakReference<>((RubyEncoding) RubyEncoding.find(context, encodingClass, runtime.newString("ascii-8bit"))); - encodings = new HashMap>(); } } @@ -63,12 +58,12 @@ static RuntimeInfo initRuntime(Ruby runtime) { if (runtime1.get() == runtime) { return info1; } else if (runtime1.get() == null) { - runtime1 = new WeakReference(runtime); + runtime1 = new WeakReference<>(runtime); info1 = new RuntimeInfo(runtime); return info1; } else { if (runtimes == null) { - runtimes = new WeakHashMap(1); + runtimes = new WeakHashMap<>(1); } RuntimeInfo cache = runtimes.get(runtime); if (cache == null) { @@ -90,26 +85,13 @@ public static RuntimeInfo forRuntime(Ruby runtime) { } } - public RubyEncoding getEncoding(ThreadContext context, String name) { - synchronized (encodings) { - WeakReference encoding = encodings.get(name); - if (encoding == null) { - Ruby runtime = context.getRuntime(); - encoding = new WeakReference((RubyEncoding)RubyEncoding.find(context, - runtime.getEncoding(), runtime.newString(name))); - encodings.put(name, encoding); - } - return encoding.get(); - } - } - public GeneratorState getSafeStatePrototype(ThreadContext context) { if (safeStatePrototype == null) { IRubyObject value = jsonModule.get().getConstant("SAFE_STATE_PROTOTYPE"); if (!(value instanceof GeneratorState)) { - throw context.getRuntime().newTypeError(value, generatorStateClass.get()); + throw context.runtime.newTypeError(value, generatorStateClass.get()); } - safeStatePrototype = new WeakReference((GeneratorState)value); + safeStatePrototype = new WeakReference<>((GeneratorState) value); } return safeStatePrototype.get(); } diff --git a/java/src/json/ext/StringDecoder.java b/java/src/json/ext/StringDecoder.java index e2b49efb..ff984935 100644 --- a/java/src/json/ext/StringDecoder.java +++ b/java/src/json/ext/StringDecoder.java @@ -23,7 +23,7 @@ final class StringDecoder extends ByteListTranscoder { */ private int surrogatePairStart = -1; - // Array used for writing multi-byte characters into the buffer at once + // Array used for writing multibyte characters into the buffer at once private final byte[] aux = new byte[4]; ByteList decode(ThreadContext context, ByteList src, int start, int end) { @@ -162,6 +162,6 @@ protected RaiseException invalidUtf8(ThreadContext context) { int start = surrogatePairStart != -1 ? surrogatePairStart : charStart; message.append(src, start, srcEnd - start); return Utils.newException(context, Utils.M_PARSER_ERROR, - context.getRuntime().newString(message)); + context.runtime.newString(message)); } } diff --git a/java/src/json/ext/StringEncoder.java b/java/src/json/ext/StringEncoder.java index b211c4ec..8d23dfb9 100644 --- a/java/src/json/ext/StringEncoder.java +++ b/java/src/json/ext/StringEncoder.java @@ -23,7 +23,7 @@ final class StringEncoder extends ByteListTranscoder { // Escaped characters will reuse this array, to avoid new allocations // or appending them byte-by-byte private final byte[] aux = - new byte[] {/* First unicode character */ + new byte[] {/* First Unicode character */ '\\', 'u', 0, 0, 0, 0, /* Second unicode character (for surrogate pairs) */ '\\', 'u', 0, 0, 0, 0, diff --git a/java/src/json/ext/Utils.java b/java/src/json/ext/Utils.java index f8c70608..a33652d7 100644 --- a/java/src/json/ext/Utils.java +++ b/java/src/json/ext/Utils.java @@ -9,7 +9,6 @@ import org.jruby.RubyArray; import org.jruby.RubyClass; import org.jruby.RubyException; -import org.jruby.RubyHash; import org.jruby.RubyString; import org.jruby.exceptions.RaiseException; import org.jruby.runtime.Block; @@ -44,12 +43,6 @@ static RubyArray ensureArray(IRubyObject object) throws RaiseException { throw runtime.newTypeError(object, runtime.getArray()); } - static RubyHash ensureHash(IRubyObject object) throws RaiseException { - if (object instanceof RubyHash) return (RubyHash)object; - Ruby runtime = object.getRuntime(); - throw runtime.newTypeError(object, runtime.getHash()); - } - static RubyString ensureString(IRubyObject object) throws RaiseException { if (object instanceof RubyString) return (RubyString)object; Ruby runtime = object.getRuntime(); @@ -59,15 +52,15 @@ static RubyString ensureString(IRubyObject object) throws RaiseException { static RaiseException newException(ThreadContext context, String className, String message) { return newException(context, className, - context.getRuntime().newString(message)); + context.runtime.newString(message)); } static RaiseException newException(ThreadContext context, String className, RubyString message) { - RuntimeInfo info = RuntimeInfo.forRuntime(context.getRuntime()); + RuntimeInfo info = RuntimeInfo.forRuntime(context.runtime); RubyClass klazz = info.jsonModule.get().getClass(className); RubyException excptn = (RubyException)klazz.newInstance(context, message, Block.NULL_BLOCK); - return new RaiseException(excptn); + return excptn.toThrowable(); } static byte[] repeat(ByteList a, int n) {