Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 1acb5df153d5
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 5ecba2518a6b
Choose a head ref
  • 2 commits
  • 10 files changed
  • 1 contributor

Commits on Mar 21, 2016

  1. Fixes #1981. Wrong number of reported lines in Coverage API

    This ended up being much simpler than I think any of us thought.
    Base problem was any lines after last *newline* marked node would
    not update the primitive 'coverage' array which coverage sets up.
    So we just call one method at end up parse to update that array
    to include final lines of the file.
    enebo committed Mar 21, 2016

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    d465231 View commit details
  2. Copy the full SHA
    5ecba25 View commit details
2,092 changes: 1,048 additions & 1,044 deletions core/src/main/java/org/jruby/parser/DefaultRubyParser.java

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions core/src/main/java/org/jruby/parser/DefaultRubyParser.y
Original file line number Diff line number Diff line change
@@ -145,6 +145,10 @@ public class DefaultRubyParser implements RubyParser {
support.setWarnings(warnings);
lexer.setWarnings(warnings);
}

public RubyYaccLexer getLexer() {
return lexer;
}
%}

%token <Token> kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF
1 change: 1 addition & 0 deletions core/src/main/java/org/jruby/parser/Parser.java
Original file line number Diff line number Diff line change
@@ -160,6 +160,7 @@ public Node parse(String file, LexerSource lexerSource, DynamicScope blockScope,

// set coverage baseline into coverage data
if (runtime.getCoverageData().isCoverageEnabled()) {
configuration.growCoverageLines(parser.getLexer().getPosition().getStartLine()-1);
runtime.getCoverageData().prepareCoverage(file, configuration.getCoverage());
}

27 changes: 17 additions & 10 deletions core/src/main/java/org/jruby/parser/ParserConfiguration.java
Original file line number Diff line number Diff line change
@@ -232,20 +232,27 @@ public void coverLine(int i) {
if (i < 0) return; // JRUBY-6868: why would there be negative line numbers?

if (runtime.getCoverageData().isCoverageEnabled()) {
if (coverage == null) {
coverage = new int[i + 1];
} else if (coverage.length <= i) {
int[] newCoverage = new int[i + 1];
Arrays.fill(newCoverage, -1);
System.arraycopy(coverage, 0, newCoverage, 0, coverage.length);
coverage = newCoverage;
}

// zero means coverable, but not yet covered
growCoverageLines(i);
coverage[i] = 0;
}
}

/**
* Called by coverLine to grow it large enough to add new covered line.
* Also called at end up parse to pick up any extra non-code lines which
* should be marked -1 for not valid code lines.
*/
public void growCoverageLines(int i) {
if (coverage == null) {
coverage = new int[i + 1];
} else if (coverage.length <= i) {
int[] newCoverage = new int[i + 1];
Arrays.fill(newCoverage, -1);
System.arraycopy(coverage, 0, newCoverage, 0, coverage.length);
coverage = newCoverage;
}
}

/**
* Get the coverage array, indicating all coverable lines
*/
10 changes: 7 additions & 3 deletions core/src/main/java/org/jruby/parser/Ruby19Parser.java
Original file line number Diff line number Diff line change
@@ -137,7 +137,11 @@ public void setWarnings(IRubyWarnings warnings) {
support.setWarnings(warnings);
lexer.setWarnings(warnings);
}
// line 141 "-"

public RubyYaccLexer getLexer() {
return lexer;
}
// line 145 "-"
// %token constants
public static final int kCLASS = 257;
public static final int kMODULE = 258;
@@ -4269,7 +4273,7 @@ public Object yyparse (RubyYaccLexer yyLex) throws java.io.IOException {
}
};
}
// line 2023 "Ruby19Parser.y"
// line 2027 "Ruby19Parser.y"

