static string HandleAddMethod(ParsedComponent parsedComponent, string add_extension)
        {
            var parameters = parsedComponent.Fields
                             .Select(x => x.Type + " " + x.Name)
                             .Aggregate((x, y) => x + ", " + y);

            var fieldSequence = parsedComponent.Fields
                                .Select(x => "c." + (parsedComponent.IsReactive() ? x.Name.VariateFirstChar() : x.Name.FirstCharToUpper()) + " = " + x.Name + ";")
                                .Aggregate((x, y) => x + Format.NewLine(2) + y);

            add_extension = add_extension
                            .Replace(ComponentParametersTag, parameters)
                            .Replace(AddingComponentsSequenceTag, fieldSequence);
            return(add_extension);
        }
Example #2
0
            internal void ConnectTo(string senderPort, ParsedComponent receiver, string receiverPort)
            {
                senderPort   = senderPort.Substring(0, 1).ToUpperInvariant() + senderPort.Substring(1).ToLowerInvariant();
                receiverPort = receiverPort.Substring(0, 1).ToUpperInvariant() + receiverPort.Substring(1).ToLowerInvariant();

                if (!OutputPorts.Contains(senderPort))
                {
                    OutputPorts = OutputPorts.Add(senderPort);
                }
                if (!receiver.InputPorts.Contains(receiverPort))
                {
                    receiver.InputPorts = receiver.InputPorts.Add(receiverPort);
                }
                OutputPortConnections = OutputPortConnections.Add(Tuple.Create(senderPort, receiver, receiverPort));
            }
        void GenerateComponentReactives(ParsedComponent parsedComponent)
        {
            if (!parsedComponent.HasFields)
            {
                return;
            }

            string result = MayBakeUsings() ? parsedComponent.Usings : string.Empty;

            var snippet = File.ReadAllText(settings.CodeSnippets.ComponentReactive);

            var subSnippet = snippet.Split(new string[] { ComponentReactiveBlock }, StringSplitOptions.None)[1];

            string members = "";

            if (parsedComponent.IsReactive())
            {
                members = parsedComponent.Fields
                          .Select(field => subSnippet
                                  .Replace(FieldPascalCaseTag, field.Name.VariateFirstChar())
                                  .Replace(FieldCamelCaseTag, field.Name)
                                  .Replace(FieldCamelCase_SetTag, field.Name == "value" ? "this." + field.Name : field.Name)
                                  .Replace(FieldTypeTag, field.Type)
                                  .Replace(FieldIdTag, field.Index.ToString()))
                          .Aggregate((x, y) => x + Format.NewLine(1) + y);
            }
            else
            {
                members = parsedComponent.Fields
                          .Select(field => $"public {field.Type} {field.Name.FirstCharToUpper()};")
                          .Aggregate((x, y) => x + Format.NewLine(1) + y);
            }

            var componentReactive = snippet
                                    .Replace(ComponentNameTag, parsedComponent.ComponentName)
                                    .Replace(subSnippet, members)
                                    .Replace(ComponentReactiveBlock, "");

            if (MayBakeUsings())
            {
                componentReactive = parsedComponent.Usings + componentReactive;
            }

            SaveGeneration(componentReactive,
                           new Tag(TagKeys.Component, parsedComponent.ComponentName),
                           new Tag(TagKeys.GenerationType, GenerationTypes.Reactive));
        }
