示例#1
0
        public void NumberListColumn_Basics()
        {
            NumberListColumn <int> column = new NumberListColumn <int>();

            column[0].SetTo(new ArraySlice <int>(new int[] { 0, 1, 2 }));

            TreeDiagnostics diagnostics      = TreeSerializer.Diagnostics(column, TreeFormat.Binary);
            int             tinyColumnLength = (int)diagnostics.Length;

            Column.Basics(() => new NumberListColumn <int>(), NumberList <int> .Empty, column[0], (index) =>
            {
                column[index].SetTo(new ArraySlice <int>(new int[] { index, index + 1, index + 2 }));
                return(column[index]);
            });

            // NumberList Equals, GetHashCode
            int[] asArray = new int[] { 0, 1, 3 };
            column[1].SetTo(new ArraySlice <int>(asArray));
            Assert.False(column[0] == column[1]);
            Assert.True(column[0] != column[1]);
            Assert.NotEqual(column[0].GetHashCode(), column[1].GetHashCode());

            // Compare to array
            Assert.True(column[1].Equals(asArray));
        }
示例#2
0
        public void NumberListColumn_NullableCases()
        {
            // StringColumns are extremely common in object models,
            // so having very compact representations for common cases
            // is really important to file size for small databases.

            GenericNumberListColumn <int> column = new GenericNumberListColumn <int>(Nullability.DefaultToNull);
            TreeDiagnostics diagnostics;

            // Empty: { }
            diagnostics = TreeSerializer.Diagnostics(column, TreeFormat.Binary);
            Assert.True(diagnostics.Length <= 2);

            // All null: { IsNull: { Count: 100, Capacity: 100 } }
            for (int i = 0; i < 100; ++i)
            {
                column[i] = null;
            }

            CollectionReadVerifier.VerifySame(column, TreeSerializer.RoundTrip(column, TreeFormat.Binary, testDoubleDispose: false));
            diagnostics = TreeSerializer.Diagnostics(column, TreeFormat.Binary);
            Assert.True(1 == diagnostics.Children.Count);
            Assert.True(diagnostics.Length <= 13);

            // All empty: Only nulls false written
            List <int> empty = new List <int>();

            for (int i = 0; i < 100; ++i)
            {
                column[i] = empty;
            }

            CollectionReadVerifier.VerifySame(column, TreeSerializer.RoundTrip(column, TreeFormat.Binary, testDoubleDispose: false));
            diagnostics = TreeSerializer.Diagnostics(column, TreeFormat.Binary);
            Assert.True(1 == diagnostics.Children.Count);
            Assert.True(diagnostics.Length <= 13);

            // No nulls, No Empty: 4b + 2.125b / value (613b) + 4 pages x 4b (16b) + overhead (~10b)
            List <int> single = new List <int>();

            single.Add(1);

            for (int i = 0; i < 100; ++i)
            {
                column[i] = single;
            }

            CollectionReadVerifier.VerifySame(column, TreeSerializer.RoundTrip(column, TreeFormat.Binary, testDoubleDispose: false));
            diagnostics = TreeSerializer.Diagnostics(column, TreeFormat.Binary);
            Assert.True(1 == diagnostics.Children.Count);
            Assert.True(diagnostics.Length <= 640);

            // Nulls and Non-Nulls; both parts must be written
            column[50] = null;

            CollectionReadVerifier.VerifySame(column, TreeSerializer.RoundTrip(column, TreeFormat.Binary, testDoubleDispose: false));
            diagnostics = TreeSerializer.Diagnostics(column, TreeFormat.Binary);
            Assert.True(2 == diagnostics.Children.Count);
            Assert.True(diagnostics.Length <= 670);
        }
示例#3
0
        public void NumberListColumn_NumberList_Basics()
        {
            // Set up column with sample values, roundtrip, re-verify
            NumberListColumn <int> column = BuildSampleColumn();

            // Verify second value is in a shared array, not at index zero, not expandable (yet), not ReadOnly
            NumberList <int> slice = column[1];

            Assert.Equal(4, slice.Count);
            Assert.True(slice.Slice.Index > 0);
            Assert.False(slice.Slice.IsExpandable);

            // Test second sample row slice IList members
            CollectionChangeVerifier.VerifyList(slice, (index) => index % 20);

            // Verify expandable after test
            Assert.Equal(0, slice.Slice.Index);
            Assert.True(slice.Slice.IsExpandable);

            // Verify values are re-merged and re-loaded properly
            string values = string.Join(", ", slice);

            column = TreeSerializer.RoundTrip(column, TreeFormat.Binary);
            Assert.Equal(values, string.Join(", ", column[1]));

            // Column range check
            Assert.Throws <IndexOutOfRangeException>(() => column[-1]);
        }
示例#4
0
        private NumberListColumn <int> BuildSampleColumn()
        {
            List <ArraySlice <int> > expected = new List <ArraySlice <int> >();

            expected.Add(new ArraySlice <int>(new int[] { 5, 6, 7 }));
            expected.Add(new ArraySlice <int>(new int[] { 2, 3, 4, 5 }));
            expected.Add(new ArraySlice <int>(Enumerable.Range(0, 8192).ToArray()));

            NumberListColumn <int> column = new NumberListColumn <int>();
            NumberListColumn <int> roundTripped;

            // Set each list, and verify they are correct when read back
            for (int i = 0; i < expected.Count; ++i)
            {
                column[i].SetTo(expected[i]);
            }

            for (int i = 0; i < expected.Count; ++i)
            {
                CollectionReadVerifier.VerifySame(expected[i], column[i]);
            }

            // Round trip and verify they deserialize correctly (note, these will be in a shared array now)
            roundTripped = TreeSerializer.RoundTrip(column, TreeFormat.Binary);
            for (int i = 0; i < expected.Count; ++i)
            {
                CollectionReadVerifier.VerifySame(expected[i], column[i]);
            }

            return(roundTripped);
        }
示例#5
0
        internal static void VerifyRoundTrip <T>(ArraySlice <T> slice, T[] copyToTargetArray) where T : unmanaged, IEquatable <T>
        {
            ArraySlice <T> roundTripped = TreeSerializer.RoundTrip(slice, TreeFormat.Binary);

            CollectionReadVerifier.VerifySame <T>(slice, roundTripped);
            VerifyCopyTo <T>(roundTripped, copyToTargetArray);
        }
示例#6
0
        public void FirstTileSetJsonTests()
        {
            // arrange
            var zUpBoxes              = BBTestDataReader.GetTestData("testfixtures/zupboxes_actual.txt");
            var tree                  = TileCutter.ConstructTree(zUpBoxes, 50, 2000.0);
            var translation           = new double[] { 141584.2745, 471164.637, 15.81555842685751 };
            var s                     = File.ReadAllText(@"./testfixtures/tileset_json_expected.json");
            var tileset_json_expected = JsonConvert.DeserializeObject <TileSet>(s);

            // act
            var tileset_json_actual = TreeSerializer.ToTileset(tree, translation);
            var actual_json         = JsonConvert.SerializeObject(tileset_json_actual, Formatting.Indented, new JsonSerializerSettings {
                NullValueHandling = NullValueHandling.Ignore
            });

            //File.WriteAllText("d:/aaa/sample_tileset_actual.json", actual_json);

            // assert
            Assert.IsTrue(tileset_json_actual.asset.version == "1.0");
            Assert.IsTrue(tileset_json_actual.geometricError == 500);

            var all_children_actual   = GetAllChildren(tileset_json_actual.root);
            var all_children_expected = GetAllChildren(tileset_json_expected.root);
            var res = AreSimilar(all_children_actual, all_children_expected);

            var sim = IsSimilar(tileset_json_expected.root, tileset_json_actual.root);

            Assert.IsTrue(sim);
            Assert.IsTrue(tileset_json_actual.root.refine == "ADD");        // 500
            Assert.IsTrue(tileset_json_actual.root.geometricError == 500);  // 500
            Assert.IsTrue(tileset_json_actual.root.transform.Length == 16); // 500
            Assert.IsTrue(tileset_json_actual.root.boundingVolume.box.Length == 12);
            Assert.IsTrue(tileset_json_actual.root.children.Count == 1);
        }
示例#7
0
 public static void Load(this ITreeSerializable item, Stream stream, TreeFormat format, TreeSerializationSettings settings = null)
 {
     using (ITreeReader reader = TreeSerializer.Reader(format, stream, settings))
     {
         item.Read(reader);
     }
 }
示例#8
0
 public static void Save(this ITreeSerializable item, Stream stream, TreeFormat format, TreeSerializationSettings settings = null)
 {
     using (ITreeWriter writer = TreeSerializer.Writer(format, stream, settings))
     {
         item.Write(writer);
     }
 }
        public void SerializerTreeVisitorVisitStringLiteralTest()
        {
            var            serializer = new JsonNodeWriter();
            TreeSerializer visitor    = new TreeSerializer(serializer);

            visitor.VisitStringLiteral(new StringLiteral(new Span(0, 10), "hello world"));
            Assert.AreEqual("\"StringLiteral\" : {\n  \"Span\" : {\n    \"start\" : \"0\",\n    \"end\" : \"10\"\n  },\n  \"Value\" : \"hello world\"\n}", serializer.ToString());
        }
示例#10
0
        public void ArraySliceTests_Basics()
        {
            int[]            sample       = Enumerable.Range(100, 50).ToArray();
            int[]            copyToTarget = new int[100];
            ArraySlice <int> slice;

            // Empty ArraySlice
            slice = ArraySlice <int> .Empty;
            slice.Trim();
            Assert.Empty(slice);
            Assert.True(slice == ArraySlice <int> .Empty);
            Assert.False(slice != ArraySlice <int> .Empty);

            VerifyCopyTo <int>(slice, copyToTarget);
            VerifyRoundTrip <int>(slice, copyToTarget);
            CollectionReadVerifier.VerifySame(slice, TreeSerializer.RoundTrip(slice, TreeFormat.Binary));
            CollectionReadVerifier.VerifySame(slice, TreeSerializer.RoundTrip(slice, TreeFormat.Json));

            // Whole Array
            slice = new ArraySlice <int>(sample);
            Assert.Equal(sample.Length, slice.Count);
            Assert.Equal(sample, slice);
            Assert.Equal(sample[10], slice[10]);
            VerifyCopyTo <int>(slice, copyToTarget);
            VerifyRoundTrip <int>(slice, copyToTarget);
            CollectionReadVerifier.VerifySame(slice, TreeSerializer.RoundTrip(slice, TreeFormat.Binary));
            CollectionReadVerifier.VerifySame(slice, TreeSerializer.RoundTrip(slice, TreeFormat.Json));

            // Array slice-to-end
            slice = new ArraySlice <int>(sample, index: 10);
            Assert.Equal(sample.Length - 10, slice.Count);
            Assert.Equal(sample[20], slice[10]);
            Assert.False(slice.Equals(sample));
            VerifyCopyTo <int>(slice, copyToTarget);
            VerifyRoundTrip <int>(slice, copyToTarget);
            CollectionReadVerifier.VerifySame(slice, TreeSerializer.RoundTrip(slice, TreeFormat.Binary));
            CollectionReadVerifier.VerifySame(slice, TreeSerializer.RoundTrip(slice, TreeFormat.Json));

            // Array slice
            slice = new ArraySlice <int>(sample, index: 10, length: 20);
            Assert.Equal(20, slice.Count);
            Assert.Equal(sample[10], slice[0]);
            VerifyCopyTo <int>(slice, copyToTarget);
            VerifyRoundTrip <int>(slice, copyToTarget);
            CollectionReadVerifier.VerifySame(slice, TreeSerializer.RoundTrip(slice, TreeFormat.Binary));
            CollectionReadVerifier.VerifySame(slice, TreeSerializer.RoundTrip(slice, TreeFormat.Json));

            // Bounds checks
            Assert.Throws <ArgumentNullException>(() => new ArraySlice <int>(null, 0, 0));                            // Array null
            Assert.Throws <ArgumentOutOfRangeException>(() => new ArraySlice <int>(sample, -1, 0));                   // index < 0
            Assert.Throws <ArgumentOutOfRangeException>(() => new ArraySlice <int>(sample, sample.Length + 1, 0));    // index > array.Length
            Assert.Throws <ArgumentOutOfRangeException>(() => new ArraySlice <int>(sample, 0, sample.Length + 1));    // length too long
            Assert.Throws <ArgumentOutOfRangeException>(() => new ArraySlice <int>(sample, 2, sample.Length + 3));

            // Clear
            slice.Clear();
            Assert.Empty(slice);
        }
