当前位置: 首页>>代码示例>>C#>>正文


C# Document.GetSemanticModelAsync方法代码示例

本文整理汇总了C#中Document.GetSemanticModelAsync方法的典型用法代码示例。如果您正苦于以下问题:C# Document.GetSemanticModelAsync方法的具体用法?C# Document.GetSemanticModelAsync怎么用?C# Document.GetSemanticModelAsync使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在Document的用法示例。


在下文中一共展示了Document.GetSemanticModelAsync方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。

示例1: VerifyFix

        private void VerifyFix(Document document, DiagnosticAnalyzer analyzer, CodeFixProvider codeFixProvider, string newSource, int? codeFixIndex, bool useCompilerAnalyzerDriver, bool allowNewCompilerDiagnostics)
        {
            Diagnostic[] analyzerDiagnostics = GetSortedDiagnostics(analyzer, document, useCompilerAnalyzerDriver: useCompilerAnalyzerDriver);
            System.Collections.Immutable.ImmutableArray<Diagnostic> compilerDiagnostics = document.GetSemanticModelAsync().Result.GetDiagnostics();

            // TODO(mavasani): Delete the below if statement once FxCop Analyzers have been ported to new IDiagnosticAnalyzer API.
            if (!useCompilerAnalyzerDriver)
            {
                Assert.True(analyzerDiagnostics.IsEmpty());
                return;
            }

            int attempts = analyzerDiagnostics.Length;

            for (int i = 0; i < attempts; ++i)
            {
                var actions = new List<CodeAction>();
                var context = new CodeFixContext(document, analyzerDiagnostics[0], (a, d) => actions.Add(a), CancellationToken.None);
                codeFixProvider.RegisterCodeFixesAsync(context).Wait();
                if (!actions.Any())
                {
                    break;
                }

                if (codeFixIndex != null)
                {
                    document = document.Apply(actions.ElementAt((int)codeFixIndex));
                    break;
                }

                document = document.Apply(actions.ElementAt(0));

                analyzerDiagnostics = GetSortedDiagnostics(analyzer, document, useCompilerAnalyzerDriver: useCompilerAnalyzerDriver);
                IEnumerable<Diagnostic> newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, document.GetSemanticModelAsync().Result.GetDiagnostics());
                if (!allowNewCompilerDiagnostics && newCompilerDiagnostics.Any())
                {
                    // Format and get the compiler diagnostics again so that the locations make sense in the output
                    document = document.WithSyntaxRoot(Formatter.Format(document.GetSyntaxRootAsync().Result, Formatter.Annotation, document.Project.Solution.Workspace));
                    newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, document.GetSemanticModelAsync().Result.GetDiagnostics());

                    Assert.True(false,
                        string.Format("Fix introduced new compiler diagnostics:\r\n{0}\r\n\r\nNew document:\r\n{1}\r\n",
                            newCompilerDiagnostics.Select(d => d.ToString()).Join("\r\n"),
                            document.GetSyntaxRootAsync().Result.ToFullString()));
                }

                if (analyzerDiagnostics.IsEmpty())
                {
                    break;
                }
            }

            Document newDocument = Simplifier.ReduceAsync(document, Simplifier.Annotation).Result;
            SyntaxNode root = newDocument.GetSyntaxRootAsync().Result;
            root = Formatter.Format(root, Formatter.Annotation, newDocument.Project.Solution.Workspace);
            string actual = root.GetText().ToString();
            Assert.Equal(newSource, actual);
        }
开发者ID:Anniepoh,项目名称:roslyn-analyzers,代码行数:58,代码来源:CodeFixTestBase.cs

