Exemplo n.º 1
0
        // Compile-time lookup of MemberRef.
        public MemberRef GetMemberRef(ExecContext context, string name, SEARCH searchType, ref ITypeDef typeDef)
        {
            // If there is an error during compliation then we can have an uninitialized
            // class on the stack. This check prevents us from throwing an exception
            // when that happens.
            // Kind of a kludge but handling errors during compilation is pretty chaotic
            // and I don't know what I could do other than to just abort on the first error.
            if (null == _fields)
            {
                return(MemberRef.invalid);
            }

            if (SEARCH.NORMAL == searchType || SEARCH.EITHER == searchType)
            {
                if (_fields.Exists(name))
                {
                    var member = _fields.Get(name);
                    typeDef = member.typeDef;

                    // If this member is getonly and we are not in this class's context, the type becomes const.
                    if (null != context && member.isGetonly)
                    {
                        ClassDef current = context.stack.GetCurrentClassDef();
                        if (null == current || (current != this && !current.IsChildOf(this)))
                        {
                            typeDef = TypeFactory.GetConstVersion(typeDef);
                        }
                    }

                    return(new MemberRef(member.index));
                }

                if (_memberFuncs.Exists(name))
                {
                    var member = _memberFuncs.Get(name);
                    typeDef = member.typeDef;
                    return(new MemberRef(this, MemberType.FUNCTION, member.index));
                }
            }

            if (SEARCH.STATIC == searchType || SEARCH.EITHER == searchType)
            {
                ClassDef def = this;
                while (null != def)
                {
                    if (def._statics.Exists(name))
                    {
                        ClassMember member = def._statics.Get(name);
                        typeDef = member.typeDef;

                        // If this member is getonly and we are not in this class's context, the type becomes const.
                        if (null != context && member.isGetonly)
                        {
                            ClassDef current = context.stack.GetCurrentClassDef();
                            if (null == current || (current != this && !current.IsChildOf(this)))
                            {
                                typeDef = TypeFactory.GetConstVersion(typeDef);
                            }
                        }

                        return(new MemberRef(def, MemberType.STATIC, member.index));
                    }
                    def = def.parent;
                }
            }

            return(MemberRef.invalid);
        }