public ClassDiagramGenerator(TextWriter writer, string indent, Accessibilities ignoreMemberAccessibilities = Accessibilities.None, bool createAssociation = true)
 {
     this.writer = writer;
     this.indent = indent;
     _ignoreMemberAccessibilities = ignoreMemberAccessibilities;
     _createAssociation           = createAssociation;
 }
 public ClassDiagramGenerator(TextWriter writer, string indent, Accessibilities ignoreMemberAccessibilities = Accessibilities.None)
 {
     this.writer = writer;
     this.indent = indent;
     _innerTypeDeclarationNodes = new List<SyntaxNode>();
     _ignoreMemberAccessibilities = ignoreMemberAccessibilities;
 }
 public ClassDiagramGenerator(TextWriter writer, string indent, Accessibilities ignoreMemberAccessibilities = Accessibilities.None)
 {
     this.writer = writer;
     this.indent = indent;
     _innerTypeDeclarationNodes   = new List <SyntaxNode>();
     _ignoreMemberAccessibilities = ignoreMemberAccessibilities;
 }
 public ClassDiagramGenerator(TextWriter writer, string indent, Accessibilities ignoreMemberAccessibilities = Accessibilities.None, bool createAssociation = true)
 {
     this.writer = writer;
     this.indent = indent;
     _additionalTypeDeclarationNodes = new List <SyntaxNode>();
     _ignoreMemberAccessibilities    = ignoreMemberAccessibilities;
     _createAssociation = createAssociation;
 }
