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

org.extendj.ast.Parameterization Maven / Gradle / Ivy

There is a newer version: 8.1.2
Show newest version
package org.extendj.ast;

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.ArrayList;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.zip.*;
import java.io.*;
import org.jastadd.util.PrettyPrintable;
import org.jastadd.util.PrettyPrinter;
import org.jastadd.util.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.IOException;
import java.util.Set;
import beaver.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
/**
 * @ast class
 * @aspect LookupParTypeDecl
 * @declaredat /home/jesper/git/extendj/java5/frontend/Generics.jrag:1063
 */
public class Parameterization extends java.lang.Object {
  
    public interface TypeProperty {
      boolean holds(TypeDecl t1, TypeDecl t2);
    }

  

    static class Substitution {
      final public TypeVariable param;
      final public TypeDecl arg;

      public Substitution(TypeVariable param, TypeDecl arg) {
        this.param = param;
        this.arg = arg;
      }

      /** Creates a raw type substitution. */
      public Substitution(TypeVariable param) {
        this.param = param;
        this.arg = null;
      }

      public TypeDecl substitute() {
        return arg == null
            ? param.erasure()
            : arg.expandWildcard(param);
      }

      /** Substitute types, preserving wildcards. */
      public TypeDecl substituteBound() {
        return arg == null
            ? param.erasure()
            : arg;
      }
    }

  

    /** Type variable names mapped to wildcard expanded argument types. */
    public final Map typeMap = new HashMap();

  

    public final java.util.List params = new ArrayList();

  

    /** Original type arguments (not wildcard expanded). */
    public final java.util.List args = new ArrayList();

  

    private final boolean isRaw;

  

    public Parameterization(Iterable typeParams, Iterable typeArgs) {
      Iterator param = typeParams.iterator();
      Iterator arg = typeArgs.iterator();
      isRaw = param.hasNext() && !arg.hasNext();
      while (param.hasNext()) {
        TypeVariable variable = param.next();
        Substitution substitution;
        if (arg.hasNext()) {
          TypeDecl argument = arg.next();
          substitution = new Substitution(variable, argument);
          this.args.add(argument);
        } else {
          substitution = new Substitution(variable);
        }
        typeMap.put(variable.name(), substitution);
        params.add(variable);
      }
    }

  

    @Override public String toString() {
      StringBuilder str = new StringBuilder();
      str.append("[");
      for (TypeVariable var : params) {
        if (str.length() > 1) {
          str.append(",");
        }
        TypeDecl arg = typeMap.get(var.name()).arg;
        str.append(var.name()).append("=").append(arg.typeName());
      }
      str.append("]");
      return str.toString();
    }

  

    public boolean isRawType() {
      return isRaw;
    }

  

    /**
     * @return the substituted type, if the name matches a type variable name.
     * Returns {@code null} if the name does not match a type variable in this
     * parameterization.
     */
    public TypeDecl substitute(String name) {
      if (typeMap.containsKey(name)) {
        return typeMap.get(name).substitute();
      }
      return null;
    }

  

    /**
     * Substitute a type bound of a type variable.
     * This should preserve wildcards.
     */
    public TypeDecl substituteBound(String name) {
      if (typeMap.containsKey(name)) {
        return typeMap.get(name).substituteBound();
      }
      return null;
    }

  

    /**
     * @return the original type argument, or the Object type, if this is a raw
     * parameterization.
     */
    public TypeDecl getArg(int i) {
      if (args.isEmpty()) {
        // This is a raw parameterization.
        return params.get(0).typeObject();
      } else {
        return args.get(i);
      }
    }

  

    public boolean sameArguments(Parameterization that) {
      Iterator it1 = this.args.iterator();
      Iterator it2 = that.args.iterator();
      while (it1.hasNext() && it2.hasNext()) {
        TypeDecl t1 = it1.next();
        TypeDecl t2 = it2.next();
        if (t1 instanceof ParTypeDecl && t2 instanceof ParTypeDecl) {
          if (!((ParTypeDecl) t1).sameArguments((ParTypeDecl) t2)) {
            return false;
          }
        } else {
          if (t1 != t2) {
            return false;
          }
        }
      }
      return !it1.hasNext() && !it2.hasNext();
    }

  

    /**
     * Check a type property on each pair of type arguments in this and that
     * parameterization.
     * @return {@code true} if this parameterization and the argument
     * parameterization have the same number of type arguments, and if the
     * given property holds for each type argument pair.
     */
    public boolean compare(Parameterization that, TypeProperty property) {
      Iterator it1 = this.args.iterator();
      Iterator it2 = that.args.iterator();
      while (it1.hasNext() && it2.hasNext()) {
        TypeDecl t1 = it1.next();
        TypeDecl t2 = it2.next();
        if (!property.holds(t1, t2)) {
          return false;
        }
      }
      return !it1.hasNext() && !it2.hasNext();
    }

  

    /**
     * Check a type property on each pair of type arguments in this and that
     * parameterization, with substituted arguments in this parameterization.
     * @return {@code true} if this parameterization and the argument
     * parameterization have the same number of type arguments, and if the
     * given property holds for each type argument pair, with the argument
     * from this parameterization substituted.
     */
    public boolean compareSubstituted(Parameterization that, TypeProperty property) {
      Iterator it1 = this.params.iterator();
      Iterator it2 = that.args.iterator();
      while (it1.hasNext() && it2.hasNext()) {
        TypeDecl t1 = substitute(it1.next().name());
        TypeDecl t2 = it2.next();
        if (!property.holds(t1, t2)) {
          return false;
        }
      }
      return !it1.hasNext() && !it2.hasNext();
    }

  public static final TypeProperty SAME_STRUCTURE = new TypeProperty() {
    @Override
    public boolean holds(TypeDecl t1, TypeDecl t2) {
      return t1.sameStructure(t2);
    }
  };

  public static final TypeProperty CONTAINED_IN = new TypeProperty() {
    @Override
    public boolean holds(TypeDecl t1, TypeDecl t2) {
      return t1.containedIn(t2);
    }
  };


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy