예제 #1
0
        public static void AppendToAliasNameSet(
            this string?alias,
            ImmutableHashSet <string> .Builder builder
            )
        {
            if (RoslynString.IsNullOrWhiteSpace(alias))
            {
                return;
            }

            builder.Add(alias);

            var caseSensitive = builder.KeyComparer == StringComparer.Ordinal;

            Debug.Assert(
                builder.KeyComparer == StringComparer.Ordinal ||
                builder.KeyComparer == StringComparer.OrdinalIgnoreCase
                );
            if (alias.TryGetWithoutAttributeSuffix(caseSensitive, out var aliasWithoutAttribute))
            {
                builder.Add(aliasWithoutAttribute);
                return;
            }

            builder.Add(alias.GetWithSingleAttributeSuffix(caseSensitive));
        }
예제 #2
0
 protected void AddIfNotNullOrWhiteSpace(string name, string?value)
 {
     if (!RoslynString.IsNullOrWhiteSpace(value))
     {
         Add(name, value);
     }
 }
예제 #3
0
 protected void AddIfNotNullOrWhiteSpace(string name, string?value, bool addQuoteIfValueContainsWhitespace = true)
 {
     if (!RoslynString.IsNullOrWhiteSpace(value))
     {
         Add(name, value, addQuoteIfValueContainsWhitespace);
     }
 }
예제 #4
0
        private ProjectFileInfo CreateProjectFileInfo(MSB.Execution.ProjectInstance project)
        {
            var commandLineArgs = GetCommandLineArgs(project);

            var outputFilePath = project.ReadPropertyString(PropertyNames.TargetPath);

            if (!RoslynString.IsNullOrWhiteSpace(outputFilePath))
            {
                outputFilePath = GetAbsolutePathRelativeToProject(outputFilePath);
            }

            var outputRefFilePath = project.ReadPropertyString(PropertyNames.TargetRefPath);

            if (!RoslynString.IsNullOrWhiteSpace(outputRefFilePath))
            {
                outputRefFilePath = GetAbsolutePathRelativeToProject(outputRefFilePath);
            }

            // Right now VB doesn't have the concept of "default namespace". But we conjure one in workspace
            // by assigning the value of the project's root namespace to it. So various feature can choose to
            // use it for their own purpose.
            // In the future, we might consider officially exposing "default namespace" for VB project
            // (e.g. through a <defaultnamespace> msbuild property)
            var defaultNamespace = project.ReadPropertyString(PropertyNames.RootNamespace) ?? string.Empty;

            var targetFramework = project.ReadPropertyString(PropertyNames.TargetFramework);

            if (RoslynString.IsNullOrWhiteSpace(targetFramework))
            {
                targetFramework = null;
            }

            var docs = project.GetDocuments()
                       .Where(IsNotTemporaryGeneratedFile)
                       .Select(MakeDocumentFileInfo)
                       .ToImmutableArray();

            var additionalDocs = project.GetAdditionalFiles()
                                 .Select(MakeNonSourceFileDocumentFileInfo)
                                 .ToImmutableArray();

            var analyzerConfigDocs = project.GetEditorConfigFiles()
                                     .Select(MakeNonSourceFileDocumentFileInfo)
                                     .ToImmutableArray();

            return(ProjectFileInfo.Create(
                       Language,
                       project.FullPath,
                       outputFilePath,
                       outputRefFilePath,
                       defaultNamespace,
                       targetFramework,
                       commandLineArgs,
                       docs,
                       additionalDocs,
                       analyzerConfigDocs,
                       project.GetProjectReferences().ToImmutableArray(),
                       Log));
        }
예제 #5
0
        protected void ReadErrorReport()
        {
            var errorReport = Project.ReadPropertyString(PropertyNames.ErrorReport);

            if (!RoslynString.IsNullOrWhiteSpace(errorReport))
            {
                Add("errorreport", errorReport.ToLower());
            }
        }
예제 #6
0
        protected void ReadDelaySign()
        {
            var delaySign = Project.ReadPropertyString(PropertyNames.DelaySign);

            if (!RoslynString.IsNullOrWhiteSpace(delaySign))
            {
                AddWithPlusOrMinus("delaysign", Conversions.ToBool(delaySign));
            }
        }
예제 #7
0
 private static string GetMSBuildFailedMessage(string projectFilePath, string message) =>
 RoslynString.IsNullOrWhiteSpace(message)
       ? string.Format(
     WorkspaceMSBuildResources.Msbuild_failed_when_processing_the_file_0,
     projectFilePath
     )
       : string.Format(
     WorkspaceMSBuildResources.Msbuild_failed_when_processing_the_file_0_with_message_1,
     projectFilePath,
     message
     );
