Skip to content

Commit b169e69

Browse files
authored
addng public identity (#18709)
1 parent 0652a56 commit b169e69

22 files changed

+796
-2
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#if !NET6_0 && IsRetargetable
2+
[assembly: System.Reflection.AssemblyFlags(System.Reflection.AssemblyNameFlags.Retargetable)]
3+
#endif
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFrameworks>net6.0;netstandard2.0</TargetFrameworks>
5+
<SignAssembly>true</SignAssembly>
6+
<DefineConstants Condition="'$(IsRetargetable)' == 'true'">$(DefineConstants);IsRetargetable</DefineConstants>
7+
<SignAssembly Condition="'$(DisableSigningOnNet6_0)' == 'true' and '$(TargetFramework)' == 'net6.0'">false</SignAssembly>
8+
<SignAssembly Condition="'$(DisableSigningOnNetStandard2_0)' == 'true' and '$(TargetFramework)' == 'netstandard2.0'">false</SignAssembly>
9+
</PropertyGroup>
10+
11+
<PropertyGroup Condition="'$(SignAssembly)' == 'true'">
12+
<AssemblyOriginatorKeyFile>test.snk</AssemblyOriginatorKeyFile>
13+
<PublicSign>true</PublicSign>
14+
</PropertyGroup>
15+
16+
</Project>
596 Bytes
Binary file not shown.

src/Compatibility/Microsoft.DotNet.ApiCompatibility/DiagnosticIds.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ public static class DiagnosticIds
1010
{
1111
public const string TypeMustExist = "CP0001";
1212
public const string MemberMustExist = "CP0002";
13+
public const string AssemblyIdentityMustMatch = "CP0003";
14+
public const string MatchingAssemblyDoesNotExist = "CP0004";
1315
public const string CannotAddAbstractMember = "CP0005";
1416
}
1517
}

