public override AstNode Visit(FieldDefinition node) { // Add the parent static flag. if(currentContainer.IsStatic()) { MemberFlags oldInstance = node.GetFlags() & MemberFlags.InstanceMask; if(oldInstance == MemberFlags.Static || oldInstance == MemberFlags.Instanced) { MemberFlags flags = node.GetFlags() & ~MemberFlags.InstanceMask; node.SetFlags(flags | MemberFlags.Static); } else Error(node, "static class member cannot {0}.", oldInstance.ToString().ToLower()); } // Add the parent unsafe flag. if(IsUnsafe) { MemberFlags flags = node.GetFlags() & ~MemberFlags.SecurityMask; node.SetFlags(flags | MemberFlags.Unsafe); } return node; }
public override AstNode Visit(FieldDefinition node) { // Push the unsafe context. bool isUnsafe = (node.GetFlags() & MemberFlags.SecurityMask) == MemberFlags.Unsafe; if(isUnsafe) PushUnsafe(); // Get the type node. Expression typeExpression = node.GetTypeNode(); // Visit the type node. typeExpression.Accept(this); // Get the type of the type expression. IChelaType type = typeExpression.GetNodeType(); type = ExtractActualType(typeExpression, type); // Check field type security. if(type.IsUnsafe()) UnsafeError(node, "safe field with unsafe type."); // Class/interfaces instances are held by reference. if(type.IsPassedByReference()) type = ReferenceType.Create(type); // Constants are always static. if(type.IsConstant()) node.SetFlags((node.GetFlags() & ~MemberFlags.InstanceMask) | MemberFlags.Static); // Process the declarations. FieldDeclaration decl = node.GetDeclarations(); while(decl != null) { // Find an existent member. ScopeMember oldField = currentContainer.FindMember(decl.GetName()); if(oldField != null) Error(node, "already declared a member with the same name."); // Create the field. FieldVariable field = new FieldVariable(decl.GetName(), node.GetFlags(), type, currentContainer); field.Position = decl.GetPosition(); decl.SetVariable(field); decl.SetNodeType(type); // Add the field into the scope. if(currentContainer.IsStructure() || currentContainer.IsClass()) { // Add the field. Structure building = (Structure)currentContainer; building.AddField(field); } else if(currentContainer.IsNamespace()) { // Make sure its a global variable. if(!field.IsStatic()) Error(node, "namespaces only can have static fields."); Namespace space = (Namespace)currentContainer; space.AddMember(field); } else { Error(node, "a field must be declared inside an structure or class."); } // Process the next declaration. decl = (FieldDeclaration)decl.GetNext(); } if(isUnsafe) PopUnsafe(); return node; }