final MultipleAsgnNode multipleAsgnNode = (MultipleAsgnNode) node; // normal items at the "head" of the masgn ArrayCallback headAssignCallback = new ArrayCallback() { public void nextValue(BodyCompiler context, Object sourceArray, int index) { ListNode headNode = (ListNode) sourceArray; Node assignNode = headNode.get(index); // perform assignment for the next node compileAssignment(assignNode, context, false); } }; CompilerCallback argsCallback = new CompilerCallback() { public void call(BodyCompiler context) { Node argsNode = multipleAsgnNode.getArgsNode(); if (argsNode instanceof StarNode) { // done processing args context.consumeCurrentValue(); } else { // assign to appropriate variable compileAssignment(argsNode, context, false); } } }; if (multipleAsgnNode.getHeadNode() == null) { if (multipleAsgnNode.getArgsNode() == null) { throw new NotCompilableException("Something's wrong, multiple assignment with no head or args at: " + multipleAsgnNode.getPosition()); } else { if (multipleAsgnNode.getArgsNode() instanceof StarNode) { // do nothing } else { context.ensureMultipleAssignableRubyArray(multipleAsgnNode.getHeadNode() != null); context.forEachInValueArray(0, 0, null, null, argsCallback); } } } else { context.ensureMultipleAssignableRubyArray(multipleAsgnNode.getHeadNode() != null); if (multipleAsgnNode.getArgsNode() == null) { context.forEachInValueArray(0, multipleAsgnNode.getHeadNode().size(), multipleAsgnNode.getHeadNode(), headAssignCallback, null); } else { context.forEachInValueArray(0, multipleAsgnNode.getHeadNode().size(), multipleAsgnNode.getHeadNode(), headAssignCallback, argsCallback); } } // TODO: don't require pop if (!expr) context.consumeCurrentValue();
final MultipleAsgn19Node multipleAsgn19Node = (MultipleAsgn19Node) node; // normal items at the front or back of the masgn ArrayCallback preAssignCallback = new ArrayCallback() { public void nextValue(BodyCompiler context, Object sourceArray, int index) { ListNode nodes = (ListNode) sourceArray; Node assignNode = nodes.get(index); // perform assignment for the next node compileAssignment(assignNode, context, false); } }; CompilerCallback restCallback = new CompilerCallback() { public void call(BodyCompiler context) { Node argsNode = multipleAsgn19Node.getRest(); if (argsNode instanceof StarNode) { // done processing args context.consumeCurrentValue(); } else { // assign to appropriate variable compileAssignment(argsNode, context, false); } } }; if (multipleAsgn19Node.getPreCount() == 0 && multipleAsgn19Node.getPostCount() == 0) { if (multipleAsgn19Node.getRest() == null) { throw new NotCompilableException("Something's wrong, multiple assignment with no head or args at: " + multipleAsgn19Node.getPosition()); } else { if (multipleAsgn19Node.getRest() instanceof StarNode) { // do nothing } else { context.ensureMultipleAssignableRubyArray(multipleAsgn19Node.getPreCount() != 0 || multipleAsgn19Node.getPostCount() != 0); context.forEachInValueArray(0, 0, null, null, restCallback); } } } else { context.ensureMultipleAssignableRubyArray(multipleAsgn19Node.getPreCount() != 0 || multipleAsgn19Node.getPostCount() != 0); if (multipleAsgn19Node.getRest() == null) { context.forEachInValueArray(0, multipleAsgn19Node.getPreCount(), multipleAsgn19Node.getPre(), multipleAsgn19Node.getPostCount(), multipleAsgn19Node.getPost(), preAssignCallback, null); } else { context.forEachInValueArray(0, multipleAsgn19Node.getPreCount(), multipleAsgn19Node.getPre(), multipleAsgn19Node.getPostCount(), multipleAsgn19Node.getPost(), preAssignCallback, restCallback); } } // TODO: don't require pop if (!expr) context.consumeCurrentValue();
Clone fragments detected by clone detection tool
File path: /jruby-1.4.0/src/org/jruby/compiler/ASTCompiler.java File path: /jruby-1.4.0/src/org/jruby/compiler/ASTCompiler19.java
Method name: void compileMultipleAsgnAssignment(Node, BodyCompiler, boolean) Method name: void compileMultipleAsgn19Assignment(Node, BodyCompiler, boolean)
Number of AST nodes: 15 Number of AST nodes: 15
1
final MultipleAsgnNode multipleAsgnNode = (MultipleAsgnNode) node;
1
final MultipleAsgn19Node multipleAsgn19Node = (MultipleAsgn19Node) node;
2
        // normal items at the "head" of the masgn
2
        // normal items at the front or back of the masgn
