Search in sources :

Example 6 with GenerationProcess

use of com.github.sviperll.adt4j.model.util.GenerationProcess in project adt4j by sviperll.

the class VisitorDefinition method createMethodMap.

private static GenerationResult<Map<String, JMethod>> createMethodMap(JDefinedClass jVisitorModel, SpecialTypeVariables specialTypeVariables) {
    GenerationProcess generation = new GenerationProcess();
    Map<String, JMethod> methods = new TreeMap<>();
    for (JMethod method : jVisitorModel.methods()) {
        AbstractJType methodType = method.type();
        if (methodType == null)
            generation.reportError(MessageFormat.format("Visitor method result type is missing: {0}", method.name()));
        else if (methodType.isError()) {
            generation.reportError(MessageFormat.format("Visitor method result type is erroneous: {0}", method.name()));
        } else if (!specialTypeVariables.isResult(method.type())) {
            generation.reportError(MessageFormat.format("Visitor method is only allowed to return type declared as a result type of visitor: {0}: expecting {1}, found: {2}", method.name(), specialTypeVariables.resultTypeParameter().name(), methodType.fullName()));
        }
        for (JTypeVar typeVariable : method.typeParamList()) {
            for (AbstractJClass bound : typeVariable.bounds()) {
                if (bound.containsTypeVar(specialTypeVariables.resultTypeParameter())) {
                    generation.reportError(MessageFormat.format("Visitor method type-parameters shouldn''t depend on result type: {0}: {1} type-variable", method.name(), typeVariable.name()));
                }
            }
        }
        for (JVar parameter : method.listParams()) {
            if (parameter.type().containsTypeVar(specialTypeVariables.resultTypeParameter())) {
                generation.reportError(MessageFormat.format("Visitor method shouldn''t have result type as a parameter: {0}: result type-parameter: {1}", method.name(), specialTypeVariables.resultTypeParameter().name()));
            }
        }
        Collection<AbstractJClass> exceptions = method.getThrows();
        if (exceptions.size() > 1)
            generation.reportError(MessageFormat.format("Visitor method is allowed to throw no exceptions or throw single exception, declared as type-variable: {0}", method.name()));
        else if (exceptions.size() == 1) {
            AbstractJClass exception = exceptions.iterator().next();
            if (exception.isError())
                generation.reportError(MessageFormat.format("Visitor method exception type is erroneous: {0}", method.name()));
            else if (!specialTypeVariables.isException(exception))
                generation.reportError(MessageFormat.format("Visitor method throws exception, not declared as type-variable: {0}: {1}", method.name(), exception.fullName()));
        }
        JMethod exitingValue = methods.put(method.name(), method);
        if (exitingValue != null) {
            generation.reportError(MessageFormat.format("Method overloading is not supported for visitor interfaces: two methods with the same name: {0}", method.name()));
        }
        for (JVar param : method.params()) {
            generation.processGenerationResult(Source.getNullability(param));
        }
    }
    return generation.createGenerationResult(methods);
}
Also used : JTypeVar(com.helger.jcodemodel.JTypeVar) AbstractJType(com.helger.jcodemodel.AbstractJType) AbstractJClass(com.helger.jcodemodel.AbstractJClass) GenerationProcess(com.github.sviperll.adt4j.model.util.GenerationProcess) TreeMap(java.util.TreeMap) JMethod(com.helger.jcodemodel.JMethod) JVar(com.helger.jcodemodel.JVar)

Example 7 with GenerationProcess

use of com.github.sviperll.adt4j.model.util.GenerationProcess in project adt4j by sviperll.

the class Stage0ValueClassModel method createStage1Model.

public GenerationResult<Stage1ValueClassModel> createStage1Model(JDefinedClass jVisitorModel, Visitor visitorAnnotation) {
    GenerationProcess generation = new GenerationProcess();
    if (error != null) {
        generation.reportError(error);
        return generation.createGenerationResult(null);
    } else {
        JAnnotationUse annotation = null;
        for (JAnnotationUse anyAnnotation : jVisitorModel.annotations()) {
            AbstractJClass annotationClass = anyAnnotation.getAnnotationClass();
            if (!annotationClass.isError()) {
                String fullName = annotationClass.fullName();
                if (fullName != null && fullName.equals(GenerateValueClassForVisitor.class.getName()))
                    annotation = anyAnnotation;
            }
        }
        if (annotation == null)
            throw new IllegalStateException("ValueClassModelFactory can't be run for interface without " + GenerateValueClassForVisitor.class + " annotation");
        VisitorDefinition visitorModel = generation.processGenerationResult(VisitorDefinition.createInstance(jVisitorModel, visitorAnnotation));
        ValueClassConfiguration configuration = generation.processGenerationResult(ValueClassConfiguration.createInstance(visitorModel, annotation, valueClass));
        Stage1ValueClassModel result = createStage1Model(configuration);
        return generation.createGenerationResult(result);
    }
}
Also used : ValueClassConfiguration(com.github.sviperll.adt4j.model.config.ValueClassConfiguration) VisitorDefinition(com.github.sviperll.adt4j.model.config.VisitorDefinition) JAnnotationUse(com.helger.jcodemodel.JAnnotationUse) GenerateValueClassForVisitor(com.github.sviperll.adt4j.GenerateValueClassForVisitor) AbstractJClass(com.helger.jcodemodel.AbstractJClass) GenerationProcess(com.github.sviperll.adt4j.model.util.GenerationProcess)

