public List <TypeDef> GetCompatibleTypes(List <KeyValuePair <String, Schema> > VersionAndSchemaList)
        {
            var ResultTypes = new List <TypeDef> {
            };

            foreach (var k in Enumerable.Range(0, VersionAndSchemaList.Count - 1))
            {
                var Old = VersionAndSchemaList[k];
                var New = VersionAndSchemaList[k + 1];
                var AddtionalTypesToBePreserved = Generate(Old.Value, New.Value).Revert;
                var h       = new HashSet <String>(AddtionalTypesToBePreserved.Types.Select(t => t.VersionedName()), StringComparer.OrdinalIgnoreCase);
                var MapConf = new TypeMapConfiguration {
                    MapTypeSpecKernel = (d, ts) =>
                    {
                        if (ts.OnTypeRef && h.Contains(ts.TypeRef.VersionedName()))
                        {
                            return(TypeSpec.CreateTypeRef(new TypeRef {
                                Name = ts.TypeRef.Name, Version = Old.Key
                            }));
                        }
                        else
                        {
                            return(ts);
                        }
                    }
                };
                ResultTypes = ResultTypes.Select(t => t.MapType(MapConf)).Concat(AddtionalTypesToBePreserved.GetTypesVersioned(Old.Key).Types).ToList();
            }
            return(ResultTypes);
        }
Beispiel #2
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
            });
        }
Beispiel #3
0
        private void ResolveNamespaces()
        {
            var TypeDictionary = new HashSet <String>();

            List <String> ResolveTypeDefName(TypeDef t, List <String> Name, String Version)
            {
                var FullName = Name;

                if (TypeToNamespace.ContainsKey(t))
                {
                    FullName = TypeToNamespace[t].Concat(Name).ToList();
                }
                TypeDictionary.Add((new TypeRef {
                    Name = FullName, Version = Version
                }).VersionedName());
                return(FullName);
            }

            List <String> ResolveTypeRefName(TypeDef t, TypeRef Ref, List <String> Name, String Version)
            {
                if (TypeToNamespace.ContainsKey(t))
                {
                    var CandidateFullName = TypeToNamespace[t].Concat(Name).ToList();
                    if (TypeDictionary.Contains((new TypeRef {
                        Name = CandidateFullName, Version = Version
                    }).VersionedName()))
                    {
                        return(CandidateFullName);
                    }
                }
                if (TypeToNamespaceImports.ContainsKey(t))
                {
                    foreach (var Namespace in TypeToNamespaceImports[t])
                    {
                        var CandidateFullName = Namespace.Concat(Name).ToList();
                        if (TypeDictionary.Contains((new TypeRef {
                            Name = CandidateFullName, Version = Version
                        }).VersionedName()))
                        {
                            return(CandidateFullName);
                        }
                    }
                }
                return(Name);
            }

            var conf = new TypeMapConfiguration
            {
                MapTypeDefKernel = t =>
                {
                    if (t.OnPrimitive)
                    {
                        var p = t.Primitive;
                        return(TypeDef.CreatePrimitive(new PrimitiveDef {
                            Name = ResolveTypeDefName(t, p.Name, ""), GenericParameters = p.GenericParameters, Attributes = p.Attributes, Description = p.Description
                        }));
                    }
                    else if (t.OnAlias)
                    {
                        var a = t.Alias;
                        return(TypeDef.CreateAlias(new AliasDef {
                            Name = ResolveTypeDefName(t, a.Name, a.Version), Version = a.Version, GenericParameters = a.GenericParameters, Type = a.Type, Attributes = a.Attributes, Description = a.Description
                        }));
                    }
                    else if (t.OnRecord)
                    {
                        var r = t.Record;
                        return(TypeDef.CreateRecord(new RecordDef {
                            Name = ResolveTypeDefName(t, r.Name, r.Version), Version = r.Version, GenericParameters = r.GenericParameters, Fields = r.Fields, Attributes = r.Attributes, Description = r.Description
                        }));
                    }
                    else if (t.OnTaggedUnion)
                    {
                        var tu = t.TaggedUnion;
                        return(TypeDef.CreateTaggedUnion(new TaggedUnionDef {
                            Name = ResolveTypeDefName(t, tu.Name, tu.Version), Version = tu.Version, GenericParameters = tu.GenericParameters, Alternatives = tu.Alternatives, Attributes = tu.Attributes, Description = tu.Description
                        }));
                    }
                    else if (t.OnEnum)
                    {
                        var e = t.Enum;
                        return(TypeDef.CreateEnum(new EnumDef {
                            Name = ResolveTypeDefName(t, e.Name, e.Version), Version = e.Version, UnderlyingType = e.UnderlyingType, Literals = e.Literals, Attributes = e.Attributes, Description = e.Description
                        }));
                    }
                    else if (t.OnClientCommand)
                    {
                        var cc = t.ClientCommand;
                        return(TypeDef.CreateClientCommand(new ClientCommandDef {
                            Name = ResolveTypeDefName(t, cc.Name, cc.Version), Version = cc.Version, OutParameters = cc.OutParameters, InParameters = cc.InParameters, Attributes = cc.Attributes, Description = cc.Description
                        }));
                    }
                    else if (t.OnServerCommand)
                    {
                        var sc = t.ServerCommand;
                        return(TypeDef.CreateServerCommand(new ServerCommandDef {
                            Name = ResolveTypeDefName(t, sc.Name, sc.Version), Version = sc.Version, OutParameters = sc.OutParameters, Attributes = sc.Attributes, Description = sc.Description
                        }));
                    }
                    else
                    {
                        throw new InvalidOperationException();
                    }
                },
                TypeDefMarker     = MarkTypeDef,
                TypeSpecMarker    = Mark,
                VariableDefMarker = Mark
            };

            Types    = Types.Select(t => t.MapType(conf)).ToList();
            TypeRefs = TypeRefs.Select(t => t.MapType(conf)).ToList();

            var confTypeSpec = new TypeMapConfiguration
            {
                MapTypeSpecKernel = (t, ts) =>
                {
                    if (ts.OnTypeRef)
                    {
                        return(TypeSpec.CreateTypeRef(new TypeRef {
                            Name = ResolveTypeRefName(t, ts.TypeRef, ts.TypeRef.Name, ts.TypeRef.Version), Version = ts.TypeRef.Version
                        }));
                    }
                    else if (ts.OnGenericParameterRef)
                    {
                        return(ts);
                    }
                    else if (ts.OnTuple)
                    {
                        return(ts);
                    }
                    else if (ts.OnGenericTypeSpec)
                    {
                        return(ts);
                    }
                    else
                    {
                        throw new InvalidOperationException();
                    }
                },
                TypeDefMarker     = Mark,
                TypeSpecMarker    = Mark,
                VariableDefMarker = Mark
            };

            Types    = Types.Select(t => t.MapType(confTypeSpec)).ToList();
            TypeRefs = TypeRefs.Select(t => t.MapType(confTypeSpec)).ToList();

            TypeToNamespace        = new Dictionary <TypeDef, List <String> >();
            TypeToNamespaceImports = new Dictionary <TypeDef, List <List <String> > >();
        }
