diff options
author | Jesse Wilson <jessewilson@google.com> | 2010-01-13 17:12:18 -0800 |
---|---|---|
committer | Jesse Wilson <jessewilson@google.com> | 2010-01-13 17:12:18 -0800 |
commit | f062bf49c71013ec19cb71218778299535aceaa8 (patch) | |
tree | 17acfe2a694f55828f64caaae4c25179e61525a8 /src/com/google/caliper/Parameter.java | |
parent | 1440b36663f61ebde1952d91b4a1f4c1a27fcefa (diff) | |
download | caliper-f062bf49c71013ec19cb71218778299535aceaa8.tar.gz |
Update Caliper to r71.
Diffstat (limited to 'src/com/google/caliper/Parameter.java')
-rw-r--r-- | src/com/google/caliper/Parameter.java | 95 |
1 files changed, 71 insertions, 24 deletions
diff --git a/src/com/google/caliper/Parameter.java b/src/com/google/caliper/Parameter.java index 1ba77b5..caca252 100644 --- a/src/com/google/caliper/Parameter.java +++ b/src/com/google/caliper/Parameter.java @@ -16,8 +16,19 @@ package com.google.caliper; -import java.lang.reflect.*; -import java.util.*; +import java.lang.reflect.Field; +import java.lang.reflect.Member; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumSet; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; /** * A parameter in a {@link SimpleBenchmark}. @@ -35,22 +46,35 @@ abstract class Parameter<T> { */ public static Map<String, Parameter<?>> forClass(Class<? extends Benchmark> suiteClass) { Map<String, Parameter<?>> parameters = new TreeMap<String, Parameter<?>>(); - for (final Field field : suiteClass.getDeclaredFields()) { + for (Field field : suiteClass.getDeclaredFields()) { if (field.isAnnotationPresent(Param.class)) { field.setAccessible(true); - Parameter parameter = Parameter.forField(suiteClass, field); + Parameter<?> parameter = forField(suiteClass, field); parameters.put(parameter.getName(), parameter); } } return parameters; } - public static Parameter forField( + private static Parameter<?> forField( Class<? extends Benchmark> suiteClass, final Field field) { - Parameter result = null; + // First check for String values on the annotation itself + final Object[] defaults = field.getAnnotation(Param.class).value(); + if (defaults.length > 0) { + return new Parameter<Object>(field) { + @Override public Collection<Object> values() throws Exception { + return Arrays.asList(defaults); + } + }; + // TODO: or should we continue so we can give an error/warning if params are also give in a + // method or field? + } + + Parameter<?> result = null; Type returnType = null; Member member = null; + // Now check for a fooValues() method try { final Method valuesMethod = suiteClass.getDeclaredMethod(field.getName() + "Values"); valuesMethod.setAccessible(true); @@ -58,13 +82,14 @@ abstract class Parameter<T> { returnType = valuesMethod.getGenericReturnType(); result = new Parameter<Object>(field) { @SuppressWarnings("unchecked") // guarded below - public Collection<Object> values() throws Exception { + @Override public Collection<Object> values() throws Exception { return (Collection<Object>) valuesMethod.invoke(null); } }; } catch (NoSuchMethodException ignored) { } + // Now check for a fooValues field try { final Field valuesField = suiteClass.getDeclaredField(field.getName() + "Values"); valuesField.setAccessible(true); @@ -75,36 +100,58 @@ abstract class Parameter<T> { returnType = valuesField.getGenericType(); result = new Parameter<Object>(field) { @SuppressWarnings("unchecked") // guarded below - public Collection<Object> values() throws Exception { + @Override public Collection<Object> values() throws Exception { return (Collection<Object>) valuesField.get(null); } }; } catch (NoSuchFieldException ignored) { } - if (result == null) { - throw new ConfigurationException("No values member defined for " + field); + if (member != null && !Modifier.isStatic(member.getModifiers())) { + throw new ConfigurationException("Values member must be static " + member); + } + + // If there isn't a values member but the parameter is an enum, we default + // to EnumSet.allOf. + if (member == null && field.getType().isEnum()) { + returnType = Collection.class; + result = new Parameter<Object>(field) { + // TODO: figure out the simplest way to make this compile and be green in IDEA too + @SuppressWarnings({"unchecked", "RawUseOfParameterizedType", "RedundantCast"}) + // guarded above + @Override public Collection<Object> values() throws Exception { + Set<Enum> set = EnumSet.allOf((Class<Enum>) field.getType()); + return (Collection) set; + } + }; } - if (!Modifier.isStatic(member.getModifiers())) { - throw new ConfigurationException("Values member must be static " + member); + if (result == null) { + return new Parameter<Object>(field) { + @Override public Collection<Object> values() { + // TODO: need tests to make sure this fails properly when no cmdline params given and + // works properly when they are given + return Collections.emptySet(); + } + }; + } else if (!isValidReturnType(returnType)) { + throw new ConfigurationException("Invalid return type " + returnType + + " for values member " + member + "; must be Collection"); } + return result; + } - // validate return type - boolean valid = false; + private static boolean isValidReturnType(Type returnType) { + if (returnType == Collection.class) { + return true; + } if (returnType instanceof ParameterizedType) { ParameterizedType type = (ParameterizedType) returnType; if (type.getRawType() == Collection.class) { - valid = true; + return true; } } - - if (!valid) { - throw new ConfigurationException("Invalid return type " + returnType - + " for values member " + member + "; must be Collection"); - } - - return result; + return false; } /** @@ -129,7 +176,7 @@ abstract class Parameter<T> { /** * Returns the field's name. */ - public String getName() { + String getName() { return field.getName(); } -}
\ No newline at end of file +} |