示例2: ProcessDocumentQueueAsync

        private async Task ProcessDocumentQueueAsync(
            Document document,
            DocumentMap.ValueSet documentQueue)
        {
            await _progress.OnFindInDocumentStartedAsync(document).ConfigureAwait(false);

            SemanticModel model = null;
            try
            {
                model = await document.GetSemanticModelAsync(_cancellationToken).ConfigureAwait(false);

                // start cache for this semantic model
                FindReferenceCache.Start(model);

                foreach (var symbolAndFinder in documentQueue)
                {
                    var symbol = symbolAndFinder.symbolAndProjectId;
                    var finder = symbolAndFinder.finder;

                    await ProcessDocumentAsync(document, symbol, finder).ConfigureAwait(false);
                }
            }
            finally
            {
                FindReferenceCache.Stop(model);

                await _progress.OnFindInDocumentCompletedAsync(document).ConfigureAwait(false);
            }
        }
开发者ID:TyOverby,项目名称:roslyn,代码行数:29,代码来源:FindReferencesSearchEngine_DocumentProcessing.cs

示例3: AddSourceToAsync

        public async Task<Document> AddSourceToAsync(Document document, ISymbol symbol, CancellationToken cancellationToken)
        {
            if (document == null)
            {
                throw new ArgumentNullException(nameof(document));
            }

            var newSemanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            var rootNamespace = newSemanticModel.GetEnclosingNamespace(0, cancellationToken);

            // Add the interface of the symbol to the top of the root namespace
            document = await CodeGenerator.AddNamespaceOrTypeDeclarationAsync(
                document.Project.Solution,
                rootNamespace,
                CreateCodeGenerationSymbol(document, symbol),
                CreateCodeGenerationOptions(newSemanticModel.SyntaxTree.GetLocation(new TextSpan()), symbol),
                cancellationToken).ConfigureAwait(false);

            var docCommentFormattingService = document.GetLanguageService<IDocumentationCommentFormattingService>();
            var docWithDocComments = await ConvertDocCommentsToRegularComments(document, docCommentFormattingService, cancellationToken).ConfigureAwait(false);

            var docWithAssemblyInfo = await AddAssemblyInfoRegionAsync(docWithDocComments, symbol.GetOriginalUnreducedDefinition(), cancellationToken).ConfigureAwait(false);
            var node = await docWithAssemblyInfo.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
            var formattedDoc = await Formatter.FormatAsync(
                docWithAssemblyInfo, SpecializedCollections.SingletonEnumerable(node.FullSpan), options: null, rules: GetFormattingRules(docWithAssemblyInfo), cancellationToken: cancellationToken).ConfigureAwait(false);

            var reducers = this.GetReducers();
            return await Simplifier.ReduceAsync(formattedDoc, reducers, null, cancellationToken).ConfigureAwait(false);
        }
开发者ID:XieShuquan,项目名称:roslyn,代码行数:29,代码来源:AbstractMetadataAsSourceService.cs

示例4: GetDiagnosticsAsync

        protected override async Task<IEnumerable<Diagnostic>> GetDiagnosticsAsync(Document document, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (!document.IsOpen())
            {
                return null;
            }

            if (document.SourceCodeKind == SourceCodeKind.Interactive)
            {
                // It's common to type usings in a submission that are intended for a future
                // submission.  We do not want to offer to remove these.
                return null;
            }

            var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var service = document.GetLanguageService<IRemoveUnnecessaryImportsService>();
            var unnecessaryUsings = service.GetUnnecessaryImports(document, model, model.SyntaxTree.GetRoot(cancellationToken), cancellationToken);
            if (unnecessaryUsings == null)
            {
                return null;
            }

            var contiguousSpans = unnecessaryUsings.GetContiguousSpans();
            return CreateClassificationDiagnostics(contiguousSpans, model, document, cancellationToken).Concat(
                   CreateFixableDiagnostics(unnecessaryUsings, model, document, cancellationToken));
        }
开发者ID:Rickinio,项目名称:roslyn,代码行数:27,代码来源:RemoveUnnecessaryUsingsDiagnosticProvider.cs

