コード例 #1
0
ファイル: ThirdPass.cs プロジェクト: goric/cflat
        /// <summary>
        /// For now, this will only allow Classes to have fields and methods.
        /// So primitives like int, real, bool won't have any.
        /// </summary>
        /// <param name="n"></param>
        public override void VisitDerefField(ASTDereferenceField n)
        {
            //we're processing something of the form: lvalue.identifier

            //Make sure the lvalue is a type and the identifier exists
            CFlatType lhs = CheckSubTree(n.Object);

            if (lhs.IsClass)
            {
                TypeClass lvalue     = (TypeClass)lhs;
                var       descriptor = (ClassDescriptor)_scopeMgr.Find(lvalue.ClassName, p => p is ClassDescriptor);
                //check if a field exists.
                MemberDescriptor memberDesc = _scopeMgr.Find(n.Field, d => d is MemberDescriptor, descriptor.Scope) as MemberDescriptor;

                if (memberDesc != null && descriptor.Fields.Contains(memberDesc))
                {
                    if (memberDesc.Modifiers.Contains(PRIVATE_MODIFIER, StringComparer.InvariantCultureIgnoreCase))
                    {
                        if (!_scopeMgr.HasSymbolShallow(n.Field))
                        {
                            ReportError(n.Location, "Cannot reference the private member '{0}' on class '{1}' from class '{2}'", memberDesc.Name, memberDesc.ContainingClass.Name, _currentClass.ClassName);
                        }
                    }

                    if (memberDesc != null)
                    {
                        //hooray, code is valid
                        n.Descriptor = memberDesc;
                        n.CFlatType  = memberDesc.Type;

                        _lastSeenType = memberDesc.Type;
                    }
                    else
                    {
                        ReportError(n.Location, "'{0}' is not a field for type '{1}'", n.Field, TypeToFriendlyName(lvalue));
                    }
                }
                else
                {
                    ReportError(n.Location, "Field '{0}' does not exist for type '{1}'", n.Field, TypeToFriendlyName(lvalue));
                }
            }
            else
            {
                ReportError(n.Location, "Type '{0}' does not support fields.", TypeToFriendlyName(lhs));
            }
        }
コード例 #2
0
        public override void VisitDerefField(ASTDereferenceField n)
        {
            //visit the identifier
            n.Object.Visit(this);
            TypeBuilderInfo info  = _typeManager.GetBuilderInfo(_lastWalkedType.Name);
            FieldBuilder    field = info.FieldMap[n.Field];

            //store the type that we're dereferencing
            _lastWalkedType = field.FieldType;

            //see what we need to do after visiting the identifier
            if (!n.IsLeftHandSide)
            {
                _gen.Emit(OpCodes.Ldfld, field);
            }
            else
            {
                _assignmentCallback = gen => gen.Emit(OpCodes.Stfld, field); //set what needs to happen at the end of the assignment
            }
        }