From 4062d2f140e75965d89445f00ace8f633ce8b547 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Tue, 22 Jan 2019 18:32:29 +0100 Subject: [PATCH] Fixes for types sometimes choosing type they inherit from instead of themselves --- Upsilon/BaseTypes/TypeContainer.cs | 9 +++--- Upsilon/BaseTypes/TypeConversion.cs | 5 +--- .../BaseTypes/UserData/UserDataTypeHandler.cs | 4 +-- Upsilon/Binder/Binder.cs | 18 ++++++++++-- Upsilon/BoundTypes/BoundTypeHandler.cs | 28 +++++++++++++++++-- Upsilon/StandardLibraries/StaticScope.cs | 5 +--- 6 files changed, 51 insertions(+), 18 deletions(-) diff --git a/Upsilon/BaseTypes/TypeContainer.cs b/Upsilon/BaseTypes/TypeContainer.cs index e0f69c3..f1771ec 100644 --- a/Upsilon/BaseTypes/TypeContainer.cs +++ b/Upsilon/BaseTypes/TypeContainer.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Immutable; +using System.Diagnostics; using Upsilon.BoundTypes; namespace Upsilon.BaseTypes @@ -103,17 +104,17 @@ namespace Upsilon.BaseTypes { private System.Type RealType { get; set; } - protected UndefinedUserDataTypeContainer(Type t) : base(t) - { - } - public UndefinedUserDataTypeContainer(System.Type realType) : base("unset") { + if (realType == null) + throw new Exception("Type can't be null"); RealType = realType; } public UndefinedUserDataTypeContainer(Type t, System.Type realType) : base(t, "unset") { + if (realType == null) + throw new Exception("Type can't be null"); RealType = realType; } diff --git a/Upsilon/BaseTypes/TypeConversion.cs b/Upsilon/BaseTypes/TypeConversion.cs index f480fcb..92f7bea 100644 --- a/Upsilon/BaseTypes/TypeConversion.cs +++ b/Upsilon/BaseTypes/TypeConversion.cs @@ -174,10 +174,7 @@ namespace Upsilon.BaseTypes if (t == typeof(ScriptType)) return Type.Unknown; - var boundType = BoundTypeHandler.GetTypeName(t); - if (boundType == null) - return new UndefinedUserDataTypeContainer(t); - return new TypeContainer(BoundTypeHandler.GetTypeName(t)); + return new UndefinedUserDataTypeContainer(t); } } diff --git a/Upsilon/BaseTypes/UserData/UserDataTypeHandler.cs b/Upsilon/BaseTypes/UserData/UserDataTypeHandler.cs index 614f397..96a1ec6 100644 --- a/Upsilon/BaseTypes/UserData/UserDataTypeHandler.cs +++ b/Upsilon/BaseTypes/UserData/UserDataTypeHandler.cs @@ -16,8 +16,6 @@ namespace Upsilon.BaseTypes.UserData public static void LoadType(System.Type t, string name) { - var info = new UserDataType(t); - Types.AddOrUpdate(t, info, (type, dataType) => dataType); UserDataBoundTypeDefinition boundType; if (t.IsEnum) { @@ -28,6 +26,8 @@ namespace Upsilon.BaseTypes.UserData boundType = UserDataBoundTypeDefinition.Create(t, name); } BoundTypeHandler.LoadUserDataTypeDefinition(boundType); + var info = new UserDataType(t); + Types.AddOrUpdate(t, info, (type, dataType) => dataType); } public static void LoadAssembly(Assembly assembly) diff --git a/Upsilon/Binder/Binder.cs b/Upsilon/Binder/Binder.cs index 3e689c6..d176152 100644 --- a/Upsilon/Binder/Binder.cs +++ b/Upsilon/Binder/Binder.cs @@ -378,6 +378,12 @@ namespace Upsilon.Binder diagnostics?.LogWarning($"Can't resolve type '{bDefProperty.ToString()}'", fullStopIndexExpression.Span); return new VariableSymbol(fullStopIndexExpression.Index, Type.Unknown, true); } + else + { + diagnostics?.LogWarning( + $"Can't resolve property '{fullStopIndexExpression.Index}' on type {parent.Name}", + fullStopIndexExpression.Span); + } } else if (indexerVariable.TypeContainer == Type.Unknown) { @@ -493,8 +499,16 @@ namespace Upsilon.Binder } else if (assignment.Type == Type.UserData) { - variable = new UserDataVariableSymbol(name, - BoundTypeHandler.GetTypeDefinition(assignment.Type.UserData), isLocal); + var ud = assignment.Type.UserData; + if (ud == null) + { + variable = new VariableSymbol(name, Type.Unknown, isLocal); + } + else + { + variable = new UserDataVariableSymbol(name, + BoundTypeHandler.GetTypeDefinition(ud), isLocal); + } } else { diff --git a/Upsilon/BoundTypes/BoundTypeHandler.cs b/Upsilon/BoundTypes/BoundTypeHandler.cs index 3a21134..b86060c 100644 --- a/Upsilon/BoundTypes/BoundTypeHandler.cs +++ b/Upsilon/BoundTypes/BoundTypeHandler.cs @@ -1,5 +1,6 @@ using System.Collections; using System.Collections.Concurrent; +using System.Collections.Generic; using System.Linq; using Upsilon.BaseTypes; @@ -17,12 +18,21 @@ namespace Upsilon.BoundTypes dic.TryAdd("function", new BoundTypeDefinition(Type.Function, new System.Type[0])); } + private static readonly ConcurrentDictionary TypeLookup = + new ConcurrentDictionary(); private static readonly ConcurrentDictionary TypeDefinitions = Reset(); public static ConcurrentDictionary Reset() { var dic = new ConcurrentDictionary(); AddDefaults(dic); + foreach (var boundTypeDefinition in dic) + { + foreach (var valueValidInternalType in boundTypeDefinition.Value.ValidInternalTypes) + { + TypeLookup.TryAdd(valueValidInternalType, boundTypeDefinition.Key); + } + } return dic; } @@ -43,14 +53,28 @@ namespace Upsilon.BoundTypes public static string GetTypeName(System.Type type) { - return TypeDefinitions.FirstOrDefault(x => - x.Value.ValidInternalTypes.Any(validType => validType.IsAssignableFrom(type))).Key; + if (TypeLookup.TryGetValue(type, out var bDefKey)) + { + return bDefKey; + } + + var bDef = TypeDefinitions.FirstOrDefault(x => + x.Value.ValidInternalTypes.Any(validType => validType.IsAssignableFrom(type))); + if (!bDef.Equals(default(KeyValuePair))) + { + TypeLookup.TryAdd(type, bDef.Key); + } + return null; } public static void LoadUserDataTypeDefinition(UserDataBoundTypeDefinition def) { var key = def.Name.ToLowerInvariant(); TypeDefinitions.AddOrUpdate(key, def, (s, definition) => definition); + foreach (var valueValidInternalType in def.ValidInternalTypes) + { + TypeLookup.TryAdd(valueValidInternalType, key); + } } } } \ No newline at end of file diff --git a/Upsilon/StandardLibraries/StaticScope.cs b/Upsilon/StandardLibraries/StaticScope.cs index 1e7706e..93f38bd 100644 --- a/Upsilon/StandardLibraries/StaticScope.cs +++ b/Upsilon/StandardLibraries/StaticScope.cs @@ -196,10 +196,7 @@ namespace Upsilon.StandardLibraries if (type == typeof(ScriptType)) // allows every type return (Type) 255; - var boundType = BoundTypeHandler.GetTypeName(type); - if (boundType != null) - return new TypeContainer(boundType); - return Type.Unknown; + return new UndefinedUserDataTypeContainer(Type.UserData, type); } } } \ No newline at end of file