diff --git a/core/src/main/java/org/jruby/Ruby.java b/core/src/main/java/org/jruby/Ruby.java index 324859cfa1f..0be4388a63b 100644 --- a/core/src/main/java/org/jruby/Ruby.java +++ b/core/src/main/java/org/jruby/Ruby.java @@ -5602,7 +5602,7 @@ public RubyClass getData() { private final WarnCallback regexpWarnings = new WarnCallback() { @Override public void warn(String message) { - getWarnings().warning(message); + getWarnings().warn(message); } }; diff --git a/core/src/main/java/org/jruby/RubyArray.java b/core/src/main/java/org/jruby/RubyArray.java index 106d60db6cc..10831978892 100644 --- a/core/src/main/java/org/jruby/RubyArray.java +++ b/core/src/main/java/org/jruby/RubyArray.java @@ -645,7 +645,7 @@ public IRubyObject initialize(ThreadContext context, Block block) { unpack(); realLength = 0; if (block.isGiven() && context.runtime.isVerbose()) { - context.runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + context.runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); } return this; } @@ -2210,7 +2210,7 @@ private IRubyObject getDefaultSeparator(Ruby runtime) { IRubyObject sep; sep = runtime.getGlobalVariables().get("$,"); if (!sep.isNil()) { - runtime.getWarnings().warn("$, is set to non-nil value"); + runtime.getWarnings().warnDeprecated("$, is set to non-nil value"); } return sep; } @@ -2549,7 +2549,7 @@ public IRubyObject index(ThreadContext context, IRubyObject obj) { @JRubyMethod(name = {"index", "find_index"}) public IRubyObject index(ThreadContext context, IRubyObject obj, Block unused) { - if (unused.isGiven()) context.runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + if (unused.isGiven()) context.runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); return index(context, obj); } @@ -2656,7 +2656,7 @@ public IRubyObject rindex(ThreadContext context, IRubyObject obj) { @JRubyMethod public IRubyObject rindex(ThreadContext context, IRubyObject obj, Block unused) { - if (unused.isGiven()) context.runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + if (unused.isGiven()) context.runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); return rindex(context, obj); } @@ -3521,7 +3521,7 @@ public IRubyObject count(ThreadContext context, Block block) { @JRubyMethod(name = "count") public IRubyObject count(ThreadContext context, IRubyObject obj, Block block) { - if (block.isGiven()) context.runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + if (block.isGiven()) context.runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); int n = 0; for (int i = 0; i < realLength; i++) { @@ -4929,7 +4929,7 @@ public IRubyObject all_pCommon(ThreadContext context, IRubyObject arg, Block blo boolean patternGiven = arg != null; if (block.isGiven() && patternGiven) { - context.runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + context.runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); } if (!block.isGiven() || patternGiven) return all_pBlockless(context, arg); @@ -4972,7 +4972,7 @@ public IRubyObject any_pCommon(ThreadContext context, IRubyObject arg, Block blo boolean patternGiven = arg != null; if (block.isGiven() && patternGiven) { - context.runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + context.runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); } if (!block.isGiven() || patternGiven) return any_pBlockless(context, arg); @@ -5014,7 +5014,7 @@ public IRubyObject none_pCommon(ThreadContext context, IRubyObject arg, Block bl boolean patternGiven = arg != null; if (block.isGiven() && patternGiven) { - context.runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + context.runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); } if (!block.isGiven() || patternGiven) return none_pBlockless(context, arg); @@ -5056,7 +5056,7 @@ public IRubyObject one_pCommon(ThreadContext context, IRubyObject arg, Block blo boolean patternGiven = arg != null; if (block.isGiven() && patternGiven) { - context.runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + context.runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); } if (!block.isGiven() || patternGiven) return one_pBlockless(context, arg); diff --git a/core/src/main/java/org/jruby/RubyEnumerable.java b/core/src/main/java/org/jruby/RubyEnumerable.java index 36d1f05f8e2..d24b49e73e0 100644 --- a/core/src/main/java/org/jruby/RubyEnumerable.java +++ b/core/src/main/java/org/jruby/RubyEnumerable.java @@ -163,7 +163,7 @@ public static IRubyObject count(ThreadContext context, IRubyObject self, final I final Ruby runtime = context.runtime; final SingleInt result = new SingleInt(); - if (block.isGiven()) runtime.getWarnings().warning(ID.BLOCK_UNUSED , "given block not used"); + if (block.isGiven()) runtime.getWarnings().warn(ID.BLOCK_UNUSED , "given block not used"); each(context, eachSite(context), self, new JavaInternalBlockBody(runtime, context, "Enumerable#count", Signature.ONE_REQUIRED) { public IRubyObject yield(ThreadContext context1, IRubyObject[] args) { @@ -690,7 +690,7 @@ public static IRubyObject find_index(ThreadContext context, IRubyObject self, fi public static IRubyObject find_index(ThreadContext context, IRubyObject self, final IRubyObject cond, final Block block) { final Ruby runtime = context.runtime; - if (block.isGiven()) runtime.getWarnings().warning(ID.BLOCK_UNUSED , "given block not used"); + if (block.isGiven()) runtime.getWarnings().warn(ID.BLOCK_UNUSED , "given block not used"); if (self instanceof RubyArray) return ((RubyArray) self).find_index(context, cond); return find_indexCommon(context, eachSite(context), self, cond); @@ -1086,7 +1086,7 @@ public static IRubyObject inject(ThreadContext context, IRubyObject self, IRubyO public static IRubyObject inject(ThreadContext context, IRubyObject self, IRubyObject init, IRubyObject method, final Block block) { final Ruby runtime = context.runtime; - if (block.isGiven()) runtime.getWarnings().warning(ID.BLOCK_UNUSED , "given block not used"); + if (block.isGiven()) runtime.getWarnings().warn(ID.BLOCK_UNUSED , "given block not used"); final String methodId = method.asJavaString(); final SingleObject result = new SingleObject<>(init); @@ -1591,7 +1591,7 @@ public static IRubyObject none_pCommon(ThreadContext context, CallSite each, IRu final boolean patternGiven = pattern != null; if (block.isGiven() && patternGiven) { - context.runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + context.runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); } try { @@ -1646,7 +1646,7 @@ public static IRubyObject one_pCommon(ThreadContext context, CallSite each, IRub final boolean patternGiven = pattern != null; if (block.isGiven() && patternGiven) { - context.runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + context.runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); } try { @@ -1729,7 +1729,7 @@ public static IRubyObject all_pCommon(ThreadContext localContext, CallSite each, final boolean patternGiven = pattern != null; if (block.isGiven() && patternGiven) { - localContext.runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + localContext.runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); } try { @@ -1819,7 +1819,7 @@ public static IRubyObject any_pCommon(ThreadContext localContext, CallSite site, final boolean patternGiven = pattern != null; if (block.isGiven() && patternGiven) { - localContext.runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + localContext.runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); } try { diff --git a/core/src/main/java/org/jruby/RubyFileTest.java b/core/src/main/java/org/jruby/RubyFileTest.java index 381e542bf01..15b7ef799d2 100644 --- a/core/src/main/java/org/jruby/RubyFileTest.java +++ b/core/src/main/java/org/jruby/RubyFileTest.java @@ -119,7 +119,7 @@ public static IRubyObject exist_p(IRubyObject recv, IRubyObject filename) { return exist_p(recv.getRuntime().getCurrentContext(), recv, filename); } - @JRubyMethod(name = {"exist?", "exists?"}, module = true) + @JRubyMethod(name = "exist?", module = true) public static IRubyObject exist_p(ThreadContext context, IRubyObject recv, IRubyObject filename) { // We get_path here to prevent doing it both existsOnClasspath and fileResource (Only call to_path once). return RubyBoolean.newBoolean(context, exist(context, get_path(context, filename))); diff --git a/core/src/main/java/org/jruby/RubyGlobal.java b/core/src/main/java/org/jruby/RubyGlobal.java index c319f1caebc..bdfeebf5f56 100644 --- a/core/src/main/java/org/jruby/RubyGlobal.java +++ b/core/src/main/java/org/jruby/RubyGlobal.java @@ -829,13 +829,13 @@ public NonEffectiveGlobalVariable(Ruby runtime, String name, IRubyObject value) @Override public IRubyObject set(IRubyObject value) { - runtime.getWarnings().warn(ID.INEFFECTIVE_GLOBAL, "warning: variable " + name + " is no longer effective; ignored"); + runtime.getWarnings().warnDeprecated(ID.INEFFECTIVE_GLOBAL, "warning: variable " + name + " is no longer effective; ignored"); return value; } @Override public IRubyObject get() { - runtime.getWarnings().warn(ID.INEFFECTIVE_GLOBAL, "warning: variable " + name + " is no longer effective"); + runtime.getWarnings().warnDeprecated(ID.INEFFECTIVE_GLOBAL, "warning: variable " + name + " is no longer effective"); return value; } } diff --git a/core/src/main/java/org/jruby/RubyIO.java b/core/src/main/java/org/jruby/RubyIO.java index eedf0a93a48..ae7e2590dfb 100644 --- a/core/src/main/java/org/jruby/RubyIO.java +++ b/core/src/main/java/org/jruby/RubyIO.java @@ -1819,6 +1819,7 @@ public static IRubyObject print(ThreadContext context, IRubyObject out, IRubyObj int i; IRubyObject line; int argc = args.length; + IRubyObject outputFS = runtime.getGlobalVariables().get("$,"); /* if no argument given, print `$_' */ if (argc == 0) { @@ -1826,8 +1827,10 @@ public static IRubyObject print(ThreadContext context, IRubyObject out, IRubyObj line = context.getLastLine(); args = new IRubyObject[]{line}; } + if (argc > 1 && !outputFS.isNil()) { + runtime.getWarnings().warnDeprecated("$, is set to non-nil value"); + } for (i=0; i0) { write(context, out, outputFS); } @@ -2403,7 +2406,7 @@ public IRubyObject close_on_exec_set(ThreadContext context, IRubyObject arg) { if (fptr == null || (fd = fptr.fd().realFileno) == -1 || !posix.isNative() || Platform.IS_WINDOWS ) { - runtime.getWarnings().warning("close_on_exec is not implemented on this platform for this stream type: " + fptr.fd().ch.getClass().getSimpleName()); + runtime.getWarnings().warningDeprecated("close_on_exec is not implemented on this platform for this stream type: " + fptr.fd().ch.getClass().getSimpleName()); return context.nil; } @@ -2858,7 +2861,7 @@ private static void warnWrite(final Ruby runtime, IRubyObject maybeIO) { } else { sep = '#'; } - runtime.getWarnings().warning(klass.toString() + sep + "write is outdated interface which accepts just one argument"); + runtime.getWarnings().warningDeprecated(klass.toString() + sep + "write is outdated interface which accepts just one argument"); } @JRubyMethod @@ -4439,66 +4442,38 @@ public static IRubyObject popen(ThreadContext context, IRubyObject recv, IRubyOb } } - @Deprecated - public static IRubyObject pipe19(ThreadContext context, IRubyObject recv) { - return pipe19(context, recv, IRubyObject.NULL_ARRAY, Block.NULL_BLOCK); + public static IRubyObject pipe(ThreadContext context, IRubyObject recv) { + return pipe(context, recv, Block.NULL_BLOCK); } - @Deprecated - public static IRubyObject pipe19(ThreadContext context, IRubyObject recv, IRubyObject modes) { - return pipe19(context, recv, new IRubyObject[] {modes}, Block.NULL_BLOCK); + @JRubyMethod(name = "pipe", meta = true) + public static IRubyObject pipe(ThreadContext context, IRubyObject klass, Block block) { + return pipe(context, klass, context.nil, context.nil, context.nil, block); } - @Deprecated - public static IRubyObject pipe19(ThreadContext context, IRubyObject klass, IRubyObject[] argv, Block block) { - return pipe(context, klass, argv, block); + @JRubyMethod(name = "pipe", meta = true) + public static IRubyObject pipe(ThreadContext context, IRubyObject klass, IRubyObject arg0, Block block) { + IRubyObject opt = TypeConverter.checkHashType(context.runtime, arg0); + + return pipe(context, klass, opt.isNil() ? arg0 : context.nil, context.nil, opt, block); } + @JRubyMethod(name = "pipe", meta = true) + public static IRubyObject pipe(ThreadContext context, IRubyObject klass, IRubyObject arg0, IRubyObject arg1, Block block) { + IRubyObject opt = TypeConverter.checkHashType(context.runtime, arg1); - public static IRubyObject pipe(ThreadContext context, IRubyObject recv) { - return pipe(context, recv, IRubyObject.NULL_ARRAY, Block.NULL_BLOCK); + return pipe(context, klass, arg0, !opt.isNil() ? context.nil : arg1, opt, block); } - @JRubyMethod(name = "pipe", optional = 3, checkArity = false, meta = true) - public static IRubyObject pipe(ThreadContext context, IRubyObject klass, IRubyObject[] argv, Block block) { - int argc = Arity.checkArgumentCount(context, argv, 0, 3); - + @JRubyMethod(name = "pipe", meta = true) + public static IRubyObject pipe(ThreadContext context, IRubyObject klass, IRubyObject v1, IRubyObject v2, IRubyObject opt, Block block) { Ruby runtime = context.runtime; - int state; + RubyIO r, w; -// IRubyObject args[] = new IRubyObject[3] - IRubyObject v1, v2; - IRubyObject opt; - v1 = v2 = opt = context.nil; OpenFile fptr, fptr2; int[] fmode_p = {0}; IRubyObject ret; - switch (argc) { - case 3: - opt = argv[2].convertToHash(); - argc--; - v2 = argv[1]; - v1 = argv[0]; - break; - case 2: - opt = TypeConverter.checkHashType(runtime, argv[1]); - if (!opt.isNil()) { - argc--; - } else { - v2 = argv[1]; - } - v1 = argv[0]; - break; - case 1: - opt = TypeConverter.checkHashType(runtime, argv[0]); - if (!opt.isNil()) { - argc--; - } else { - v1 = argv[0]; - } - } - PosixShim posix = new PosixShim(runtime); Channel[] fds = posix.pipe(); if (fds == null) @@ -4513,7 +4488,7 @@ public static IRubyObject pipe(ThreadContext context, IRubyObject klass, IRubyOb // close(pipes[1]); // rb_jump_tag(state); // } - r = new RubyIO(runtime, (RubyClass)klass); + r = new RubyIO(runtime, (RubyClass) klass); r.initializeCommon(context, new ChannelFD(fds[0], runtime.getPosix(), runtime.getFilenoUtil()), runtime.newFixnum(OpenFlags.O_RDONLY), context.nil); fptr = r.getOpenFileChecked(); @@ -4527,7 +4502,7 @@ public static IRubyObject pipe(ThreadContext context, IRubyObject klass, IRubyOb // if (!NIL_P(r)) rb_io_close(r); // rb_jump_tag(state); // } - w = new RubyIO(runtime, (RubyClass)klass); + w = new RubyIO(runtime, (RubyClass) klass); w.initializeCommon(context, new ChannelFD(fds[1], runtime.getPosix(), runtime.getFilenoUtil()), runtime.newFixnum(OpenFlags.O_WRONLY), context.nil); fptr2 = w.getOpenFileChecked(); fptr2.setSync(true); @@ -5750,6 +5725,37 @@ public IRubyObject sysread(ThreadContext context, IRubyObject[] args) { return sysreadCommon(context, runtime, _length, _str); } + @Deprecated + public static IRubyObject pipe19(ThreadContext context, IRubyObject recv) { + return pipe19(context, recv, IRubyObject.NULL_ARRAY, Block.NULL_BLOCK); + } + + @Deprecated + public static IRubyObject pipe19(ThreadContext context, IRubyObject recv, IRubyObject modes) { + return pipe19(context, recv, new IRubyObject[] {modes}, Block.NULL_BLOCK); + } + + @Deprecated + public static IRubyObject pipe19(ThreadContext context, IRubyObject klass, IRubyObject[] argv, Block block) { + return pipe(context, klass, argv, block); + } + + @Deprecated + public static IRubyObject pipe(ThreadContext context, IRubyObject klass, IRubyObject[] argv, Block block) { + switch (argv.length) { + case 0: + return pipe(context, klass, block); + case 1: + return pipe(context, klass, argv[0], block); + case 2: + return pipe(context, klass, argv[0], argv[1], block); + case 3: + return pipe(context, klass, argv[0], argv[1], argv[2], block); + default: + throw context.runtime.newArgumentError(argv.length, 0, 3); + } + } + protected OpenFile openFile; /** diff --git a/core/src/main/java/org/jruby/RubyKernel.java b/core/src/main/java/org/jruby/RubyKernel.java index fb7eb52bd40..54c4482dba3 100644 --- a/core/src/main/java/org/jruby/RubyKernel.java +++ b/core/src/main/java/org/jruby/RubyKernel.java @@ -1933,7 +1933,7 @@ public static RubyFixnum spawn(ThreadContext context, IRubyObject recv, IRubyObj return RubyProcess.spawn(context, recv, args); } - @JRubyMethod(required = 1, optional = 9, checkArity = false, module = true, visibility = PRIVATE) + @JRubyMethod(required = 1, optional = 9, checkArity = false, module = true, notImplemented = true, visibility = PRIVATE) public static IRubyObject syscall(ThreadContext context, IRubyObject recv, IRubyObject[] args) { throw context.runtime.newNotImplementedError("Kernel#syscall is not implemented in JRuby"); } diff --git a/core/src/main/java/org/jruby/RubyModule.java b/core/src/main/java/org/jruby/RubyModule.java index 6a00093415a..f8620ca7fbf 100644 --- a/core/src/main/java/org/jruby/RubyModule.java +++ b/core/src/main/java/org/jruby/RubyModule.java @@ -118,6 +118,7 @@ import org.jruby.runtime.opto.Invalidator; import org.jruby.runtime.opto.OptoFactory; import org.jruby.runtime.profile.MethodEnhancer; +import org.jruby.util.RubyStringBuilder; import org.jruby.util.ByteList; import org.jruby.util.ClassProvider; import org.jruby.util.CommonByteLists; @@ -1472,11 +1473,9 @@ public void undef(ThreadContext context, String name) { } methodLocation.addMethod(name, UndefinedMethod.getInstance()); - if (isSingleton()) { - ((MetaClass) this).getAttached().callMethod(context, "singleton_method_undefined", runtime.newSymbol(name)); - } else { - callMethod(context, "method_undefined", runtime.newSymbol(name)); - } + RubySymbol nameSymbol = runtime.newSymbol(name); + + methodUndefined(context, nameSymbol); } @JRubyMethod(name = "include?") @@ -1595,11 +1594,7 @@ public void removeMethod(ThreadContext context, String id) { invalidateCacheDescendants(); } - if (isSingleton()) { - ((MetaClass) this).getAttached().callMethod(context, "singleton_method_removed", name); - } else { - callMethod(context, "method_removed", name); - } + methodRemoved(context, name); } private static void warnMethodRemoval(final ThreadContext context, final String id) { @@ -2317,15 +2312,39 @@ private void addAccessor(ThreadContext context, RubySymbol identifier, Visibilit final String variableName = identifier.asInstanceVariable().idString(); if (readable) { addMethod(internedIdentifier, new AttrReaderMethod(methodLocation, visibility, variableName)); - callMethod(context, "method_added", identifier); + methodAdded(context, identifier); } if (writeable) { identifier = identifier.asWriter(); addMethod(identifier.idString(), new AttrWriterMethod(methodLocation, visibility, variableName)); + methodAdded(context, identifier); + } + } + + protected void methodAdded(ThreadContext context, RubySymbol identifier) { + if (isSingleton()) { + ((MetaClass) this).getAttached().callMethod(context, "singleton_method_added", identifier); + } else { callMethod(context, "method_added", identifier); } } + private void methodUndefined(ThreadContext context, RubySymbol nameSymbol) { + if (isSingleton()) { + ((MetaClass) this).getAttached().callMethod(context, "singleton_method_undefined", nameSymbol); + } else { + callMethod(context, "method_undefined", nameSymbol); + } + } + + private void methodRemoved(ThreadContext context, RubySymbol name) { + if (isSingleton()) { + ((MetaClass) this).getAttached().callMethod(context, "singleton_method_removed", name); + } else { + callMethod(context, "method_removed", name); + } + } + /** set_method_visibility * */ @@ -3028,7 +3047,7 @@ public IRubyObject attr(ThreadContext context, IRubyObject[] args) { Ruby runtime = context.runtime; if (args.length == 2 && (args[1] == runtime.getTrue() || args[1] == runtime.getFalse())) { - runtime.getWarnings().warning(ID.OBSOLETE_ARGUMENT, "optional boolean argument is obsoleted"); + runtime.getWarnings().warnDeprecated(ID.OBSOLETE_ARGUMENT, "optional boolean argument is obsoleted"); boolean writeable = args[1].isTrue(); RubySymbol sym = TypeConverter.checkID(args[0]); addAccessor(context, sym, getCurrentVisibilityForDefineMethod(context), args[0].isTrue(), writeable); @@ -3531,7 +3550,7 @@ public IRubyObject _module_function(ThreadContext context, IRubyObject[] args) { newMethod.setImplementationClass(getSingletonClass()); newMethod.setVisibility(PUBLIC); getSingletonClass().addMethod(name.idString(), newMethod); - callMethod(context, "singleton_method_added", name); + getSingletonClass().methodAdded(context, name); } } @@ -3664,11 +3683,7 @@ public IRubyObject aliasMethod(ThreadContext context, IRubyObject newId, IRubyOb defineAlias(newSym.idString(), oldSym.idString()); - if (isSingleton()) { - ((MetaClass) this).getAttached().callMethod(context, "singleton_method_added", newSym); - } else { - callMethod(context, "method_added", newSym); - } + methodAdded(context, newSym); return newSym; } @@ -4583,6 +4598,36 @@ public final void setConstantVisibility(Ruby runtime, String name, boolean hidde storeConstant(name, entry.value, hidden, entry.getFile(), entry.getLine()); } + @JRubyMethod(name = "refinements") + public IRubyObject refinements(ThreadContext context) { + RubyArray refinementModules = context.runtime.newArray(); + + refinements.forEach((key, value) -> { + refinementModules.append(value); + }); + return refinementModules; + } + + @JRubyMethod(name = "target") + public IRubyObject target(ThreadContext context) { + return getRefinedClassOrThrow(context, true); + } + + @JRubyMethod(name = "refined_class") + public IRubyObject refined_class(ThreadContext context) { + return getRefinedClassOrThrow(context, false); + } + + private IRubyObject getRefinedClassOrThrow(ThreadContext context, boolean nameIsTarget) { + if (!isRefinement()) { + String methodName = nameIsTarget ? "target" : "refined_class"; + String errMsg = RubyStringBuilder.str(context.runtime, + "undefined method `"+ methodName +"' for ", rubyBaseName(), + ":", getMetaClass()); + throw context.runtime.newNoMethodError(errMsg, this, "target", context.runtime.newEmptyArray()); + } + return refinedClass; + } // ////////////////// CLASS VARIABLE API METHODS //////////////// // @@ -4999,9 +5044,9 @@ private IRubyObject setConstantCommon(String name, IRubyObject value, boolean hi if (notAutoload || !setAutoloadConstant(name, value, file, line)) { if (warn && notAutoload) { if (this.equals(getRuntime().getObject())) { - getRuntime().getWarnings().warning(ID.CONSTANT_ALREADY_INITIALIZED, "already initialized constant " + name); + getRuntime().getWarnings().warn(ID.CONSTANT_ALREADY_INITIALIZED, "already initialized constant " + name); } else { - getRuntime().getWarnings().warning(ID.CONSTANT_ALREADY_INITIALIZED, "already initialized constant " + this + "::" + name); + getRuntime().getWarnings().warn(ID.CONSTANT_ALREADY_INITIALIZED, "already initialized constant " + this + "::" + name); } } diff --git a/core/src/main/java/org/jruby/RubyRegexp.java b/core/src/main/java/org/jruby/RubyRegexp.java index b97a4731722..6f168c08131 100755 --- a/core/src/main/java/org/jruby/RubyRegexp.java +++ b/core/src/main/java/org/jruby/RubyRegexp.java @@ -944,7 +944,7 @@ public IRubyObject initialize_m(IRubyObject arg0, IRubyObject arg1, IRubyObject newOptions.setEncodingNone(true); return regexpInitialize(arg0.convertToString().getByteList(), ASCIIEncoding.INSTANCE, newOptions); } else { - metaClass.runtime.getWarnings().warn("encoding option is ignored - " + kcodeBytes); + metaClass.runtime.getWarnings().warnDeprecated("encoding option is ignored - " + kcodeBytes); } } return regexpInitializeString(arg0.convertToString(), newOptions); diff --git a/core/src/main/java/org/jruby/common/RubyWarnings.java b/core/src/main/java/org/jruby/common/RubyWarnings.java index b97de474261..1c5e372c033 100644 --- a/core/src/main/java/org/jruby/common/RubyWarnings.java +++ b/core/src/main/java/org/jruby/common/RubyWarnings.java @@ -191,6 +191,10 @@ public void warnDeprecated(ID id, String message) { if (runtime.getWarningCategories().contains(Category.DEPRECATED)) warn(id, message); } + public void warnDeprecated(String message) { + if (runtime.getWarningCategories().contains(Category.DEPRECATED)) warn(message); + } + public void warnDeprecatedAlternate(String name, String alternate) { if (runtime.getWarningCategories().contains(Category.DEPRECATED)) warn(ID.DEPRECATED_METHOD, name + " is deprecated; use " + alternate + " instead"); } @@ -208,26 +212,42 @@ public void warnOnce(ID id, String message) { } /** - * Verbose mode warning methods, their contract is that consumer must explicitly check for runtime.isVerbose() before calling them + * Verbose mode warning methods, only warn in verbose mode */ public void warning(String message) { warning(ID.MISCELLANEOUS, message); } + public void warningDeprecated(String message) { + warningDeprecated(ID.MISCELLANEOUS, message); + } + @Override public void warning(ID id, String message) { + if (!isVerbose()) return; + warn(id, message); } + public void warningDeprecated(ID id, String message) { + if (!isVerbose()) return; + + warnDeprecated(id, message); + } + /** * Prints a warning, only in verbose mode. */ @Override public void warning(ID id, String fileName, int lineNumber, String message) { + if (!isVerbose()) return; + warn(id, fileName, lineNumber, message); } public void warning(String fileName, int lineNumber, String message) { + if (!isVerbose()) return; + warn(fileName, lineNumber, message); } diff --git a/core/src/main/java/org/jruby/ir/IRBuilder.java b/core/src/main/java/org/jruby/ir/IRBuilder.java index 9af6b1bdbab..7a74b57e67f 100644 --- a/core/src/main/java/org/jruby/ir/IRBuilder.java +++ b/core/src/main/java/org/jruby/ir/IRBuilder.java @@ -3151,12 +3151,6 @@ protected void receiveBlockArg(final ArgsNode argsNode) { public void receiveArgs(final ArgsNode argsNode) { Signature signature = scope.getStaticScope().getSignature(); - if (signature.equals(Signature.NO_ARGUMENTS)) { - addInstr(new CheckArityInstr(0, 0, false, -1, UndefinedValue.UNDEFINED)); - receiveBlockArg(argsNode); - return; - } - Variable keywords = addResultInstr(new ReceiveKeywordsInstr(temp(), signature.hasRest(), argsNode.hasKwargs())); KeywordRestArgNode keyRest = argsNode.getKeyRest(); diff --git a/core/src/main/java/org/jruby/ir/persistence/IRReaderStream.java b/core/src/main/java/org/jruby/ir/persistence/IRReaderStream.java index a7c682c3794..a2441ca04b6 100644 --- a/core/src/main/java/org/jruby/ir/persistence/IRReaderStream.java +++ b/core/src/main/java/org/jruby/ir/persistence/IRReaderStream.java @@ -529,6 +529,7 @@ public Operand decode(OperandType type) { case GLOBAL_VARIABLE: return GlobalVariable.decode(this); case HASH: return Hash.decode(this); case IR_EXCEPTION: return IRException.decode(this); + case INTEGER: return org.jruby.ir.operands.Integer.decode(this); case LABEL: return Label.decode(this); case LOCAL_VARIABLE: return LocalVariable.decode(this); case NIL: return manager.getNil(); diff --git a/core/src/main/java/org/jruby/javasupport/binding/MethodGatherer.java b/core/src/main/java/org/jruby/javasupport/binding/MethodGatherer.java index f3a1d5f2586..7518ca151ac 100644 --- a/core/src/main/java/org/jruby/javasupport/binding/MethodGatherer.java +++ b/core/src/main/java/org/jruby/javasupport/binding/MethodGatherer.java @@ -72,6 +72,8 @@ public class MethodGatherer { static { STATIC_RESERVED_NAMES = newReservedNamesMap(1); STATIC_RESERVED_NAMES.put("new", new AssignedName("new", Priority.RESERVED)); + // "singleton_method_added" gets called on the metaclass for metaclass method definitions + STATIC_RESERVED_NAMES.put("singleton_method_added", new AssignedName("singleton_method_added", Priority.RESERVED)); } static { @@ -82,6 +84,8 @@ public class MethodGatherer { INSTANCE_RESERVED_NAMES.put("initialize", new AssignedName("initialize", Priority.RESERVED)); // "equal?" should not be overridden (GH-5990) INSTANCE_RESERVED_NAMES.put("equal?", new AssignedName("equal?", Priority.RESERVED)); + // "singleton_method_added" gets called on the object for singleton method definitions + INSTANCE_RESERVED_NAMES.put("singleton_method_added", new AssignedName("singleton_method_added", Priority.RESERVED)); } // TODO: other reserved names? diff --git a/core/src/main/java/org/jruby/lexer/yacc/RubyLexer.java b/core/src/main/java/org/jruby/lexer/yacc/RubyLexer.java index 8b786bca75b..38e4331b6fc 100644 --- a/core/src/main/java/org/jruby/lexer/yacc/RubyLexer.java +++ b/core/src/main/java/org/jruby/lexer/yacc/RubyLexer.java @@ -162,6 +162,10 @@ private void warning(ID id, String file, int line, String message) { warnings.warning(id, file, line + 1, message); // rubysource-line is 0 based } + private void warn(ID id, String message) { + warnings.warn(id, getFile(), getRubySourceline(), message); + } + public enum Keyword { END ("end", new ByteList(new byte[] {'e', 'n', 'd'}, USASCII_ENCODING), keyword_end, keyword_end, EXPR_END), ELSE ("else", new ByteList(new byte[] {'e', 'l', 's', 'e'}, USASCII_ENCODING), keyword_else, keyword_else, EXPR_BEG), @@ -354,7 +358,7 @@ public int nextc() { c = '\n'; } else if (ruby_sourceline > last_cr_line) { last_cr_line = ruby_sourceline; - warning(ID.VOID_VALUE_EXPRESSION, "encountered \\r in middle of line, treated as a mere space"); + warn(ID.VOID_VALUE_EXPRESSION, "encountered \\r in middle of line, treated as a mere space"); } } @@ -1489,7 +1493,7 @@ private int dollar() { try { ref = Integer.parseInt(refAsString.substring(1)); } catch (NumberFormatException e) { - warning(ID.AMBIGUOUS_ARGUMENT, "`" + refAsString + "' is too big for a number variable, always nil"); + warn(ID.AMBIGUOUS_ARGUMENT, "`" + refAsString + "' is too big for a number variable, always nil"); ref = 0; } @@ -1531,7 +1535,7 @@ private int dot() { } if (parenNest == 0 && isLookingAtEOL()) { - warning(ID.MISCELLANEOUS, "... at EOL, should be parenthesized?"); + warn(ID.MISCELLANEOUS, "... at EOL, should be parenthesized?"); } else if (getLeftParenBegin() >= 0 && getLeftParenBegin() + 1 == parenNest) { if (isLexState(last_state, EXPR_LABEL)) { return tDOT3; diff --git a/core/src/main/java/org/jruby/parser/RubyParserBase.java b/core/src/main/java/org/jruby/parser/RubyParserBase.java index 297d294f01a..08e8b300321 100644 --- a/core/src/main/java/org/jruby/parser/RubyParserBase.java +++ b/core/src/main/java/org/jruby/parser/RubyParserBase.java @@ -1597,11 +1597,11 @@ public void warn(int line, String message) { // FIXME: Replace this with file/line version and stop using ISourcePosition public void warning(int line, String message) { - if (warnings.isVerbose()) warning(ID.USELESS_EXPRESSION, lexer.getFile(), line, message); + warning(ID.USELESS_EXPRESSION, lexer.getFile(), line, message); } public void warning(ID id, String file, int line, String message) { - warnings.warning(id, file, line + 1, message); // node/lexer lines are 0 based + warnings.warn(id, file, line + 1, message); // node/lexer lines are 0 based } // ENEBO: Totally weird naming (in MRI is not allocated and is a local var name) [1.9] diff --git a/core/src/main/java/org/jruby/util/StringSupport.java b/core/src/main/java/org/jruby/util/StringSupport.java index ea9ef3a7178..3d9239bf30f 100644 --- a/core/src/main/java/org/jruby/util/StringSupport.java +++ b/core/src/main/java/org/jruby/util/StringSupport.java @@ -2154,7 +2154,7 @@ public static IRubyObject rbStrEnumerateLines(RubyString str, ThreadContext cont if (wantarray) { // this code should be live in 3.0 if (false) { // #if STRING_ENUMERATORS_WANTARRAY - runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); } else { runtime.getWarnings().warning(ID.BLOCK_DEPRECATED, "passing a block to String#lines is deprecated"); wantarray = false; diff --git a/core/src/main/java/org/jruby/util/cli/Options.java b/core/src/main/java/org/jruby/util/cli/Options.java index 0dd1f7cbaad..ff556ecbadd 100644 --- a/core/src/main/java/org/jruby/util/cli/Options.java +++ b/core/src/main/java/org/jruby/util/cli/Options.java @@ -72,7 +72,7 @@ public class Options { public static final Option COMPILE_MODE = enumeration(COMPILER, "compile.mode", CompileMode.class, CompileMode.JIT, "Set compilation mode. JIT = at runtime; FORCE = before execution."); public static final Option COMPILE_DUMP = bool(COMPILER, "compile.dump", false, "Dump to console all bytecode generated at runtime."); public static final Option COMPILE_INVOKEDYNAMIC = bool(COMPILER, "compile.invokedynamic", INVOKEDYNAMIC_DEFAULT, "Use invokedynamic for optimizing Ruby code."); - public static final Option COMPILE_CACHE_CLASSES = bool(COMPILER, "compile.cache.classes", false, "Use cache of compiled sript classes"); + public static final Option COMPILE_CACHE_CLASSES = bool(COMPILER, "compile.cache.classes", false, "Use cache of compiled script classes"); public static final Option COMPILE_CACHE_CLASSES_LOGGING = bool(COMPILER, "compile.cache.classes.logging", false, "Log whether cached script classes are being saved or used"); public static final Option INVOKEDYNAMIC_MAXFAIL = integer(INVOKEDYNAMIC, "invokedynamic.maxfail", 1000, "Maximum call site failures after which to inline cache."); @@ -158,7 +158,7 @@ public class Options { public static final Option USE_FIXNUM_CACHE = bool(MISCELLANEOUS, "fixnum.cache", true, "Use a cache of low-valued Fixnum objects."); public static final Option FIXNUM_CACHE_RANGE = integer(MISCELLANEOUS, "fixnum.cache.size", 256, "Values to retrieve from Fixnum cache, in the range -X..(X-1)."); public static final Option PACKED_ARRAYS = bool(MISCELLANEOUS, "packed.arrays", true, "Toggle whether to use \"packed\" arrays for small tuples."); - public static final Option REGEXP_INTERRUPTIBLE = bool(MISCELLANEOUS, "regexp.interruptible", true, "Allow regexp operations to be interuptible from Ruby."); + public static final Option REGEXP_INTERRUPTIBLE = bool(MISCELLANEOUS, "regexp.interruptible", true, "Allow regexp operations to be interruptible from Ruby."); public static final Option JAR_CACHE_EXPIRATION = integer(MISCELLANEOUS, "jar.cache.expiration", 750, "The time (ms) between checks if a JAR file containing resources has been updated."); public static final Option DEBUG_LOADSERVICE = bool(DEBUG, "debug.loadService", false, "Log require/load file searches."); diff --git a/lib/pom.rb b/lib/pom.rb index 6ccff499362..1da605ec579 100644 --- a/lib/pom.rb +++ b/lib/pom.rb @@ -47,7 +47,7 @@ def log(message=nil) ['find', '0.2.0'], ['forwardable', '1.3.3'], ['getoptlong', '0.2.1'], - ['io-console', '0.7.1'], + ['io-console', '0.7.2'], # https://github.com/ruby/io-nonblock/issues/4 # ['io-nonblock', '0.1.0'], ['io-wait', '0.3.1'], @@ -95,7 +95,7 @@ def log(message=nil) ['shellwords', '0.2.0'], ['singleton', '0.2.0'], ['stringio', '3.1.0'], - ['strscan', '3.0.7'], + ['strscan', '3.0.9'], ['subspawn', '0.1.1'], # has 3 transitive deps: ['subspawn-posix', '0.1.1'], ['ffi-binary-libfixposix', '0.5.1.1'], diff --git a/lib/pom.xml b/lib/pom.xml index ef2c858bebf..31c6dfef0b4 100644 --- a/lib/pom.xml +++ b/lib/pom.xml @@ -307,7 +307,7 @@ DO NOT MODIFY - GENERATED CODE rubygems io-console - 0.7.1 + 0.7.2 gem provided @@ -710,7 +710,7 @@ DO NOT MODIFY - GENERATED CODE rubygems strscan - 3.0.7 + 3.0.9 gem provided @@ -1100,7 +1100,7 @@ DO NOT MODIFY - GENERATED CODE specifications/find-0.2.0* specifications/forwardable-1.3.3* specifications/getoptlong-0.2.1* - specifications/io-console-0.7.1* + specifications/io-console-0.7.2* specifications/io-wait-0.3.1* specifications/ipaddr-1.2.6* specifications/irb-1.11.0* @@ -1131,7 +1131,7 @@ DO NOT MODIFY - GENERATED CODE specifications/shellwords-0.2.0* specifications/singleton-0.2.0* specifications/stringio-3.1.0* - specifications/strscan-3.0.7* + specifications/strscan-3.0.9* specifications/subspawn-0.1.1* specifications/subspawn-posix-0.1.1* specifications/ffi-binary-libfixposix-0.5.1.1* @@ -1179,7 +1179,7 @@ DO NOT MODIFY - GENERATED CODE gems/find-0.2.0*/**/* gems/forwardable-1.3.3*/**/* gems/getoptlong-0.2.1*/**/* - gems/io-console-0.7.1*/**/* + gems/io-console-0.7.2*/**/* gems/io-wait-0.3.1*/**/* gems/ipaddr-1.2.6*/**/* gems/irb-1.11.0*/**/* @@ -1210,7 +1210,7 @@ DO NOT MODIFY - GENERATED CODE gems/shellwords-0.2.0*/**/* gems/singleton-0.2.0*/**/* gems/stringio-3.1.0*/**/* - gems/strscan-3.0.7*/**/* + gems/strscan-3.0.9*/**/* gems/subspawn-0.1.1*/**/* gems/subspawn-posix-0.1.1*/**/* gems/ffi-binary-libfixposix-0.5.1.1*/**/* @@ -1258,7 +1258,7 @@ DO NOT MODIFY - GENERATED CODE cache/find-0.2.0* cache/forwardable-1.3.3* cache/getoptlong-0.2.1* - cache/io-console-0.7.1* + cache/io-console-0.7.2* cache/io-wait-0.3.1* cache/ipaddr-1.2.6* cache/irb-1.11.0* @@ -1289,7 +1289,7 @@ DO NOT MODIFY - GENERATED CODE cache/shellwords-0.2.0* cache/singleton-0.2.0* cache/stringio-3.1.0* - cache/strscan-3.0.7* + cache/strscan-3.0.9* cache/subspawn-0.1.1* cache/subspawn-posix-0.1.1* cache/ffi-binary-libfixposix-0.5.1.1* diff --git a/spec/ruby/core/module/attr_accessor_spec.rb b/spec/ruby/core/module/attr_accessor_spec.rb index eea5b4b64b8..503dccc61ed 100644 --- a/spec/ruby/core/module/attr_accessor_spec.rb +++ b/spec/ruby/core/module/attr_accessor_spec.rb @@ -1,5 +1,6 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' +require_relative 'shared/attr_added' describe "Module#attr_accessor" do it "creates a getter and setter for each given attribute name" do @@ -106,4 +107,6 @@ class Integer 1.foobar.should be_nil end end + + it_behaves_like :module_attr_added, :attr_accessor end diff --git a/spec/ruby/core/module/attr_reader_spec.rb b/spec/ruby/core/module/attr_reader_spec.rb index 0b6d9967192..37fd537ff5c 100644 --- a/spec/ruby/core/module/attr_reader_spec.rb +++ b/spec/ruby/core/module/attr_reader_spec.rb @@ -1,5 +1,6 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' +require_relative 'shared/attr_added' describe "Module#attr_reader" do it "creates a getter for each given attribute name" do @@ -67,4 +68,6 @@ class TrueClass (attr_reader :foo, 'bar').should == [:foo, :bar] end end + + it_behaves_like :module_attr_added, :attr_reader end diff --git a/spec/ruby/core/module/attr_spec.rb b/spec/ruby/core/module/attr_spec.rb index 72a6646b1ee..2f9f4e26dc5 100644 --- a/spec/ruby/core/module/attr_spec.rb +++ b/spec/ruby/core/module/attr_spec.rb @@ -1,5 +1,6 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' +require_relative 'shared/attr_added' describe "Module#attr" do before :each do @@ -153,4 +154,6 @@ def initialize (attr :qux, true).should == [:qux, :qux=] end end + + it_behaves_like :module_attr_added, :attr end diff --git a/spec/ruby/core/module/attr_writer_spec.rb b/spec/ruby/core/module/attr_writer_spec.rb index aaea0ce43f5..5b863ef88c1 100644 --- a/spec/ruby/core/module/attr_writer_spec.rb +++ b/spec/ruby/core/module/attr_writer_spec.rb @@ -1,5 +1,6 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' +require_relative 'shared/attr_added' describe "Module#attr_writer" do it "creates a setter for each given attribute name" do @@ -77,4 +78,6 @@ class TrueClass (attr_writer :foo, 'bar').should == [:foo=, :bar=] end end + + it_behaves_like :module_attr_added, :attr_writer end diff --git a/spec/ruby/core/module/shared/attr_added.rb b/spec/ruby/core/module/shared/attr_added.rb new file mode 100644 index 00000000000..e37622d284b --- /dev/null +++ b/spec/ruby/core/module/shared/attr_added.rb @@ -0,0 +1,34 @@ +describe :module_attr_added, shared: true do + it "calls method_added for normal classes" do + ScratchPad.record [] + + cls = Class.new do + class << self + def method_added(name) + ScratchPad.recorded << name + end + end + end + + cls.send(@method, :foo) + + ScratchPad.recorded.each {|name| name.to_s.should =~ /foo[=]?/} + end + + it "calls singleton_method_added for singleton classes" do + ScratchPad.record [] + cls = Class.new do + class << self + def singleton_method_added(name) + # called for this def so ignore it + return if name == :singleton_method_added + ScratchPad.recorded << name + end + end + end + + cls.singleton_class.send(@method, :foo) + + ScratchPad.recorded.each {|name| name.to_s.should =~ /foo[=]?/} + end +end \ No newline at end of file diff --git a/spec/tags/ruby/core/module/refine_tags.txt b/spec/tags/ruby/core/module/refine_tags.txt index f56a17a41d6..1a0ee3f3962 100644 --- a/spec/tags/ruby/core/module/refine_tags.txt +++ b/spec/tags/ruby/core/module/refine_tags.txt @@ -2,4 +2,3 @@ fails:Module#refine for methods accessed indirectly is not honored by & fails(not implemented, jruby/jruby#6161):Module#refine for methods accessed indirectly is honored by & fails:Module#refine when super is called in a refinement looks in the lexical scope refinements before other active refinements fails:Module#refine for methods accessed indirectly is honored by Kernel#public_method -fails:Module#refine raises TypeError if not passed a class diff --git a/test/check_versions.sh b/test/check_versions.sh index 952cb6114e8..9c91f4f1a05 100755 --- a/test/check_versions.sh +++ b/test/check_versions.sh @@ -65,7 +65,7 @@ check lib/target/jruby-stdlib-$jar_version.jar 17 check maven/jruby-jars/pkg/jruby-jars-$gem_version.gem 30 check maven/jruby-jars/lib/jruby-core-$jar_version-complete.jar 16 check maven/jruby-jars/lib/jruby-stdlib-$jar_version.jar 17 -check maven/jruby-complete/target/jruby-complete-$jar_version.jar 32 +check maven/jruby-complete/target/jruby-complete-$jar_version.jar 33 check maven/jruby/target/jruby-$jar_version.jar 9 check maven/jruby-dist/target/jruby-dist-$jar_version-bin.tar.gz 45 jruby-$jar_version check maven/jruby-dist/target/jruby-dist-$jar_version-src.zip 20 jruby-$jar_version