/* * 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.ast; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import polyglot.ast.Formal; import polyglot.ast.Node; import polyglot.ast.NodeFactory; import polyglot.ast.TypeNode; import polyglot.ast.TypeNode_c; import polyglot.frontend.SetResolverGoal; import polyglot.types.ClassType; import polyglot.types.CodeDef; import polyglot.types.CodeInstance; import polyglot.types.Context; import polyglot.types.DerefTransform; import polyglot.types.LazyRef; import polyglot.types.LocalDef; import polyglot.types.Ref; import polyglot.types.SemanticException; import polyglot.types.Type; import polyglot.types.TypeSystem; import polyglot.types.Types; import polyglot.util.CodeWriter; import polyglot.util.Position; import polyglot.util.TransformingList; import polyglot.util.TypedList; import polyglot.visit.ContextVisitor; import polyglot.visit.NodeVisitor; import polyglot.visit.PrettyPrinter; import polyglot.visit.TypeCheckPreparer; import polyglot.visit.TypeChecker; import x10.errors.Errors; import x10.types.ClosureDef; import x10.types.FunctionType; import x10.types.ParameterType; import x10.types.X10ClassType; import polyglot.types.TypeSystem; import x10.types.constraints.CConstraint; import x10.types.constraints.CConstraint; import x10.types.constraints.ConstraintManager; import x10.visit.X10TypeChecker; public class FunctionTypeNode_c extends TypeNode_c implements FunctionTypeNode { List<TypeParamNode> typeParams; List<Formal> formals; DepParameterExpr guard; // List<TypeNode> throwTypes; TypeNode returnType; TypeNode offersType; public FunctionTypeNode_c(Position pos, List<TypeParamNode> typeParams, List<Formal> formals, TypeNode returnType, DepParameterExpr guard, TypeNode offersType) { super(pos); this.typeParams = TypedList.copyAndCheck(typeParams, TypeParamNode.class, true); this.formals = TypedList.copyAndCheck(formals, Formal.class, true); // this.throwTypes = TypedList.copyAndCheck(throwTypes, TypeNode.class, true); this.returnType = returnType; this.guard = guard; this.offersType = offersType; } @Override public Node disambiguate(ContextVisitor ar) { NodeFactory nf = (NodeFactory) ar.nodeFactory(); TypeSystem ts = (TypeSystem) ar.typeSystem(); FunctionTypeNode_c n = this; List<ParameterType> typeParams = new ArrayList<ParameterType>(n.typeParameters().size()); for (TypeParamNode tpn : n.typeParameters()) { typeParams.add(tpn.type()); } List<Ref<? extends Type>> formalTypes = new ArrayList<Ref<? extends Type>>(n.formals().size()); for (Formal f : n.formals()) { formalTypes.add(f.type().typeRef()); } List<LocalDef> formalNames = new ArrayList<LocalDef>(n.formals().size()); for (Formal f : n.formals()) { formalNames.add(f.localDef()); } //if (guard != null) // throw new SemanticException("Function types with guards are currently unsupported.", position()); if (guard != null && guard.typeConstraint() != null && !Types.get(guard.typeConstraint()).terms().isEmpty()) { Errors.issue(ar.job(), new SemanticException("Type constraints not permitted in function type guards.", position())); guard = guard.typeConstraint(null); } if (typeParams.size() != 0) { Errors.issue(ar.job(), new SemanticException("Function types with type parameters are currently unsupported.", position())); typeParams = Collections.<ParameterType>emptyList(); } FunctionType result = ts.functionType(position(), returnType.typeRef(), typeParams, formalTypes, formalNames, guard != null ? guard.valueConstraint() : Types.lazyRef(ConstraintManager.getConstraintSystem().makeCConstraint()) // guard != null ? guard.typeConstraint() : null, ); ((LazyRef<Type>) typeRef()).update(result); return nf.CanonicalTypeNode(position(), typeRef()); } /* * (non-Javadoc) * * @see x10.ast.FunctionTypeNode#returnType() */ public TypeNode returnType() { return this.returnType; } public TypeNode offersType() { return this.offersType; } /** Set the return type of the method. */ public FunctionTypeNode returnType(TypeNode returnType) { FunctionTypeNode_c n = (FunctionTypeNode_c) copy(); n.returnType = returnType; return n; } /* (non-Javadoc) * @see x10.ast.FunctionTypeNode#typeParameters() */ public List<TypeParamNode> typeParameters() { return Collections.<TypeParamNode> unmodifiableList(this.typeParams); } /** Set the formals of the method. */ public FunctionTypeNode typeParameters(List<TypeParamNode> typeParams) { FunctionTypeNode_c n = (FunctionTypeNode_c) copy(); n.typeParams = TypedList.copyAndCheck(typeParams, TypeParamNode.class, true); return n; } /* (non-Javadoc) * @see x10.ast.FunctionTypeNode#formals() */ public List<Formal> formals() { return Collections.<Formal> unmodifiableList(this.formals); } /** Set the formals of the method. */ public FunctionTypeNode formals(List<Formal> formals) { FunctionTypeNode_c n = (FunctionTypeNode_c) copy(); n.formals = TypedList.copyAndCheck(formals, Formal.class, true); return n; } /* (non-Javadoc) * @see x10.ast.FunctionTypeNode#guard() */ public DepParameterExpr guard() { return guard; } public FunctionTypeNode guard(DepParameterExpr guard) { FunctionTypeNode_c n = (FunctionTypeNode_c) copy(); n.guard = guard; return n; } /** Visit the children of the method. */ public Node visitChildren(NodeVisitor v) { List<TypeParamNode> typeParams = this.visitList(this.typeParams, v); List<Formal> formals = this.visitList(this.formals, v); DepParameterExpr guard = (DepParameterExpr) this.visitChild(this.guard, v); TypeNode returnType = (TypeNode) this.visitChild(this.returnType, v); return reconstruct(typeParams, formals, guard, returnType); } protected Node reconstruct(List<TypeParamNode> typeParams, List<Formal> formals, DepParameterExpr guard, TypeNode returnType) { FunctionTypeNode_c n = this; n = (FunctionTypeNode_c) n.typeParameters(typeParams); n = (FunctionTypeNode_c) n.formals(formals); n = (FunctionTypeNode_c) n.guard(guard); n = (FunctionTypeNode_c) n.returnType(returnType); return n; } public String toString() { StringBuilder sb = new StringBuilder(); if (typeParams.size() > 0) { sb.append("["); String sep = ""; for (TypeParamNode p : typeParams) { sb.append(sep); sb.append(p); sep = ", "; } sb.append("]"); } sb.append("("); String sep = ""; for (Formal p : formals) { sb.append(sep); sb.append(p); sep = ", "; } sb.append(")"); if (guard != null) sb.append(guard); sb.append(" => "); sb.append(returnType); return sb.toString(); } public void prettyPrint(CodeWriter w, PrettyPrinter tr) { w.begin(0); if (typeParams.size() > 0) { w.write("["); w.allowBreak(2, 2, "", 0); w.begin(0); for (Iterator<Formal> i = formals.iterator(); i.hasNext();) { Formal f = i.next(); print(f, w, tr); if (i.hasNext()) { w.write(","); w.allowBreak(0, " "); } } w.end(); w.write("]"); w.allowBreak(2, 2, " ", 1); } w.write("("); w.allowBreak(2, 2, "", 0); w.begin(0); for (Iterator<Formal> i = formals.iterator(); i.hasNext();) { Formal f = i.next(); print(f, w, tr); if (i.hasNext()) { w.write(","); w.allowBreak(0, " "); } } w.end(); w.write(")"); w.allowBreak(2, 2, " ", 1); if (guard != null) print(guard, w, tr); /* if (!throwTypes().isEmpty()) { w.allowBreak(6); w.write("throws "); for (Iterator<TypeNode> i = throwTypes().iterator(); i.hasNext();) { TypeNode tn = i.next(); print(tn, w, tr); if (i.hasNext()) { w.write(","); w.allowBreak(4, " "); } } } */ w.write(" => "); print(returnType, w, tr); w.end(); } }