示例#11
0
        public void RefColumn_Basics()
        {
            string referencedTable = "ReferencedTable";

            Column.Basics <int>(() => new RefColumn(referencedTable), -1, 10, (index) => 2 * index);

            // Verify ReferencedTableName stored and correctly kept after deserialize
            Assert.Equal(referencedTable, TreeSerializer.RoundTrip(new RefColumn(referencedTable), () => new RefColumn(referencedTable), TreeFormat.Binary).ReferencedTableName);
        }
示例#12
0
        public void RefListColumn_Basics()
        {
            string        referencedTable = "ReferencedTable";
            RefListColumn column          = new RefListColumn(referencedTable);

            RefListColumn roundTripped = TreeSerializer.RoundTrip(column, () => new RefListColumn(referencedTable), TreeFormat.Binary);

            Assert.Equal(referencedTable, roundTripped.ReferencedTableName);
        }
示例#13
0
        private static void WiteTilesetJson(double[] translation, Node tree, string outputPath)
        {
            var tileset = TreeSerializer.ToTileset(tree, translation);
            var s       = JsonConvert.SerializeObject(tileset, Formatting.Indented, new JsonSerializerSettings()
            {
                NullValueHandling = NullValueHandling.Ignore
            });

            File.WriteAllText($"{outputPath}/tileset.json", s);
        }
示例#14
0
        public void StringColumn_LongValuesAndMerging()
        {
            StringColumn  column   = new StringColumn();
            List <string> expected = new List <string>();
            StringColumn  roundTripped;

            // Test values just at and above LargeValue limit
            expected.Add(new string(' ', 2047));
            expected.Add(null);
            expected.Add(string.Empty);
            expected.Add("Normal");
            expected.Add(new string(' ', 2048));

            for (int i = 0; i < expected.Count; ++i)
            {
                column[i] = expected[i];
            }

            // Verify values properly captured
            CollectionReadVerifier.VerifySame(expected, column);

            // Proactively Trim (before serialization) and verify values not corrupted
            column.Trim();
            CollectionReadVerifier.VerifySame(expected, column);

            // Verify roundtripped column and column not corrupted by serialization
            roundTripped = TreeSerializer.RoundTrip(column, TreeFormat.Binary);
            CollectionReadVerifier.VerifySame(expected, roundTripped);
            CollectionReadVerifier.VerifySame(expected, column);

            // Set a short value to long and a long value to short, and add another value
            expected[0] = new string(':', 2400);
            expected[2] = "MuchShorter";
            expected.Add("Simple");

            for (int i = 0; i < expected.Count; ++i)
            {
                column[i] = expected[i];
            }

            // Verify values read back correctly immediately
            CollectionReadVerifier.VerifySame(expected, column);

            // Verify values re-roundtrip again properly (merging old and new immutable values)
            roundTripped = TreeSerializer.RoundTrip(column, TreeFormat.Binary);
            CollectionReadVerifier.VerifySame(expected, roundTripped);
            CollectionReadVerifier.VerifySame(expected, column);

            // Add a value causing a gap; verify count, new value returned, values in gap defaulted properly
            column[100] = "Centennial";

            Assert.Equal(101, column.Count);
            Assert.Equal("Centennial", column[100]);
            Assert.Null(column[99]);
        }
示例#15
0
        public void StringColumn_EmptyCases()
        {
            // StringColumns are extremely common in object models,
            // so having very compact representations for common cases
            // is really important to file size for small databases.

            StringColumn    column = new StringColumn();
            TreeDiagnostics diagnostics;

            // Empty: { }
            diagnostics = TreeSerializer.Diagnostics(column, TreeFormat.Binary);
            Assert.True(diagnostics.Length <= 2);

            // All null: { IsNull: { Count: 100, Capacity: 100 } }
            for (int i = 0; i < 100; ++i)
            {
                column[i] = null;
            }

            CollectionReadVerifier.VerifySame(column, TreeSerializer.RoundTrip(column, TreeFormat.Binary, testDoubleDispose: false));
            diagnostics = TreeSerializer.Diagnostics(column, TreeFormat.Binary);
            Assert.True(1 == diagnostics.Children.Count);
            Assert.True(diagnostics.Length <= 13);

            // All empty: Only nulls false written
            for (int i = 0; i < 100; ++i)
            {
                column[i] = "";
            }

            CollectionReadVerifier.VerifySame(column, TreeSerializer.RoundTrip(column, TreeFormat.Binary, testDoubleDispose: false));
            diagnostics = TreeSerializer.Diagnostics(column, TreeFormat.Binary);
            Assert.True(1 == diagnostics.Children.Count);
            Assert.True(diagnostics.Length <= 13);

            // No nulls, No Empty: 3b / value (2b end + 1b text) + 4 pages x 4b + 20b overhead
            for (int i = 0; i < 100; ++i)
            {
                column[i] = "-";
            }

            CollectionReadVerifier.VerifySame(column, TreeSerializer.RoundTrip(column, TreeFormat.Binary, testDoubleDispose: false));
            diagnostics = TreeSerializer.Diagnostics(column, TreeFormat.Binary);
            Assert.True(1 == diagnostics.Children.Count);
            Assert.True(diagnostics.Length <= 336);

            // Nulls and Non-Nulls; both parts must be written
            column[50] = null;

            CollectionReadVerifier.VerifySame(column, TreeSerializer.RoundTrip(column, TreeFormat.Binary, testDoubleDispose: false));
            diagnostics = TreeSerializer.Diagnostics(column, TreeFormat.Binary);
            Assert.True(2 == diagnostics.Children.Count);
            Assert.True(diagnostics.Length <= 336 + 40);
        }
        public void DistinctColumn_Conversion()
        {
            int defaultValue = -1;
            Func <DistinctColumn <int> > ctor = () => new DistinctColumn <int>(new NumberColumn <int>(defaultValue), defaultValue);

            DistinctColumn <int> column   = ctor();
            List <int>           expected = new List <int>();

            // Verify empty and set up to map values by default
            Assert.Empty(column);
            Assert.True(column.IsMappingValues);

            // Round trip and verify it resets back to mapping correctly
            column = TreeSerializer.RoundTrip(column, ctor, TreeFormat.Binary);
            Assert.Empty(column);
            Assert.True(column.IsMappingValues);

            // Add 1,000 values with 10 distinct values
            for (int i = 0; i < 1000; ++i)
            {
                int value = i % 10;
                column[i] = value;
                expected.Add(value);
            }

            // Verify column is mapping, has 11 unique values (default + 10), and matches expected array
            Assert.True(column.IsMappingValues);
            Assert.Equal(11, column.DistinctCount);
            CollectionReadVerifier.VerifySame(expected, column);

            // Round trip; verify mapped column rehydrates properly
            column = TreeSerializer.RoundTrip(column, ctor, TreeFormat.Binary);
            CollectionReadVerifier.VerifySame(expected, column);

            // Add enough values to force the column to convert
            for (int i = 1000; i < 1300; ++i)
            {
                column[i] = i;
                expected.Add(i);
            }

            Assert.False(column.IsMappingValues);
            Assert.Equal(-1, column.DistinctCount);
            CollectionReadVerifier.VerifySame(expected, column);

            // Round-trip; verify individual values column rehydrates properly
            column = TreeSerializer.RoundTrip(column, ctor, TreeFormat.Binary);
            CollectionReadVerifier.VerifySame(expected, column);

            // Test RemoveFromEnd on unmapped form of column
            column.RemoveFromEnd(100);
            expected.RemoveRange(expected.Count - 100, 100);
            CollectionReadVerifier.VerifySame(expected, column);
        }
示例#17
0
        public void Database_Basics()
        {
            V1.Community community = new V1.Community();
            community.People = new List <V1.Person>();

            community.People.Add(new V1.Person()
            {
                Age = 39, Name = "Scott"
            });
            community.People.Add(new V1.Person()
            {
                Age = 36, Name = "Adam"
            });

            // Use ReadOnlyList.VerifySame to check count, enumerators, and indexer
            community.DB.Save("V1.Community.bsoa", TreeFormat.Binary);
            V1.Community roundTripped = new V1.Community();
            roundTripped.DB.Load("V1.Community.bsoa", TreeFormat.Binary);
            CollectionReadVerifier.VerifySame(community.People, roundTripped.People);

            // Try loading database with size diagnostics
            TreeDiagnostics diagnostics = TreeSerializer.Diagnostics(community.DB, () => new V1.Community().DB, TreeFormat.Binary);

            // Verify table and column names in diagnostics
            string text = diagnostics.ToString();

            Assert.Contains("Person", text);
            Assert.Contains("Age", text);
            Assert.Contains("Name", text);

            // Verify Person has two columns, Write doesn't throw
            Assert.Equal("Person", diagnostics.Children[0].Name);
            Assert.Equal(Names.Columns, diagnostics.Children[0].Children[0].Name);
            Assert.Equal(2, diagnostics.Children[0].Children[0].Children.Count);
            diagnostics.Write(Console.Out, 3);

            // Verify Trim doesn't throw (results not visible)
            community.DB.Trim();
            CollectionReadVerifier.VerifySame(community.People, roundTripped.People);

            // Verify Copy constructor recursively copies (List.SetTo -> LocalIndex -> CopyFrom construction)
            V1.Community copy = new V1.Community(community);
            CollectionReadVerifier.VerifySame(community.People, copy.People);
            community.People[0].Age += 10;
            Assert.NotEqual(community.People[0].Age, copy.People[0].Age);

            // Verify Database.Clear works
            community.DB.Clear();
            var people = community.People;

            Assert.True(people == null || people.Count == 0);
        }