src/Compatibility/Microsoft.DotNet.ApiCompatibility/Resources.resx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,30 @@
117117
<resheader name="writer">
118118
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
119119
</resheader>
120+
<data name="AssemblyNameDoesNotExist" xml:space="preserve">
121+
<value>Assembly with name '{0}' does not exist at {1}.</value>
122+
</data>
123+
<data name="AssemblyNameDoesNotMatch" xml:space="preserve">
124+
<value>{2} assembly name '{0}' does not match with {3} assembly name '{1}'.</value>
125+
</data>
126+
<data name="AssemblyPublicKeyTokenDoesNotMatch" xml:space="preserve">
127+
<value>{2} assembly token '{0}' does not match with {3} '{1}'.</value>
128+
</data>
120129
<data name="AssemblySearchDirectoryDoesNotExist" xml:space="preserve">
121130
<value>Provided assembly search directory '{0}' does not exist.</value>
122131
</data>
123132
<data name="CannotAddAbstractMember" xml:space="preserve">
124133
<value>Cannot add abstract member '{0}' to {1} because does not exist on {2}</value>
125134
</data>
135+
<data name="AssembyCultureDoesNotMatch" xml:space="preserve">
136+
<value>{2} assembly culture '{0}' does not match with {3} assembly culture '{1}'.</value>
137+
</data>
138+
<data name="AssembyVersionDoesNotMatch" xml:space="preserve">
139+
<value>{3} assembly version '{1}' should be equal to {2} version '{0}'.</value>
140+
</data>
141+
<data name="AssembyVersionIsNotCompatible" xml:space="preserve">
142+
<value>{2} assembly version '{0}' should be equal to or higher than {3} version '{1}'.</value>
143+
</data>
126144
<data name="CouldNotResolveReference" xml:space="preserve">
127145
<value>Could not resolve reference '{0}' in any of the provided search directories.</value>
128146
</data>
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// Copyright (c) .NET Foundation and contributors. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Reflection;
7+
using System.Text;
8+
using Microsoft.CodeAnalysis;
9+
using Microsoft.DotNet.ApiCompatibility.Abstractions;
10+
11+
namespace Microsoft.DotNet.ApiCompatibility.Rules
12+
{
13+
public class AssemblyIdentityMustMatch : Rule
14+
{
15+
public override void Initialize(RuleRunnerContext context)
16+
{
17+
context.RegisterOnAssemblySymbolAction(RunOnAssemblySymbol);
18+
}
19+
20+
private void RunOnAssemblySymbol(IAssemblySymbol left, IAssemblySymbol right, string leftName, string rightName, IList<CompatDifference> differences)
21+
{
22+
if (left == null && right != null)
23+
{
24+
differences.Add(new CompatDifference(DiagnosticIds.MatchingAssemblyDoesNotExist, string.Format(Resources.AssemblyNameDoesNotExist, leftName, right.Identity.Name), DifferenceType.Removed, right.Identity.GetDisplayName()));
25+
return;
26+
}
27+
28+
if (left != null && right == null)
29+
{
30+
differences.Add(new CompatDifference(DiagnosticIds.MatchingAssemblyDoesNotExist, string.Format(Resources.AssemblyNameDoesNotExist, rightName, left.Identity.Name), DifferenceType.Added, left.Identity.GetDisplayName()));
31+
return;
32+
}
33+
34+
AssemblyIdentity leftIdentity = left.Identity;
35+
AssemblyIdentity rightIdentity = right.Identity;
36+
37+
string leftAssemblyName = leftIdentity.Name;
38+
string leftAssemblyCulture = string.IsNullOrEmpty(leftIdentity.CultureName) ? "neutral" : leftIdentity.CultureName;
39+
Version leftAssemblyVersion = leftIdentity.Version;
40+
ReadOnlySpan<byte> leftAssemblyPublicKeyToken = leftIdentity.PublicKeyToken.AsSpan();
41+
42+
string rightAssemblyName = rightIdentity.Name;
43+
string rightAssemblyCulture = string.IsNullOrEmpty(rightIdentity.CultureName) ? "neutral" : rightIdentity.CultureName;
44+
Version rightAssemblyVersion = rightIdentity.Version;
45+
ReadOnlySpan<byte> rightAssemblyPublicKeyToken = rightIdentity.PublicKeyToken.AsSpan();
46+
47+
if (leftAssemblyName != rightAssemblyName)
48+
{
49+
differences.Add(CreateIdentityDifference(Resources.AssemblyNameDoesNotMatch, leftAssemblyName, rightAssemblyName, leftName, rightName, rightIdentity));
50+
}
51+
52+
if (leftAssemblyCulture != rightAssemblyCulture)
53+
{
54+
differences.Add(CreateIdentityDifference(Resources.AssembyCultureDoesNotMatch, leftAssemblyCulture, rightAssemblyCulture, leftName, rightName, rightIdentity));
55+
}
56+
57+
if (rightAssemblyVersion < leftAssemblyVersion)
58+
{
59+
differences.Add(CreateIdentityDifference(Resources.AssembyVersionIsNotCompatible, rightAssemblyVersion.ToString(), leftAssemblyVersion.ToString(), rightName, leftName, rightIdentity));
60+
}
61+
else if (Settings.StrictMode && leftAssemblyVersion < rightAssemblyVersion)
62+
{
63+
differences.Add(CreateIdentityDifference(Resources.AssembyVersionDoesNotMatch, leftAssemblyVersion.ToString(), rightAssemblyVersion.ToString(), leftName, rightName, leftIdentity));
64+
}
65+
66+
bool isLeftRetargetable = (left.Identity.Flags & AssemblyNameFlags.Retargetable) != 0;
67+
bool isRightRetargetable = (right.Identity.Flags & AssemblyNameFlags.Retargetable) != 0;
68+
if (!leftAssemblyPublicKeyToken.IsEmpty && !isLeftRetargetable && !leftAssemblyPublicKeyToken.SequenceEqual(rightAssemblyPublicKeyToken))
69+
{
70+
differences.Add(CreateIdentityDifference(
71+
Resources.AssemblyPublicKeyTokenDoesNotMatch,
72+
GetStringRepresentation(leftAssemblyPublicKeyToken),
73+
GetStringRepresentation(rightAssemblyPublicKeyToken),
74+
leftName,
75+
rightName,
76+
rightIdentity));
77+
}
78+
else if (Settings.StrictMode && !rightAssemblyPublicKeyToken.IsEmpty && !isRightRetargetable)
79+
{
80+
differences.Add(CreateIdentityDifference(
81+
Resources.AssemblyPublicKeyTokenDoesNotMatch,
82+
GetStringRepresentation(rightAssemblyPublicKeyToken),
83+
GetStringRepresentation(leftAssemblyPublicKeyToken),
84+
rightName,
85+
leftName,
86+
leftIdentity));
87+
}
88+
}
89+
90+
private static string GetStringRepresentation(ReadOnlySpan<byte> publicKeyToken)
91+
{
92+
if (publicKeyToken.IsEmpty)
93+
return "null";
94+
95+
StringBuilder sb = new StringBuilder();
96+
foreach (var b in publicKeyToken)
97+
{
98+
sb.Append(b.ToString("x2"));
99+
}
100+
return sb.ToString();
101+
}
102+
103+
private CompatDifference CreateIdentityDifference(string format, string leftProperty, string rightProperty, string leftName, string rightName, AssemblyIdentity identity) =>
104+
new CompatDifference(DiagnosticIds.AssemblyIdentityMustMatch, string.Format(format, leftProperty, rightProperty, leftName, rightName), DifferenceType.Changed, identity.GetDisplayName());
105+
}
106+
}

