Пример #1
0
        public Namespace(
            Token namespaceToken,
            string name,
            TopLevelConstruct owner,
            LibraryMetadata library,
            FileScope fileScope,
            AnnotationCollection annotations)
            : base(namespaceToken, owner, fileScope)
        {
            this.Library     = library;
            this.DefaultName = name;
            this.FullyQualifiedDefaultName = owner == null
                ? name
                : (((Namespace)owner).FullyQualifiedDefaultName + "." + name);
            this.FullyQualifiedDefaultNameSegments = this.FullyQualifiedDefaultName.Split('.');
            this.DefaultNameSegments = this.DefaultName.Split('.');

            this.NamesByLocale = annotations.GetNamesByLocale(this.DefaultNameSegments.Length)
                                 .ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Split('.'));

            Locale defaultLocale = fileScope.CompilationScope.Locale;

            if (!this.NamesByLocale.ContainsKey(defaultLocale))
            {
                this.NamesByLocale[defaultLocale] = this.DefaultName.Split('.');
            }

            this.NestDepth = this.FullyQualifiedDefaultNameSegments.Length - this.DefaultNameSegments.Length;
        }
Пример #2
0
        private void BuildLocaleNameIdTableEntry(
            ParserContext parser,
            ByteBuffer output,
            ClassDefinition cd,
            Locale[] localesUsed,
            Locale classOriginalLocale)
        {
            // TODO: This would be so much easier if there was an interface. This is super goofy.
            List <TopLevelEntity>       topLevelConstructs = new List <TopLevelEntity>();
            List <AnnotationCollection> tlcAnnotations     = new List <AnnotationCollection>();
            List <string> tlcDefaultNames = new List <string>();
            List <int>    memberIds       = new List <int>();

            foreach (FieldDefinition field in cd.Fields)
            {
                if (field.Modifiers.HasStatic)
                {
                    continue;
                }
                topLevelConstructs.Add(field);
                tlcAnnotations.Add(field.Annotations);
                tlcDefaultNames.Add(field.NameToken.Value);
                memberIds.Add(field.MemberID);
            }
            foreach (FunctionDefinition method in cd.Methods)
            {
                if (method.Modifiers.HasStatic)
                {
                    continue;
                }
                topLevelConstructs.Add(method);
                tlcAnnotations.Add(method.Annotations);
                tlcDefaultNames.Add(method.NameToken.Value);
                memberIds.Add(method.MemberID);
            }

            // Apparently static members are getting allocated member ID's. They shouldn't be.
            // Adding this hack to get the total member count including static members.
            int effectiveMemberCount = topLevelConstructs.Count;
            int perceivedMemberCount = 0; // updated as members are encountered

            // Build a lookup of all the localized names by member ID by locale ID
            Dictionary <int, List <int> > nameIdByMemberIdByLocaleId = new Dictionary <int, List <int> >();

            for (int i = 0; i < effectiveMemberCount; ++i)
            {
                TopLevelEntity tlc      = topLevelConstructs[i];
                int            memberId = memberIds[i];
                perceivedMemberCount = Math.Max(memberId + 1, perceivedMemberCount);
                AnnotationCollection annotations = tlcAnnotations[i];
                string defaultName = tlcDefaultNames[i];
                Dictionary <Locale, string> localizedNames = annotations.GetNamesByLocale(1);
                localizedNames[classOriginalLocale] = defaultName;
                int defaultNameId = parser.LiteralLookup.GetNameId(defaultName);
                foreach (Locale locale in localesUsed)
                {
                    // If this locale isn't even used anywhere, don't bother adding it to the lookup.
                    int localeId = parser.GetLocaleId(locale);
                    if (localeId == -1)
                    {
                        throw new Exception();
                    }
                    List <int> nameIdByMemberId = null;
                    if (!nameIdByMemberIdByLocaleId.ContainsKey(localeId))
                    {
                        nameIdByMemberId = new List <int>();
                        nameIdByMemberIdByLocaleId[localeId] = nameIdByMemberId;
                    }
                    else
                    {
                        nameIdByMemberId = nameIdByMemberIdByLocaleId[localeId];
                    }
                    string name   = localizedNames.ContainsKey(locale) ? localizedNames[locale] : defaultName;
                    int    nameId = parser.LiteralLookup.GetNameId(name);
                    while (nameIdByMemberId.Count <= memberId)
                    {
                        nameIdByMemberId.Add(-1); // there are some gaps due to static members.
                    }
                    nameIdByMemberId[memberId] = nameId;
                }
            }

            List <int> op = new List <int>();

            op.Add(cd.ClassID);
            op.Add(perceivedMemberCount);
            foreach (int localeId in nameIdByMemberIdByLocaleId.Keys.OrderBy(k => k))
            {
                op.Add(localeId);
                List <int> nameIdsByMemberId = nameIdByMemberIdByLocaleId[localeId];
                for (int i = 0; i < perceivedMemberCount; ++i)
                {
                    int nameId = -1;
                    if (i < nameIdsByMemberId.Count)
                    {
                        int localizedNameId = nameIdsByMemberId[i];
                        if (localizedNameId != -1)
                        {
                            nameId = localizedNameId;
                        }
                    }
                    op.Add(nameId);
                }
            }

            output.Add(null, OpCode.LOC_TABLE, op.ToArray());
        }