示例5: HandleDeclarationAsync

        private async Task<Document> HandleDeclarationAsync(Document document, SyntaxNode root, SyntaxNode node, CancellationToken cancellationToken)
        {
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            var declarationContext = node.Parent;

            TypeSyntax typeSyntax = null;
            if (declarationContext is VariableDeclarationSyntax)
            {
                typeSyntax = ((VariableDeclarationSyntax)declarationContext).Type;
            }
            else if (declarationContext is ForEachStatementSyntax)
            {
                typeSyntax = ((ForEachStatementSyntax)declarationContext).Type;
            }
            else
            {
                Contract.Fail($"unhandled kind {declarationContext.Kind().ToString()}");
            }

            var typeSymbol = semanticModel.GetTypeInfo(typeSyntax).ConvertedType;

            var typeName = typeSymbol.GenerateTypeSyntax()
                                     .WithLeadingTrivia(node.GetLeadingTrivia())
                                     .WithTrailingTrivia(node.GetTrailingTrivia());

            Debug.Assert(!typeName.ContainsDiagnostics, "Explicit type replacement likely introduced an error in code");

            var newRoot = root.ReplaceNode(node, typeName);
            return document.WithSyntaxRoot(newRoot);
        }
开发者ID:CAPCHIK,项目名称:roslyn,代码行数:30,代码来源:UseExplicitTypeCodeFixProvider.cs

示例6: AddImportsAsync

        public async Task<Document> AddImportsAsync(Document document, IEnumerable<TextSpan> spans, OptionSet options, CancellationToken cancellationToken)
        {
            options = options ?? document.Project.Solution.Workspace.Options;

            var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);

            // Create a simple interval tree for simplification spans.
            var spansTree = new SimpleIntervalTree<TextSpan>(TextSpanIntervalIntrospector.Instance, spans);

            Func<SyntaxNodeOrToken, bool> isInSpan = (nodeOrToken) =>
                spansTree.GetOverlappingIntervals(nodeOrToken.FullSpan.Start, nodeOrToken.FullSpan.Length).Any();

            var nodesWithExplicitNamespaces = root.DescendantNodesAndSelf().Where(n => isInSpan(n) && GetExplicitNamespaceSymbol(n, model) != null).ToList();

            var namespacesToAdd = new HashSet<INamespaceSymbol>();
            namespacesToAdd.AddRange(nodesWithExplicitNamespaces.Select(n => GetExplicitNamespaceSymbol(n, model)));

            // annotate these nodes so they get simplified later
            var newRoot = root.ReplaceNodes(nodesWithExplicitNamespaces, (o, r) => r.WithAdditionalAnnotations(Simplifier.Annotation));
            var newDoc = document.WithSyntaxRoot(newRoot);
            var newModel = await newDoc.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            newRoot = await this.AddNamespaceImportsAsync(newDoc, newModel, options, namespacesToAdd, cancellationToken).ConfigureAwait(false);
            return document.WithSyntaxRoot(newRoot);
        }
开发者ID:SoumikMukherjeeDOTNET,项目名称:roslyn,代码行数:26,代码来源:ImportAdderService.cs

示例7: AnalyzeTypeAtPositionAsync

        public async Task<ExtractInterfaceTypeAnalysisResult> AnalyzeTypeAtPositionAsync(
            Document document,
            int position,
            TypeDiscoveryRule typeDiscoveryRule,
            CancellationToken cancellationToken)
        {
            var typeNode = GetTypeDeclaration(document, position, typeDiscoveryRule, cancellationToken);
            if (typeNode == null)
            {
                var errorMessage = FeaturesResources.CouldNotExtractInterfaceSelection;
                return new ExtractInterfaceTypeAnalysisResult(errorMessage);
            }

            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            var type = semanticModel.GetDeclaredSymbol(typeNode, cancellationToken);
            if (type == null || type.Kind != SymbolKind.NamedType)
            {
                var errorMessage = FeaturesResources.CouldNotExtractInterfaceSelection;
                return new ExtractInterfaceTypeAnalysisResult(errorMessage);
            }

            var typeToExtractFrom = type as INamedTypeSymbol;
            var extractableMembers = typeToExtractFrom.GetMembers().Where(IsExtractableMember);
            if (!extractableMembers.Any())
            {
                var errorMessage = FeaturesResources.CouldNotExtractInterfaceTypeMember;
                return new ExtractInterfaceTypeAnalysisResult(errorMessage);
            }

            return new ExtractInterfaceTypeAnalysisResult(this, document, typeNode, typeToExtractFrom, extractableMembers);
        }
