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); }