/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* (C) Copyright IBM Corporation 2006-2010.
*/
package x10.types;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import polyglot.ast.Expr;
import polyglot.frontend.Job;
import polyglot.frontend.Source;
import polyglot.types.ClassDef;
import polyglot.types.ClassType;
import polyglot.types.ClassType_c;
import polyglot.types.CodeInstance;
import polyglot.types.ConstructorInstance;
import polyglot.types.DerefTransform;
import polyglot.types.FieldInstance;
import polyglot.types.Flags;
import polyglot.types.LazyRef;
import polyglot.types.LocalInstance;
import polyglot.types.Matcher;
import polyglot.types.MethodAsTypeTransform;
import polyglot.types.MethodDef;
import polyglot.types.Package;
import polyglot.types.Ref;
import polyglot.types.Resolver;
import polyglot.types.Name;
import polyglot.types.ContainerType;
import polyglot.types.Type;
import polyglot.types.TypeObject;
import polyglot.types.Types;
import polyglot.types.TypeSystem;
import polyglot.types.ClassDef.Kind;
import polyglot.util.CodeWriter;
import polyglot.util.InternalCompilerError;
import polyglot.util.Position;
import polyglot.util.Transformation;
import polyglot.util.TransformingList;
import x10.types.constraints.CConstraint;
/**
* A representation of the type of a closure.
* Treated as a ClassType implementing a FunctionType, with the signature
* for the function type retrieved from the sole method (the apply method)
* defined on the class type.
*/
public class ClosureType_c extends FunctionType_c implements ClosureType {
private static final long serialVersionUID = 331189963001388621L;
public ClosureType_c(final TypeSystem ts, Position pos, Position errorPosition, X10ClassDef def, CodeInstance<?> methodContainer) {
super(ts, pos, errorPosition, def);
this.methodContainer = methodContainer;
}
protected CodeInstance<?> methodContainer;
public CodeInstance<?> methodContainer() {
return methodContainer;
}
public ClosureType methodContainer(CodeInstance<?> methodContainer) {
ClosureType_c ct = (ClosureType_c) copy();
ct.methodContainer = methodContainer;
return ct;
}
protected ClosureInstance ci;
public ClosureInstance closureInstance() {
return ci;
}
public ClosureType closureInstance(ClosureInstance ci) {
ClosureType_c ct = (ClosureType_c) copy();
ct.ci = ci;
return ct;
}
public MethodInstance applyMethod() {
try {
return (MethodInstance) methods().get(0);
} catch (Exception z) {
return null;
}
}
public Type returnType() {
return applyMethod().returnType();
}
public CConstraint guard() {
return applyMethod().guard();
}
public List<Type> typeParameters() {
return applyMethod().typeParameters();
}
public List<LocalInstance> formalNames() {
return applyMethod().formalNames();
}
public List<Type> argumentTypes() {
return applyMethod().formalTypes();
}
public FunctionType functionInterface() {
for (Type itype : interfaces()) {
return (FunctionType) itype;
}
throw new InternalCompilerError("Found a closure type "+typeToString()+" at "+position()+" that does not implement a function interface");
}
@Override
public String typeToString() {
MethodInstance mi = applyMethod();
if (mi==null) // this could happen if the method is installed before the type is properly formed, e.g. in -report types=2 execution.
return "???";
StringBuilder sb = new StringBuilder();
List<LocalInstance> formals = mi.formalNames();
for (int i=0; i < formals.size(); ++i) {
LocalInstance f = formals.get(i);
if (sb.length() > 0)
sb.append(", ");
sb.append(f.name());
sb.append(':');
sb.append(f.type());
}
return "(" + sb.toString() + ")" + guardToString(guard()) + "=> " + mi.returnType();
}
@Override
public int hashCode() {
return def.get().hashCode();
}
@Override
public boolean equalsImpl(TypeObject o) {
if (o == this)
return true;
if (o == null)
return false;
if (o instanceof ClosureType_c) {
ClosureType_c t = (ClosureType_c) o;
if (! flags().equals(t.flags()))
return false;
if (def != t.def) {
if (def == null || t.def == null)
return false;
else if (!Types.get(def).equals(Types.get(t.def)))
return false;
}
return true;
}
return false;
}
public void print(CodeWriter w) {
w.write(toString());
}
}