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

org.snapscript.tree.define.ClassHierarchy Maven / Gradle / Ivy

package org.snapscript.tree.define;

import java.util.List;

import org.snapscript.core.ModifierType;
import org.snapscript.core.constraint.AnyConstraint;
import org.snapscript.core.constraint.Constraint;
import org.snapscript.core.constraint.ConstraintVerifier;
import org.snapscript.core.error.InternalStateException;
import org.snapscript.core.scope.Scope;
import org.snapscript.core.type.Type;
import org.snapscript.tree.constraint.ClassConstraint;
import org.snapscript.tree.constraint.TraitConstraint;

public class ClassHierarchy implements TypeHierarchy {
      
   private final ConstraintVerifier verifier;
   private final TraitConstraint[] traits; 
   private final ClassConstraint base;
   private final Constraint any;
   
   public ClassHierarchy(TraitConstraint... traits) {
      this(null, traits);     
   }
   
   public ClassHierarchy(ClassConstraint base, TraitConstraint... traits) {
      this.verifier = new ConstraintVerifier();
      this.any = new AnyConstraint();
      this.traits = traits;
      this.base = base;
   }

   @Override
   public void define(Scope scope, Type type) throws Exception {
      List types = type.getTypes();
      
      if(base == null) {
         types.add(any);
      } else {
         Type match = base.getType(scope);
         
         if(match == null) {
            throw new InternalStateException("Invalid super class for type '" + type + "'");
         }
         int modifiers = match.getModifiers();
         
         if(!ModifierType.isClass(modifiers)) {
            throw new InternalStateException("Invalid super class '" + match + "' for type '" + type + "'");
         }
         types.add(base);  
      }
      for(int i = 0; i < traits.length; i++) {
         Constraint trait = traits[i];
         Type match = trait.getType(scope);
         
         if(match == null) {
            throw new InternalStateException("Invalid trait for type '" + type + "'");
         }
         int modifiers = match.getModifiers();
         
         if(!ModifierType.isTrait(modifiers)) {
            throw new InternalStateException("Invalid trait '" + match + "' for type '" + type + "'");
         }
         types.add(trait);
      }
   }
   
   @Override
   public void compile(Scope scope, Type type) throws Exception {
      List types = type.getTypes();
      
      for(Constraint base : types) {
         try {
            verifier.verify(scope, base);
         } catch(Exception e) {
            throw new InternalStateException("Invalid super class for type '" + type + "'", e); 
         }
      }
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy