public override AstNode Visit(SetAccessorDefinition node) { PropertyVariable property = node.GetProperty(); if(node.GetChildren() == null && property.SetAccessor != null) return node; if(node.GetChildren() != null && property.SetAccessor != null) Error(node, "multiples definitions of the set accessor."); // Build the property flags. MemberFlags flags = node.GetFlags(); if(flags == MemberFlags.ImplicitVis) { flags = property.GetFlags(); } else { // TODO: Check compatibility. flags |= property.GetFlags() & ~MemberFlags.VisibilityMask; } // Get the instance type. MemberFlags instanceFlags = MemberFlags.InstanceMask & flags; // Abstract properties cannot have a body. if((instanceFlags == MemberFlags.Abstract || instanceFlags == MemberFlags.Contract) && node.GetChildren() != null) Error(node, "abstract properties cannot have a definition body."); // Create the set accesor. if(property.SetAccessor == null) { // Create the argument list. List<IChelaType> arguments = new List<IChelaType> (); // Add the this argument. IChelaType selfType = null; if(currentContainer.IsStructure() || currentContainer.IsClass() || currentContainer.IsInterface()) { Structure building = (Structure) currentContainer; if(instanceFlags != MemberFlags.Static) { // Instance the building. building = building.GetSelfInstance(); // Create the self parameter. selfType = ReferenceType.Create(building); arguments.Add(selfType); } } // Append the indices. foreach(IChelaType indexType in property.Indices) arguments.Add(indexType); // Add the value argument. arguments.Add(property.GetVariableType()); // Create the function type. FunctionType functionType = FunctionType.Create(ChelaType.GetVoidType(), arguments, false); // Create the function. Function accessor; if(selfType != null) accessor = new Method("set_" + property.GetName(), flags, currentContainer); else accessor = new Function("set_" + property.GetName(), flags, currentContainer); // Set the arguments. accessor.SetFunctionType(functionType); // Set the function position. accessor.Position = node.GetPosition(); // Store the function in the property. property.SetAccessor = accessor; // Store the function in his scope. if(currentContainer.IsStructure() || currentContainer.IsClass() || currentContainer.IsInterface()) { Structure building = (Structure)currentContainer; building.AddFunction("set_" + property.GetName(), accessor); } else if(currentContainer.IsNamespace()) { Namespace space = (Namespace)currentContainer; space.AddMember(accessor); } else { Error(node, "a property cannot be declared here."); } // If there's a body, declare the "argument" variables. if(node.GetChildren() != null) { LexicalScope scope = CreateLexicalScope(node, accessor); // Add the "this" local. if(selfType != null) new ArgumentVariable(0, "this", scope, selfType); // Add the "value" local LocalVariable valueVar = new LocalVariable("value", scope, property.GetVariableType()); node.SetValueLocal(valueVar); // Add the indices variables. AstNode index = node.GetIndices(); List<LocalVariable> indexerVars = new List<LocalVariable> (); while(index != null) { // Create the local LocalVariable local = new LocalVariable(index.GetName(), scope, index.GetNodeType()); indexerVars.Add(local); // Process the next. index = index.GetNext(); } node.SetIndexerVariables(indexerVars); node.SetScope(scope); } } else { // Check for declaration compatibility. if(flags != property.SetAccessor.GetFlags()) Error(node, "incompatible set accessor declarations."); } // Set the node function to the accessor. node.SetFunction(property.SetAccessor); return node; }