示例#18
0
        public void NumberListColumn_TypeList_Basics()
        {
            // Set up column with sample values, roundtrip, re-verify
            NumberListColumn <int> column = BuildSampleColumn();

            // Verify second value is in a shared array, not at index zero, not expandable (yet), not ReadOnly
            NumberList <int> row1List  = column[1];
            TypedList <int>  row1Typed = new TypedList <int>(row1List, (index) => index, (index) => index);

            // Test second sample row slice IList members on NumberListConverter
            CollectionChangeVerifier.VerifyList(row1Typed, (index) => index % 20);

            // Verify values are re-merged and re-loaded properly
            string values = string.Join(", ", row1List);

            column = TreeSerializer.RoundTrip(column, TreeFormat.Binary);
            Assert.Equal(values, string.Join(", ", column[1]));

            // TypedList Equality
            TypedList <int> row1 = new TypedList <int>(column[1], (index) => index, (index) => index);
            TypedList <int> row0 = new TypedList <int>(column[0], (index) => index, (index) => index);

            Assert.True(row1.Equals(row1));
            Assert.False(row1.Equals(row0));
            Assert.False(row1 == row0);
            Assert.True(row1 != row0);
            Assert.False(null == row0);
            Assert.True(null != row0);
            Assert.Equal(row1.GetHashCode(), row1.GetHashCode());

            // TypedList.Indices
            Assert.Equal(row1.Indices, column[1]);

            // SetTo(other)
            TypedList <int> firstRow = new TypedList <int>(column[0], (index) => index, (index) => index);

            row1Typed.SetTo(firstRow);
            Assert.Equal(string.Join(", ", firstRow), string.Join(", ", row1Typed));

            // SetTo(null)
            row1Typed.SetTo(null);
            Assert.Empty(row1Typed);

            // SetTo(IList)
            row1Typed.SetTo(new int[] { 2, 3, 4, 5 });
            Assert.Equal("2, 3, 4, 5", string.Join(", ", row1Typed));

            // SetTo(empty)
            row1Typed.SetTo(Array.Empty <int>());
            Assert.Empty(row1Typed);
        }
示例#19
0
        public void BooleanColumn_AllDefault()
        {
            BooleanColumn c = new BooleanColumn(true);

            // Set a large number of values all to the default
            for (int i = 0; i < 8192; ++i)
            {
                c[i] = true;
            }

            // Verify the column serializes small (not to one bit per row)
            TreeDiagnostics diagnostics = TreeSerializer.Diagnostics(c, () => new BooleanColumn(true), TreeFormat.Binary);

            Assert.True(diagnostics.Length < 100);
        }
示例#20
0
        public void SerializeToJsonTest()
        {
            // arrange
            var t0    = new Tile(0, new Wkx.BoundingBox());
            var t1    = new Tile(1, new Wkx.BoundingBox());
            var tiles = new List <Tile> {
                t0, t1
            };
            var translation = new double[] { -8406745.0078531764, 4744614.2577285888, 38.29 };
            var bbox        = new double[] { 0, 0, 1, 1 };

            // act
            var json       = TreeSerializer.ToJson(tiles, translation, bbox, 500, "replace");
            var jsonobject = JObject.Parse(json);

            Assert.IsTrue(jsonobject != null);
        }
示例#21
0
        public void SerializeTree()
        {
            // arrange
            var t0    = new Tile(0, new Wkx.BoundingBox());
            var t1    = new Tile(1, new Wkx.BoundingBox());
            var tiles = new List <Tile> {
                t0, t1
            };

            // act
            var translation = new double[] { -8406745.0078531764, 4744614.2577285888, 38.29 };
            var bbox        = new double[] { 0, 0, 1, 1 };

            // assert
            var tileset = TreeSerializer.ToTileset(tiles, translation, bbox, 500, "replace");

            Assert.IsTrue(tileset.root.children.Count == 2);
        }
示例#22
0
        public void NumberListColumn_Basics()
        {
            NumberListColumn <int> column = new NumberListColumn <int>();

            column[0].SetTo(new ArraySlice <int>(new int[] { 0, 1, 2 }));

            TreeDiagnostics diagnostics      = TreeSerializer.Diagnostics(column, TreeFormat.Binary);
            int             tinyColumnLength = (int)diagnostics.Length;

            Column.Basics(() => new NumberListColumn <int>(), NumberList <int> .Empty, column[0], (index) =>
            {
                column[index].SetTo(new ArraySlice <int>(new int[] { index, index + 1, index + 2 }));
                return(column[index]);
            });

            // NumberList Equals, GetHashCode
            int[] asArray = new int[] { 0, 1, 3 };
            column[1].SetTo(new ArraySlice <int>(asArray));
            Assert.False(column[0] == column[1]);
            Assert.True(column[0] != column[1]);
            Assert.NotEqual(column[0].GetHashCode(), column[1].GetHashCode());

            // Compare to array
            Assert.True(column[1].Equals(asArray));

            // ForEach
            column.Clear();
            column[0].SetTo(new ArraySlice <int>(new int[] { 0, 1, 2 }));
            int sum = 0;

            column.ForEach((slice) =>
            {
                int[] array = slice.Array;
                int end     = slice.Index + slice.Count;
                for (int i = slice.Index; i < end; ++i)
                {
                    sum += array[i];
                }
            });
            Assert.Equal(3, sum);
        }
示例#23
0
        public void TestSerialization()
        {
            Student peter  = new Student("Peter", TestName.Physics, 7);
            Student john   = new Student("John", TestName.Geography, 7);
            Student frank  = new Student("Frank", TestName.Economics, 8);
            Student robert = new Student("Robert", TestName.Economics, 10);

            Tree <Student> tree = new Tree <Student>();

            tree.Add(peter);
            tree.Add(john);
            tree.Add(frank);
            tree.Add(robert);

            string path = AppDomain.CurrentDomain.BaseDirectory + "/binaryTree.xml";

            TreeSerializer.Serialize(tree, path);

            Tree <Student> treeDeser = TreeSerializer.Deserialize(path);

            Assert.AreEqual(tree.Count, treeDeser.Count);
        }
示例#24
0
        public void GenericNumberListColumn_Basics()
        {
            List <int> empty = new List <int>();

            GenericNumberListColumn <int> column = new GenericNumberListColumn <int>();

            column[0] = new int[] { 0, 1, 2 };

            TreeDiagnostics diagnostics      = TreeSerializer.Diagnostics(column, TreeFormat.Binary);
            int             tinyColumnLength = (int)diagnostics.Length;

            Column.Basics(() => new GenericNumberListColumn <int>(), null, column[0], (index) =>
            {
                IList <int> values = column[index];
                if (values == null || values.Count == 0)
                {
                    column[index] = new int[] { index, index + 1, index + 2 };
                    values        = column[index];
                }

                return(values);
            });

            // ForEach
            column.Clear();
            column[0] = new int[] { 0, 1, 2 };
            int sum = 0;

            column.ForEach((slice) =>
            {
                int[] array = slice.Array;
                int end     = slice.Index + slice.Count;
                for (int i = slice.Index; i < end; ++i)
                {
                    sum += array[i];
                }
            });
            Assert.Equal(3, sum);
        }
        public void TreeReaderWriter_ExtensionMethods_Tests()
        {
            // DateTime and Guid serialization covered in TreeSerializable.Basics

            Random r       = new Random();
            Sample sample  = new Sample(r);
            Sample sample2 = new Sample(r);

            // List and Dictionary serialization built-ins
            CollectionContainer <Sample> samples = new CollectionContainer <Sample>();

            samples.Add(sample);
            samples.Add(sample2);

            samples.AssertEqual(TreeSerializer.RoundTrip(samples, TreeFormat.Json));
            samples.AssertEqual(TreeSerializer.RoundTrip(samples, TreeFormat.Binary));


            // Null List / Dictionary handling
            samples.SetCollectionsNull();
            samples.AssertEqual(TreeSerializer.RoundTrip(samples, TreeFormat.Json));
            samples.AssertEqual(TreeSerializer.RoundTrip(samples, TreeFormat.Binary));
        }