3
        ArrayCallback headAssignCallback = new ArrayCallback() {
3
        ArrayCallback preAssignCallback = new ArrayCallback() {
4
                    public void nextValue(BodyCompiler context, Object sourceArray,
4
                    public void nextValue(BodyCompiler context, Object sourceArray,
5
                            int index) {
5
                            int index) {
6
                        ListNode headNode = (ListNode) sourceArray;
6
                        ListNode nodes = (ListNode) sourceArray;
7
                        Node assignNode = headNode.get(index);
7
                        Node assignNode = nodes.get(index);
8
                        // perform assignment for the next node
8
                        // perform assignment for the next node
9
                        compileAssignment(assignNode, context, false);
9
                        compileAssignment(assignNode, context, false);
10
                    }
10
                    }
11
                };
11
                };
12
        CompilerCallback argsCallback = new CompilerCallback() {
12
        CompilerCallback restCallback = new CompilerCallback() {
13
                    public void call(BodyCompiler context) {
13
                    public void call(BodyCompiler context) {
14
                        Node argsNode = multipleAsgnNode.getArgsNode();
14
                        Node argsNode = multipleAsgn19Node.getRest();
15
                        if (argsNode instanceof StarNode) {
15
                        if (argsNode instanceof StarNode) {
16
                            // done processing args
16
                            // done processing args
17
                            context.consumeCurrentValue();
17
                            context.consumeCurrentValue();
18
                        } else {
18
                        } else {
19
                            // assign to appropriate variable
19
                            // assign to appropriate variable
20
                            compileAssignment(argsNode, context, false);
20
                            compileAssignment(argsNode, context, false);
21
                        }
21
                        }
22
                    }
22
                    }
23
                };
23
                };
24
        if (multipleAsgnNode.getHeadNode() == null) {
24
        if (multipleAsgn19Node.getPreCount() == 0 && multipleAsgn19Node.getPostCount() == 0) {
25
            if (multipleAsgnNode.getArgsNode() == null) {
25
            if (multipleAsgn19Node.getRest() == null) {
26
                throw new NotCompilableException("Something's wrong, multiple assignment with no head or args at: " + multipleAsgnNode.getPosition());
26
                throw new NotCompilableException("Something's wrong, multiple assignment with no head or args at: " + multipleAsgn19Node.getPosition());
27
            } else {
27
            } else {
28
                if (multipleAsgnNode.getArgsNode() instanceof StarNode) {
28
                if (multipleAsgn19Node.getRest() instanceof StarNode) {
29
                    // do nothing
29
                    // do nothing
30
                } else {
30
                } else {
31
                    context.ensureMultipleAssignableRubyArray(multipleAsgnNode.getHeadNode() != null);
31
                    context.ensureMultipleAssignableRubyArray(multipleAsgn19Node.getPreCount() != 0 || multipleAsgn19Node.getPostCount() != 0);
32
                    context.forEachInValueArray(0, 0, null, null, argsCallback);
32
                    context.forEachInValueArray(0, 0, null, null, restCallback);
33
                }
33
                }
34
            }
34
            }
35
        } else {
35
        } else {
36
            context.ensureMultipleAssignableRubyArray(multipleAsgnNode.getHeadNode() != null);
36
            context.ensureMultipleAssignableRubyArray(multipleAsgn19Node.get
37
            
37
PreCount() != 0 || multipleAsgn19Node.getPostCount() != 0);
38
            if (multipleAsgnNode.getArgsNode() == null) {
38
            if (multipleAsgn19Node.getRest() == null) {
39
                context.forEachInValueArray(0, multipleAsgnNode.getHeadNode().size(), multipleAsgnNode.getHeadNode(), headAssignCallback, null);
39
                context.forEachInValueArray(0, multipleAsgn19Node.getPreCount(), multipleAsgn19Node.getPre(), multipleAsgn19Node.getPostCount(), multipleAsgn19Node.getPost(), preAssignCallback, null);
40
            } else {
40
            } else {
41
                context.forEachInValueArray(0, multipleAsgnNode.getHeadNode().size(), multipleAsgnNode.getHeadNode(), headAssignCallback, argsCallback);
41
                context.forEachInValueArray(0, multipleAsgn19Node.getPreCount(), multipleAsgn19Node.getPre(), multipleAsgn19Node.getPostCount(), multipleAsgn19Node.getPost(), preAssignCallback, restCallback);
42
            }
42
            }
43
        }
43
        }
44
        // TODO: don't require pop
44
        // TODO: don't require pop
45
        if (!expr) context.consumeCurrentValue();
45
        if (!expr) context.consumeCurrentValue();
