/// <summary> /// Generic attribute reference handling. /// /// IDENTIFIER /// </summary> /// <param name="context"></param> public override void EnterGeneric_attribute_reference(KryptonParser.Generic_attribute_referenceContext context) { var parent = _typeReferenceContainers.Peek(); var name = context.IDENTIFIER().GetText(); var type = new GenericAttribute(name); var reference = new FormalTypeReference(type, null); parent.AddTypeReference(reference); }
/// <summary> /// Type reference entry. /// /// (namespace_reference '::')? type_name generic_types? /// </summary> /// <param name="context"></param> public override void EnterType_reference(KryptonParser.Type_referenceContext context) { // pass if we are a generic attribute reference. var attribute = context.generic_attribute_reference(); if (attribute != null) { return; } var parent = _typeReferenceContainers.Peek(); var name = context.type_name().GetText(); var ns = context.namespace_reference()?.GetText() ?? ""; // if "this" is the namespace we are referencing the local context // setting the namespace to nothing will make us look through the active context first if (ns == LocalNamespaceToken) { ns = ""; } var path = ns.Split(new[] { NamespaceDelimiterToken }, StringSplitOptions.RemoveEmptyEntries); var activeContext = _contextStack.Peek(); // Resolve the member reference if (!TryResolveMember(path, name, activeContext, out var member)) { throw new KryptonParserException($"Unable to resolve type {ns} {name}"); } IType type; // If we are a generic type... var generic = context.generic_types() != null; if (generic) { type = new GenericType(name); _typeReferenceContainers.Push((ITypeReferenceContainer)type); } else { type = new ConcreteType(name); } // Create a type reference and add it to our parent. var reference = new FormalTypeReference(type, member.Parent); parent.AddTypeReference(reference); }