Exemple #1
0
        //internal FullName(Name[] parts, Int32 fromIndex)
        //{
        //   _mNames = parts;
        //   _mFromIndex = fromIndex;
        //   _mRaw = null;
        //   IsTopLevelConst = false;
        //}
        private FullName(NamePart[] parts, Int32 fromIndex)
        {
            Debug.Assert(parts.All(p => p.TypeParameters != null));

             _mNames = parts;
             _mFromIndex = fromIndex;
             _mRaw = null;
             IsTopLevelConst = false;
        }
Exemple #2
0
        internal FullName(NamePart[] parts, Boolean isTopLevelConst = false)
        {
            _mNames = parts;
             _mFromIndex = 0;
             _mRaw = null;

             Debug.Assert(!isTopLevelConst || parts.Length == 1);
             Debug.Assert(parts.All(p => p.TypeParameters != null));

             IsTopLevelConst = isTopLevelConst;
        }
Exemple #3
0
        private CapnpType _ResolveName(NamePart part, CapnpComposite nameScope, CapnpBoundGenericType genericScope = null)
        {
            var result = _ResolveName(part.Name);

            if (result == null)
            {
                // Todo: this is somewhat "bolted" on, can we unify with generics?
                if (part.Name == "List" && part.TypeParameters.Length == 1)
                {
                    var param = nameScope.ResolveFullName(part.TypeParameters[0]);
                    if (param == null)
                    {
                        return(null);
                    }
                    return(new CapnpList
                    {
                        Parameter = param
                    });
                }
            }

            // E.g. an unresolved Using.
            if (result is CapnpReference)
            {
                return(result);
            }

            if (result is CapnpGenericType)
            {
                // Resolve generic parameters given our generic state.
                // Note that the name could refer to a generic parameter creating a *partially closed* type.
                var generic = (CapnpGenericType)result;

                // We don't allow *partial* closing of a generic type (there's no syntax for it).
                if (generic.TypeParameters.Length != part.TypeParameters.Length && part.TypeParameters.Length > 0)
                {
                    return(null);
                }

                // Nothing to parameterize.
                if (generic.TypeParameters.Length == 0 && part.TypeParameters.Length > 0)
                {
                    return(null);
                }

                // If the type does not actually have generic parameters, and we're not a nested type of a generic type, we're done.
                if (!generic.IsGeneric && genericScope == null)
                {
                    return(result);
                }

                Debug.Assert(generic.TypeParameters.Length == part.TypeParameters.Length || part.TypeParameters.Length == 0);

                var resolvedParams = part.TypeParameters.Length == 0 ? generic.TypeParameters : // the type is fully open
                                     part.TypeParameters.Select(p => nameScope.ResolveFullName(p)).ToArray();

                // If any of the type parameters are unresolved, we have to wait.
                if (resolvedParams.Any(p => p == null || p is CapnpReference))
                {
                    return(null);
                }

                // The generic scope is the scope in which generic parameters our bound.
                // If none are defined the parent scope is closed using just the generic parameters.
                var parentScope = genericScope ?? generic.Scope.MakeOpenGenericType();

                return(new CapnpBoundGenericType
                {
                    OpenType = generic,
                    ParentScope = parentScope,
                    TypeParameters = resolvedParams
                });
            }
            else if (result is CapnpBoundGenericType)
            {
                var closed = (CapnpBoundGenericType)result;

                if (part.TypeParameters.Length > 0 && closed.TypeParameters.Length != part.TypeParameters.Length)
                {
                    return(null);
                }

                var resolvedParams = closed.TypeParameters;

                if (part.TypeParameters.Length > 0)
                {
                    // Cannot be partially closed and it makes no sense to close an already fully closed generic type
                    Debug.Assert(closed.TypeParameters.All(p => (p is CapnpGenericParameter)));

                    resolvedParams = part.TypeParameters.Select(p => nameScope.ResolveFullName(p)).ToArray();
                    if (resolvedParams.Any(p => p == null || p is CapnpReference))
                    {
                        return(null);
                    }
                }

                // Return a new closed generic whose scope is the current genericScope if defined.
                // Note that in the case both genericScope and clode.ParentScope exist, genericScope is "more closed" but point
                // to the same open type.
                Debug.Assert(genericScope == null || closed.ParentScope == null || genericScope.OpenType == closed.ParentScope.OpenType);

                return(new CapnpBoundGenericType
                {
                    OpenType = closed.OpenType,
                    ParentScope = genericScope ?? closed.ParentScope,
                    TypeParameters = resolvedParams
                });
            }
            else if (part.TypeParameters.Length > 0)
            {
                // The name defines generic parameters but the type is not generic.
                return(null);
            }
            else if (result is CapnpGenericParameter)
            {
                return(result);
            }
            else if (genericScope != null)
            {
                // An annotation or enumeration or whatever contained within a generic struct is itself generic.
                return(new CapnpBoundGenericType
                {
                    OpenType = (CapnpNamedType)result,
                    ParentScope = genericScope,
                    TypeParameters = Empty <CapnpType> .Array
                });
            }
            else
            {
                return(result);
            }
        }