예제 #8
0
        protected void ReadPlatform()
        {
            var platform    = Project.ReadPropertyString(PropertyNames.PlatformTarget);
            var prefer32bit = Project.ReadPropertyBool(PropertyNames.Prefer32Bit);

            if (prefer32bit && (RoslynString.IsNullOrWhiteSpace(platform) || string.Equals("anycpu", platform, StringComparison.OrdinalIgnoreCase)))
            {
                platform = "anycpu32bitpreferred";
            }

            AddIfNotNullOrWhiteSpace("platform", platform);
        }
예제 #9
0
        protected void ReadFeatures()
        {
            var features = Project.ReadPropertyString(PropertyNames.Features);

            if (!RoslynString.IsNullOrWhiteSpace(features))
            {
                foreach (var feature in CompilerOptionParseUtilities.ParseFeatureFromMSBuild(features))
                {
                    Add("features", feature);
                }
            }
        }
예제 #10
0
        protected void ReadSigning()
        {
            var signAssembly = Project.ReadPropertyBool(PropertyNames.SignAssembly);

            if (signAssembly)
            {
                var keyFile = Project.ReadPropertyString(PropertyNames.KeyOriginatorFile);
                if (!RoslynString.IsNullOrWhiteSpace(keyFile))
                {
                    Add("keyFile", keyFile);
                }

                var keyContainer = Project.ReadPropertyString(PropertyNames.KeyContainerName);
                if (!RoslynString.IsNullOrWhiteSpace(keyContainer))
                {
                    Add("keycontainer", keyContainer);
                }
            }
        }
예제 #11
0
        private static void DiffRules(
            string oldRulesJsonPath,
            string newRulesJsonPath,
            string outputPath,
            string?latestRulesJsonPath = null)
        {
            RuleFileContent oldContent = ReadRuleFileContent(oldRulesJsonPath);
            RuleFileContent newContent = ReadRuleFileContent(newRulesJsonPath);

            // If we have the latest rules, we can backfill missing help link URLs.
            if (!RoslynString.IsNullOrWhiteSpace(latestRulesJsonPath))
            {
                RuleFileContent latestContent = ReadRuleFileContent(latestRulesJsonPath);
                Dictionary <string, RuleInfo> latestRulesById = latestContent.Rules.ToDictionary(r => r.Id);
                foreach (RuleInfo rule in oldContent.Rules.Concat(newContent.Rules))
                {
                    if (RoslynString.IsNullOrWhiteSpace(rule.HelpLink) &&
                        latestRulesById.TryGetValue(rule.Id, out RuleInfo latestRule))
                    {
                        rule.HelpLink = latestRule.HelpLink;
                    }
                }
            }

            Dictionary <string, RuleInfo> oldRulesById = oldContent.Rules.ToDictionary(r => r.Id);
            Dictionary <string, RuleInfo> newRulesById = newContent.Rules.ToDictionary(r => r.Id);
            IEnumerable <RuleInfo>        addedRules   =
                newContent.Rules
                .Where(r => !oldRulesById.ContainsKey(r.Id));
            IEnumerable <RuleInfo> removedRules =
                oldContent.Rules
                .Where(r => !newRulesById.ContainsKey(r.Id));
            IEnumerable <RuleInfo> changedRules =
                newContent.Rules
                .Where(r => oldRulesById.TryGetValue(r.Id, out RuleInfo oldRule) &&
                       r.IsEnabledByDefault != oldRule.IsEnabledByDefault);
            StringBuilder sb = new StringBuilder();

            GenerateAddRemovedRulesDiffMarkdown(sb, "### Added", addedRules);
            GenerateAddRemovedRulesDiffMarkdown(sb, "### Removed", removedRules);
            GenerateChangedRulesDiffMarkdown(sb, "### Changed", changedRules);
            File.WriteAllText(outputPath, sb.ToString());
        }
        private void ReadDoc()
        {
            var documentationFile     = Project.ReadPropertyString(PropertyNames.DocFileItem);
            var generateDocumentation = Project.ReadPropertyBool(PropertyNames.GenerateDocumentation);

            var hasDocumentationFile = !RoslynString.IsNullOrWhiteSpace(documentationFile);

            if (hasDocumentationFile || generateDocumentation)
            {
                if (!RoslynString.IsNullOrWhiteSpace(documentationFile))
                {
                    Add("doc", documentationFile);
                }
                else
                {
                    Add("doc");
                }
            }
        }
        private void ReadVbRuntime()
        {
            var vbRuntime = Project.ReadPropertyString(PropertyNames.VbRuntime);

            if (!RoslynString.IsNullOrWhiteSpace(vbRuntime))
            {
                if (string.Equals("default", vbRuntime, StringComparison.OrdinalIgnoreCase))
                {
                    Add("vbruntime+");
                }
                else if (string.Equals("embed", vbRuntime, StringComparison.OrdinalIgnoreCase))
                {
                    Add("vbruntime*");
                }
                else if (string.Equals("none", vbRuntime, StringComparison.OrdinalIgnoreCase))
                {
                    Add("vbruntime-");
                }
                else
                {
                    Add("vbruntime", vbRuntime);
                }
            }
        }
