diff dmd/TypeQualified.d @ 0:10317f0c89a5

Initial commit
author korDen
date Sat, 24 Oct 2009 08:42:06 +0400
parents
children 69d078c417c6
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/TypeQualified.d	Sat Oct 24 08:42:06 2009 +0400
@@ -0,0 +1,271 @@
+module dmd.TypeQualified;
+
+import dmd.Type;
+import dmd.Import;
+import dmd.TypeExp;
+import dmd.DotIdExp;
+import dmd.VarDeclaration;
+import dmd.EnumMember;
+import dmd.TupleDeclaration;
+import dmd.Id;
+import dmd.VarExp;
+import dmd.TemplateInstance;
+import dmd.Loc;
+import dmd.Array;
+import dmd.TY;
+import dmd.Identifier;
+import dmd.OutBuffer;
+import dmd.HdrGenState;
+import dmd.Scope;
+import dmd.Dsymbol;
+import dmd.DYNCAST;
+import dmd.Expression;
+import dmd.Util;
+
+class TypeQualified : Type
+{
+    Loc loc;
+    Array idents;	// array of Identifier's representing ident.ident.ident etc.
+
+    this(TY ty, Loc loc)
+	{
+		super(ty);
+		this.loc = loc;
+		
+		idents = new Array();
+	}
+	
+version (DumbClone) {
+} else {
+	Type clone()
+	{
+		assert(false);
+	}
+}	
+    void syntaxCopyHelper(TypeQualified t)
+	{
+		//printf("TypeQualified::syntaxCopyHelper(%s) %s\n", t->toChars(), toChars());
+		idents.setDim(t.idents.dim);
+		for (int i = 0; i < idents.dim; i++)
+		{
+			Identifier id = cast(Identifier)t.idents.data[i];
+			if (id.dyncast() == DYNCAST.DYNCAST_DSYMBOL)
+			{
+				TemplateInstance ti = cast(TemplateInstance)id;
+
+				ti = cast(TemplateInstance)ti.syntaxCopy(null);
+				id = cast(Identifier)ti;
+			}
+
+			idents.data[i] = cast(void*)id;
+		}
+	}
+	
+    void addIdent(Identifier ident)
+	{
+		idents.push(cast(void*)ident);
+	}
+	
+    void toCBuffer2Helper(OutBuffer buf, HdrGenState* hgs)
+	{
+		int i;
+
+		for (i = 0; i < idents.dim; i++)
+		{
+			Identifier id = cast(Identifier)idents.data[i];
+			buf.writeByte('.');
+
+			if (id.dyncast() == DYNCAST.DYNCAST_DSYMBOL)
+			{
+				TemplateInstance ti = cast(TemplateInstance)id;
+				ti.toCBuffer(buf, hgs);
+			} else {
+				buf.writestring(id.toChars());
+			}
+		}
+	}
+	
+    ulong size(Loc loc)
+	{
+		assert(false);
+	}
+	
+	/*************************************
+	* Takes an array of Identifiers and figures out if
+	 * it represents a Type or an Expression.
+	 * Output:
+	 *	if expression, *pe is set
+	 *	if type, *pt is set
+	 */
+    void resolveHelper(Loc loc, Scope sc, Dsymbol s, Dsymbol scopesym, Expression* pe, Type* pt, Dsymbol* ps)
+	{
+		VarDeclaration v;
+		EnumMember em;
+		TupleDeclaration td;
+		Expression e;
+
+static if (false) {
+		printf("TypeQualified.resolveHelper(sc = %p, idents = '%s')\n", sc, toChars());
+		if (scopesym)
+			printf("\tscopesym = '%s'\n", scopesym.toChars());
+}
+		*pe = null;
+		*pt = null;
+		*ps = null;
+		if (s)
+		{
+			//printf("\t1: s = '%s' %p, kind = '%s'\n",s.toChars(), s, s.kind());
+			s.checkDeprecated(loc, sc);		// check for deprecated aliases
+			s = s.toAlias();
+			//printf("\t2: s = '%s' %p, kind = '%s'\n",s.toChars(), s, s.kind());
+			for (int i = 0; i < idents.dim; i++)
+			{
+				Identifier id = cast(Identifier)idents.data[i];
+				Dsymbol sm = s.searchX(loc, sc, id);
+				//printf("\t3: s = '%s' %p, kind = '%s'\n",s.toChars(), s, s.kind());
+				//printf("\tgetType = '%s'\n", s.getType().toChars());
+				if (!sm)
+				{	
+					Type t;
+
+					v = s.isVarDeclaration();
+					if (v && id == Id.length)
+					{
+						e = v.getConstInitializer();
+						if (!e)
+							e = new VarExp(loc, v);
+						t = e.type;
+						if (!t)
+						goto Lerror;
+						goto L3;
+					}
+					t = s.getType();
+					if (!t && s.isDeclaration())
+						t = s.isDeclaration().type;
+					if (t)
+					{
+						sm = t.toDsymbol(sc);
+						if (sm)
+						{	sm = sm.search(loc, id, 0);
+						if (sm)
+							goto L2;
+						}
+						//e = t.getProperty(loc, id);
+						e = new TypeExp(loc, t);
+						e = t.dotExp(sc, e, id);
+						i++;
+					L3:
+						for (; i < idents.dim; i++)
+						{
+							id = cast(Identifier)idents.data[i];
+							//printf("e: '%s', id: '%s', type = %p\n", e.toChars(), id.toChars(), e.type);
+							if (id == Id.offsetof)
+							{   e = new DotIdExp(e.loc, e, id);
+								e = e.semantic(sc);
+							}
+							else
+								e = e.type.dotExp(sc, e, id);
+						}
+						*pe = e;
+					}
+					else
+					  Lerror:
+						error(loc, "identifier '%s' of '%s' is not defined", id.toChars(), toChars());
+					return;
+				}
+			L2:
+				s = sm.toAlias();
+			}
+
+			v = s.isVarDeclaration();
+			if (v)
+			{
+///static if (false) {
+///				// It's not a type, it's an expression
+///				Expression *e = v.getConstInitializer();
+///				if (e)
+///				{
+///					*pe = e.copy();	// make copy so we can change loc
+///					(*pe).loc = loc;
+///				}
+///				else
+///}
+				{
+///static if (false) {
+///					WithScopeSymbol withsym;
+///					if (scopesym && (withsym = scopesym.isWithScopeSymbol()) !is null)
+///					{
+///						// Same as wthis.ident
+///						e = new VarExp(loc, withsym.withstate.wthis);
+///						e = new DotIdExp(loc, e, ident);
+///						//assert(0);	// BUG: should handle this
+///					}
+///					else
+///}
+						*pe = new VarExp(loc, v);
+				}
+				return;
+			}
+			em = s.isEnumMember();
+			if (em)
+			{
+				// It's not a type, it's an expression
+				*pe = em.value.copy();
+				return;
+			}
+
+		L1:
+			Type t = s.getType();
+			if (!t)
+			{
+				// If the symbol is an import, try looking inside the import
+				Import si;
+
+				si = s.isImport();
+				if (si)
+				{
+					s = si.search(loc, s.ident, 0);
+					if (s && s != si)
+						goto L1;
+					s = si;
+				}
+				*ps = s;
+				return;
+			}
+			if (t.ty == TY.Tinstance && t != this && !t.deco)
+			{   
+				error(loc, "forward reference to '%s'", t.toChars());
+				return;
+			}
+
+			if (t != this)
+			{
+				if (t.reliesOnTident())
+				{
+					Scope scx;
+
+					for (scx = sc; 1; scx = scx.enclosing)
+					{
+						if (!scx)
+						{   
+							error(loc, "forward reference to '%s'", t.toChars());
+							return;
+						}
+						if (scx.scopesym == scopesym)
+							break;
+					}
+					t = t.semantic(loc, scx);
+					//((TypeIdentifier *)t).resolve(loc, scx, pe, &t, ps);
+				}
+			}
+			if (t.ty == TY.Ttuple)
+				*pt = t;
+			else
+				*pt = t.merge();
+		}
+		if (!s)
+		{
+			error(loc, "identifier '%s' is not defined", toChars());
+		}
+	}
+}
\ No newline at end of file