/* * 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.List; import polyglot.types.ErrorRef_c; import polyglot.types.FieldInstance; import polyglot.types.FieldInstance_c; import polyglot.types.Flags; 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.util.CollectionUtil; import x10.util.CollectionFactory; import polyglot.util.InternalCompilerError; import polyglot.util.Position; import x10.constraint.XFailure; import x10.constraint.XLocal; import x10.constraint.XVar; import x10.constraint.XTerm; import x10.types.constraints.CConstraint; import x10.types.constraints.CConstraint; import x10.types.constraints.ConstraintManager; /** * * @author vj * */ public class X10FieldInstance_c extends FieldInstance_c implements X10FieldInstance { private static final long serialVersionUID = 2257055113898437924L; public X10FieldInstance_c(TypeSystem ts, Position pos, Ref<? extends X10FieldDef> def) { super(ts, pos, def); } public X10FieldDef x10Def() { return (X10FieldDef) def(); } public List<Type> annotations() { return X10TypeObjectMixin.annotations(this); } public List<Type> annotationsMatching(Type t) { return X10TypeObjectMixin.annotationsMatching(this, t); } public boolean isProperty() { return x10Def().isProperty(); } // public Type leftType() { // return super.type(); // } @Override public X10FieldInstance type(Type type) { // clear the right type so we recompute it. return type(type, null); } public X10FieldInstance type(Type type, Type rightType) { if (type == this.type) return this; X10FieldInstance_c fi = (X10FieldInstance_c) super.type(type); assert fi != this; fi.rightType = rightType; return fi; } @Override public X10FieldInstance container(ContainerType container) { if (container == this.container) return this; return (X10FieldInstance) super.container(container); } Type rightType; public Type rightType() { TypeSystem xts = (TypeSystem) ts; // vj: Force a recomputation if rightType is UnknownType. // this.type() may have changed -- though this.type might not!! // However we have no way of resetting rightType when // this.type() changes. However, this.type() should change only // monotonically from unknown to some known value. // Hence force a recompute each time rightType() is called // if .rightType is an UnknownType. if (rightType == null || xts.isUnknown(rightType)) { Type t = type(); // If the field is final, replace T by T{self==t} Flags flags = flags(); if (flags.isFinal()) { if (xts.isUnknown(t)) { rightType = t; } else { CConstraint rc = Types.xclause(t); rc = rc==null ? ConstraintManager.getConstraintSystem().makeCConstraint() : rc.copy(); XTerm receiver; if (flags.isStatic()) { receiver = xts.xtypeTranslator().translate(container()); // Do not add self binding for static fields. This information // is any way going to get added in instantiateAccess. XTerm self = xts.xtypeTranslator().translate(receiver, this); // Add {self = receiver.field} clause. rc.addSelfBinding(self); } else { receiver = x10Def().thisVar(); assert receiver != null; XTerm self = xts.xtypeTranslator().translate(receiver, this); // Add {self = receiver.field} clause. rc.addSelfBinding(self); rc.setThisVar((XVar) receiver); } rightType = Types.xclause(Types.baseType(t), rc); } } else { rightType = t; } assert rightType != null; } return rightType; } private SemanticException error; public SemanticException error() { return error; } public X10FieldInstance error(SemanticException e) { if (e == this.error) return this; X10FieldInstance_c n = (X10FieldInstance_c) copy(); n.error = e; return n; } public String containerString() { Type container = container(); container = Types.baseType(container); if (container instanceof FunctionType) { return "(" + container.toString() + ")"; } return container.fullName().toString(); } public String toString() { return "field " + flags().prettyPrint() + containerString() + "." + name() + ": " + safeType(); } public boolean isValid() { return !(def instanceof ErrorRef_c<?>); } }