Example #4
0
        static ParsedComponent CreateOrRetrieveComponentFromString(string stringVersionOfComponent,
                                                                   int sourceLineNumber,
                                                                   Dictionary <string, ParsedComponent> components)
        {
            string componentName;
            string typeName = null;

            if (Regex.IsMatch(stringVersionOfComponent, COMPONENT_WITH_TYPE_DECLARATION))
            {
                var match = Regex.Match(stringVersionOfComponent, COMPONENT_WITH_TYPE_DECLARATION);
                componentName = match.Groups[1].Value;
                typeName      = match.Groups[2].Value;

                var metadata = ImmutableDictionary <string, string> .Empty;
                for (var i = 3; i < match.Groups.Count; i++)
                {
                    var matchMeta = Regex.Match(match.Groups[i].Value, COMPONENT_METADATA);
                    metadata = metadata.Add(matchMeta.Groups[1].Value, matchMeta.Groups[2].Value);
                }

                if (components.ContainsKey(componentName))
                {
                    throw new ArgumentException(string.Format("Invalid input on line {0}, process '{1}' has already been declared", sourceLineNumber, componentName));
                }
                var component = new ParsedComponent(componentName, typeName, metadata);
                component.Setup();
                components[componentName] = component;
                return(component);
            }
            else
            {
                componentName = stringVersionOfComponent;

                if (!components.ContainsKey(componentName))
                {
                    throw new ArgumentException(string.Format("Invalid input on line {0}, the process '{1}' has not been declared", sourceLineNumber, componentName));
                }
                return(components[componentName]);
            }
        }
        void GenerateGroupBuilders(ParsedComponent parsedComponent)
        {
            var group_builder_snippet = File.ReadAllText(settings.CodeSnippets.Group_Builder);

            foreach (var context in parsedComponent.Contexts)
            {
                var group_builderFile = group_builder_snippet
                                        .Replace(ContextNameTag, context)
                                        .Replace(ComponentNameTag, parsedComponent.ComponentName);

                SaveGeneration(group_builderFile,
                               new Tag(TagKeys.Context, context),
                               new Tag(TagKeys.Component, parsedComponent.ComponentName),
                               new Tag(TagKeys.GenerationType, GenerationTypes.GroupBuilder));

                if (!parsedComponent.HasFields || !parsedComponent.IsReactive())
                {
                    continue;
                }

                var snippetPath = parsedComponent.Fields.Length > 1 ? settings.CodeSnippets.Collector : settings.CodeSnippets.CollectorFieldless;

                var collector_snippet = File.ReadAllText(snippetPath);

                var componentEnumValues = parsedComponent.Fields
                                          .Select(field => field.Name)
                                          .Aggregate((x, y) => x + "," + Format.NewLine(1) + y);

                var collector_File = collector_snippet
                                     .Replace(ComponentNameTag, parsedComponent.ComponentName)
                                     .Replace(ComponentEnumValuesTag, componentEnumValues)
                                     .Replace(ContextNameTag, context);

                SaveGeneration(collector_File,
                               new Tag(TagKeys.Context, context),
                               new Tag(TagKeys.Component, parsedComponent.ComponentName),
                               new Tag(TagKeys.GenerationType, GenerationTypes.Collector));
            }
        }