src/Compatibility/Microsoft.DotNet.ApiCompatibility/xlf/Resources.cs.xlf

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,41 @@
22
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
33
<file datatype="xml" source-language="en" target-language="cs" original="../Resources.resx">
44
<body>
5+
<trans-unit id="AssemblyNameDoesNotExist">
6+
<source>Assembly with name '{0}' does not exist at {1}.</source>
7+
<target state="new">Assembly with name '{0}' does not exist at {1}.</target>
8+
<note />
9+
</trans-unit>
10+
<trans-unit id="AssemblyNameDoesNotMatch">
11+
<source>{2} assembly name '{0}' does not match with {3} assembly name '{1}'.</source>
12+
<target state="new">{2} assembly name '{0}' does not match with {3} assembly name '{1}'.</target>
13+
<note />
14+
</trans-unit>
15+
<trans-unit id="AssemblyPublicKeyTokenDoesNotMatch">
16+
<source>{2} assembly token '{0}' does not match with {3} '{1}'.</source>
17+
<target state="new">{2} assembly token '{0}' does not match with {3} '{1}'.</target>
18+
<note />
19+
</trans-unit>
520
<trans-unit id="AssemblySearchDirectoryDoesNotExist">
621
<source>Provided assembly search directory '{0}' does not exist.</source>
722
<target state="new">Provided assembly search directory '{0}' does not exist.</target>
823
<note />
924
</trans-unit>
25+
<trans-unit id="AssembyCultureDoesNotMatch">
26+
<source>{2} assembly culture '{0}' does not match with {3} assembly culture '{1}'.</source>
27+
<target state="new">{2} assembly culture '{0}' does not match with {3} assembly culture '{1}'.</target>
28+
<note />
29+
</trans-unit>
30+
<trans-unit id="AssembyVersionDoesNotMatch">
31+
<source>{3} assembly version '{1}' should be equal to {2} version '{0}'.</source>
32+
<target state="new">{3} assembly version '{1}' should be equal to {2} version '{0}'.</target>
33+
<note />
34+
</trans-unit>
35+
<trans-unit id="AssembyVersionIsNotCompatible">
36+
<source>{2} assembly version '{0}' should be equal to or higher than {3} version '{1}'.</source>
37+
<target state="new">{2} assembly version '{0}' should be equal to or higher than {3} version '{1}'.</target>
38+
<note />
39+
</trans-unit>
1040
<trans-unit id="CannotAddAbstractMember">
1141
<source>Cannot add abstract member '{0}' to {1} because does not exist on {2}</source>
1242
<target state="new">Cannot add abstract member '{0}' to {1} because does not exist on {2}</target>