/** The parse method use an lexer stream and parse it to an AST node
* structure
@@ -4288,4 +4292,4 @@ public RubyParserResult parse(ParserConfiguration configuration, LexerSource sou
return support.getResult();
}
}
// line 8253 "-"
// line 8257 "-"
4 changes: 4 additions & 0 deletions core/src/main/java/org/jruby/parser/Ruby19Parser.y
Original file line number Diff line number Diff line change
@@ -134,6 +134,10 @@ public class Ruby19Parser implements RubyParser {
support.setWarnings(warnings);
lexer.setWarnings(warnings);
}

public RubyYaccLexer getLexer() {
return lexer;
}
%}

// We need to make sure we have same tokens in the same order and up
10 changes: 7 additions & 3 deletions core/src/main/java/org/jruby/parser/Ruby20Parser.java
Original file line number Diff line number Diff line change
@@ -138,7 +138,11 @@ public void setWarnings(IRubyWarnings warnings) {
support.setWarnings(warnings);
lexer.setWarnings(warnings);
}
// line 142 "-"

public RubyYaccLexer getLexer() {
return lexer;
}
// line 146 "-"
// %token constants
public static final int kCLASS = 257;
public static final int kMODULE = 258;
@@ -4623,7 +4627,7 @@ public Object yyparse (RubyYaccLexer yyLex) throws java.io.IOException {
}
};
}
// line 2215 "Ruby20Parser.y"
// line 2219 "Ruby20Parser.y"

/** The parse method use an lexer stream and parse it to an AST node
* structure
@@ -4642,4 +4646,4 @@ public RubyParserResult parse(ParserConfiguration configuration, LexerSource sou
return support.getResult();
}
}
// line 8667 "-"
// line 8671 "-"
4 changes: 4 additions & 0 deletions core/src/main/java/org/jruby/parser/Ruby20Parser.y
Original file line number Diff line number Diff line change
@@ -135,6 +135,10 @@ public class Ruby20Parser implements RubyParser {
support.setWarnings(warnings);
lexer.setWarnings(warnings);
}

public RubyYaccLexer getLexer() {
return lexer;
}
%}

// We need to make sure we have same tokens in the same order and up
2 changes: 2 additions & 0 deletions core/src/main/java/org/jruby/parser/RubyParser.java
Original file line number Diff line number Diff line change
@@ -31,11 +31,13 @@
import java.io.IOException;
import org.jruby.common.IRubyWarnings;
import org.jruby.lexer.yacc.LexerSource;
import org.jruby.lexer.yacc.RubyYaccLexer;

/**
* Common interface specifying the contract of Ruby parsers (1.8.6 + 1.9)
*/
public interface RubyParser {
public RubyParserResult parse(ParserConfiguration configuration, LexerSource source) throws IOException;
public void setWarnings(IRubyWarnings warnings);
public RubyYaccLexer getLexer();
}
116 changes: 116 additions & 0 deletions core/src/main/ruby/jruby/java/core_ext/#object.rb#
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
class Object
# include the class specified by +include_class+ into the current namespace,
# using either its base name or by using a name returned from an optional block,
# passing all specified classes in turn and providing the block package name
# and base class name.
def include_class(include_class, &block)
warn "#{__method__} is deprecated. Use java_import."
java_import(include_class, &block)
end

# TODO: this can go away now, but people may be using it
def java_kind_of?(other)
return true if self.kind_of?(other)
return false unless self.respond_to?(:java_class) && other.respond_to?(:java_class) &&
other.kind_of?(Module) && !self.kind_of?(Module)
return other.java_class.assignable_from?(self.java_class)
end

# Import one or many Java classes as follows:
#
# java_import java.lang.System
# java_import java.lang.System, java.lang.Thread
# java_import [java.lang.System, java.lang.Thread]
#
# Optionally java_import can also include a block to be used for custom
#
#
def java_import(*import_classes)
import_classes = import_classes.each_with_object([]) do |classes, flattened|
if classes.is_a?(Array)
flattened.push(*classes)
else
flattened.push(classes)
end
end

import_classes.map do |import_class|
case import_class
when String
cc = java.lang.Character
valid_name = import_class.split(".").all? do |frag|
cc.java_identifier_start? frag[0].ord and
frag.each_char.all? {|c| cc.java_identifier_part? c.ord }
end
unless valid_name
raise ArgumentError.new "not a valid Java identifier: #{import_class}"
end
# pull in the class
raise ArgumentError.new "must use jvm-style name: #{import_class}" if import_class.include? "::"
import_class = JavaUtilities.get_proxy_class(import_class)
when Module
if import_class.respond_to? "java_class"
# ok, it's a proxy
else
raise ArgumentError.new "not a Java class or interface: #{import_class}"
end
else
raise ArgumentError.new "invalid Java class or interface: #{import_class}"
end

java_class = import_class.java_class
class_name = java_class.simple_name

if block_given?
package = java_class.package

# package can be nil if it's default or no package was defined by the classloader
if package
package_name = package.name
elsif java_class.canonical_name =~ /(.*)\.[^.]$/
package_name = $1
else
package_name = ""
end

constant = yield(package_name, class_name)
else
constant = class_name

# Inner classes are separated with $, get last element
if constant =~ /\$([^$])$/
constant = $1
end
end

unless constant =~ /^[A-Z].*/
raise ArgumentError.new "cannot import class `" + java_class.name + "' as `" + constant + "'"
end

# JRUBY-3453: Make import not complain if Java already has already imported the specific Java class
# If no constant is defined, or the constant is not already set to the java_import, assign it
eval_str = "if !defined?(#{constant}) || #{constant} != import_class; #{constant} = import_class; end"
if Module === self
class_eval(eval_str, __FILE__, __LINE__)
else
eval(eval_str, binding, __FILE__, __LINE__)
end

import_class
end
end

private :java_import

def handle_different_imports(*args, &block)
if args.first.respond_to?(:java_class)
java_import(*args, &block)
else
other_import(*args, &block)
end
end

unless respond_to?(:import)
alias :import :java_import
end
end