开发者ID:GloryChou,项目名称:roslyn,代码行数:31,代码来源:AbstractExtractInterfaceService.cs

示例8: AnalyzeTypeAtPositionAsync

        public async Task<ExtractInterfaceTypeAnalysisResult> AnalyzeTypeAtPositionAsync(
            Document document,
            int position,
            TypeDiscoveryRule typeDiscoveryRule,
            CancellationToken cancellationToken)
        {
            var typeNode = await GetTypeDeclarationAsync(document, position, typeDiscoveryRule, cancellationToken).ConfigureAwait(false);
            if (typeNode == null)
            {
                var errorMessage = FeaturesResources.Could_not_extract_interface_colon_The_selection_is_not_inside_a_class_interface_struct;
                return new ExtractInterfaceTypeAnalysisResult(errorMessage);
            }

            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            var type = semanticModel.GetDeclaredSymbol(typeNode, cancellationToken);
            if (type == null || type.Kind != SymbolKind.NamedType)
            {
                var errorMessage = FeaturesResources.Could_not_extract_interface_colon_The_selection_is_not_inside_a_class_interface_struct;
                return new ExtractInterfaceTypeAnalysisResult(errorMessage);
            }

            var typeToExtractFrom = type as INamedTypeSymbol;
            var extractableMembers = typeToExtractFrom.GetMembers().Where(IsExtractableMember);
            if (!extractableMembers.Any())
            {
                var errorMessage = FeaturesResources.Could_not_extract_interface_colon_The_type_does_not_contain_any_member_that_can_be_extracted_to_an_interface;
                return new ExtractInterfaceTypeAnalysisResult(errorMessage);
            }

            return new ExtractInterfaceTypeAnalysisResult(this, document, typeNode, typeToExtractFrom, extractableMembers);
        }
开发者ID:Rickinio,项目名称:roslyn,代码行数:31,代码来源:AbstractExtractInterfaceService.cs

示例9: IsThirdPartyNavigationAllowed

        private static bool IsThirdPartyNavigationAllowed(ISymbol symbolToNavigateTo, int caretPosition, Document document, CancellationToken cancellationToken)
        {
            var syntaxRoot = document.GetSyntaxRootAsync(cancellationToken).WaitAndGetResult(cancellationToken);
            var syntaxFactsService = document.GetLanguageService<ISyntaxFactsService>();
            var containingTypeDeclaration = syntaxFactsService.GetContainingTypeDeclaration(syntaxRoot, caretPosition);

            if (containingTypeDeclaration != null)
            {
                var semanticModel = document.GetSemanticModelAsync(cancellationToken).WaitAndGetResult(cancellationToken);
                var containingTypeSymbol = semanticModel.GetDeclaredSymbol(containingTypeDeclaration, cancellationToken) as ITypeSymbol;

                // Allow third parties to navigate to all symbols except types/constructors
                // if we are navigating from the corresponding type.

                if (containingTypeSymbol != null &&
                    (symbolToNavigateTo is ITypeSymbol || symbolToNavigateTo.IsConstructor()))
                {
                    var candidateTypeSymbol = symbolToNavigateTo is ITypeSymbol
                        ? symbolToNavigateTo
                        : symbolToNavigateTo.ContainingType;

                    if (containingTypeSymbol == candidateTypeSymbol)
                    {
                        // We are navigating from the same type, so don't allow third parties to perform the navigation.
                        // This ensures that if we navigate to a class from within that class, we'll stay in the same file
                        // rather than navigate to, say, XAML.
                        return false;
                    }
                }
            }

            return true;
        }
