Пример #1
0
        private TypeReference InnerResolveType(ILocation location, TypeName type, bool throwIfNoMatch)
        {
            Require.Assigned(location);
            if (type.IsFunction || !type.HasNamespace || (type.TemplateParameters.Count > 0))
            {
                if (localResolveCache.ContainsKey(type.Data))
                {
                    TypeReference t = localResolveCache[type.Data];
                    if ((t != null) || (!throwIfNoMatch))
                    {
                        return(t);
                    }
                }
            }
            else
            {
                if (resolveCache.ContainsKey(type.Data))
                {
                    TypeReference t = resolveCache[type.Data];
                    if ((t != null) || (!throwIfNoMatch))
                    {
                        return(t);
                    }
                }
            }
            TypeReference result;
            TypeName      original = type;

            if (type.Nullable)
            {
                result = InnerResolveType(location, new TypeName(type, Nullability.NotNullable), throwIfNoMatch);
            }
            else
            {
                if (type.IsFunction)
                {
                    result = type.ResolveFunctionType(this);
                }
                else
                {
                    if (type.HasNamespace)
                    {
                        if (type.TemplateParameters.Count > 0)
                        {
                            TypeName resolvedInnerName = new TypeName(type.PrimaryName);
                            resolvedInnerName.SetHasNamespace();
                            foreach (TypeName templateParameter in type.TemplateParameters)
                            {
                                TypeReference t = InnerResolveType(templateParameter, templateParameter, throwIfNoMatch);
                                if ((!throwIfNoMatch) && (t == null))
                                {
                                    return(null);
                                }
                                if (t.TypeName.Data.StartsWith("MapBucket"))
                                {
                                    t = InnerResolveType(templateParameter, templateParameter, throwIfNoMatch);
                                    throw new Exception("boom");
                                }
                                resolvedInnerName.AddTemplateParameter(t.TypeName);
                            }
                            type = resolvedInnerName;
                        }
                        LoadType(type);
                        if ((!store.HasDefinition(type)) && store.HasTemplateDefinition(type))
                        {
                            List <TypeReference> parameters = new List <TypeReference>();
                            foreach (TypeName templateParameter in type.TemplateParameters)
                            {
                                TypeReference t = InnerResolveType(templateParameter, templateParameter, throwIfNoMatch);
                                if ((!throwIfNoMatch) && (t == null))
                                {
                                    return(null);
                                }
                                parameters.Add(t);
                            }
                            store.InstantiateTemplate(type, parameters);
                        }
                        result = ResolveTypeFullyQualified(location, type, throwIfNoMatch);
                    }
                    else
                    {
                        if (type.TemplateParameters.Count > 0)
                        {
                            TypeName outerType = new TypeName(type.PrimaryName);
                            foreach (TypeName innerName in type.TemplateParameters)
                            {
                                TypeReference t = InnerResolveType(location, innerName, throwIfNoMatch);
                                if ((!throwIfNoMatch) && (t == null))
                                {
                                    return(null);
                                }
                                outerType.AddTemplateParameter(t.TypeName);
                            }
                            type = outerType;
                        }

                        if (imports.Count == 0)
                        {
                            imports.Put(""); // when no imports are found, assume baseline system
                        }
                        if (!imports.Contains("pluk.base"))
                        {
                            imports.Put("pluk.base"); // this may seem silly, bit if we come here recursively this avoids a concurrent modifiecation assertion
                        }
                        result = null;
                        foreach (string ns in imports)
                        {
                            TypeName fullname = type.Prefix(ns);
                            result = InnerResolveType(location, fullname, false);
                            if (result != null)
                            {
                                type = fullname;
                                break;
                            }
                        }
                        if (result == null)
                        {
                            if (throwIfNoMatch)
                            {
                                throw new CompilerException(location, string.Format(Resource.Culture, Resource.NoDefinitionForType, type.DataModifierLess));
                            }
                        }
                    }
                }
            }
            if (original.Nullable && (!original.IsVoid) && (result != null))
            {
                result = new NullableTypeReference(result, new TypeName(result.TypeName, Nullability.ExplicitNullable));
            }
            if (result != null)
            {
                resolveCache[result.TypeName.Data] = result;
            }
            if ((result == null) || original.IsFunction || !original.HasNamespace || (original.TemplateParameters.Count > 0))
            {
                localResolveCache[original.Data] = result;
            }
            else
            {
                resolveCache[original.Data] = result;
            }
            return(result);
        }