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); } }