Merge pull request #4777 from dasMulli/bugfix/assembly-attributes-migration

Migration: Handle different variations of specifying assembly attributes.
This commit is contained in:
Livar 2016-11-18 13:56:30 -08:00 committed by GitHub
commit dd2fe2fac5
2 changed files with 59 additions and 37 deletions

View file

@ -1,5 +1,4 @@
using System.Reflection; using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -7,16 +6,15 @@ using System.Runtime.InteropServices;
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")] [assembly: AssemblyCompanyAttribute("")]
[assembly: AssemblyProduct("ConsoleApp1")] [assembly: System.Reflection.AssemblyProduct("ConsoleApp1")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCopyright("")] [assembly: AssemblyCopyright("")]
[assembly: AssemblyDescription("")] [assembly: AssemblyDescription("")]
[assembly: AssemblyFileVersion("")] [assembly: AssemblyFileVersion("")]
[assembly: AssemblyInformationalVersion("")] [assembly: AssemblyInformationalVersion("")]
[assembly: AssemblyTitle("")] [assembly: System.Reflection.AssemblyTitleAttribute("")]
[assembly: AssemblyVersion("1.0.0")] [assembly: AssemblyVersion("1.0.0"), System.Resources.NeutralResourcesLanguageAttribute("")]
[assembly: NeutralResourcesLanguage("")]
// Setting ComVisible to false makes the types in this assembly not visible // Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from // to COM components. If you need to access a type in this assembly from

View file