Example #6
0
        private static FbpParseResult Parse(string fbpProgram, Dictionary <string, object> initialData)
        {
            var components = new Dictionary <string, ParsedComponent>();
            var lines      = fbpProgram.Split('\n');

            if (initialData == null)
            {
                initialData = new Dictionary <string, object>();
            }

            for (var i = 0; i < lines.Length; ++i)
            {
                var line = lines[i].Trim();
                if (Regex.IsMatch(line, COMMENT))
                {
                    continue;
                }

                var separatorIndex = line.IndexOf("->");
                if (separatorIndex < 0)
                {
                    continue;
                }

                var senderText   = line.Substring(0, separatorIndex).Trim();
                var receiverText = line.Substring(separatorIndex + 2).Trim();

                ParsedComponent receiver     = null;
                string          receiverPort = null;

                if (Regex.IsMatch(receiverText, PORT_AND_COMPONENT))
                {
                    var match = Regex.Match(receiverText, PORT_AND_COMPONENT);
                    receiverPort = match.Groups[1].Value;
                    receiver     = CreateOrRetrieveComponentFromString(match.Groups[2].Value, i, components);
                }
                else if (Regex.IsMatch(receiverText, PORT_AND_COMPONENT_WITH_TYPE))
                {
                    var match = Regex.Match(receiverText, PORT_AND_COMPONENT_WITH_TYPE);
                    receiverPort = match.Groups[1].Value;
                    receiver     = CreateOrRetrieveComponentFromString(match.Groups[2].Value, i, components);
                }
                else
                {
                    throw new ArgumentException(string.Format("Invalid input on line {0}, receiver declaration is malformed: '{1}'", i, receiverText));
                }


                if (Regex.IsMatch(senderText, COMPONENT_AND_PORT))
                {
                    var match      = Regex.Match(senderText, COMPONENT_AND_PORT);
                    var sender     = CreateOrRetrieveComponentFromString(match.Groups[1].Value, i, components);
                    var senderPort = match.Groups[2].Value;
                    sender.ConnectTo(senderPort, receiver, receiverPort);
                }
                else if (Regex.IsMatch(senderText, COMPONENT_AND_PORT_WITH_TYPE))
                {
                    var match      = Regex.Match(senderText, COMPONENT_AND_PORT_WITH_TYPE);
                    var sender     = CreateOrRetrieveComponentFromString(match.Groups[1].Value, i, components);
                    var senderPort = match.Groups[2].Value;
                    sender.ConnectTo(senderPort, receiver, receiverPort);
                }
                else if (Regex.IsMatch(senderText, INITIAL_PASSED_IN_DATA))
                {
                    var match = Regex.Match(senderText, INITIAL_PASSED_IN_DATA);
                    var key   = match.Groups[1].Value;
                    if (initialData.ContainsKey(key))
                    {
                        receiver.SetInitialData(receiverPort, initialData[key]);
                    }
                    else
                    {
                        throw new ArgumentException(string.Format("Initial data {0} was not found in the provided Dictionary", key));
                    }
                }
                else if (Regex.IsMatch(senderText, INITIAL_BOOL_DATA))
                {
                    var match = Regex.Match(senderText, INITIAL_BOOL_DATA);
                    receiver.SetInitialData(receiverPort, bool.Parse(match.Value));
                }
                else if (Regex.IsMatch(senderText, INITIAL_STRING_DATA))
                {
                    var match = Regex.Match(senderText, INITIAL_STRING_DATA);

                    /*
                     * var metadata = ImmutableDictionary<string, string>.Empty.Add("value", match.Groups[2].Value);
                     * var component = new ParsedComponent("Value", "string", metadata);
                     * component.Setup();
                     * components[component.Name] = component;
                     * component.ConnectTo("Value", receiver, receiverPort);
                     */
                    receiver.SetInitialData(receiverPort, match.Groups[2].Value.Replace("\\'", "'"));
                }
                else if (Regex.IsMatch(senderText, INITIAL_FLOAT_DATA))
                {
                    var match = Regex.Match(senderText, INITIAL_FLOAT_DATA);
                    receiver.SetInitialData(receiverPort, float.Parse(match.Value));
                }
                else if (Regex.IsMatch(senderText, INITIAL_INT_DATA))
                {
                    var match = Regex.Match(senderText, INITIAL_INT_DATA);
                    receiver.SetInitialData(receiverPort, int.Parse(match.Value));
                }
                else
                {
                    throw new ArgumentException(string.Format("Invalid input on line {0}, sender declaration is malformed: '{1}'", i, senderText));
                }
            }

            return(new FbpParseResult(ImmutableList <ParsedComponent> .Empty.AddRange(components.Values)));
        }
        ParsedComponent ParseComponent(string component)
        {
            // remove all access modifiers
            component = component.ReplaceAll("", "private", "protected", "internal", "public");

            if (component.Contains("namespace"))
            {
                var startID = component.IndexOf("namespace");
                var fromNamespaceComponent = component.Substring(startID);
                var OpeningBracketID       = fromNamespaceComponent.IndexOf("{");
                var ClosingGracketID       = fromNamespaceComponent.FindMatchingBracket(OpeningBracketID);

                component = component.Substring(OpeningBracketID + startID + 1, ClosingGracketID - OpeningBracketID - 1);
            }

            var temp = component
                       .AslineArray()
                       .Where(x => x.Contains("class"))
                       .FirstOrDefault();
            var id    = temp.IndexOf("class");
            var temp2 = temp
                        .Substring(id);

            var name = temp2
                       .Split(' ')
                       [1];

            var attributesTextRaw = component
                                    .AslineArray()
                                    .Where(line => line.Contains("[") || line.Contains("]"));

            var attributesText = attributesTextRaw.Count() > 0 ?
                                 attributesTextRaw
                                 .Aggregate((a, b) => a + b)
                                 .RemoveWhitespace() : null;

            var attributes = attributesText != null?
                             attributesText.ReplaceAll("", "[", "]")
                             .Split(',')
                             .Select(x =>
            {
                if (x.Contains("."))
                {
                    var parts = x.Split('.');
                    return(parts[parts.Length - 1]);
                }
                return(x);
            })
                                 : new string[] { DefaultContext };

            var isUnique = false;

            if (attributes.Contains(UniqueAttibute))
            {
                attributes = attributes.Where(x => x != UniqueAttibute);
                isUnique   = true;
            }

            var usingsLines = component
                              .AslineArray()
                              .Where(x => x.Contains("using"));

            var usings = usingsLines.Count() > 0 ? usingsLines.Aggregate((a, b) => a + Format.NewLine() + b) : string.Empty;

            var hasFields = component
                            .Split(new string[] { "{", "}" }, StringSplitOptions.None)[1]
                            .RemoveWhitespace() != "";

            var fields = component
                         .Split(new string[] { "{", "}" }, StringSplitOptions.None)[1]
                         .Split(new string[] { ";" }, StringSplitOptions.None)
                         .ToList();

            var result = new ParsedComponent();

            result.ComponentName = name;
            result.Attributes    = attributes.ToArray();
            result.Contexts      = attributes.Where(a => state.Contexts.Contains(a)).ToArray();
            result.IsUnique      = isUnique;
            result.HasFields     = hasFields;
            result.Usings        = usings;

            if (fields.Any())
            {
                var r = fields
                        .Select(x => x.Split(' ').Where(y => !(y == string.Empty || y == null || y.Contains(" "))).Skip(1).ToList()).ToList();
                r             = r.Take(r.Count - 1).ToList();
                result.Fields = r.Select(fieldPair => new FieldParsed()
                {
                    Index = r.IndexOf(fieldPair), Type = fieldPair[0], Name = fieldPair[1]
                }).ToArray();
            }

            if (settings.ForseReactiveComponents)
            {
                result.ForseReactive = true;
            }
            return(result);
        }
        void GenerateComponentExtensions(ParsedComponent parsedComponent)
        {
            foreach (var context in parsedComponent.Contexts)
            {
                string result = MayBakeUsings() ? parsedComponent.Usings : string.Empty;

                // Header
                var snippetHeader   = File.ReadAllText(settings.CodeSnippets.ComponentHeader);
                var componentHeader = snippetHeader
                                      .Replace(ComponentNameTag, parsedComponent.ComponentName);

                result += Format.NewLine() + componentHeader;

                // Get Property
                var snippet_Get       = File.ReadAllText(settings.CodeSnippets.ComponentExtensions_Get_Property);
                var snippet_Fieldless = File.ReadAllText(settings.CodeSnippets.ComponentExtensions_Fieldless);

                var snippet = parsedComponent.HasFields ? snippet_Get : snippet_Fieldless;

                var get_extension =
                    snippet
                    .Replace(ComponentNameTag, parsedComponent.ComponentName)
                    .Replace(ContextNameTag, context);

                result += Format.NewLine() + get_extension;

                if (parsedComponent.HasFields)
                {
                    // Add Method
                    var snippet_Add = File.ReadAllText(settings.CodeSnippets.ComponentExtensions_Add_Method);

                    string add_extension = snippet_Add;

                    add_extension = HandleAddMethod(parsedComponent, add_extension);

                    var clearActionsSequence = parsedComponent.Fields
                                               .Select(x => string.Format("{0}.On{1}Change = null;", parsedComponent.ComponentName, x.Name.VariateFirstChar()))
                                               .Aggregate((x, y) => x + Format.NewLine(2) + y);

                    var NanoListFieldsInitialization = parsedComponent.Fields.ToList()
                                                       .Where(field => field.Type.Contains("NanoList"))
                                                       .Select(y =>
                                                               Format.NewLine() + "c." +
                                                               (parsedComponent.IsReactive() ? y.Name.VariateFirstChar() : y.Name.FirstCharToUpper())
                                                               + ".Initialize(c._InternalOnValueChange, " + y.Index + ");" +
                                                               Format.NewLine() + "if (c." + y.Name.VariateFirstChar() + ".Count > 0) { c._InternalOnValueChange(" + y.Index + "); }" +
                                                               Format.NewLine()).ToList();

                    add_extension = add_extension
                                    .Replace(ClearingActionsSequenceTag, parsedComponent.IsReactive() ? clearActionsSequence : "")
                                    .Replace(ComponentNameTag, parsedComponent.ComponentName)
                                    .Replace(ContextNameTag, context);

                    if (NanoListFieldsInitialization.Count > 0)
                    {
                        var marker = "return this;";
                        NanoListFieldsInitialization.ForEach(x => add_extension = add_extension.Insert(add_extension.IndexOf(marker), x));
                    }

                    result += Format.NewLine() + add_extension;
                }

                result = GenaratedHeader + result;

                var prefix = state.Contexts.Count > 1 ? context : string.Empty;

                SaveGeneration(result,
                               new Tag(TagKeys.Context, context),
                               new Tag(TagKeys.GenerationType, GenerationTypes.AddRemove));
            }
        }
 void ExtendComponentFieldTypes(ParsedComponent component)
 {
     component.Fields.ToList()
     .Where(field => field.Type.Contains("List")).ToList().ForEach(x => x.Type = string.Format("NanoList<{0}>", x.Type.Extract('<', '>')));
 }