This commit is contained in:
Hackerpilot 2015-10-30 16:28:16 -07:00
parent cc7d0112f3
commit 563df24b42
1 changed files with 56 additions and 24 deletions

View File

@ -31,15 +31,39 @@ final class MismatchedArgumentCheck : BaseAnalyzer
auto identVisitor = scoped!IdentVisitor; auto identVisitor = scoped!IdentVisitor;
identVisitor.visit(fce.unaryExpression); identVisitor.visit(fce.unaryExpression);
const(DSymbol)* sym = resolveSymbol(sc, const(DSymbol)*[] symbols = resolveSymbol(sc,
identVisitor.names.length > 0 ? identVisitor.names : [CONSTRUCTOR_SYMBOL_NAME]); identVisitor.names.length > 0 ? identVisitor.names : [CONSTRUCTOR_SYMBOL_NAME]);
// The cast is a hack because .array() confuses the compiler's overload
// resolution code. static struct ErrorMessage
const(istring)[] params = sym is null ? [] : sym.argNames[].map!(a => cast() a).array(); {
const ArgMismatch[] mismatches = compareArgsToParams(params, args); size_t line;
foreach (size_t i, ref const mm; mismatches) size_t column;
addErrorMessage(argVisitor.lines[i], argVisitor.columns[i], KEY, string message;
createWarningFromMismatch(mm)); }
ErrorMessage[] messages;
bool matched;
foreach (sym; symbols)
{
// The cast is a hack because .array() confuses the compiler's overload
// resolution code.
const(istring)[] params = sym is null ? [] : sym.argNames[].map!(a => cast() a).array();
const ArgMismatch[] mismatches = compareArgsToParams(params, args);
if (mismatches.length == 0)
matched = true;
else
{
foreach (size_t i, ref const mm; mismatches)
{
messages ~= ErrorMessage(argVisitor.lines[i], argVisitor.columns[i],
createWarningFromMismatch(mm));
}
}
}
if (!matched) foreach (m; messages)
addErrorMessage(m.line, m.column, KEY, m.message);
} }
alias visit = ASTVisitor.visit; alias visit = ASTVisitor.visit;
@ -117,29 +141,37 @@ final class ArgVisitor : ASTVisitor
istring[] args; istring[] args;
} }
const(DSymbol)* resolveSymbol(const Scope* sc, const istring[] symbolChain) const(DSymbol)*[] resolveSymbol(const Scope* sc, const istring[] symbolChain)
{ {
import std.array : empty; import std.array : empty;
const(DSymbol)*[] s = sc.getSymbolsByName(symbolChain[0]); const(DSymbol)*[] matchingSymbols = sc.getSymbolsByName(symbolChain[0]);
if (s.empty) if (matchingSymbols.empty)
return null; return null;
const(DSymbol)* sym = s[0]; foreach (ref symbol; matchingSymbols)
foreach (i; 1 .. symbolChain.length)
{ {
if (sym.kind == CompletionKind.variableName inner: foreach (i; 1 .. symbolChain.length)
|| sym.kind == CompletionKind.memberVariableName {
|| sym.kind == CompletionKind.functionName) if (symbol.kind == CompletionKind.variableName
sym = sym.type; || symbol.kind == CompletionKind.memberVariableName
if (sym is null) || symbol.kind == CompletionKind.functionName)
return null; symbol = symbol.type;
auto p = sym.getPartsByName(symbolChain[i]); if (symbol is null)
if (p.empty) {
return null; symbol = null;
sym = p[0]; break inner;
}
auto p = symbol.getPartsByName(symbolChain[i]);
if (p.empty)
{
symbol = null;
break inner;
}
symbol = p[0];
}
} }
return sym; return matchingSymbols;
} }
struct ArgMismatch struct ArgMismatch