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 java.lang.reflect.Member; 013import java.lang.reflect.Field; 014import java.lang.reflect.Method; 015import java.lang.reflect.Constructor; 016import java.util.stream.Stream; 017import java.lang.reflect.Modifier; 018import java.util.function.Predicate; 019 020import static org.eclipse.golo.runtime.TypeMatching.argumentsNumberMatches; 021import static org.eclipse.golo.runtime.DecoratorsHelper.isMethodDecorated; 022 023public final class Extractors { 024 private Extractors() { 025 throw new UnsupportedOperationException("don't instantiate"); 026 } 027 028 public static Stream<Constructor<?>> getConstructors(Class<?> klass) { 029 if (klass == null) { 030 return Stream.empty(); 031 } 032 return Stream.of(klass.getConstructors()); 033 } 034 035 public static Stream<Method> getMethods(Class<?> klass) { 036 if (klass == null) { 037 return Stream.empty(); 038 } 039 return Stream.concat( 040 Stream.of(klass.getDeclaredMethods()), 041 Stream.of(klass.getMethods())) 042 .distinct() 043 .sorted((m1, m2) -> { 044 if (m1.isVarArgs() && !m2.isVarArgs()) { 045 return 1; 046 } 047 if (m2.isVarArgs() && !m1.isVarArgs()) { 048 return -1; 049 } 050 return 0; 051 }); 052 } 053 054 public static Stream<Field> getFields(Class<?> klass) { 055 if (klass == null) { 056 return Stream.empty(); 057 } 058 return Stream.concat( 059 Stream.of(klass.getDeclaredFields()), 060 Stream.of(klass.getFields())) 061 .distinct(); 062 } 063 064 public static Stream<String> getImportedNames(Class<?> klass) { 065 if (klass == null) { 066 return Stream.empty(); 067 } 068 return Stream.of(Module.imports(klass)); 069 } 070 071 public static Stream<Member> getMembers(Class<?> klass) { 072 if (klass == null) { 073 return Stream.empty(); 074 } 075 return Stream.concat(getMethods(klass), getFields(klass)); 076 } 077 078 public static boolean isPublic(Member m) { 079 return Modifier.isPublic(m.getModifiers()); 080 } 081 082 public static boolean isStatic(Member m) { 083 return Modifier.isStatic(m.getModifiers()); 084 } 085 086 public static boolean isConcrete(Member m) { 087 return !Modifier.isAbstract(m.getModifiers()); 088 } 089 090 public static Predicate<Member> isNamed(String name) { 091 return m -> m.getName().equals(name); 092 } 093 094 public static Predicate<Method> matchFunctionReference(String name, int arity, boolean varargs) { 095 return m -> 096 m.getName().equals(name) 097 && (isMethodDecorated(m) || argumentsNumberMatches(m.getParameterCount(), arity, varargs)) 098 && (arity < 0 || m.isVarArgs() == varargs); 099 } 100 101}