Summary
Number of common nesting structure subtrees2
Number of refactorable cases1
Number of non-refactorable cases1
Time elapsed for finding largest common nesting structure subtrees (ms)2.4
Clones locationClones are in different classes having the same super class
Number of node comparisons26
  1. {Refactorable}
    Mapping Summary
    Number of mapped statements4
    Number of unmapped statements in the first code fragment1
    Number of unmapped statements in the second code fragment1
    Time elapsed for statement mapping (ms)9.8
    Clone typeType 2
    Mapped Statements
    ID Statement ID Statement
    5
    if (multipleAsgnNode.getArgsNode() == null)
    5
    if (multipleAsgnNode.getArgsNode() == null)
    5
    if (multipleAsgn19Node.getRest() == null)
    Differences
    Expression1Expression2Difference
    getArgsNodegetRestMETHOD_INVOCATION_NAME_MISMATCH
    multipleAsgnNodemultipleAsgn19NodeVARIABLE_NAME_MISMATCH
    org.jruby.ast.MultipleAsgnNodeorg.jruby.ast.MultipleAsgn19NodeSUBCLASS_TYPE_MISMATCH
    5
    if (multipleAsgn19Node.getRest() == null)
    6
    throw new NotCompilableException("Something's wrong, multiple assignment with no head or args at: " + multipleAsgnNode.getPosition());
    6
    throw new NotCompilableException("Something's wrong, multiple assignment with no head or args at: " + multipleAsgnNode.getPosition());
    6
    throw new NotCompilableException("Something's wrong, multiple assignment with no head or args at: " + multipleAsgn19Node.getPosition());
    Differences
    Expression1Expression2Difference
    multipleAsgnNodemultipleAsgn19NodeVARIABLE_NAME_MISMATCH
    org.jruby.ast.MultipleAsgnNodeorg.jruby.ast.MultipleAsgn19NodeSUBCLASS_TYPE_MISMATCH
    6
    throw new NotCompilableException("Something's wrong, multiple assignment with no head or args at: " + multipleAsgn19Node.getPosition());
    else
    else
    7
    if (multipleAsgnNode.getArgsNode() instanceof StarNode)
    7
    if (multipleAsgnNode.getArgsNode() instanceof StarNode)
    7
    if (multipleAsgn19Node.getRest() instanceof StarNode)
    Differences
    Expression1Expression2Difference
    getArgsNodegetRestMETHOD_INVOCATION_NAME_MISMATCH
    multipleAsgnNodemultipleAsgn19NodeVARIABLE_NAME_MISMATCH
    org.jruby.ast.MultipleAsgnNodeorg.jruby.ast.MultipleAsgn19NodeSUBCLASS_TYPE_MISMATCH
    7
    if (multipleAsgn19Node.getRest() instanceof StarNode)
    else
    else
                                                                                                                                                                                                                                                                
    8
    context.ensureMultipleAssignableRubyArray(multipleAsgn19Node.getPreCount() != 0 || multipleAsgn19Node.getPostCount() != 0);
    8
    context.ensureMultipleAssignableRubyArray(multipleAsgnNode.getHeadNode() != null);
                                                                                                                                                                              
    9
    context.forEachInValueArray(0, 0, null, null, argsCallback);
    9
    context.forEachInValueArray(0, 0, null, null, argsCallback);
    9
    context.forEachInValueArray(0, 0, null, null, restCallback);
    Differences
    Expression1Expression2Difference
    argsCallbackrestCallbackVARIABLE_NAME_MISMATCH
    9
    context.forEachInValueArray(0, 0, null, null, restCallback);
    Precondition Violations (0)
    Row Violation
  1. {Non-refactorable}
    Mapping Summary
    Number of mapped statements3
    Number of unmapped statements in the first code fragment1
    Number of unmapped statements in the second code fragment1
    Time elapsed for statement mapping (ms)5.7
    Clone typeType 2
    Mapped Statements
    ID Statement ID Statement
                                                                                                                                                                                                                                                                  
    10
    context.ensureMultipleAssignableRubyArray(multipleAsgn19Node.getPreCount() != 0 || multipleAsgn19Node.getPostCount() != 0);
    10
    context.ensureMultipleAssignableRubyArray(multipleAsgnNode.getHeadNode() != null);
                                                                                                                                                                                
    11
    if (multipleAsgnNode.getArgsNode() == null)
    11
    if (multipleAsgnNode.getArgsNode() == null)
    11
    if (multipleAsgn19Node.getRest() == null)
    Differences
    Expression1Expression2Difference
    getArgsNodegetRestMETHOD_INVOCATION_NAME_MISMATCH
    multipleAsgnNodemultipleAsgn19NodeVARIABLE_NAME_MISMATCH
    org.jruby.ast.MultipleAsgnNodeorg.jruby.ast.MultipleAsgn19NodeSUBCLASS_TYPE_MISMATCH
    11
    if (multipleAsgn19Node.getRest() == null)
    12
    context.forEachInValueArray(0, multipleAsgnNode.getHeadNode().size(), multipleAsgnNode.getHeadNode(), headAssignCallback, null);
    12
    context.forEachInValueArray(0, multipleAsgnNode.getHeadNode().size(), multipleAsgnNode.getHeadNode(), headAssignCallback, null);
    12
    context.forEachInValueArray(0, multipleAsgn19Node.getPreCount(), multipleAsgn19Node.getPre(), multipleAsgn19Node.getPostCount(), multipleAsgn19Node.getPost(), preAssignCallback, null);
    Differences
    Expression1Expression2Difference
    context.forEachInValueArray(0,multipleAsgnNode.getHeadNode().size(),multipleAsgnNode.getHeadNode(),headAssignCallback,null)context.forEachInValueArray(0,multipleAsgn19Node.getPreCount(),multipleAsgn19Node.getPre(),multipleAsgn19Node.getPostCount(),multipleAsgn19Node.getPost(),preAssignCallback,null)ARGUMENT_NUMBER_MISMATCH
    Preondition Violations
    Expression context.forEachInValueArray(0,multipleAsgnNode.getHeadNode().size(),multipleAsgnNode.getHeadNode(),headAssignCallback,null) is a void method call, and thus it cannot be parameterized
    Expression context.forEachInValueArray(0,multipleAsgn19Node.getPreCount(),multipleAsgn19Node.getPre(),multipleAsgn19Node.getPostCount(),multipleAsgn19Node.getPost(),preAssignCallback,null) is a void method call, and thus it cannot be parameterized
    12
    context.forEachInValueArray(0, multipleAsgn19Node.getPreCount(), multipleAsgn19Node.getPre(), multipleAsgn19Node.getPostCount(), multipleAsgn19Node.getPost(), preAssignCallback, null);
    else
    else
    13
    context.forEachInValueArray(0, multipleAsgnNode.getHeadNode().size(), multipleAsgnNode.getHeadNode(), headAssignCallback, argsCallback);
    13
    context.forEachInValueArray(0, multipleAsgnNode.getHeadNode().size(), multipleAsgnNode.getHeadNode(), headAssignCallback, argsCallback);
    13
    context.forEachInValueArray(0, multipleAsgn19Node.getPreCount(), multipleAsgn19Node.getPre(), multipleAsgn19Node.getPostCount(), multipleAsgn19Node.getPost(), preAssignCallback, restCallback);
    Differences
    Expression1Expression2Difference
    context.forEachInValueArray(0,multipleAsgnNode.getHeadNode().size(),multipleAsgnNode.getHeadNode(),headAssignCallback,argsCallback)context.forEachInValueArray(0,multipleAsgn19Node.getPreCount(),multipleAsgn19Node.getPre(),multipleAsgn19Node.getPostCount(),multipleAsgn19Node.getPost(),preAssignCallback,restCallback)ARGUMENT_NUMBER_MISMATCH
    Preondition Violations
    Expression context.forEachInValueArray(0,multipleAsgnNode.getHeadNode().size(),multipleAsgnNode.getHeadNode(),headAssignCallback,argsCallback) is a void method call, and thus it cannot be parameterized
    Expression context.forEachInValueArray(0,multipleAsgn19Node.getPreCount(),multipleAsgn19Node.getPre(),multipleAsgn19Node.getPostCount(),multipleAsgn19Node.getPost(),preAssignCallback,restCallback) is a void method call, and thus it cannot be parameterized
    13
    context.forEachInValueArray(0, multipleAsgn19Node.getPreCount(), multipleAsgn19Node.getPre(), multipleAsgn19Node.getPostCount(), multipleAsgn19Node.getPost(), preAssignCallback, restCallback);
    Precondition Violations (4)
    Row Violation
    1Expression context.forEachInValueArray(0,multipleAsgnNode.getHeadNode().size(),multipleAsgnNode.getHeadNode(),headAssignCallback,null) is a void method call, and thus it cannot be parameterized
    2Expression context.forEachInValueArray(0,multipleAsgn19Node.getPreCount(),multipleAsgn19Node.getPre(),multipleAsgn19Node.getPostCount(),multipleAsgn19Node.getPost(),preAssignCallback,null) is a void method call, and thus it cannot be parameterized
    3Expression context.forEachInValueArray(0,multipleAsgnNode.getHeadNode().size(),multipleAsgnNode.getHeadNode(),headAssignCallback,argsCallback) is a void method call, and thus it cannot be parameterized
    4Expression context.forEachInValueArray(0,multipleAsgn19Node.getPreCount(),multipleAsgn19Node.getPre(),multipleAsgn19Node.getPostCount(),multipleAsgn19Node.getPost(),preAssignCallback,restCallback) is a void method call, and thus it cannot be parameterized