Exemple #5
0
        internal SymbolSpecificationDialog(SymbolSpecificationViewModel viewModel)
        {
            _viewModel = viewModel;
            InitializeComponent();
            DataContext = viewModel;

            SymbolKinds.AddHandler(UIElement.PreviewKeyDownEvent, (KeyEventHandler)HandleSymbolKindsPreviewKeyDown, true);
            Accessibilities.AddHandler(UIElement.PreviewKeyDownEvent, (KeyEventHandler)HandleAccessibilitiesPreviewKeyDown, true);
            Modifiers.AddHandler(UIElement.PreviewKeyDownEvent, (KeyEventHandler)HandleModifiersPreviewKeyDown, true);
        }
        private static bool GeneratePlantUmlFromFile(Dictionary <string, string> parameters)
        {
            var inputFileName = parameters["in"];

            if (!File.Exists(inputFileName))
            {
                Console.WriteLine($"\"{inputFileName}\" does not exist.");
                return(false);
            }
            var outputFileName = "";

            if (parameters.ContainsKey("out"))
            {
                outputFileName = parameters["out"];
                try
                {
                    var outdir = Path.GetDirectoryName(outputFileName);
                    Directory.CreateDirectory(outdir);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    return(false);
                }
            }
            else
            {
                outputFileName = CombinePath(Path.GetDirectoryName(inputFileName),
                                             Path.GetFileNameWithoutExtension(inputFileName) + ".puml");
            }

            try
            {
                using (var stream = new FileStream(inputFileName, FileMode.Open, FileAccess.Read))
                {
                    var             tree      = CSharpSyntaxTree.ParseText(SourceText.From(stream));
                    var             root      = tree.GetRoot();
                    Accessibilities ignoreAcc = GetIgnoreAccessibilities(parameters);

                    using (var filestream = new FileStream(outputFileName, FileMode.Create, FileAccess.Write))
                        using (var writer = new StreamWriter(filestream))
                        {
                            var gen = new ClassDiagramGenerator(writer, "    ", ignoreAcc);
                            gen.Generate(root);
                        }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return(false);
            }
            return(true);
        }
        public void VisitConstructorInfoElementProducesCorrectValue(
            Func<MethodBase, bool> predicate, Accessibilities expected)
        {
            var sut = new AccessibilityCollector();
            BindingFlags bindingFlags =
                BindingFlags.Public | BindingFlags.NonPublic |
                BindingFlags.Instance | BindingFlags.Static;
            var constructorInfoElement = typeof(object).Assembly
                .GetTypes().SelectMany(t => t.GetConstructors(bindingFlags))
                .Where(predicate).Cast<ConstructorInfo>().First().ToElement();

            var actual = sut.Visit(constructorInfoElement);

            Assert.Empty(sut.Value);
            Assert.Equal(expected, actual.Value.Single());
        }
        private static bool GeneratePlantUmlFromDir(Dictionary <string, string> parameters)
        {
            var inputRoot = parameters["in"];

            if (!Directory.Exists(inputRoot))
            {
                Console.WriteLine($"Directory \"{inputRoot}\" does not exist.");
                return(false);
            }
            var outputRoot = inputRoot;

            if (parameters.ContainsKey("out"))
            {
                outputRoot = parameters["out"];
                try
                {
                    Directory.CreateDirectory(outputRoot);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    return(false);
                }
            }

            var excludePaths = new List <string>();
            var pumlexclude  = CombinePath(inputRoot, ".pumlexclude");

            if (File.Exists(pumlexclude))
            {
                excludePaths = File.ReadAllLines(pumlexclude).ToList();
            }
            if (parameters.ContainsKey("-excludePaths"))
            {
                excludePaths.AddRange(parameters["-excludePaths"].Split(','));
            }

            var files       = Directory.EnumerateFiles(inputRoot, "*.cs", SearchOption.AllDirectories);
            var includeRefs = new StringBuilder();

            includeRefs.AppendLine("@startuml");
            var error = false;

            foreach (var inputFile in files)
            {
                if (excludePaths
                    .Select(p => CombinePath(inputRoot, p))
                    .Any(p => inputFile.StartsWith(p, StringComparison.InvariantCultureIgnoreCase)))
                {
                    Console.WriteLine($"Skipped \"{inputFile}\"...");
                    continue;
                }
                Console.WriteLine($"Processing \"{inputFile}\"...");
                try
                {
                    var outputDir = CombinePath(outputRoot, Path.GetDirectoryName(inputFile).Replace(inputRoot, ""));
                    Directory.CreateDirectory(outputDir);
                    var outputFile = CombinePath(outputDir,
                                                 Path.GetFileNameWithoutExtension(inputFile) + ".puml");

                    using (var stream = new FileStream(inputFile, FileMode.Open, FileAccess.Read))
                    {
                        var             tree      = CSharpSyntaxTree.ParseText(SourceText.From(stream));
                        var             root      = tree.GetRoot();
                        Accessibilities ignoreAcc = GetIgnoreAccessibilities(parameters);

                        using (var filestream = new FileStream(outputFile, FileMode.Create, FileAccess.Write))
                            using (var writer = new StreamWriter(filestream))
                            {
                                var gen = new ClassDiagramGenerator(writer, "    ", ignoreAcc);
                                gen.Generate(root);
                            }
                    }

                    includeRefs.AppendLine("!include " + outputFile.Replace(outputRoot, @".\"));
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    error = true;
                }
            }
            includeRefs.AppendLine("@enduml");
            File.WriteAllText(CombinePath(outputRoot, "include.puml"), includeRefs.ToString());
            if (error)
            {
                Console.WriteLine("There were files that could not be processed.");
                return(false);
            }
            return(true);
        }
Exemple #9
0
        public static void ComputeRefactoring(RefactoringContext context, MemberDeclarationListSelection selectedMembers)
        {
            if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeAccessibility) &&
                !selectedMembers.Parent.IsKind(SyntaxKind.InterfaceDeclaration))
            {
                Accessibilities validAccessibilities = ChangeAccessibilityAnalysis.GetValidAccessibilities(selectedMembers, allowOverride: true);

                if (validAccessibilities != Accessibilities.None)
                {
                    bool canHaveMultipleDeclarations = CanHaveMultipleDeclarations();

                    TryRegisterRefactoring(validAccessibilities, Accessibility.Public, canHaveMultipleDeclarations);
                    TryRegisterRefactoring(validAccessibilities, Accessibility.Internal, canHaveMultipleDeclarations);
                    TryRegisterRefactoring(validAccessibilities, Accessibility.Protected, canHaveMultipleDeclarations);
                    TryRegisterRefactoring(validAccessibilities, Accessibility.Private, canHaveMultipleDeclarations);
                }
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.InitializeFieldFromConstructor) &&
                !selectedMembers.Parent.IsKind(SyntaxKind.InterfaceDeclaration))
            {
                InitializeFieldFromConstructorRefactoring.ComputeRefactoring(context, selectedMembers);
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.AddEmptyLineBetweenDeclarations))
            {
                AddEmptyLineBetweenDeclarationsRefactoring.ComputeRefactoring(context, selectedMembers);
            }

            void TryRegisterRefactoring(Accessibilities accessibilities, Accessibility accessibility, bool canHaveMultipleDeclarations)
            {
                if ((accessibilities & accessibility.GetAccessibilities()) != 0)
                {
                    if (canHaveMultipleDeclarations)
                    {
                        context.RegisterRefactoring(
                            ChangeAccessibilityRefactoring.GetTitle(accessibility),
                            async cancellationToken =>
                        {
                            SemanticModel semanticModel = await context.Document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
                            return(await ChangeAccessibilityRefactoring.RefactorAsync(context.Document.Solution(), selectedMembers, accessibility, semanticModel, cancellationToken).ConfigureAwait(false));
                        },
                            EquivalenceKey.Join(RefactoringIdentifiers.ChangeAccessibility, accessibility.ToString()));
                    }
                    else
                    {
                        context.RegisterRefactoring(
                            ChangeAccessibilityRefactoring.GetTitle(accessibility),
                            cancellationToken => ChangeAccessibilityRefactoring.RefactorAsync(context.Document, selectedMembers, accessibility, cancellationToken),
                            EquivalenceKey.Join(RefactoringIdentifiers.ChangeAccessibility, accessibility.ToString()));
                    }
                }
            }

            bool CanHaveMultipleDeclarations()
            {
                foreach (MemberDeclarationSyntax member in selectedMembers)
                {
                    switch (member.Kind())
                    {
                    case SyntaxKind.ClassDeclaration:
                    {
                        if (((ClassDeclarationSyntax)member).Modifiers.Contains(SyntaxKind.PartialKeyword))
                        {
                            return(true);
                        }

                        break;
                    }

                    case SyntaxKind.InterfaceDeclaration:
                    {
                        if (((InterfaceDeclarationSyntax)member).Modifiers.Contains(SyntaxKind.PartialKeyword))
                        {
                            return(true);
                        }

                        break;
                    }

                    case SyntaxKind.StructDeclaration:
                    {
                        if (((StructDeclarationSyntax)member).Modifiers.Contains(SyntaxKind.PartialKeyword))
                        {
                            return(true);
                        }

                        break;
                    }

                    case SyntaxKind.MethodDeclaration:
                    {
                        if (((MethodDeclarationSyntax)member).Modifiers.ContainsAny(SyntaxKind.PartialKeyword, SyntaxKind.AbstractKeyword, SyntaxKind.VirtualKeyword, SyntaxKind.OverrideKeyword))
                        {
                            return(true);
                        }

                        break;
                    }

                    case SyntaxKind.PropertyDeclaration:
                    {
                        if (((PropertyDeclarationSyntax)member).Modifiers.ContainsAny(SyntaxKind.AbstractKeyword, SyntaxKind.VirtualKeyword, SyntaxKind.OverrideKeyword))
                        {
                            return(true);
                        }

                        break;
                    }

                    case SyntaxKind.IndexerDeclaration:
                    {
                        if (((IndexerDeclarationSyntax)member).Modifiers.ContainsAny(SyntaxKind.AbstractKeyword, SyntaxKind.VirtualKeyword, SyntaxKind.OverrideKeyword))
                        {
                            return(true);
                        }

                        break;
                    }

                    case SyntaxKind.EventDeclaration:
                    {
                        if (((EventDeclarationSyntax)member).Modifiers.ContainsAny(SyntaxKind.AbstractKeyword, SyntaxKind.VirtualKeyword, SyntaxKind.OverrideKeyword))
                        {
                            return(true);
                        }

                        break;
                    }

                    case SyntaxKind.EventFieldDeclaration:
                    {
                        if (((EventFieldDeclarationSyntax)member).Modifiers.ContainsAny(SyntaxKind.AbstractKeyword, SyntaxKind.VirtualKeyword, SyntaxKind.OverrideKeyword))
                        {
                            return(true);
                        }

                        break;
                    }
                    }
                }

                return(false);
            }
        }