@ -19,23 +19,26 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
{ {
internal class MigrateAssemblyInfoRule : IMigrationRule internal class MigrateAssemblyInfoRule : IMigrationRule
{ {
private const string SystemReflectionNamespace = "System.Reflection";
private const string SystemResourcesNamespace = "System.Resources";
private static IReadOnlyDictionary<string, IReadOnlyList<string>> Suppresses { get; } = new Dictionary<string, IReadOnlyList<string>> private static IReadOnlyDictionary<string, IReadOnlyList<string>> Suppresses { get; } = new Dictionary<string, IReadOnlyList<string>>
{ {
{ "csc", new string[] {"CS1701", "CS1702", "CS1705" } } { "csc", new string[] {"CS1701", "CS1702", "CS1705" } }
}; };
private static IReadOnlyList<string> GenerateAssemblyInfoWhitelist = new List<string>() private static IReadOnlyList<KnownAssemblyAttribute> GenerateAssemblyInfoWhitelist = new List<KnownAssemblyAttribute>()
{ {
"AssemblyCompany", new KnownAssemblyAttribute(SystemReflectionNamespace, "AssemblyCompany"),
"AssemblyConfiguration", new KnownAssemblyAttribute(SystemReflectionNamespace, "AssemblyConfiguration"),
"AssemblyCopyright", new KnownAssemblyAttribute(SystemReflectionNamespace, "AssemblyCopyright"),
"AssemblyDescription", new KnownAssemblyAttribute(SystemReflectionNamespace, "AssemblyDescription"),
"AssemblyFileVersion", new KnownAssemblyAttribute(SystemReflectionNamespace, "AssemblyFileVersion"),
"AssemblyInformationalVersion", new KnownAssemblyAttribute(SystemReflectionNamespace, "AssemblyInformationalVersion"),
"AssemblyProduct", new KnownAssemblyAttribute(SystemReflectionNamespace, "AssemblyProduct"),
"AssemblyTitle", new KnownAssemblyAttribute(SystemReflectionNamespace, "AssemblyTitle"),
"AssemblyVersion", new KnownAssemblyAttribute(SystemReflectionNamespace, "AssemblyVersion"),
"NeutralResourcesLanguage" new KnownAssemblyAttribute(SystemResourcesNamespace, "NeutralResourcesLanguage")
}; };
private readonly ITransformApplicator _transformApplicator; private readonly ITransformApplicator _transformApplicator;
@ -50,23 +53,23 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
var projectContext = migrationRuleInputs.DefaultProjectContext; var projectContext = migrationRuleInputs.DefaultProjectContext;
var compilationOptions = ResolveCompilationOptions(projectContext, "Debug"); var compilationOptions = ResolveCompilationOptions(projectContext, "Debug");
var sources = GetCompilationSources(projectContext, compilationOptions); var sources = GetCompilationSources(projectContext, compilationOptions);
var assemblyInfoList = GetAssemblyInfo(sources); var assemblyAttributeList = GetWhitelistedKnownAssemblyAttributes(sources);
foreach(var assemblyInfo in assemblyInfoList) foreach(var assemblyAttribute in assemblyAttributeList)
{ {
var propertyTransform = new AddPropertyTransform<string>( var propertyTransform = new AddPropertyTransform<string>(
$"Generate{assemblyInfo}Attribute", assemblyAttribute.GenerateAssemblyAttributePropertyName,
a => "false", a => "false",
a => true); a => true);
_transformApplicator.Execute( _transformApplicator.Execute(
propertyTransform.Transform(assemblyInfo), propertyTransform.Transform(assemblyAttribute.AttributeName),
migrationRuleInputs.CommonPropertyGroup, migrationRuleInputs.CommonPropertyGroup,
true); true);
} }
} }
public IEnumerable<string> GetCompilationSources(ProjectContext project, CommonCompilerOptions compilerOptions) private IEnumerable<string> GetCompilationSources(ProjectContext project, CommonCompilerOptions compilerOptions)
{ {
if (compilerOptions.CompileInclude == null) if (compilerOptions.CompileInclude == null)
{ {
@ -78,28 +81,28 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
return includeFiles.Select(f => f.SourcePath); return includeFiles.Select(f => f.SourcePath);
} }
public List<string> GetAssemblyInfo(IEnumerable<string> sourceFiles) private List<KnownAssemblyAttribute> GetWhitelistedKnownAssemblyAttributes(IEnumerable<string> sourceFiles)
{ {
var assemblyInfoList = new List<string>(); var assemblyInfoList = new List<KnownAssemblyAttribute>();
foreach (var sourceFile in sourceFiles) foreach (var sourceFile in sourceFiles)
{ {
var tree = CSharpSyntaxTree.ParseText(File.ReadAllText(sourceFile)); var tree = CSharpSyntaxTree.ParseText(File.ReadAllText(sourceFile));
var root = tree.GetRoot(); var root = tree.GetRoot();
// assembly attributes can be only on first level // assembly attributes can be only on first level
foreach (var attributeListSyntax in root.ChildNodes().OfType<AttributeListSyntax>()) var attributeListSyntaxNodes = root.ChildNodes().OfType<AttributeListSyntax>();
{
if (attributeListSyntax.Target.Identifier.Kind() == SyntaxKind.AssemblyKeyword) assemblyInfoList.AddRange(
{ attributeListSyntaxNodes
foreach (var attributeSyntax in attributeListSyntax .Where(node => node.Target.Identifier.Kind() == SyntaxKind.AssemblyKeyword)
.Attributes .SelectMany(node => node.Attributes)
.Select(a => a.Name.ToString()) .Select(attribute => attribute.Name.ToString())
.Where(a => GenerateAssemblyInfoWhitelist.Contains(a))) .Select(name =>
{ GenerateAssemblyInfoWhitelist
assemblyInfoList.Add(attributeSyntax); .FirstOrDefault(b => b.MatchNames.Contains(name))
} )
} .Where(knownAttribute => knownAttribute != null)
} );
} }
return assemblyInfoList; return assemblyInfoList;
@ -142,5 +145,26 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
return baseOption; return baseOption;
} }
private class KnownAssemblyAttribute
{
public string Namespace { get; }
public string AttributeName { get; }
public IList<string> MatchNames { get; }
public string GenerateAssemblyAttributePropertyName { get; }
public KnownAssemblyAttribute(string namespaceName, string attributeName)
{
Namespace = namespaceName;
AttributeName = attributeName;
GenerateAssemblyAttributePropertyName = $"Generate{attributeName}Attribute";
MatchNames = new [] {
attributeName,
$"{attributeName}Attribute",
$"{namespaceName}.{attributeName}",
$"{namespaceName}.{attributeName}Attribute"
};
}
}
} }
} }