开发者ID:sebgod,项目名称:roslyn,代码行数:33,代码来源:AbstractGoToDefinitionService.cs

示例10: GetSymbolAsync

 public async Task<ISymbol> GetSymbolAsync(Document document, CancellationToken cancellationToken)
 {
     var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
     var node = root.FindNode(Span);
     var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
     var symbol = semanticModel.GetDeclaredSymbol(node, cancellationToken);
     return symbol;
 }
开发者ID:SoumikMukherjeeDOTNET,项目名称:roslyn,代码行数:8,代码来源:DeclaredSymbolInfo.cs

示例11: RemoveUnnecessaryCastAsync

 private static async Task<Document> RemoveUnnecessaryCastAsync(
     Document document, TextSpan span, CancellationToken cancellationToken)
 {
     var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
     var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
     var cast = GetCastNode(root, model, span, cancellationToken);
     return await RemoveUnnecessaryCastAsync(document, cast, cancellationToken).ConfigureAwait(false);
 }
开发者ID:Rickinio,项目名称:roslyn,代码行数:8,代码来源:RemoveUnnecessaryCastCodeFixProvider.cs

示例12: AddSimplifierAnnotationsAsync

        private async Task<Document> AddSimplifierAnnotationsAsync(
            Document document, ImmutableArray<Diagnostic> diagnostics, 
            FixAllState fixAllState, CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
            var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false);

            // Find all nodes to simplify corresponding to diagnostic spans.
            var nodesToSimplify = new List<SyntaxNode>();
            foreach (var diagnostic in diagnostics)
            {
                string codeActionEquivalenceKey;
                var node = GetNodeToSimplify(root, model, diagnostic, options, out codeActionEquivalenceKey, cancellationToken);
                if (node != null && fixAllState.CodeActionEquivalenceKey == codeActionEquivalenceKey)
                {
                    nodesToSimplify.Add(node);
                }
            }

            // Add simplifier and formatter annotations to all nodes to simplify.
            // If the fix all provider needs to fixup any of the parent nodes, then we iterate through each of the nodesToSimplify
            // and fixup any parenting node, computing a new document with required simplifier annotations in each iteration.
            // Otherwise, if the fix all provider doesn't need parent fixup, we just add simplifier annotation to all nodesToSimplify.
            if (!NeedsParentFixup)
            {
                root = root.ReplaceNodes(nodesToSimplify, (o, n) =>
                    n.WithAdditionalAnnotations(Simplifier.Annotation, Formatter.Annotation));
            }
            else
            {
                // Add a custom annotation to nodesToSimplify so we can get back to them later.
                var annotation = new SyntaxAnnotation();
                root = root.ReplaceNodes(nodesToSimplify, (o, n) =>
                    o.WithAdditionalAnnotations(annotation));
                document = document.WithSyntaxRoot(root);

                while (true)
                {
                    root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
                    var annotatedNodes = root.GetAnnotatedNodes(annotation);

                    // Get the next un-processed node to simplify, processed nodes should have simplifier annotation.
                    var annotatedNode = annotatedNodes.FirstOrDefault(n => !n.HasAnnotation(Simplifier.Annotation));
                    if (annotatedNode == null)
                    {
                        // All nodesToSimplify have been processed.
                        // Remove all the custom annotations added for tracking nodesToSimplify.
                        root = root.ReplaceNodes(annotatedNodes, (o, n) => o.WithoutAnnotations(annotation));
                        break;
                    }

                    document = await AddSimplifyAnnotationsAsync(document, annotatedNode, cancellationToken).ConfigureAwait(false);
                }
            }

            return document.WithSyntaxRoot(root);
        }
