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 java.lang.reflect.Method; 014import java.lang.reflect.Parameter; 015import java.lang.invoke.MethodHandle; 016import java.util.Arrays; 017import java.util.List; 018import java.util.Collections; 019 020import static java.util.stream.Collectors.toList; 021import static gololang.Messages.message; 022import static java.lang.invoke.MethodHandles.permuteArguments; 023 024public final class NamedArgumentsHelper { 025 026 private NamedArgumentsHelper() { 027 // utility class 028 } 029 030 public static Boolean hasNamedParameters(Method method) { 031 return Arrays.stream(method.getParameters()).allMatch(Parameter::isNamePresent); 032 } 033 034 public static List<String> getParameterNames(Method method) { 035 if (hasNamedParameters(method)) { 036 return Arrays.stream(method.getParameters()) 037 .map(Parameter::getName) 038 .collect(toList()); 039 } 040 return Collections.emptyList(); 041 } 042 043 public static void checkArgumentPosition(int position, String argument, String declaration) { 044 if (position == -1) { 045 throw new IllegalArgumentException(message("invalid_argument_name", argument, declaration)); 046 } 047 } 048 049 public static int[] getArgumentsOrder(String methodName, List<String> parameterNames, String[] argumentNames, int nameOffset, int orderOffset) { 050 int[] argumentsOrder = new int[parameterNames.size() + orderOffset]; 051 for (int i = 0; i <= orderOffset; i++) { 052 argumentsOrder[i] = i; 053 } 054 for (int i = 0; i < argumentNames.length; i++) { 055 int actualPosition = parameterNames.indexOf(argumentNames[i]); 056 checkArgumentPosition(actualPosition, argumentNames[i], methodName + parameterNames); 057 argumentsOrder[actualPosition + orderOffset] = i + nameOffset; 058 } 059 return argumentsOrder; 060 } 061 062 public static MethodHandle reorderArguments(String methodName, List<String> parameterNames, MethodHandle handle, String[] argumentNames, int nameOffset, int orderOffset) { 063 if (argumentNames.length == 0) { return handle; } 064 if (parameterNames.isEmpty()) { 065 Warnings.noParameterNames(methodName, argumentNames); 066 return handle; 067 } 068 return permuteArguments(handle, handle.type(), getArgumentsOrder(methodName, parameterNames, argumentNames, nameOffset, orderOffset)); 069 } 070 071}