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: 875adbb28f67
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 0c95b3d74c0a
Choose a head ref
  • 5 commits
  • 12 files changed
  • 1 contributor

Commits on Aug 1, 2015

  1. Copy the full SHA
    bf8c2d9 View commit details
  2. Copy the full SHA
    fe1c3e7 View commit details
  3. Copy the full SHA
    ad99c23 View commit details

Commits on Aug 3, 2015

  1. Copy the full SHA
    871f25b View commit details
  2. Merge with master

    enebo committed Aug 3, 2015
    Copy the full SHA
    0c95b3d View commit details
82 changes: 60 additions & 22 deletions core/src/main/java/org/jruby/ast/ArgsNode.java
Original file line number Diff line number Diff line change
@@ -53,14 +53,16 @@
* b = block arg
*/
public class ArgsNode extends Node {
private final ListNode pre;
private final ListNode optArgs;
private Node[] args;
private short optIndex;
private short postIndex;
private short keywordsIndex;

protected final ArgumentNode restArgNode;
private final ListNode post;
private final ListNode keywords;
private final KeywordRestArgNode keyRest;
private final BlockArgNode blockArgNode;

private static final Node[] NO_ARGS = new Node[] {};
/**
* Construct a new ArgsNode with no keyword arguments.
*/
@@ -82,31 +84,61 @@ public ArgsNode(ISourcePosition position, ListNode pre, ListNode optionalArgumen
keyRest != null && keyRest.containsVariableAssignment() ||
blockArgNode != null && blockArgNode.containsVariableAssignment());

this.pre = pre;
this.post = post;
this.optArgs = optionalArguments;
int preSize = pre != null ? pre.size() : 0;
int optSize = optionalArguments != null ? optionalArguments.size() : 0;
int postSize = post != null ? post.size() : 0;
int keywordsSize = keywords != null ? keywords.size() : 0;
int size = preSize + optSize + postSize + keywordsSize;

args = size > 0 ? new Node[size] : NO_ARGS;
optIndex = (short) (preSize != 0 ? preSize : 0);
postIndex = (short) (optSize != 0 ? optIndex + optSize : optIndex);
keywordsIndex = (short) (postSize != 0 ? postIndex + postSize : postIndex);

if (preSize > 0) System.arraycopy(pre.children(), 0, args, 0, preSize);
if (optSize > 0) System.arraycopy(optionalArguments.children(), 0, args, optIndex, optSize);
if (postSize > 0) System.arraycopy(post.children(), 0, args, postIndex, postSize);
if (keywordsSize > 0) System.arraycopy(keywords.children(), 0, args, keywordsIndex, keywordsSize);

this.restArgNode = rest;
this.blockArgNode = blockArgNode;
this.keywords = keywords;
this.keyRest = keyRest;
}

public Node[] getArgs() {
return args;
}

public int getOptArgIndex() {
return optIndex;
}

public int getPostIndex() {
return postIndex;
}

public int getKeywordsIndex() {
return keywordsIndex;
}

@Override
public NodeType getNodeType() {
return NodeType.ARGSNODE;
}

public boolean hasKwargs() {
return keywords != null || keyRest != null;
boolean keywords = getKeywordCount() > 0;
return keywords || keyRest != null;
}

