Ejemplo n.º 1
0
        // this method is called later, when all the objects' names are registered as references

        public void Define(AnalysisEnvironment environment, FunctionDeclaration decl)
        {
            if (this is Interop.ClrFunctionRecord)
            {
                return;
            }

            this.Declaration = decl;

            // evaluate the type used for current function. including the return types and parameter types.
            // a function is complete only when:

            // (1) its return type can be described with available types.
            // (2) all of its parameter types can be described with available types.
            // (3) all of the locals can be described with available types.
            // (4) all the references to outside is within the availble definitions.

            // (1) return type evaluation

            this.ReturnType = environment.GetDirectTypeRecord(decl.ReturnType);
            if (this.ReturnType is Record.IOperationType op)
            {
                op.Evaluate(environment);
            }
            else
            {
                this.ReturnType.GetIdentifer(this.Parent, environment);
            }

            // (2) parameter evaluation

            this.ParameterModifer.Clear();
            this.Parameters.Clear();
            this.ParameterSymbol.Clear();
            this.ParameterType.Clear();
            foreach (var param in decl.Parameters)
            {
                DataRecord data = new DataRecord();
                data.Definition         = environment.GetDirectTypeRecord(param.Type);
                data.ExplicitType       = param.Type;
                data.Expression         = param.Default;
                data.Symbol             = param.Identifer.Value;
                data.ClrTypeRecordIndex = data.Definition.ClrTypeRecordIndex;

                ParameterType.Add(data.Definition);
                ParameterSymbol.Add(data.Symbol, data.Oid);
                environment.SetObject(data.Oid, data);

                var modifers = Analysis.ParameterModifers.ByValue;
                foreach (var item in param.Modifers)
                {
                    switch (item.Value.ToLower())
                    {
                    case "readonly":
                        modifers |= ParameterModifers.Readonly; break;

                    case "extends":
                        modifers |= ParameterModifers.Extends; break;

                    case "byname":
                        modifers  = modifers & (~ParameterModifers.PassAttributes);
                        modifers |= ParameterModifers.ByName;
                        break;

                    case "byref":
                    case "byreference":
                        modifers  = modifers & (~ParameterModifers.PassAttributes);
                        modifers |= ParameterModifers.ByReference;
                        break;

                    case "byval":
                    case "byvalue":
                        modifers  = modifers & (~ParameterModifers.PassAttributes);
                        modifers |= ParameterModifers.ByValue;
                        break;

                    case "cdom":
                    case "currentdomain":
                        modifers |= ParameterModifers.CurrentDomain; break;
                    }
                }

                this.ParameterModifer.Add(modifers);
                this.Parameters.Add(param.Identifer.Value, data);
                data.ClrTypeRecordIndex = data.Definition.ClrTypeRecordIndex;
            }
        }