<commit_before>/*
 * Copyright (c) 2005 Your Corporation. All Rights Reserved.
 */
package com.intellij.util.xml.impl;

import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.WeakValueHashMap;
import com.intellij.util.xml.JavaMethodSignature;
import net.sf.cglib.proxy.AdvancedEnhancer;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Factory;
import net.sf.cglib.proxy.InvocationHandler;
import org.jetbrains.annotations.NotNull;

import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.Set;

/**
 * @author peter
 */
public class AdvancedProxy {
  private static final Map<ProxyDescription, Factory> ourFactories = new WeakValueHashMap<ProxyDescription, Factory>();
  private static final Map<Class, Constructor> ourConstructors = new WeakValueHashMap<Class, Constructor>();

  public static InvocationHandler getInvocationHandler(Object proxy) {
    return (InvocationHandler)((Factory) proxy).getCallback(0);
  }

  public static <T> T createProxy(final InvocationHandler handler, final Class<T> superClassOrInterface, final Class... otherInterfaces) {
    if (superClassOrInterface.isInterface()) {
      Class[] interfaces = new Class[otherInterfaces.length+1];
      interfaces [0] = superClassOrInterface;
      System.arraycopy(otherInterfaces, 0, interfaces, 1, otherInterfaces.length);
      return (T) createProxy(null, interfaces, handler, Collections.<JavaMethodSignature>emptySet());
    }
    return (T) createProxy(superClassOrInterface, otherInterfaces, handler, Collections.<JavaMethodSignature>emptySet());
  }

