All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.snapscript.core.type.index.SignatureGenerator Maven / Gradle / Ivy

package org.snapscript.core.type.index;

import static java.util.Collections.EMPTY_LIST;
import static org.snapscript.core.function.Origin.PLATFORM;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.snapscript.core.annotation.Annotation;
import org.snapscript.core.annotation.AnnotationConverter;
import org.snapscript.core.constraint.Constraint;
import org.snapscript.core.constraint.ConstraintMapper;
import org.snapscript.core.error.InternalStateException;
import org.snapscript.core.function.FunctionSignature;
import org.snapscript.core.function.Parameter;
import org.snapscript.core.function.ParameterBuilder;
import org.snapscript.core.function.Signature;
import org.snapscript.core.module.Module;
import org.snapscript.core.scope.Scope;
import org.snapscript.core.type.Type;

public class SignatureGenerator {
   
   private final GenericConstraintExtractor extractor;
   private final AnnotationConverter converter;
   private final ParameterBuilder builder;
   private final ConstraintMapper mapper;
   
   public SignatureGenerator() {
      this.extractor = new GenericConstraintExtractor();
      this.converter = new AnnotationConverter();
      this.builder = new ParameterBuilder();
      this.mapper = new ConstraintMapper();
   }

   public Signature generate(Type type, Method method) {
      Constraint[] generics = extractor.extractGenerics(method);
      Constraint[] parameters = extractor.extractParameters(method);
      Object[][] annotations = method.getParameterAnnotations();
      Scope scope = type.getScope();
      Module module = type.getModule();
      boolean variable = method.isVarArgs();      
      
      try {
         List signature = new ArrayList();
         List constraints = new ArrayList();
   
         for(int i = 0; i < generics.length; i++) {
            Constraint constraint = generics[i];
            Constraint match = mapper.map(scope, constraint);
            
            constraints.add(match);
         }
         for(int i = 0; i < parameters.length; i++){
            boolean last = i + 1 == parameters.length;
            Constraint constraint = parameters[i];
            Parameter parameter = builder.create(constraint, i, variable && last);
            Object[] list = annotations[i];
            
            if(list.length > 0) {
               List actual = parameter.getAnnotations();
               
               for(int j = 0; j < list.length; j++) {
                  Object value = list[j];
                  Object result = converter.convert(value);
                  Annotation annotation = (Annotation)result;
                  
                  actual.add(annotation);
               }
            }
            signature.add(parameter);
         }
         return new FunctionSignature(signature, constraints, module, method, PLATFORM, true, variable);
      } catch(Exception e) {
         throw new InternalStateException("Could not create function for " + method, e);
      }
   }
   
   public Signature generate(Type type, Constructor constructor) {
      Constraint[] constraints = extractor.extractParameters(constructor);
      Object[][] annotations = constructor.getParameterAnnotations();
      Module module = type.getModule();
      boolean variable = constructor.isVarArgs();
      
      try {
         List parameters = new ArrayList();
   
         for(int i = 0; i < constraints.length; i++){
            boolean last = i + 1 == constraints.length;
            Constraint constraint = constraints[i];
            Parameter parameter = builder.create(constraint, i, variable && last);
            Object[] list = annotations[i];
            
            if(list.length > 0) {
               List actual = parameter.getAnnotations();
               
               for(int j = 0; j < list.length; j++) {
                  Object value = list[j];
                  Object result = converter.convert(value);
                  Annotation annotation = (Annotation)result;
                  
                  actual.add(annotation);
               }
            }
            parameters.add(parameter);
         }
         return new FunctionSignature(parameters, EMPTY_LIST, module, constructor, PLATFORM, true, variable);
      } catch(Exception e) {
         throw new InternalStateException("Could not create constructor for " + constructor, e);
      }
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy