public override AstNode Visit(MemberAccess node) { // Begin the node builder.BeginNode(node); // Get the reference expression. Expression baseRef = node.GetReference(); // Visit it. baseRef.Accept(this); // Get the reference and coercion type. IChelaType refType = baseRef.GetNodeType(); IChelaType coercionType = node.GetCoercionType(); if(refType != coercionType) Cast(node, baseRef.GetNodeValue(), refType, coercionType); // Cast generic place holders into something more appropiate. Scope memberParent = GetMemberParent(node); if(coercionType.IsPlaceHolderType() && memberParent.IsType()) { IChelaType targetType = (IChelaType)memberParent; if(targetType.IsPassedByReference()) targetType = ReferenceType.Create(targetType); // Cast the generic placeholder. builder.CreateGCast(targetType); } // Pop redundant reference. ScopeMember member = (ScopeMember)node.GetNodeValue(); if((coercionType.IsReference() || coercionType.IsStructure()) && member.IsStatic()) builder.CreatePop(); // Load the implicit this. if(node.ImplicitSelf) LoadCurrentSelf(); // Next checks are only for functions. IChelaType nodeType = node.GetNodeType(); if(!nodeType.IsFunctionGroup() && !nodeType.IsFunction()) return builder.EndNode(); // Handle virtual suppression. if(nodeType.IsFunctionGroup() && refType.IsMetaType()) { FunctionGroupSelector selector = (FunctionGroupSelector)node.GetNodeValue(); Function selected = selector.GetSelected(); // Load implicit this. if(!selected.IsStatic() && selector.ImplicitThis) LoadCurrentSelf(); } // Only primitives and structure can be boxed. IChelaType referencedType = DeReferenceType(coercionType); bool firstClass = referencedType.IsFirstClass(); bool structure = referencedType.IsStructure(); if(!firstClass && !structure) return builder.EndNode(); // Box structures when calling virtual methods. Method method = null; if(nodeType.IsFunctionGroup()) { // Set the must box flag. FunctionGroupSelector selector = (FunctionGroupSelector)node.GetNodeValue(); Function selected = selector.GetSelected(); if(selected == null) Error(node, "Trying to get unselected function."); if(selected.IsMethod()) method = (Method)selected; } else //if(nodeType.IsFunction()) { Function function = (Function)node.GetNodeValue(); if(function.IsMethod()) method = (Method)function; } // Only methods may require boxing. if(method != null) { if(!method.GetParentScope().IsStructure()) { // Must box. IChelaType boxType; if(firstClass) boxType = currentModule.GetAssociatedClass(referencedType); else boxType = referencedType; builder.CreateBox(boxType); } else if(firstClass) // Light primitive boxing. { builder.CreatePrimBox(currentModule.GetAssociatedClass(referencedType)); } } return builder.EndNode(); }
public override AstNode Visit(MemberAccess node) { // Get the node type. IChelaType variableType = node.GetNodeType(); // Ignore type references, namespaces and functions. if(variableType.IsMetaType() || variableType.IsNamespace() || variableType.IsFunctionGroup() || variableType.IsFunction()) return node; // The type must be a reference. variableType = DeReferenceType(variableType); // Now, it can be a constant if(variableType.IsConstant()) { // Perform constant expansion. FieldVariable field = (FieldVariable)node.GetNodeValue(); if(!field.IsExternal()) return field.GetInitializer().ToAstNode(node.GetPosition()); } return node; }
public override AstNode Visit(MemberAccess node) { // This is the same as VariableReference implementation. // Get the node type. IChelaType variableType = node.GetNodeType(); // Ignore type references, namespaces and functions. if(variableType.IsMetaType() || variableType.IsNamespace() || variableType.IsFunctionGroup() || variableType.IsFunction()) return node; // The type must be a reference. variableType = DeReferenceType(variableType); // Now, it must be a constant. if(!variableType.IsConstant()) Error(node, "constant initialization can't reference no constant variables."); // The node value, must be the constant variable. FieldVariable constantVar = (FieldVariable)node.GetNodeValue(); // Find the corresponding constant data. ConstantData depData; if(constants.TryGetValue(constantVar, out depData)) currentConstant.AddDependency(depData); return node; }