예제 #14
0
 public override string ToString() =>
 RoslynString.IsNullOrWhiteSpace(TargetFramework)
       ? FilePath ?? string.Empty
       : $"{FilePath} ({TargetFramework})";
예제 #15
0
        internal static void ParseResourceDescription(
            string resourceDescriptor,
            string?baseDirectory,
            bool skipLeadingSeparators, //VB does this
            out string?filePath,
            out string?fullPath,
            out string?fileName,
            out string resourceName,
            out string?accessibility)
        {
            filePath      = null;
            fullPath      = null;
            fileName      = null;
            resourceName  = "";
            accessibility = null;

            // resource descriptor is: "<filePath>[,<string name>[,public|private]]"
            string[] parts = ParseSeparatedStrings(resourceDescriptor, s_resourceSeparators).ToArray();

            int offset = 0;

            int length = parts.Length;

            if (skipLeadingSeparators)
            {
                for (; offset < length && string.IsNullOrEmpty(parts[offset]); offset++)
                {
                }

                length -= offset;
            }


            if (length >= 1)
            {
                filePath = RemoveQuotesAndSlashes(parts[offset + 0]);
            }

            if (length >= 2)
            {
                resourceName = RemoveQuotesAndSlashes(parts[offset + 1]);
            }

            if (length >= 3)
            {
                accessibility = RemoveQuotesAndSlashes(parts[offset + 2]);
            }

            if (RoslynString.IsNullOrWhiteSpace(filePath))
            {
                return;
            }

            fileName = PathUtilities.GetFileName(filePath);
            fullPath = FileUtilities.ResolveRelativePath(filePath, baseDirectory);

            // The default resource name is the file name.
            // Also use the file name for the name when user specifies string like "filePath,,private"
            if (RoslynString.IsNullOrWhiteSpace(resourceName))
            {
                resourceName = fileName;
            }
        }
