Example #1
0
        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);
                }
            }
        }
Example #2
0
        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));
        }
Example #3
0
        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}");
            }
        }