001/*
002 * Copyright (c) 2012-2017 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 */
009
010package org.eclipse.golo.runtime;
011
012import gololang.FunctionReference;
013
014import java.lang.invoke.*;
015import java.lang.reflect.Method;
016import java.lang.reflect.Parameter;
017
018import static java.lang.invoke.MethodHandles.constant;
019import static java.lang.invoke.MethodType.genericMethodType;
020
021public final class ClosureReferenceSupport {
022
023  private ClosureReferenceSupport() {
024    throw new UnsupportedOperationException("Don't instantiate invokedynamic bootstrap class");
025  }
026
027  public static CallSite bootstrap(MethodHandles.Lookup caller, String name, MethodType type, String moduleClass, int arity, int varargs) throws Throwable {
028    Class<?> module = caller.lookupClass().getClassLoader().loadClass(moduleClass);
029    Method function = module.getDeclaredMethod(name, genericMethodType(arity, varargs == 1).parameterArray());
030    function.setAccessible(true);
031    return new ConstantCallSite(constant(
032          FunctionReference.class,
033          new FunctionReference(caller.unreflect(function), parameterNames(function))));
034  }
035
036  private static String[] parameterNames(Method function) {
037    Parameter[] parameters = function.getParameters();
038    String[] parameterNames = new String[parameters.length];
039    for (int i = 0; i < parameters.length; i++) {
040      parameterNames[i] = parameters[i].getName();
041    }
042    return parameterNames;
043  }
044
045}