public int countKeywords() {
if (hasKwargs()) {
if (keywords == null) {
boolean keywords = args.length - keywordsIndex > 0;
if (keywords) {
// Rest keyword argument
return 0;
}
return keywords.size();
return args.length - keywordsIndex;
} else {
return 0;
}
@@ -129,19 +161,19 @@ public <T> T accept(NodeVisitor<T> iVisitor) {
* Gets the required arguments at the beginning of the argument definition
*/
public ListNode getPre() {
return pre;
return new ListNode(getPosition()).addAll(args, 0, getPreCount());
}

public int getRequiredArgsCount() {
return getPreCount() + getPostCount();
}

public int getOptionalArgsCount() {
return optArgs == null ? 0 : optArgs.size();
return postIndex - optIndex;
}

public ListNode getPost() {
return post;
return new ListNode(getPosition()).addAll(args, postIndex, getPostCount());
}

public int getMaxArgumentsCount() {
@@ -153,7 +185,7 @@ public int getMaxArgumentsCount() {
* @return Returns a ListNode
*/
public ListNode getOptArgs() {
return optArgs;
return new ListNode(getPosition()).addAll(args, optIndex, getOptionalArgsCount());
}

/**
@@ -174,15 +206,15 @@ public BlockArgNode getBlock() {
}

public int getPostCount() {
return post == null ? 0 : post.size();
return keywordsIndex - postIndex;
}

public int getPreCount() {
return pre == null ? 0 : pre.size();
return optIndex;
}

public ListNode getKeywords() {
return keywords;
return new ListNode(getPosition()).addAll(args, keywordsIndex, getKeywordCount());
}

public KeywordRestArgNode getKeyRest() {
@@ -196,6 +228,12 @@ public boolean hasKeyRest() {
// FIXME: This is a hot mess and I think we will still have some extra nulls inserted
@Override
public List<Node> childNodes() {
ListNode post = getPost();
ListNode keywords = getKeywords();
ListNode pre = getPre();
ListNode optArgs = getOptArgs();


if (post != null) {
if (keywords != null) {
if (keyRest != null) return Node.createList(pre, optArgs, restArgNode, post, keywords, keyRest, blockArgNode);
@@ -216,18 +254,18 @@ public List<Node> childNodes() {
}

public int getKeywordCount() {
return keywords == null ? 0 : keywords.size();
return args.length - keywordsIndex;
}

/**
* How many of the keywords listed happen to be required keyword args. Note: total kwargs - req kwarg = opt kwargs.
*/
public int getRequiredKeywordCount() {
if (keywords == null) return 0;
if (getKeywordCount() < 1) return 0;

int count = 0;
for (Node keyWordNode : getKeywords().children()) {
for (Node asgnNode : keyWordNode.childNodes()) {
for (int i = 0; i < getKeywordCount(); i++) {
for (Node asgnNode : args[keywordsIndex + i].childNodes()) {
if (Helpers.isRequiredKeywordArgumentValueNode(asgnNode)) count++;
}
}
14 changes: 3 additions & 11 deletions core/src/main/java/org/jruby/ast/DefnNode.java
Original file line number Diff line number Diff line change
@@ -43,9 +43,9 @@
* method definition node.
*/
public class DefnNode extends MethodDefNode implements INameNode {
public DefnNode(ISourcePosition position, ArgumentNode nameNode, ArgsNode argsNode,
public DefnNode(ISourcePosition position, String name, ArgsNode argsNode,
StaticScope scope, Node bodyNode) {
super(position, nameNode, argsNode, scope, bodyNode);
super(position, name, argsNode, scope, bodyNode);
}

public NodeType getNodeType() {
@@ -56,15 +56,7 @@ public <T> T accept(NodeVisitor<T> iVisitor) {
return iVisitor.visitDefnNode(this);
}

/**
* Get the name of this method
*/
@Override
public String getName() {
return nameNode.getName();
}

public List<Node> childNodes() {
return Node.createList(nameNode, argsNode, bodyNode);
return Node.createList(argsNode, bodyNode);
}
}
14 changes: 3 additions & 11 deletions core/src/main/java/org/jruby/ast/DefsNode.java
Original file line number Diff line number Diff line change
@@ -43,9 +43,9 @@
*/
public class DefsNode extends MethodDefNode implements INameNode {
private final Node receiverNode;
public DefsNode(ISourcePosition position, Node receiverNode, ArgumentNode nameNode, ArgsNode argsNode,
public DefsNode(ISourcePosition position, Node receiverNode, String name, ArgsNode argsNode,
StaticScope scope, Node bodyNode) {
super(position, nameNode, argsNode, scope, bodyNode);
super(position, name, argsNode, scope, bodyNode);

assert receiverNode != null : "receiverNode is not null";

@@ -72,15 +72,7 @@ public Node getReceiverNode() {
return receiverNode;
}

/**
* Gets the name of this method
*/
@Override
public String getName() {
return nameNode.getName();
}

public List<Node> childNodes() {
return Node.createList(receiverNode, nameNode, argsNode, bodyNode);
return Node.createList(receiverNode, argsNode, bodyNode);
}
}
8 changes: 8 additions & 0 deletions core/src/main/java/org/jruby/ast/ListNode.java
Original file line number Diff line number Diff line change
@@ -129,6 +129,14 @@ public ListNode addAll(ListNode other) {
}
return this;
}

public ListNode addAll(Node[] other, int index, int length) {
for (int i = 0; i < length; i++) {
addInternal(other[index + i]);
}

return this;
}

/**
* Add other element to this list
19 changes: 5 additions & 14 deletions core/src/main/java/org/jruby/ast/MethodDefNode.java
Original file line number Diff line number Diff line change
@@ -34,21 +34,20 @@
import org.jruby.ast.types.INameNode;
import org.jruby.lexer.yacc.ISourcePosition;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.Signature;

public abstract class MethodDefNode extends Node implements INameNode {
protected final ArgumentNode nameNode;
protected final String name;
protected final ArgsNode argsNode;
protected final StaticScope scope;
protected final Node bodyNode;

public MethodDefNode(ISourcePosition position, ArgumentNode nameNode, ArgsNode argsNode,
public MethodDefNode(ISourcePosition position, String name, ArgsNode argsNode,
StaticScope scope, Node bodyNode) {
super(position, argsNode.containsVariableAssignment() || bodyNode.containsVariableAssignment());
super(position, bodyNode.containsVariableAssignment());

assert bodyNode != null : "bodyNode must not be null";

this.nameNode = nameNode;
this.name = name;
this.argsNode = argsNode;
this.scope = scope;
this.bodyNode = bodyNode;
@@ -81,19 +80,11 @@ public Node getBodyNode() {
return bodyNode;
}

/**
* Gets the name's node.
* @return Returns an ArgumentNode
*/
public ArgumentNode getNameNode() {
return nameNode;
}

/**
* Gets the name.
* @return Returns a String
*/
public String getName() {
return nameNode.getName();
return name;
}
}
24 changes: 13 additions & 11 deletions core/src/main/java/org/jruby/ir/IRBuilder.java
Original file line number Diff line number Diff line change
@@ -1828,22 +1828,22 @@ protected void receiveNonBlockArgs(final ArgsNode argsNode) {
int argIndex = 0;

// Pre(-opt and rest) required args
ListNode preArgs = argsNode.getPre();
Node[] args = argsNode.getArgs();
int preCount = signature.pre();
for (int i = 0; i < preCount; i++, argIndex++) {
receiveRequiredArg(preArgs.get(i), argIndex, false, -1, -1);
receiveRequiredArg(args[i], argIndex, false, -1, -1);
}

// Fixup opt/rest
int opt = signature.opt() > 0 ? signature.opt() : 0;

// Now for opt args
if (opt > 0) {
ListNode optArgs = argsNode.getOptArgs();
int optIndex = argsNode.getOptArgIndex();
for (int j = 0; j < opt; j++, argIndex++) {
// Jump to 'l' if this arg is not null. If null, fall through and build the default value!
Label l = getNewLabel();
OptArgNode n = (OptArgNode)optArgs.get(j);
OptArgNode n = (OptArgNode)args[optIndex + j];
String argName = n.getName();
Variable av = getNewLocalVariable(argName, 0);
if (scope instanceof IRMethod) addArgumentDescription(ArgumentType.opt, argName);
@@ -1875,10 +1875,10 @@ protected void receiveNonBlockArgs(final ArgsNode argsNode) {
}

// Post(-opt and rest) required args
ListNode postArgs = argsNode.getPost();
int postCount = postArgs != null ? postArgs.size() : -1;
int postCount = argsNode.getPostCount();
int postIndex = argsNode.getPostIndex();
for (int i = 0; i < postCount; i++) {
receiveRequiredArg(postArgs.get(i), i, true, signature.pre(), postCount);
receiveRequiredArg(args[postIndex + i], i, true, signature.pre(), postCount);
}
}

@@ -1930,11 +1930,13 @@ public void receiveArgs(final ArgsNode argsNode) {
receiveNonBlockArgs(argsNode);

// 2.0 keyword args
ListNode keywords = argsNode.getKeywords();
Node[] args = argsNode.getArgs();
int required = argsNode.getRequiredArgsCount();
if (keywords != null) {
for (Node knode : keywords.children()) {
KeywordArgNode kwarg = (KeywordArgNode)knode;
if (argsNode.hasKwargs()) {
int keywordIndex = argsNode.getKeywordsIndex();
int keywordsCount = argsNode.getKeywordCount();
for (int i = 0; i < keywordsCount; i++) {
KeywordArgNode kwarg = (KeywordArgNode) args[keywordIndex + i];
AssignableNode kasgn = kwarg.getAssignable();
String argName = ((INameNode) kasgn).getName();
Variable av = getNewLocalVariable(argName, 0);
4 changes: 2 additions & 2 deletions core/src/main/java/org/jruby/parser/RubyParser.java
Original file line number Diff line number Diff line change
@@ -3680,7 +3680,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
Node body = ((Node)yyVals[-1+yyTop]);
if (body == null) body = NilImplicitNode.NIL;

yyVal = new DefnNode(((ISourcePosition)yyVals[-5+yyTop]), new ArgumentNode(((ISourcePosition)yyVals[-5+yyTop]), ((String)yyVals[-4+yyTop])), (ArgsNode) yyVals[-2+yyTop], support.getCurrentScope(), body);
yyVal = new DefnNode(((ISourcePosition)yyVals[-5+yyTop]), ((String)yyVals[-4+yyTop]), (ArgsNode) yyVals[-2+yyTop], support.getCurrentScope(), body);
support.popCurrentScope();
support.setInDef(false);
return yyVal;
@@ -3705,7 +3705,7 @@ public Object yyparse (RubyLexer yyLex) throws java.io.IOException {
Node body = ((Node)yyVals[-1+yyTop]);
if (body == null) body = NilImplicitNode.NIL;

yyVal = new DefsNode(((ISourcePosition)yyVals[-8+yyTop]), ((Node)yyVals[-7+yyTop]), new ArgumentNode(((ISourcePosition)yyVals[-8+yyTop]), ((String)yyVals[-4+yyTop])), (ArgsNode) yyVals[-2+yyTop], support.getCurrentScope(), body);
yyVal = new DefsNode(((ISourcePosition)yyVals[-8+yyTop]), ((Node)yyVals[-7+yyTop]), ((String)yyVals[-4+yyTop]), (ArgsNode) yyVals[-2+yyTop], support.getCurrentScope(), body);
support.popCurrentScope();
support.setInSingle(support.getInSingle() - 1);
return yyVal;
Loading