Package st.gravel.support.jvm

Source Code of st.gravel.support.jvm.ClassDescriptionMirror

package st.gravel.support.jvm;

import java.util.HashSet;

import st.gravel.core.Symbol;
import st.gravel.support.compiler.ast.AbstractClassMapping;
import st.gravel.support.compiler.ast.ClassDescriptionNode;
import st.gravel.support.compiler.ast.ClassMapping;
import st.gravel.support.compiler.ast.ClassNode;
import st.gravel.support.compiler.ast.MethodNode;
import st.gravel.support.compiler.ast.PackageNode;
import st.gravel.support.compiler.ast.Parser;
import st.gravel.support.compiler.ast.Reference;
import st.gravel.support.compiler.ast.SystemDefinitionNode;
import st.gravel.support.jvm.runtime.ImageBootstrapper;

public abstract class ClassDescriptionMirror {
  public static ClassDescriptionMirror forReference(Reference reference) {
    return reference.isMeta() ? new MetaclassMirror(reference)
        : new ClassMirror(reference);
  }

  protected final Reference reference;

  protected ClassDescriptionMirror(Reference reference) {
    super();
    this.reference = reference;
  }

  public Object compile_classified_(String source, String protocol) {
    final MethodNode method = Parser.factory.parseMethod_(source)
        .withProtocol_(protocol);

    ClassDescriptionNode currentClassNode = definitionClassNode();
    final MethodNode current = currentClassNode.methodOrNilAt_(method
        .selector());
    Symbol targetPackageName = current == null ? definitionClassNode()
        .packageName() : current.packageName();
    if (targetPackageName == null) {
      targetPackageName = definitionClassNode().packageName();
      if (targetPackageName == null) {
        targetPackageName = current.packageName();
      }
    }
    SystemDefinitionNode newSystem = ImageBootstrapper.systemMapping
        .systemDefinitionNode().copyUpdatePackage_do_(
            targetPackageName,
            new Block1<PackageNode, PackageNode>() {

              @Override
              public PackageNode value_(PackageNode packageNode) {
                return packageNode.copyUpdateClassNode_do_(
                    definitionClassNode().reference(),
                    new Block1<ClassNode, ClassNode>() {

                      @Override
                      public ClassNode value_(
                          ClassNode classNode) {

                        return current == null ? classNode
                            .withMethodNode_(method)
                            : classNode
                                .copyReplaceMethodNode_(method);
                      }
                    });
              }
            });
    ImageBootstrapper.systemMapping.updateTo_(newSystem);
    return getMethodMirror(Symbol.value(method.selector()));
  }

  public abstract ClassDescriptionNode definitionClassNode();

  public ClassDescriptionNode runtimeClassNode() {
    return ImageBootstrapper.systemMapping.classMappingAtReference_(
        reference).classNode();
  }

  public HashSet<Symbol> definitionSelectors() {
    final HashSet<Symbol> set = new HashSet<Symbol>();
    definitionClassNode().selectorsDo_(new Block1<Object, String>() {

      @Override
      public Object value_(String selectorString) {
        set.add(Symbol.value(selectorString));
        return null;
      }
    });
    return set;
  }

  public HashSet<Symbol> flattenedSelectors() {
    final HashSet<Symbol> set = new HashSet<Symbol>();
    runtimeClassNode().selectorsDo_(new Block1<Object, String>() {

      @Override
      public Object value_(String selectorString) {
        set.add(Symbol.value(selectorString));
        return null;
      }
    });
    return set;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj)
      return true;
    if (obj == null)
      return false;
    if (getClass() != obj.getClass())
      return false;
    ClassDescriptionMirror other = (ClassDescriptionMirror) obj;
    if (reference == null) {
      if (other.reference != null)
        return false;
    } else if (!reference.equals(other.reference))
      return false;
    return true;
  }

  public MethodMirror getMethodMirror(Object selObject) {
    if (!(selObject instanceof Symbol))
      return null;
    Symbol selector = (Symbol) selObject;
    MethodNode method = getMethodNode(selector);
    if (method == null) {
      return null;
    }
    return new MethodMirror(method, this);
  }

  private MethodNode getMethodNode(Symbol selector) {
    MethodNode method = runtimeClassNode().methodOrNilAt_(
        selector.asString());
    return method;
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result
        + ((reference == null) ? 0 : reference.hashCode());
    return result;
  }

  public boolean includesBehavior_(Object classOrMirror) {
    if (classOrMirror instanceof ClassDescriptionMirror)
      return ObjectExtensions.includesBehavior_(instance(),
          ((ClassDescriptionMirror) classOrMirror).instance());
    return ObjectExtensions.includesBehavior_(instance(), classOrMirror);
  }

  public ObjectClass instance() {
    Object singleton = ImageBootstrapper.systemMapping
        .singletonAtReference_(reference.nonmeta());
    return (ObjectClass) singleton;
  }

  public Symbol packageName() {
    return definitionClassNode().packageName();
  }

  public boolean isTrait() {
    return definitionClassNode().isTrait();
  }

  public Reference reference() {
    return reference;
  }

  public HashSet<ClassDescriptionMirror> subclasses() {
    final HashSet<ClassDescriptionMirror> set = new HashSet<>();
    ImageBootstrapper.systemMapping.subclassMappingsFor_do_(reference,
        new Block1<Object, AbstractClassMapping>() {

          @Override
          public Object value_(AbstractClassMapping arg1) {
            set.add(ClassDescriptionMirror.forReference(arg1
                .reference()));
            return null;
          }
        });
    return set;
  }

  public ClassDescriptionMirror superclass() {
    Reference superclassReference = ImageBootstrapper.systemMapping
        .classMappingAtReference_(reference).superclassReference();
    if (superclassReference == null)
      return null;
    return ClassDescriptionMirror.forReference(superclassReference);
  }

  public boolean canUnderstand_(Symbol selector) {
    return getMethodNode(selector) != null;
  }

}
TOP

Related Classes of st.gravel.support.jvm.ClassDescriptionMirror

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.