示例#26
0
        public static void Basics <T>(Func <IColumn <T> > builder, T defaultValue, T otherValue, Func <int, T> valueProvider)
        {
            IColumn <T> column   = builder();
            List <T>    expected = new List <T>();

            // ICollection basics
            Assert.False(column.IsReadOnly);
            Assert.False(column.IsSynchronized);
            Assert.Null(column.SyncRoot);

            Assert.Equal(typeof(T), column.Type);

            // Empty behavior
            Assert.Equal(0, column.Count);
            Assert.Equal(defaultValue, column[0]);
            Assert.Equal(defaultValue, column[10]);
            Assert.Equal(0, column.Count);

            // Empty roundtrip works
            CollectionReadVerifier.VerifySame(expected, TreeSerializer.RoundTrip(column, builder, TreeFormat.Binary));
            CollectionReadVerifier.VerifySame(expected, TreeSerializer.RoundTrip(column, builder, TreeFormat.Json));

            // Empty trim works
            column.Trim();

            // Append values
            for (int i = 0; i < 50; ++i)
            {
                T value = valueProvider(i);
                column.Add(value);
                expected.Add(value);
            }

            // Verify count, values, indexer, enumerators
            Assert.Equal(expected.Count, column.Count);
            CollectionReadVerifier.VerifySame <T>(expected, column);

            // Verify item type supports equatability (needed for IndexOf, Contains to work)
            Assert.True(otherValue.Equals(otherValue));
            Assert.Equal(otherValue.GetHashCode(), otherValue.GetHashCode());
            Assert.False(otherValue.Equals(defaultValue));
            Assert.NotEqual(otherValue.GetHashCode(), defaultValue?.GetHashCode() ?? 0);
            Assert.False(otherValue.Equals(1.45d));

            // Contains / IndexOf
            T notInList = valueProvider(50);

            if (!expected.Contains(notInList))
            {
                Assert.DoesNotContain(notInList, column);
                Assert.Equal(-1, column.IndexOf(notInList));
            }

            Assert.Contains(valueProvider(1), column);
            Assert.Equal(1, column.IndexOf(valueProvider(1)));

            // CopyTo
            T[] other = new T[column.Count + 1];
            column.CopyTo(other, 1);
            Assert.Equal(column[0], other[1]);

            // CopyTo preconditions
            if (!Debugger.IsAttached)
            {
                Assert.Throws <ArgumentNullException>(() => column.CopyTo(null, 0));
                Assert.Throws <ArgumentException>(() => column.CopyTo(other, 2));
                Assert.Throws <ArgumentOutOfRangeException>(() => column.CopyTo(other, -1));
                Assert.Throws <ArgumentException>(() => column.CopyTo((Array)(new decimal[column.Count]), 0));
            }

            // CopyTo (untyped)
            other = new T[column.Count];
            column.CopyTo((Array)other, 0);
            CollectionReadVerifier.VerifySame(other, column, quick: true);

            // Change existing value
            column[1] = otherValue;
            Assert.Equal(otherValue, column[1]);

            // Set value back to default, back to non-default
            column[1] = defaultValue;
            Assert.Equal(defaultValue, column[1]);
            column[1] = valueProvider(1);
            Assert.Equal(valueProvider(1), column[1]);

            // Add() without instance
            T item = column.Add();

            Assert.Equal(defaultValue, item);

            // Copy values via CopyItem
            column.CopyItem(1, column, 2);
            Assert.Equal(column[1], column[2]);
            column[1] = valueProvider(1);

            // CopyItem type checking
            if (!Debugger.IsAttached)
            {
                Assert.Throws <ArgumentException>(() => column.CopyItem(1, new NumberColumn <Decimal>(0.0m), 0));
            }

            // Append so resize is required
            column[100] = valueProvider(100);

            // Verify old values were kept, middle defaulted, last one set
            for (int i = 0; i < column.Count; ++i)
            {
                T value = (i < 50 || i == 100 ? valueProvider(i) : defaultValue);
                Assert.Equal(value, column[i]);
            }

            // Verify serialization round trip via all current serialization mechanisms
            CollectionReadVerifier.VerifySame(column, TreeSerializer.RoundTrip(column, builder, TreeFormat.Binary), quick: true);
            CollectionReadVerifier.VerifySame(column, TreeSerializer.RoundTrip(column, builder, TreeFormat.Json), quick: true);

            // Verify column is properly skippable (required to allow flexible file format schema)
            TreeSerializer.VerifySkip(column, TreeFormat.Binary);
            TreeSerializer.VerifySkip(column, TreeFormat.Json);

            // Verify original values are still there post-serialization (ensure column not corrupted by serialization)
            for (int i = 0; i < column.Count; ++i)
            {
                T value = (i < 50 || i == 100 ? valueProvider(i) : defaultValue);
                Assert.Equal(value, column[i]);
            }

            // Swap two non-default values, verify swapped, swap back
            column.Swap(10, 20);
            Assert.Equal(valueProvider(10), column[20]);
            Assert.Equal(valueProvider(20), column[10]);
            column.Swap(10, 20);
            Assert.Equal(valueProvider(10), column[10]);
            Assert.Equal(valueProvider(20), column[20]);

            // Swap a default with a non-default value, verify swapped, swap back
            column.Swap(30, 60);
            Assert.Equal(valueProvider(30), column[60]);
            Assert.Equal(defaultValue, column[30]);
            column.Swap(30, 60);
            Assert.Equal(valueProvider(30), column[30]);
            Assert.Equal(defaultValue, column[60]);

            // Verify RemoveFromEnd for only default values works
            column.RemoveFromEnd(column.Count - 60);
            Assert.Equal(60, column.Count);
            Assert.Equal(defaultValue, column[60]);

            // Verify RemoveFromEnd down to non-default values works
            column.RemoveFromEnd(60 - 10);
            Assert.Equal(10, column.Count);

            for (int i = 0; i < 60; ++i)
            {
                T value = (i < 10 ? valueProvider(i) : defaultValue);
                Assert.Equal(value, column[i]);
            }

            // Append a default value big enough another resize would be required
            //  Verify the count is tracked correctly, previous items are initialized to default
            column[201] = defaultValue;
            Assert.Equal(202, column.Count);
            Assert.Equal(defaultValue, column[200]);

            // Verify serialization handles 'many defaults at end' properly
            CollectionReadVerifier.VerifySame(column, TreeSerializer.RoundTrip(column, builder, TreeFormat.Binary), quick: true);

            // Verify Trim doesn't throw
            column.Trim();

            // Verify clear resets count and that previously set values are back to default if accessed
            column.Clear();
            Assert.Equal(0, column.Count);
            Assert.Equal(defaultValue, column[0]);
            Assert.Equal(defaultValue, column[1]);

            // Add one default value (inner array may still not be allocated), then try RemoveFromEnd
            column[0] = defaultValue;
            column.RemoveFromEnd(1);
            Assert.Equal(0, column.Count);

            if (!Debugger.IsAttached)
            {
                // Verify indexer range check (< 0 only; columns auto-size for bigger values)
                Assert.Throws <IndexOutOfRangeException>(() => column[-1]);

                // Verify Remove throws (not expected to be implemented)
                Assert.Throws <NotSupportedException>(() => column.Remove(defaultValue));
            }
        }
 public void JsonTreeReaderWriter_Basics()
 {
     // Run ITreeSerializable suite on JsonTreeReader and JsonTreeWriter
     TreeSerializer.Basics(TreeFormat.Json);
 }