src/Compatibility/Microsoft.DotNet.ApiCompatibility/xlf/Resources.de.xlf

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,41 @@
22
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
33
<file datatype="xml" source-language="en" target-language="de" original="../Resources.resx">
44
<body>
5+
<trans-unit id="AssemblyNameDoesNotExist">
6+
<source>Assembly with name '{0}' does not exist at {1}.</source>
7+
<target state="new">Assembly with name '{0}' does not exist at {1}.</target>
8+
<note />
9+
</trans-unit>
10+
<trans-unit id="AssemblyNameDoesNotMatch">
11+
<source>{2} assembly name '{0}' does not match with {3} assembly name '{1}'.</source>
12+
<target state="new">{2} assembly name '{0}' does not match with {3} assembly name '{1}'.</target>
13+
<note />
14+
</trans-unit>
15+
<trans-unit id="AssemblyPublicKeyTokenDoesNotMatch">
16+
<source>{2} assembly token '{0}' does not match with {3} '{1}'.</source>
17+
<target state="new">{2} assembly token '{0}' does not match with {3} '{1}'.</target>
18+
<note />
19+
</trans-unit>
520
<trans-unit id="AssemblySearchDirectoryDoesNotExist">
621
<source>Provided assembly search directory '{0}' does not exist.</source>
722
<target state="new">Provided assembly search directory '{0}' does not exist.</target>
823
<note />
924
</trans-unit>
25+
<trans-unit id="AssembyCultureDoesNotMatch">
26+
<source>{2} assembly culture '{0}' does not match with {3} assembly culture '{1}'.</source>
27+
<target state="new">{2} assembly culture '{0}' does not match with {3} assembly culture '{1}'.</target>
28+
<note />
29+
</trans-unit>
30+
<trans-unit id="AssembyVersionDoesNotMatch">
31+
<source>{3} assembly version '{1}' should be equal to {2} version '{0}'.</source>
32+
<target state="new">{3} assembly version '{1}' should be equal to {2} version '{0}'.</target>
33+
<note />
34+
</trans-unit>
35+
<trans-unit id="AssembyVersionIsNotCompatible">
36+
<source>{2} assembly version '{0}' should be equal to or higher than {3} version '{1}'.</source>
37+
<target state="new">{2} assembly version '{0}' should be equal to or higher than {3} version '{1}'.</target>
38+
<note />
39+
</trans-unit>
1040
<trans-unit id="CannotAddAbstractMember">
1141
<source>Cannot add abstract member '{0}' to {1} because does not exist on {2}</source>
1242
<target state="new">Cannot add abstract member '{0}' to {1} because does not exist on {2}</target>

