protected override bool LLEquals(TypeSpec obj, bool partialNameMatch)
        {
            ClosureTypeSpec spec = obj as ClosureTypeSpec;

            if (spec == null)
            {
                return(false);
            }

            if (partialNameMatch)
            {
                if (Arguments == null && spec.Arguments == null &&
                    ReturnType == null && spec.ReturnType == null)
                {
                    return(true);
                }
                if (Arguments == null || spec.Arguments == null)
                {
                    return(false);
                }
                if (ReturnType == null || spec.ReturnType == null)
                {
                    return(false);
                }
                return(Arguments.EqualsPartialMatch(spec.Arguments) &&
                       ReturnType.EqualsPartialMatch(spec.ReturnType));
            }
            else
            {
                var specArgs = spec.Arguments is TupleTypeSpec ? spec.Arguments : new TupleTypeSpec(spec.Arguments);
                var thisArgs = Arguments is TupleTypeSpec ? Arguments : new TupleTypeSpec(Arguments);
                return(BothNullOrEqual(thisArgs, specArgs) &&
                       BothNullOrEqual(ReturnType, spec.ReturnType));
            }
        }
        static bool ReplaceName(ClosureTypeSpec closure, string toFind, string replacement, ref TypeSpec result)
        {
            var resultArgs   = closure.Arguments;
            var resultReturn = closure.ReturnType;

            var argsChanged   = ReplaceName(closure.Arguments, toFind, replacement, ref resultArgs);
            var returnChanged = ReplaceName(closure.ReturnType, toFind, replacement, ref resultReturn);

            if (argsChanged || returnChanged)
            {
                result = new ClosureTypeSpec(resultArgs, resultReturn);
                return(true);
            }
            return(false);
        }
        ClosureTypeSpec ParseClosure(TypeSpec arg, bool throws)
        {
            TypeSpec returnType = Parse();

            if (returnType == null)
            {
                throw ErrorHelper.CreateError(ReflectorError.kTypeParseBase + 12, "Unexpected end while parsing a closure.");
            }
            ClosureTypeSpec closure = new ClosureTypeSpec();

            closure.Arguments  = arg;
            closure.ReturnType = returnType;
            closure.Throws     = throws;
            return(closure);
        }
        public bool IsBoundGeneric(BaseDeclaration context, TypeMapper mapper)
        {
            switch (this.Kind)
            {
            case TypeSpecKind.Named:
                NamedTypeSpec ns = (NamedTypeSpec)this;
                Entity        en = mapper.TryGetEntityForSwiftClassName(ns.Name);
                if (en == null)
                {
                    if (context.IsTypeSpecGeneric(ns))
                    {
                        return(false);                        // unbound
                    }
                }
                foreach (TypeSpec genParm in GenericParameters)
                {
                    if (genParm.IsUnboundGeneric(context, mapper))
                    {
                        return(false);                        // unbound
                    }
                }
                return(true);

            case TypeSpecKind.Closure:
                ClosureTypeSpec cs = (ClosureTypeSpec)this;
                return(cs.Arguments.IsBoundGeneric(context, mapper) && cs.ReturnType.IsBoundGeneric(context, mapper));

            case TypeSpecKind.Tuple:
                TupleTypeSpec ts = (TupleTypeSpec)this;
                foreach (TypeSpec elem in ts.Elements)
                {
                    if (elem.IsUnboundGeneric(context, mapper))
                    {
                        return(false);
                    }
                }
                return(true);

            default:
                throw new NotSupportedException("unknown TypeSpecKind " + this.Kind.ToString());
            }
        }
        public bool IsUnboundGeneric(BaseDeclaration context, TypeMapper mapper)
        {
            switch (Kind)
            {
            case TypeSpecKind.Named:
                NamedTypeSpec ns = (NamedTypeSpec)this;
                if (context.IsTypeSpecGeneric(ns.ToString()))
                {
                    return(true);
                }
                foreach (TypeSpec genparm in GenericParameters)
                {
                    if (genparm.IsUnboundGeneric(context, mapper))
                    {
                        return(true);
                    }
                }
                return(false);

            case TypeSpecKind.Closure:
                ClosureTypeSpec cs = (ClosureTypeSpec)this;
                return(cs.Arguments.IsUnboundGeneric(context, mapper) && cs.ReturnType.IsUnboundGeneric(context, mapper));

            case TypeSpecKind.Tuple:
                TupleTypeSpec ts = (TupleTypeSpec)this;
                foreach (TypeSpec elem in ts.Elements)
                {
                    if (elem.IsUnboundGeneric(context, mapper))
                    {
                        return(true);
                    }
                }
                return(false);

            case TypeSpecKind.ProtocolList:
                return(false);

            default:
                throw new NotSupportedException("unknown TypeSpecKind " + this.Kind.ToString());
            }
        }