示例#1
0
        void ParseTemplateBaseCursor(Cursor cursor)
        {
            var tokens = _context.TranslationUnit.Tokenize(cursor.Extent)
                         .TakeWhile(t => !t.Spelling.Equals("{"))
                         .SkipWhile(t => !t.Spelling.Equals(":"));

            if (!tokens.Any())
            {
                return;
            }

            var baseTokens = tokens.ToList();
            int templSpecStart = -1, templSpecEnd = -1;

            for (int i = 0; i < baseTokens.Count; i++)
            {
                var token = baseTokens[i];
                if (token.Spelling == "<")
                {
                    templSpecStart = i;
                }
                else if (token.Spelling == ">")
                {
                    templSpecEnd = i;
                }
            }

            if (templSpecStart != -1 && templSpecEnd != -1)
            {
                string template     = baseTokens[templSpecStart - 1].Spelling;
                string templateSpec = string.Join(" ",
                                                  baseTokens.GetRange(templSpecStart + 1, templSpecEnd - templSpecStart - 1)
                                                  .Select(t => t.Spelling));
                templateSpec = TypeRefDefinition.GetBasicName(templateSpec);

                string          templateName = $"{template}<{templateSpec}>";
                ClassDefinition classTemplate;
                if (!project.ClassDefinitions.TryGetValue(templateName, out classTemplate))
                {
                    var classTemplateNew = new ClassTemplateDefinition(template, _context.Header);
                    classTemplateNew.TemplateParameters.Add(templateSpec);

                    var baseTemplate = project.ClassDefinitions.FirstOrDefault(c => c.Value.Name.Equals(template));
                    classTemplateNew.BaseClass = baseTemplate.Value;

                    project.ClassDefinitions[templateName] = classTemplateNew;
                    _context.Header.Classes.Add(classTemplateNew);
                    classTemplate = classTemplateNew;
                }

                _context.Class.BaseClass = classTemplate;
            }
        }
        private void CopyTemplateMethods(ClassDefinition thisClass, ClassTemplateDefinition template,
                                         Dictionary <string, string> templateParams = null)
        {
            if (templateParams == null)
            {
                templateParams = new Dictionary <string, string>();
                var templateBase = template.BaseClass as ClassTemplateDefinition;

                for (int i = 0; i < template.TemplateParameters.Count; i++)
                {
                    string param      = templateBase.TemplateParameters[i];
                    string paramValue = template.TemplateParameters[i];
                    templateParams[param] = TypeRefDefinition.GetBasicName(paramValue);
                }

                CopyTemplateMethods(thisClass, templateBase, templateParams);
                return;
            }

            thisClass.BaseClass = template.BaseClass;

            var scriptedNameMapping = Project.ClassNameMapping as ScriptedMapping;

            if (scriptedNameMapping != null)
            {
                scriptedNameMapping.Globals.Header = thisClass.Header;
            }
            // TODO:
            //template.ManagedName = Project.ClassNameMapping.Map(template.Name);

            foreach (var templateClass in template.NestedClasses)
            {
                var classSpec = new ClassDefinition(templateClass.Name, thisClass.Header, thisClass);
                Project.ClassDefinitions.Add(classSpec.FullyQualifiedName, classSpec);

                foreach (var templateMethod in templateClass.Methods)
                {
                    SpecializeTemplateMethod(classSpec, templateMethod, templateParams);
                }
            }

            foreach (var templateMethod in template.Methods.Where(m => !m.IsConstructor))
            {
                SpecializeTemplateMethod(thisClass, templateMethod, templateParams);
            }
        }