public int GetCurrentParameterIndex(CodeLocation where) { /* * if(args.ParsedExpression is PostfixExpression_MethodCall) * { * var mc = args.ParsedExpression as PostfixExpression_MethodCall; * * if(mc.ArgumentCount == 0) * return 0; * for(int i = 0; i < mc.ArgumentCount; i++) * { * if(where <= mc.Arguments[i].EndLocation) * return i+1; * } * }*/ var idx = args.CurrentlyTypedArgumentIndex; var ms = CurrentResult as MemberSymbol; ISemantic _u; if (ms != null && UFCSResolver.IsUfcsResult(ms, out _u)) { idx++; } return(idx); }
static void HandleDMethodOverload(ResolutionContext ctxt, bool eval, ISymbolValue baseValue, List <ISemantic> callArguments, bool returnBaseTypeOnly, List <AbstractType> argTypeFilteredOverloads, ref bool hasHandledUfcsResultBefore, MemberSymbol ms, ref AbstractType untemplatedMethod) { var dm = ms.Definition as DMethod; if (dm == null) { return; } ISemantic firstUfcsArg; bool isUfcs = UFCSResolver.IsUfcsResult(ms, out firstUfcsArg); // In the case of an ufcs, insert the first argument into the CallArguments list if (isUfcs && !hasHandledUfcsResultBefore) { callArguments.Insert(0, eval ? baseValue as ISemantic : firstUfcsArg); hasHandledUfcsResultBefore = true; } else if (!isUfcs && hasHandledUfcsResultBefore) // In the rare case of having a ufcs result occuring _after_ a normal member result, remove the initial arg again { callArguments.RemoveAt(0); hasHandledUfcsResultBefore = false; } if (dm.Parameters.Count == 0 && callArguments.Count > 0) { return; } var deducedTypeDict = new DeducedTypeDictionary(ms); var templateParamDeduction = new TemplateParameterDeduction(deducedTypeDict, ctxt); var back = ctxt.ScopedBlock; using (ctxt.Push(ms)) { if (ctxt.ScopedBlock != back) { ctxt.CurrentContext.DeducedTemplateParameters = deducedTypeDict; } bool add = true; int currentArg = 0; if (dm.Parameters.Count > 0 || callArguments.Count > 0) { bool hadDTuples = false; for (int i = 0; i < dm.Parameters.Count; i++) { var paramType = dm.Parameters[i].Type; // Handle the usage of tuples: Tuples may only be used as as-is, so not as an array, pointer or in a modified way.. if (paramType is IdentifierDeclaration && (hadDTuples |= TryHandleMethodArgumentTuple(ctxt, ref add, callArguments, dm, deducedTypeDict, i, ref currentArg))) { continue; } else if (currentArg < callArguments.Count) { if (!(add = templateParamDeduction.HandleDecl(null, paramType, callArguments[currentArg++]))) { break; } } else { // If there are more parameters than arguments given, check if the param has default values add = !(dm.Parameters[i] is DVariable) || (dm.Parameters[i] as DVariable).Initializer != null; // Assume that all further method parameters do have default values - and don't check further parameters break; } } // Too few args if (!hadDTuples && currentArg < callArguments.Count) { add = false; } } if (!add) { return; } // If type params were unassigned, try to take the defaults if (dm.TemplateParameters != null) { foreach (var tpar in dm.TemplateParameters) { if (deducedTypeDict[tpar] == null && !templateParamDeduction.Handle(tpar, null)) { return; } } } if (deducedTypeDict.AllParamatersSatisfied) { ms.DeducedTypes = deducedTypeDict.ToReadonly(); var bt = TypeDeclarationResolver.GetMethodReturnType(dm, ctxt) ?? ms.Base; if (eval || !returnBaseTypeOnly) { bt = new MemberSymbol(dm, bt, ms.DeclarationOrExpressionBase, ms.DeducedTypes) { Tag = ms.Tag } } ; if (dm.TemplateParameters == null || dm.TemplateParameters.Length == 0) { untemplatedMethod = bt; //ISSUE: Have another state that indicates an ambiguous non-templated method matching. } argTypeFilteredOverloads.Add(bt); } } }