diff sema/TypeCheck.d @ 158:57b0b4464a0b

Parsing "new", putting it in AST and performs some tests on it. Eg. if the contructor exists and the params matches.
author Anders Johnsen <skabet@gmail.com>
date Tue, 22 Jul 2008 00:33:58 +0200
parents c3b24e7e8cf8
children 6cb2f4201e2a
line wrap: on
line diff
--- a/sema/TypeCheck.d	Mon Jul 21 22:14:06 2008 +0200
+++ b/sema/TypeCheck.d	Tue Jul 22 00:33:58 2008 +0200
@@ -1,9 +1,11 @@
 module sema.TypeCheck;
 
 import sema.Visitor,
+       sema.Symbol,
        sema.DType;
 
-import tango.io.Stdout;
+import tango.io.Stdout,
+       Integer = tango.text.convert.Integer;
 
 import basic.SourceLocation,
        basic.Message;
@@ -90,7 +92,7 @@
 
         foreach(i, arg; exp.args)
         {
-            auto argType = (cast(DFunction)exp.exp.type).params[i];
+            auto argType = exp.exp.type.asFunction.params[i];
             auto expType = arg.type;
             if(argType.byteSize != expType.byteSize)
             {
@@ -113,6 +115,95 @@
         exp.args = newArgs;
     }
 
+    override void visitNewExp(NewExp exp)
+    {
+        super.visitNewExp(exp);
+
+        Exp[] newArgs;
+        
+        Symbol[] methods = exp.newType.getSymbol.findMembers("this");
+
+        if ( exp.c_args.length )
+        {
+            if ( !methods.length )
+            {
+                messages.report(NoConstructor, exp.newType.loc);
+                return;
+            }
+
+            Symbol[] possible;
+            Symbol perfect;
+
+            foreach( s ; methods )
+            {
+                bool per = true;
+
+                foreach(i, arg; exp.c_args)
+                {
+                    auto argType = s.type.asFunction.params[i];
+                    auto expType = arg.type;
+                    if(argType != expType)
+                    {
+                        per = false;
+                        if( !expType.hasImplicitConversionTo(argType) )
+                            break;
+                    }
+
+                    if ( i == exp.c_args.length-1 
+                            && i == s.type.asFunction.params.length-1)
+                        if (per)
+                            perfect = s;
+                        else
+                            possible ~= s;
+                }
+            }
+
+            Symbol sel;
+
+            if ( perfect )
+                sel = perfect;
+            else
+                if ( possible.length )
+                    sel = possible[0];
+
+            if ( sel )
+            {
+                foreach(i, arg; exp.c_args)
+                {
+                    auto argType = sel.type.asFunction.params[i];
+                    auto expType = arg.type;
+                    if(argType.byteSize != expType.byteSize)
+                    {
+                        if(!expType.hasImplicitConversionTo(argType))
+                            messages.report(InvalidImplicitCast, exp.loc)
+                                .arg(expType.toString)
+                                .arg(argType.toString);
+
+                        auto castExp = new CastExp(
+                                SLoc.Invalid,
+                                new Identifier(argType.name),
+                                arg);
+                        castExp.env = exp.newType.env;
+                        newArgs ~= castExp;
+                    }
+                    else
+                        newArgs ~= arg;
+                }
+                exp.c_args = newArgs;
+            }
+            else
+            {
+                messages.report(NoMachingCon, exp.newType.loc);
+                foreach( i, s ; methods )
+                {
+                    messages.report(CandidateNr, 
+                            (cast(FuncDecl)s.decl).identifier.loc)
+                        .arg(Integer.toString(i+1));
+                }
+            }
+        }
+    }
+
     override void visitAssignExp(AssignExp exp)
     {
         super.visitAssignExp(exp);