Example 8 with GenerationProcess

use of com.github.sviperll.adt4j.model.util.GenerationProcess in project adt4j by sviperll.

the class FieldReader method readUpdater.

GenerationResult<Void> readUpdater(MethodUsage interfaceMethod, VariableDeclaration param, AbstractJType paramType, boolean isVarArg) {
    GenerationProcess generation = new GenerationProcess();
    for (JAnnotationUse annotationUsage : param.annotations()) {
        AbstractJClass annotationClass = annotationUsage.getAnnotationClass();
        if (!annotationClass.isError()) {
            String annotationClassName = annotationClass.fullName();
            if (annotationClassName != null && annotationClassName.equals(Updater.class.getName())) {
                String updaterName = annotationUsage.getParam("name", String.class);
                if (updaterName == null || updaterName.equals(":auto"))
                    updaterName = "with" + Source.capitalize(param.name());
                MemberAccess accessLevel = annotationUsage.getParam("access", MemberAccess.class);
                boolean isNullable = Source.isNullable(param);
                FieldFlags flags = new FieldFlags(isNullable, isVarArg, accessLevel);
                FieldConfiguration configuration = new FieldConfiguration(updaterName, paramType, flags);
                generation.processGenerationResult(read(interfaceMethod, param, configuration));
            }
        }
    }
    return generation.<Void>createGenerationResult(null);
}
Also used : MemberAccess(com.github.sviperll.adt4j.MemberAccess) JAnnotationUse(com.helger.jcodemodel.JAnnotationUse) AbstractJClass(com.helger.jcodemodel.AbstractJClass) GenerationProcess(com.github.sviperll.adt4j.model.util.GenerationProcess)

Example 9 with GenerationProcess

use of com.github.sviperll.adt4j.model.util.GenerationProcess in project adt4j by sviperll.

the class Stage0ValueClassModelFactory method createStage0Model.

public Stage0ValueClassModel createStage0Model(JDefinedClass bootModel, Visitor visitorAnnotation) {
    GenerationProcess generation = new GenerationProcess();
    JAnnotationUse annotation = null;
    for (JAnnotationUse anyAnnotation : bootModel.annotations()) {
        AbstractJClass annotationClass = anyAnnotation.getAnnotationClass();
        if (!annotationClass.isError()) {
            String fullName = annotationClass.fullName();
            if (fullName != null && fullName.equals(GenerateValueClassForVisitor.class.getName()))
                annotation = anyAnnotation;
        }
    }
    if (annotation == null)
        throw new IllegalStateException("ValueClassModelFactory can't be run for interface without " + GenerateValueClassForVisitor.class + " annotation");
    VisitorDefinition visitorModel = generation.processGenerationResult(VisitorDefinition.createInstance(bootModel, visitorAnnotation));
    ValueClassConfiguration configuration = generation.processGenerationResult(ValueClassConfiguration.createInstance(visitorModel, annotation));
    int mods = configuration.isValueClassPublic() ? JMod.PUBLIC : JMod.NONE;
    JDefinedClass valueClass;
    try {
        valueClass = factory.defineClass(bootModel._package().name(), mods, configuration.valueClassName());
    } catch (JClassAlreadyExistsException ex) {
        return new Stage0ValueClassModel("Class " + configuration.valueClassName() + " already exists");
    }
    JAnnotationUse generatedAnnotation = valueClass.annotate(Generated.class);
    generatedAnnotation.param("value", GenerateValueClassForVisitorProcessor.class.getName());
    Source.annotateParametersAreNonnullByDefault(valueClass);
    return new Stage0ValueClassModel(valueClass);
}
Also used : ValueClassConfiguration(com.github.sviperll.adt4j.model.config.ValueClassConfiguration) VisitorDefinition(com.github.sviperll.adt4j.model.config.VisitorDefinition) JDefinedClass(com.helger.jcodemodel.JDefinedClass) AbstractJClass(com.helger.jcodemodel.AbstractJClass) JClassAlreadyExistsException(com.helger.jcodemodel.JClassAlreadyExistsException) JAnnotationUse(com.helger.jcodemodel.JAnnotationUse) GenerateValueClassForVisitor(com.github.sviperll.adt4j.GenerateValueClassForVisitor) GenerationProcess(com.github.sviperll.adt4j.model.util.GenerationProcess) GenerateValueClassForVisitorProcessor(com.github.sviperll.adt4j.GenerateValueClassForVisitorProcessor)

Example 10 with GenerationProcess

use of com.github.sviperll.adt4j.model.util.GenerationProcess in project adt4j by sviperll.

the class Stage1ValueClassModel method createResult.

