ReflectiveMethod.java
package com.mackenziehigh.autumn.lang.compiler.typesystem;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.mackenziehigh.autumn.lang.compiler.typesystem.design.IAnnotation;
import com.mackenziehigh.autumn.lang.compiler.typesystem.design.IAnnotationMethod;
import com.mackenziehigh.autumn.lang.compiler.typesystem.design.IClassType;
import com.mackenziehigh.autumn.lang.compiler.typesystem.design.IDeclaredType;
import com.mackenziehigh.autumn.lang.compiler.typesystem.design.IFormalParameter;
import com.mackenziehigh.autumn.lang.compiler.typesystem.design.IMethod;
import com.mackenziehigh.autumn.lang.compiler.typesystem.design.IReturnType;
import com.mackenziehigh.autumn.lang.compiler.typesystem.design.ITypeFactory;
import com.mackenziehigh.autumn.resources.Finished;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;
/**
* An instance of this class represents a previously compiled method.
*
* @author Mackenzie High
*/
@Finished("2014/07/12")
public final class ReflectiveMethod
extends AbstractInvokableMember
implements IMethod,
IAnnotationMethod
{
private final Method method;
/**
* Sole Constructor.
*
* @param factory is the factory that is used to access types.
* @param method is the method that this object will represent.
*/
public ReflectiveMethod(final ITypeFactory factory,
final Method method)
{
super(factory);
Preconditions.checkNotNull(method);
this.method = method;
}
/**
* {@inheritDoc}
*/
@Override
public Method getMethod()
{
return method;
}
/**
* {@inheritDoc}
*/
@Override
public IDeclaredType getOwner()
{
final Class klass = method.getDeclaringClass();
final IDeclaredType type = (IDeclaredType) getTypeFactory().fromClass(klass);
return type;
}
/**
* {@inheritDoc}
*/
@Override
public List<IAnnotation> getAnnotations()
{
final List result = Lists.newLinkedList();
for (Annotation element : method.getDeclaredAnnotations())
{
final IAnnotation annotation = CustomAnnotation.fromAnnotation(getTypeFactory(), element);
result.add(annotation);
}
return ImmutableList.copyOf(result);
}
/**
* {@inheritDoc}
*/
@Override
public int getModifiers()
{
return method.getModifiers();
}
/**
* {@inheritDoc}
*/
@Override
public IReturnType getReturnType()
{
return (IReturnType) getTypeFactory().fromClass(method.getReturnType());
}
/**
* {@inheritDoc}
*/
@Override
public String getName()
{
return method.getName();
}
/**
* {@inheritDoc}
*/
@Override
public List<IFormalParameter> getParameters()
{
final List<IFormalParameter> result = Lists.newLinkedList();
for (int i = 0; i < method.getParameterTypes().length; i++)
{
final Annotation[] annotations = method.getParameterAnnotations()[i];
final Class type = method.getParameterTypes()[i];
final IFormalParameter parameter = new ReflectiveFormalParameter(
getTypeFactory(),
annotations,
type);
result.add(parameter);
}
return ImmutableList.copyOf(result);
}
/**
* {@inheritDoc}
*/
@Override
public Collection<IClassType> getThrowsClause()
{
final List<IClassType> result = Lists.newLinkedList();
for (Class exception : method.getExceptionTypes())
{
result.add((IClassType) getTypeFactory().fromClass(exception));
}
return ImmutableSet.copyOf(result);
}
/**
* {@inheritDoc}
*/
@Override
public boolean isAnnotationMethod()
{
return method.getDeclaringClass().isAnnotation();
}
/**
* {@inheritDoc}
*/
@Override
public String toString()
{
return this.getNamePlusDescriptor();
}
}