<commit_before>package org.dynalang.dynalink.beans;

import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.dynalang.dynalink.DynamicLinker;
import org.dynalang.dynalink.DynamicLinkerFactory;
import org.dynalang.dynalink.MonomorphicCallSite;
import org.dynalang.dynalink.NoSuchDynamicMethodException;
import org.dynalang.dynalink.support.CallSiteDescriptorFactory;

import junit.framework.TestCase;

public class TestCompositeOperations extends TestCase {

    public void testGetElemPropMethodOnMap() throws Throwable {
        final String op = "dyn:getElem|getProp|getMethod";
        final Map<String, Object> map = new HashMap<>();
        assertNull(invokeBoth(op, map, "foo"));
        assertEquals(true, invokeBoth(op, map, "empty"));
        assertSame(getDynamicMethod(HashMap.class, "size"), invokeBoth(op, map, "size"));
        map.put("foo", "bar");
        assertSame("bar", invokeBoth(op, map, "foo"));
        map.put("empty", "xyz");
        assertSame("xyz", invokeBoth(op, map, "empty"));
        map.put("size", "abc");
        assertSame("abc", invokeBoth(op, map, "size"));
    }

    public static class HashMapWithProperty extends HashMap<Object, Object> {
        private Object color;

        public void setColor(Object color) {
            this.color = color;
        }

        public Object getColor() {
            return color;
        }
    }

    public void testSetElemPropOnMap() throws Throwable {
        final String op = "dyn:setElem|setProp";
        final HashMapWithProperty map = new HashMapWithProperty();
        invoke(op, map, "color", "foo");
        assertSame("foo", map.get("color"));
        invokeFixedKey(op, map, "color", "bar");
        assertSame("bar", map.get("color"));
        assertNull(map.getColor());
    }

    public void testSetPropElemOnMap() throws Throwable {
        final String op = "dyn:setProp|setElem";
        final HashMapWithProperty map = new HashMapWithProperty();

        invoke(op, map, "color", "foo");
        assertNull(map.get("color"));
        assertSame("foo", map.getColor());

        invokeFixedKey(op, map, "color", "bar");
        assertNull(map.get("color"));
        assertSame("bar", map.getColor());

        invoke(op, map, "shape", "baz");
        assertSame("baz", map.get("shape"));
        invokeFixedKey(op, map, "shape", "bay");
        assertSame("bay", map.get("shape"));

        assertSame("bar", map.getColor());
    }

    public static class ArrayListWithProperty extends ArrayList<Object> {
        private Object color;

        public void setColor(Object color) {
            this.color = color;
        }

        public Object getColor() {
            return color;
        }
    }

    public void testSetElemPropOnList() throws Throwable {
        final String op = "dyn:setElem|setProp";
        final ArrayListWithProperty list = new ArrayListWithProperty();
        invoke(op, list, "color", "foo1");
        assertSame("foo1", list.getColor());
        invokeFixedKey(op, list, "color", "foo2");
        assertSame("foo2", list.getColor());
        list.add("elem0");
        invoke(op, list, 0, "elem0-changed1");
        assertSame("elem0-changed1", list.get(0));
        invokeFixedKey(op, list, 0, "elem0-changed2");
        assertSame("elem0-changed2", list.get(0));
    }

    public void testSetPropElemOnList() throws Throwable {
        final String op = "dyn:setProp|setElem";
        final ArrayListWithProperty list = new ArrayListWithProperty();
        invoke(op, list, "color", "foo1");
        assertSame("foo1", list.getColor());
        invokeFixedKey(op, list, "color", "foo2");
        assertSame("foo2", list.getColor());
        list.add("elem0");
        invoke(op, list, 0, "elem0-changed1");
        assertSame("elem0-changed1", list.get(0));
        invokeFixedKey(op, list, 0, "elem0-changed2");
        assertSame("elem0-changed2", list.get(0));
    }

    public void testGetElemPropMethodOnList() throws Throwable {
        final String op = "dyn:getElem|getProp|getMethod";
        final List<Object> list = new ArrayList<>();

        // As the key is fixed at link time, an IndexOutOfBoundsException is expected
        try {
            invokeFixedKey(op, list, 0);
            fail();
        } catch(IndexOutOfBoundsException e) {
        }
        // OTOH, if the key is not fixed, we'll just fall back through all of the alternatives and return null.
        // TODO: figure out if this is the desired behavior.
        assertNull(invoke(op, list, 0));


        // We can decide with 100% certainty that there's neither an element, property, nor method named "foo" at link
        // time.
        try {
            invokeFixedKey(op, list, "foo");
            fail();
        } catch(NoSuchDynamicMethodException e) {
            // This is expected
        }
        assertNull(invoke(op, list, "foo"));

        assertEquals(true, invokeBoth(op, list, "empty"));
        assertSame(getDynamicMethod(ArrayList.class, "size"), invokeBoth(op, list, "size"));
        list.add("bar");
        assertSame("bar", invokeBoth(op, list, 0));
    }

