public override AstNode Visit(EventAccessorDefinition node) { EventVariable eventVariable = node.GetEvent(); // Build the event flags. MemberFlags flags = node.GetFlags(); if(flags == MemberFlags.ImplicitVis) { flags = eventVariable.GetFlags(); } else { // TODO: Check compatibility. flags |= eventVariable.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 events cannot have a definition body."); // 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 argument. selfType = ReferenceType.Create(building); arguments.Add(selfType); } } // Add the value argument. arguments.Add(eventVariable.GetVariableType()); // Create the function type. FunctionType functionType = FunctionType.Create(ChelaType.GetVoidType(), arguments, false); // Build the function name. string functionName = node.GetName() + "_" + eventVariable.GetName(); // Create the function. Function accessor; if(selfType != null) accessor = new Method(functionName, flags, currentContainer); else accessor = new Function(functionName, flags, currentContainer); // Set the arguments. accessor.SetFunctionType(functionType); // Set the function position. accessor.Position = node.GetPosition(); // Store the function in the event. if(node.GetName() == "add") eventVariable.AddModifier = accessor; else eventVariable.RemoveModifier = accessor; // Store the function in his scope. if(currentContainer.IsStructure() || currentContainer.IsClass() || currentContainer.IsInterface()) { Structure building = (Structure)currentContainer; building.AddFunction(functionName, accessor); } else if(currentContainer.IsNamespace()) { Namespace space = (Namespace)currentContainer; space.AddMember(accessor); } else { Error(node, "an event 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, eventVariable.GetVariableType()); node.SetValueLocal(valueVar); // Store the scope node.SetScope(scope); } // Set the node function to the accessor. node.SetFunction(accessor); return node; }
public override AstNode Visit(EventAccessorDefinition node) { // Begin the node. builder.BeginNode(node); // Get the function. Function function = node.GetFunction(); // Ignore declarations. if(node.GetChildren() == null) return builder.EndNode(); // Store the old function. Function oldFunction = currentFunction; currentFunction = function; // Get the function lexical scope. LexicalScope topScope = (LexicalScope)node.GetScope(); PushScope(topScope); // Create the top basic block. BasicBlock topBlock = CreateBasicBlock(); topBlock.SetName("top"); builder.SetBlock(topBlock); // Prepare returning, required by exception handling. PrepareReturning(node, function, topScope); // Store the "value" argument in a local variable. int index = function.IsStatic() ? 0 : 1; LocalVariable valueLocal = node.GetValueLocal(); builder.CreateLoadArg((byte)index++); builder.CreateStoreLocal(valueLocal); // Visit his children. VisitList(node.GetChildren()); // Finish return. FinishReturn(node, function); // Restore the scope. PopScope(); // Restore the current function. currentFunction = oldFunction; return builder.EndNode(); }
public override AstNode Visit(EventAccessorDefinition node) { // Get the function. Function function = node.GetFunction(); if(node.GetChildren() == null) return node; // Store the old function. Function oldFunction = currentFunction; currentFunction = function; // Update the scope. PushScope(node.GetScope()); // Visit his children. VisitList(node.GetChildren()); // Restore the scope. PopScope(); // Restore the current function. currentFunction = oldFunction; return node; }