# HG changeset patch # User Anders Johnsen # Date 1216743855 -7200 # Node ID 7606387b2f0a4b3df56c8d450a7da1d36000326f # Parent ba94fd56354886914fb9cce6d93af9d38f1b8abe Better handling of param checking on method calls. diff -r ba94fd563548 -r 7606387b2f0a sema/TypeCheck.d --- a/sema/TypeCheck.d Tue Jul 22 16:53:47 2008 +0200 +++ b/sema/TypeCheck.d Tue Jul 22 18:24:15 2008 +0200 @@ -123,84 +123,48 @@ Symbol[] methods = exp.newType.getSymbol.findMembers("this"); - if ( exp.c_args.length ) + if (!methods.length) { - if ( !methods.length ) - { - messages.report(NoConstructor, exp.newType.loc); - return; - } + messages.report(NoConstructor, exp.newType.loc); + return; + } + + Symbol sel = getBestMatch(exp.c_args, methods); - Symbol[] possible; - Symbol perfect; - - foreach( s ; methods ) + if (sel) + { + foreach (i, arg; exp.c_args) { - bool per = true; - - foreach(i, arg; exp.c_args) + auto argType = sel.type.asFunction.params[i]; + auto expType = arg.type; + if (argType.byteSize != expType.byteSize) { - 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 (!expType.hasImplicitConversionTo(argType)) + messages.report(InvalidImplicitCast, exp.loc) + .arg(expType.toString) + .arg(argType.toString); - if ( perfect ) - sel = perfect; - else - if ( possible.length ) - sel = possible[0]; - - if ( sel ) + 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; + exp.callSym = sel; + } + else + { + messages.report(NoMachingCon, exp.newType.loc); + foreach ( i, s ; methods ) { - 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; - exp.callSym = sel; - } - 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)); - } + messages.report(CandidateNr, + (cast(FuncDecl)s.decl).identifier.loc) + .arg(Integer.toString(i+1)); } } } @@ -278,6 +242,60 @@ } } + private Symbol getBestMatch(Exp[] arg_list , Symbol[] available) + body + { + Symbol[] _a; + foreach (a ; available) + if (a.type.isFunction) + _a ~= a; + available = _a; + + assert(available.length, "No available methods in symbol-list."); + + Symbol[] possible; + Symbol perfect; + + foreach (s ; available) + { + if (s.type.asFunction.params.length < arg_list.length) + continue; + + bool per = true; + + foreach (i, arg; arg_list) + { + auto argType = s.type.asFunction.params[i]; + auto expType = arg.type; + if (argType != expType) + { + per = false; + if( !expType.hasImplicitConversionTo(argType) ) + break; + } + + if (i == arg_list.length-1) + { + bool work = true; + foreach (a ; (cast(FuncDecl)s.decl).funcArgs[i+1..$]) + if (a.init is null) + work = false; + + if (work) + if (per) + return s; + else + possible ~= s; + } + } + } + + if (possible.length) + return possible[0]; + + return null; + } + MessageHandler messages; } diff -r ba94fd563548 -r 7606387b2f0a tests/parser/new_1.d --- a/tests/parser/new_1.d Tue Jul 22 16:53:47 2008 +0200 +++ b/tests/parser/new_1.d Tue Jul 22 18:24:15 2008 +0200 @@ -1,2 +1,2 @@ class A{this(int y){}int x;}struct B -{}void main(){B b;long x;A a=new A(x);} +{}void main(){B b;long x;A a=new A(x);} int x = 5; int foo(){int y = 5; y = y + x * 5; return y;}