Search in sources :

Example 6 with ClassMirror

use of com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror in project CommandHelper by EngineHub.

the class ExhaustiveVisitor method verify.

public static void verify(ClassMirror<? extends ExhaustiveVisitor> classMirror) throws ClassNotFoundException {
    Class<? extends ExhaustiveVisitor> clazz = classMirror.loadClass();
    System.out.println("Verifying " + clazz);
    VisitorInfo info = clazz.getAnnotation(VisitorInfo.class);
    Class<?> baseClass = classMirror.getGenerics().get(new ClassMirror<>(ExhaustiveVisitor.class).getClassReference()).get(0).loadClass();
    List<String> uhohs = new ArrayList<>();
    // Make sure all public visit methods have only one parameter (which extends T) and return void
    Set<Class<?>> handledClasses = new HashSet<>();
    for (Method m : clazz.getMethods()) {
        if (m.getDeclaringClass() == ExhaustiveVisitor.class) {
            // This is the method defined in this class, which doesn't need to be checked. Skip it.
            continue;
        }
        if (VISIT.equals(m.getName()) && (m.getModifiers() & Modifier.PUBLIC) != 0) {
            if (m.getReturnType() != void.class) {
                uhohs.add("Return type of public visit() methods must be void, but " + clazz.getName() + " " + m + " does not conform");
            }
            if (m.getParameterTypes().length != 1) {
                uhohs.add("Public visit() methods must accept exactly one parameter, but" + clazz.getName() + " " + m + " does not conform");
            } else {
                Class<?> param = m.getParameterTypes()[0];
                if (baseClass.isAssignableFrom(param)) {
                    handledClasses.add(param);
                } else {
                    uhohs.add("Public visit() methods parameters must extend the given base class's type, but the" + " parameter of method " + m + " in " + clazz.getName() + " has a disjoint type than " + baseClass.getName() + ". Make the method non-public, or rename it, if you would" + " like to keep the method.");
                }
            }
        }
    }
    // Make sure that all subclasses are accounted for, taking into
    // account the value of directSubclassOnly
    Set<Class<?>> needsToHandle = new HashSet<>();
    for (Class<?> c : ClassDiscovery.getDefaultInstance().loadClassesThatExtend(baseClass)) {
        if ((c.getModifiers() & Modifier.ABSTRACT) != 0) {
            // thus is not required to be implemented
            continue;
        }
        if (info != null && info.directSubclassOnly()) {
            if (c.getSuperclass() == baseClass || Arrays.asList(c.getInterfaces()).contains(c)) {
                needsToHandle.add(c);
            }
        } else {
            needsToHandle.add(c);
        }
    }
    if (!needsToHandle.equals(handledClasses)) {
        String s = clazz.getName() + " is missing needed implementations of the visit method. It is required" + " that it handle the following: " + needsToHandle + ", however, it only handles the following:" + " " + handledClasses + ". Please add the following implementations:\n";
        needsToHandle.removeAll(handledClasses);
        for (Class<?> n : needsToHandle) {
            s += "public void visit(" + n.getName().replace("$", ".") + " obj) { /* Implement me */ }\n";
        }
        uhohs.add(s);
    }
    if (!uhohs.isEmpty()) {
        throw new RuntimeException(StringUtils.Join(uhohs, "\n"));
    }
}
Also used : ArrayList(java.util.ArrayList) Method(java.lang.reflect.Method) ClassMirror(com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror) HashSet(java.util.HashSet)

Example 7 with ClassMirror

use of com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror in project CommandHelper by EngineHub.

the class ClassDiscovery method getKnownClasses.

/**
 * Returns a list of all known classes. The ClassMirror for each class is returned, and further examination can be
 * done on each class, or loadClass can be called on the ClassMirror to get the actual Class object. No ClassLoaders
 * are involved directly in this operation.
 *
 * @return A list of ClassMirror objects for all known classes
 */
public Set<ClassMirror<?>> getKnownClasses() {
    doDiscovery();
    Set<ClassMirror<?>> ret = new HashSet<>();
    for (URL url : urlCache) {
        ret.addAll(getKnownClasses(url));
    }
    return ret;
}
Also used : ClassMirror(com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror) URL(java.net.URL) HashSet(java.util.HashSet)

Example 8 with ClassMirror

use of com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror in project CommandHelper by EngineHub.

the class AnnotationChecks method verifyNonInheritImplements.

