Mercurial > projects > dang
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);