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

org.snapscript.compile.validate.TypeValidator Maven / Gradle / Ivy

package org.snapscript.compile.validate;

import static org.snapscript.core.ModifierType.ABSTRACT;
import static org.snapscript.core.ModifierType.PUBLIC;
import static org.snapscript.core.Reserved.ANY_TYPE;
import static org.snapscript.core.Reserved.TYPE_CLASS;
import static org.snapscript.core.Reserved.TYPE_THIS;

import java.util.List;
import java.util.Set;

import org.snapscript.core.ModifierType;
import org.snapscript.core.constraint.transform.ConstraintTransformer;
import org.snapscript.core.convert.AliasResolver;
import org.snapscript.core.convert.ConstraintMatcher;
import org.snapscript.core.function.Function;
import org.snapscript.core.function.index.FunctionIndexer;
import org.snapscript.core.function.index.FunctionPointer;
import org.snapscript.core.module.Module;
import org.snapscript.core.property.Property;
import org.snapscript.core.type.Type;
import org.snapscript.core.type.TypeExtractor;

public class TypeValidator {
   
   private static final String[] PROPERTIES = { TYPE_THIS, TYPE_CLASS };
   private static final String[] TYPES = { ANY_TYPE };
   
   private final PropertyValidator properties;
   private final FunctionValidator functions;
   private final TypeExtractor extractor;
   private final FunctionIndexer indexer;
   private final AliasResolver resolver;
   
   public TypeValidator(ConstraintMatcher matcher, ConstraintTransformer transformer, TypeExtractor extractor, FunctionIndexer indexer) {
      this.functions = new FunctionValidator(matcher, transformer, extractor, indexer);
      this.properties = new PropertyValidator(matcher);
      this.resolver = new AliasResolver();
      this.extractor = extractor;
      this.indexer = indexer;
   }
   
   public void validate(Type type) throws Exception {
      Type actual = resolver.resolve(type);
      Class real = actual.getType();
      
      if(real == null) {
         validateModule(actual);
         validateHierarchy(actual);
         validateFunctions(actual);
         validateProperties(actual);
      }
   }
   
   private void validateModule(Type type) throws Exception {
      Module module = type.getModule();
      
      if(module == null) {
         throw new ValidateException("Type '" + type + "' has no module");
      }
   }
   
   private void validateHierarchy(Type type) throws Exception {
      Set types = extractor.getTypes(type);
      
      for(int i = 0; i < TYPES.length; i++) {
         String require = TYPES[i];
         int matches = 0;
         
         for(Type base : types) {
            String name = base.getName();
            
            if(name.equals(require)) {
               matches++;
            }
         }
         if(matches == 0) {
            throw new ValidateException("Type '" + type + "' has an invalid hierarchy");
         }
      }
   }

   private void validateProperties(Type type) throws Exception {
      List list = type.getProperties();
      
      for(int i = 0; i < PROPERTIES.length; i++) {
         String require = PROPERTIES[i];
         int matches = 0;
         
         for(Property property : list) {
            String name = property.getName();
            
            if(name.equals(require)) {
               matches++;
            }
            properties.validate(property);
         }
         if(matches == 0) {
            throw new ValidateException("Type '" + type + "' has no property '" + require + "'");
         }
      }
   }

   private void validateFunctions(Type type) throws Exception {
      int modifiers = type.getModifiers();
      List list = type.getFunctions();
      
      if(!ModifierType.isAbstract(modifiers)) {
         List pointers = indexer.index(type, PUBLIC.mask | ABSTRACT.mask);
         
         for(FunctionPointer pointer : pointers) {
            Function function = pointer.getFunction();
            functions.validate(function, type); // ensure abstract methods are implemted
         }
      }
      for(Function function : list) {
         functions.validate(function);
      }
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy