// 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; } }