예제 #1
0
        public void SetFields(ClassDeclarationSyntax classNode, AbstractionModel model)
        {
            try
            {
                var parser = new CodeParser()
                {
                    AccessLevel = "public"
                };

                var fields = parser
                             .FilterByAccessLevel(parser.GetFields(classNode), accessLevel: "public")
                             .Select(p => (p as FieldDeclarationSyntax).Declaration);

                foreach (var field in fields)
                {
                    var fieldName  = field.Variables.First().Identifier.ToString();
                    var fieldValue = field.Variables.First().Initializer?.Value.ToString() ?? "default";
                    var type       = field.Type.ToString();

                    model.AddField(fieldName, fieldValue, type);

                    if (field.HasLeadingTrivia)
                    {
                        var parsedDocumentation = GetDocumentation(field);
                        model.AddDocumentation(fieldName, parsedDocumentation);
                    }
                }
            }
            catch (Exception e)
            {
                Logging.Log($"Failed to set fields in AbstractionModelManager.\nError: {e}");
            }
        }
예제 #2
0
        private void SetPorts(ClassDeclarationSyntax classNode, AbstractionModel model, bool isInputPort = false)
        {
            try
            {
                if (isInputPort)
                {
                    var parser = new CodeParser();

                    var baseList     = (parser.GetBaseObjects(classNode));
                    var portNodeList = (baseList.First() as BaseListSyntax)?.Types.ToList();

                    if (portNodeList == null)
                    {
                        return;
                    }
                    var portSyntaxNodes = portNodeList.Where(n => MatchStartOfString(n.ToString(), ProgrammingParadigms));

                    var docLines         = model.SourceCode.Split(new [] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
                    var classDeclaration = docLines.First(line => line.Trim().Contains($"class {model.Type}"));

                    var implementedPortNames = new List <string>();
                    if (classDeclaration.Contains("//"))
                    {
                        // Get implemented port names
                        // string implementedPortsInlineComment = baseList.LastOrDefault()?.GetTrailingTrivia().ToString().Trim(new []{' ', '/', '\r', '\n'}) ?? "";
                        var implementedPortsInlineComment =
                            classDeclaration.Split(new[] { "//" }, StringSplitOptions.RemoveEmptyEntries).LastOrDefault();

                        if (!string.IsNullOrEmpty(implementedPortsInlineComment))
                        {
                            implementedPortNames = implementedPortsInlineComment.Split(new[] { ", " }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()).ToList();
                        }
                    }

                    var modelGenerics = model.GetGenerics();

                    var implementedPortCount = 0;
                    foreach (var portSyntaxNode in portSyntaxNodes)
                    {
                        var port = new Port()
                        {
                            Type = portSyntaxNode.Type.ToString()
                        };

                        if (implementedPortCount < implementedPortNames.Count)
                        {
                            port.Name = implementedPortNames[implementedPortCount];
                        }
                        else
                        {
                            port.Name = "?" + port.Type;
                        }

                        // Handle reverse ports (e.g. IDataFlowB and IEventB)
                        // var typeWithoutGenerics = TypeWithoutGenerics(port.Type);
                        // port.IsReversePort = typeWithoutGenerics.EndsWith("B");
                        port.IsReversePort = IsReversePort(port.Type);

                        if (port.IsReversePort)
                        {
                            port.IsInputPort = false;
                            model.AddAcceptedPort(port.Type, port.Name, true);
                        }
                        else
                        {
                            port.IsInputPort = true;
                            model.AddImplementedPort(port.Type, port.Name);
                        }

                        var indexList = new List <int>();

                        if (portSyntaxNode.Type is GenericNameSyntax gen)
                        {
                            var portGenerics = gen
                                               .DescendantNodesAndSelf().OfType <GenericNameSyntax>()
                                               .SelectMany(n => n.TypeArgumentList.Arguments.Select(a => a.ToString()))
                                               .ToHashSet();

                            foreach (var portGeneric in portGenerics)
                            {
                                var index = modelGenerics.IndexOf(portGeneric);
                                if (index != -1)
                                {
                                    indexList.Add(index);
                                }
                            }
                        }

                        model.AddPortGenericIndices(port.Name, indexList);
                        implementedPortCount++;
                    }
                }
                else
                {
                    var parser = new CodeParser()
                    {
                        AccessLevel = "private"
                    };

                    var privateFields   = parser.GetFields(classNode);
                    var portSyntaxNodes = privateFields.Where(n =>
                                                              n is FieldDeclarationSyntax field &&
                                                              (MatchStartOfString(field.Declaration.Type.ToString(), ProgrammingParadigms) ||
                                                               MatchStartOfString(field.Declaration.Type.ToString(), ProgrammingParadigms, prefix: "List<")))
                                          .Select(s => s as FieldDeclarationSyntax);


                    var modelGenerics = model.GetGenerics();
                    foreach (var portSyntaxNode in portSyntaxNodes)
                    {
                        var port = new Port()
                        {
                            Type = portSyntaxNode.Declaration.Type.ToString(),
                            Name = portSyntaxNode.Declaration.Variables.First().Identifier.ToString(),
                        };

                        port.Description = portSyntaxNode.HasLeadingTrivia ? ParsePortDocumentation(portSyntaxNode.GetLeadingTrivia().ToString()) : "";

                        // Handle reverse ports (e.g. IDataFlowB and IEventB)
                        // var typeWithoutGenerics = TypeWithoutGenerics(port.Type);
                        // port.IsReversePort = typeWithoutGenerics.EndsWith("B");
                        port.IsReversePort = IsReversePort(port.Type);

                        if (port.IsReversePort)
                        {
                            port.IsInputPort = true;
                            model.AddImplementedPort(port.Type, port.Name, isReversePort: true, description: port.Description);
                        }
                        else
                        {
                            port.IsInputPort = false;
                            model.AddAcceptedPort(port.Type, port.Name, description: port.Description);
                        }

                        var indexList = new List <int>();

                        if (portSyntaxNode.Declaration.Type is GenericNameSyntax gen)
                        {
                            var portGenerics = gen
                                               .DescendantNodesAndSelf().OfType <GenericNameSyntax>()
                                               .SelectMany(n => n.TypeArgumentList.Arguments.Select(a => a.ToString()).Where(a => modelGenerics.Contains(a)))
                                               .ToHashSet();

                            foreach (var portGeneric in portGenerics)
                            {
                                var index = modelGenerics.IndexOf(portGeneric);
                                if (index != -1)
                                {
                                    indexList.Add(index);
                                }
                            }
                        }

                        model.AddPortGenericIndices(port.Name, indexList);
                    }
                }
            }
            catch (Exception e)
            {
                Logging.Log($"Failed to set {(isInputPort ? "implemented" : "accepted")} ports in AbstractionModelManager.\nError: {e}");
            }
        }