예제 #16
0
            private Task <ProjectInfo> CreateProjectInfoAsync(
                ProjectFileInfo projectFileInfo,
                ProjectId projectId,
                bool addDiscriminator,
                CancellationToken cancellationToken
                )
            {
                var language    = projectFileInfo.Language;
                var projectPath = projectFileInfo.FilePath;
                var projectName = Path.GetFileNameWithoutExtension(projectPath) ?? string.Empty;

                if (
                    addDiscriminator &&
                    !RoslynString.IsNullOrWhiteSpace(projectFileInfo.TargetFramework)
                    )
                {
                    projectName += "(" + projectFileInfo.TargetFramework + ")";
                }

                var version = projectPath is null
                    ? VersionStamp.Default
                    : VersionStamp.Create(FileUtilities.GetFileTimeStamp(projectPath));

                if (projectFileInfo.IsEmpty)
                {
                    var assemblyName = GetAssemblyNameFromProjectPath(projectPath);

                    var parseOptions = GetLanguageService <ISyntaxTreeFactoryService>(language)
                                       ?.GetDefaultParseOptions();
                    var compilationOptions = GetLanguageService <ICompilationFactoryService>(
                        language
                        )
                                             ?.GetDefaultCompilationOptions();

                    return(Task.FromResult(
                               ProjectInfo.Create(
                                   projectId,
                                   version,
                                   projectName,
                                   assemblyName: assemblyName,
                                   language: language,
                                   filePath: projectPath,
                                   outputFilePath: string.Empty,
                                   outputRefFilePath: string.Empty,
                                   compilationOptions: compilationOptions,
                                   parseOptions: parseOptions,
                                   documents: SpecializedCollections.EmptyEnumerable <DocumentInfo>(),
                                   projectReferences: SpecializedCollections.EmptyEnumerable <ProjectReference>(),
                                   metadataReferences: SpecializedCollections.EmptyEnumerable <MetadataReference>(),
                                   analyzerReferences: SpecializedCollections.EmptyEnumerable <AnalyzerReference>(),
                                   additionalDocuments: SpecializedCollections.EmptyEnumerable <DocumentInfo>(),
                                   isSubmission: false,
                                   hostObjectType: null
                                   )
                               ));
                }

                return(DoOperationAndReportProgressAsync(
                           ProjectLoadOperation.Resolve,
                           projectPath,
                           projectFileInfo.TargetFramework,
                           async() =>
                {
                    var projectDirectory = Path.GetDirectoryName(projectPath);

                    // parse command line arguments
                    var commandLineParser = GetLanguageService <ICommandLineParserService>(
                        projectFileInfo.Language
                        );

                    if (commandLineParser is null)
                    {
                        var message = string.Format(
                            WorkspaceMSBuildResources.Unable_to_find_a_0_for_1,
                            nameof(ICommandLineParserService),
                            projectFileInfo.Language
                            );
                        throw new Exception(message);
                    }

                    var commandLineArgs = commandLineParser.Parse(
                        arguments: projectFileInfo.CommandLineArgs,
                        baseDirectory: projectDirectory,
                        isInteractive: false,
                        sdkDirectory: RuntimeEnvironment.GetRuntimeDirectory()
                        );

                    var assemblyName = commandLineArgs.CompilationName;
                    if (RoslynString.IsNullOrWhiteSpace(assemblyName))
                    {
                        // if there isn't an assembly name, make one from the file path.
                        // Note: This may not be necessary any longer if the command line args
                        // always produce a valid compilation name.
                        assemblyName = GetAssemblyNameFromProjectPath(projectPath);
                    }

                    // Ensure sure that doc-comments are parsed
                    var parseOptions = commandLineArgs.ParseOptions;
                    if (parseOptions.DocumentationMode == DocumentationMode.None)
                    {
                        parseOptions = parseOptions.WithDocumentationMode(
                            DocumentationMode.Parse
                            );
                    }

                    // add all the extra options that are really behavior overrides
                    var metadataService = GetWorkspaceService <IMetadataService>();
                    var compilationOptions = commandLineArgs.CompilationOptions
                                             .WithXmlReferenceResolver(new XmlFileResolver(projectDirectory))
                                             .WithSourceReferenceResolver(
                        new SourceFileResolver(
                            ImmutableArray <string> .Empty,
                            projectDirectory
                            )
                        )
                                             // TODO: https://github.com/dotnet/roslyn/issues/4967
                                             .WithMetadataReferenceResolver(
                        new WorkspaceMetadataFileReferenceResolver(
                            metadataService,
                            new RelativePathResolver(
                                ImmutableArray <string> .Empty,
                                projectDirectory
                                )
                            )
                        )
                                             .WithStrongNameProvider(
                        new DesktopStrongNameProvider(commandLineArgs.KeyFileSearchPaths)
                        )
                                             .WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default);

                    var documents = CreateDocumentInfos(
                        projectFileInfo.Documents,
                        projectId,
                        commandLineArgs.Encoding
                        );
                    var additionalDocuments = CreateDocumentInfos(
                        projectFileInfo.AdditionalDocuments,
                        projectId,
                        commandLineArgs.Encoding
                        );
                    var analyzerConfigDocuments = CreateDocumentInfos(
                        projectFileInfo.AnalyzerConfigDocuments,
                        projectId,
                        commandLineArgs.Encoding
                        );
                    CheckForDuplicateDocuments(
                        documents.Concat(additionalDocuments).Concat(analyzerConfigDocuments),
                        projectPath,
                        projectId
                        );

                    var analyzerReferences = ResolveAnalyzerReferences(commandLineArgs);

                    var resolvedReferences = await ResolveReferencesAsync(
                        projectId,
                        projectFileInfo,
                        commandLineArgs,
                        cancellationToken
                        )
                                             .ConfigureAwait(false);

                    return ProjectInfo
                    .Create(
                        projectId,
                        version,
                        projectName,
                        assemblyName,
                        language,
                        projectPath,
                        outputFilePath: projectFileInfo.OutputFilePath,
                        outputRefFilePath: projectFileInfo.OutputRefFilePath,
                        compilationOptions: compilationOptions,
                        parseOptions: parseOptions,
                        documents: documents,
                        projectReferences: resolvedReferences.ProjectReferences,
                        metadataReferences: resolvedReferences.MetadataReferences,
                        analyzerReferences: analyzerReferences,
                        additionalDocuments: additionalDocuments,
                        isSubmission: false,
                        hostObjectType: null
                        )
                    .WithDefaultNamespace(projectFileInfo.DefaultNamespace)
                    .WithAnalyzerConfigDocuments(analyzerConfigDocuments)
                    .WithCompilationOutputInfo(
                        new CompilationOutputInfo(projectFileInfo.OutputFilePath)
                        );
                }