protected String getObjectTypeString() { Class<?> clazz = getObjectType(); if (clazz == null) { return ""; } return EvalUtils.getDataTypeNameFromClass(clazz, false) + "."; }
// The precondition ensures generic type safety @SuppressWarnings("unchecked") public <T> NestedSet<T> getSet(Class<T> type) { // Empty sets don't need have to have a type since they don't have items if (set.isEmpty()) { return (NestedSet<T>) set; } Preconditions.checkArgument( contentType.canBeCastTo(type), String.format( "Expected a set of '%s' but got a set of '%s'", EvalUtils.getDataTypeNameFromClass(type), contentType)); return (NestedSet<T>) set; }
@Override @Nullable public Object call(Object[] args, @Nullable FuncallExpression ast, @Nullable Environment env) throws EvalException, InterruptedException { final Location loc = (ast == null) ? location : ast.getLocation(); // Add extra arguments, if needed if (extraArgs != null) { int i = args.length - extraArgs.length; for (BuiltinFunction.ExtraArgKind extraArg : extraArgs) { switch (extraArg) { case LOCATION: args[i] = loc; break; case SYNTAX_TREE: args[i] = ast; break; case ENVIRONMENT: args[i] = env; break; } i++; } } // Last but not least, actually make an inner call to the function with the resolved arguments. try { return invokeMethod.invoke(this, args); } catch (InvocationTargetException x) { Throwable e = x.getCause(); if (e instanceof EvalException) { throw ((EvalException) e).ensureLocation(loc); } else if (e instanceof InterruptedException) { throw (InterruptedException) e; } else if (e instanceof ClassCastException || e instanceof ExecutionException || e instanceof IllegalStateException) { throw new EvalException(loc, "in call to " + getName(), e); } else if (e instanceof IllegalArgumentException) { throw new EvalException(loc, "Illegal argument in call to " + getName(), e); } else { throw badCallException(loc, e, args); } } catch (IllegalArgumentException e) { // Either this was thrown by Java itself, or it's a bug // To cover the first case, let's manually check the arguments. final int len = args.length - ((extraArgs == null) ? 0 : extraArgs.length); final Class<?>[] types = invokeMethod.getParameterTypes(); for (int i = 0; i < args.length; i++) { if (args[i] != null && !types[i].isAssignableFrom(args[i].getClass())) { String paramName = i < len ? signature.getSignature().getNames().get(i) : extraArgs[i - len].name(); int extraArgsCount = (extraArgs == null) ? 0 : extraArgs.length; throw new EvalException( loc, String.format( "Method %s is not applicable for arguments %s: '%s' is %s, but should be %s", getShortSignature(true), printTypeString(args, args.length - extraArgsCount), paramName, EvalUtils.getDataTypeName(args[i]), EvalUtils.getDataTypeNameFromClass(types[i]))); } } throw badCallException(loc, e, args); } catch (IllegalAccessException e) { throw badCallException(loc, e, args); } }