/* * 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 * * This file was originally derived from the Polyglot extensible compiler framework. * * (C) Copyright 2000-2007 Polyglot project group, Cornell University * (C) Copyright IBM Corporation 2007-2012. */ package polyglot.types; import java.util.*; import polyglot.util.*; import x10.types.MethodInstance; /** * An <code>ArrayType</code> represents an array of base java types. */ public class JavaArrayType_c extends ReferenceType_c implements JavaArrayType { private static final long serialVersionUID = 5957743833621743101L; protected Ref<? extends Type> base; protected List<FieldDef> fields; protected List<MethodDef> methods; protected List<Ref<? extends Type>> interfaces; /** Used for deserializing types. */ protected JavaArrayType_c() { } public JavaArrayType_c(TypeSystem ts, Position pos, Ref<? extends Type> base) { super(ts, pos, pos); this.base = base; methods = null; fields = null; interfaces = null; } protected void init() { if (methods == null) { methods = new ArrayList<MethodDef>(1); // Add method public Object clone() MethodDef mi = ts.methodDef(position(), position(), Types.<JavaArrayType_c>ref(this), ts.Public(), Types.<Type>ref(ts.Any()), Name.make("clone"), Collections.<Ref<? extends Type>>emptyList(), Collections.<Ref<? extends Type>>emptyList()); methods.add(mi); } if (fields == null) { fields = new ArrayList<FieldDef>(1); // Add field public final int length FieldDef fi = ts.fieldDef(position(), Types.<JavaArrayType_c>ref(this), ts.Public().Final(), Types.ref(ts.Int()), Name.make("length")); fi.setNotConstant(); fields.add(fi); } if (interfaces == null) { interfaces = new ArrayList<Ref<? extends Type>>(2); } } public Ref<? extends Type> theBaseType() { return base; } /** Get the base type of the array. */ public Type base() { return Types.get(base); } /** Set the base type of the array. */ public JavaArrayType base(Type base) { return base(Types.ref(base)); } public JavaArrayType base(Ref<? extends Type> base) { if (base == this.base) return this; JavaArrayType_c n = (JavaArrayType_c) copy(); n.base = base; return n; } /** Get the ulitimate base type of the array. */ public Type ultimateBase() { if (base().isArray()) { return base().toArray().ultimateBase(); } return base(); } public int dims() { return 1 + (base().isArray() ? base().toArray().dims() : 0); } public String typeToString() { return base.toString() + "[]"; } public void print(CodeWriter w) { base().print(w); w.write("[]"); } /** Translate the type. */ public String translate(Resolver c) { return base().translate(c) + "[]"; } public boolean isArray() { return true; } public JavaArrayType toArray() { return this; } /** Get the methods implemented by the array type. */ public List<MethodInstance> methods() { init(); return new TransformingList<MethodDef,MethodInstance>(methods, new MethodAsTypeTransform()); } /** Get the fields of the array type. */ public List<FieldInstance> fields() { init(); return new TransformingList<FieldDef,FieldInstance>(fields, new FieldAsTypeTransform()); } /** Get the clone() method. */ public MethodInstance cloneMethod() { return methods().get(0); } /** Get a field of the type by name. */ public FieldInstance fieldNamed(Name name) { FieldInstance fi = lengthField(); return name.equals(fi.name()) ? fi : null; } /** Get the length field. */ public FieldInstance lengthField() { return fields().get(0); } /** Get the super type of the array type. */ public Type superClass() { return ts.Any(); } /** Get the interfaces implemented by the array type. */ public List<Type> interfaces() { init(); return new TransformingList<Ref<? extends Type>,Type>(interfaces, new DerefTransform<Type>()); } public int hashCode() { return base().hashCode() << 1; } public boolean equalsImpl(TypeObject t) { if (t instanceof JavaArrayType) { JavaArrayType a = (JavaArrayType) t; return ts.equals((TypeObject) base(), (TypeObject) a.base()); } return false; } public boolean isX10Struct() { return false; } public Type makeX10Struct() { throw new InternalCompilerError("Should not have been called. Cannot make an Unknown type a struct."); } }