src/Compatibility/Microsoft.DotNet.ApiCompatibility/xlf/Resources.es.xlf

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,41 @@
22
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
33
<file datatype="xml" source-language="en" target-language="es" original="../Resources.resx">
44
<body>
5+
<trans-unit id="AssemblyNameDoesNotExist">
6+
<source>Assembly with name '{0}' does not exist at {1}.</source>
7+
<target state="new">Assembly with name '{0}' does not exist at {1}.</target>
8+
<note />
9+
</trans-unit>
10+
<trans-unit id="AssemblyNameDoesNotMatch">
11+
<source>{2} assembly name '{0}' does not match with {3} assembly name '{1}'.</source>
12+
<target state="new">{2} assembly name '{0}' does not match with {3} assembly name '{1}'.</target>
13+
<note />
14+
</trans-unit>
15+
<trans-unit id="AssemblyPublicKeyTokenDoesNotMatch">
16+
<source>{2} assembly token '{0}' does not match with {3} '{1}'.</source>
17+
<target state="new">{2} assembly token '{0}' does not match with {3} '{1}'.</target>
18+
<note />
19+
</trans-unit>
520
<trans-unit id="AssemblySearchDirectoryDoesNotExist">
621
<source>Provided assembly search directory '{0}' does not exist.</source>
722
<target state="new">Provided assembly search directory '{0}' does not exist.</target>
823
<note />
924
</trans-unit>
25+
<trans-unit id="AssembyCultureDoesNotMatch">
26+
<source>{2} assembly culture '{0}' does not match with {3} assembly culture '{1}'.</source>
27+
<target state="new">{2} assembly culture '{0}' does not match with {3} assembly culture '{1}'.</target>
28+
<note />
29+
</trans-unit>
30+
<trans-unit id="AssembyVersionDoesNotMatch">
31+
<source>{3} assembly version '{1}' should be equal to {2} version '{0}'.</source>
32+
<target state="new">{3} assembly version '{1}' should be equal to {2} version '{0}'.</target>
33+
<note />
34+
</trans-unit>
35+
<trans-unit id="AssembyVersionIsNotCompatible">
36+
<source>{2} assembly version '{0}' should be equal to or higher than {3} version '{1}'.</source>
37+
<target state="new">{2} assembly version '{0}' should be equal to or higher than {3} version '{1}'.</target>
38+
<note />
39+
</trans-unit>
1040
<trans-unit id="CannotAddAbstractMember">
1141
<source>Cannot add abstract member '{0}' to {1} because does not exist on {2}</source>
1242
<target state="new">Cannot add abstract member '{0}' to {1} because does not exist on {2}</target>

src/Compatibility/Microsoft.DotNet.ApiCompatibility/xlf/Resources.fr.xlf

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,41 @@
22
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
33
<file datatype="xml" source-language="en" target-language="fr" original="../Resources.resx">
44
<body>
5+
<trans-unit id="AssemblyNameDoesNotExist">
6+
<source>Assembly with name '{0}' does not exist at {1}.</source>
7+
<target state="new">Assembly with name '{0}' does not exist at {1}.</target>
8+
<note />
9+
</trans-unit>
10+
<trans-unit id="AssemblyNameDoesNotMatch">
11+
<source>{2} assembly name '{0}' does not match with {3} assembly name '{1}'.</source>
12+
<target state="new">{2} assembly name '{0}' does not match with {3} assembly name '{1}'.</target>
13+
<note />
14+
</trans-unit>
15+
<trans-unit id="AssemblyPublicKeyTokenDoesNotMatch">
16+
<source>{2} assembly token '{0}' does not match with {3} '{1}'.</source>
17+
<target state="new">{2} assembly token '{0}' does not match with {3} '{1}'.</target>
18+
<note />
19+
</trans-unit>
520
<trans-unit id="AssemblySearchDirectoryDoesNotExist">
621
<source>Provided assembly search directory '{0}' does not exist.</source>
722
<target state="new">Provided assembly search directory '{0}' does not exist.</target>
823
<note />
924
</trans-unit>
25+
<trans-unit id="AssembyCultureDoesNotMatch">
26+
<source>{2} assembly culture '{0}' does not match with {3} assembly culture '{1}'.</source>
27+
<target state="new">{2} assembly culture '{0}' does not match with {3} assembly culture '{1}'.</target>
28+
<note />
29+
</trans-unit>
30+
<trans-unit id="AssembyVersionDoesNotMatch">
31+
<source>{3} assembly version '{1}' should be equal to {2} version '{0}'.</source>
32+
<target state="new">{3} assembly version '{1}' should be equal to {2} version '{0}'.</target>
33+
<note />
34+
</trans-unit>
35+
<trans-unit id="AssembyVersionIsNotCompatible">
36+
<source>{2} assembly version '{0}' should be equal to or higher than {3} version '{1}'.</source>
37+
<target state="new">{2} assembly version '{0}' should be equal to or higher than {3} version '{1}'.</target>
38+
<note />
39+
</trans-unit>
1040
<trans-unit id="CannotAddAbstractMember">
1141
<source>Cannot add abstract member '{0}' to {1} because does not exist on {2}</source>
1242
<target state="new">Cannot add abstract member '{0}' to {1} because does not exist on {2}</target>

0 commit comments

Comments
 (0)