/* * 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.types.ConstructorDef; import polyglot.types.ConstructorInstance; import polyglot.types.ConstructorInstance_c; import polyglot.types.Context; import polyglot.types.DerefTransform; import polyglot.types.ErrorRef_c; import polyglot.types.LocalDef; import polyglot.types.LocalInstance; import polyglot.types.MethodDef; import polyglot.types.ProcedureInstance; import polyglot.types.Ref; import polyglot.types.SemanticException; import polyglot.types.ContainerType; import polyglot.types.Type; import polyglot.types.TypeSystem; import polyglot.types.Types; import polyglot.types.UpcastTransform; import polyglot.util.CollectionUtil; import x10.util.CollectionFactory; import polyglot.util.InternalCompilerError; import polyglot.util.Position; import polyglot.util.Transformation; import polyglot.util.TransformingList; import x10.types.constraints.CConstraint; import x10.types.constraints.TypeConstraint; /** * An X10ConstructorInstance_c varies from a ConstructorInstance_c only in that it * maintains a returnType, and a guard. * * <p>If an explicit returnType is not declared in the constructor * then the returnType is simply the container together with the constraints * introduced by the property call in the body of the constructor (if the container has * properties). * * <p> It also has a typeParameteres() method. This currently returns null. * Constructor definitions may not specify type parameters. The type parameters of * the container are intended to be in effect in the constructor declaration. * * * @author vj * */ public class X10ConstructorInstance_c extends ConstructorInstance_c implements X10ConstructorInstance { private static final long serialVersionUID = 65438556574848648L; public X10ConstructorInstance_c(TypeSystem ts, Position pos, Position errorPos, Ref<? extends X10ConstructorDef> def) { super(ts, pos, errorPos, def); } @Override public boolean moreSpecific(Type ct, ProcedureInstance<ConstructorDef> p, Context context) { return Types.moreSpecificImpl(ct, this, p, context); } public X10ConstructorDef x10Def() { return (X10ConstructorDef) def(); } public Ref<? extends Type> offerType() { return x10Def().offerType(); } public List<Type> annotations() { return X10TypeObjectMixin.annotations(this); } public List<Type> annotationsMatching(Type t) { return X10TypeObjectMixin.annotationsMatching(this, t); } /* (non-Javadoc) * @see x10.types.X10ConstructorInstance#depClause() */ // public CConstraint constraint() { return Types.realX(returnType()); } public Ref<? extends Type> returnType; public Ref<? extends Type> returnTypeRef() { if (returnType == null) { return x10Def().returnType(); } return returnType; } public Type returnType() { if (returnType == null) { return x10Def().returnType().get(); } return Types.get(returnType); } public X10ConstructorInstance returnType(Type retType) { return returnTypeRef(Types.ref(retType)); } public X10ConstructorInstance returnTypeRef(Ref<? extends Type> retType) { if (retType == this.returnType) return this; X10ConstructorInstance_c n = (X10ConstructorInstance_c) copy(); n.returnType = retType; return n; } @Override public X10ConstructorInstance container(ContainerType container) { if (container == this.container) return this; return (X10ConstructorInstance) super.container(container); } @Override public boolean callValid(Type thisType, List<Type> argTypes, Context context) { // this should have been instantiated correctly; if so, the call is valid return true; } public List<Type> typeParameters() { return Collections.<Type>emptyList(); // [IP] TODO // return new TransformingList<ParameterType, Type>(((X10ParsedClassType) this.container()).x10Def().typeParameters(), new UpcastTransform<Type, ParameterType>()); } public X10ConstructorInstance typeParameters(List<Type> typeParameters) { if (typeParameters.size() != 0) throw new InternalCompilerError("Attempt to set type parameters of a constructor instance: "+this, this.position()); return this; // [IP] TODO // if (typeParameters.size() != x10Def().typeParameters().size()) // throw new InternalCompilerError("Attempt to set incorrect number of type parameters of a constructor instance: "+this+" params: "+typeParameters, this.position()); // // Set the container's type parameters instead // return (X10ConstructorInstance) this.container(((X10ParsedClassType) this.container()).typeArguments(typeParameters)); } public List<LocalInstance> formalNames; public List<LocalInstance> formalNames() { if (this.formalNames == null) { // Why is this not cached in this.formalNames? return new TransformingList<LocalDef, LocalInstance>(x10Def().formalNames(), new Transformation<LocalDef,LocalInstance>() { public LocalInstance transform(LocalDef o) { return o.asInstance(); } }); } return formalNames; } public X10ConstructorInstance formalNames(List<LocalInstance> formalNames) { if (formalNames == this.formalNames) return this; X10ConstructorInstance_c n = (X10ConstructorInstance_c) copy(); n.formalNames = formalNames; return n; } @Override public X10ConstructorInstance formalTypes(List<Type> formalTypes) { if (formalTypes == this.formalTypes) return this; return (X10ConstructorInstance) super.formalTypes(formalTypes); } private SemanticException error; public SemanticException error() { return error; } public X10ConstructorInstance error(SemanticException e) { if (e == this.error) return this; X10ConstructorInstance_c n = (X10ConstructorInstance_c) copy(); n.error = e; return n; } public String toString() { String s = designator() + " " + flags().prettyPrint() + signature(); return s; } public String signature() { StringBuilder sb = new StringBuilder(); sb.append(container().toString()); sb.append("."); sb.append(TypeSystem.CONSTRUCTOR_NAME); // [IP] Constructors don't have type parameters, they inherit them from the container. //List<String> params = new ArrayList<String>(); //List<Type> typeParameters = typeParameters(); //if (typeParameters != null) { // for (int i = 0; i < typeParameters.size(); i++) { // params.add(typeParameters.get(i).toString()); // } //} //if (params.size() > 0) { // sb.append("["); // sb.append(CollectionUtil.listToString(params)); // sb.append("]"); //} List<String> formals = new ArrayList<String>(); List<Type> formalTypes = formalTypes(); if (formalTypes != null) { List<LocalInstance> formalNames = formalNames(); for (int i = 0; i < formalTypes.size(); i++) { String s = ""; String t = formalTypes.get(i).toString(); if (formalNames != null && i < formalNames.size()) { X10LocalInstance a = (X10LocalInstance) formalNames.get(i); if (a != null && ! a.x10Def().isUnnamed()) s = a.name() + ": " + t; else s = t; } else { s = t; } formals.add(s); } } else { for (int i = 0; i < def().formalTypes().size(); i++) { formals.add(def().formalTypes().get(i).toString()); } } sb.append("("); sb.append(CollectionUtil.listToString(formals)); sb.append(")"); CConstraint guard = guard(); if (guard != null) sb.append(guard); else if (x10Def().guard() != null) sb.append(x10Def().guard()); TypeConstraint typeGuard = this.typeGuard(); if (typeGuard != null) sb.append(typeGuard); else if (x10Def().typeGuard() != null) sb.append(x10Def().typeGuard()); Ref<? extends Type> returnType = returnTypeRef(); if (returnType != null && returnType.known()) { sb.append(": "); sb.append(returnType); } return sb.toString(); } public boolean isValid() { return !(def instanceof ErrorRef_c<?>); } }