  public static <T> T createProxy(final Class<T> superClass,
                                  final Class[] interfaces,
                                  final InvocationHandler handler,
                                  final Set<JavaMethodSignature> additionalMethods,
                                  final Object... constructorArgs) {
    try {
      final Callback[] callbacks = new Callback[]{handler};

      final ProxyDescription key = new ProxyDescription(superClass, interfaces, additionalMethods);
      Factory factory = ourFactories.get(key);
      if (factory != null) {
        final Class<? extends Factory> aClass = factory.getClass();
        return (T) factory.newInstance(findConstructor(aClass, constructorArgs).getParameterTypes(), constructorArgs, callbacks);
      }

      //System.out.println("key = " + key);
      AdvancedEnhancer e = new AdvancedEnhancer();
      e.setAdditionalMethods(additionalMethods);
      e.setSuperclass(superClass);
      e.setInterfaces(interfaces);
      e.setCallbacks(callbacks);
      if (superClass != null) {
        factory = (Factory)e.create(findConstructor(superClass, constructorArgs).getParameterTypes(), constructorArgs);
      } else {
        assert constructorArgs.length == 0;
        factory = (Factory)e.create();
      }

      ourFactories.put(key, factory);
      return (T)factory;
    }
    catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  @NotNull
  private static Constructor findConstructor(final Class aClass, final Object... constructorArgs) {
    if (constructorArgs.length == 0) {
      try {
        Constructor constructor = ourConstructors.get(aClass);
        if (constructor == null) {
          constructor = aClass.getConstructor(ArrayUtil.EMPTY_CLASS_ARRAY);
          ourConstructors.put(aClass, constructor);
        }
        return constructor;
      }
      catch (NoSuchMethodException e) {
        throw new AssertionError("Cannot find constructor for arguments: " + Arrays.asList(constructorArgs));
      }
    }

    loop: for (final Constructor constructor : aClass.getDeclaredConstructors()) {
      final Class[] parameterTypes = constructor.getParameterTypes();
      if (parameterTypes.length == constructorArgs.length) {
        for (int i = 0; i < parameterTypes.length; i++) {
          Class parameterType = parameterTypes[i];
          final Object constructorArg = constructorArgs[i];
          if (!parameterType.isInstance(constructorArg) && constructorArg != null) {
            continue loop;
          }
        }
        return constructor;
      }
    }<commit_msg>diagnostics<commit_after>/*
 * Copyright (c) 2005 Your Corporation. All Rights Reserved.
 */
package com.intellij.util.xml.impl;

import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.WeakValueHashMap;
import com.intellij.util.xml.JavaMethodSignature;
import net.sf.cglib.proxy.AdvancedEnhancer;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Factory;
import net.sf.cglib.proxy.InvocationHandler;
import org.jetbrains.annotations.NotNull;

import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.Set;

/**
 * @author peter
 */
public class AdvancedProxy {
  private static final Map<ProxyDescription, Factory> ourFactories = new WeakValueHashMap<ProxyDescription, Factory>();
  private static final Map<Class, Constructor> ourConstructors = new WeakValueHashMap<Class, Constructor>();

  public static InvocationHandler getInvocationHandler(Object proxy) {
    return (InvocationHandler)((Factory) proxy).getCallback(0);
  }

  public static <T> T createProxy(final InvocationHandler handler, final Class<T> superClassOrInterface, final Class... otherInterfaces) {
    if (superClassOrInterface.isInterface()) {
      Class[] interfaces = new Class[otherInterfaces.length+1];
      interfaces [0] = superClassOrInterface;
      System.arraycopy(otherInterfaces, 0, interfaces, 1, otherInterfaces.length);
      return (T) createProxy(null, interfaces, handler, Collections.<JavaMethodSignature>emptySet());
    }
    return (T) createProxy(superClassOrInterface, otherInterfaces, handler, Collections.<JavaMethodSignature>emptySet());
  }

  public static <T> T createProxy(final Class<T> superClass,
                                  final Class[] interfaces,
                                  final InvocationHandler handler,
                                  final Set<JavaMethodSignature> additionalMethods,
                                  final Object... constructorArgs) {
    try {
      final Callback[] callbacks = new Callback[]{handler};

      final ProxyDescription key = new ProxyDescription(superClass, interfaces, additionalMethods);
      Factory factory = ourFactories.get(key);
      if (factory != null) {
        final Class<? extends Factory> aClass = factory.getClass();
        return (T) factory.newInstance(findConstructor(aClass, constructorArgs).getParameterTypes(), constructorArgs, callbacks);
      }

      //System.out.println("key = " + key);
      AdvancedEnhancer e = new AdvancedEnhancer();
      e.setAdditionalMethods(additionalMethods);
      e.setSuperclass(superClass);
      e.setInterfaces(interfaces);
      e.setCallbacks(callbacks);
      if (superClass != null) {
        factory = (Factory)e.create(findConstructor(superClass, constructorArgs).getParameterTypes(), constructorArgs);
      } else {
        assert constructorArgs.length == 0;
        factory = (Factory)e.create();
      }

      ourFactories.put(key, factory);
      return (T)factory;
    }
    catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  @NotNull
  private static Constructor findConstructor(final Class aClass, final Object... constructorArgs) {
    if (constructorArgs.length == 0) {
      try {
        Constructor constructor = ourConstructors.get(aClass);
        if (constructor == null) {
          constructor = aClass.getConstructor(ArrayUtil.EMPTY_CLASS_ARRAY);
          ourConstructors.put(aClass, constructor);
        }
        return constructor;
      }
      catch (NoSuchMethodException e) {
        throw new AssertionError("Cannot find constructor for arguments: " + Arrays.asList(constructorArgs) + " in class " + aClass);
      }
    }

    loop: for (final Constructor constructor : aClass.getDeclaredConstructors()) {
      final Class[] parameterTypes = constructor.getParameterTypes();
      if (parameterTypes.length == constructorArgs.length) {
        for (int i = 0; i < parameterTypes.length; i++) {
          Class parameterType = parameterTypes[i];
          final Object constructorArg = constructorArgs[i];
          if (!parameterType.isInstance(constructorArg) && constructorArg != null) {
            continue loop;
          }
        }
        return constructor;
      }
    }
{'fraction_non_alphanumeric': 0.10321369927281257, 'fraction_numerical': 0.0028149190710767065, 'mean_word_length': 3.2763289869608827, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6982184', 'n_tokens_mistral': 2285, 'n_tokens_neox': 2229, 'n_words': 527}