Exemple #10
0
        public static Accessibilities GetValidAccessibilities(MemberDeclarationListSelection selectedMembers, bool allowOverride = false)
        {
            if (selectedMembers.Count < 2)
            {
                return(Accessibilities.None);
            }

            var all = Accessibilities.None;

            Accessibilities valid = Accessibilities.Public
                                    | Accessibilities.Internal
                                    | Accessibilities.Protected
                                    | Accessibilities.Private;

            foreach (MemberDeclarationSyntax member in selectedMembers)
            {
                Accessibility accessibility = SyntaxAccessibility.GetExplicitAccessibility(member);

                if (accessibility == Accessibility.NotApplicable)
                {
                    accessibility = SyntaxAccessibility.GetDefaultExplicitAccessibility(member);

                    if (accessibility == Accessibility.NotApplicable)
                    {
                        return(Accessibilities.None);
                    }
                }

                Accessibilities accessibilities = accessibility.GetAccessibilities();

                switch (accessibility)
                {
                case Accessibility.Private:
                case Accessibility.Protected:
                case Accessibility.ProtectedAndInternal:
                case Accessibility.ProtectedOrInternal:
                case Accessibility.Internal:
                case Accessibility.Public:
                {
                    all |= accessibilities;
                    break;
                }

                default:
                {
                    Debug.Fail(accessibility.ToString());
                    return(Accessibilities.None);
                }
                }

                foreach (Accessibility accessibility2 in AvailableAccessibilities)
                {
                    if (accessibility != accessibility2 &&
                        !SyntaxAccessibility.IsValidAccessibility(member, accessibility2, ignoreOverride: allowOverride))
                    {
                        valid &= ~accessibility2.GetAccessibilities();
                    }
                }
            }

            switch (all)
            {
            case Accessibilities.Private:
            case Accessibilities.Protected:
            case Accessibilities.Internal:
            case Accessibilities.Public:
            {
                valid &= ~all;
                break;
            }
            }

            return(valid);
        }
