internal static object GetNodeData(Node node, Type type) { if (node.Value == Utilities.NullIndicator) { return(null); } // Ensures that the type's static constructor has been run before we try to load it. // A convenient place to add base type rules is in the type's static constructor, so // this ensures the base type rules are registered before they are needed. System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.TypeHandle); if (type == typeof(string) && node.Value == MultiLineStringNode.Terminator && node.ChildNodeType == NodeChildrenType.multiLineString && node.ChildLines.Count > 0) { return(MultiLineStringSpecialCaseHandler.ParseSpecialStringCase(node)); } if (BaseTypesManager.IsBaseType(type)) { return(RetrieveDataWithErrorChecking(() => RetrieveBaseTypeNode(node, type))); } if (CollectionTypesManager.IsSupportedType(type)) { return(RetrieveDataWithErrorChecking(() => CollectionTypesManager.RetrieveCollection(node, type))); } if (!node.Value.IsNullOrEmpty()) { return(RetrieveDataWithErrorChecking(() => ComplexTypeShortcuts.GetFromShortcut(node.Value, type))); } return(RetrieveDataWithErrorChecking(() => ComplexTypes.RetrieveComplexType(node, type))); object RetrieveDataWithErrorChecking(Func <object> retrieveDataFunction) { try { return(retrieveDataFunction.Invoke()); } catch (CannotRetrieveDataFromNodeException deeperException) { // If there's a parsing error deeper in the tree, we want to throw *that* error, so the user gets a line // number appropriate to the actual error. throw deeperException; } catch { throw new CannotRetrieveDataFromNodeException(node, type); } } }
private static object RetrieveBaseTypeNode(Node node, Type type) { // Base types are unique in that they CAN be serialized as a single line, and indeed that is how SUCC will always save them. // However, you CAN manually write a file that uses complex type rules for a base type, and thanks to the logic in this method, // it will still work. // See https://github.com/JimmyCushnie/SUCC/issues/26 if (node.ChildNodeType == NodeChildrenType.key && node.ChildNodes.Count > 0) { return(ComplexTypes.RetrieveComplexType(node, type)); } if (BaseTypesManager.TryParseBaseType(node.Value, type, out var result)) { return(result); } return(ComplexTypeShortcuts.GetFromShortcut(node.Value, type)); }
internal static object GetNodeData(Node node, Type type) { if (node.Value == Utilities.NullIndicator) { return(null); } System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.TypeHandle); try { if (type == typeof(string) && node.Value == MultiLineStringNode.Terminator && node.ChildLines.Count > 0) { return(BaseTypes.ParseSpecialStringCase(node)); } if (BaseTypes.IsBaseType(type)) { return(BaseTypes.ParseBaseType(node.Value, type)); } var collection = CollectionTypes.TryGetCollection(node, type); if (collection != null) { return(collection); } if (!String.IsNullOrEmpty(node.Value)) { return(ComplexTypeShortcuts.GetFromShortcut(node.Value, type)); } return(ComplexTypes.RetrieveComplexType(node, type)); } catch (Exception e) { throw new Exception($"Error getting data of type {type} from node: {e.InnerException}"); } }