예제 #1
0
        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);
                }
            }
        }