示例#28
0
        public void ParserParseTest()
        {
            string path        = (string)TestContext.DataRow["files"];
            string testcontent = File.ReadAllText(path);

            string[] testparts = testcontent.Split(new string[] { "<<<TEST>>>" }, StringSplitOptions.RemoveEmptyEntries);
            Assert.IsTrue(testparts.Length >= 2);

            var sourceUnit = new CodeSourceUnit(testparts[0], path, Encoding.UTF8, Lexer.LexicalStates.INITIAL, LanguageFeatures.Basic);
            var factory    = new BasicNodesFactory(sourceUnit);
            var errors     = new TestErrorSink();

            //
            sourceUnit.Parse(factory, errors, new TestErrorRecovery());

            //
            if (testparts[1].TrimStart().StartsWith(Errors))
            {
                var matches     = _errorRegex.Matches(testparts[1]);
                var knownErrors = matches[0].Groups["Number"].Value.Split(',');
                Assert.AreEqual(1, matches.Count, path);
                Assert.AreEqual(knownErrors.Length, errors.Count, path);
                int errorid = 0;
                for (int i = 0; i < knownErrors.Length; i++)
                {
                    Assert.IsTrue(int.TryParse(knownErrors[i], out errorid), path);
                    Assert.AreEqual(errorid, errors.Errors[i].Error.Id, path);
                    Assert.IsNotNull(errors.Errors[i].ToString());
                }
                testparts[1] = matches[0].Groups["JSON"].Value;
            }
            else
            {
                Assert.AreEqual(0, errors.Count, path);
            }

            Assert.IsNotNull(sourceUnit.Ast);

            var            serializer = new JsonNodeWriter();
            TreeSerializer visitor    = new TreeSerializer(serializer);

            sourceUnit.Ast.VisitMe(visitor);

            Regex  rgx      = new Regex(@"""Span""[^}]*},?\s*\n?"); // omit Span for more compact testing (position must be verified separately)
            string expected = rgx.Replace(testparts[1].Trim().Replace("\r", string.Empty).Replace("\n", string.Empty).Replace(" ", string.Empty), string.Empty);
            string actual   = rgx.Replace(serializer.ToString().Replace("\r", string.Empty).Replace("\n", string.Empty).Replace(" ", string.Empty), string.Empty);

            if (testparts[1].Trim() != "<<<IGNORE>>>")
            {
                // IMPORTANT - Uncomment to regenerate test data
                //File.WriteAllText(path, testparts[0] + "\n<<<TEST>>>\n" + rgx.Replace(serializer.ToString(), string.Empty));
                Assert.AreEqual(expected, actual, path);
            }

            // check every node has a parent
            var parentChecker = new ContainingElementCheck();

            parentChecker.VisitGlobalCode(sourceUnit.Ast);

            // check nodes have correct span corresponding to correct source text
            var spanChecker = new NameSpanCheck(testparts[0]);

            spanChecker.VisitGlobalCode(sourceUnit.Ast);
        }
示例#29
0
        public static FileParserResult ParseFile(Text Text)
        {
            var TypeFunctions = new HashSet <String>()
            {
                "Primitive", "Alias", "Record", "TaggedUnion", "Enum", "ClientCommand", "ServerCommand"
            };
            var Functions = new HashSet <String>(TypeFunctions.Concat(new List <String>()
            {
                "Namespace", "Import"
            }));

            var ps = new TreeFormatParseSetting()
            {
                IsTableParameterFunction = Name => Functions.Contains(Name),
                IsTableContentFunction   = Name => Functions.Contains(Name),
                IsTreeParameterFunction  = Name => false,
                IsTreeContentFunction    = Name => false
            };

            var sp           = new TreeFormatSyntaxParser(ps, Text);
            var ParserResult = sp.Parse();
            var ts           = new TreeSerializer();

            var Types                   = new List <TypeDef>();
            var TypeRefs                = new List <TypeDef>();
            var Imports                 = new List <String>();
            var TypeToNamespace         = new Dictionary <TypeDef, List <String> >();
            var TypeToNamespaceImports  = new Dictionary <TypeDef, List <List <String> > >();
            var CurrentNamespace        = new List <String>();
            var CurrentNamespaceImports = new List <List <String> >();

            var Positions = new Dictionary <Object, TextRange>();

            foreach (var TopNode in ParserResult.Value.MultiNodesList)
            {
                if (TopNode.OnFunctionNodes)
                {
                    var pr = new TreeFormatParseResult
                    {
                        Value = new Forest {
                            MultiNodesList = new List <MultiNodes> {
                                TopNode
                            }
                        },
                        Text             = Text,
                        Positions        = ParserResult.Positions,
                        RawFunctionCalls = ParserResult.RawFunctionCalls
                    };
                    var es = new TreeFormatEvaluateSetting
                    {
                        FunctionCallEvaluator = (f, nm) =>
                        {
                            Action <Object, Object> Mark = (SemanticsObj, SyntaxObj) =>
                            {
                                var Range = nm.GetRange(SyntaxObj);
                                if (Range.OnSome)
                                {
                                    Positions.Add(SemanticsObj, Range.Value);
                                }
                            };

                            Func <TFSemantics.Node, List <String> > ExtractNamespaceParts = Node =>
                            {
                                var Namespace = GetLeafNodeValue(Node, nm, "InvalidName");

                                var NamespaceParts = new List <String>();
                                int InvalidCharIndex;
                                var osml = TokenParser.TrySplitSymbolMemberChain(Namespace, out InvalidCharIndex);
                                if (osml.OnNone)
                                {
                                    var Range       = nm.GetRange(Node);
                                    var InvalidChar = Namespace.Substring(InvalidCharIndex, 1);
                                    if (Range.OnSome)
                                    {
                                        Range = new TextRange {
                                            Start = nm.Text.Calc(Range.Value.Start, InvalidCharIndex), End = nm.Text.Calc(Range.Value.Start, InvalidCharIndex + 1)
                                        };
                                    }
                                    throw new InvalidTokenException("InvalidChar", new FileTextRange {
                                        Text = nm.Text, Range = Range
                                    }, InvalidChar);
                                }
                                foreach (var p in osml.Value)
                                {
                                    if (p.Parameters.Count > 0)
                                    {
                                        var Range = nm.GetRange(Node);
                                        var Part  = Namespace.Substring(p.SymbolStartIndex, p.SymbolEndIndex);
                                        if (Range.OnSome)
                                        {
                                            Range = new TextRange {
                                                Start = nm.Text.Calc(Range.Value.Start, p.SymbolStartIndex), End = nm.Text.Calc(Range.Value.Start, p.SymbolEndIndex)
                                            };
                                        }
                                        throw new InvalidTokenException("InvalidNamespacePart", new FileTextRange {
                                            Text = nm.Text, Range = Range
                                        }, Part);
                                    }
                                    int LocalInvalidCharIndex;
                                    var oName = TokenParser.TryUnescapeSymbolName(p.Name, out LocalInvalidCharIndex);
                                    if (oName.OnNone)
                                    {
                                        InvalidCharIndex = p.NameStartIndex + LocalInvalidCharIndex;
                                        var Range       = nm.GetRange(Node);
                                        var InvalidChar = Namespace.Substring(InvalidCharIndex, 1);
                                        if (Range.OnSome)
                                        {
                                            Range = new TextRange {
                                                Start = nm.Text.Calc(Range.Value.Start, InvalidCharIndex), End = nm.Text.Calc(Range.Value.Start, InvalidCharIndex + 1)
                                            };
                                        }
                                        throw new InvalidTokenException("InvalidChar", new FileTextRange {
                                            Text = nm.Text, Range = Range
                                        }, InvalidChar);
                                    }
                                    NamespaceParts.Add(p.Name);
                                }

                                return(NamespaceParts);
                            };

                            if (TypeFunctions.Contains(f.Name.Text))
                            {
                                if (f.Parameters.Count < 1 || f.Parameters.Count > 2)
                                {
                                    throw new InvalidEvaluationException("InvalidParameterCount", nm.GetFileRange(f), f);
                                }

                                var TypeRef = ParseTypeRef(f.Parameters[0], nm, Positions);
                                var Name    = TypeRef.Name;
                                var Version = TypeRef.Version;

                                var Attributes  = new List <KeyValuePair <String, List <String> > >();
                                var Description = "";
                                if (f.Parameters.Count >= 2)
                                {
                                    var DescriptionParameter = f.Parameters[1];
                                    if (!DescriptionParameter.OnLeaf)
                                    {
                                        throw new InvalidEvaluationException("InvalidDescription", nm.GetFileRange(DescriptionParameter), DescriptionParameter);
                                    }
                                    var c = TokenParser.DecomposeDescription(DescriptionParameter.Leaf);
                                    Attributes = c.Attributes;
                                    Mark(Attributes, f.Parameters[1]);
                                    Description = c.Description;
                                }

                                var ContentLines = new List <FunctionCallTableLine> {
                                };
                                if (f.Content.OnSome)
                                {
                                    var ContentValue = f.Content.Value;
                                    if (!ContentValue.OnTableContent)
                                    {
                                        throw new InvalidEvaluationException("InvalidContent", nm.GetFileRange(ContentValue), ContentValue);
                                    }
                                    ContentLines = ContentValue.TableContent;
                                }

                                switch (f.Name.Text)
                                {
                                case "Primitive":
                                {
                                    if (Version != "")
                                    {
                                        throw new InvalidEvaluationException("InvalidName", nm.GetFileRange(f.Parameters[0]), f.Parameters[0]);
                                    }

                                    var GenericParameters = new List <VariableDef>();

                                    foreach (var Line in ContentLines)
                                    {
                                        String   cName        = null;
                                        TypeSpec cType        = null;
                                        var      cAttributes  = new List <KeyValuePair <String, List <String> > >();
                                        var      cDescription = "";

                                        if (Line.Nodes.Count == 2)
                                        {
                                            cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName");
                                            cType = ParseTypeSpec(Line.Nodes[1], nm, Positions);
                                        }
                                        else if (Line.Nodes.Count == 3)
                                        {
                                            cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName");
                                            cType = ParseTypeSpec(Line.Nodes[1], nm, Positions);
                                            var c = TokenParser.DecomposeDescription(GetLeafNodeValue(Line.Nodes[2], nm, "InvalidDescription"));
                                            cAttributes = c.Attributes;
                                            Mark(cAttributes, Line.Nodes[2]);
                                            cDescription = c.Description;
                                        }
                                        else if (Line.Nodes.Count == 0)
                                        {
                                            continue;
                                        }
                                        else
                                        {
                                            throw new InvalidEvaluationException("InvalidLineNodeCount", nm.GetFileRange(Line), Line);
                                        }

                                        if (cName.StartsWith("'"))
                                        {
                                            cName = new String(cName.Skip(1).ToArray());
                                            var gp = new VariableDef {
                                                Name = cName, Type = cType, Attributes = cAttributes, Description = cDescription
                                            };
                                            Mark(gp, Line);
                                            GenericParameters.Add(gp);
                                        }
                                        else
                                        {
                                            throw new InvalidEvaluationException("InvalidLine", nm.GetFileRange(Line), Line);
                                        }
                                    }

                                    var p = new PrimitiveDef {
                                        Name = Name, GenericParameters = GenericParameters, Attributes = Attributes, Description = Description
                                    };
                                    Mark(p, f);
                                    var t = TypeDef.CreatePrimitive(p);
                                    Mark(t, f);
                                    Types.Add(t);
                                    TypeToNamespace.Add(t, CurrentNamespace);
                                    TypeToNamespaceImports.Add(t, CurrentNamespaceImports);
                                    return(new List <TFSemantics.Node> {
                                        });
                                }

                                case "Alias":
                                {
                                    var      GenericParameters = new List <VariableDef>();
                                    TypeSpec Type = null;

                                    foreach (var Line in ContentLines)
                                    {
                                        String   cName        = null;
                                        TypeSpec cType        = null;
                                        var      cAttributes  = new List <KeyValuePair <String, List <String> > >();
                                        var      cDescription = "";

                                        if (Line.Nodes.Count == 1)
                                        {
                                            if (Type != null)
                                            {
                                                throw new InvalidEvaluationException("InvalidLine", nm.GetFileRange(Line), Line);
                                            }
                                            Type = ParseTypeSpec(Line.Nodes[0], nm, Positions);
                                            continue;
                                        }
                                        else if (Line.Nodes.Count == 2)
                                        {
                                            cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName");
                                            cType = ParseTypeSpec(Line.Nodes[1], nm, Positions);
                                        }
                                        else if (Line.Nodes.Count == 3)
                                        {
                                            cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName");
                                            cType = ParseTypeSpec(Line.Nodes[1], nm, Positions);
                                            var c = TokenParser.DecomposeDescription(GetLeafNodeValue(Line.Nodes[2], nm, "InvalidDescription"));
                                            cAttributes = c.Attributes;
                                            Mark(cAttributes, Line.Nodes[2]);
                                            cDescription = c.Description;
                                        }
                                        else if (Line.Nodes.Count == 0)
                                        {
                                            continue;
                                        }
                                        else
                                        {
                                            throw new InvalidEvaluationException("InvalidLineNodeCount", nm.GetFileRange(Line), Line);
                                        }

                                        if (cName.StartsWith("'"))
                                        {
                                            cName = new String(cName.Skip(1).ToArray());
                                            var gp = new VariableDef {
                                                Name = cName, Type = cType, Attributes = cAttributes, Description = cDescription
                                            };
                                            Mark(gp, Line);
                                            GenericParameters.Add(gp);
                                        }
                                        else
                                        {
                                            throw new InvalidEvaluationException("InvalidLine", nm.GetFileRange(Line), Line);
                                        }
                                    }

                                    if (Type == null)
                                    {
                                        throw new InvalidEvaluationException("InvalidContent", nm.GetFileRange(ContentLines), ContentLines);
                                    }

                                    var a = new AliasDef {
                                        Name = Name, Version = Version, GenericParameters = GenericParameters, Type = Type, Attributes = Attributes, Description = Description
                                    };
                                    Mark(a, f);
                                    var t = TypeDef.CreateAlias(a);
                                    Mark(t, f);
                                    Types.Add(t);
                                    TypeToNamespace.Add(t, CurrentNamespace);
                                    TypeToNamespaceImports.Add(t, CurrentNamespaceImports);
                                    return(new List <TFSemantics.Node> {
                                        });
                                }

                                case "Record":
                                {
                                    var GenericParameters = new List <VariableDef>();
                                    var Fields            = new List <VariableDef>();

                                    foreach (var Line in ContentLines)
                                    {
                                        String   cName        = null;
                                        TypeSpec cType        = null;
                                        var      cAttributes  = new List <KeyValuePair <String, List <String> > >();
                                        var      cDescription = "";

                                        if (Line.Nodes.Count == 2)
                                        {
                                            cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName");
                                            cType = ParseTypeSpec(Line.Nodes[1], nm, Positions);
                                        }
                                        else if (Line.Nodes.Count == 3)
                                        {
                                            cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName");
                                            cType = ParseTypeSpec(Line.Nodes[1], nm, Positions);
                                            var c = TokenParser.DecomposeDescription(GetLeafNodeValue(Line.Nodes[2], nm, "InvalidDescription"));
                                            cAttributes = c.Attributes;
                                            Mark(cAttributes, Line.Nodes[2]);
                                            cDescription = c.Description;
                                        }
                                        else if (Line.Nodes.Count == 0)
                                        {
                                            continue;
                                        }
                                        else
                                        {
                                            throw new InvalidEvaluationException("InvalidLineNodeCount", nm.GetFileRange(Line), Line);
                                        }

                                        if (cName.StartsWith("'"))
                                        {
                                            cName = new String(cName.Skip(1).ToArray());
                                            var gp = new VariableDef {
                                                Name = cName, Type = cType, Attributes = cAttributes, Description = cDescription
                                            };
                                            Mark(gp, Line);
                                            GenericParameters.Add(gp);
                                        }
                                        else
                                        {
                                            var p = new VariableDef {
                                                Name = cName, Type = cType, Attributes = cAttributes, Description = cDescription
                                            };
                                            Mark(p, Line);
                                            Fields.Add(p);
                                        }
                                    }

                                    var r = new RecordDef {
                                        Name = Name, Version = Version, GenericParameters = GenericParameters, Fields = Fields, Attributes = Attributes, Description = Description
                                    };
                                    Mark(r, f);
                                    var t = TypeDef.CreateRecord(r);
                                    Mark(t, f);
                                    Types.Add(t);
                                    TypeToNamespace.Add(t, CurrentNamespace);
                                    TypeToNamespaceImports.Add(t, CurrentNamespaceImports);
                                    return(new List <TFSemantics.Node> {
                                        });
                                }

                                case "TaggedUnion":
                                {
                                    var GenericParameters = new List <VariableDef>();
                                    var Alternatives      = new List <VariableDef>();

                                    foreach (var Line in ContentLines)
                                    {
                                        String   cName        = null;
                                        TypeSpec cType        = null;
                                        var      cAttributes  = new List <KeyValuePair <String, List <String> > >();
                                        var      cDescription = "";

                                        if (Line.Nodes.Count == 2)
                                        {
                                            cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidAlternativeName");
                                            cType = ParseTypeSpec(Line.Nodes[1], nm, Positions);
                                        }
                                        else if (Line.Nodes.Count == 3)
                                        {
                                            cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidAlternativeName");
                                            cType = ParseTypeSpec(Line.Nodes[1], nm, Positions);
                                            var c = TokenParser.DecomposeDescription(GetLeafNodeValue(Line.Nodes[2], nm, "InvalidDescription"));
                                            cAttributes = c.Attributes;
                                            Mark(cAttributes, Line.Nodes[2]);
                                            cDescription = c.Description;
                                        }
                                        else if (Line.Nodes.Count == 0)
                                        {
                                            continue;
                                        }
                                        else
                                        {
                                            throw new InvalidEvaluationException("InvalidLineNodeCount", nm.GetFileRange(Line), Line);
                                        }

                                        if (cName.StartsWith("'"))
                                        {
                                            cName = new String(cName.Skip(1).ToArray());
                                            var gp = new VariableDef {
                                                Name = cName, Type = cType, Attributes = cAttributes, Description = cDescription
                                            };
                                            Mark(gp, Line);
                                            GenericParameters.Add(gp);
                                        }
                                        else
                                        {
                                            var p = new VariableDef {
                                                Name = cName, Type = cType, Attributes = cAttributes, Description = cDescription
                                            };
                                            Mark(p, Line);
                                            Alternatives.Add(p);
                                        }
                                    }

                                    var tu = new TaggedUnionDef {
                                        Name = Name, Version = Version, GenericParameters = GenericParameters, Alternatives = Alternatives, Attributes = Attributes, Description = Description
                                    };
                                    Mark(tu, f);
                                    var t = TypeDef.CreateTaggedUnion(tu);
                                    Mark(t, f);
                                    Types.Add(t);
                                    TypeToNamespace.Add(t, CurrentNamespace);
                                    TypeToNamespaceImports.Add(t, CurrentNamespaceImports);
                                    return(new List <TFSemantics.Node> {
                                        });
                                }

                                case "Enum":
                                {
                                    var Literals = new List <LiteralDef>();

                                    Int64 NextValue = 0;
                                    foreach (var Line in ContentLines)
                                    {
                                        String cName        = null;
                                        Int64  cValue       = NextValue;
                                        var    cAttributes  = new List <KeyValuePair <String, List <String> > >();
                                        var    cDescription = "";

                                        if (Line.Nodes.Count == 1)
                                        {
                                            cName  = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidLiteralName");
                                            cValue = NextValue;
                                        }
                                        else if (Line.Nodes.Count == 2)
                                        {
                                            cName  = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidLiteralName");
                                            cValue = NumericStrings.InvariantParseInt64(GetLeafNodeValue(Line.Nodes[1], nm, "InvalidLiteralValue"));
                                        }
                                        else if (Line.Nodes.Count == 3)
                                        {
                                            cName  = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidLiteralName");
                                            cValue = NumericStrings.InvariantParseInt64(GetLeafNodeValue(Line.Nodes[1], nm, "InvalidLiteralValue"));
                                            var c = TokenParser.DecomposeDescription(GetLeafNodeValue(Line.Nodes[2], nm, "InvalidDescription"));
                                            cAttributes = c.Attributes;
                                            Mark(cAttributes, Line.Nodes[2]);
                                            cDescription = c.Description;
                                        }
                                        else if (Line.Nodes.Count == 0)
                                        {
                                            continue;
                                        }
                                        else
                                        {
                                            throw new InvalidEvaluationException("InvalidLineNodeCount", nm.GetFileRange(Line), Line);
                                        }
                                        NextValue = cValue + 1;

                                        var ltl = new LiteralDef {
                                            Name = cName, Value = cValue, Attributes = cAttributes, Description = cDescription
                                        };
                                        Mark(ltl, Line);
                                        Literals.Add(ltl);
                                    }

                                    var IntTypeName = new List <String> {
                                        "Int"
                                    };
                                    Mark(IntTypeName, f);
                                    var r = new TypeRef {
                                        Name = IntTypeName, Version = ""
                                    };
                                    Mark(r, f);
                                    var UnderlyingType = TypeSpec.CreateTypeRef(r);
                                    Mark(UnderlyingType, f);
                                    var ed = new EnumDef {
                                        Name = Name, Version = Version, UnderlyingType = UnderlyingType, Literals = Literals, Attributes = Attributes, Description = Description
                                    };
                                    Mark(ed, f);
                                    var t = TypeDef.CreateEnum(ed);
                                    Mark(t, f);
                                    Types.Add(t);
                                    TypeToNamespace.Add(t, CurrentNamespace);
                                    TypeToNamespaceImports.Add(t, CurrentNamespaceImports);
                                    return(new List <TFSemantics.Node> {
                                        });
                                }

                                case "ClientCommand":
                                {
                                    var OutParameters = new List <VariableDef>();
                                    var InParameters  = new List <VariableDef>();

                                    Boolean IsInParameter = false;
                                    foreach (var Line in ContentLines)
                                    {
                                        String   cName        = null;
                                        TypeSpec cType        = null;
                                        var      cAttributes  = new List <KeyValuePair <String, List <String> > >();
                                        var      cDescription = "";

                                        if (Line.Nodes.Count == 1)
                                        {
                                            if (GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName") == ">")
                                            {
                                                IsInParameter = true;
                                                continue;
                                            }
                                            else
                                            {
                                                throw new InvalidEvaluationException("InvalidLine", nm.GetFileRange(Line), Line);
                                            }
                                        }
                                        else if (Line.Nodes.Count == 2)
                                        {
                                            cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName");
                                            cType = ParseTypeSpec(Line.Nodes[1], nm, Positions);
                                        }
                                        else if (Line.Nodes.Count == 3)
                                        {
                                            cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName");
                                            cType = ParseTypeSpec(Line.Nodes[1], nm, Positions);
                                            var c = TokenParser.DecomposeDescription(GetLeafNodeValue(Line.Nodes[2], nm, "InvalidDescription"));
                                            cAttributes = c.Attributes;
                                            Mark(cAttributes, Line.Nodes[2]);
                                            cDescription = c.Description;
                                        }
                                        else if (Line.Nodes.Count == 0)
                                        {
                                            continue;
                                        }
                                        else
                                        {
                                            throw new InvalidEvaluationException("InvalidLineNodeCount", nm.GetFileRange(Line), Line);
                                        }

                                        var p = new VariableDef {
                                            Name = cName, Type = cType, Attributes = cAttributes, Description = cDescription
                                        };
                                        Mark(p, Line);
                                        if (IsInParameter)
                                        {
                                            InParameters.Add(p);
                                        }
                                        else
                                        {
                                            OutParameters.Add(p);
                                        }
                                    }

                                    var cc = new ClientCommandDef {
                                        Name = Name, Version = Version, OutParameters = OutParameters, InParameters = InParameters, Attributes = Attributes, Description = Description
                                    };
                                    Mark(cc, f);
                                    var t = TypeDef.CreateClientCommand(cc);
                                    Mark(t, f);
                                    Types.Add(t);
                                    TypeToNamespace.Add(t, CurrentNamespace);
                                    TypeToNamespaceImports.Add(t, CurrentNamespaceImports);
                                    return(new List <TFSemantics.Node> {
                                        });
                                }

                                case "ServerCommand":
                                {
                                    var OutParameters = new List <VariableDef>();

                                    foreach (var Line in ContentLines)
                                    {
                                        String   cName        = null;
                                        TypeSpec cType        = null;
                                        var      cAttributes  = new List <KeyValuePair <String, List <String> > >();
                                        var      cDescription = "";

                                        if (Line.Nodes.Count == 2)
                                        {
                                            cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName");
                                            cType = ParseTypeSpec(Line.Nodes[1], nm, Positions);
                                        }
                                        else if (Line.Nodes.Count == 3)
                                        {
                                            cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName");
                                            cType = ParseTypeSpec(Line.Nodes[1], nm, Positions);
                                            var c = TokenParser.DecomposeDescription(GetLeafNodeValue(Line.Nodes[2], nm, "InvalidDescription"));
                                            cAttributes = c.Attributes;
                                            Mark(cAttributes, Line.Nodes[2]);
                                            cDescription = c.Description;
                                        }
                                        else if (Line.Nodes.Count == 0)
                                        {
                                            continue;
                                        }
                                        else
                                        {
                                            throw new InvalidEvaluationException("InvalidLineNodeCount", nm.GetFileRange(Line), Line);
                                        }

                                        var p = new VariableDef {
                                            Name = cName, Type = cType, Attributes = cAttributes, Description = cDescription
                                        };
                                        Mark(p, Line);
                                        OutParameters.Add(p);
                                    }

                                    var sc = new ServerCommandDef {
                                        Name = Name, Version = Version, OutParameters = OutParameters, Attributes = Attributes, Description = Description
                                    };
                                    Mark(sc, f);
                                    var t = TypeDef.CreateServerCommand(sc);
                                    Mark(t, f);
                                    Types.Add(t);
                                    TypeToNamespace.Add(t, CurrentNamespace);
                                    TypeToNamespaceImports.Add(t, CurrentNamespaceImports);
                                    return(new List <TFSemantics.Node> {
                                        });
                                }

                                default:
                                {
                                    throw new InvalidEvaluationException("UnknownFunction", nm.GetFileRange(f), f);
                                }
                                }
                            }
                            else if (f.Name.Text == "Namespace")
                            {
                                if (f.Parameters.Count != 1)
                                {
                                    throw new InvalidEvaluationException("InvalidParameterCount", nm.GetFileRange(f), f);
                                }
                                var NamespaceParts = ExtractNamespaceParts(f.Parameters[0]);

                                Mark(NamespaceParts, f);
                                CurrentNamespace = NamespaceParts;
                                return(new List <TFSemantics.Node> {
                                });
                            }
                            else if (f.Name.Text == "Import")
                            {
                                if (f.Parameters.Count != 0)
                                {
                                    throw new InvalidEvaluationException("InvalidParameterCount", nm.GetFileRange(f), f);
                                }

                                var ContentLines = new List <FunctionCallTableLine> {
                                };
                                if (f.Content.OnSome)
                                {
                                    var ContentValue = f.Content.Value;
                                    if (!ContentValue.OnTableContent)
                                    {
                                        throw new InvalidEvaluationException("InvalidContent", nm.GetFileRange(ContentValue), ContentValue);
                                    }
                                    ContentLines = ContentValue.TableContent;
                                }

                                var NamespaceImports = new List <List <String> >();

                                foreach (var Line in ContentLines)
                                {
                                    if (Line.Nodes.Count == 1)
                                    {
                                        var NamespaceParts = ExtractNamespaceParts(Line.Nodes[0]);
                                        Mark(NamespaceParts, Line.Nodes[0]);
                                        NamespaceImports.Add(NamespaceParts);
                                    }
                                    else if (Line.Nodes.Count == 0)
                                    {
                                        continue;
                                    }
                                    else
                                    {
                                        throw new InvalidEvaluationException("InvalidLineNodeCount", nm.GetFileRange(Line), Line);
                                    }
                                }

                                CurrentNamespaceImports = CurrentNamespaceImports.Concat(NamespaceImports).ToList();

                                return(new List <TFSemantics.Node> {
                                });
                            }
                            else
                            {
                                throw new InvalidEvaluationException("UnknownFunction", nm.GetFileRange(f), f);
                            }
                        }
                    };
                    var e = new TreeFormatEvaluator(es, pr);
                    e.Evaluate();
                }
                else
                {
                    var pr = new TreeFormatParseResult
                    {
                        Value = new Forest {
                            MultiNodesList = new List <MultiNodes> {
                                TopNode
                            }
                        },
                        Text             = Text,
                        Positions        = ParserResult.Positions,
                        RawFunctionCalls = ParserResult.RawFunctionCalls
                    };
                    var es = new TreeFormatEvaluateSetting {
                    };
                    var e  = new TreeFormatEvaluator(es, pr);
                    var er = e.Evaluate();
                    if (er.Value.Nodes.Count > 0)
                    {
                        var ReadResult = ts.Read <Schema>(CollectionOperations.CreatePair(er.Value, er.Positions));
                        Types.AddRange(ReadResult.Key.Types);
                        TypeRefs.AddRange(ReadResult.Key.TypeRefs);
                        Imports.AddRange(ReadResult.Key.Imports);
                        foreach (var p in ReadResult.Value)
                        {
                            if (p.Value.Range.OnSome)
                            {
                                Positions.Add(p.Key, p.Value.Range.Value);
                            }
                        }
                    }
                }
            }

            return(new FileParserResult {
                Text = Text, Positions = Positions, Types = Types, TypeRefs = TypeRefs, Imports = Imports, TypeToNamespace = TypeToNamespace, TypeToNamespaceImports = TypeToNamespaceImports
            });
        }
示例#30
0
        public static FileParserResult ParseFile(Text Text)
        {
            var TypeFunctions = new HashSet <String>()
            {
                "Primitive", "Entity", "Enum"
            };
            var TableParameterFunctions = new HashSet <String>(TypeFunctions.Concat(new List <String> {
                "Query"
            }));
            var TableContentFunctions = TypeFunctions;

            var ps = new TreeFormatParseSetting()
            {
                IsTableParameterFunction = Name => TableParameterFunctions.Contains(Name),
                IsTableContentFunction   = Name => TableContentFunctions.Contains(Name)
            };

            var sp           = new TreeFormatSyntaxParser(ps, Text);
            var ParserResult = sp.Parse();
            var ts           = new TreeSerializer();

            var Types    = new List <TypeDef>();
            var TypeRefs = new List <TypeDef>();
            var Imports  = new List <String>();

            var Positions = new Dictionary <Object, TextRange>();

            foreach (var TopNode in ParserResult.Value.MultiNodesList)
            {
                if (TopNode.OnFunctionNodes)
                {
                    var pr = new TreeFormatParseResult
                    {
                        Value = new Forest {
                            MultiNodesList = new List <MultiNodes> {
                                TopNode
                            }
                        },
                        Text             = Text,
                        Positions        = ParserResult.Positions,
                        RawFunctionCalls = ParserResult.RawFunctionCalls
                    };
                    var es = new TreeFormatEvaluateSetting
                    {
                        FunctionCallEvaluator = (f, nm) =>
                        {
                            Action <Object, Object> Mark = (SemanticsObj, SyntaxObj) =>
                            {
                                var Range = nm.GetRange(SyntaxObj);
                                if (Range.OnSome)
                                {
                                    Positions.Add(SemanticsObj, Range.Value);
                                }
                            };

                            if (TypeFunctions.Contains(f.Name.Text))
                            {
                                if (f.Parameters.Count < 1 || f.Parameters.Count > 2)
                                {
                                    throw new InvalidEvaluationException("InvalidParameterCount", nm.GetFileRange(f), f);
                                }

                                var VersionedName = GetLeafNodeValue(f.Parameters[0], nm, "InvalidName");
                                var TypeRef       = ParseTypeRef(VersionedName);
                                Mark(TypeRef, f.Parameters[0]);
                                var Name = (String)TypeRef;

                                var Attributes  = new List <KeyValuePair <String, List <String> > >();
                                var Description = "";
                                if (f.Parameters.Count >= 2)
                                {
                                    var DescriptionParameter = f.Parameters[1];
                                    if (!DescriptionParameter.OnLeaf)
                                    {
                                        throw new InvalidEvaluationException("InvalidDescription", nm.GetFileRange(DescriptionParameter), DescriptionParameter);
                                    }
                                    var c = OS.TokenParser.DecomposeDescription(DescriptionParameter.Leaf);
                                    Attributes = c.Attributes;
                                    Mark(Attributes, f.Parameters[1]);
                                    Description = c.Description;
                                }

                                var ContentLines = new List <FunctionCallTableLine> {
                                };
                                if (f.Content.OnSome)
                                {
                                    var ContentValue = f.Content.Value;
                                    if (!ContentValue.OnTableContent)
                                    {
                                        throw new InvalidEvaluationException("InvalidContent", nm.GetFileRange(ContentValue), ContentValue);
                                    }
                                    ContentLines = ContentValue.TableContent;
                                }

                                switch (f.Name.Text)
                                {
                                case "Primitive":
                                {
                                    var GenericParameters = new List <VariableDef>();

                                    foreach (var Line in ContentLines)
                                    {
                                        String   cName        = null;
                                        TypeSpec cType        = null;
                                        var      cAttributes  = new List <KeyValuePair <String, List <String> > >();
                                        var      cDescription = "";

                                        if (Line.Nodes.Count == 2)
                                        {
                                            cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName");
                                            cType = ParseTypeSpec(Line.Nodes[1], nm, Positions);
                                        }
                                        else if (Line.Nodes.Count == 3)
                                        {
                                            cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName");
                                            cType = ParseTypeSpec(Line.Nodes[1], nm, Positions);
                                            var c = OS.TokenParser.DecomposeDescription(GetLeafNodeValue(Line.Nodes[2], nm, "InvalidDescription"));
                                            cAttributes = c.Attributes;
                                            Mark(cAttributes, Line.Nodes[2]);
                                            cDescription = c.Description;
                                        }
                                        else if (Line.Nodes.Count == 0)
                                        {
                                            continue;
                                        }
                                        else
                                        {
                                            throw new InvalidEvaluationException("InvalidLineNodeCount", nm.GetFileRange(Line), Line);
                                        }

                                        if (cName.StartsWith("'"))
                                        {
                                            cName = new String(cName.Skip(1).ToArray());
                                            var gp = new VariableDef {
                                                Name = cName, Type = cType, Attributes = cAttributes, Description = cDescription, Attribute = null
                                            };
                                            Mark(gp, Line);
                                            GenericParameters.Add(gp);
                                        }
                                        else
                                        {
                                            throw new InvalidEvaluationException("InvalidLine", nm.GetFileRange(Line), Line);
                                        }
                                    }

                                    var p = new PrimitiveDef {
                                        Name = Name, Attributes = Attributes, Description = Description
                                    };
                                    Mark(p, f);
                                    var t = TypeDef.CreatePrimitive(p);
                                    Mark(t, f);
                                    Types.Add(t);
                                    return(new List <TFSemantics.Node> {
                                        });
                                }

                                case "Entity":
                                {
                                    var Fields = new List <VariableDef>();

                                    foreach (var Line in ContentLines)
                                    {
                                        String   cName        = null;
                                        TypeSpec cType        = null;
                                        var      cAttributes  = new List <KeyValuePair <String, List <String> > >();
                                        var      cDescription = "";

                                        if (Line.Nodes.Count == 2)
                                        {
                                            cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName");
                                            cType = ParseTypeSpec(Line.Nodes[1], nm, Positions);
                                        }
                                        else if (Line.Nodes.Count == 3)
                                        {
                                            cName = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidFieldName");
                                            cType = ParseTypeSpec(Line.Nodes[1], nm, Positions);
                                            var c = OS.TokenParser.DecomposeDescription(GetLeafNodeValue(Line.Nodes[2], nm, "InvalidDescription"));
                                            cAttributes = c.Attributes;
                                            Mark(cAttributes, Line.Nodes[2]);
                                            cDescription = c.Description;
                                        }
                                        else if (Line.Nodes.Count == 0)
                                        {
                                            continue;
                                        }
                                        else
                                        {
                                            throw new InvalidEvaluationException("InvalidLineNodeCount", nm.GetFileRange(Line), Line);
                                        }

                                        var p = new VariableDef {
                                            Name = cName, Type = cType, Attributes = cAttributes, Description = cDescription
                                        };
                                        Mark(p, Line);
                                        Fields.Add(p);
                                    }

                                    var ed = new EntityDef {
                                        Name = Name, Fields = Fields, Attributes = Attributes, Description = Description
                                    };
                                    Mark(ed, f);
                                    var t = TypeDef.CreateEntity(ed);
                                    Mark(t, f);
                                    Types.Add(t);
                                    return(new List <TFSemantics.Node> {
                                        });
                                }

                                case "Enum":
                                {
                                    var Literals = new List <LiteralDef>();

                                    Int64 NextValue = 0;
                                    foreach (var Line in ContentLines)
                                    {
                                        String cName        = null;
                                        Int64  cValue       = NextValue;
                                        var    cAttributes  = new List <KeyValuePair <String, List <String> > >();
                                        var    cDescription = "";

                                        if (Line.Nodes.Count == 1)
                                        {
                                            cName  = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidLiteralName");
                                            cValue = NextValue;
                                        }
                                        else if (Line.Nodes.Count == 2)
                                        {
                                            cName  = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidLiteralName");
                                            cValue = NumericStrings.InvariantParseInt64(GetLeafNodeValue(Line.Nodes[1], nm, "InvalidLiteralValue"));
                                        }
                                        else if (Line.Nodes.Count == 3)
                                        {
                                            cName  = GetLeafNodeValue(Line.Nodes[0], nm, "InvalidLiteralName");
                                            cValue = NumericStrings.InvariantParseInt64(GetLeafNodeValue(Line.Nodes[1], nm, "InvalidLiteralValue"));
                                            var c = OS.TokenParser.DecomposeDescription(GetLeafNodeValue(Line.Nodes[2], nm, "InvalidDescription"));
                                            cAttributes = c.Attributes;
                                            Mark(cAttributes, Line.Nodes[2]);
                                            cDescription = c.Description;
                                        }
                                        else if (Line.Nodes.Count == 0)
                                        {
                                            continue;
                                        }
                                        else
                                        {
                                            throw new InvalidEvaluationException("InvalidLineNodeCount", nm.GetFileRange(Line), Line);
                                        }
                                        NextValue = cValue + 1;

                                        var ltl = new LiteralDef {
                                            Name = cName, Value = cValue, Attributes = cAttributes, Description = cDescription
                                        };
                                        Mark(ltl, Line);
                                        Literals.Add(ltl);
                                    }

                                    var r = (TypeRef)("Int");
                                    Mark(r, f);
                                    var UnderlyingType = TypeSpec.CreateTypeRef(r);
                                    Mark(UnderlyingType, f);
                                    var ed = new EnumDef {
                                        Name = Name, UnderlyingType = UnderlyingType, Literals = Literals, Attributes = Attributes, Description = Description
                                    };
                                    Mark(ed, f);
                                    var t = TypeDef.CreateEnum(ed);
                                    Mark(t, f);
                                    Types.Add(t);
                                    return(new List <TFSemantics.Node> {
                                        });
                                }

                                default:
                                {
                                    throw new InvalidEvaluationException("UnknownFunction", nm.GetFileRange(f), f);
                                }
                                }
                            }
                            else if (f.Name.Text == "Query")
                            {
                                if (f.Parameters.Count != 0)
                                {
                                    throw new InvalidEvaluationException("InvalidParameterCount", nm.GetFileRange(f), f);
                                }

                                var Verbs = new Dictionary <String, Func <Verb> >
                                {
                                    { "Select", () => Verb.CreateSelect() },
                                    { "Lock", () => Verb.CreateLock() },
                                    { "Insert", () => Verb.CreateInsert() },
                                    { "Update", () => Verb.CreateUpdate() },
                                    { "Upsert", () => Verb.CreateUpsert() },
                                    { "Delete", () => Verb.CreateDelete() }
                                };
                                var Numerals = new Dictionary <String, Func <Numeral> >
                                {
                                    { "Optional", () => Numeral.CreateOptional() },
                                    { "One", () => Numeral.CreateOne() },
                                    { "Many", () => Numeral.CreateMany() },
                                    { "All", () => Numeral.CreateAll() },
                                    { "Range", () => Numeral.CreateRange() },
                                    { "Count", () => Numeral.CreateCount() }
                                };
                                Func <int, TextLine, List <QueryDef> > ParseQueryDef = (IndentLevel, Line) =>
                                {
                                    var l = new List <TFSemantics.Node>();
                                    List <TFSemantics.Node> cl      = null;
                                    TextPosition            clStart = default(TextPosition);
                                    TextPosition            clEnd   = default(TextPosition);
                                    if (Line.Text.Length < IndentLevel * 4)
                                    {
                                        return(new List <QueryDef> {
                                        });
                                    }
                                    var LineRange = new TextRange {
                                        Start = Text.Calc(Line.Range.Start, IndentLevel * 4), End = Line.Range.End
                                    };
                                    var Range = LineRange;
                                    while (true)
                                    {
                                        var tpr = TreeFormatTokenParser.ReadToken(Text, pr.Positions, Range);
                                        if (!tpr.OnSome)
                                        {
                                            break;
                                        }

                                        var v = tpr.Value.Token;
                                        if (v.OnSingleLineComment)
                                        {
                                            break;
                                        }
                                        if (v.OnLeftParenthesis)
                                        {
                                            if (cl != null)
                                            {
                                                throw new InvalidTokenException("DoubleLeftParenthesis", new FileTextRange {
                                                    Text = Text, Range = Range
                                                }, "(");
                                            }
                                            cl      = new List <TFSemantics.Node>();
                                            clStart = Range.Start;
                                            clEnd   = Range.End;
                                        }
                                        else if (v.OnRightParenthesis)
                                        {
                                            if (cl == null)
                                            {
                                                throw new InvalidTokenException("DismatchedRightParenthesis", new FileTextRange {
                                                    Text = Text, Range = Range
                                                }, ")");
                                            }
                                            if (cl.Count == 0)
                                            {
                                                throw new InvalidTokenException("EmptyIndex", new FileTextRange {
                                                    Text = Text, Range = Range
                                                }, ")");
                                            }
                                            if (tpr.Value.RemainingChars.OnSome)
                                            {
                                                clEnd = tpr.Value.RemainingChars.Value.End;
                                            }
                                            l.Add(nm.MakeStemNode("", cl, new TextRange {
                                                Start = clStart, End = clEnd
                                            }));
                                            cl      = null;
                                            clStart = default(TextPosition);
                                            clEnd   = default(TextPosition);
                                        }
                                        else if (v.OnSingleLineLiteral)
                                        {
                                            if (cl != null)
                                            {
                                                cl.Add(nm.MakeLeafNode(v.SingleLineLiteral, pr.Positions[v]));
                                            }
                                            else
                                            {
                                                l.Add(nm.MakeLeafNode(v.SingleLineLiteral, pr.Positions[v]));
                                            }
                                        }
                                        else
                                        {
                                            throw new InvalidTokenException("UnknownToken", new FileTextRange {
                                                Text = Text, Range = Range
                                            }, Text.GetTextInLine(Range));
                                        }

                                        if (!tpr.Value.RemainingChars.OnSome)
                                        {
                                            break;
                                        }

                                        Range = tpr.Value.RemainingChars.Value;
                                    }
                                    if (cl != null)
                                    {
                                        throw new InvalidTokenException("DismatchedRightParentheses", new FileTextRange {
                                            Text = Text, Range = Range
                                        }, "");
                                    }

                                    if (l.Count == 0)
                                    {
                                        return(new List <QueryDef> {
                                        });
                                    }

                                    if (l.Count != 4 && l.Count != 6 && l.Count != 8)
                                    {
                                        throw new InvalidSyntaxException("InvalidQuery", new FileTextRange {
                                            Text = Text, Range = LineRange
                                        });
                                    }
                                    var From = GetLeafNodeValue(l[0], nm, "InvalidFrom");
                                    if (From != "From")
                                    {
                                        throw new InvalidTokenException("InvalidFrom", nm.GetFileRange(l[0]), From);
                                    }
                                    var EntityName = GetLeafNodeValue(l[1], nm, "InvalidEntityName");
                                    var VerbName   = GetLeafNodeValue(l[2], nm, "InvalidVerb");
                                    if (!Verbs.ContainsKey(VerbName))
                                    {
                                        throw new InvalidTokenException("InvalidVerb", nm.GetFileRange(l[2]), VerbName);
                                    }
                                    var Verb = Verbs[VerbName]();
                                    Mark(Verb, l[2]);
                                    var NumeralName = GetLeafNodeValue(l[3], nm, "InvalidNumeral");
                                    if (!Numerals.ContainsKey(NumeralName))
                                    {
                                        throw new InvalidTokenException("InvalidNumeral", nm.GetFileRange(l[3]), NumeralName);
                                    }
                                    var Numeral = Numerals[NumeralName]();
                                    Mark(Numeral, l[3]);

                                    var By      = new List <String> {
                                    };
                                    var OrderBy = new List <KeyColumn> {
                                    };

                                    if (l.Count >= 6)
                                    {
                                        var ByOrOrderByName = GetLeafNodeValue(l[4], nm, "InvalidByOrOrderBy");
                                        if (ByOrOrderByName == "By")
                                        {
                                            if (l[5].OnLeaf)
                                            {
                                                By = new List <String> {
                                                    l[5].Leaf
                                                };
                                            }
                                            else if (l[5].OnStem)
                                            {
                                                By = l[5].Stem.Children.Select(c => GetLeafNodeValue(c, nm, "InvalidKeyColumn")).ToList();
                                            }
                                            else
                                            {
                                                throw new InvalidSyntaxException("InvalidBy", nm.GetFileRange(l[5]));
                                            }
                                            Mark(By, l[5]);
                                        }
                                        else if (ByOrOrderByName == "OrderBy")
                                        {
                                            if (l[5].OnLeaf)
                                            {
                                                OrderBy = (new List <String> {
                                                    l[5].Leaf
                                                }).Select(c => c.EndsWith("-") ? new KeyColumn {
                                                    Name = c.Substring(0, c.Length - 1), IsDescending = true
                                                } : new KeyColumn {
                                                    Name = c, IsDescending = false
                                                }).ToList();
                                            }
                                            else if (l[5].OnStem)
                                            {
                                                OrderBy = l[5].Stem.Children.Select(c => GetLeafNodeValue(c, nm, "InvalidKeyColumn")).Select(c => c.EndsWith("-") ? new KeyColumn {
                                                    Name = c.Substring(0, c.Length - 1), IsDescending = true
                                                } : new KeyColumn {
                                                    Name = c, IsDescending = false
                                                }).ToList();
                                            }
                                            else
                                            {
                                                throw new InvalidSyntaxException("InvalidOrderBy", nm.GetFileRange(l[5]));
                                            }
                                            Mark(OrderBy, l[5]);
                                        }
                                        else
                                        {
                                            throw new InvalidSyntaxException("InvalidByOrOrderBy", nm.GetFileRange(l[5]));
                                        }
                                    }
                                    if (l.Count >= 8)
                                    {
                                        if (OrderBy.Count != 0)
                                        {
                                            throw new InvalidSyntaxException("InvalidOrderBy", nm.GetFileRange(l[6]));
                                        }
                                        var OrderByName = GetLeafNodeValue(l[6], nm, "InvalidOrderBy");
                                        if (OrderByName == "OrderBy")
                                        {
                                            if (l[7].OnLeaf)
                                            {
                                                OrderBy = (new List <String> {
                                                    l[7].Leaf
                                                }).Select(c => c.EndsWith("-") ? new KeyColumn {
                                                    Name = c.Substring(0, c.Length - 1), IsDescending = true
                                                } : new KeyColumn {
                                                    Name = c, IsDescending = false
                                                }).ToList();
                                            }
                                            else if (l[7].OnStem)
                                            {
                                                OrderBy = l[7].Stem.Children.Select(c => GetLeafNodeValue(c, nm, "InvalidKeyColumn")).Select(c => c.EndsWith("-") ? new KeyColumn {
                                                    Name = c.Substring(0, c.Length - 1), IsDescending = true
                                                } : new KeyColumn {
                                                    Name = c, IsDescending = false
                                                }).ToList();
                                            }
                                            else
                                            {
                                                throw new InvalidSyntaxException("InvalidOrderBy", nm.GetFileRange(l[7]));
                                            }
                                            Mark(OrderBy, l[7]);
                                        }
                                        else
                                        {
                                            throw new InvalidSyntaxException("InvalidOrderBy", nm.GetFileRange(l[7]));
                                        }
                                    }

                                    var q = new QueryDef {
                                        EntityName = EntityName, Verb = Verb, Numeral = Numeral, By = By, OrderBy = OrderBy
                                    };
                                    Mark(q, Line);
                                    return(new List <QueryDef> {
                                        q
                                    });
                                };

                                var Queries = f.Content.Value.LineContent.Lines.SelectMany(Line => ParseQueryDef(f.Content.Value.LineContent.IndentLevel, Line)).ToList();
                                Mark(Queries, f);
                                var ql = new QueryListDef {
                                    Queries = Queries
                                };
                                Mark(ql, f);
                                var t = TypeDef.CreateQueryList(ql);
                                Mark(t, f);
                                Types.Add(t);
                                return(new List <TFSemantics.Node> {
                                });
                            }
                            else
                            {
                                throw new InvalidEvaluationException("UnknownFunction", nm.GetFileRange(f), f);
                            }
                        }
                    };
                    var e = new TreeFormatEvaluator(es, pr);
                    e.Evaluate();
                }
                else
                {
                    var pr = new TreeFormatParseResult
                    {
                        Value = new Forest {
                            MultiNodesList = new List <MultiNodes> {
                                TopNode
                            }
                        },
                        Text             = Text,
                        Positions        = ParserResult.Positions,
                        RawFunctionCalls = ParserResult.RawFunctionCalls
                    };
                    var es = new TreeFormatEvaluateSetting {
                    };
                    var e  = new TreeFormatEvaluator(es, pr);
                    var er = e.Evaluate();
                    if (er.Value.Nodes.Count > 0)
                    {
                        var ReadResult = ts.Read <Schema>(CollectionOperations.CreatePair(er.Value, er.Positions));
                        Types.AddRange(ReadResult.Key.Types);
                        TypeRefs.AddRange(ReadResult.Key.TypeRefs);
                        Imports.AddRange(ReadResult.Key.Imports);
                        foreach (var p in ReadResult.Value)
                        {
                            if (p.Value.Range.OnSome)
                            {
                                Positions.Add(p.Key, p.Value.Range.Value);
                            }
                        }
                    }
                }
            }

            var Schema = new Schema {
                Types = Types, TypeRefs = TypeRefs, Imports = Imports
            };

            return(new FileParserResult {
                Schema = Schema, Text = Text, Positions = Positions
            });
        }