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