public static void verifyNonInheritImplements() throws ClassNotFoundException {
    Set<ClassMirror<?>> toVerify;
    toVerify = ClassDiscovery.getDefaultInstance().getClassesWithAnnotation(NonInheritImplements.class);
    Set<String> uhohs = new HashSet<>();
    for (ClassMirror<?> c : toVerify) {
        Class<?> iface = Class.forName(c.getAnnotation(NonInheritImplements.class).getValue("value").toString());
        if (!iface.isInterface()) {
            uhohs.add("The class given to @NonInheritImplements, tagged on " + c.getClassName() + " is not an interface, and must be.");
            continue;
        }
        // methods.
        for (Method im : iface.getDeclaredMethods()) {
            try {
                c.getMethod(im.getName(), im.getParameterTypes());
            } catch (NoSuchMethodException ex) {
                String msg = "The class " + c.getClassName() + " implements " + iface.getSimpleName() + " but does not" + " implement the method public " + im.getReturnType().getSimpleName() + " " + im.getName() + "(";
                List<String> params = new ArrayList<>();
                msg += StringUtils.Join(im.getParameters(), ", ", ", ", ", ", "", (Object item) -> {
                    Parameter ci = (Parameter) item;
                    return ci.getType().getSimpleName() + " " + ci.getName();
                });
                msg += ") {}";
                uhohs.add(msg);
            }
        }
    }
    if (!uhohs.isEmpty()) {
        String error = StringUtils.Join(uhohs, "\n");
        throw new Error(error);
    }
}
Also used : NonInheritImplements(com.laytonsmith.annotations.NonInheritImplements) Method(java.lang.reflect.Method) ClassMirror(com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror) Parameter(java.lang.reflect.Parameter) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet)

Example 9 with ClassMirror

use of com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror in project CommandHelper by EngineHub.

the class GeneralTest method testAnnotationValue.

@Test
public void testAnnotationValue() throws Exception {
    ClassMirror<?> c1 = ClassDiscovery.getDefaultInstance().forName(GeneralTest.class.getName());
    ClassMirror<GeneralTest> c2 = new ClassMirror<>(GeneralTest.class);
    FieldMirror f1 = c1.getField("field");
    FieldMirror f2 = c1.getField("field");
    MethodMirror m1 = c1.getMethod("method", new Class[] {});
    MethodMirror m2 = c2.getMethod("method", new Class[] {});
    assertEquals(c1.loadAnnotation(TestAnnotation.class).value(), "value");
    assertEquals(c2.loadAnnotation(TestAnnotation.class).value(), "value");
    assertEquals(f1.loadAnnotation(TestAnnotation.class).value(), "field");
    assertEquals(f2.loadAnnotation(TestAnnotation.class).value(), "field");
    assertEquals(m1.loadAnnotation(TestAnnotation.class).value(), "method");
    assertEquals(m2.loadAnnotation(TestAnnotation.class).value(), "method");
}
Also used : FieldMirror(com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.FieldMirror) MethodMirror(com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.MethodMirror) ClassMirror(com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror) Test(org.junit.Test)

Aggregations

ClassMirror (com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirror)9 HashSet (java.util.HashSet)6 ArrayList (java.util.ArrayList)5 URL (java.net.URL)4 File (java.io.File)3 Method (java.lang.reflect.Method)3 DynamicClassLoader (com.laytonsmith.PureUtilities.ClassLoading.DynamicClassLoader)2 CFunction (com.laytonsmith.core.constructs.CFunction)2 Event (com.laytonsmith.core.events.Event)2 Function (com.laytonsmith.core.functions.Function)2 IOException (java.io.IOException)2 UnsupportedEncodingException (java.io.UnsupportedEncodingException)2 MalformedURLException (java.net.MalformedURLException)2 ClassDiscovery (com.laytonsmith.PureUtilities.ClassLoading.ClassDiscovery)1 ClassDiscoveryCache (com.laytonsmith.PureUtilities.ClassLoading.ClassDiscoveryCache)1 AnnotationMirror (com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.AnnotationMirror)1 ClassMirrorVisitor (com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.ClassMirrorVisitor)1 FieldMirror (com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.FieldMirror)1 MethodMirror (com.laytonsmith.PureUtilities.ClassLoading.ClassMirror.MethodMirror)1 ReflectionUtils (com.laytonsmith.PureUtilities.Common.ReflectionUtils)1