public GenerationResult<JDefinedClass> createResult() {
    GenerationProcess generation = new GenerationProcess();
    generation.reportAllErrors(validateInterfaces());
    Map<String, FieldConfiguration> gettersConfigutation = generation.processGenerationResult(configuration.getGettersConfigutation(valueClass, types));
    Map<String, FieldConfiguration> updatersConfiguration = generation.processGenerationResult(configuration.getUpdatersConfiguration(valueClass, types));
    Map<String, PredicateConfigutation> predicates = generation.processGenerationResult(configuration.getPredicates());
    FinalValueClassModel result;
    if (generation.hasErrors()) {
        FinalValueClassModelEnvironment environment = new FinalValueClassModelEnvironment(valueClass, null, configuration);
        result = FinalValueClassModel.createErrorModel(environment, types);
    } else {
        JDefinedClass acceptingInterface;
        try {
            acceptingInterface = createAcceptingInterface();
        } catch (JClassAlreadyExistsException ex) {
            throw new RuntimeException("Unexpected exception", ex);
        }
        if (configuration.isValueClassSerializable()) {
            acceptingInterface._extends(types._Serializable);
        }
        FinalValueClassModelEnvironment environment = new FinalValueClassModelEnvironment(valueClass, acceptingInterface, configuration);
        result = FinalValueClassModel.createModel(environment, types);
    }
    result.buildSerialVersionUID();
    FinalValueClassModel.MethodBuilder methodBuilder = result.createMethodBuilder(configuration.serialization());
    Map<String, JMethod> constructorMethods = methodBuilder.buildConstructorMethods(configuration.serialization());
    methodBuilder.buildPrivateConstructor();
    if (configuration.isValueClassSerializable())
        methodBuilder.buildReadObjectMethod();
    methodBuilder.buildProtectedConstructor(configuration.serialization());
    methodBuilder.buildAcceptMethod();
    for (FieldConfiguration getter : gettersConfigutation.values()) {
        methodBuilder.generateGetter(getter);
    }
    for (FieldConfiguration updater : updatersConfiguration.values()) {
        methodBuilder.generateUpdater(updater);
    }
    for (Map.Entry<String, PredicateConfigutation> predicate : predicates.entrySet()) {
        methodBuilder.generatePredicate(predicate.getKey(), predicate.getValue());
    }
    if (configuration.isValueClassComparable()) {
        methodBuilder.buildCompareTo();
    }
    methodBuilder.buildEqualsMethod();
    methodBuilder.buildHashCodeMethod(configuration.hashCodeBase());
    methodBuilder.buildToStringMethod();
    try {
        result.buildFactory(constructorMethods);
    } catch (JClassAlreadyExistsException ex) {
        throw new RuntimeException("Unexpected exception :)", ex);
    }
    return generation.createGenerationResult(valueClass);
}
Also used : JDefinedClass(com.helger.jcodemodel.JDefinedClass) JClassAlreadyExistsException(com.helger.jcodemodel.JClassAlreadyExistsException) PredicateConfigutation(com.github.sviperll.adt4j.model.config.PredicateConfigutation) GenerationProcess(com.github.sviperll.adt4j.model.util.GenerationProcess) JMethod(com.helger.jcodemodel.JMethod) Map(java.util.Map) FieldConfiguration(com.github.sviperll.adt4j.model.config.FieldConfiguration)

Aggregations

GenerationProcess (com.github.sviperll.adt4j.model.util.GenerationProcess)15 AbstractJClass (com.helger.jcodemodel.AbstractJClass)9 JAnnotationUse (com.helger.jcodemodel.JAnnotationUse)7 MemberAccess (com.github.sviperll.adt4j.MemberAccess)4 JMethod (com.helger.jcodemodel.JMethod)4 TreeMap (java.util.TreeMap)4 JDefinedClass (com.helger.jcodemodel.JDefinedClass)3 JTypeVar (com.helger.jcodemodel.JTypeVar)3 GenerateValueClassForVisitor (com.github.sviperll.adt4j.GenerateValueClassForVisitor)2 ValueClassConfiguration (com.github.sviperll.adt4j.model.config.ValueClassConfiguration)2 VariableDeclaration (com.github.sviperll.adt4j.model.config.VariableDeclaration)2 VisitorDefinition (com.github.sviperll.adt4j.model.config.VisitorDefinition)2 MethodUsage (com.github.sviperll.adt4j.model.config.VisitorDefinition.MethodUsage)2 JClassAlreadyExistsException (com.helger.jcodemodel.JClassAlreadyExistsException)2 Caching (com.github.sviperll.adt4j.Caching)1 GeneratePredicate (com.github.sviperll.adt4j.GeneratePredicate)1 GenerateValueClassForVisitorProcessor (com.github.sviperll.adt4j.GenerateValueClassForVisitorProcessor)1 WrapsGeneratedValueClass (com.github.sviperll.adt4j.WrapsGeneratedValueClass)1 FieldConfiguration (com.github.sviperll.adt4j.model.config.FieldConfiguration)1 PredicateConfigutation (com.github.sviperll.adt4j.model.config.PredicateConfigutation)1