开发者ID:jkotas,项目名称:roslyn,代码行数:58,代码来源:BatchSimplificationFixAllProvider.cs

示例13: ImplementAbstractClassAsync

 private async Task<Document> ImplementAbstractClassAsync(Document document, SyntaxNode node, CancellationToken cancellationToken)
 {
     var service = document.GetLanguageService<IImplementAbstractClassService>();
     return await service.ImplementAbstractClassAsync(
         document,
         await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false),
         node,
         cancellationToken).ConfigureAwait(false);
 }
开发者ID:Rickinio,项目名称:roslyn,代码行数:9,代码来源:ImplementAbstractClassCodeFixProvider.cs

示例14: FindSymbolAsync

        private async Task<ISymbol> FindSymbolAsync(Document document, int position, CancellationToken cancellationToken)
        {
            var workspace = document.Project.Solution.Workspace;

            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            var symbol = await SymbolFinder.FindSymbolAtPositionAsync(semanticModel, position, workspace, bindLiteralsToUnderlyingType: true, cancellationToken: cancellationToken).ConfigureAwait(false);

            return FindRelatedExplicitlyDeclaredSymbol(symbol, semanticModel.Compilation);
        }
开发者ID:sebgod,项目名称:roslyn,代码行数:9,代码来源:AbstractGoToDefinitionService.cs

示例15: GetCodeFixAsync

        protected override async Task<CodeAction> GetCodeFixAsync(SyntaxNode root, SyntaxNode node, Document document, Diagnostic diagnostics, CancellationToken cancellationToken)
        {
            var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            var methodSymbol = model.GetDeclaredSymbol(node, cancellationToken) as IMethodSymbol;
            if (methodSymbol.ReturnsVoid)
            {
                return null;
            }

            var ienumerableSymbol = model.Compilation.GetTypeByMetadataName("System.Collections.IEnumerable");
            var ienumeratorSymbol = model.Compilation.GetTypeByMetadataName("System.Collections.IEnumerator");
            var ienumerableGenericSymbol = model.Compilation.GetTypeByMetadataName("System.Collections.Generic.IEnumerable`1");
            var ienumeratorGenericSymbol = model.Compilation.GetTypeByMetadataName("System.Collections.Generic.IEnumerator`1");

            if (ienumerableGenericSymbol == null ||
                ienumerableSymbol == null ||
                ienumeratorGenericSymbol == null ||
                ienumeratorSymbol == null)
            {
                return null;
            }

            var returnType = methodSymbol.ReturnType;

            if (returnType.InheritsFromOrEquals(ienumerableSymbol))
            {
                if (returnType.GetArity() != 1)
                {
                    return null;
                }

                var typeArg = returnType.GetTypeArguments().First();
                ienumerableGenericSymbol = ienumerableGenericSymbol.Construct(typeArg);
            }
            else
            {
                ienumerableGenericSymbol = ienumerableGenericSymbol.Construct(returnType);
            }

            TypeSyntax oldReturnType;
            var newReturnType = ienumerableGenericSymbol.GenerateTypeSyntax();
            var newMethodDeclarationNode = WithReturnType(node, newReturnType, out oldReturnType);
            if (newMethodDeclarationNode == null)
            {
                // the language updated and added a new kind of MethodDeclarationSyntax without updating this file
                return null;
            }

            root = root.ReplaceNode(node, newMethodDeclarationNode);
            var newDocument = document.WithSyntaxRoot(root);
            return new MyCodeAction(
                string.Format(CSharpFeaturesResources.ChangeReturnType,
                    oldReturnType.ToString(),
                    ienumerableGenericSymbol.ToMinimalDisplayString(model, node.SpanStart)), newDocument);
        }
开发者ID:rafaellincoln,项目名称:roslyn,代码行数:55,代码来源:CSharpChangeToIEnumerableCodeFixProvider.cs


注:本文中的Document.GetSemanticModelAsync方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。