Esempio n. 1
0
        // 1. In some class's scope, classScope != kInvalidIndex;
        //    1.1 In the same class scope, return member function directly
        //    1.2 In the derive class scope, return member fucntion != kPrivate
        //    1.3 Return member function whose access == kPublic
        //
        // 2. In global scope, classScope == kInvalidIndex;
        public ProcedureNode GetMemberFunction(string procName, List <ProtoCore.Type> argTypeList, int classScope, out bool isAccessible, out int functionHostClassIndex, bool isStaticOrConstructor = false)
        {
            isAccessible           = false;
            functionHostClassIndex = Constants.kInvalidIndex;

            if (ProcTable == null)
            {
                return(null);
            }

            ProcedureMatchOptions opts = new ProcedureMatchOptions()
            {
                FunctionName   = procName,
                ParameterTypes = argTypeList,
                ExcludeAutoGeneratedThisProc = true,
                ExactMatchWithNumArgs        = false,
                ExactMatchWithArgTypes       = false,
                FilterCallback = x => (!isStaticOrConstructor) || (x.IsConstructor || x.IsStatic)
            };

            int functionIndex = ProcTable.GetFunctionBySignature(opts, out ProcedureNode procNode);

            if (functionIndex != Constants.kInvalidIndex)
            {
                int myClassIndex = TypeSystem.classTable.IndexOf(Name);
                functionHostClassIndex = myClassIndex;
                procNode = ProcTable.Procedures[functionIndex];

                if (classScope == Constants.kInvalidIndex)
                {
                    isAccessible = (procNode.AccessModifier == CompilerDefinitions.AccessModifier.Public);
                }
                else if (classScope == myClassIndex)
                {
                    isAccessible = true;
                }
                else if (TypeSystem.classTable.ClassNodes[classScope].IsMyBase(myClassIndex))
                {
                    isAccessible = (procNode.AccessModifier != CompilerDefinitions.AccessModifier.Private);
                }
                else
                {
                    isAccessible = (procNode.AccessModifier == CompilerDefinitions.AccessModifier.Public);
                }

                return(procNode);
            }

            if (Base != Constants.kInvalidIndex)
            {
                procNode = TypeSystem.classTable.ClassNodes[Base].GetMemberFunction(procName, argTypeList, classScope, out isAccessible, out functionHostClassIndex, isStaticOrConstructor);
            }

            return(procNode);
        }
Esempio n. 2
0
        public int IndexOf(string name, List <ProtoCore.Type> argTypeList, bool isStaticOrConstructor = false)
        {
            ProcedureMatchOptions opts = new ProcedureMatchOptions()
            {
                FunctionName   = name,
                ParameterTypes = argTypeList,
                ExcludeAutoGeneratedThisProc = true,
                ExactMatchWithNumArgs        = false,
                ExactMatchWithArgTypes       = false,
                FilterCallback = x => !isStaticOrConstructor || (x.IsStatic || x.IsConstructor)
            };

            return(GetFunctionBySignature(opts, out ProcedureNode _));
        }
Esempio n. 3
0
        /// <summary>
        /// Get function by its signature.
        /// </summary>
        /// <param name="opts">Matching options</param>
        /// <param name="outputProcNode">Output procedure node. Null if nothing is found</param>
        /// <returns>Index of the ProcedureNode in the Procedures list. Returns -1 If nothing is found</returns>
        internal int GetFunctionBySignature(ProcedureMatchOptions opts, out ProcedureNode outputProcNode)
        {
            int outputProcNodeIndex = Constants.kInvalidIndex;

            outputProcNode = null;

            // how many default parameters are used
            int smallestDefaultArgNum = int.MaxValue;

            for (int ii = 0; ii < Procedures.Count; ++ii)
            {
                var f = Procedures[ii];

                if (opts.FilterCallback(f) == false)
                {
                    continue;
                }

                if ((opts.FunctionName != f.Name) ||
                    (opts.ExcludeAutoGeneratedThisProc && f.IsAutoGeneratedThisProc) ||
                    (opts.IsStatic != null) && (opts.IsStatic != f.IsStatic) ||
                    (opts.IsConstructor != null) && (opts.IsConstructor != f.IsConstructor))
                {
                    goto NotMatch;
                }

                if (!f.IsActive)
                {
                    goto NotMatch;
                }

                if (opts.ParameterTypes != null)
                {
                    var argNum   = f.ArgumentTypes.Count;
                    var paramNum = opts.ParameterTypes.Count;

                    if (opts.ExactMatchWithNumArgs && (argNum != paramNum))
                    {
                        goto NotMatch;
                    }

                    if (opts.ExactMatchWithArgTypes)
                    {
                        for (int k = 0; k < paramNum; k++)
                        {
                            if (f.ArgumentTypes[k].Name != opts.ParameterTypes[k].Name || f.ArgumentTypes[k].UID != opts.ParameterTypes[k].UID)
                            {
                                goto NotMatch;
                            }
                        }
                    }

                    int defaultArgs = f.ArgumentInfos.Count(X => X.DefaultExpression != null);
                    if ((argNum < paramNum) || (defaultArgs < argNum - paramNum))
                    {
                        // The current procedure has either:
                        // too less arguments that we are looking for.
                        // or
                        // too many arguments(even with defaults) than we are looking for
                        goto NotMatch;
                    }

                    // Look for the function with the least amount of default arguments
                    var num = argNum - paramNum;
                    if (num <= smallestDefaultArgNum)
                    {
                        smallestDefaultArgNum = num;

                        outputProcNodeIndex = ii;
                        outputProcNode      = Procedures[ii];
                    }

                    if (smallestDefaultArgNum == 0)
                    {
                        break;
                    }
                }
                else
                {
                    outputProcNodeIndex = ii;
                    outputProcNode      = Procedures[ii];

                    break;
                }

NotMatch:
                ;
            }
            return(outputProcNodeIndex);
        }