Exemple #11
0
        public static Accessibilities GetValidAccessibilities(
            MemberDeclarationListSelection selectedMembers,
            SemanticModel semanticModel,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (selectedMembers.Count < 2)
            {
                return(Accessibilities.None);
            }

            ImmutableArray <Accessibility> avaiableAccessibilities = AvailableAccessibilities;

            var all = Accessibilities.None;

            Accessibilities valid = Accessibilities.Public
                                    | Accessibilities.Internal
                                    | Accessibilities.Protected
                                    | Accessibilities.Private;

            foreach (MemberDeclarationSyntax member in selectedMembers)
            {
                Accessibility accessibility = SyntaxAccessibility.GetExplicitAccessibility(member);

                if (accessibility == Accessibility.NotApplicable)
                {
                    accessibility = SyntaxAccessibility.GetDefaultExplicitAccessibility(member);

                    if (accessibility == Accessibility.NotApplicable)
                    {
                        return(Accessibilities.None);
                    }
                }

                switch (accessibility)
                {
                case Accessibility.Private:
                case Accessibility.Protected:
                case Accessibility.ProtectedAndInternal:
                case Accessibility.ProtectedOrInternal:
                case Accessibility.Internal:
                case Accessibility.Public:
                {
                    all |= accessibility.GetAccessibilities();
                    break;
                }

                default:
                {
                    Debug.Fail(accessibility.ToString());
                    return(Accessibilities.None);
                }
                }

                ModifierListInfo modifiersInfo = SyntaxInfo.ModifierListInfo(member);

                if (modifiersInfo.Modifiers.ContainsAny(
                        SyntaxKind.AbstractKeyword,
                        SyntaxKind.VirtualKeyword,
                        SyntaxKind.OverrideKeyword))
                {
                    valid &= ~Accessibilities.Private;
                }

                if (modifiersInfo.IsOverride &&
                    IsBaseDeclarationWithoutSource(member, semanticModel, cancellationToken))
                {
                    switch (accessibility)
                    {
                    case Accessibility.Private:
                    case Accessibility.Protected:
                    case Accessibility.Internal:
                    case Accessibility.Public:
                    {
                        valid &= accessibility.GetAccessibilities();

                        if (valid == Accessibilities.None)
                        {
                            return(Accessibilities.None);
                        }

                        avaiableAccessibilities = _accessibilityArrayMap[accessibility];
                        continue;
                    }

                    default:
                    {
                        return(Accessibilities.None);
                    }
                    }
                }

                foreach (Accessibility accessibility2 in avaiableAccessibilities)
                {
                    if (accessibility != accessibility2 &&
                        !SyntaxAccessibility.IsValidAccessibility(member, accessibility2, ignoreOverride: true))
                    {
                        valid &= ~accessibility2.GetAccessibilities();

                        if (valid == Accessibilities.None)
                        {
                            return(Accessibilities.None);
                        }
                    }
                }
            }

            switch (all)
            {
            case Accessibilities.Private:
            case Accessibilities.Protected:
            case Accessibilities.Internal:
            case Accessibilities.Public:
            {
                valid &= ~all;
                break;
            }
            }

            return(valid);
        }
        private bool GeneratePlantUmlFromDir(Dictionary <string, string> parameters)
        {
            var inputRoot = parameters["in"];

            if (!Directory.Exists(inputRoot))
            {
                OnError(new Exception($"Directory \"{inputRoot}\" does not exist."));
                return(false);
            }

            // Use GetFullPath to fully support relative paths.
            var outputRoot = Path.GetFullPath(inputRoot);

            if (parameters.ContainsKey("out"))
            {
                outputRoot = parameters["out"];
                try
                {
                    Directory.CreateDirectory(outputRoot);
                }
                catch (Exception e)
                {
                    OnError(e);
                    return(false);
                }
            }

            var excludePaths = new List <string>();
            var pumlexclude  = CombinePath(inputRoot, ".pumlexclude");

            if (File.Exists(pumlexclude))
            {
                excludePaths = File.ReadAllLines(pumlexclude).ToList();
            }
            if (parameters.ContainsKey("-excludePaths"))
            {
                excludePaths.AddRange(parameters["-excludePaths"].Split(','));
            }

            var files = Directory.EnumerateFiles(inputRoot, "*.cs", SearchOption.AllDirectories);

            var includeRefs = new StringBuilder();

            includeRefs.AppendLine("@startuml");

            var error = false;

            foreach (var inputFile in files)
            {
                if (excludePaths
                    .Select(p => CombinePath(inputRoot, p))
                    .Any(p => inputFile.StartsWith(p, StringComparison.InvariantCultureIgnoreCase)))
                {
                    OnProgress($"Skipped \"{inputFile}\"...");
                    continue;
                }

                OnProgress($"Create puml: \"{inputFile}\"...");
                try
                {
                    var outputDir = CombinePath(outputRoot, Path.GetDirectoryName(inputFile).Replace(inputRoot, ""));
                    Directory.CreateDirectory(outputDir);
                    var outputFile = CombinePath(outputDir,
                                                 Path.GetFileNameWithoutExtension(inputFile) + ".puml");

                    using (var stream = new FileStream(inputFile, FileMode.Open, FileAccess.Read))
                    {
                        var             tree      = CSharpSyntaxTree.ParseText(SourceText.From(stream));
                        var             root      = tree.GetRoot();
                        Accessibilities ignoreAcc = GetIgnoreAccessibilities(parameters);

                        using (var filestream = new FileStream(outputFile, FileMode.Create, FileAccess.Write))
                            using (var writer = new StreamWriter(filestream))
                            {
                                var gen = new PlantUmlClassDiagramGenerator.Library.ClassDiagramGenerator(writer, "    ", ignoreAcc, parameters.ContainsKey("-createAssociation"));
                                gen.Generate(root);
                            }
                    }

                    if (parameters.ContainsKey("-allInOne"))
                    {
                        var lines = File.ReadAllLines(outputFile);
                        foreach (string line in lines.Skip(1).SkipLast(1))
                        {
                            includeRefs.AppendLine(line);
                        }
                    }
                    else
                    {
                        var newRoot = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @".\" : @".";
                        includeRefs.AppendLine("!include " + outputFile.Replace(outputRoot, newRoot));
                    }
                }
                catch (Exception e)
                {
                    Exception ex = new Exception($"Error {inputFile}, {e.Message}", e);
                    OnError(ex);
                    error = true;
                }
            }
            includeRefs.AppendLine("@enduml");
            File.WriteAllText(CombinePath(outputRoot, "include.puml"), includeRefs.ToString());

            if (error)
            {
                OnError(new Exception("There were files that could not be processed."));
                return(false);
            }
            return(true);
        }
        public void VisitEventInfoElementProducesCorrectValue(
            Func<EventInfo, bool> predicate, Accessibilities expected)
        {
            var sut = new AccessibilityCollector();
            BindingFlags bindingFlags =
                BindingFlags.Public | BindingFlags.NonPublic |
                BindingFlags.Instance | BindingFlags.Static;
            var eventInfoElement = typeof(object).Assembly
                .GetTypes().Concat(new[] { typeof(ClassWithMembers) })
                .SelectMany(t => t.GetEvents(bindingFlags))
                .Where(predicate).First().ToElement();

            var actual = sut.Visit(eventInfoElement);

            Assert.Empty(sut.Value);
            Assert.Equal(expected, actual.Value.Single());
        }
        public void VisitTypeElementProducesCorrectValue(
            Func<Type, bool> predicate, Accessibilities expected)
        {
            var sut = new AccessibilityCollector();
            var typeElement = typeof(object).Assembly
                .GetTypes().Where(predicate).First().ToElement();

            var actual = sut.Visit(typeElement);

            Assert.Empty(sut.Value);
            Assert.Equal(expected, actual.Value.Single());
        }