private Type GetType(UHeaderParser.TypeContext context)
        {
            var name = context.typeName().GetText();

            if (_types.TryGetValue(name, out var val))
            {
                return(val);
            }

            if (name.StartsWith("E"))
            {
                return(Get(context, n => new Enum(n)));
            }
            if (name.EndsWith("Signature"))
            {
                return(Get(context, n => new Delegate(n)));
            }

            return(Get(context, n => new Class(n)));
        }
        private T Get <T>(UHeaderParser.TypeContext context, Func <string, T> activator) where T : Type
        {
            var    name             = context.typeName().GetText();
            string templateBaseName = null;

            if (name.Contains("<"))
            {
                templateBaseName = context.typeName().Identifier().First().GetText();
                var templateTypes = context.typeName().type();

                name  = templateBaseName;
                name += "__";
                name += string.Join(", ", templateTypes.Select(x => x.typeName().Identifier().First().GetText()));
            }

            if (_types.TryGetValue(name, out var val))
            {
                if (val is T)
                {
                    return((T)val);
                }

                throw new InvalidOperationException($"Элемент уже использован как {val.GetType()}");
            }

            var def = activator(name);

            def.TemplateBaseName = templateBaseName;
            _types.TryAdd(name, def);

            foreach (var nameContext in context.typeName().type())
            {
                def.TemplateTypes.Add(ParceType(nameContext));
            }

            return(def);
        }
        private Variable ParceType(UHeaderParser.TypeContext context)
        {
            var      typeName = context.typeName().GetText();
            Variable variable;

            if (PrimitiveVariable.PrimitiveTypes.Contains(typeName))
            {
                variable = new PrimitiveVariable(typeName);
            }
            else
            {
                var type = GetType(context);
                if (type is Class)
                {
                    variable = new ClassVariable((Class)type);
                }
                else if (type is Delegate)
                {
                    variable = new DelegateVariable((Delegate)type);
                }
                else if (type is Enum)
                {
                    variable = new EnumVariable((Enum)type);
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }

            variable.IsConst     = context.FoundChild <UHeaderParser.IsConstContext>();
            variable.IsPointer   = context.FoundChild <UHeaderParser.IsPtrQuantContext>();
            variable.IsReference = context.FoundChild <UHeaderParser.IsRefQuantContext>();
            variable.IsInterface = typeName.StartsWith("I");

            return(variable);
        }
 /// <summary>
 /// Visit a parse tree produced by <see cref="UHeaderParser.type"/>.
 /// <para>
 /// The default implementation returns the result of calling <see cref="AbstractParseTreeVisitor{Result}.VisitChildren(IRuleNode)"/>
 /// on <paramref name="context"/>.
 /// </para>
 /// </summary>
 /// <param name="context">The parse tree.</param>
 /// <return>The visitor result.</return>
 public virtual Result VisitType([NotNull] UHeaderParser.TypeContext context)
 {
     return(VisitChildren(context));
 }