Beispiel #4
0
        public static Optional <TypeSpec> TryParseTypeSpec(String TypeString, Action <Object, int, int> Mark, out int InvalidCharIndex)
        {
            var osml = TokenParser.TrySplitSymbolMemberChain(TypeString, out InvalidCharIndex);

            if (osml.OnNone)
            {
                return(Optional <TypeSpec> .Empty);
            }
            var sml = osml.Value;

            var tTotal     = Optional <TypeSpec> .Empty;
            var FirstStart = 0;

            foreach (var s in sml)
            {
                var LocalInvalidCharIndex = 0;
                var oName = TokenParser.TryUnescapeSymbolName(s.Name, out LocalInvalidCharIndex);
                if (oName.OnNone)
                {
                    InvalidCharIndex = s.NameStartIndex + LocalInvalidCharIndex;
                    return(Optional <TypeSpec> .Empty);
                }
                var Name = oName.Value;

                var l = new List <TypeSpec>();
                foreach (var p in s.Parameters)
                {
                    var LocalLocalInvalidCharIndex = 0;
                    var ov = TryParseTypeSpec(p.Key, (o, Start, End) => Mark(o, p.Value + Start, p.Value + End), out LocalLocalInvalidCharIndex);
                    if (ov.OnNone)
                    {
                        InvalidCharIndex = p.Value + LocalLocalInvalidCharIndex;
                        return(Optional <TypeSpec> .Empty);
                    }
                    l.Add(ov.Value);
                }
                Mark(l, s.NameEndIndex, s.SymbolEndIndex);

                TypeSpec t;
                if (Name.StartsWith("'"))
                {
                    Name = new String(Name.Skip(1).ToArray());
                    t    = TypeSpec.CreateGenericParameterRef(Name);
                }
                else
                {
                    if (tTotal.OnSome)
                    {
                        if (!tTotal.Value.OnTypeRef || (tTotal.Value.TypeRef.Version != ""))
                        {
                            InvalidCharIndex = s.NameStartIndex;
                            return(Optional <TypeSpec> .Empty);
                        }
                    }
                    String Version;
                    ParseNameAndVersion(Name, out Name, out Version);
                    var NameList = tTotal.OnSome ? tTotal.Value.TypeRef.Name.Concat(new List <String> {
                        Name
                    }).ToList() : new List <String> {
                        Name
                    };
                    var Ref = new TypeRef {
                        Name = NameList, Version = Version
                    };
                    Mark(NameList, s.NameStartIndex, s.NameStartIndex + Name.Length);
                    Mark(Ref, s.NameStartIndex, s.NameEndIndex);
                    t = TypeSpec.CreateTypeRef(Ref);
                }
                Mark(t, s.NameStartIndex, s.NameEndIndex);

                if (s.Parameters.Count > 0)
                {
                    if (tTotal.OnNone && String.Equals(Name, "Tuple", StringComparison.OrdinalIgnoreCase))
                    {
                        t = TypeSpec.CreateTuple(l);
                    }
                    else
                    {
                        if (!t.OnTypeRef)
                        {
                            InvalidCharIndex = s.NameStartIndex;
                            return(Optional <TypeSpec> .Empty);
                        }
                        var gts = new GenericTypeSpec {
                            TypeSpec = t, ParameterValues = l
                        };
                        Mark(gts, s.SymbolStartIndex, s.SymbolEndIndex);
                        t = TypeSpec.CreateGenericTypeSpec(gts);
                    }
                    Mark(t, s.SymbolStartIndex, s.SymbolEndIndex);
                }

                if (tTotal.OnNone)
                {
                    tTotal     = t;
                    FirstStart = s.SymbolStartIndex;
                }
                else
                {
                    if (!tTotal.Value.OnTypeRef || !t.OnTypeRef)
                    {
                        InvalidCharIndex = s.NameStartIndex;
                        return(Optional <TypeSpec> .Empty);
                    }
                    tTotal = t;
                }
            }

            return(tTotal);
        }