    public void testGetElemPropMethodOnArray() throws Throwable {
        final String op = "dyn:getElem|getProp|getMethod";<commit_msg>Throw IndexOutOfBoundsException when appropriate<commit_after>package org.dynalang.dynalink.beans;

import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.dynalang.dynalink.DynamicLinker;
import org.dynalang.dynalink.DynamicLinkerFactory;
import org.dynalang.dynalink.MonomorphicCallSite;
import org.dynalang.dynalink.NoSuchDynamicMethodException;
import org.dynalang.dynalink.support.CallSiteDescriptorFactory;

import junit.framework.TestCase;

public class TestCompositeOperations extends TestCase {

    public void testGetElemPropMethodOnMap() throws Throwable {
        final String op = "dyn:getElem|getProp|getMethod";
        final Map<String, Object> map = new HashMap<>();
        assertNull(invokeBoth(op, map, "foo"));
        assertEquals(true, invokeBoth(op, map, "empty"));
        assertSame(getDynamicMethod(HashMap.class, "size"), invokeBoth(op, map, "size"));
        map.put("foo", "bar");
        assertSame("bar", invokeBoth(op, map, "foo"));
        map.put("empty", "xyz");
        assertSame("xyz", invokeBoth(op, map, "empty"));
        map.put("size", "abc");
        assertSame("abc", invokeBoth(op, map, "size"));
    }

    public static class HashMapWithProperty extends HashMap<Object, Object> {
        private Object color;

        public void setColor(Object color) {
            this.color = color;
        }

        public Object getColor() {
            return color;
        }
    }

    public void testSetElemPropOnMap() throws Throwable {
        final String op = "dyn:setElem|setProp";
        final HashMapWithProperty map = new HashMapWithProperty();
        invoke(op, map, "color", "foo");
        assertSame("foo", map.get("color"));
        invokeFixedKey(op, map, "color", "bar");
        assertSame("bar", map.get("color"));
        assertNull(map.getColor());
    }

    public void testSetPropElemOnMap() throws Throwable {
        final String op = "dyn:setProp|setElem";
        final HashMapWithProperty map = new HashMapWithProperty();

        invoke(op, map, "color", "foo");
        assertNull(map.get("color"));
        assertSame("foo", map.getColor());

        invokeFixedKey(op, map, "color", "bar");
        assertNull(map.get("color"));
        assertSame("bar", map.getColor());

        invoke(op, map, "shape", "baz");
        assertSame("baz", map.get("shape"));
        invokeFixedKey(op, map, "shape", "bay");
        assertSame("bay", map.get("shape"));

        assertSame("bar", map.getColor());
    }

    public static class ArrayListWithProperty extends ArrayList<Object> {
        private Object color;

        public void setColor(Object color) {
            this.color = color;
        }

        public Object getColor() {
            return color;
        }
    }

    public void testSetElemPropOnList() throws Throwable {
        final String op = "dyn:setElem|setProp";
        final ArrayListWithProperty list = new ArrayListWithProperty();
        invoke(op, list, "color", "foo1");
        assertSame("foo1", list.getColor());
        invokeFixedKey(op, list, "color", "foo2");
        assertSame("foo2", list.getColor());
        list.add("elem0");
        invoke(op, list, 0, "elem0-changed1");
        assertSame("elem0-changed1", list.get(0));
        invokeFixedKey(op, list, 0, "elem0-changed2");
        assertSame("elem0-changed2", list.get(0));
    }

    public void testSetPropElemOnList() throws Throwable {
        final String op = "dyn:setProp|setElem";
        final ArrayListWithProperty list = new ArrayListWithProperty();
        invoke(op, list, "color", "foo1");
        assertSame("foo1", list.getColor());
        invokeFixedKey(op, list, "color", "foo2");
        assertSame("foo2", list.getColor());
        list.add("elem0");
        invoke(op, list, 0, "elem0-changed1");
        assertSame("elem0-changed1", list.get(0));
        invokeFixedKey(op, list, 0, "elem0-changed2");
        assertSame("elem0-changed2", list.get(0));
    }

    public void testGetElemPropMethodOnList() throws Throwable {
        final String op = "dyn:getElem|getProp|getMethod";
        final List<Object> list = new ArrayList<>();

        // As the key is fixed at link time, an IndexOutOfBoundsException is expected
        try {
            invokeFixedKey(op, list, 0);
            fail();
        } catch(IndexOutOfBoundsException e) {
        }
        try {
            invoke(op, list, 0);
            fail();
        } catch(IndexOutOfBoundsException e) {
        }


        // We can decide with 100% certainty that there's neither an element, property, nor method named "foo" at link
        // time.
        try {
            invokeFixedKey(op, list, "foo");
            fail();
        } catch(NoSuchDynamicMethodException e) {
            // This is expected
        }
        assertNull(invoke(op, list, "foo"));

        assertEquals(true, invokeBoth(op, list, "empty"));
        assertSame(getDynamicMethod(ArrayList.class, "size"), invokeBoth(op, list, "size"));
        list.add("bar");
        assertSame("bar", invokeBoth(op, list, 0));
    }

    public void testGetElemPropMethodOnArray() throws Throwable {
        final String op = "dyn:getElem|getProp|getMethod";
{'fraction_non_alphanumeric': 0.1340911191202292, 'fraction_numerical': 0.007393032067276592, 'mean_word_length': 2.8760744985673354, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1695462', 'n_tokens_mistral': 3164, 'n_tokens_neox': 3070, 'n_words': 752}