diff --git a/restore.sh b/restore.sh old mode 100644 new mode 100755 diff --git a/src/PublicApiAnalyzers/Core/Analyzers/AnalyzerReleases.Unshipped.md b/src/PublicApiAnalyzers/Core/Analyzers/AnalyzerReleases.Unshipped.md index cdf4f1397e..e4fc9a28de 100644 --- a/src/PublicApiAnalyzers/Core/Analyzers/AnalyzerReleases.Unshipped.md +++ b/src/PublicApiAnalyzers/Core/Analyzers/AnalyzerReleases.Unshipped.md @@ -1 +1,17 @@ ; Please do not edit this file manually, it should only be updated through code fix application. + +### New Rules + +Rule ID | Category | Severity | Notes +--------|----------|----------|------- +RS0051 | ApiDesign | Disabled | DeclarePublicApiAnalyzer, [Documentation](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md) +RS0052 | ApiDesign | Disabled | DeclarePublicApiAnalyzer, [Documentation](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md) +RS0053 | ApiDesign | Disabled | DeclarePublicApiAnalyzer, [Documentation](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md) +RS0054 | ApiDesign | Disabled | DeclarePublicApiAnalyzer, [Documentation](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md) +RS0055 | ApiDesign | Disabled | DeclarePublicApiAnalyzer, [Documentation](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md) +RS0056 | ApiDesign | Disabled | DeclarePublicApiAnalyzer, [Documentation](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md) +RS0057 | ApiDesign | Disabled | DeclarePublicApiAnalyzer, [Documentation](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md) +RS0058 | ApiDesign | Disabled | DeclarePublicApiAnalyzer, [Documentation](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md) +RS0059 | ApiDesign | Disabled | DeclarePublicApiAnalyzer, [Documentation](https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md) +RS0060 | ApiDesign | Disabled | DeclarePublicApiAnalyzer, [Documentation](https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md) +RS0061 | ApiDesign | Disabled | DeclarePublicApiAnalyzer, [Documentation](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md) diff --git a/src/PublicApiAnalyzers/Core/Analyzers/DeclarePublicApiAnalyzer.Impl.cs b/src/PublicApiAnalyzers/Core/Analyzers/DeclarePublicApiAnalyzer.Impl.cs index 5a939f5662..03056fb63d 100644 --- a/src/PublicApiAnalyzers/Core/Analyzers/DeclarePublicApiAnalyzer.Impl.cs +++ b/src/PublicApiAnalyzers/Core/Analyzers/DeclarePublicApiAnalyzer.Impl.cs @@ -92,11 +92,12 @@ private static readonly ImmutableArray s_ignorableMethodKinds private readonly Compilation _compilation; private readonly ApiData _unshippedData; private readonly bool _useNullability; - private readonly ConcurrentDictionary _typeCanBeExtendedCache = new(); + private readonly bool _isPublic; + private readonly ConcurrentDictionary<(ITypeSymbol Type, bool IsPublic), bool> _typeCanBeExtendedCache = new(); private readonly ConcurrentDictionary _visitedApiList = new(StringComparer.Ordinal); - private readonly IReadOnlyDictionary _publicApiMap; + private readonly IReadOnlyDictionary _apiMap; - internal Impl(Compilation compilation, ApiData shippedData, ApiData unshippedData) + internal Impl(Compilation compilation, ApiData shippedData, ApiData unshippedData, bool isPublic) { _compilation = compilation; _useNullability = shippedData.NullableRank >= 0 || unshippedData.NullableRank >= 0; @@ -113,7 +114,8 @@ internal Impl(Compilation compilation, ApiData shippedData, ApiData unshippedDat publicApiMap.Add(cur.Text, cur); } - _publicApiMap = publicApiMap; + _apiMap = publicApiMap; + _isPublic = isPublic; } internal void OnSymbolAction(SymbolAnalysisContext symbolContext) @@ -155,7 +157,7 @@ private void CheckPropertyAccessor(SymbolAnalysisContext symbolContext, IMethodS return; } - if (!this.IsPublicAPI(accessor)) + if (!this.IsTrackedAPI(accessor)) { return; } @@ -170,7 +172,7 @@ private void CheckPropertyAccessor(SymbolAnalysisContext symbolContext, IMethodS /// the location of the symbol will be used. private void OnSymbolActionCore(ISymbol symbol, Action reportDiagnostic, INamedTypeSymbol? obsoleteAttribute, Location? explicitLocation = null) { - if (!IsPublicAPI(symbol)) + if (!IsTrackedAPI(symbol)) { return; } @@ -206,9 +208,9 @@ private static string WithObliviousMarker(string name) /// the location of the symbol will be used. private void OnSymbolActionCore(ISymbol symbol, Action reportDiagnostic, bool isImplicitlyDeclaredConstructor, INamedTypeSymbol? obsoleteAttribute, Location? explicitLocation = null) { - Debug.Assert(IsPublicAPI(symbol)); + Debug.Assert(IsTrackedAPI(symbol)); - ApiName publicApiName = GetPublicApiName(symbol); + ApiName publicApiName = GetApiName(symbol); _visitedApiList.TryAdd(publicApiName.Name, default); _visitedApiList.TryAdd(WithObliviousMarker(publicApiName.Name), default); _visitedApiList.TryAdd(publicApiName.NameWithNullability, default); @@ -236,22 +238,22 @@ private void OnSymbolActionCore(ISymbol symbol, Action reportDiagnos reportObliviousApi(symbol); } - var hasPublicApiEntryWithNullability = _publicApiMap.TryGetValue(publicApiName.NameWithNullability, out foundApiLine); + var hasApiEntryWithNullability = _apiMap.TryGetValue(publicApiName.NameWithNullability, out foundApiLine); - var hasPublicApiEntryWithNullabilityAndOblivious = - !hasPublicApiEntryWithNullability && + var hasApiEntryWithNullabilityAndOblivious = + !hasApiEntryWithNullability && symbolUsesOblivious && - _publicApiMap.TryGetValue(WithObliviousMarker(publicApiName.NameWithNullability), out foundApiLine); + _apiMap.TryGetValue(WithObliviousMarker(publicApiName.NameWithNullability), out foundApiLine); - if (!hasPublicApiEntryWithNullability && !hasPublicApiEntryWithNullabilityAndOblivious) + if (!hasApiEntryWithNullability && !hasApiEntryWithNullabilityAndOblivious) { - var hasPublicApiEntryWithoutNullability = _publicApiMap.TryGetValue(publicApiName.Name, out foundApiLine); + var hasApiEntryWithoutNullability = _apiMap.TryGetValue(publicApiName.Name, out foundApiLine); - var hasPublicApiEntryWithoutNullabilityButOblivious = - !hasPublicApiEntryWithoutNullability && - _publicApiMap.TryGetValue(WithObliviousMarker(publicApiName.Name), out foundApiLine); + var hasApiEntryWithoutNullabilityButOblivious = + !hasApiEntryWithoutNullability && + _apiMap.TryGetValue(WithObliviousMarker(publicApiName.Name), out foundApiLine); - if (!hasPublicApiEntryWithoutNullability && !hasPublicApiEntryWithoutNullabilityButOblivious) + if (!hasApiEntryWithoutNullability && !hasApiEntryWithoutNullabilityButOblivious) { reportDeclareNewApi(symbol, isImplicitlyDeclaredConstructor, withObliviousIfNeeded(publicApiName.NameWithNullability)); } @@ -260,15 +262,15 @@ private void OnSymbolActionCore(ISymbol symbol, Action reportDiagnos reportAnnotateApi(symbol, isImplicitlyDeclaredConstructor, publicApiName, foundApiLine.IsShippedApi, foundApiLine.Path); } } - else if (hasPublicApiEntryWithNullability && symbolUsesOblivious) + else if (hasApiEntryWithNullability && symbolUsesOblivious) { reportAnnotateApi(symbol, isImplicitlyDeclaredConstructor, publicApiName, foundApiLine.IsShippedApi, foundApiLine.Path); } } else { - var hasPublicApiEntryWithoutNullability = _publicApiMap.TryGetValue(publicApiName.Name, out foundApiLine); - if (!hasPublicApiEntryWithoutNullability) + var hasApiEntryWithoutNullability = _apiMap.TryGetValue(publicApiName.Name, out foundApiLine); + if (!hasApiEntryWithoutNullability) { reportDeclareNewApi(symbol, isImplicitlyDeclaredConstructor, publicApiName.Name); } @@ -276,7 +278,7 @@ private void OnSymbolActionCore(ISymbol symbol, Action reportDiagnos if (publicApiName.Name != publicApiName.NameWithNullability) { // '#nullable enable' would be useful and should be set - reportDiagnosticAtLocations(ShouldAnnotateApiFilesRule, ImmutableDictionary.Empty); + reportDiagnosticAtLocations(GetDiagnostic(ShouldAnnotatePublicApiFilesRule, ShouldAnnotateInternalApiFilesRule), ImmutableDictionary.Empty); } } @@ -293,13 +295,13 @@ private void OnSymbolActionCore(ISymbol symbol, Action reportDiagnos method.ContainingType.TypeKind == TypeKind.Class && !method.ContainingType.IsSealed && method.ContainingType.BaseType != null && - IsPublicApiCore(method.ContainingType.BaseType) && - !CanTypeBeExtendedPublicly(method.ContainingType.BaseType)) + IsTrackedApiCore(method.ContainingType.BaseType) && + !CanTypeBeExtended(method.ContainingType.BaseType)) { string errorMessageName = GetErrorMessageName(method, isImplicitlyDeclaredConstructor); ImmutableDictionary propertyBag = ImmutableDictionary.Empty; var locations = isImplicitlyDeclaredConstructor ? method.ContainingType.Locations : method.Locations; - reportDiagnostic(Diagnostic.Create(ExposedNoninstantiableType, locations[0], propertyBag, errorMessageName)); + reportDiagnostic(Diagnostic.Create(GetDiagnostic(ExposedNoninstantiableTypePublic, ExposedNoninstantiableTypeInternal), locations[0], propertyBag, errorMessageName)); } // Flag public API with optional parameters that violate backcompat requirements: https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md. @@ -307,7 +309,9 @@ private void OnSymbolActionCore(ISymbol symbol, Action reportDiagnos { foreach (var overload in method.GetOverloads()) { - if (!IsPublicAPI(overload)) + var symbolAccessibility = overload.GetResultantVisibility(); + var minAccessibility = _isPublic ? SymbolVisibility.Public : SymbolVisibility.Internal; + if (symbolAccessibility > minAccessibility) { continue; } @@ -331,7 +335,8 @@ private void OnSymbolActionCore(ISymbol symbol, Action reportDiagnos if (overloadHasOptionalParams && !isMethodShippedApi) { string errorMessageName = GetErrorMessageName(method, isImplicitlyDeclaredConstructor); - reportDiagnosticAtLocations(AvoidMultipleOverloadsWithOptionalParameters, ImmutableDictionary.Empty, errorMessageName, AvoidMultipleOverloadsWithOptionalParameters.HelpLinkUri); + var diagnostic = GetDiagnostic(AvoidMultipleOverloadsWithOptionalParametersPublic, AvoidMultipleOverloadsWithOptionalParametersInternal); + reportDiagnosticAtLocations(diagnostic, ImmutableDictionary.Empty, errorMessageName, diagnostic.HelpLinkUri); break; } @@ -343,18 +348,20 @@ private void OnSymbolActionCore(ISymbol symbol, Action reportDiagnos if (!isMethodShippedApi) { string errorMessageName = GetErrorMessageName(method, isImplicitlyDeclaredConstructor); - reportDiagnosticAtLocations(OverloadWithOptionalParametersShouldHaveMostParameters, ImmutableDictionary.Empty, errorMessageName, OverloadWithOptionalParametersShouldHaveMostParameters.HelpLinkUri); + var diagnostic = GetDiagnostic(OverloadWithOptionalParametersShouldHaveMostParametersPublic, OverloadWithOptionalParametersShouldHaveMostParametersInternal); + reportDiagnosticAtLocations(diagnostic, ImmutableDictionary.Empty, errorMessageName, diagnostic.HelpLinkUri); break; } else if (!overloadHasOptionalParams) { - var overloadPublicApiName = GetPublicApiName(overload); + var overloadPublicApiName = GetApiName(overload); var isOverloadUnshipped = !lookupPublicApi(overloadPublicApiName, out ApiLine overloadPublicApiLine) || !overloadPublicApiLine.IsShippedApi; if (isOverloadUnshipped) { string errorMessageName = GetErrorMessageName(method, isImplicitlyDeclaredConstructor); - reportDiagnosticAtLocations(OverloadWithOptionalParametersShouldHaveMostParameters, ImmutableDictionary.Empty, errorMessageName, OverloadWithOptionalParametersShouldHaveMostParameters.HelpLinkUri); + var diagnostic = GetDiagnostic(OverloadWithOptionalParametersShouldHaveMostParametersPublic, OverloadWithOptionalParametersShouldHaveMostParametersInternal); + reportDiagnosticAtLocations(diagnostic, ImmutableDictionary.Empty, errorMessageName, diagnostic.HelpLinkUri); break; } } @@ -388,11 +395,11 @@ void reportDeclareNewApi(ISymbol symbol, bool isImplicitlyDeclaredConstructor, s // Compute public API names for any stale siblings to remove from unshipped text (e.g. during signature change of unshipped public API). var siblingPublicApiNamesToRemove = GetSiblingNamesToRemoveFromUnshippedText(symbol); ImmutableDictionary propertyBag = ImmutableDictionary.Empty - .Add(PublicApiNamePropertyBagKey, publicApiName) + .Add(ApiNamePropertyBagKey, publicApiName) .Add(MinimalNamePropertyBagKey, errorMessageName) - .Add(PublicApiNamesOfSiblingsToRemovePropertyBagKey, siblingPublicApiNamesToRemove); + .Add(ApiNamesOfSiblingsToRemovePropertyBagKey, siblingPublicApiNamesToRemove); - reportDiagnosticAtLocations(DeclareNewApiRule, propertyBag, errorMessageName); + reportDiagnosticAtLocations(GetDiagnostic(DeclareNewPublicApiRule, DeclareNewInternalApiRule), propertyBag, errorMessageName); } void reportAnnotateApi(ISymbol symbol, bool isImplicitlyDeclaredConstructor, ApiName publicApiName, bool isShipped, string filename) @@ -400,13 +407,13 @@ void reportAnnotateApi(ISymbol symbol, bool isImplicitlyDeclaredConstructor, Api // Public API missing annotations in public API file - report diagnostic. string errorMessageName = GetErrorMessageName(symbol, isImplicitlyDeclaredConstructor); ImmutableDictionary propertyBag = ImmutableDictionary.Empty - .Add(PublicApiNamePropertyBagKey, publicApiName.Name) - .Add(PublicApiNameWithNullabilityPropertyBagKey, withObliviousIfNeeded(publicApiName.NameWithNullability)) + .Add(ApiNamePropertyBagKey, publicApiName.Name) + .Add(ApiNameWithNullabilityPropertyBagKey, withObliviousIfNeeded(publicApiName.NameWithNullability)) .Add(MinimalNamePropertyBagKey, errorMessageName) - .Add(PublicApiIsShippedPropertyBagKey, isShipped ? "true" : "false") + .Add(ApiIsShippedPropertyBagKey, isShipped ? "true" : "false") .Add(FileName, filename); - reportDiagnosticAtLocations(AnnotateApiRule, propertyBag, errorMessageName); + reportDiagnosticAtLocations(GetDiagnostic(AnnotatePublicApiRule, AnnotateInternalApiRule), propertyBag, errorMessageName); } string withObliviousIfNeeded(string name) @@ -419,20 +426,20 @@ void reportObliviousApi(ISymbol symbol) // Public API using oblivious types in public API file - report diagnostic. string errorMessageName = GetErrorMessageName(symbol, isImplicitlyDeclaredConstructor); - reportDiagnosticAtLocations(ObliviousApiRule, ImmutableDictionary.Empty, errorMessageName); + reportDiagnosticAtLocations(GetDiagnostic(ObliviousPublicApiRule, ObliviousInternalApiRule), ImmutableDictionary.Empty, errorMessageName); } bool lookupPublicApi(ApiName overloadPublicApiName, out ApiLine overloadPublicApiLine) { if (_useNullability) { - return _publicApiMap.TryGetValue(overloadPublicApiName.NameWithNullability, out overloadPublicApiLine) || - _publicApiMap.TryGetValue(WithObliviousMarker(overloadPublicApiName.NameWithNullability), out overloadPublicApiLine) || - _publicApiMap.TryGetValue(overloadPublicApiName.Name, out overloadPublicApiLine); + return _apiMap.TryGetValue(overloadPublicApiName.NameWithNullability, out overloadPublicApiLine) || + _apiMap.TryGetValue(WithObliviousMarker(overloadPublicApiName.NameWithNullability), out overloadPublicApiLine) || + _apiMap.TryGetValue(overloadPublicApiName.Name, out overloadPublicApiLine); } else { - return _publicApiMap.TryGetValue(overloadPublicApiName.Name, out overloadPublicApiLine); + return _apiMap.TryGetValue(overloadPublicApiName.Name, out overloadPublicApiLine); } } } @@ -444,14 +451,14 @@ symbol is IMethodSymbol methodSymbol && methodSymbol.AssociatedSymbol is IPropertySymbol property) { var formatString = symbol.Equals(property.GetMethod) - ? PublicApiAnalyzerResources.PublicImplicitGetAccessor - : PublicApiAnalyzerResources.PublicImplicitSetAccessor; + ? PublicApiAnalyzerResources.ImplicitGetAccessor + : PublicApiAnalyzerResources.ImplicitSetAccessor; return string.Format(CultureInfo.CurrentCulture, formatString, property.Name); } return isImplicitlyDeclaredConstructor ? - string.Format(CultureInfo.CurrentCulture, PublicApiAnalyzerResources.PublicImplicitConstructorErrorMessageName, symbol.ContainingSymbol.ToDisplayString(ShortSymbolNameFormat)) : + string.Format(CultureInfo.CurrentCulture, PublicApiAnalyzerResources.ImplicitConstructorErrorMessageName, symbol.ContainingSymbol.ToDisplayString(ShortSymbolNameFormat)) : symbol.ToDisplayString(ShortSymbolNameFormat); } @@ -477,36 +484,36 @@ private string GetSiblingNamesToRemoveFromUnshippedTextCore(ISymbol symbol) if (symbol.ContainingSymbol is INamespaceOrTypeSymbol containingSymbol) { // First get the lines in the unshipped text for siblings of the symbol: - // (a) Contains Public API name of containing symbol. - // (b) Doesn't contain Public API name of nested types/namespaces of containing symbol. - var containingSymbolPublicApiName = GetPublicApiName(containingSymbol); + // (a) Contains API name of containing symbol. + // (b) Doesn't contain API name of nested types/namespaces of containing symbol. + var containingSymbolApiName = GetApiName(containingSymbol); var nestedNamespaceOrTypeMembers = containingSymbol.GetMembers().OfType().ToImmutableArray(); - var nestedNamespaceOrTypesPublicApiNames = new List(nestedNamespaceOrTypeMembers.Length); + var nestedNamespaceOrTypesApiNames = new List(nestedNamespaceOrTypeMembers.Length); foreach (var nestedNamespaceOrType in nestedNamespaceOrTypeMembers) { - var nestedNamespaceOrTypePublicApiName = GetPublicApiName(nestedNamespaceOrType).Name; - nestedNamespaceOrTypesPublicApiNames.Add(nestedNamespaceOrTypePublicApiName); + var nestedNamespaceOrTypeApiName = GetApiName(nestedNamespaceOrType).Name; + nestedNamespaceOrTypesApiNames.Add(nestedNamespaceOrTypeApiName); } var publicApiLinesForSiblingsOfSymbol = new HashSet(); foreach (var apiLine in _unshippedData.ApiList) { var apiLineText = apiLine.Text; - if (apiLineText == containingSymbolPublicApiName.Name) + if (apiLineText == containingSymbolApiName.Name) { // Not a sibling of symbol. continue; } - if (!ContainsPublicApiName(apiLineText, containingSymbolPublicApiName.Name + ".")) + if (!ContainsPublicApiName(apiLineText, containingSymbolApiName.Name + ".")) { // Doesn't contain containingSymbol public API name - not a sibling of symbol. continue; } var containedInNestedMember = false; - foreach (var nestedNamespaceOrTypePublicApiName in nestedNamespaceOrTypesPublicApiNames) + foreach (var nestedNamespaceOrTypePublicApiName in nestedNamespaceOrTypesApiNames) { if (ContainsPublicApiName(apiLineText, nestedNamespaceOrTypePublicApiName + ".")) { @@ -537,19 +544,19 @@ private string GetSiblingNamesToRemoveFromUnshippedTextCore(ISymbol symbol) continue; } } - else if (!IsPublicAPI(sibling)) + else if (!IsTrackedAPI(sibling)) { continue; } - var siblingPublicApiName = GetPublicApiName(sibling); + var siblingPublicApiName = GetApiName(sibling); publicApiLinesForSiblingsOfSymbol.Remove(siblingPublicApiName.Name); publicApiLinesForSiblingsOfSymbol.Remove(siblingPublicApiName.NameWithNullability); publicApiLinesForSiblingsOfSymbol.Remove(WithObliviousMarker(siblingPublicApiName.NameWithNullability)); } // Join all the symbols names with a special separator. - return string.Join(PublicApiNamesOfSiblingsToRemovePropertyBagValueSeparator, publicApiLinesForSiblingsOfSymbol); + return string.Join(ApiNamesOfSiblingsToRemovePropertyBagValueSeparator, publicApiLinesForSiblingsOfSymbol); } } @@ -566,13 +573,13 @@ private static bool UsesOblivious(ISymbol symbol) return ObliviousDetector.Instance.Visit(symbol); } - private ApiName GetPublicApiName(ISymbol symbol) + private ApiName GetApiName(ISymbol symbol) { return new ApiName( - getPublicApiString(symbol, s_publicApiFormat), - getPublicApiString(symbol, s_publicApiFormatWithNullability)); + getApiString(symbol, s_publicApiFormat), + getApiString(symbol, s_publicApiFormatWithNullability)); - string getPublicApiString(ISymbol symbol, SymbolDisplayFormat format) + string getApiString(ISymbol symbol, SymbolDisplayFormat format) { string publicApiName = symbol.ToDisplayString(format); @@ -696,7 +703,7 @@ private void VisitForwardedTypeRecursively(ISymbol symbol, Action re /// internal void ReportDeletedApiList(Action reportDiagnostic) { - foreach (KeyValuePair pair in _publicApiMap) + foreach (KeyValuePair pair in _apiMap) { if (_visitedApiList.ContainsKey(pair.Key)) { @@ -709,8 +716,8 @@ internal void ReportDeletedApiList(Action reportDiagnostic) } Location location = GetLocationFromApiLine(pair.Value); - ImmutableDictionary propertyBag = ImmutableDictionary.Empty.Add(PublicApiNamePropertyBagKey, pair.Value.Text); - reportDiagnostic(Diagnostic.Create(RemoveDeletedApiRule, location, propertyBag, pair.Value.Text)); + ImmutableDictionary propertyBag = ImmutableDictionary.Empty.Add(ApiNamePropertyBagKey, pair.Value.Text); + reportDiagnostic(Diagnostic.Create(GetDiagnostic(RemoveDeletedPublicApiRule, RemoveDeletedInternalApiRule), location, propertyBag, pair.Value.Text)); } } @@ -735,7 +742,7 @@ private static Location GetLocationFromApiLine(ApiLine apiLine) return Location.Create(apiLine.Path, apiLine.Span, linePositionSpan); } - private bool IsPublicAPI(ISymbol symbol) + private bool IsTrackedAPI(ISymbol symbol) { if (symbol is IMethodSymbol methodSymbol && s_ignorableMethodKinds.Contains(methodSymbol.MethodKind)) { @@ -749,38 +756,62 @@ private bool IsPublicAPI(ISymbol symbol) return false; } - return IsPublicApiCore(symbol); + return IsTrackedApiCore(symbol); } - private bool IsPublicApiCore(ISymbol symbol) + private bool IsTrackedApiCore(ISymbol symbol) { - return symbol.DeclaredAccessibility switch - { - Accessibility.Public => symbol.ContainingType == null || IsPublicApiCore(symbol.ContainingType), - Accessibility.Protected - or Accessibility.ProtectedOrInternal => symbol.ContainingType != null - && IsPublicApiCore(symbol.ContainingType) - && CanTypeBeExtendedPublicly(symbol.ContainingType),// Protected symbols must have parent types (that is, top-level protected - // symbols are not allowed. - _ => false, - }; + var resultantVisibility = symbol.GetResultantVisibility(); + +#pragma warning disable IDE0047 // Remove unnecessary parentheses + if (resultantVisibility == SymbolVisibility.Private + || ((resultantVisibility == SymbolVisibility.Public) != _isPublic)) + { + return false; + } +#pragma warning restore IDE0047 // Remove unnecessary parentheses + + for (var current = symbol.ContainingType; current != null; current = current.ContainingType) + { + switch (current.DeclaredAccessibility) + { + case Accessibility.Protected: + case Accessibility.ProtectedOrInternal when _isPublic: + if (!CanTypeBeExtended(current)) + { + return false; + } + + break; + } + } + + return true; } - private bool CanTypeBeExtendedPublicly(ITypeSymbol type) + private bool CanTypeBeExtended(ITypeSymbol type) { - return _typeCanBeExtendedCache.GetOrAdd(type, CanTypeBeExtendedPubliclyImpl); + return _typeCanBeExtendedCache.GetOrAdd((type, _isPublic), CanTypeBeExtendedImpl); } - private static bool CanTypeBeExtendedPubliclyImpl(ITypeSymbol type) + private static bool CanTypeBeExtendedImpl((ITypeSymbol Type, bool IsPublic) key) { // a type can be extended publicly if (1) it isn't sealed, and (2) it has some constructor that is // not internal, private or protected&internal - return !type.IsSealed && - type.GetMembers(WellKnownMemberNames.InstanceConstructorName).Any( - m => m.DeclaredAccessibility is not Accessibility.Internal and not Accessibility.Private and not Accessibility.ProtectedAndInternal + return !key.Type.IsSealed && + key.Type.GetMembers(WellKnownMemberNames.InstanceConstructorName).Any( + m => m.DeclaredAccessibility switch + { + Accessibility.Internal or Accessibility.ProtectedAndInternal => !key.IsPublic, + Accessibility.Private => false, + _ => true, + } ); } + private DiagnosticDescriptor GetDiagnostic(DiagnosticDescriptor publicDiagnostic, DiagnosticDescriptor privateDiagnostic) + => _isPublic ? publicDiagnostic : privateDiagnostic; + /// /// Various Visit* methods return true if an oblivious reference type is detected. /// diff --git a/src/PublicApiAnalyzers/Core/Analyzers/DeclarePublicApiAnalyzer.cs b/src/PublicApiAnalyzers/Core/Analyzers/DeclarePublicApiAnalyzer.cs index d6eea8fd97..b27f7c4bb0 100644 --- a/src/PublicApiAnalyzers/Core/Analyzers/DeclarePublicApiAnalyzer.cs +++ b/src/PublicApiAnalyzers/Core/Analyzers/DeclarePublicApiAnalyzer.cs @@ -11,30 +11,30 @@ using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Text; -using DiagnosticIds = Roslyn.Diagnostics.Analyzers.RoslynDiagnosticIds; - namespace Microsoft.CodeAnalysis.PublicApiAnalyzers { - using static PublicApiAnalyzerResources; - [DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] public sealed partial class DeclarePublicApiAnalyzer : DiagnosticAnalyzer { - internal const string ShippedFileNamePrefix = "PublicAPI.Shipped"; - internal const string ShippedFileName = "PublicAPI.Shipped.txt"; - internal const string UnshippedFileNamePrefix = "PublicAPI.Unshipped"; internal const string Extension = ".txt"; - internal const string UnshippedFileName = UnshippedFileNamePrefix + Extension; - internal const string PublicApiNamePropertyBagKey = "PublicAPIName"; - internal const string PublicApiNameWithNullabilityPropertyBagKey = "PublicAPINameWithNullability"; + internal const string PublicShippedFileNamePrefix = "PublicAPI.Shipped"; + internal const string PublicShippedFileName = PublicShippedFileNamePrefix + Extension; + internal const string InternalShippedFileNamePrefix = "InternalAPI.Shipped"; + internal const string InternalShippedFileName = InternalShippedFileNamePrefix + Extension; + internal const string PublicUnshippedFileNamePrefix = "PublicAPI.Unshipped"; + internal const string PublicUnshippedFileName = PublicUnshippedFileNamePrefix + Extension; + internal const string InternalUnshippedFileNamePrefix = "InternalAPI.Unshipped"; + internal const string InternalUnshippedFileName = InternalUnshippedFileNamePrefix + Extension; + internal const string ApiNamePropertyBagKey = "APIName"; + internal const string ApiNameWithNullabilityPropertyBagKey = "APINameWithNullability"; internal const string MinimalNamePropertyBagKey = "MinimalName"; - internal const string PublicApiNamesOfSiblingsToRemovePropertyBagKey = "PublicApiNamesOfSiblingsToRemove"; - internal const string PublicApiNamesOfSiblingsToRemovePropertyBagValueSeparator = ";;"; + internal const string ApiNamesOfSiblingsToRemovePropertyBagKey = "ApiNamesOfSiblingsToRemove"; + internal const string ApiNamesOfSiblingsToRemovePropertyBagValueSeparator = ";;"; internal const string RemovedApiPrefix = "*REMOVED*"; internal const string NullableEnable = "#nullable enable"; internal const string InvalidReasonShippedCantHaveRemoved = "The shipped API file can't have removed members"; internal const string InvalidReasonMisplacedNullableEnable = "The '#nullable enable' marker can only appear as the first line in the shipped API file"; - internal const string PublicApiIsShippedPropertyBagKey = "PublicAPIIsShipped"; + internal const string ApiIsShippedPropertyBagKey = "APIIsShipped"; internal const string FileName = "FileName"; private const char ObliviousMarker = '~'; @@ -44,130 +44,6 @@ public sealed partial class DeclarePublicApiAnalyzer : DiagnosticAnalyzer /// private const string BailOnMissingPublicApiFilesEditorConfigOptionName = "dotnet_public_api_analyzer.require_api_files"; - internal static readonly DiagnosticDescriptor DeclareNewApiRule = new( - id: DiagnosticIds.DeclarePublicApiRuleId, - title: CreateLocalizableResourceString(nameof(DeclarePublicApiTitle)), - messageFormat: CreateLocalizableResourceString(nameof(DeclarePublicApiMessage)), - category: "ApiDesign", - defaultSeverity: DiagnosticSeverity.Warning, - isEnabledByDefault: true, - description: CreateLocalizableResourceString(nameof(DeclarePublicApiDescription)), - helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md", - customTags: WellKnownDiagnosticTagsExtensions.Telemetry); - - internal static readonly DiagnosticDescriptor AnnotateApiRule = new( - id: DiagnosticIds.AnnotatePublicApiRuleId, - title: CreateLocalizableResourceString(nameof(AnnotatePublicApiTitle)), - messageFormat: CreateLocalizableResourceString(nameof(AnnotatePublicApiMessage)), - category: "ApiDesign", - defaultSeverity: DiagnosticSeverity.Warning, - isEnabledByDefault: true, - description: CreateLocalizableResourceString(nameof(AnnotatePublicApiDescription)), - helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md", - customTags: WellKnownDiagnosticTagsExtensions.Telemetry); - - internal static readonly DiagnosticDescriptor ObliviousApiRule = new( - id: DiagnosticIds.ObliviousPublicApiRuleId, - title: CreateLocalizableResourceString(nameof(ObliviousPublicApiTitle)), - messageFormat: CreateLocalizableResourceString(nameof(ObliviousPublicApiMessage)), - category: "ApiDesign", - defaultSeverity: DiagnosticSeverity.Warning, - isEnabledByDefault: true, - description: CreateLocalizableResourceString(nameof(ObliviousPublicApiDescription)), - helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md", - customTags: WellKnownDiagnosticTagsExtensions.Telemetry); - - internal static readonly DiagnosticDescriptor RemoveDeletedApiRule = new( - id: DiagnosticIds.RemoveDeletedApiRuleId, - title: CreateLocalizableResourceString(nameof(RemoveDeletedApiTitle)), - messageFormat: CreateLocalizableResourceString(nameof(RemoveDeletedApiMessage)), - category: "ApiDesign", - defaultSeverity: DiagnosticSeverity.Warning, - isEnabledByDefault: true, - description: CreateLocalizableResourceString(nameof(RemoveDeletedApiDescription)), - helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md", - customTags: WellKnownDiagnosticTagsExtensions.CompilationEndAndTelemetry); - - internal static readonly DiagnosticDescriptor RemovedApiIsNotActuallyRemovedRule = new( - id: DiagnosticIds.RemovedApiIsNotActuallyRemovedRuleId, - title: CreateLocalizableResourceString(nameof(RemovedApiIsNotActuallyRemovedTitle)), - messageFormat: CreateLocalizableResourceString(nameof(RemovedApiIsNotActuallyRemovedMessage)), - category: "ApiDesign", - defaultSeverity: DiagnosticSeverity.Warning, - isEnabledByDefault: true, - helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md", - customTags: WellKnownDiagnosticTagsExtensions.CompilationEndAndTelemetry); - - internal static readonly DiagnosticDescriptor ExposedNoninstantiableType = new( - id: DiagnosticIds.ExposedNoninstantiableTypeRuleId, - title: CreateLocalizableResourceString(nameof(ExposedNoninstantiableTypeTitle)), - messageFormat: CreateLocalizableResourceString(nameof(ExposedNoninstantiableTypeMessage)), - category: "ApiDesign", - defaultSeverity: DiagnosticSeverity.Warning, - isEnabledByDefault: true, - helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md", - customTags: WellKnownDiagnosticTagsExtensions.Telemetry); - - internal static readonly DiagnosticDescriptor PublicApiFilesInvalid = new( - id: DiagnosticIds.PublicApiFilesInvalid, - title: CreateLocalizableResourceString(nameof(PublicApiFilesInvalidTitle)), - messageFormat: CreateLocalizableResourceString(nameof(PublicApiFilesInvalidMessage)), - category: "ApiDesign", - defaultSeverity: DiagnosticSeverity.Warning, - isEnabledByDefault: true, - helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md", - customTags: WellKnownDiagnosticTagsExtensions.CompilationEndAndTelemetry); - - internal static readonly DiagnosticDescriptor PublicApiFileMissing = new( - id: DiagnosticIds.PublicApiFileMissing, - title: CreateLocalizableResourceString(nameof(PublicApiFileMissingTitle)), - messageFormat: CreateLocalizableResourceString(nameof(PublicApiFileMissingMessage)), - category: "ApiDesign", - defaultSeverity: DiagnosticSeverity.Warning, - isEnabledByDefault: true, - helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md", - customTags: WellKnownDiagnosticTagsExtensions.CompilationEndAndTelemetry); - - internal static readonly DiagnosticDescriptor DuplicateSymbolInApiFiles = new( - id: DiagnosticIds.DuplicatedSymbolInPublicApiFiles, - title: CreateLocalizableResourceString(nameof(DuplicateSymbolsInPublicApiFilesTitle)), - messageFormat: CreateLocalizableResourceString(nameof(DuplicateSymbolsInPublicApiFilesMessage)), - category: "ApiDesign", - defaultSeverity: DiagnosticSeverity.Warning, - isEnabledByDefault: true, - helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md", - customTags: WellKnownDiagnosticTagsExtensions.CompilationEndAndTelemetry); - - internal static readonly DiagnosticDescriptor AvoidMultipleOverloadsWithOptionalParameters = new( - id: DiagnosticIds.AvoidMultipleOverloadsWithOptionalParameters, - title: CreateLocalizableResourceString(nameof(AvoidMultipleOverloadsWithOptionalParametersTitle)), - messageFormat: CreateLocalizableResourceString(nameof(AvoidMultipleOverloadsWithOptionalParametersMessage)), - category: "ApiDesign", - defaultSeverity: DiagnosticSeverity.Warning, - isEnabledByDefault: true, - helpLinkUri: @"https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md", - customTags: WellKnownDiagnosticTagsExtensions.Telemetry); - - internal static readonly DiagnosticDescriptor OverloadWithOptionalParametersShouldHaveMostParameters = new( - id: DiagnosticIds.OverloadWithOptionalParametersShouldHaveMostParameters, - title: CreateLocalizableResourceString(nameof(OverloadWithOptionalParametersShouldHaveMostParametersTitle)), - messageFormat: CreateLocalizableResourceString(nameof(OverloadWithOptionalParametersShouldHaveMostParametersMessage)), - category: "ApiDesign", - defaultSeverity: DiagnosticSeverity.Warning, - isEnabledByDefault: true, - helpLinkUri: @"https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md", - customTags: WellKnownDiagnosticTagsExtensions.Telemetry); - - internal static readonly DiagnosticDescriptor ShouldAnnotateApiFilesRule = new( - id: DiagnosticIds.ShouldAnnotateApiFilesRuleId, - title: CreateLocalizableResourceString(nameof(ShouldAnnotateApiFilesTitle)), - messageFormat: CreateLocalizableResourceString(nameof(ShouldAnnotateApiFilesMessage)), - category: "ApiDesign", - defaultSeverity: DiagnosticSeverity.Warning, - isEnabledByDefault: true, - description: CreateLocalizableResourceString(nameof(ShouldAnnotateApiFilesDescription)), - helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md", - customTags: WellKnownDiagnosticTagsExtensions.Telemetry); internal static readonly SymbolDisplayFormat ShortSymbolNameFormat = new( @@ -212,11 +88,6 @@ public sealed partial class DeclarePublicApiAnalyzer : DiagnosticAnalyzer (SymbolDisplayMiscellaneousOptions)IncludeNullableReferenceTypeModifier | (SymbolDisplayMiscellaneousOptions)IncludeNonNullableReferenceTypeModifier); - public override ImmutableArray SupportedDiagnostics { get; } = - ImmutableArray.Create(DeclareNewApiRule, AnnotateApiRule, ObliviousApiRule, RemoveDeletedApiRule, ExposedNoninstantiableType, - PublicApiFilesInvalid, PublicApiFileMissing, DuplicateSymbolInApiFiles, AvoidMultipleOverloadsWithOptionalParameters, - OverloadWithOptionalParametersShouldHaveMostParameters, ShouldAnnotateApiFilesRule, RemovedApiIsNotActuallyRemovedRule); - public override void Initialize(AnalysisContext context) { context.EnableConcurrentExecution(); @@ -230,10 +101,9 @@ public override void Initialize(AnalysisContext context) private void OnCompilationStart(CompilationStartAnalysisContext compilationContext) { var errors = new List(); - // Switch to "RegisterAdditionalFileAction" available in Microsoft.CodeAnalysis "3.8.x" to report additional file diagnostics: https://github.com/dotnet/roslyn-analyzers/issues/3918 - if (!TryGetApiData(compilationContext.Options, compilationContext.Compilation, errors, compilationContext.CancellationToken, out ApiData shippedData, out ApiData unshippedData) || - !ValidateApiFiles(shippedData, unshippedData, errors)) + if (!TryGetAndValidateApiFiles(compilationContext.Options, compilationContext.Compilation, isPublic: true, compilationContext.CancellationToken, errors, out ApiData publicShippedData, out ApiData publicUnshippedData) + || !TryGetAndValidateApiFiles(compilationContext.Options, compilationContext.Compilation, isPublic: false, compilationContext.CancellationToken, errors, out ApiData internalShippedData, out ApiData internalUnshippedData)) { compilationContext.RegisterCompilationEndAction(context => { @@ -248,17 +118,30 @@ private void OnCompilationStart(CompilationStartAnalysisContext compilationConte Debug.Assert(errors.Count == 0); - var impl = new Impl(compilationContext.Compilation, shippedData, unshippedData); - compilationContext.RegisterSymbolAction( - impl.OnSymbolAction, - SymbolKind.NamedType, - SymbolKind.Event, - SymbolKind.Field, - SymbolKind.Method); - compilationContext.RegisterSymbolAction( - impl.OnPropertyAction, - SymbolKind.Property); - compilationContext.RegisterCompilationEndAction(impl.OnCompilationEnd); + var publicImpl = new Impl(compilationContext.Compilation, publicShippedData, publicUnshippedData, isPublic: true); + var internalImpl = new Impl(compilationContext.Compilation, internalShippedData, internalUnshippedData, isPublic: false); + RegisterImplActions(compilationContext, publicImpl); + RegisterImplActions(compilationContext, internalImpl); + + static bool TryGetAndValidateApiFiles(AnalyzerOptions options, Compilation compilation, bool isPublic, CancellationToken cancellationToken, List errors, out ApiData shippedData, out ApiData unshippedData) + { + return TryGetApiData(options, compilation, isPublic, errors, cancellationToken, out shippedData, out unshippedData) + && ValidateApiFiles(shippedData, unshippedData, isPublic, errors); + } + + static void RegisterImplActions(CompilationStartAnalysisContext compilationContext, Impl impl) + { + compilationContext.RegisterSymbolAction( + impl.OnSymbolAction, + SymbolKind.NamedType, + SymbolKind.Event, + SymbolKind.Field, + SymbolKind.Method); + compilationContext.RegisterSymbolAction( + impl.OnPropertyAction, + SymbolKind.Property); + compilationContext.RegisterCompilationEndAction(impl.OnCompilationEnd); + } } private static ApiData ReadApiData(List<(string path, SourceText sourceText)> data, bool isShippedApi) @@ -303,9 +186,9 @@ private static ApiData ReadApiData(List<(string path, SourceText sourceText)> da return new ApiData(apiBuilder.ToImmutable(), removedBuilder.ToImmutable(), maxNullableRank); } - private static bool TryGetApiData(AnalyzerOptions analyzerOptions, Compilation compilation, List errors, CancellationToken cancellationToken, out ApiData shippedData, out ApiData unshippedData) + private static bool TryGetApiData(AnalyzerOptions analyzerOptions, Compilation compilation, bool isPublic, List errors, CancellationToken cancellationToken, out ApiData shippedData, out ApiData unshippedData) { - if (!TryGetApiText(analyzerOptions.AdditionalFiles, cancellationToken, out var shippedText, out var unshippedText)) + if (!TryGetApiText(analyzerOptions.AdditionalFiles, isPublic, cancellationToken, out var shippedText, out var unshippedText)) { if (shippedText == null && unshippedText == null) { @@ -322,8 +205,14 @@ private static bool TryGetApiData(AnalyzerOptions analyzerOptions, Compilation c return true; } - var missingFileName = shippedText == null ? ShippedFileName : UnshippedFileName; - errors.Add(Diagnostic.Create(PublicApiFileMissing, Location.None, missingFileName)); + var missingFileName = (shippedText, isPublic) switch + { + (shippedText: null, isPublic: true) => PublicShippedFileName, + (shippedText: null, isPublic: false) => InternalShippedFileName, + (shippedText: not null, isPublic: true) => PublicUnshippedFileName, + (shippedText: not null, isPublic: false) => InternalUnshippedFileName + }; + errors.Add(Diagnostic.Create(isPublic ? PublicApiFileMissing : InternalApiFileMissing, Location.None, missingFileName)); shippedData = default; unshippedData = default; return false; @@ -386,6 +275,7 @@ private static bool TryGetEditorConfigOptionForMissingFiles(AnalyzerOptions anal private static bool TryGetApiText( ImmutableArray additionalTexts, + bool isPublic, CancellationToken cancellationToken, [NotNullWhen(returnValue: true)] out List<(string path, SourceText text)>? shippedText, [NotNullWhen(returnValue: true)] out List<(string path, SourceText text)>? unshippedText) @@ -397,7 +287,7 @@ private static bool TryGetApiText( { cancellationToken.ThrowIfCancellationRequested(); - var file = new PublicApiFile(additionalText.Path); + var file = new PublicApiFile(additionalText.Path, isPublic); if (file.IsApiFile) { @@ -434,33 +324,34 @@ private static bool TryGetApiText( return shippedText != null && unshippedText != null; } - private static bool ValidateApiFiles(ApiData shippedData, ApiData unshippedData, List errors) + private static bool ValidateApiFiles(ApiData shippedData, ApiData unshippedData, bool isPublic, List errors) { + var descriptor = isPublic ? PublicApiFilesInvalid : InternalApiFilesInvalid; if (!shippedData.RemovedApiList.IsEmpty) { - errors.Add(Diagnostic.Create(PublicApiFilesInvalid, Location.None, InvalidReasonShippedCantHaveRemoved)); + errors.Add(Diagnostic.Create(descriptor, Location.None, InvalidReasonShippedCantHaveRemoved)); } if (shippedData.NullableRank > 0) { // '#nullable enable' must be on the first line - errors.Add(Diagnostic.Create(PublicApiFilesInvalid, Location.None, InvalidReasonMisplacedNullableEnable)); + errors.Add(Diagnostic.Create(descriptor, Location.None, InvalidReasonMisplacedNullableEnable)); } if (unshippedData.NullableRank > 0) { // '#nullable enable' must be on the first line - errors.Add(Diagnostic.Create(PublicApiFilesInvalid, Location.None, InvalidReasonMisplacedNullableEnable)); + errors.Add(Diagnostic.Create(descriptor, Location.None, InvalidReasonMisplacedNullableEnable)); } var publicApiMap = new Dictionary(StringComparer.Ordinal); - ValidateApiList(publicApiMap, shippedData.ApiList, errors); - ValidateApiList(publicApiMap, unshippedData.ApiList, errors); + ValidateApiList(publicApiMap, shippedData.ApiList, isPublic, errors); + ValidateApiList(publicApiMap, unshippedData.ApiList, isPublic, errors); return errors.Count == 0; } - private static void ValidateApiList(Dictionary publicApiMap, ImmutableArray apiList, List errors) + private static void ValidateApiList(Dictionary publicApiMap, ImmutableArray apiList, bool isPublic, List errors) { foreach (ApiLine cur in apiList) { @@ -472,7 +363,7 @@ private static void ValidateApiList(Dictionary publicApiMap, Im LinePositionSpan duplicateLinePositionSpan = cur.SourceText.Lines.GetLinePositionSpan(cur.Span); Location duplicateLocation = Location.Create(cur.Path, cur.Span, duplicateLinePositionSpan); - errors.Add(Diagnostic.Create(DuplicateSymbolInApiFiles, duplicateLocation, new[] { existingLocation }, cur.Text)); + errors.Add(Diagnostic.Create(isPublic ? DuplicateSymbolInPublicApiFiles : DuplicateSymbolInInternalApiFiles, duplicateLocation, new[] { existingLocation }, cur.Text)); } else { diff --git a/src/PublicApiAnalyzers/Core/Analyzers/DeclarePublicApiAnalyzer_Diagnostics.cs b/src/PublicApiAnalyzers/Core/Analyzers/DeclarePublicApiAnalyzer_Diagnostics.cs new file mode 100644 index 0000000000..386a2220cd --- /dev/null +++ b/src/PublicApiAnalyzers/Core/Analyzers/DeclarePublicApiAnalyzer_Diagnostics.cs @@ -0,0 +1,278 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. + +using System.Collections.Immutable; +using DiagnosticIds = Roslyn.Diagnostics.Analyzers.RoslynDiagnosticIds; + +namespace Microsoft.CodeAnalysis.PublicApiAnalyzers +{ + using static PublicApiAnalyzerResources; + + public partial class DeclarePublicApiAnalyzer + { + internal static readonly DiagnosticDescriptor DeclareNewPublicApiRule = new( + id: DiagnosticIds.DeclarePublicApiRuleId, + title: CreateLocalizableResourceString(nameof(DeclarePublicApiTitle)), + messageFormat: CreateLocalizableResourceString(nameof(DeclarePublicApiMessage)), + category: "ApiDesign", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: true, + description: CreateLocalizableResourceString(nameof(DeclarePublicApiDescription)), + helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md", + customTags: WellKnownDiagnosticTagsExtensions.Telemetry); + + internal static readonly DiagnosticDescriptor DeclareNewInternalApiRule = new( + id: DiagnosticIds.DeclareInternalApiRuleId, + title: CreateLocalizableResourceString(nameof(DeclareInternalApiTitle)), + messageFormat: CreateLocalizableResourceString(nameof(DeclareInternalApiMessage)), + category: "ApiDesign", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: false, + description: CreateLocalizableResourceString(nameof(DeclarePublicApiDescription)), + helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md", + customTags: WellKnownDiagnosticTagsExtensions.Telemetry); + + internal static readonly DiagnosticDescriptor AnnotatePublicApiRule = new( + id: DiagnosticIds.AnnotatePublicApiRuleId, + title: CreateLocalizableResourceString(nameof(AnnotatePublicApiTitle)), + messageFormat: CreateLocalizableResourceString(nameof(AnnotatePublicApiMessage)), + category: "ApiDesign", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: true, + description: CreateLocalizableResourceString(nameof(AnnotatePublicApiDescription)), + helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md", + customTags: WellKnownDiagnosticTagsExtensions.Telemetry); + + internal static readonly DiagnosticDescriptor AnnotateInternalApiRule = new( + id: DiagnosticIds.AnnotateInternalApiRuleId, + title: CreateLocalizableResourceString(nameof(AnnotateInternalApiTitle)), + messageFormat: CreateLocalizableResourceString(nameof(AnnotateInternalApiMessage)), + category: "ApiDesign", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: false, + description: CreateLocalizableResourceString(nameof(AnnotateInternalApiDescription)), + helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/InternalApiAnalyzers/InternalApiAnalyzers.Help.md", + customTags: WellKnownDiagnosticTagsExtensions.Telemetry); + + internal static readonly DiagnosticDescriptor ObliviousPublicApiRule = new( + id: DiagnosticIds.ObliviousPublicApiRuleId, + title: CreateLocalizableResourceString(nameof(ObliviousPublicApiTitle)), + messageFormat: CreateLocalizableResourceString(nameof(ObliviousPublicApiMessage)), + category: "ApiDesign", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: true, + description: CreateLocalizableResourceString(nameof(ObliviousPublicApiDescription)), + helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md", + customTags: WellKnownDiagnosticTagsExtensions.Telemetry); + + internal static readonly DiagnosticDescriptor ObliviousInternalApiRule = new( + id: DiagnosticIds.ObliviousInternalApiRuleId, + title: CreateLocalizableResourceString(nameof(ObliviousInternalApiTitle)), + messageFormat: CreateLocalizableResourceString(nameof(ObliviousInternalApiMessage)), + category: "ApiDesign", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: false, + description: CreateLocalizableResourceString(nameof(ObliviousInternalApiDescription)), + helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/InternalApiAnalyzers/InternalApiAnalyzers.Help.md", + customTags: WellKnownDiagnosticTagsExtensions.Telemetry); + + internal static readonly DiagnosticDescriptor RemoveDeletedPublicApiRule = new( + id: DiagnosticIds.RemoveDeletedPublicApiRuleId, + title: CreateLocalizableResourceString(nameof(RemoveDeletedPublicApiTitle)), + messageFormat: CreateLocalizableResourceString(nameof(RemoveDeletedPublicApiMessage)), + category: "ApiDesign", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: true, + description: CreateLocalizableResourceString(nameof(RemoveDeletedPublicApiDescription)), + helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md", + customTags: WellKnownDiagnosticTagsExtensions.CompilationEndAndTelemetry); + + internal static readonly DiagnosticDescriptor RemoveDeletedInternalApiRule = new( + id: DiagnosticIds.RemoveDeletedInternalApiRuleId, + title: CreateLocalizableResourceString(nameof(RemoveDeletedInternalApiTitle)), + messageFormat: CreateLocalizableResourceString(nameof(RemoveDeletedInternalApiMessage)), + category: "ApiDesign", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: false, + description: CreateLocalizableResourceString(nameof(RemoveDeletedInternalApiDescription)), + helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/InternalApiAnalyzers/InternalApiAnalyzers.Help.md", + customTags: WellKnownDiagnosticTagsExtensions.CompilationEndAndTelemetry); + + internal static readonly DiagnosticDescriptor RemovedApiIsNotActuallyRemovedRule = new( + id: DiagnosticIds.RemovedApiIsNotActuallyRemovedRuleId, + title: CreateLocalizableResourceString(nameof(RemovedApiIsNotActuallyRemovedTitle)), + messageFormat: CreateLocalizableResourceString(nameof(RemovedApiIsNotActuallyRemovedMessage)), + category: "ApiDesign", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: true, + helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md", + customTags: WellKnownDiagnosticTagsExtensions.CompilationEndAndTelemetry); + + internal static readonly DiagnosticDescriptor ExposedNoninstantiableTypePublic = new( + id: DiagnosticIds.ExposedNoninstantiableTypeRuleIdPublic, + title: CreateLocalizableResourceString(nameof(ExposedNoninstantiableTypeTitle)), + messageFormat: CreateLocalizableResourceString(nameof(ExposedNoninstantiableTypeMessage)), + category: "ApiDesign", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: true, + helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md", + customTags: WellKnownDiagnosticTagsExtensions.Telemetry); + + internal static readonly DiagnosticDescriptor ExposedNoninstantiableTypeInternal = new( + id: DiagnosticIds.ExposedNoninstantiableTypeRuleIdInternal, + title: CreateLocalizableResourceString(nameof(ExposedNoninstantiableTypeTitle)), + messageFormat: CreateLocalizableResourceString(nameof(ExposedNoninstantiableTypeMessage)), + category: "ApiDesign", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: false, + helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md", + customTags: WellKnownDiagnosticTagsExtensions.Telemetry); + + internal static readonly DiagnosticDescriptor PublicApiFilesInvalid = new( + id: DiagnosticIds.PublicApiFilesInvalid, + title: CreateLocalizableResourceString(nameof(PublicApiFilesInvalidTitle)), + messageFormat: CreateLocalizableResourceString(nameof(PublicApiFilesInvalidMessage)), + category: "ApiDesign", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: true, + helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md", + customTags: WellKnownDiagnosticTagsExtensions.CompilationEndAndTelemetry); + + internal static readonly DiagnosticDescriptor InternalApiFilesInvalid = new( + id: DiagnosticIds.InternalApiFilesInvalid, + title: CreateLocalizableResourceString(nameof(InternalApiFilesInvalidTitle)), + messageFormat: CreateLocalizableResourceString(nameof(InternalApiFilesInvalidMessage)), + category: "ApiDesign", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: false, + helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/InternalApiAnalyzers/InternalApiAnalyzers.Help.md", + customTags: WellKnownDiagnosticTagsExtensions.CompilationEndAndTelemetry); + + internal static readonly DiagnosticDescriptor PublicApiFileMissing = new( + id: DiagnosticIds.PublicApiFileMissing, + title: CreateLocalizableResourceString(nameof(PublicApiFileMissingTitle)), + messageFormat: CreateLocalizableResourceString(nameof(PublicApiFileMissingMessage)), + category: "ApiDesign", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: true, + helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md", + customTags: WellKnownDiagnosticTagsExtensions.CompilationEndAndTelemetry); + + internal static readonly DiagnosticDescriptor InternalApiFileMissing = new( + id: DiagnosticIds.InternalApiFileMissing, + title: CreateLocalizableResourceString(nameof(InternalApiFileMissingTitle)), + messageFormat: CreateLocalizableResourceString(nameof(InternalApiFileMissingMessage)), + category: "ApiDesign", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: false, + helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/InternalApiAnalyzers/InternalApiAnalyzers.Help.md", + customTags: WellKnownDiagnosticTagsExtensions.CompilationEndAndTelemetry); + + internal static readonly DiagnosticDescriptor DuplicateSymbolInPublicApiFiles = new( + id: DiagnosticIds.DuplicatedSymbolInPublicApiFiles, + title: CreateLocalizableResourceString(nameof(DuplicateSymbolsInPublicApiFilesTitle)), + messageFormat: CreateLocalizableResourceString(nameof(DuplicateSymbolsInPublicApiFilesMessage)), + category: "ApiDesign", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: true, + helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md", + customTags: WellKnownDiagnosticTagsExtensions.CompilationEndAndTelemetry); + + internal static readonly DiagnosticDescriptor DuplicateSymbolInInternalApiFiles = new( + id: DiagnosticIds.DuplicatedSymbolInInternalApiFiles, + title: CreateLocalizableResourceString(nameof(DuplicateSymbolsInInternalApiFilesTitle)), + messageFormat: CreateLocalizableResourceString(nameof(DuplicateSymbolsInInternalApiFilesMessage)), + category: "ApiDesign", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: false, + helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/InternalApiAnalyzers/InternalApiAnalyzers.Help.md", + customTags: WellKnownDiagnosticTagsExtensions.CompilationEndAndTelemetry); + + internal static readonly DiagnosticDescriptor AvoidMultipleOverloadsWithOptionalParametersPublic = new( + id: DiagnosticIds.AvoidMultipleOverloadsWithOptionalParametersPublic, + title: CreateLocalizableResourceString(nameof(AvoidMultipleOverloadsWithOptionalParametersTitle)), + messageFormat: CreateLocalizableResourceString(nameof(AvoidMultipleOverloadsWithOptionalParametersMessage)), + category: "ApiDesign", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: true, + helpLinkUri: @"https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md", + customTags: WellKnownDiagnosticTagsExtensions.Telemetry); + + internal static readonly DiagnosticDescriptor AvoidMultipleOverloadsWithOptionalParametersInternal = new( + id: DiagnosticIds.AvoidMultipleOverloadsWithOptionalParametersInternal, + title: CreateLocalizableResourceString(nameof(AvoidMultipleOverloadsWithOptionalParametersTitle)), + messageFormat: CreateLocalizableResourceString(nameof(AvoidMultipleOverloadsWithOptionalParametersMessage)), + category: "ApiDesign", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: false, + helpLinkUri: @"https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md", + customTags: WellKnownDiagnosticTagsExtensions.Telemetry); + + internal static readonly DiagnosticDescriptor OverloadWithOptionalParametersShouldHaveMostParametersPublic = new( + id: DiagnosticIds.OverloadWithOptionalParametersShouldHaveMostParametersPublic, + title: CreateLocalizableResourceString(nameof(OverloadWithOptionalParametersShouldHaveMostParametersTitle)), + messageFormat: CreateLocalizableResourceString(nameof(OverloadWithOptionalParametersShouldHaveMostParametersMessage)), + category: "ApiDesign", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: true, + helpLinkUri: @"https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md", + customTags: WellKnownDiagnosticTagsExtensions.Telemetry); + + internal static readonly DiagnosticDescriptor OverloadWithOptionalParametersShouldHaveMostParametersInternal = new( + id: DiagnosticIds.OverloadWithOptionalParametersShouldHaveMostParametersInternal, + title: CreateLocalizableResourceString(nameof(OverloadWithOptionalParametersShouldHaveMostParametersTitle)), + messageFormat: CreateLocalizableResourceString(nameof(OverloadWithOptionalParametersShouldHaveMostParametersMessage)), + category: "ApiDesign", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: false, + helpLinkUri: @"https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md", + customTags: WellKnownDiagnosticTagsExtensions.Telemetry); + + internal static readonly DiagnosticDescriptor ShouldAnnotatePublicApiFilesRule = new( + id: DiagnosticIds.ShouldAnnotatePublicApiFilesRuleId, + title: CreateLocalizableResourceString(nameof(ShouldAnnotatePublicApiFilesTitle)), + messageFormat: CreateLocalizableResourceString(nameof(ShouldAnnotatePublicApiFilesMessage)), + category: "ApiDesign", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: true, + description: CreateLocalizableResourceString(nameof(ShouldAnnotatePublicApiFilesDescription)), + helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md", + customTags: WellKnownDiagnosticTagsExtensions.Telemetry); + + internal static readonly DiagnosticDescriptor ShouldAnnotateInternalApiFilesRule = new( + id: DiagnosticIds.ShouldAnnotateInternalApiFilesRuleId, + title: CreateLocalizableResourceString(nameof(ShouldAnnotateInternalApiFilesTitle)), + messageFormat: CreateLocalizableResourceString(nameof(ShouldAnnotateInternalApiFilesMessage)), + category: "ApiDesign", + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: false, + description: CreateLocalizableResourceString(nameof(ShouldAnnotatePublicApiFilesDescription)), + helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/main/src/InternalApiAnalyzers/InternalApiAnalyzers.Help.md", + customTags: WellKnownDiagnosticTagsExtensions.Telemetry); + + public override ImmutableArray SupportedDiagnostics { get; } = + ImmutableArray.Create( + DeclareNewPublicApiRule, + DeclareNewInternalApiRule, + AnnotatePublicApiRule, + AnnotateInternalApiRule, + ObliviousPublicApiRule, + ObliviousInternalApiRule, + RemoveDeletedPublicApiRule, + RemoveDeletedInternalApiRule, + ExposedNoninstantiableTypePublic, + ExposedNoninstantiableTypeInternal, + PublicApiFilesInvalid, + InternalApiFilesInvalid, + PublicApiFileMissing, + InternalApiFileMissing, + DuplicateSymbolInPublicApiFiles, + DuplicateSymbolInInternalApiFiles, + AvoidMultipleOverloadsWithOptionalParametersPublic, + AvoidMultipleOverloadsWithOptionalParametersInternal, + OverloadWithOptionalParametersShouldHaveMostParametersPublic, + OverloadWithOptionalParametersShouldHaveMostParametersInternal, + ShouldAnnotatePublicApiFilesRule, + ShouldAnnotateInternalApiFilesRule, + RemovedApiIsNotActuallyRemovedRule); + } +} diff --git a/src/PublicApiAnalyzers/Core/Analyzers/PublicApiAnalyzerResources.resx b/src/PublicApiAnalyzers/Core/Analyzers/PublicApiAnalyzerResources.resx index 93a05d5fec..531042fefa 100644 --- a/src/PublicApiAnalyzers/Core/Analyzers/PublicApiAnalyzerResources.resx +++ b/src/PublicApiAnalyzers/Core/Analyzers/PublicApiAnalyzerResources.resx @@ -121,7 +121,7 @@ Add public types and members to the declared API - Symbol '{0}' is not part of the declared API + Symbol '{0}' is not part of the declared public API All public types and members should be declared in PublicAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. @@ -135,13 +135,13 @@ All public types and members should be declared with nullability annotations in PublicAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. - + Enable tracking of nullability of reference types in the declared API - + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). @@ -153,13 +153,13 @@ All public members should use either nullable or non-nullable reference types, but no oblivious reference types. - + Remove deleted types and members from the declared API - + Symbol '{0}' is part of the declared API, but is either not public or could not be found - + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. {Locked="*REMOVED*"} @@ -187,7 +187,7 @@ The symbol '{0}' appears more than once in the public API files - + implicit constructor for '{0}' @@ -197,15 +197,15 @@ Symbol '{0}' violates the backcompat requirement: 'Do not add multiple overloads with optional parameters'. See '{1}' for details. - Public API with optional parameter(s) should have the most parameters amongst its public overloads + API with optional parameter(s) should have the most parameters amongst its public overloads - Symbol '{0}' violates the backcompat requirement: 'Public API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. + '{0}' violates the backcompat requirement: 'API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. - + implicit get-accessor for '{0}' - + implicit set-accessor for '{0}' @@ -214,34 +214,104 @@ The solution must contain two files with the type "AdditionalFiles": PublicAPI.Unshipped.txt and PublicAPI.Shipped.txt. At least one of these files is missing or has the wrong type. - - Add all items in document '{0}' to the public API + + Add all items in document '{0}' to the API - - Add all items in project '{0}' to the public API + + Add all items in project '{0}' to the API - - Add all items in the solution to the public API + + Add all items in the solution to the API - - Annotate all items in document '{0}' in the public API + + Annotate all items in document '{0}' in the API - - Annotate all items in project '{0}' in the public API + + Annotate all items in project '{0}' in the API - - Annotate all items in the solution in the public API + + Annotate all items in the solution in the API - - Enable nullability annotations in the public API for project '{0}' + + Enable nullability annotations in the API for project '{0}' - - Enable nullability annotations in the public API for the solution + + Enable nullability annotations in the API for the solution Symbol '{0}' is marked as removed but it isn't deleted in source code - Public API is marked as removed but it exists in source code + API is marked as removed but it exists in source code + + + Add internal types and members to the declared API + + + Symbol '{0}' is not part of the declared API + + + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + + + Annotate nullability of internal types and members in the declared API + + + Symbol '{0}' is missing nullability annotations in the declared API + + + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + + + Enable tracking of nullability of reference types in the declared API + + + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + + + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + + + Internal members should not use oblivious types + + + Symbol '{0}' uses some oblivious reference types + + + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + + + Remove deleted types and members from the declared internal API + + + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found + + + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + {Locked="*REMOVED*"} + + + The contents of the internal API files are invalid + + + The contents of the internal API files are invalid: {0} + + + Missing shipped or unshipped internal API file + + + Internal API file '{0}' is missing or not marked as an additional analyzer file + + + Do not duplicate symbols in internal API files + + + The symbol '{0}' appears more than once in the internal API files + + + One or both of the internal API files are missing + + + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. - \ No newline at end of file + diff --git a/src/PublicApiAnalyzers/Core/Analyzers/PublicApiFile.cs b/src/PublicApiAnalyzers/Core/Analyzers/PublicApiFile.cs index a11477daae..2bc1dc0555 100644 --- a/src/PublicApiAnalyzers/Core/Analyzers/PublicApiFile.cs +++ b/src/PublicApiAnalyzers/Core/Analyzers/PublicApiFile.cs @@ -7,12 +7,12 @@ namespace Microsoft.CodeAnalysis.PublicApiAnalyzers { public readonly struct PublicApiFile { - public PublicApiFile(string path) + public PublicApiFile(string path, bool isPublic) { var fileName = Path.GetFileName(path); - IsShipping = IsFile(fileName, DeclarePublicApiAnalyzer.ShippedFileNamePrefix); - var isUnshippedFile = IsFile(fileName, DeclarePublicApiAnalyzer.UnshippedFileNamePrefix); + IsShipping = IsFile(fileName, isPublic ? DeclarePublicApiAnalyzer.PublicShippedFileNamePrefix : DeclarePublicApiAnalyzer.InternalShippedFileNamePrefix); + var isUnshippedFile = IsFile(fileName, isPublic ? DeclarePublicApiAnalyzer.PublicUnshippedFileNamePrefix : DeclarePublicApiAnalyzer.InternalUnshippedFileNamePrefix); IsApiFile = IsShipping || isUnshippedFile; } diff --git a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.cs.xlf b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.cs.xlf index 0836ed90d9..d17a1cc5ec 100644 --- a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.cs.xlf +++ b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.cs.xlf @@ -2,34 +2,49 @@ - - Add all items in document '{0}' to the public API - Přidat všechny položky v dokumentu {0} do veřejného rozhraní API + + Add all items in document '{0}' to the API + Add all items in document '{0}' to the API - - Add all items in project '{0}' to the public API - Přidat všechny položky v projektu {0} do veřejného rozhraní API + + Add all items in project '{0}' to the API + Add all items in project '{0}' to the API - - Add all items in the solution to the public API - Přidat všechny položky v řešení do veřejného rozhraní API + + Add all items in the solution to the API + Add all items in the solution to the API - - Annotate all items in document '{0}' in the public API - Přidat anotaci ke všem položkám v dokumentu {0} ve veřejném rozhraní API + + Annotate all items in document '{0}' in the API + Annotate all items in document '{0}' in the API - - Annotate all items in project '{0}' in the public API - Přidat anotaci ke všem položkám v projektu {0} ve veřejném rozhraní API + + Annotate all items in project '{0}' in the API + Annotate all items in project '{0}' in the API - - Annotate all items in the solution in the public API - Přidat anotaci ke všem položkám v řešení ve veřejném rozhraní API + + Annotate all items in the solution in the API + Annotate all items in the solution in the API + + + + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is missing nullability annotations in the declared API + Symbol '{0}' is missing nullability annotations in the declared API + + + + Annotate nullability of internal types and members in the declared API + Annotate nullability of internal types and members in the declared API @@ -57,14 +72,29 @@ Nepřidávat více přetížení s nepovinnými parametry + + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is not part of the declared API + Symbol '{0}' is not part of the declared API + + + + Add internal types and members to the declared API + Add internal types and members to the declared API + + All public types and members should be declared in PublicAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. Všechny veřejné typy a členy by se měly deklarovat v souboru PublicAPI.txt. To přivádí pozornost ke změnám rozhraní API v revizích a historii správy zdrojového kódu a pomáhá předcházet změnám způsobujícím chybu. - Symbol '{0}' is not part of the declared API - Symbol {0} není součástí deklarovaného rozhraní API. + Symbol '{0}' is not part of the declared public API + Symbol {0} není součástí deklarovaného rozhraní API. @@ -72,6 +102,16 @@ Přidat veřejné typy a členy do deklarovaného rozhraní API + + The symbol '{0}' appears more than once in the internal API files + The symbol '{0}' appears more than once in the internal API files + + + + Do not duplicate symbols in internal API files + Do not duplicate symbols in internal API files + + The symbol '{0}' appears more than once in the public API files Symbol {0} se v souborech veřejného rozhraní API vyskytuje více než jednou. @@ -82,14 +122,14 @@ Neduplikovat symboly v souborech veřejných rozhraní API - - Enable nullability annotations in the public API for project '{0}' - Povolit anotace o možnosti použití hodnoty null ve veřejném rozhraní API pro projekt {0} + + Enable nullability annotations in the API for project '{0}' + Enable nullability annotations in the API for project '{0}' - - Enable nullability annotations in the public API for the solution - Povolit anotace o možnosti použití hodnoty null ve veřejném rozhraní API pro řešení + + Enable nullability annotations in the API for the solution + Enable nullability annotations in the API for the solution @@ -102,6 +142,66 @@ Konstruktor činí z nedědičné základní třídy dědičnou. + + implicit constructor for '{0}' + implicit constructor for '{0}' + + + + implicit get-accessor for '{0}' + implicit get-accessor for '{0}' + + + + implicit set-accessor for '{0}' + implicit set-accessor for '{0}' + + + + Internal API file '{0}' is missing or not marked as an additional analyzer file + Internal API file '{0}' is missing or not marked as an additional analyzer file + + + + Missing shipped or unshipped internal API file + Missing shipped or unshipped internal API file + + + + The contents of the internal API files are invalid: {0} + The contents of the internal API files are invalid: {0} + + + + The contents of the internal API files are invalid + The contents of the internal API files are invalid + + + + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + + + + One or both of the internal API files are missing + One or both of the internal API files are missing + + + + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + + + + Symbol '{0}' uses some oblivious reference types + Symbol '{0}' uses some oblivious reference types + + + + Internal members should not use oblivious types + Internal members should not use oblivious types + + All public members should use either nullable or non-nullable reference types, but no oblivious reference types. Všechny veřejné členy by měly používat odkazové typy s možnou hodnotou null, nebo bez ní, ale ne odkazové typy bez určení možnosti použití hodnoty null. @@ -118,13 +218,13 @@ - Symbol '{0}' violates the backcompat requirement: 'Public API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. - Symbol {0} porušuje požadavek na zpětnou kompatibilitu: Veřejné rozhraní API s nepovinnými parametry by mělo mít ze všech veřejných přetížení nejvíce parametrů. Podrobnosti najdete tady: {1} + '{0}' violates the backcompat requirement: 'API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. + Symbol {0} porušuje požadavek na zpětnou kompatibilitu: Veřejné rozhraní API s nepovinnými parametry by mělo mít ze všech veřejných přetížení nejvíce parametrů. Podrobnosti najdete tady: {1} - Public API with optional parameter(s) should have the most parameters amongst its public overloads - Veřejné rozhraní API s nepovinnými parametry by mělo mít ze všech veřejných přetížení nejvíce parametrů + API with optional parameter(s) should have the most parameters amongst its public overloads + Veřejné rozhraní API s nepovinnými parametry by mělo mít ze všech veřejných přetížení nejvíce parametrů @@ -157,34 +257,34 @@ Chybí nejméně jeden soubor veřejného rozhraní API - - implicit constructor for '{0}' - implicitní konstruktor pro {0} - + + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + {Locked="*REMOVED*"} - - implicit get-accessor for '{0}' - implicitní přístupový objekt get pro {0} + + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found - - implicit set-accessor for '{0}' - implicitní přístupový objekt set pro {0} + + Remove deleted types and members from the declared internal API + Remove deleted types and members from the declared internal API - + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. - Když se odebírá veřejný typ nebo člen, vložte tuto položku do souboru PublicAPI.Unshipped.txt s předponou *REMOVED*. To upozorňuje na změny rozhraní API v revizích kódu a historii správy zdrojového kódu a pomáhá předcházet změnám způsobujícím chybu. + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. {Locked="*REMOVED*"} - + Symbol '{0}' is part of the declared API, but is either not public or could not be found - Symbol {0} je součástí deklarovaného rozhraní API, ale buď není veřejný, nebo se ho nepovedlo najít. + Symbol '{0}' is part of the declared API, but is either not public or could not be found - + Remove deleted types and members from the declared API - Odebrat odstraněné typy a členy z deklarovaného rozhraní API + Remove deleted types and members from the declared API @@ -193,23 +293,38 @@ - Public API is marked as removed but it exists in source code - Veřejné rozhraní API se označilo jako odebrané, ale existuje ve zdrojovém kódu. + API is marked as removed but it exists in source code + Veřejné rozhraní API se označilo jako odebrané, ale existuje ve zdrojovém kódu. + + + + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + + + + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + + + + Enable tracking of nullability of reference types in the declared API + Enable tracking of nullability of reference types in the declared API - + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - Soubory PublicAPI.txt by měly mít #nullable enable, aby se sledovala informace o možné hodnotě null, nebo by se tato diagnostika měla potlačit. Když se možnost nastavit hodnotu null povolí, PublicAPI.txt bude uchovávat informace o tom, které typy bude možné nastavit na null (přípona typu ?) a které ne (přípona !). Kromě toho sleduje všechna rozhraní API, která stále používají typy bez určení možnosti použití hodnoty null (předpona ~ na řádku). + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - V souboru PublicAPI.txt chybí #nullable enable, takže se nezaznamenají anotace o možnosti použití hodnoty null u rozhraní API. Doporučuje se toto sledování povolit. + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - + Enable tracking of nullability of reference types in the declared API - Povolit sledování možnosti použití hodnoty null pro typy odkazů v deklarovaném rozhraní API + Enable tracking of nullability of reference types in the declared API diff --git a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.de.xlf b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.de.xlf index 2e7b84b994..3f638a6f95 100644 --- a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.de.xlf +++ b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.de.xlf @@ -2,34 +2,49 @@ - - Add all items in document '{0}' to the public API - Alle Elemente im Dokument "{0}" der öffentlichen API hinzufügen + + Add all items in document '{0}' to the API + Add all items in document '{0}' to the API - - Add all items in project '{0}' to the public API - Alle Elemente im Projekt "{0}" der öffentlichen API hinzufügen + + Add all items in project '{0}' to the API + Add all items in project '{0}' to the API - - Add all items in the solution to the public API - Alle Elemente in der Projektmappe der öffentlichen API hinzufügen + + Add all items in the solution to the API + Add all items in the solution to the API - - Annotate all items in document '{0}' in the public API - Alle Elemente im Dokument "{0}" in der öffentlichen API anmerken + + Annotate all items in document '{0}' in the API + Annotate all items in document '{0}' in the API - - Annotate all items in project '{0}' in the public API - Alle Elemente im Projekt "{0}" in der öffentlichen API anmerken + + Annotate all items in project '{0}' in the API + Annotate all items in project '{0}' in the API - - Annotate all items in the solution in the public API - Alle Elemente in der Projektmappe in der öffentlichen API anmerken + + Annotate all items in the solution in the API + Annotate all items in the solution in the API + + + + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is missing nullability annotations in the declared API + Symbol '{0}' is missing nullability annotations in the declared API + + + + Annotate nullability of internal types and members in the declared API + Annotate nullability of internal types and members in the declared API @@ -57,14 +72,29 @@ Nicht mehrere Überladungen mit optionalen Parametern hinzufügen + + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is not part of the declared API + Symbol '{0}' is not part of the declared API + + + + Add internal types and members to the declared API + Add internal types and members to the declared API + + All public types and members should be declared in PublicAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. Alle öffentlichen Typen und Member müssen in "PublicAPI.txt" deklariert werden. Dadurch wird die Aufmerksamkeit auf API-Änderungen in den Codeüberprüfungen und der Versionsgeschichte der Quellcodeverwaltung gelenkt, und Breaking Changes werden verhindert. - Symbol '{0}' is not part of the declared API - Das Symbol "{0}" ist nicht Teil der deklarierten API. + Symbol '{0}' is not part of the declared public API + Das Symbol "{0}" ist nicht Teil der deklarierten API. @@ -72,6 +102,16 @@ Öffentliche Typen und Member der deklarierten API hinzufügen + + The symbol '{0}' appears more than once in the internal API files + The symbol '{0}' appears more than once in the internal API files + + + + Do not duplicate symbols in internal API files + Do not duplicate symbols in internal API files + + The symbol '{0}' appears more than once in the public API files Das Symbol "{0}" wird in den öffentlichen API-Dateien mehrmals aufgeführt. @@ -82,14 +122,14 @@ Symbole in öffentlichen API-Dateien nicht duplizieren - - Enable nullability annotations in the public API for project '{0}' - Anmerkungen zur NULL-Zulässigkeit in der öffentlichen API für das Projekt "{0}" aktivieren + + Enable nullability annotations in the API for project '{0}' + Enable nullability annotations in the API for project '{0}' - - Enable nullability annotations in the public API for the solution - Anmerkungen zur NULL-Zulässigkeit in der öffentlichen API für die Projektmappe aktivieren + + Enable nullability annotations in the API for the solution + Enable nullability annotations in the API for the solution @@ -102,6 +142,66 @@ Konstruktor macht nicht vererbbare Basisklasse vererbbar + + implicit constructor for '{0}' + implicit constructor for '{0}' + + + + implicit get-accessor for '{0}' + implicit get-accessor for '{0}' + + + + implicit set-accessor for '{0}' + implicit set-accessor for '{0}' + + + + Internal API file '{0}' is missing or not marked as an additional analyzer file + Internal API file '{0}' is missing or not marked as an additional analyzer file + + + + Missing shipped or unshipped internal API file + Missing shipped or unshipped internal API file + + + + The contents of the internal API files are invalid: {0} + The contents of the internal API files are invalid: {0} + + + + The contents of the internal API files are invalid + The contents of the internal API files are invalid + + + + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + + + + One or both of the internal API files are missing + One or both of the internal API files are missing + + + + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + + + + Symbol '{0}' uses some oblivious reference types + Symbol '{0}' uses some oblivious reference types + + + + Internal members should not use oblivious types + Internal members should not use oblivious types + + All public members should use either nullable or non-nullable reference types, but no oblivious reference types. Alle öffentlichen Member sollten Verweistypen, die NULL-Werte zulassen oder nicht zulassen, aber keine nicht beachtenden Verweistypen verwenden. @@ -118,13 +218,13 @@ - Symbol '{0}' violates the backcompat requirement: 'Public API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. - Das Symbol "{0}" verletzt die backcompat-Anforderung: Öffentliche API mit optionalen Parametern muss die meisten Parameter bei den öffentlichen Überladungen aufweisen. Details finden Sie unter "{1}". + '{0}' violates the backcompat requirement: 'API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. + Das Symbol "{0}" verletzt die backcompat-Anforderung: Öffentliche API mit optionalen Parametern muss die meisten Parameter bei den öffentlichen Überladungen aufweisen. Details finden Sie unter "{1}". - Public API with optional parameter(s) should have the most parameters amongst its public overloads - Öffentliche API mit optionalen Parametern muss die meisten Parameter bei den öffentlichen Überladungen aufweisen + API with optional parameter(s) should have the most parameters amongst its public overloads + Öffentliche API mit optionalen Parametern muss die meisten Parameter bei den öffentlichen Überladungen aufweisen @@ -157,34 +257,34 @@ Mindestens eine der öffentlichen API-Dateien fehlt. - - implicit constructor for '{0}' - Impliziter Konstruktor für "{0}" - + + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + {Locked="*REMOVED*"} - - implicit get-accessor for '{0}' - Impliziter get-Accessor für "{0}" + + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found - - implicit set-accessor for '{0}' - Impliziter set-Accessor für "{0}" + + Remove deleted types and members from the declared internal API + Remove deleted types and members from the declared internal API - + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. - Wenn Sie einen öffentlichen Typ oder Member entfernen, fügen Sie diesen Eintrag in "PublicAPI.Unshipped.txt" mit dem Präfix "*REMOVED*" ein. Dadurch wird die Aufmerksamkeit auf API-Änderungen in den Codeüberprüfungen und dem Quellcodeverwaltungsverlauf gelenkt und trägt dazu bei, Breaking Changes zu verhindern. + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. {Locked="*REMOVED*"} - + Symbol '{0}' is part of the declared API, but is either not public or could not be found - Das Symbol "{0}" ist Teil der deklarierten API, aber entweder nicht öffentlich oder nicht auffindbar. + Symbol '{0}' is part of the declared API, but is either not public or could not be found - + Remove deleted types and members from the declared API - Gelöschte Typen und Member aus der deklarierten API entfernen + Remove deleted types and members from the declared API @@ -193,23 +293,38 @@ - Public API is marked as removed but it exists in source code - Die öffentliche API ist als entfernt markiert, ist jedoch im Quellcode noch vorhanden. + API is marked as removed but it exists in source code + Die öffentliche API ist als entfernt markiert, ist jedoch im Quellcode noch vorhanden. + + + + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + + + + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + + + + Enable tracking of nullability of reference types in the declared API + Enable tracking of nullability of reference types in the declared API - + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - Für "PublicAPI.txt"-Dateien muss "#nullable enable" festgelegt sein, um Informationen zur NULL-Zulässigkeit nachzuverfolgen. Andernfalls sollte diese Diagnose unterdrückt werden. Bei aktivierter NULL-Zulässigkeit zeichnet "PublicAPI.txt" auf, welche Typen NULL-Werte zulassen (Suffix "?" für den Typ) bzw. keine NULL-Werte zulassen (Suffix "!"). Zudem werden alle APIs verfolgt, die noch immer einen Verweistyp ohne Beachtung verwenden (Präfix "~" in der Zeile). + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - In "PublicAPI.txt" fehlt "#nullable enable", daher werden die Anmerkungen zur NULL-Zulässigkeit der API nicht aufgezeichnet. Es wird empfohlen, diese Nachverfolgung zu aktivieren. + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - + Enable tracking of nullability of reference types in the declared API - Nachverfolgung der NULL-Zulässigkeit von Verweistypen in der deklarierten API aktivieren + Enable tracking of nullability of reference types in the declared API diff --git a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.es.xlf b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.es.xlf index c5b99b52ee..a263a04d43 100644 --- a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.es.xlf +++ b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.es.xlf @@ -2,34 +2,49 @@ - - Add all items in document '{0}' to the public API - Agregar todos los elementos del documento "{0}" a la API pública + + Add all items in document '{0}' to the API + Add all items in document '{0}' to the API - - Add all items in project '{0}' to the public API - Agregar todos los elementos del proyecto "{0}" a la API pública + + Add all items in project '{0}' to the API + Add all items in project '{0}' to the API - - Add all items in the solution to the public API - Agregar todos los elementos de la solución a la API pública + + Add all items in the solution to the API + Add all items in the solution to the API - - Annotate all items in document '{0}' in the public API - Anotar todos los elementos del documento "{0}" en la API pública + + Annotate all items in document '{0}' in the API + Annotate all items in document '{0}' in the API - - Annotate all items in project '{0}' in the public API - Anotar todos los elementos del proyecto "{0}" en la API pública + + Annotate all items in project '{0}' in the API + Annotate all items in project '{0}' in the API - - Annotate all items in the solution in the public API - Anotar todos los elementos de la solución en la API pública + + Annotate all items in the solution in the API + Annotate all items in the solution in the API + + + + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is missing nullability annotations in the declared API + Symbol '{0}' is missing nullability annotations in the declared API + + + + Annotate nullability of internal types and members in the declared API + Annotate nullability of internal types and members in the declared API @@ -57,14 +72,29 @@ No agregar varias sobrecargas públicas con los parámetros opcionales + + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is not part of the declared API + Symbol '{0}' is not part of the declared API + + + + Add internal types and members to the declared API + Add internal types and members to the declared API + + All public types and members should be declared in PublicAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. Todos los tipos y miembros públicos deben declararse en PublicAPI.txt. Esto atrae la atención a los cambios de la API en las revisiones de código y el historial de control de código fuente; además, ayuda a evitar cambios importantes. - Symbol '{0}' is not part of the declared API - El símbolo "{0}" no forma parte de la API declarada. + Symbol '{0}' is not part of the declared public API + El símbolo "{0}" no forma parte de la API declarada. @@ -72,6 +102,16 @@ Agregar miembros y tipos públicos a la API declarada + + The symbol '{0}' appears more than once in the internal API files + The symbol '{0}' appears more than once in the internal API files + + + + Do not duplicate symbols in internal API files + Do not duplicate symbols in internal API files + + The symbol '{0}' appears more than once in the public API files El símbolo "{0}" aparece más de una vez en los archivos de la API pública. @@ -82,14 +122,14 @@ No duplicar símbolos en los archivos de la API pública - - Enable nullability annotations in the public API for project '{0}' - Habilitar las anotaciones de nulabilidad en la API pública para el proyecto "{0}" + + Enable nullability annotations in the API for project '{0}' + Enable nullability annotations in the API for project '{0}' - - Enable nullability annotations in the public API for the solution - Habilitar las anotaciones de nulabilidad en la API pública para la solución + + Enable nullability annotations in the API for the solution + Enable nullability annotations in the API for the solution @@ -102,6 +142,66 @@ El constructor convierte en heredable su clase base no heredable + + implicit constructor for '{0}' + implicit constructor for '{0}' + + + + implicit get-accessor for '{0}' + implicit get-accessor for '{0}' + + + + implicit set-accessor for '{0}' + implicit set-accessor for '{0}' + + + + Internal API file '{0}' is missing or not marked as an additional analyzer file + Internal API file '{0}' is missing or not marked as an additional analyzer file + + + + Missing shipped or unshipped internal API file + Missing shipped or unshipped internal API file + + + + The contents of the internal API files are invalid: {0} + The contents of the internal API files are invalid: {0} + + + + The contents of the internal API files are invalid + The contents of the internal API files are invalid + + + + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + + + + One or both of the internal API files are missing + One or both of the internal API files are missing + + + + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + + + + Symbol '{0}' uses some oblivious reference types + Symbol '{0}' uses some oblivious reference types + + + + Internal members should not use oblivious types + Internal members should not use oblivious types + + All public members should use either nullable or non-nullable reference types, but no oblivious reference types. Todos los miembros públicos deben usar tipos de referencia que acepten o no valores NULL, pero no tipos de referencia inconscientes. @@ -118,13 +218,13 @@ - Symbol '{0}' violates the backcompat requirement: 'Public API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. - El símbolo "{0}" infringe el requisito de compatibilidad con versiones anteriores: "La API pública con parámetros opcionales debe tener la mayoría de los parámetros entre sus sobrecargas públicas". Consulte "{1}" para obtener más detalles. + '{0}' violates the backcompat requirement: 'API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. + El símbolo "{0}" infringe el requisito de compatibilidad con versiones anteriores: "La API pública con parámetros opcionales debe tener la mayoría de los parámetros entre sus sobrecargas públicas". Consulte "{1}" para obtener más detalles. - Public API with optional parameter(s) should have the most parameters amongst its public overloads - La API pública con parámetros opcionales debe tener la mayoría de los parámetros entre sus sobrecargas públicas + API with optional parameter(s) should have the most parameters amongst its public overloads + La API pública con parámetros opcionales debe tener la mayoría de los parámetros entre sus sobrecargas públicas @@ -157,34 +257,34 @@ Faltan los dos archivos de la API pública o uno de ellos - - implicit constructor for '{0}' - constructor implícito para "{0}" - + + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + {Locked="*REMOVED*"} - - implicit get-accessor for '{0}' - descriptor de acceso get implícito para "{0}" + + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found - - implicit set-accessor for '{0}' - descriptor de acceso set implícito para "{0}" + + Remove deleted types and members from the declared internal API + Remove deleted types and members from the declared internal API - + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. - Al quitar un tipo o miembro público, coloque esa entrada en PublicAPI.Unshipped.txt con el prefijo "*REMOVED*". Esto atrae la atención a los cambios de la API en las revisiones de código y el historial de control de código fuente; además, ayuda a evitar cambios importantes. + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. {Locked="*REMOVED*"} - + Symbol '{0}' is part of the declared API, but is either not public or could not be found - El símbolo "{0}" forma parte de la API declarada, pero no es pública o no se encontró. + Symbol '{0}' is part of the declared API, but is either not public or could not be found - + Remove deleted types and members from the declared API - Quitar tipos y miembros eliminados de la API declarada + Remove deleted types and members from the declared API @@ -193,23 +293,38 @@ - Public API is marked as removed but it exists in source code - La API pública se marcó como quitada, pero existe en el código fuente + API is marked as removed but it exists in source code + La API pública se marcó como quitada, pero existe en el código fuente + + + + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + + + + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + + + + Enable tracking of nullability of reference types in the declared API + Enable tracking of nullability of reference types in the declared API - + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - Los archivos PublicAPI.txt deben tener "#nullable Enable" para hacer un seguimiento de la información de nulabilidad, o bien se debe suprimir este diagnóstico. Con la nulabilidad habilitada, PublicAPI.txt registra los tipos que aceptan valores NULL (sufijo "?" en el tipo) o que no admiten valores NULL (sufijo "!"). También realiza el seguimiento de cualquier API que aún use un tipo de referencia obvio (prefijo "~" en la línea). + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - Falta "#nullable enable" en PublicAPI.txt, por lo que las anotaciones de nulabilidad de la API no se registran. Se recomienda habilitar este seguimiento. + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - + Enable tracking of nullability of reference types in the declared API - Habilitar el seguimiento de la nulabilidad de los tipos de referencia en la API declarada + Enable tracking of nullability of reference types in the declared API diff --git a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.fr.xlf b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.fr.xlf index 9e22945cf3..645f066275 100644 --- a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.fr.xlf +++ b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.fr.xlf @@ -2,34 +2,49 @@ - - Add all items in document '{0}' to the public API - Ajouter tous les éléments du document '{0}' à l'API publique + + Add all items in document '{0}' to the API + Add all items in document '{0}' to the API - - Add all items in project '{0}' to the public API - Ajouter tous les éléments du projet '{0}' à l'API publique + + Add all items in project '{0}' to the API + Add all items in project '{0}' to the API - - Add all items in the solution to the public API - Ajouter tous les éléments de la solution à l'API publique + + Add all items in the solution to the API + Add all items in the solution to the API - - Annotate all items in document '{0}' in the public API - Annoter tous les éléments du document '{0}' dans l'API publique + + Annotate all items in document '{0}' in the API + Annotate all items in document '{0}' in the API - - Annotate all items in project '{0}' in the public API - Annoter tous les éléments du projet '{0}' dans l'API publique + + Annotate all items in project '{0}' in the API + Annotate all items in project '{0}' in the API - - Annotate all items in the solution in the public API - Annoter tous les éléments de la solution dans l'API publique + + Annotate all items in the solution in the API + Annotate all items in the solution in the API + + + + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is missing nullability annotations in the declared API + Symbol '{0}' is missing nullability annotations in the declared API + + + + Annotate nullability of internal types and members in the declared API + Annotate nullability of internal types and members in the declared API @@ -57,14 +72,29 @@ Ne pas ajouter plusieurs surcharges publiques avec des paramètres optionnels + + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is not part of the declared API + Symbol '{0}' is not part of the declared API + + + + Add internal types and members to the declared API + Add internal types and members to the declared API + + All public types and members should be declared in PublicAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. Tous les types et membres publics doivent être déclarés dans PublicAPI.txt. Cela permet d'attirer l'attention sur les changements apportés à l'API dans les revues de code et l'historique de contrôle de code source. Cela permet également d'éviter les changements cassants. - Symbol '{0}' is not part of the declared API - Le symbole '{0}' ne fait pas partie de l'API déclarée + Symbol '{0}' is not part of the declared public API + Le symbole '{0}' ne fait pas partie de l'API déclarée @@ -72,6 +102,16 @@ Ajouter des types et membres publics à l'API déclarée + + The symbol '{0}' appears more than once in the internal API files + The symbol '{0}' appears more than once in the internal API files + + + + Do not duplicate symbols in internal API files + Do not duplicate symbols in internal API files + + The symbol '{0}' appears more than once in the public API files Le symbole '{0}' apparaît plusieurs fois dans les fichiers de l'API publique @@ -82,14 +122,14 @@ Ne pas dupliquer les symboles dans les fichiers d'une API publique - - Enable nullability annotations in the public API for project '{0}' - Activer les annotations de nullabilité dans l'API publique pour le projet '{0}' + + Enable nullability annotations in the API for project '{0}' + Enable nullability annotations in the API for project '{0}' - - Enable nullability annotations in the public API for the solution - Activer les annotations de nullabilité dans l'API publique pour la solution + + Enable nullability annotations in the API for the solution + Enable nullability annotations in the API for the solution @@ -102,6 +142,66 @@ Le constructeur fait de la classe de base noninheritable une classe inheritable + + implicit constructor for '{0}' + implicit constructor for '{0}' + + + + implicit get-accessor for '{0}' + implicit get-accessor for '{0}' + + + + implicit set-accessor for '{0}' + implicit set-accessor for '{0}' + + + + Internal API file '{0}' is missing or not marked as an additional analyzer file + Internal API file '{0}' is missing or not marked as an additional analyzer file + + + + Missing shipped or unshipped internal API file + Missing shipped or unshipped internal API file + + + + The contents of the internal API files are invalid: {0} + The contents of the internal API files are invalid: {0} + + + + The contents of the internal API files are invalid + The contents of the internal API files are invalid + + + + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + + + + One or both of the internal API files are missing + One or both of the internal API files are missing + + + + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + + + + Symbol '{0}' uses some oblivious reference types + Symbol '{0}' uses some oblivious reference types + + + + Internal members should not use oblivious types + Internal members should not use oblivious types + + All public members should use either nullable or non-nullable reference types, but no oblivious reference types. Tous les membres publics doivent utiliser des types référence nullables ou non nullables, mais aucun type référence inconscient. @@ -118,13 +218,13 @@ - Symbol '{0}' violates the backcompat requirement: 'Public API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. - Le symbole '{0}' viole l'exigence de compatibilité descendante : 'L'API publique avec un ou plusieurs paramètres optionnels doit avoir le plus de paramètres possibles parmi ses surcharges publiques'. Pour plus d'informations, consultez '{1}'. + '{0}' violates the backcompat requirement: 'API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. + Le symbole '{0}' viole l'exigence de compatibilité descendante : 'L'API publique avec un ou plusieurs paramètres optionnels doit avoir le plus de paramètres possibles parmi ses surcharges publiques'. Pour plus d'informations, consultez '{1}'. - Public API with optional parameter(s) should have the most parameters amongst its public overloads - L'API publique avec un ou plusieurs paramètres optionnels doit avoir le plus de paramètres possible parmi ses surcharges publiques + API with optional parameter(s) should have the most parameters amongst its public overloads + L'API publique avec un ou plusieurs paramètres optionnels doit avoir le plus de paramètres possible parmi ses surcharges publiques @@ -157,34 +257,34 @@ Il manque l'un des deux fichiers d'API publiques, ou les deux - - implicit constructor for '{0}' - constructeur implicite pour '{0}' - + + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + {Locked="*REMOVED*"} - - implicit get-accessor for '{0}' - accesseur get implicite pour '{0}' + + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found - - implicit set-accessor for '{0}' - accesseur set implicite pour '{0}' + + Remove deleted types and members from the declared internal API + Remove deleted types and members from the declared internal API - + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. - Lorsque vous supprimez un type ou un membre public, placez cette entrée dans PublicAPI.Unshipped.txt avec le préfixe « *REMOVED* ». Cela permet d'attirer l'attention sur les modifications de l'API dans les revues de code et l'historique du contrôle de la source, et d'éviter les modifications de rupture. + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. {Locked="*REMOVED*"} - + Symbol '{0}' is part of the declared API, but is either not public or could not be found - Le symbole '{0}' fait partie de l'API déclarée, mais il n'est pas public ou est introuvable + Symbol '{0}' is part of the declared API, but is either not public or could not be found - + Remove deleted types and members from the declared API - Enlever les types et membres supprimés de l'API déclarée + Remove deleted types and members from the declared API @@ -193,23 +293,38 @@ - Public API is marked as removed but it exists in source code - L’API publique est marquée comme étant supprimée, mais elle existe dans le code source + API is marked as removed but it exists in source code + L’API publique est marquée comme étant supprimée, mais elle existe dans le code source + + + + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + + + + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + + + + Enable tracking of nullability of reference types in the declared API + Enable tracking of nullability of reference types in the declared API - + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - Les fichiers PublicAPI.txt doivent avoir '#nullable enable' pour effectuer le suivi des informations de possibilité de valeur null ou ce diagnostic doit être supprimé. Si l'option de possibilité de valeur null est activée, PublicAPI.txt enregistre les types nullable (suffixe '?' sur le type) ou non-nullable (suffixe '!'). Il effectue également le suivi des API qui utilisent encore un type référence inconscient (préfixe '~' sur la ligne). + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - PublicAPI.txt ne contient pas '#nullable enable'. Les annotations de nullabilité de l'API ne sont donc pas enregistrées. Il est recommandé d'activer ce suivi. + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - + Enable tracking of nullability of reference types in the declared API - Activer le suivi de la possibilité de valeur null des types référence dans l'API déclarée + Enable tracking of nullability of reference types in the declared API diff --git a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.it.xlf b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.it.xlf index a55a5060a9..4c20d9c6ee 100644 --- a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.it.xlf +++ b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.it.xlf @@ -2,34 +2,49 @@ - - Add all items in document '{0}' to the public API - Aggiungi tutti gli elementi del documento '{0}' all'API pubblica + + Add all items in document '{0}' to the API + Add all items in document '{0}' to the API - - Add all items in project '{0}' to the public API - Aggiungi tutti gli elementi del progetto '{0}' all'API pubblica + + Add all items in project '{0}' to the API + Add all items in project '{0}' to the API - - Add all items in the solution to the public API - Aggiungi tutti gli elementi della soluzione all'API pubblica + + Add all items in the solution to the API + Add all items in the solution to the API - - Annotate all items in document '{0}' in the public API - Annota tutti gli elementi del documento '{0}' nell'API pubblica + + Annotate all items in document '{0}' in the API + Annotate all items in document '{0}' in the API - - Annotate all items in project '{0}' in the public API - Annota tutti gli elementi del progetto '{0}' nell'API pubblica + + Annotate all items in project '{0}' in the API + Annotate all items in project '{0}' in the API - - Annotate all items in the solution in the public API - Annota tutti gli elementi della soluzione nell'API pubblica + + Annotate all items in the solution in the API + Annotate all items in the solution in the API + + + + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is missing nullability annotations in the declared API + Symbol '{0}' is missing nullability annotations in the declared API + + + + Annotate nullability of internal types and members in the declared API + Annotate nullability of internal types and members in the declared API @@ -57,14 +72,29 @@ Non aggiungere più overload public con parametri facoltativi + + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is not part of the declared API + Symbol '{0}' is not part of the declared API + + + + Add internal types and members to the declared API + Add internal types and members to the declared API + + All public types and members should be declared in PublicAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. Tutti i tipi e i membri public devono essere dichiarati in PublicAPI.txt. In questo modo si richiama l'attenzione sulle modifiche all'API nelle revisioni del codice e nella cronologia del controllo del codice sorgente e contribuisce a evitare modifiche che causano un'interruzione. - Symbol '{0}' is not part of the declared API - Il simbolo '{0}' non fa parte dell'API dichiarata + Symbol '{0}' is not part of the declared public API + Il simbolo '{0}' non fa parte dell'API dichiarata @@ -72,6 +102,16 @@ Aggiungere tipi e membri public all'API dichiarata + + The symbol '{0}' appears more than once in the internal API files + The symbol '{0}' appears more than once in the internal API files + + + + Do not duplicate symbols in internal API files + Do not duplicate symbols in internal API files + + The symbol '{0}' appears more than once in the public API files Il simbolo '{0}' è presente più volte nei file dell'API pubblica @@ -82,14 +122,14 @@ Non duplicare simboli nei file dell'API pubblica - - Enable nullability annotations in the public API for project '{0}' - Abilita le annotazioni di supporto dei valori Null nell'API pubblica per il progetto '{0}' + + Enable nullability annotations in the API for project '{0}' + Enable nullability annotations in the API for project '{0}' - - Enable nullability annotations in the public API for the solution - Abilita le annotazioni di supporto dei valori Null nell'API pubblica per la soluzione + + Enable nullability annotations in the API for the solution + Enable nullability annotations in the API for the solution @@ -102,6 +142,66 @@ Il costruttore rende ereditabile la classe di base non ereditabile + + implicit constructor for '{0}' + implicit constructor for '{0}' + + + + implicit get-accessor for '{0}' + implicit get-accessor for '{0}' + + + + implicit set-accessor for '{0}' + implicit set-accessor for '{0}' + + + + Internal API file '{0}' is missing or not marked as an additional analyzer file + Internal API file '{0}' is missing or not marked as an additional analyzer file + + + + Missing shipped or unshipped internal API file + Missing shipped or unshipped internal API file + + + + The contents of the internal API files are invalid: {0} + The contents of the internal API files are invalid: {0} + + + + The contents of the internal API files are invalid + The contents of the internal API files are invalid + + + + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + + + + One or both of the internal API files are missing + One or both of the internal API files are missing + + + + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + + + + Symbol '{0}' uses some oblivious reference types + Symbol '{0}' uses some oblivious reference types + + + + Internal members should not use oblivious types + Internal members should not use oblivious types + + All public members should use either nullable or non-nullable reference types, but no oblivious reference types. Tutti i membri pubblici devono usare tipi riferimento nullable o non nullable, ma non tipi riferimento oblivious. @@ -118,13 +218,13 @@ - Symbol '{0}' violates the backcompat requirement: 'Public API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. - Il simbolo '{0}' viola il requisito di compatibilità con le versioni precedenti: 'L'API pubblica con parametri facoltativi deve includere la maggior parte dei parametri tra i relativi overload public'. Per dettagli, vedere '{1}'. + '{0}' violates the backcompat requirement: 'API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. + Il simbolo '{0}' viola il requisito di compatibilità con le versioni precedenti: 'L'API pubblica con parametri facoltativi deve includere la maggior parte dei parametri tra i relativi overload public'. Per dettagli, vedere '{1}'. - Public API with optional parameter(s) should have the most parameters amongst its public overloads - L'API pubblica con parametri facoltativi deve includere la maggior parte dei parametri tra i relativi overload public + API with optional parameter(s) should have the most parameters amongst its public overloads + L'API pubblica con parametri facoltativi deve includere la maggior parte dei parametri tra i relativi overload public @@ -157,34 +257,34 @@ Uno o entrambi i file dell'API pubblica sono mancanti - - implicit constructor for '{0}' - costruttore implicito per '{0}' - + + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + {Locked="*REMOVED*"} - - implicit get-accessor for '{0}' - funzione di accesso get implicita per '{0}' + + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found - - implicit set-accessor for '{0}' - funzione di accesso set implicita per '{0}' + + Remove deleted types and members from the declared internal API + Remove deleted types and members from the declared internal API - + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. - Quando si rimuove un tipo o un membro pubblico, è necessario inserire questa voce in PublicAPI.Unshipped.txt con prefisso '*REMOVED*’. In questo modo si richiama l'attenzione sulle modifiche all'API nelle revisioni del codice e nella cronologia dei controlli del codice sorgente, e si contribuisce a evitare modifiche che causano un'interruzione. + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. {Locked="*REMOVED*"} - + Symbol '{0}' is part of the declared API, but is either not public or could not be found - Il simbolo '{0}' fa parte dell'API dichiarata, ma non è public oppure non è stato possibile trovarlo + Symbol '{0}' is part of the declared API, but is either not public or could not be found - + Remove deleted types and members from the declared API - Rimuovere tipi e membri eliminati dall'API dichiarata + Remove deleted types and members from the declared API @@ -193,23 +293,38 @@ - Public API is marked as removed but it exists in source code - L'API pubblica è contrassegnata come rimossa, ma è presente nel codice sorgente + API is marked as removed but it exists in source code + L'API pubblica è contrassegnata come rimossa, ma è presente nel codice sorgente + + + + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + + + + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + + + + Enable tracking of nullability of reference types in the declared API + Enable tracking of nullability of reference types in the declared API - + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - I file PublicAPI.txt devono includere `#nullable enable` per tenere traccia delle informazioni sul supporto dei valori Null, in caso contrario questa diagnostica deve essere eliminata. Se il supporto dei valori Null è abilitato, PublicAPI.txt registra i tipi nullable (suffisso `?` nel tipo) o non nullable (suffisso `!`). Tiene inoltre traccia di eventuali API che usano ancora un tipo riferimento senza annotazioni nullable (prefisso `~` nella riga). + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - In PublicAPI.txt manca '#nullable enable', di conseguenza le annotazioni di supporto dei valori Null dell'API non sono registrate. È consigliabile abilitare questa verifica. + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - + Enable tracking of nullability of reference types in the declared API - Abilita il rilevamento del supporto dei valori Null dei tipi riferimento nell'API dichiarata + Enable tracking of nullability of reference types in the declared API diff --git a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.ja.xlf b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.ja.xlf index 8509dcdef6..9ef61ae9f4 100644 --- a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.ja.xlf +++ b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.ja.xlf @@ -2,34 +2,49 @@ - - Add all items in document '{0}' to the public API - ドキュメント '{0}' 内のすべての項目のパブリック API への追加 + + Add all items in document '{0}' to the API + Add all items in document '{0}' to the API - - Add all items in project '{0}' to the public API - プロジェクト '{0}' 内のすべての項目のパブリック API への追加 + + Add all items in project '{0}' to the API + Add all items in project '{0}' to the API - - Add all items in the solution to the public API - ソリューション内のすべての項目のパブリック API への追加 + + Add all items in the solution to the API + Add all items in the solution to the API - - Annotate all items in document '{0}' in the public API - パブリック API のドキュメント '{0}' 内のすべての項目に注釈を付ける + + Annotate all items in document '{0}' in the API + Annotate all items in document '{0}' in the API - - Annotate all items in project '{0}' in the public API - パブリック API のプロジェクト '{0}' 内のすべての項目に注釈を付ける + + Annotate all items in project '{0}' in the API + Annotate all items in project '{0}' in the API - - Annotate all items in the solution in the public API - パブリック API のソリューション内のすべての項目に注釈を付ける + + Annotate all items in the solution in the API + Annotate all items in the solution in the API + + + + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is missing nullability annotations in the declared API + Symbol '{0}' is missing nullability annotations in the declared API + + + + Annotate nullability of internal types and members in the declared API + Annotate nullability of internal types and members in the declared API @@ -57,14 +72,29 @@ 省略可能なパラメーターを持つ複数のパブリック オーバーロードを追加しない + + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is not part of the declared API + Symbol '{0}' is not part of the declared API + + + + Add internal types and members to the declared API + Add internal types and members to the declared API + + All public types and members should be declared in PublicAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. すべてのパブリックの型とメンバーは、PublicAPI.txt で宣言する必要があります。これにより、コード レビューとソース管理履歴で API 変更に注意を引くことができ、破壊的変更を防ぐことができます。 - Symbol '{0}' is not part of the declared API - シンボル '{0}' は宣言された API の一部ではありません + Symbol '{0}' is not part of the declared public API + シンボル '{0}' は宣言された API の一部ではありません @@ -72,6 +102,16 @@ 宣言された API にパブリックの型とメンバーを追加する + + The symbol '{0}' appears more than once in the internal API files + The symbol '{0}' appears more than once in the internal API files + + + + Do not duplicate symbols in internal API files + Do not duplicate symbols in internal API files + + The symbol '{0}' appears more than once in the public API files シンボル '{0}' が、パブリック API ファイルに複数含まれています @@ -82,14 +122,14 @@ パブリック API ファイル内でシンボルを重複させない - - Enable nullability annotations in the public API for project '{0}' - プロジェクト '{0}' のパブリック API で、NULL 許容の注釈を有効にする + + Enable nullability annotations in the API for project '{0}' + Enable nullability annotations in the API for project '{0}' - - Enable nullability annotations in the public API for the solution - ソリューションのパブリック API で、NULL 許容の注釈を有効にする + + Enable nullability annotations in the API for the solution + Enable nullability annotations in the API for the solution @@ -102,6 +142,66 @@ コンストラクターにより、継承不可能な基底クラスが継承可能になります + + implicit constructor for '{0}' + implicit constructor for '{0}' + + + + implicit get-accessor for '{0}' + implicit get-accessor for '{0}' + + + + implicit set-accessor for '{0}' + implicit set-accessor for '{0}' + + + + Internal API file '{0}' is missing or not marked as an additional analyzer file + Internal API file '{0}' is missing or not marked as an additional analyzer file + + + + Missing shipped or unshipped internal API file + Missing shipped or unshipped internal API file + + + + The contents of the internal API files are invalid: {0} + The contents of the internal API files are invalid: {0} + + + + The contents of the internal API files are invalid + The contents of the internal API files are invalid + + + + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + + + + One or both of the internal API files are missing + One or both of the internal API files are missing + + + + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + + + + Symbol '{0}' uses some oblivious reference types + Symbol '{0}' uses some oblivious reference types + + + + Internal members should not use oblivious types + Internal members should not use oblivious types + + All public members should use either nullable or non-nullable reference types, but no oblivious reference types. すべてのパブリック メンバーは、Null 許容参照型と null 非許容参照型のいずれかを使用する必要がありますが、oblivious 参照型は使用しません。 @@ -118,13 +218,13 @@ - Symbol '{0}' violates the backcompat requirement: 'Public API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. - シンボル '{0}' は下位互換性の要件、「省略可能なパラメーターを持つパブリック API は、そのパブリック オーバーロード内のほとんどのパラメーターを持つ必要がある」に違反しています。詳細は '{1}' を参照してください。 + '{0}' violates the backcompat requirement: 'API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. + シンボル '{0}' は下位互換性の要件、「省略可能なパラメーターを持つパブリック API は、そのパブリック オーバーロード内のほとんどのパラメーターを持つ必要がある」に違反しています。詳細は '{1}' を参照してください。 - Public API with optional parameter(s) should have the most parameters amongst its public overloads - 省略可能なパラメーターを持つパブリック API は、そのパブリック オーバーロード内のほとんどのパラメーターを持つ必要がある + API with optional parameter(s) should have the most parameters amongst its public overloads + 省略可能なパラメーターを持つパブリック API は、そのパブリック オーバーロード内のほとんどのパラメーターを持つ必要がある @@ -157,34 +257,34 @@ パブリック API ファイルの 1 つまたは両方が見つからない - - implicit constructor for '{0}' - '{0}' の暗黙的なコンストラクター - + + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + {Locked="*REMOVED*"} - - implicit get-accessor for '{0}' - '{0}' の暗黙的な get アクセサー + + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found - - implicit set-accessor for '{0}' - '{0}' の暗黙的な set アクセサー + + Remove deleted types and members from the declared internal API + Remove deleted types and members from the declared internal API - + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. - パブリックの型またはメンバーを削除する際、その項目を PublicAPI.Unshipped.txt に '*REMOVED*' プレフィックスを付けて記入する必要があります。これにより、コード レビューとソース管理履歴で API の変更に注意を引くことができ、破壊的変更を防ぐことができます。 + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. {Locked="*REMOVED*"} - + Symbol '{0}' is part of the declared API, but is either not public or could not be found - シンボル '{0}' は宣言された API の一部ですが、パブリックではないか、見つかりませんでした + Symbol '{0}' is part of the declared API, but is either not public or could not be found - + Remove deleted types and members from the declared API - 削除された型とメンバーを、宣言された API から削除する + Remove deleted types and members from the declared API @@ -193,23 +293,38 @@ - Public API is marked as removed but it exists in source code - パブリック API が削除済みとマークされていますが、ソース コード内に存在します + API is marked as removed but it exists in source code + パブリック API が削除済みとマークされていますが、ソース コード内に存在します + + + + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + + + + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + + + + Enable tracking of nullability of reference types in the declared API + Enable tracking of nullability of reference types in the declared API - + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - PublicAPI.txt ファイルでは、NULL 値の許容情報を追跡するために '#nullable enable' を指定する必要があります。指定されていない場合は、この診断を中止する必要があります。NULL 値の許容を有効にすると、PublicAPI.txt は、どの型が null 許容 (型にサフィックス '?' を含む) または null 非許容 (サフィックス '!') かを記録します。また、oblivious 参照型 (行にプレフィックス '~' を含む) を使用している API を追跡します。 + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - PublicAPI.txt に '#nullable enable' がありません。そのため、API の NULL 許容の注釈は記録されていません。この追跡を有効にすることをお勧めします。 + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - + Enable tracking of nullability of reference types in the declared API - 宣言された API 内で参照型の NULL 値の許容を追跡できるようにする + Enable tracking of nullability of reference types in the declared API diff --git a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.ko.xlf b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.ko.xlf index d64d31992c..d1a697b640 100644 --- a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.ko.xlf +++ b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.ko.xlf @@ -2,34 +2,49 @@ - - Add all items in document '{0}' to the public API - '{0}' 문서의 모든 항목을 퍼블릭 API에 추가 + + Add all items in document '{0}' to the API + Add all items in document '{0}' to the API - - Add all items in project '{0}' to the public API - '{0}' 프로젝트의 모든 항목을 퍼블릭 API에 추가 + + Add all items in project '{0}' to the API + Add all items in project '{0}' to the API - - Add all items in the solution to the public API - 솔루션의 모든 항목을 퍼블릭 API에 추가 + + Add all items in the solution to the API + Add all items in the solution to the API - - Annotate all items in document '{0}' in the public API - 퍼블릭 API에서 '{0}' 문서의 모든 항목에 주석 추가 + + Annotate all items in document '{0}' in the API + Annotate all items in document '{0}' in the API - - Annotate all items in project '{0}' in the public API - 퍼블릭 API에서 '{0}' 프로젝트의 모든 항목에 주석 추가 + + Annotate all items in project '{0}' in the API + Annotate all items in project '{0}' in the API - - Annotate all items in the solution in the public API - 퍼블릭 API에서 솔루션의 모든 항목에 주석 추가 + + Annotate all items in the solution in the API + Annotate all items in the solution in the API + + + + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is missing nullability annotations in the declared API + Symbol '{0}' is missing nullability annotations in the declared API + + + + Annotate nullability of internal types and members in the declared API + Annotate nullability of internal types and members in the declared API @@ -57,14 +72,29 @@ 선택적 매개 변수가 있는 여러 공용 오버로드를 추가하지 마세요. + + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is not part of the declared API + Symbol '{0}' is not part of the declared API + + + + Add internal types and members to the declared API + Add internal types and members to the declared API + + All public types and members should be declared in PublicAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. 모든 public 형식 및 멤버는 PublicAPI.txt에서 선언해야 합니다. 이로 인해 코드 검토 및 소스 제어 기록에서 API 변경 내용을 쉽게 확인할 수 있고 큰 변경을 방지할 수 있습니다. - Symbol '{0}' is not part of the declared API - '{0}' 기호가 선언된 API에 포함되지 않습니다. + Symbol '{0}' is not part of the declared public API + '{0}' 기호가 선언된 API에 포함되지 않습니다. @@ -72,6 +102,16 @@ 선언된 API에 공용 형식 및 멤버 추가 + + The symbol '{0}' appears more than once in the internal API files + The symbol '{0}' appears more than once in the internal API files + + + + Do not duplicate symbols in internal API files + Do not duplicate symbols in internal API files + + The symbol '{0}' appears more than once in the public API files '{0}' 기호가 퍼블릭 API 파일에 두 번 이상 나타납니다. @@ -82,14 +122,14 @@ 공용 API 파일에서 기호를 복제하지 마세요. - - Enable nullability annotations in the public API for project '{0}' - 퍼블릭 API에서 '{0}' 프로젝트에 Null 허용 여부 주석 사용 + + Enable nullability annotations in the API for project '{0}' + Enable nullability annotations in the API for project '{0}' - - Enable nullability annotations in the public API for the solution - 퍼블릭 API에서 솔루션에 Null 허용 여부 주석 사용 + + Enable nullability annotations in the API for the solution + Enable nullability annotations in the API for the solution @@ -102,6 +142,66 @@ 생성자가 상속할 수 없는 기본 클래스를 상속할 수 있도록 만듭니다. + + implicit constructor for '{0}' + implicit constructor for '{0}' + + + + implicit get-accessor for '{0}' + implicit get-accessor for '{0}' + + + + implicit set-accessor for '{0}' + implicit set-accessor for '{0}' + + + + Internal API file '{0}' is missing or not marked as an additional analyzer file + Internal API file '{0}' is missing or not marked as an additional analyzer file + + + + Missing shipped or unshipped internal API file + Missing shipped or unshipped internal API file + + + + The contents of the internal API files are invalid: {0} + The contents of the internal API files are invalid: {0} + + + + The contents of the internal API files are invalid + The contents of the internal API files are invalid + + + + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + + + + One or both of the internal API files are missing + One or both of the internal API files are missing + + + + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + + + + Symbol '{0}' uses some oblivious reference types + Symbol '{0}' uses some oblivious reference types + + + + Internal members should not use oblivious types + Internal members should not use oblivious types + + All public members should use either nullable or non-nullable reference types, but no oblivious reference types. 모든 public 멤버는 nullable 또는 nullable이 아닌 참조 형식을 사용해야 하지만, 인식 불가능한 참조 형식은 사용하면 안 됩니다. @@ -118,13 +218,13 @@ - Symbol '{0}' violates the backcompat requirement: 'Public API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. - '{0}' 기호가 backcompat 요구 사항인 '선택적 매개 변수가 있는 공용 API에는 공용 오버로드 중 가장 많은 매개 변수를 보유해야 합니다.'를 위반합니다. 자세한 내용은 '{1}'을(를) 참조하세요. + '{0}' violates the backcompat requirement: 'API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. + '{0}' 기호가 backcompat 요구 사항인 '선택적 매개 변수가 있는 공용 API에는 공용 오버로드 중 가장 많은 매개 변수를 보유해야 합니다.'를 위반합니다. 자세한 내용은 '{1}'을(를) 참조하세요. - Public API with optional parameter(s) should have the most parameters amongst its public overloads - 선택적 매개 변수가 있는 퍼블릭 API에는 퍼블릭 오버로드 중 대부분의 매개 변수가 포함되어야 합니다. + API with optional parameter(s) should have the most parameters amongst its public overloads + 선택적 매개 변수가 있는 퍼블릭 API에는 퍼블릭 오버로드 중 대부분의 매개 변수가 포함되어야 합니다. @@ -157,34 +257,34 @@ 공용 API 파일 중 하나 또는 둘 다 없습니다. - - implicit constructor for '{0}' - '{0}'의 암시적 생성자 - + + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + {Locked="*REMOVED*"} - - implicit get-accessor for '{0}' - '{0}'의 암시적 get 접근자 + + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found - - implicit set-accessor for '{0}' - '{0}'의 암시적 set 접근자 + + Remove deleted types and members from the declared internal API + Remove deleted types and members from the declared internal API - + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. - public 형식 및 멤버를 제거할 경우 해당 항목을 '*REMOVED*' 접두사를 사용해 PublicAPI.Unshipped.txt에 넣습니다. 이렇게 하면 코드 검토와 원본 제어 기록에서 API 변경 내용에 주의를 기울이게 하고, 호환성이 손상되는 변경을 방지할 수 있습니다. + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. {Locked="*REMOVED*"} - + Symbol '{0}' is part of the declared API, but is either not public or could not be found - '{0}' 기호가 선언된 API의 일부이지만, 공용이 아니거나 찾을 수 없습니다. + Symbol '{0}' is part of the declared API, but is either not public or could not be found - + Remove deleted types and members from the declared API - 선언된 API에서 삭제된 형식 및 멤버 제거 + Remove deleted types and members from the declared API @@ -193,23 +293,38 @@ - Public API is marked as removed but it exists in source code - 공용 API가 제거됨으로 표시되지만 소스 코드에는 있습니다. + API is marked as removed but it exists in source code + 공용 API가 제거됨으로 표시되지만 소스 코드에는 있습니다. + + + + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + + + + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + + + + Enable tracking of nullability of reference types in the declared API + Enable tracking of nullability of reference types in the declared API - + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - Null 허용 여부 정보를 추적하려면 PublicAPI.txt 파일에 '#nullable enable'이 있어야 합니다. 또는 이 진단이 표시되지 않아야 합니다. Null 허용 여부를 사용하는 경우 PublicAPI.txt는 nullable 형식(형식에 접미사 '?') 또는 nullable이 아닌 형식(접미사 '!')을 기록합니다. 또한 null을 허용하지 않는 참조 형식(줄에 접두사 '~')을 계속 사용하는 모든 API를 추적합니다. + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - PublicAPI.txt에 '#nullable enable'이 없으므로 API의 Null 허용 여부 주석이 기록되지 않았습니다. 이 추적을 사용하도록 설정하는 것이 좋습니다. + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - + Enable tracking of nullability of reference types in the declared API - 선언된 API에서 참조 형식의 Null 허용 여부 추적 사용 + Enable tracking of nullability of reference types in the declared API diff --git a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.pl.xlf b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.pl.xlf index 491daaf499..2c2462c38b 100644 --- a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.pl.xlf +++ b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.pl.xlf @@ -2,34 +2,49 @@ - - Add all items in document '{0}' to the public API - Dodaj wszystkie elementy w dokumencie „{0}” do publicznego interfejsu API + + Add all items in document '{0}' to the API + Add all items in document '{0}' to the API - - Add all items in project '{0}' to the public API - Dodaj wszystkie elementy w projekcie „{0}” do publicznego interfejsu API + + Add all items in project '{0}' to the API + Add all items in project '{0}' to the API - - Add all items in the solution to the public API - Dodaj wszystkie elementy w rozwiązaniu do publicznego interfejsu API + + Add all items in the solution to the API + Add all items in the solution to the API - - Annotate all items in document '{0}' in the public API - Dodawanie adnotacji do wszystkich elementów w dokumencie „{0}” w publicznym interfejsie API + + Annotate all items in document '{0}' in the API + Annotate all items in document '{0}' in the API - - Annotate all items in project '{0}' in the public API - Dodawanie adnotacji do wszystkich elementów w projekcie „{0}” w publicznym interfejsie API + + Annotate all items in project '{0}' in the API + Annotate all items in project '{0}' in the API - - Annotate all items in the solution in the public API - Dodawanie adnotacji do wszystkich elementów w rozwiązaniu w publicznym interfejsie API + + Annotate all items in the solution in the API + Annotate all items in the solution in the API + + + + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is missing nullability annotations in the declared API + Symbol '{0}' is missing nullability annotations in the declared API + + + + Annotate nullability of internal types and members in the declared API + Annotate nullability of internal types and members in the declared API @@ -57,14 +72,29 @@ Nie dodawaj wielu przeciążeń publicznych z opcjonalnymi parametrami + + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is not part of the declared API + Symbol '{0}' is not part of the declared API + + + + Add internal types and members to the declared API + Add internal types and members to the declared API + + All public types and members should be declared in PublicAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. Wszystkie publiczne typy i składowe powinny być zadeklarowane w pliku PublicAPI.txt. To przyciąga uwagę do zmian interfejsu API w przeglądach kodu i historii kontroli źródła oraz pomaga zapobiegać zmianom powodującym nieprawidłowe działanie. - Symbol '{0}' is not part of the declared API - Symbol „{0}” nie jest częścią zadeklarowanego interfejsu API + Symbol '{0}' is not part of the declared public API + Symbol „{0}” nie jest częścią zadeklarowanego interfejsu API @@ -72,6 +102,16 @@ Dodaj publiczne typy i składowe do zadeklarowanego interfejsu API + + The symbol '{0}' appears more than once in the internal API files + The symbol '{0}' appears more than once in the internal API files + + + + Do not duplicate symbols in internal API files + Do not duplicate symbols in internal API files + + The symbol '{0}' appears more than once in the public API files Symbol „{0}” występuje więcej niż raz w plikach publicznego interfejsu API @@ -82,14 +122,14 @@ Nie duplikuj symboli w plikach publicznego interfejsu API - - Enable nullability annotations in the public API for project '{0}' - Włączanie adnotacji opcji dopuszczania wartości null w publicznym interfejsie API dla projektu „{0}” + + Enable nullability annotations in the API for project '{0}' + Enable nullability annotations in the API for project '{0}' - - Enable nullability annotations in the public API for the solution - Włączanie adnotacji opcji dopuszczania wartości null w publicznym interfejsie API dla rozwiązania + + Enable nullability annotations in the API for the solution + Enable nullability annotations in the API for the solution @@ -102,6 +142,66 @@ Konstruktor umożliwia dziedziczenie klasy podstawowej nieprzeznaczonej do dziedziczenia + + implicit constructor for '{0}' + implicit constructor for '{0}' + + + + implicit get-accessor for '{0}' + implicit get-accessor for '{0}' + + + + implicit set-accessor for '{0}' + implicit set-accessor for '{0}' + + + + Internal API file '{0}' is missing or not marked as an additional analyzer file + Internal API file '{0}' is missing or not marked as an additional analyzer file + + + + Missing shipped or unshipped internal API file + Missing shipped or unshipped internal API file + + + + The contents of the internal API files are invalid: {0} + The contents of the internal API files are invalid: {0} + + + + The contents of the internal API files are invalid + The contents of the internal API files are invalid + + + + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + + + + One or both of the internal API files are missing + One or both of the internal API files are missing + + + + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + + + + Symbol '{0}' uses some oblivious reference types + Symbol '{0}' uses some oblivious reference types + + + + Internal members should not use oblivious types + Internal members should not use oblivious types + + All public members should use either nullable or non-nullable reference types, but no oblivious reference types. Wszystkie publiczne składowe powinny używać typów referencyjnych dopuszczających wartość null lub nie dopuszczających jej, ale nie nieświadomych typów referencyjnych. @@ -118,13 +218,13 @@ - Symbol '{0}' violates the backcompat requirement: 'Public API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. - Symbol „{0}” narusza wymaganie wstecznej zgodności: „Publiczny interfejs API z opcjonalnymi parametrami powinien mieć najwięcej parametrów spośród przeciążeń publicznych”. Zobacz „{1}”, aby uzyskać szczegółowe informacje. + '{0}' violates the backcompat requirement: 'API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. + Symbol „{0}” narusza wymaganie wstecznej zgodności: „Publiczny interfejs API z opcjonalnymi parametrami powinien mieć najwięcej parametrów spośród przeciążeń publicznych”. Zobacz „{1}”, aby uzyskać szczegółowe informacje. - Public API with optional parameter(s) should have the most parameters amongst its public overloads - Publiczny interfejs API z opcjonalnymi parametrami powinien mieć najwięcej parametrów spośród jego przeciążeń publicznych + API with optional parameter(s) should have the most parameters amongst its public overloads + Publiczny interfejs API z opcjonalnymi parametrami powinien mieć najwięcej parametrów spośród jego przeciążeń publicznych @@ -157,34 +257,34 @@ Brakuje co najmniej jednego pliku publicznego interfejsu API - - implicit constructor for '{0}' - niejawny konstruktor dla elementu „{0}” - + + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + {Locked="*REMOVED*"} - - implicit get-accessor for '{0}' - niejawna metoda dostępu get dla elementu „{0}” + + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found - - implicit set-accessor for '{0}' - niejawna metoda dostępu set dla elementu „{0}” + + Remove deleted types and members from the declared internal API + Remove deleted types and members from the declared internal API - + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. - W przypadku usunięcia typu publicznego lub składowej należy usunąć także powiązany wpis w pliku PublicAPI.Unshipped.txt. z prefiksem ’*REMOVED*’. To przyciąga uwagę do zmian interfejsu API w przeglądach kodu i historii kontroli źródła oraz pomaga zapobiegać zmianom powodującym nieprawidłowe działanie. + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. {Locked="*REMOVED*"} - + Symbol '{0}' is part of the declared API, but is either not public or could not be found - Symbol „{0}” jest częścią zadeklarowanego interfejsu API, ale nie jest publiczny lub nie można go odnaleźć + Symbol '{0}' is part of the declared API, but is either not public or could not be found - + Remove deleted types and members from the declared API - Usuń usunięte typy i składowe z zadeklarowanego interfejsu API + Remove deleted types and members from the declared API @@ -193,23 +293,38 @@ - Public API is marked as removed but it exists in source code - Publiczny interfejs API został oznaczony jako usunięty, ale istnieje w kodzie źródłowym + API is marked as removed but it exists in source code + Publiczny interfejs API został oznaczony jako usunięty, ale istnieje w kodzie źródłowym + + + + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + + + + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + + + + Enable tracking of nullability of reference types in the declared API + Enable tracking of nullability of reference types in the declared API - + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - Pliki PublicAPI.txt powinny zawierać wartość „#nullable enable” w celu śledzenia informacji o dopuszczaniu wartości null lub należy pominąć tę diagnostykę. W przypadku włączenia informacji o dopuszczaniu wartości null plik PublicAPI.txt rejestruje typy dopuszczające wartość null (sufiks „?” dla typu) i niedopuszczające wartości null (sufiks „!”). Śledzi on również wszelkie interfejsy API, które nadal korzystają z nieświadomego typu odwołania (prefiks „~” w wierszu). + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - W pliku PublicAPI.txt brakuje elementu „#nullable enable”, dlatego adnotacje opcji dopuszczania wartości null nie są rejestrowane. Zaleca się włączenie tego śledzenia. + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - + Enable tracking of nullability of reference types in the declared API - Włącz śledzenie wartości null typów referencyjnych w zadeklarowanym interfejsie API + Enable tracking of nullability of reference types in the declared API diff --git a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.pt-BR.xlf b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.pt-BR.xlf index 6cd65553d0..a05eff2a40 100644 --- a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.pt-BR.xlf +++ b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.pt-BR.xlf @@ -2,34 +2,49 @@ - - Add all items in document '{0}' to the public API - Adicionar todos os itens no documento '{0}' à API pública + + Add all items in document '{0}' to the API + Add all items in document '{0}' to the API - - Add all items in project '{0}' to the public API - Adicionar todos os itens no projeto '{0}' à API pública + + Add all items in project '{0}' to the API + Add all items in project '{0}' to the API - - Add all items in the solution to the public API - Adicionar todos os itens da solução à API pública + + Add all items in the solution to the API + Add all items in the solution to the API - - Annotate all items in document '{0}' in the public API - Anotar todos os itens do documento '{0}' na API pública + + Annotate all items in document '{0}' in the API + Annotate all items in document '{0}' in the API - - Annotate all items in project '{0}' in the public API - Anotar todos os itens do projeto '{0}' na API pública + + Annotate all items in project '{0}' in the API + Annotate all items in project '{0}' in the API - - Annotate all items in the solution in the public API - Anotar todos os itens da solução na API pública + + Annotate all items in the solution in the API + Annotate all items in the solution in the API + + + + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is missing nullability annotations in the declared API + Symbol '{0}' is missing nullability annotations in the declared API + + + + Annotate nullability of internal types and members in the declared API + Annotate nullability of internal types and members in the declared API @@ -57,14 +72,29 @@ Não adicione várias sobrecargas públicas com parâmetros opcionais + + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is not part of the declared API + Symbol '{0}' is not part of the declared API + + + + Add internal types and members to the declared API + Add internal types and members to the declared API + + All public types and members should be declared in PublicAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. Todos os tipos e membros públicos devem ser declarados no PublicAPI.txt. Isso chama a atenção para as alterações da API no histórico de revisões de código e de controle do código-fonte e ajuda a evitar alterações interruptivas. - Symbol '{0}' is not part of the declared API - O símbolo '{0}' não faz parte da API declarada + Symbol '{0}' is not part of the declared public API + O símbolo '{0}' não faz parte da API declarada @@ -72,6 +102,16 @@ Adicionar membros e tipos públicos à API declarada + + The symbol '{0}' appears more than once in the internal API files + The symbol '{0}' appears more than once in the internal API files + + + + Do not duplicate symbols in internal API files + Do not duplicate symbols in internal API files + + The symbol '{0}' appears more than once in the public API files O símbolo '{0}' aparece mais de uma vez nos arquivos da API pública @@ -82,14 +122,14 @@ Não duplique símbolos em arquivos de API pública - - Enable nullability annotations in the public API for project '{0}' - Habilitar anotações de nulidade na API pública para o projeto '{0}' + + Enable nullability annotations in the API for project '{0}' + Enable nullability annotations in the API for project '{0}' - - Enable nullability annotations in the public API for the solution - Habilitar anotações de nulidade na API pública para a solução + + Enable nullability annotations in the API for the solution + Enable nullability annotations in the API for the solution @@ -102,6 +142,66 @@ O construtor transforma a classe base não herdável em herdável + + implicit constructor for '{0}' + implicit constructor for '{0}' + + + + implicit get-accessor for '{0}' + implicit get-accessor for '{0}' + + + + implicit set-accessor for '{0}' + implicit set-accessor for '{0}' + + + + Internal API file '{0}' is missing or not marked as an additional analyzer file + Internal API file '{0}' is missing or not marked as an additional analyzer file + + + + Missing shipped or unshipped internal API file + Missing shipped or unshipped internal API file + + + + The contents of the internal API files are invalid: {0} + The contents of the internal API files are invalid: {0} + + + + The contents of the internal API files are invalid + The contents of the internal API files are invalid + + + + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + + + + One or both of the internal API files are missing + One or both of the internal API files are missing + + + + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + + + + Symbol '{0}' uses some oblivious reference types + Symbol '{0}' uses some oblivious reference types + + + + Internal members should not use oblivious types + Internal members should not use oblivious types + + All public members should use either nullable or non-nullable reference types, but no oblivious reference types. Todos os membros públicos devem usar tipos de referência que permitem valor nulo ou não anuláveis, mas nenhum tipo de referência inconsistente. @@ -118,13 +218,13 @@ - Symbol '{0}' violates the backcompat requirement: 'Public API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. - O símbolo '{0}' viola o requisito de backcompat: 'A API pública com parâmetros opcionais deve ter a maioria dos parâmetros entre suas sobrecargas públicas. Confira '{1}' para obter detalhes. + '{0}' violates the backcompat requirement: 'API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. + O símbolo '{0}' viola o requisito de backcompat: 'A API pública com parâmetros opcionais deve ter a maioria dos parâmetros entre suas sobrecargas públicas. Confira '{1}' para obter detalhes. - Public API with optional parameter(s) should have the most parameters amongst its public overloads - A API pública com parâmetros opcionais deve ter a maioria dos parâmetros entre as sobrecargas públicas dela + API with optional parameter(s) should have the most parameters amongst its public overloads + A API pública com parâmetros opcionais deve ter a maioria dos parâmetros entre as sobrecargas públicas dela @@ -157,34 +257,34 @@ Um ou ambos os arquivos de API pública estão ausentes - - implicit constructor for '{0}' - construtor implícito para '{0}' - + + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + {Locked="*REMOVED*"} - - implicit get-accessor for '{0}' - acessador get implícito para '{0}' + + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found - - implicit set-accessor for '{0}' - acessador set implícito para '{0}' + + Remove deleted types and members from the declared internal API + Remove deleted types and members from the declared internal API - + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. - Ao remover um tipo ou membro público, coloque essa entrada em PublicAPI.Unshipped.txt com o prefixo '*REMOVED*'. Isso chama a atenção para as alterações da API nas revisões de código e no histórico de controle de origem e ajuda a evitar alterações significativas. + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. {Locked="*REMOVED*"} - + Symbol '{0}' is part of the declared API, but is either not public or could not be found - O símbolo '{0}' faz parte da API declarada, mas não é público ou não pôde ser encontrado + Symbol '{0}' is part of the declared API, but is either not public or could not be found - + Remove deleted types and members from the declared API - Remova os tipos e membros excluídos da API declarada + Remove deleted types and members from the declared API @@ -193,23 +293,38 @@ - Public API is marked as removed but it exists in source code - A API pública está marcada como removida, mas existe no código-fonte + API is marked as removed but it exists in source code + A API pública está marcada como removida, mas existe no código-fonte + + + + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + + + + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + + + + Enable tracking of nullability of reference types in the declared API + Enable tracking of nullability of reference types in the declared API - + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - Os arquivos PublicAPI.txt devem ter `#nullable enable` para controlar as informações de nulidade ou esse diagnóstico deve ser suprimido. Com a nulidade habilitada, o PublicAPI.txt registra quais tipos são anuláveis (sufixo `?` no tipo) ou não anuláveis (sufixo `!`). Ele também rastreia APIs que ainda estejam usando um tipo de referência alheio (prefixo `~` na linha). + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - O PublicAPI.txt está sem '#nullable enable', portanto, as anotações de nulidade da API não estão sendo registradas. É recomendado que esse controle seja habilitado. + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - + Enable tracking of nullability of reference types in the declared API - Habilitar o acompanhamento de nulidade de tipos de referência na API declarada + Enable tracking of nullability of reference types in the declared API diff --git a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.ru.xlf b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.ru.xlf index d66585228f..29f2448b31 100644 --- a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.ru.xlf +++ b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.ru.xlf @@ -2,34 +2,49 @@ - - Add all items in document '{0}' to the public API - Добавление всех элементов в документе "{0}" в общедоступный API + + Add all items in document '{0}' to the API + Add all items in document '{0}' to the API - - Add all items in project '{0}' to the public API - Добавление всех элементов в проекте "{0}" в общедоступный API + + Add all items in project '{0}' to the API + Add all items in project '{0}' to the API - - Add all items in the solution to the public API - Добавление всех элементов в решении в общедоступный API + + Add all items in the solution to the API + Add all items in the solution to the API - - Annotate all items in document '{0}' in the public API - Аннотирование всех элементов в документе "{0}" в общедоступном API + + Annotate all items in document '{0}' in the API + Annotate all items in document '{0}' in the API - - Annotate all items in project '{0}' in the public API - Аннотирование всех элементов в проекте "{0}" в общедоступном API + + Annotate all items in project '{0}' in the API + Annotate all items in project '{0}' in the API - - Annotate all items in the solution in the public API - Аннотирование всех элементов в решении в общедоступном API + + Annotate all items in the solution in the API + Annotate all items in the solution in the API + + + + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is missing nullability annotations in the declared API + Symbol '{0}' is missing nullability annotations in the declared API + + + + Annotate nullability of internal types and members in the declared API + Annotate nullability of internal types and members in the declared API @@ -57,14 +72,29 @@ Не добавляйте несколько общедоступных перегрузок с необязательными параметрами + + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is not part of the declared API + Symbol '{0}' is not part of the declared API + + + + Add internal types and members to the declared API + Add internal types and members to the declared API + + All public types and members should be declared in PublicAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. Все открытые типы и элементы должны быть объявлены в PublicAPI.txt. Это привлекает внимание к изменениям API при проверках кода и в журнале системы управления версиями и помогает предотвратить критические изменения. - Symbol '{0}' is not part of the declared API - Символ "{0}" не является частью объявленного API. + Symbol '{0}' is not part of the declared public API + Символ "{0}" не является частью объявленного API. @@ -72,6 +102,16 @@ Добавьте открытые типы и элементы в объявленный API + + The symbol '{0}' appears more than once in the internal API files + The symbol '{0}' appears more than once in the internal API files + + + + Do not duplicate symbols in internal API files + Do not duplicate symbols in internal API files + + The symbol '{0}' appears more than once in the public API files Символ "{0}" встречается больше одного раза в файлах открытого API. @@ -82,14 +122,14 @@ Не дублируйте символы в файлах открытого API - - Enable nullability annotations in the public API for project '{0}' - Включите заметки о допустимости значений NULL в общедоступном API для проекта "{0}" + + Enable nullability annotations in the API for project '{0}' + Enable nullability annotations in the API for project '{0}' - - Enable nullability annotations in the public API for the solution - Включите заметки о допустимости значений NULL в общедоступном API для решения + + Enable nullability annotations in the API for the solution + Enable nullability annotations in the API for the solution @@ -102,6 +142,66 @@ Конструктор делает ненаследуемый базовый класс наследуемым + + implicit constructor for '{0}' + implicit constructor for '{0}' + + + + implicit get-accessor for '{0}' + implicit get-accessor for '{0}' + + + + implicit set-accessor for '{0}' + implicit set-accessor for '{0}' + + + + Internal API file '{0}' is missing or not marked as an additional analyzer file + Internal API file '{0}' is missing or not marked as an additional analyzer file + + + + Missing shipped or unshipped internal API file + Missing shipped or unshipped internal API file + + + + The contents of the internal API files are invalid: {0} + The contents of the internal API files are invalid: {0} + + + + The contents of the internal API files are invalid + The contents of the internal API files are invalid + + + + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + + + + One or both of the internal API files are missing + One or both of the internal API files are missing + + + + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + + + + Symbol '{0}' uses some oblivious reference types + Symbol '{0}' uses some oblivious reference types + + + + Internal members should not use oblivious types + Internal members should not use oblivious types + + All public members should use either nullable or non-nullable reference types, but no oblivious reference types. Все открытые элементы должны использовать ссылочные типы, допускающие или не допускающие значение null, но не игнорируемые ссылочные типы. @@ -118,13 +218,13 @@ - Symbol '{0}' violates the backcompat requirement: 'Public API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. - Символ "{0}" нарушает требование обратной совместимости: "Открытый API с необязательными параметрами должен иметь основную часть параметров среди своих открытых перегрузок". Дополнительные сведения см. в "{1}". + '{0}' violates the backcompat requirement: 'API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. + Символ "{0}" нарушает требование обратной совместимости: "Открытый API с необязательными параметрами должен иметь основную часть параметров среди своих открытых перегрузок". Дополнительные сведения см. в "{1}". - Public API with optional parameter(s) should have the most parameters amongst its public overloads - Большинство параметров открытого API с необязательными параметрами должны находиться среди открытых перегрузок этого API + API with optional parameter(s) should have the most parameters amongst its public overloads + Большинство параметров открытого API с необязательными параметрами должны находиться среди открытых перегрузок этого API @@ -157,34 +257,34 @@ Отсутствует один или оба файла открытого API - - implicit constructor for '{0}' - неявный конструктор для "{0}" - + + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + {Locked="*REMOVED*"} - - implicit get-accessor for '{0}' - неявный метод доступа get для "{0}" + + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found - - implicit set-accessor for '{0}' - неявный метод доступа set для "{0}" + + Remove deleted types and members from the declared internal API + Remove deleted types and members from the declared internal API - + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. - При удалении открытого типа или элемента поместите эту запись в файл PublicAPI.Unshipped.txt с префиксом "*REMOVED*". Это привлечет внимание к изменениями API при проверке кода и в истории управления версиями, а также поможет предотвратить критические изменения. + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. {Locked="*REMOVED*"} - + Symbol '{0}' is part of the declared API, but is either not public or could not be found - Символ "{0}" является частью объявленного API, однако не является открытым либо не был найден + Symbol '{0}' is part of the declared API, but is either not public or could not be found - + Remove deleted types and members from the declared API - Удалите удаленные типы и элементы из объявленного API + Remove deleted types and members from the declared API @@ -193,23 +293,38 @@ - Public API is marked as removed but it exists in source code - Открытый API помечен как удаленный, но он существует в исходном коде + API is marked as removed but it exists in source code + Открытый API помечен как удаленный, но он существует в исходном коде + + + + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + + + + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + + + + Enable tracking of nullability of reference types in the declared API + Enable tracking of nullability of reference types in the declared API - + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - Для файлов PublicAPI.txt необходимо установить директиву #nullable enable, чтобы отслеживать сведения о допустимости значений NULL, либо отключить этот параметр диагностики. Если значения NULL являются допустимыми, в файлах PublicAPI.txt записываются типы, которые допускают значения NULL (суффикс "?" типа) или не допускают значения NULL (суффикс "!"). Также отслеживаются все API, в которых все еще используется ссылочный тип без заметок о допустимости значений NULL (префикс "~" в строке). + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - В файле PublicAPI.txt отсутствует "#nullable enable", поэтому заметки о допустимости значений NULL для API не записываются. Рекомендуется включить их отслеживание. + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - + Enable tracking of nullability of reference types in the declared API - Включение отслеживания допустимости значений NULL ссылочных типов в объявленном API + Enable tracking of nullability of reference types in the declared API diff --git a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.tr.xlf b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.tr.xlf index 47b798c428..b835577bd9 100644 --- a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.tr.xlf +++ b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.tr.xlf @@ -2,34 +2,49 @@ - - Add all items in document '{0}' to the public API - '{0}' belgesindeki tüm öğeleri genel API'ye ekle + + Add all items in document '{0}' to the API + Add all items in document '{0}' to the API - - Add all items in project '{0}' to the public API - '{0}' projesindeki tüm öğeleri genel API'ye ekle + + Add all items in project '{0}' to the API + Add all items in project '{0}' to the API - - Add all items in the solution to the public API - Çözümdeki tüm öğeleri genel API'ye ekle + + Add all items in the solution to the API + Add all items in the solution to the API - - Annotate all items in document '{0}' in the public API - Genel API'de yer alan '{0}' belgesindeki tüm öğelere not ekle + + Annotate all items in document '{0}' in the API + Annotate all items in document '{0}' in the API - - Annotate all items in project '{0}' in the public API - Genel API'de yer alan '{0}' projesindeki tüm öğelere not ekle + + Annotate all items in project '{0}' in the API + Annotate all items in project '{0}' in the API - - Annotate all items in the solution in the public API - Genel API'de yer alan çözümdeki tüm öğelere not ekle + + Annotate all items in the solution in the API + Annotate all items in the solution in the API + + + + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is missing nullability annotations in the declared API + Symbol '{0}' is missing nullability annotations in the declared API + + + + Annotate nullability of internal types and members in the declared API + Annotate nullability of internal types and members in the declared API @@ -57,14 +72,29 @@ İsteğe bağlı parametreleri olan birden fazla genel aşırı yükleme eklemeyin + + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is not part of the declared API + Symbol '{0}' is not part of the declared API + + + + Add internal types and members to the declared API + Add internal types and members to the declared API + + All public types and members should be declared in PublicAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. Tüm genel türler ve üyeler PublicAPI.txt içinde bildirilmelidir. Bu işlem, kod incelemeleri ve kaynak denetimi geçmişindeki API değişikliklerine dikkat çeker ve hataya neden olan değişikliklerin önlenmesine yardımcı olur. - Symbol '{0}' is not part of the declared API - '{0}' sembolü bildirilen API'nin bir parçası değil + Symbol '{0}' is not part of the declared public API + '{0}' sembolü bildirilen API'nin bir parçası değil @@ -72,6 +102,16 @@ Genel türleri ve üyeleri bildirilen API'ye ekleyin + + The symbol '{0}' appears more than once in the internal API files + The symbol '{0}' appears more than once in the internal API files + + + + Do not duplicate symbols in internal API files + Do not duplicate symbols in internal API files + + The symbol '{0}' appears more than once in the public API files '{0}' sembolü, genel API dosyalarında birden çok kez görünüyor @@ -82,14 +122,14 @@ Genel API dosyalarında sembolleri yinelemeyin - - Enable nullability annotations in the public API for project '{0}' - '{0}' projesi için genel API'deki null atanabilirlik ek açıklamalarını etkinleştir + + Enable nullability annotations in the API for project '{0}' + Enable nullability annotations in the API for project '{0}' - - Enable nullability annotations in the public API for the solution - Çözüm için genel API'deki null atanabilirlik ek açıklamalarını etkinleştir + + Enable nullability annotations in the API for the solution + Enable nullability annotations in the API for the solution @@ -102,6 +142,66 @@ Oluşturucu, devralınamayan temel sınıfı devralınabilir hale getirir + + implicit constructor for '{0}' + implicit constructor for '{0}' + + + + implicit get-accessor for '{0}' + implicit get-accessor for '{0}' + + + + implicit set-accessor for '{0}' + implicit set-accessor for '{0}' + + + + Internal API file '{0}' is missing or not marked as an additional analyzer file + Internal API file '{0}' is missing or not marked as an additional analyzer file + + + + Missing shipped or unshipped internal API file + Missing shipped or unshipped internal API file + + + + The contents of the internal API files are invalid: {0} + The contents of the internal API files are invalid: {0} + + + + The contents of the internal API files are invalid + The contents of the internal API files are invalid + + + + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + + + + One or both of the internal API files are missing + One or both of the internal API files are missing + + + + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + + + + Symbol '{0}' uses some oblivious reference types + Symbol '{0}' uses some oblivious reference types + + + + Internal members should not use oblivious types + Internal members should not use oblivious types + + All public members should use either nullable or non-nullable reference types, but no oblivious reference types. Tüm genel üyeler null atanabilir veya null atanamaz başvuru türleri kullanmalıdır ancak uyarısız atanabilen başvuru türü içermemelidir. @@ -118,13 +218,13 @@ - Symbol '{0}' violates the backcompat requirement: 'Public API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. - '{0}' sembolü geriye dönük uyumluluk gereksinimini ihlal ediyor: 'İsteğe bağlı parametreleri olan genel API'nin, genel aşırı yüklemeleri arasında en çok parametreye sahip olması gerekir.' Ayrıntılar için bkz. '{1}'. + '{0}' violates the backcompat requirement: 'API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. + '{0}' sembolü geriye dönük uyumluluk gereksinimini ihlal ediyor: 'İsteğe bağlı parametreleri olan genel API'nin, genel aşırı yüklemeleri arasında en çok parametreye sahip olması gerekir.' Ayrıntılar için bkz. '{1}'. - Public API with optional parameter(s) should have the most parameters amongst its public overloads - İsteğe bağlı parametreler içeren genel API'nin, en çok parametreye genel aşırı yüklemelerinde sahip olması gerekir + API with optional parameter(s) should have the most parameters amongst its public overloads + İsteğe bağlı parametreler içeren genel API'nin, en çok parametreye genel aşırı yüklemelerinde sahip olması gerekir @@ -157,34 +257,34 @@ Ortak API dosyalarından biri veya her ikisi de eksik - - implicit constructor for '{0}' - '{0}' için örtük oluşturucu - + + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + {Locked="*REMOVED*"} - - implicit get-accessor for '{0}' - '{0}' için örtük get erişimcisi + + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found - - implicit set-accessor for '{0}' - '{0}' için örtük set erişimcisi + + Remove deleted types and members from the declared internal API + Remove deleted types and members from the declared internal API - + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. - Bir genel türü veya üyeyi kaldırırken, bu girişi PublicAPI.Unshipped.txt dosyasına '*REMOVED*' önekiyle birlikte yerleştirin. Bu işlem, kod incelemeleri ve kaynak denetimi geçmişindeki API değişikliklerine dikkat çeker ve hataya neden olan değişikliklerin önlenmesine yardımcı olur. + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. {Locked="*REMOVED*"} - + Symbol '{0}' is part of the declared API, but is either not public or could not be found - '{0}' sembolü bildirilen API'nin parçası, ancak genel değil veya bulunamadı + Symbol '{0}' is part of the declared API, but is either not public or could not be found - + Remove deleted types and members from the declared API - Silinen türleri ve üyeleri bildirilen API'den kaldırın + Remove deleted types and members from the declared API @@ -193,23 +293,38 @@ - Public API is marked as removed but it exists in source code - Genel API kaldırıldı olarak işaretlenmiş ancak kaynak kodunda mevcut + API is marked as removed but it exists in source code + Genel API kaldırıldı olarak işaretlenmiş ancak kaynak kodunda mevcut + + + + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + + + + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + + + + Enable tracking of nullability of reference types in the declared API + Enable tracking of nullability of reference types in the declared API - + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - PublicAPI.txt dosyalarında null atanabilirlik bilgilerini izlemek için `#nullable enable` bulunmalıdır veya bu tanılama gizlenmelidir. Null atanabilirlik etkin olduğunda PublicAPI.txt, null atanabilir (türde `?` soneki) veya null atanamaz (`!` soneki) türleri kaydeder. Ayrıca, hala bir kayıtsız başvuru türünü (satırda `~` ön eki) kullanan tüm API'leri de izler. + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - PublicAPI.txt dosyasında '#nullable enable' eksik olduğundan API'nin null atanabilirlik ek açıklamaları kaydedilmiyor. Bu izlemenin etkinleştirilmesi önerilir. + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - + Enable tracking of nullability of reference types in the declared API - Bildirilen API'de başvuru türlerinin null olduğunu izlemeyi etkinleştirin + Enable tracking of nullability of reference types in the declared API diff --git a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.zh-Hans.xlf b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.zh-Hans.xlf index b782b2400a..ebe20b9864 100644 --- a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.zh-Hans.xlf +++ b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.zh-Hans.xlf @@ -2,34 +2,49 @@ - - Add all items in document '{0}' to the public API - 将文档“{0}”中的所有项添加到公共 API + + Add all items in document '{0}' to the API + Add all items in document '{0}' to the API - - Add all items in project '{0}' to the public API - 将项目“{0}”中的所有项添加到公共 API + + Add all items in project '{0}' to the API + Add all items in project '{0}' to the API - - Add all items in the solution to the public API - 将解决方案中的所有项添加到公共 API + + Add all items in the solution to the API + Add all items in the solution to the API - - Annotate all items in document '{0}' in the public API - 在公共 API 中对文档“{0}”中的所有项进行批注 + + Annotate all items in document '{0}' in the API + Annotate all items in document '{0}' in the API - - Annotate all items in project '{0}' in the public API - 在公共 API 中对项目“{0}”中的所有项进行批注 + + Annotate all items in project '{0}' in the API + Annotate all items in project '{0}' in the API - - Annotate all items in the solution in the public API - 在公共 API 中对解决方案中的所有项进行批注 + + Annotate all items in the solution in the API + Annotate all items in the solution in the API + + + + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is missing nullability annotations in the declared API + Symbol '{0}' is missing nullability annotations in the declared API + + + + Annotate nullability of internal types and members in the declared API + Annotate nullability of internal types and members in the declared API @@ -57,14 +72,29 @@ 请勿添加具有可选参数的多个公共重载 + + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is not part of the declared API + Symbol '{0}' is not part of the declared API + + + + Add internal types and members to the declared API + Add internal types and members to the declared API + + All public types and members should be declared in PublicAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. 应在 PublicAPI.txt 中声明所有公共类型和成员。这将关注代码评审和源代码管理历史记录中的 API 更改,并有助于防止重大更改。 - Symbol '{0}' is not part of the declared API - 符号“{0}”不是已声明 API 的一部分 + Symbol '{0}' is not part of the declared public API + 符号“{0}”不是已声明 API 的一部分 @@ -72,6 +102,16 @@ 向已声明 API 添加公共类型和成员 + + The symbol '{0}' appears more than once in the internal API files + The symbol '{0}' appears more than once in the internal API files + + + + Do not duplicate symbols in internal API files + Do not duplicate symbols in internal API files + + The symbol '{0}' appears more than once in the public API files 符号“{0}”多次出现在公共 API 文件中 @@ -82,14 +122,14 @@ 请勿在公共 API 文件中复制符号 - - Enable nullability annotations in the public API for project '{0}' - 在项目“{0}”的公共 API 中启用为 Null 性注释 + + Enable nullability annotations in the API for project '{0}' + Enable nullability annotations in the API for project '{0}' - - Enable nullability annotations in the public API for the solution - 在解决方案的公共 API 中启用为 Null 性注释 + + Enable nullability annotations in the API for the solution + Enable nullability annotations in the API for the solution @@ -102,6 +142,66 @@ 构造函数使不可继承的基类可以继承 + + implicit constructor for '{0}' + implicit constructor for '{0}' + + + + implicit get-accessor for '{0}' + implicit get-accessor for '{0}' + + + + implicit set-accessor for '{0}' + implicit set-accessor for '{0}' + + + + Internal API file '{0}' is missing or not marked as an additional analyzer file + Internal API file '{0}' is missing or not marked as an additional analyzer file + + + + Missing shipped or unshipped internal API file + Missing shipped or unshipped internal API file + + + + The contents of the internal API files are invalid: {0} + The contents of the internal API files are invalid: {0} + + + + The contents of the internal API files are invalid + The contents of the internal API files are invalid + + + + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + + + + One or both of the internal API files are missing + One or both of the internal API files are missing + + + + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + + + + Symbol '{0}' uses some oblivious reference types + Symbol '{0}' uses some oblivious reference types + + + + Internal members should not use oblivious types + Internal members should not use oblivious types + + All public members should use either nullable or non-nullable reference types, but no oblivious reference types. 所有公共成员都应使用可以为 null 或不可为 null 的引用类型,但不能使用未知引用类型。 @@ -118,13 +218,13 @@ - Symbol '{0}' violates the backcompat requirement: 'Public API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. - 符号“{0}”违反了 backcompat 要求:“具有可选参数的公共 API 应在其公共重载中具有最多参数”。有关详细信息,请参阅“{1}”。 + '{0}' violates the backcompat requirement: 'API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. + 符号“{0}”违反了 backcompat 要求:“具有可选参数的公共 API 应在其公共重载中具有最多参数”。有关详细信息,请参阅“{1}”。 - Public API with optional parameter(s) should have the most parameters amongst its public overloads - 具有可选参数的公共 API 应在其公共重载中具有最多参数 + API with optional parameter(s) should have the most parameters amongst its public overloads + 具有可选参数的公共 API 应在其公共重载中具有最多参数 @@ -157,34 +257,34 @@ 缺少一个或两个公共 API 文件 - - implicit constructor for '{0}' - “{0}”的隐式构造函数 - + + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + {Locked="*REMOVED*"} - - implicit get-accessor for '{0}' - “{0}”的隐式 get 访问器 + + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found - - implicit set-accessor for '{0}' - “{0}”的隐式 set 访问器 + + Remove deleted types and members from the declared internal API + Remove deleted types and members from the declared internal API - + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. - 删除公共类型或成员时,将其项输入 PublicAPI.Unshipped.txt 中,并附上前缀 "*REMOVED*"。这样能够在代码评审和源代码管理历史记录中引起对 API 更改的注意,有助于防止中断性更改。 + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. {Locked="*REMOVED*"} - + Symbol '{0}' is part of the declared API, but is either not public or could not be found - 符号“{0}”是已声明 API 的一部分,但此符号不是公共符号或无法找到 + Symbol '{0}' is part of the declared API, but is either not public or could not be found - + Remove deleted types and members from the declared API - 从已声明 API 中删除已删除的类型和成员 + Remove deleted types and members from the declared API @@ -193,23 +293,38 @@ - Public API is marked as removed but it exists in source code - 公共 API 标记为已删除,但它存在于源代码中 + API is marked as removed but it exists in source code + 公共 API 标记为已删除,但它存在于源代码中 + + + + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + + + + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + + + + Enable tracking of nullability of reference types in the declared API + Enable tracking of nullability of reference types in the declared API - + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - PublicAPI.txt 文件应具有 "#nullable enable" 以跟踪为 Null 性信息,或者应取消显示此诊断。如果启用了为 Null 性,则 PublicAPI.txt 会记录哪些类型可为 Null (类型上带后缀 "?")而哪些不可为 Null (带后缀 "!")。它还会跟踪所有仍在使用不带此信息的引用类型(行上带前缀 "~")的 API。 + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - PublicAPI.txt 缺少 "#nullable enable",因此不会记录 API 的为 Null 性注释。建议启用此跟踪。 + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - + Enable tracking of nullability of reference types in the declared API - 在已声明 API 中启用对引用类型的为 Null 性的跟踪 + Enable tracking of nullability of reference types in the declared API diff --git a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.zh-Hant.xlf b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.zh-Hant.xlf index 2799bb93dc..653506306e 100644 --- a/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.zh-Hant.xlf +++ b/src/PublicApiAnalyzers/Core/Analyzers/xlf/PublicApiAnalyzerResources.zh-Hant.xlf @@ -2,34 +2,49 @@ - - Add all items in document '{0}' to the public API - 將文件 '{0}' 中的所有項目新增至公用 API + + Add all items in document '{0}' to the API + Add all items in document '{0}' to the API - - Add all items in project '{0}' to the public API - 將專案 '{0}' 中的所有項目新增至公用 API + + Add all items in project '{0}' to the API + Add all items in project '{0}' to the API - - Add all items in the solution to the public API - 將解決方案中的所有項目新增至公用 API + + Add all items in the solution to the API + Add all items in the solution to the API - - Annotate all items in document '{0}' in the public API - 標註公用 API 中文件 '{0}' 的所有項目 + + Annotate all items in document '{0}' in the API + Annotate all items in document '{0}' in the API - - Annotate all items in project '{0}' in the public API - 標註公用 API 中專案 '{0}' 的所有項目 + + Annotate all items in project '{0}' in the API + Annotate all items in project '{0}' in the API - - Annotate all items in the solution in the public API - 標註公用 API 中解決方案的所有項目 + + Annotate all items in the solution in the API + Annotate all items in the solution in the API + + + + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared with nullability annotations in InternalAPI.txt. This draws attention to API nullability changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is missing nullability annotations in the declared API + Symbol '{0}' is missing nullability annotations in the declared API + + + + Annotate nullability of internal types and members in the declared API + Annotate nullability of internal types and members in the declared API @@ -57,14 +72,29 @@ 無法新增多個具有選擇性參數的公用多載 + + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + All internal types and members should be declared in InternalAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + + + + Symbol '{0}' is not part of the declared API + Symbol '{0}' is not part of the declared API + + + + Add internal types and members to the declared API + Add internal types and members to the declared API + + All public types and members should be declared in PublicAPI.txt. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. 應在 PublicAPI.txt 中宣告所有公用類型與成員。此舉會讓您注意到程式碼檢閱與原始檔控制歷程記錄中的 API 變更,同時有助於避免發生中斷性變更。 - Symbol '{0}' is not part of the declared API - 符號 '{0}' 並非宣告 API 的一部分 + Symbol '{0}' is not part of the declared public API + 符號 '{0}' 並非宣告 API 的一部分 @@ -72,6 +102,16 @@ 為宣告的 API 新增公用類型與成員 + + The symbol '{0}' appears more than once in the internal API files + The symbol '{0}' appears more than once in the internal API files + + + + Do not duplicate symbols in internal API files + Do not duplicate symbols in internal API files + + The symbol '{0}' appears more than once in the public API files 公用 API 檔案中出現多次符號 '{0}' @@ -82,14 +122,14 @@ 請勿在公用 API 檔案中使用重複的符號 - - Enable nullability annotations in the public API for project '{0}' - 啟用公用 API 中專案 '{0}' 的可 NULL 性註釋 + + Enable nullability annotations in the API for project '{0}' + Enable nullability annotations in the API for project '{0}' - - Enable nullability annotations in the public API for the solution - 啟用公用 API 中解決方案的可 NULL 性註釋 + + Enable nullability annotations in the API for the solution + Enable nullability annotations in the API for the solution @@ -102,6 +142,66 @@ 建構函式可將無法繼承的基底類別變成為可繼承 + + implicit constructor for '{0}' + implicit constructor for '{0}' + + + + implicit get-accessor for '{0}' + implicit get-accessor for '{0}' + + + + implicit set-accessor for '{0}' + implicit set-accessor for '{0}' + + + + Internal API file '{0}' is missing or not marked as an additional analyzer file + Internal API file '{0}' is missing or not marked as an additional analyzer file + + + + Missing shipped or unshipped internal API file + Missing shipped or unshipped internal API file + + + + The contents of the internal API files are invalid: {0} + The contents of the internal API files are invalid: {0} + + + + The contents of the internal API files are invalid + The contents of the internal API files are invalid + + + + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + The solution must contain two files with the type "AdditionalFiles": InternalAPI.Unshipped.txt and internalAPI.Shipped.txt. At least one of these files is missing or has the wrong type. + + + + One or both of the internal API files are missing + One or both of the internal API files are missing + + + + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + All internal members should use either nullable or non-nullable reference types, but no oblivious reference types. + + + + Symbol '{0}' uses some oblivious reference types + Symbol '{0}' uses some oblivious reference types + + + + Internal members should not use oblivious types + Internal members should not use oblivious types + + All public members should use either nullable or non-nullable reference types, but no oblivious reference types. 所有公開成員都應使用可為 Null 或不可為 Null 的參考型別,但不可使用無警示的參考型別。 @@ -118,13 +218,13 @@ - Symbol '{0}' violates the backcompat requirement: 'Public API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. - 符號 '{0}' 違反回溯相容性需求:「具有選擇性參數的公用 API,大部分的參數應位於其公用多載之間。」。請參閱 '{1}' 以取得詳細資料。 + '{0}' violates the backcompat requirement: 'API with optional parameter(s) should have the most parameters amongst its public overloads'. See '{1}' for details. + 符號 '{0}' 違反回溯相容性需求:「具有選擇性參數的公用 API,大部分的參數應位於其公用多載之間。」。請參閱 '{1}' 以取得詳細資料。 - Public API with optional parameter(s) should have the most parameters amongst its public overloads - 具有選擇性參數的公用 API,大部分的參數應位於其公用多載之間 + API with optional parameter(s) should have the most parameters amongst its public overloads + 具有選擇性參數的公用 API,大部分的參數應位於其公用多載之間 @@ -157,34 +257,34 @@ 缺少兩個公用 API 檔案的其中一個或兩者 - - implicit constructor for '{0}' - '{0}' 的隱含建構函式 - + + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + When removing a internal type or member, put that entry in InternalAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. + {Locked="*REMOVED*"} - - implicit get-accessor for '{0}' - '{0}' 的隱含 get 存取子 + + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found + Symbol '{0}' is part of the declared internal API, but is either not internal or could not be found - - implicit set-accessor for '{0}' - '{0}' 的隱含 set 存取子 + + Remove deleted types and members from the declared internal API + Remove deleted types and members from the declared internal API - + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. - 移除公用類型或成員時,請將該項目放在 PublicAPI.Unshipped.txt 中並包含 '*REMOVED*' 前置詞。如此會讓您注意到在程式碼檢閱以及原始檔控制歷程記錄中 API 的變更,同時有助於避免發生中斷性變更。 + When removing a public type or member, put that entry in PublicAPI.Unshipped.txt with '*REMOVED*' prefix. This draws attention to API changes in the code reviews and source control history, and helps prevent breaking changes. {Locked="*REMOVED*"} - + Symbol '{0}' is part of the declared API, but is either not public or could not be found - 符號 '{0}' 是宣告 API 的一部分,但可能找不到或並非公用 + Symbol '{0}' is part of the declared API, but is either not public or could not be found - + Remove deleted types and members from the declared API - 從宣告的 API 移除已刪除的類型與成員 + Remove deleted types and members from the declared API @@ -193,23 +293,38 @@ - Public API is marked as removed but it exists in source code - 公用 API 標記為已移除,但存在於原始程式碼中 + API is marked as removed but it exists in source code + 公用 API 標記為已移除,但存在於原始程式碼中 + + + + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + InternalAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, InternalAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). + + + + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. + + + + Enable tracking of nullability of reference types in the declared API + Enable tracking of nullability of reference types in the declared API - + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - PublicAPI.txt 檔案必須具備 '#nullable enable',才能追蹤可為 NULL 的資訊,否則應隱藏此診斷。若啟用可為 NULL,PublicAPI.txt 便能記錄型可為 Null (類型的尾碼為 '?') 或不可為 Null (尾碼為 '!') 的類型。其也會追蹤仍在使用未經察覺之參考型別的任何 API (行的首碼為 '~')。 + PublicAPI.txt files should have `#nullable enable` to track nullability information, or this diagnostic should be suppressed. With nullability enabled, PublicAPI.txt records which types are nullable (suffix `?` on type) or non-nullable (suffix `!`). It also tracks any API that is still using an oblivious reference type (prefix `~` on line). - + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - PublicAPI.txt 缺少 '#nullable enable',因此未記錄 API 的可 NULL 性註釋。建議啟用此追蹤。 + PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - + Enable tracking of nullability of reference types in the declared API - 在宣告 API 中啟用參考型別的可為 Null 追蹤 + Enable tracking of nullability of reference types in the declared API diff --git a/src/PublicApiAnalyzers/Core/CodeFixes/AnnotatePublicApiFix.cs b/src/PublicApiAnalyzers/Core/CodeFixes/AnnotatePublicApiFix.cs index baf7fd352e..76aa333aa6 100644 --- a/src/PublicApiAnalyzers/Core/CodeFixes/AnnotatePublicApiFix.cs +++ b/src/PublicApiAnalyzers/Core/CodeFixes/AnnotatePublicApiFix.cs @@ -24,7 +24,7 @@ public sealed class AnnotatePublicApiFix : CodeFixProvider private const char ObliviousMarker = '~'; public sealed override ImmutableArray FixableDiagnosticIds { get; } = - ImmutableArray.Create(DiagnosticIds.AnnotatePublicApiRuleId); + ImmutableArray.Create(DiagnosticIds.AnnotatePublicApiRuleId, DiagnosticIds.AnnotateInternalApiRuleId); public sealed override FixAllProvider GetFixAllProvider() => new PublicSurfaceAreaFixAllProvider(); @@ -36,8 +36,8 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) foreach (Diagnostic diagnostic in context.Diagnostics) { string minimalSymbolName = diagnostic.Properties[DeclarePublicApiAnalyzer.MinimalNamePropertyBagKey]; - string publicSymbolName = diagnostic.Properties[DeclarePublicApiAnalyzer.PublicApiNamePropertyBagKey]; - string publicSymbolNameWithNullability = diagnostic.Properties[DeclarePublicApiAnalyzer.PublicApiNameWithNullabilityPropertyBagKey]; + string publicSymbolName = diagnostic.Properties[DeclarePublicApiAnalyzer.ApiNamePropertyBagKey]; + string publicSymbolNameWithNullability = diagnostic.Properties[DeclarePublicApiAnalyzer.ApiNameWithNullabilityPropertyBagKey]; string fileName = diagnostic.Properties[DeclarePublicApiAnalyzer.FileName]; TextDocument? document = project.GetPublicApiDocument(fileName); @@ -48,6 +48,7 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) new DeclarePublicApiFix.AdditionalDocumentChangeAction( $"Annotate {minimalSymbolName} in public API", document.Id, + isPublic: diagnostic.Id == DiagnosticIds.AnnotatePublicApiRuleId, c => GetFix(document, publicSymbolName, publicSymbolNameWithNullability, c)), diagnostic); } @@ -128,14 +129,18 @@ protected override async Task GetChangedSolutionAsync(CancellationToke foreach (Diagnostic diagnostic in grouping) { - if (diagnostic.Id != DeclarePublicApiAnalyzer.AnnotateApiRule.Id) + switch (diagnostic.Id) { - continue; + case DiagnosticIds.AnnotateInternalApiRuleId: + case DiagnosticIds.AnnotatePublicApiRuleId: + break; + default: + continue; } - string oldName = diagnostic.Properties[DeclarePublicApiAnalyzer.PublicApiNamePropertyBagKey]; - string newName = diagnostic.Properties[DeclarePublicApiAnalyzer.PublicApiNameWithNullabilityPropertyBagKey]; - bool isShipped = diagnostic.Properties[DeclarePublicApiAnalyzer.PublicApiIsShippedPropertyBagKey] == "true"; + string oldName = diagnostic.Properties[DeclarePublicApiAnalyzer.ApiNamePropertyBagKey]; + string newName = diagnostic.Properties[DeclarePublicApiAnalyzer.ApiNameWithNullabilityPropertyBagKey]; + bool isShipped = diagnostic.Properties[DeclarePublicApiAnalyzer.ApiIsShippedPropertyBagKey] == "true"; string fileName = diagnostic.Properties[DeclarePublicApiAnalyzer.FileName]; if (!allChanges.TryGetValue(fileName, out var mapToUpdate)) @@ -184,7 +189,7 @@ private class PublicSurfaceAreaFixAllProvider : FixAllProvider { ImmutableArray diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(fixAllContext.Document).ConfigureAwait(false); diagnosticsToFix.Add(new KeyValuePair>(fixAllContext.Project, diagnostics)); - title = string.Format(CultureInfo.InvariantCulture, PublicApiAnalyzerResources.AddAllItemsInDocumentToThePublicApiTitle, fixAllContext.Document.Name); + title = string.Format(CultureInfo.InvariantCulture, PublicApiAnalyzerResources.AddAllItemsInDocumentToTheApiTitle, fixAllContext.Document.Name); break; } @@ -193,7 +198,7 @@ private class PublicSurfaceAreaFixAllProvider : FixAllProvider Project project = fixAllContext.Project; ImmutableArray diagnostics = await fixAllContext.GetAllDiagnosticsAsync(project).ConfigureAwait(false); diagnosticsToFix.Add(new KeyValuePair>(fixAllContext.Project, diagnostics)); - title = string.Format(CultureInfo.InvariantCulture, PublicApiAnalyzerResources.AddAllItemsInProjectToThePublicApiTitle, fixAllContext.Project.Name); + title = string.Format(CultureInfo.InvariantCulture, PublicApiAnalyzerResources.AddAllItemsInProjectToTheApiTitle, fixAllContext.Project.Name); break; } @@ -205,7 +210,7 @@ private class PublicSurfaceAreaFixAllProvider : FixAllProvider diagnosticsToFix.Add(new KeyValuePair>(project, diagnostics)); } - title = PublicApiAnalyzerResources.AddAllItemsInTheSolutionToThePublicApiTitle; + title = PublicApiAnalyzerResources.AddAllItemsInTheSolutionToTheApiTitle; break; } diff --git a/src/PublicApiAnalyzers/Core/CodeFixes/DeclarePublicApiFix.cs b/src/PublicApiAnalyzers/Core/CodeFixes/DeclarePublicApiFix.cs index c65f35100c..dc34dc3ea7 100644 --- a/src/PublicApiAnalyzers/Core/CodeFixes/DeclarePublicApiFix.cs +++ b/src/PublicApiAnalyzers/Core/CodeFixes/DeclarePublicApiFix.cs @@ -14,6 +14,7 @@ using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Text; +using Roslyn.Diagnostics.Analyzers; using DiagnosticIds = Roslyn.Diagnostics.Analyzers.RoslynDiagnosticIds; namespace Microsoft.CodeAnalysis.PublicApiAnalyzers @@ -21,7 +22,7 @@ namespace Microsoft.CodeAnalysis.PublicApiAnalyzers [ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic, Name = "DeclarePublicApiFix"), Shared] public sealed class DeclarePublicApiFix : CodeFixProvider { - public sealed override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(DiagnosticIds.DeclarePublicApiRuleId); + public sealed override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create(DiagnosticIds.DeclarePublicApiRuleId, DiagnosticIds.DeclareInternalApiRuleId); public sealed override FixAllProvider GetFixAllProvider() { @@ -34,19 +35,21 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) foreach (Diagnostic diagnostic in context.Diagnostics) { + bool isPublic = diagnostic.Id == DiagnosticIds.DeclarePublicApiRuleId; string minimalSymbolName = diagnostic.Properties[DeclarePublicApiAnalyzer.MinimalNamePropertyBagKey]; - string publicSurfaceAreaSymbolName = diagnostic.Properties[DeclarePublicApiAnalyzer.PublicApiNamePropertyBagKey]; - ImmutableHashSet siblingSymbolNamesToRemove = diagnostic.Properties[DeclarePublicApiAnalyzer.PublicApiNamesOfSiblingsToRemovePropertyBagKey] - .Split(DeclarePublicApiAnalyzer.PublicApiNamesOfSiblingsToRemovePropertyBagValueSeparator.ToCharArray()) + string publicSurfaceAreaSymbolName = diagnostic.Properties[DeclarePublicApiAnalyzer.ApiNamePropertyBagKey]; + ImmutableHashSet siblingSymbolNamesToRemove = diagnostic.Properties[DeclarePublicApiAnalyzer.ApiNamesOfSiblingsToRemovePropertyBagKey] + .Split(DeclarePublicApiAnalyzer.ApiNamesOfSiblingsToRemovePropertyBagValueSeparator.ToCharArray()) .ToImmutableHashSet(); - foreach (var file in GetUnshippedPublicApiFiles(context.Document.Project)) + foreach (var file in GetUnshippedPublicApiFiles(context.Document.Project, isPublic)) { context.RegisterCodeFix( new AdditionalDocumentChangeAction( - $"Add {minimalSymbolName} to public API file {file?.Name}", + $"Add {minimalSymbolName} to API file {file?.Name}", file?.Id, - c => GetFixAsync(file, project, publicSurfaceAreaSymbolName, siblingSymbolNamesToRemove, c)), + isPublic, + c => GetFixAsync(file, isPublic, project, publicSurfaceAreaSymbolName, siblingSymbolNamesToRemove, c)), diagnostic); } } @@ -54,13 +57,13 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) return Task.CompletedTask; } - private static IEnumerable GetUnshippedPublicApiFiles(Project project) + private static IEnumerable GetUnshippedPublicApiFiles(Project project, bool isPublic) { var count = 0; foreach (var additional in project.AdditionalDocuments) { - var file = new PublicApiFile(additional.FilePath); + var file = new PublicApiFile(additional.FilePath, isPublic); if (file.IsApiFile && !file.IsShipping) { @@ -75,28 +78,28 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) } } - private static async Task GetFixAsync(TextDocument? publicSurfaceAreaDocument, Project project, string newSymbolName, ImmutableHashSet siblingSymbolNamesToRemove, CancellationToken cancellationToken) + private static async Task GetFixAsync(TextDocument? surfaceAreaDocument, bool isPublic, Project project, string newSymbolName, ImmutableHashSet siblingSymbolNamesToRemove, CancellationToken cancellationToken) { - if (publicSurfaceAreaDocument == null) + if (surfaceAreaDocument == null) { var newSourceText = AddSymbolNamesToSourceText(sourceText: null, new[] { newSymbolName }); - return AddPublicApiFiles(project, newSourceText); + return AddPublicApiFiles(project, newSourceText, isPublic); } else { - var sourceText = await publicSurfaceAreaDocument.GetTextAsync(cancellationToken).ConfigureAwait(false); + var sourceText = await surfaceAreaDocument.GetTextAsync(cancellationToken).ConfigureAwait(false); var newSourceText = AddSymbolNamesToSourceText(sourceText, new[] { newSymbolName }); newSourceText = RemoveSymbolNamesFromSourceText(newSourceText, siblingSymbolNamesToRemove); - return publicSurfaceAreaDocument.Project.Solution.WithAdditionalDocumentText(publicSurfaceAreaDocument.Id, newSourceText); + return surfaceAreaDocument.Project.Solution.WithAdditionalDocumentText(surfaceAreaDocument.Id, newSourceText); } } - private static Solution AddPublicApiFiles(Project project, SourceText unshippedText) + private static Solution AddPublicApiFiles(Project project, SourceText unshippedText, bool isPublic) { Debug.Assert(unshippedText.Length > 0); - project = AddAdditionalDocument(project, DeclarePublicApiAnalyzer.ShippedFileName, SourceText.From(string.Empty)); - project = AddAdditionalDocument(project, DeclarePublicApiAnalyzer.UnshippedFileName, unshippedText); + project = AddAdditionalDocument(project, isPublic ? DeclarePublicApiAnalyzer.PublicShippedFileName : DeclarePublicApiAnalyzer.InternalShippedFileName, SourceText.From(string.Empty)); + project = AddAdditionalDocument(project, isPublic ? DeclarePublicApiAnalyzer.PublicUnshippedFileName : DeclarePublicApiAnalyzer.InternalUnshippedFileName, unshippedText); return project.Solution; // Local functions. @@ -182,10 +185,10 @@ internal class AdditionalDocumentChangeAction : CodeAction { private readonly Func> _createChangedAdditionalDocument; - public AdditionalDocumentChangeAction(string title, DocumentId? apiDocId, Func> createChangedAdditionalDocument) + public AdditionalDocumentChangeAction(string title, DocumentId? apiDocId, bool isPublic, Func> createChangedAdditionalDocument) { this.Title = title; - EquivalenceKey = apiDocId.CreateEquivalenceKey(); + EquivalenceKey = apiDocId.CreateEquivalenceKey(isPublic); _createChangedAdditionalDocument = createChangedAdditionalDocument; } @@ -202,15 +205,17 @@ protected override Task GetChangedSolutionAsync(CancellationToken canc private class FixAllAdditionalDocumentChangeAction : CodeAction { private readonly List>> _diagnosticsToFix; + private readonly bool _isPublic; private readonly DocumentId? _apiDocId; private readonly Solution _solution; - public FixAllAdditionalDocumentChangeAction(string title, DocumentId? apiDocId, Solution solution, List>> diagnosticsToFix) + public FixAllAdditionalDocumentChangeAction(string title, DocumentId? apiDocId, Solution solution, List>> diagnosticsToFix, bool isPublic) { this.Title = title; _apiDocId = apiDocId; _solution = solution; _diagnosticsToFix = diagnosticsToFix; + this._isPublic = isPublic; } public override string Title { get; } @@ -252,20 +257,22 @@ await publicSurfaceAreaAdditionalDocument.GetTextAsync(cancellationToken).Config foreach (Diagnostic diagnostic in grouping) { - if (diagnostic.Id == DeclarePublicApiAnalyzer.ShouldAnnotateApiFilesRule.Id || - diagnostic.Id == DeclarePublicApiAnalyzer.ObliviousApiRule.Id) + if (diagnostic.Id is RoslynDiagnosticIds.ShouldAnnotatePublicApiFilesRuleId + or RoslynDiagnosticIds.ShouldAnnotateInternalApiFilesRuleId + or RoslynDiagnosticIds.ObliviousPublicApiRuleId + or RoslynDiagnosticIds.ObliviousInternalApiRuleId) { continue; } - string publicSurfaceAreaSymbolName = diagnostic.Properties[DeclarePublicApiAnalyzer.PublicApiNamePropertyBagKey]; + string publicSurfaceAreaSymbolName = diagnostic.Properties[DeclarePublicApiAnalyzer.ApiNamePropertyBagKey]; newSymbolNames.Add(publicSurfaceAreaSymbolName); - string siblingNamesToRemove = diagnostic.Properties[DeclarePublicApiAnalyzer.PublicApiNamesOfSiblingsToRemovePropertyBagKey]; + string siblingNamesToRemove = diagnostic.Properties[DeclarePublicApiAnalyzer.ApiNamesOfSiblingsToRemovePropertyBagKey]; if (siblingNamesToRemove.Length > 0) { - var namesToRemove = siblingNamesToRemove.Split(DeclarePublicApiAnalyzer.PublicApiNamesOfSiblingsToRemovePropertyBagValueSeparator.ToCharArray()); + var namesToRemove = siblingNamesToRemove.Split(DeclarePublicApiAnalyzer.ApiNamesOfSiblingsToRemovePropertyBagValueSeparator.ToCharArray()); foreach (var nameToRemove in namesToRemove) { symbolNamesToRemoveBuilder.Add(nameToRemove); @@ -306,7 +313,7 @@ await publicSurfaceAreaAdditionalDocument.GetTextAsync(cancellationToken).Config var project = newSolution.GetProject(pair.Key); if (uniqueProjectPaths.Add(project.FilePath ?? project.Name)) { - newSolution = AddPublicApiFiles(project, pair.Value); + newSolution = AddPublicApiFiles(project, pair.Value, _isPublic); } } @@ -326,7 +333,7 @@ private class PublicSurfaceAreaFixAllProvider : FixAllProvider { ImmutableArray diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(fixAllContext.Document).ConfigureAwait(false); diagnosticsToFix.Add(new KeyValuePair>(fixAllContext.Project, diagnostics)); - title = string.Format(CultureInfo.InvariantCulture, PublicApiAnalyzerResources.AddAllItemsInDocumentToThePublicApiTitle, fixAllContext.Document.Name); + title = string.Format(CultureInfo.InvariantCulture, PublicApiAnalyzerResources.AddAllItemsInDocumentToTheApiTitle, fixAllContext.Document.Name); break; } @@ -335,7 +342,7 @@ private class PublicSurfaceAreaFixAllProvider : FixAllProvider Project project = fixAllContext.Project; ImmutableArray diagnostics = await fixAllContext.GetAllDiagnosticsAsync(project).ConfigureAwait(false); diagnosticsToFix.Add(new KeyValuePair>(fixAllContext.Project, diagnostics)); - title = string.Format(CultureInfo.InvariantCulture, PublicApiAnalyzerResources.AddAllItemsInProjectToThePublicApiTitle, fixAllContext.Project.Name); + title = string.Format(CultureInfo.InvariantCulture, PublicApiAnalyzerResources.AddAllItemsInProjectToTheApiTitle, fixAllContext.Project.Name); break; } @@ -347,7 +354,7 @@ private class PublicSurfaceAreaFixAllProvider : FixAllProvider diagnosticsToFix.Add(new KeyValuePair>(project, diagnostics)); } - title = PublicApiAnalyzerResources.AddAllItemsInTheSolutionToThePublicApiTitle; + title = PublicApiAnalyzerResources.AddAllItemsInTheSolutionToTheApiTitle; break; } @@ -359,7 +366,7 @@ private class PublicSurfaceAreaFixAllProvider : FixAllProvider return null; } - return new FixAllAdditionalDocumentChangeAction(title, fixAllContext.CreateDocIdFromEquivalenceKey(), fixAllContext.Solution, diagnosticsToFix); + return new FixAllAdditionalDocumentChangeAction(title, fixAllContext.CreateDocIdFromEquivalenceKey(out bool isPublic), fixAllContext.Solution, diagnosticsToFix, isPublic); } } diff --git a/src/PublicApiAnalyzers/Core/CodeFixes/NullableEnablePublicApiFix.cs b/src/PublicApiAnalyzers/Core/CodeFixes/NullableEnablePublicApiFix.cs index cd69d6cd27..6f4ea7d1dc 100644 --- a/src/PublicApiAnalyzers/Core/CodeFixes/NullableEnablePublicApiFix.cs +++ b/src/PublicApiAnalyzers/Core/CodeFixes/NullableEnablePublicApiFix.cs @@ -21,7 +21,7 @@ namespace Microsoft.CodeAnalysis.PublicApiAnalyzers public sealed class NullableEnablePublicApiFix : CodeFixProvider { public sealed override ImmutableArray FixableDiagnosticIds { get; } = - ImmutableArray.Create(DiagnosticIds.ShouldAnnotateApiFilesRuleId); + ImmutableArray.Create(DiagnosticIds.ShouldAnnotatePublicApiFilesRuleId, DiagnosticIds.ShouldAnnotateInternalApiFilesRuleId); public sealed override FixAllProvider GetFixAllProvider() => new PublicSurfaceAreaFixAllProvider(); @@ -32,14 +32,16 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) foreach (Diagnostic diagnostic in context.Diagnostics) { - TextDocument? document = project.GetShippedDocument(); + var isPublic = diagnostic.Id == DiagnosticIds.ShouldAnnotatePublicApiFilesRuleId; + TextDocument? document = project.GetShippedDocument(isPublic); if (document != null) { context.RegisterCodeFix( new DeclarePublicApiFix.AdditionalDocumentChangeAction( - $"Add '#nullable enable' to public API", + $"Add '#nullable enable' to {(isPublic ? "public" : "internal")} API", document.Id, + isPublic, c => GetFixAsync(document, c)), diagnostic); } @@ -48,12 +50,12 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) return Task.CompletedTask; } - private static async Task GetFixAsync(TextDocument publicSurfaceAreaDocument, CancellationToken cancellationToken) + private static async Task GetFixAsync(TextDocument surfaceAreaDocument, CancellationToken cancellationToken) { - SourceText sourceText = await publicSurfaceAreaDocument.GetTextAsync(cancellationToken).ConfigureAwait(false); + SourceText sourceText = await surfaceAreaDocument.GetTextAsync(cancellationToken).ConfigureAwait(false); SourceText newSourceText = AddNullableEnable(sourceText); - return publicSurfaceAreaDocument.Project.Solution.WithAdditionalDocumentText(publicSurfaceAreaDocument.Id, newSourceText); + return surfaceAreaDocument.Project.Solution.WithAdditionalDocumentText(surfaceAreaDocument.Id, newSourceText); } private static SourceText AddNullableEnable(SourceText sourceText) @@ -79,29 +81,32 @@ public FixAllAdditionalDocumentChangeAction(string title, Solution solution, Lis protected override async Task GetChangedSolutionAsync(CancellationToken cancellationToken) { - var updatedPublicSurfaceAreaText = new List>(); + var updatedSurfaceAreaText = new List<(DocumentId, SourceText)>(); using var uniqueShippedDocuments = PooledHashSet.GetInstance(); foreach (var project in _projectsToFix) { - TextDocument? shippedDocument = project.GetShippedDocument(); - if (shippedDocument == null || - shippedDocument.FilePath != null && !uniqueShippedDocuments.Add(shippedDocument.FilePath)) + foreach (var isPublic in new[] { true, false }) { - // Skip past duplicate shipped documents. - // Multi-tfm projects can likely share the same api files, and we want to avoid duplicate code fix application. - continue; - } + TextDocument? shippedDocument = project.GetShippedDocument(isPublic); + if (shippedDocument == null || + shippedDocument.FilePath != null && !uniqueShippedDocuments.Add(shippedDocument.FilePath)) + { + // Skip past duplicate shipped documents. + // Multi-tfm projects can likely share the same api files, and we want to avoid duplicate code fix application. + continue; + } - var shippedSourceText = await shippedDocument.GetTextAsync(cancellationToken).ConfigureAwait(false); - SourceText newShippedSourceText = AddNullableEnable(shippedSourceText); - updatedPublicSurfaceAreaText.Add(new KeyValuePair(shippedDocument!.Id, newShippedSourceText)); + var shippedSourceText = await shippedDocument.GetTextAsync(cancellationToken).ConfigureAwait(false); + SourceText newShippedSourceText = AddNullableEnable(shippedSourceText); + updatedSurfaceAreaText.Add((shippedDocument!.Id, newShippedSourceText)); + } } Solution newSolution = _solution; - foreach (KeyValuePair pair in updatedPublicSurfaceAreaText) + foreach (var (document, text) in updatedSurfaceAreaText) { - newSolution = newSolution.WithAdditionalDocumentText(pair.Key, pair.Value); + newSolution = newSolution.WithAdditionalDocumentText(document, text); } return newSolution; @@ -120,7 +125,7 @@ private class PublicSurfaceAreaFixAllProvider : FixAllProvider case FixAllScope.Project: { projectsToFix.Add(fixAllContext.Project); - title = string.Format(CultureInfo.InvariantCulture, PublicApiAnalyzerResources.EnableNullableInProjectToThePublicApiTitle, fixAllContext.Project.Name); + title = string.Format(CultureInfo.InvariantCulture, PublicApiAnalyzerResources.EnableNullableInProjectToTheApiTitle, fixAllContext.Project.Name); break; } @@ -135,7 +140,7 @@ private class PublicSurfaceAreaFixAllProvider : FixAllProvider } } - title = PublicApiAnalyzerResources.EnableNullableInTheSolutionToThePublicApiTitle; + title = PublicApiAnalyzerResources.EnableNullableInTheSolutionToTheApiTitle; break; } diff --git a/src/PublicApiAnalyzers/Core/CodeFixes/PublicApiFixHelpers.cs b/src/PublicApiAnalyzers/Core/CodeFixes/PublicApiFixHelpers.cs index 0d0fd67cb2..bfe0c4c4fa 100644 --- a/src/PublicApiAnalyzers/Core/CodeFixes/PublicApiFixHelpers.cs +++ b/src/PublicApiAnalyzers/Core/CodeFixes/PublicApiFixHelpers.cs @@ -20,27 +20,28 @@ internal static void Deconstruct(this KeyValuePair k private const string ApiDocEquivalenceKeyPrefix = "__ApiDoc__"; - internal static string CreateEquivalenceKey(this DocumentId? doc) + internal static string CreateEquivalenceKey(this DocumentId? doc, bool isPublic) { if (doc is null) { - return $"{ApiDocEquivalenceKeyPrefix};;"; + return $"{ApiDocEquivalenceKeyPrefix};;;{isPublic}"; } else { - return $"{ApiDocEquivalenceKeyPrefix};{doc.ProjectId.Id};{doc.Id}"; + return $"{ApiDocEquivalenceKeyPrefix};{doc.ProjectId.Id};{doc.Id};{isPublic}"; } } - internal static DocumentId? CreateDocIdFromEquivalenceKey(this FixAllContext fixAllContext) + internal static DocumentId? CreateDocIdFromEquivalenceKey(this FixAllContext fixAllContext, out bool isPublic) { var split = fixAllContext.CodeActionEquivalenceKey.Split(SemicolonSplit, StringSplitOptions.RemoveEmptyEntries); - if (split.Length == 3 && - string.Equals(split[0], ApiDocEquivalenceKeyPrefix, StringComparison.Ordinal) && - Guid.TryParse(split[1], out var projectGuid) && projectGuid != Guid.Empty && - Guid.TryParse(split[2], out var docGuid) && docGuid != Guid.Empty) + isPublic = bool.Parse(split[^1]); + + if (split is [ApiDocEquivalenceKeyPrefix, var projectGuidString, var docGuidString, _] + && Guid.TryParse(projectGuidString, out var projectGuid) && projectGuid != Guid.Empty && + Guid.TryParse(docGuidString, out var docGuid) && docGuid != Guid.Empty) { var projectId = ProjectId.CreateFromSerialized(projectGuid); return DocumentId.CreateFromSerialized(projectId, docGuid); @@ -54,8 +55,8 @@ internal static string CreateEquivalenceKey(this DocumentId? doc) return project.AdditionalDocuments.FirstOrDefault(doc => doc.Name.Equals(name, StringComparison.Ordinal)); } - internal static TextDocument? GetShippedDocument(this Project project) - => project.GetPublicApiDocument(DeclarePublicApiAnalyzer.ShippedFileName); + internal static TextDocument? GetShippedDocument(this Project project, bool isPublic) + => project.GetPublicApiDocument(isPublic ? DeclarePublicApiAnalyzer.PublicShippedFileName : DeclarePublicApiAnalyzer.InternalShippedFileName); /// /// Returns the trailing newline from the end of , if one exists. diff --git a/src/PublicApiAnalyzers/UnitTests/AnnotatePublicApiAnalyzerTests.cs b/src/PublicApiAnalyzers/UnitTests/AnnotatePublicApiAnalyzerTestsBase.cs similarity index 59% rename from src/PublicApiAnalyzers/UnitTests/AnnotatePublicApiAnalyzerTests.cs rename to src/PublicApiAnalyzers/UnitTests/AnnotatePublicApiAnalyzerTestsBase.cs index b9514b9c95..1998e533c3 100644 --- a/src/PublicApiAnalyzers/UnitTests/AnnotatePublicApiAnalyzerTests.cs +++ b/src/PublicApiAnalyzers/UnitTests/AnnotatePublicApiAnalyzerTestsBase.cs @@ -2,6 +2,7 @@ #pragma warning disable CA1305 +using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp.Testing; using Microsoft.CodeAnalysis.Testing; @@ -11,8 +12,19 @@ namespace Microsoft.CodeAnalysis.PublicApiAnalyzers.UnitTests { - public class AnnotatePublicApiAnalyzerTests + public abstract class AnnotatePublicApiAnalyzerTestsBase { + protected abstract bool IsInternalTest { get; } + protected abstract string EnabledModifier { get; } + protected abstract string ShippedFileName { get; } + protected abstract string UnshippedFileName { get; } + protected abstract string UnshippedFileNamePrefix { get; } + protected abstract string AnnotateApiId { get; } + protected abstract string ShouldAnnotateApiFilesId { get; } + protected abstract string ObliviousApiId { get; } + + protected abstract IEnumerable DisabledDiagnostics { get; } + #region Utilities private async Task VerifyCSharpAsync(string source, string shippedApiText, string unshippedApiText, params DiagnosticResult[] expected) { @@ -27,15 +39,16 @@ private async Task VerifyCSharpAsync(string source, string shippedApiText, strin if (shippedApiText != null) { - test.TestState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.ShippedFileName, shippedApiText)); + test.TestState.AdditionalFiles.Add((ShippedFileName, shippedApiText)); } if (unshippedApiText != null) { - test.TestState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.UnshippedFileName, unshippedApiText)); + test.TestState.AdditionalFiles.Add((UnshippedFileName, unshippedApiText)); } test.ExpectedDiagnostics.AddRange(expected); + test.DisabledDiagnostics.AddRange(DisabledDiagnostics); await test.RunAsync(); } @@ -49,11 +62,11 @@ private async Task VerifyAdditionalFileFixAsync(string source, string oldShipped var test = new CSharpCodeFixTest(); test.TestState.Sources.Add(source); - test.TestState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.ShippedFileName, oldShippedApiText)); - test.TestState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.UnshippedFileName, oldUnshippedApiText)); + test.TestState.AdditionalFiles.Add((ShippedFileName, oldShippedApiText)); + test.TestState.AdditionalFiles.Add((UnshippedFileName, oldUnshippedApiText)); - test.FixedState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.ShippedFileName, newShippedApiText)); - test.FixedState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.UnshippedFileName, newUnshippedApiText)); + test.FixedState.AdditionalFiles.Add((ShippedFileName, newShippedApiText)); + test.FixedState.AdditionalFiles.Add((UnshippedFileName, newUnshippedApiText)); await test.RunAsync(); } @@ -64,12 +77,12 @@ private async Task VerifyAdditionalFileFixAsync(string source, string oldShipped [Fact, WorkItem(4040, "https://github.com/dotnet/roslyn-analyzers/issues/4040")] public async Task NoObliviousWhenUnannotatedClassConstraintAsync() { - var source = @" -#nullable enable -public class C where T : class -{ -} -"; + var source = $$""" + #nullable enable + {{EnabledModifier}} class C where T : class + { + } + """; var shippedText = @""; var unshippedText = @"#nullable enable @@ -83,12 +96,12 @@ public class C where T : class [Fact, WorkItem(4040, "https://github.com/dotnet/roslyn-analyzers/issues/4040")] public async Task NoObliviousWhenAnnotatedClassConstraintAsync() { - var source = @" -#nullable enable -public class C where T : class? -{ -} -"; + var source = $$""" + #nullable enable + {{EnabledModifier}} class C where T : class? + { + } + """; var shippedText = @""; var unshippedText = @"#nullable enable @@ -102,12 +115,12 @@ public class C where T : class? [Fact] public async Task NoObliviousWhenAnnotatedClassConstraintMultipleFiles() { - var source = @" -#nullable enable -public class C where T : class? -{ -} -"; + var source = $$""" + #nullable enable + {{EnabledModifier}} class C where T : class? + { + } + """; var shippedText = @"#nullable enable"; var unshippedText1 = @"#nullable enable @@ -124,9 +137,9 @@ public class C where T : class? Sources = { source }, AdditionalFiles = { - (DeclarePublicApiAnalyzer.ShippedFileName, shippedText), - (DeclarePublicApiAnalyzer.UnshippedFileName, unshippedText1), - (DeclarePublicApiAnalyzer.UnshippedFileNamePrefix + "test" + DeclarePublicApiAnalyzer.Extension, unshippedText2), + (ShippedFileName, shippedText), + (UnshippedFileName, unshippedText1), + (UnshippedFileNamePrefix + "test" + DeclarePublicApiAnalyzer.Extension, unshippedText2), }, }, }; @@ -137,14 +150,14 @@ public class C where T : class? [Fact, WorkItem(4040, "https://github.com/dotnet/roslyn-analyzers/issues/4040")] public async Task ObliviousWhenObliviousClassConstraintAsync() { - var source = @" -#nullable enable -public class {|RS0041:C|} // oblivious -#nullable disable - where T : class -{ -} -"; + var source = $$""" + #nullable enable + {{EnabledModifier}} class {|{{ObliviousApiId}}:C|} // oblivious + #nullable disable + where T : class + { + } + """; var shippedText = @""; var unshippedText = @"#nullable enable @@ -158,13 +171,13 @@ public class {|RS0041:C|} // oblivious [Fact, WorkItem(4040, "https://github.com/dotnet/roslyn-analyzers/issues/4040")] public async Task NoObliviousWhenUnannotatedReferenceTypeConstraintAsync() { - var source = @" -#nullable enable -public class D { } -public class C where T : D -{ -} -"; + var source = $$""" + #nullable enable + {{EnabledModifier}} class D { } + {{EnabledModifier}} class C where T : D + { + } + """; var shippedText = @""; var unshippedText = @"#nullable enable @@ -180,13 +193,13 @@ public class C where T : D [Fact, WorkItem(4040, "https://github.com/dotnet/roslyn-analyzers/issues/4040")] public async Task NoObliviousWhenAnnotatedReferenceTypeConstraintAsync() { - var source = @" -#nullable enable -public class D { } -public class C where T : D? -{ -} -"; + var source = $$""" + #nullable enable + {{EnabledModifier}} class D { } + {{EnabledModifier}} class C where T : D? + { + } + """; var shippedText = @""; var unshippedText = @"#nullable enable @@ -202,16 +215,16 @@ public class C where T : D? [Fact, WorkItem(4040, "https://github.com/dotnet/roslyn-analyzers/issues/4040")] public async Task ObliviousWhenObliviousReferenceTypeConstraintAsync() { - var source = @" -#nullable enable -public class D { } + var source = $$""" + #nullable enable + {{EnabledModifier}} class D { } -public class {|RS0041:C|} // oblivious -#nullable disable - where T : D -{ -} -"; + {{EnabledModifier}} class {|{{ObliviousApiId}}:C|} // oblivious + #nullable disable + where T : D + { + } + """; var shippedText = @""; var unshippedText = @"#nullable enable @@ -227,13 +240,13 @@ public class {|RS0041:C|} // oblivious [Fact] public async Task DoNotAnnotateMemberInUnannotatedUnshippedAPI_NullableAsync() { - var source = @" -#nullable enable -public class C -{ - public string? {|RS0037:Field|}; -} -"; + var source = $$""" + #nullable enable + {{EnabledModifier}} class C + { + {{EnabledModifier}} string? {|{{ShouldAnnotateApiFilesId}}:Field|}; + } + """; var shippedText = @""; var unshippedText = @"C @@ -246,13 +259,13 @@ public class C [Fact] public async Task DoNotAnnotateMemberInUnannotatedUnshippedAPI_NonNullableAsync() { - var source = @" -#nullable enable -public class C -{ - public string {|RS0037:Field2|}; -} -"; + var source = $$""" + #nullable enable + {{EnabledModifier}} class C + { + {{EnabledModifier}} string {|{{ShouldAnnotateApiFilesId}}:Field2|}; + } + """; var shippedText = @""; var unshippedText = @"C @@ -265,14 +278,14 @@ public class C [Fact] public async Task DoNotAnnotateMemberInUnannotatedShippedAPIAsync() { - var source = @" -#nullable enable -public class C -{ - public string? {|RS0037:Field|}; - public string {|RS0037:Field2|}; -} -"; + var source = $$""" + #nullable enable + {{EnabledModifier}} class C + { + {{EnabledModifier}} string? {|{{ShouldAnnotateApiFilesId}}:Field|}; + {{EnabledModifier}} string {|{{ShouldAnnotateApiFilesId}}:Field2|}; + } + """; var shippedText = @"C C.C() -> void @@ -286,15 +299,15 @@ public class C [Fact] public async Task AnnotatedMemberInAnnotatedShippedAPIAsync() { - var source = @" -#nullable enable -public class C -{ - public string? OldField; - public string? {|RS0036:Field|}; - public string {|RS0036:Field2|}; -} -"; + var source = $$""" + #nullable enable + {{EnabledModifier}} class C + { + {{EnabledModifier}} string? OldField; + {{EnabledModifier}} string? {|{{AnnotateApiId}}:Field|}; + {{EnabledModifier}} string {|{{AnnotateApiId}}:Field2|}; + } + """; var shippedText = @"#nullable enable C @@ -318,15 +331,15 @@ public class C [Fact] public async Task AnnotatedMemberInAnnotatedUnshippedAPI_EnabledViaUnshippedAsync() { - var source = @" -#nullable enable -public class C -{ - public string? OldField; - public string? {|RS0036:Field|}; - public string {|RS0036:Field2|}; -} -"; + var source = $$""" + #nullable enable + {{EnabledModifier}} class C + { + {{EnabledModifier}} string? OldField; + {{EnabledModifier}} string? {|{{AnnotateApiId}}:Field|}; + {{EnabledModifier}} string {|{{AnnotateApiId}}:Field2|}; + } + """; var unshippedText = @"#nullable enable C @@ -350,15 +363,15 @@ public class C [Fact] public async Task AnnotatedMemberInAnnotatedUnshippedAPI_EnabledViaMultipleUnshippedAsync() { - var source = @" -#nullable enable -public class C -{ - public string? OldField; - public string? {|RS0036:Field|}; - public string {|RS0036:Field2|}; -} -"; + var source = $$""" + #nullable enable + {{EnabledModifier}} class C + { + {{EnabledModifier}} string? OldField; + {{EnabledModifier}} string? {|{{AnnotateApiId}}:Field|}; + {{EnabledModifier}} string {|{{AnnotateApiId}}:Field2|}; + } + """; var unshippedText = @"#nullable enable C @@ -380,13 +393,13 @@ public class C test.TestState.Sources.Add(source); - test.TestState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.ShippedFileName, shippedText)); - test.TestState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.UnshippedFileName, string.Empty)); - test.TestState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.UnshippedFileNamePrefix + "test" + DeclarePublicApiAnalyzer.Extension, unshippedText)); + test.TestState.AdditionalFiles.Add((ShippedFileName, shippedText)); + test.TestState.AdditionalFiles.Add((UnshippedFileName, string.Empty)); + test.TestState.AdditionalFiles.Add((UnshippedFileNamePrefix + "test" + DeclarePublicApiAnalyzer.Extension, unshippedText)); - test.FixedState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.ShippedFileName, shippedText)); - test.FixedState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.UnshippedFileName, string.Empty)); - test.FixedState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.UnshippedFileNamePrefix + "test" + DeclarePublicApiAnalyzer.Extension, fixedUnshippedText)); + test.FixedState.AdditionalFiles.Add((ShippedFileName, shippedText)); + test.FixedState.AdditionalFiles.Add((UnshippedFileName, string.Empty)); + test.FixedState.AdditionalFiles.Add((UnshippedFileNamePrefix + "test" + DeclarePublicApiAnalyzer.Extension, fixedUnshippedText)); await test.RunAsync(); } @@ -394,15 +407,15 @@ public class C [Fact] public async Task AnnotatedMemberInAnnotatedUnshippedAPI_EnabledViaShippedAsync() { - var source = @" -#nullable enable -public class C -{ - public string? OldField; - public string? {|RS0036:Field|}; - public string {|RS0036:Field2|}; -} -"; + var source = $$""" + #nullable enable + {{EnabledModifier}} class C + { + {{EnabledModifier}} string? OldField; + {{EnabledModifier}} string? {|{{AnnotateApiId}}:Field|}; + {{EnabledModifier}} string {|{{AnnotateApiId}}:Field2|}; + } + """; var shippedText = @"#nullable enable"; var unshippedText = @"C @@ -423,15 +436,15 @@ public class C [Fact] public async Task AnnotatedMemberInAnnotatedUnshippedAPI_EnabledViaBothAsync() { - var source = @" -#nullable enable -public class C -{ - public string? OldField; - public string? {|RS0036:Field|}; - public string {|RS0036:Field2|}; -} -"; + var source = $$""" + #nullable enable + {{EnabledModifier}} class C + { + {{EnabledModifier}} string? OldField; + {{EnabledModifier}} string? {|{{AnnotateApiId}}:Field|}; + {{EnabledModifier}} string {|{{AnnotateApiId}}:Field2|}; + } + """; var shippedText = @"#nullable enable"; var unshippedText = @"#nullable enable @@ -454,13 +467,13 @@ public class C [Fact] public async Task TestAddAndRemoveMembers_CSharp_Fix_WithAddedNullability_WithoutObliviousAsync() { - var source = @" -#nullable enable -public class C -{ - public string? {|RS0036:ChangedField|}; -} -"; + var source = $$""" + #nullable enable + {{EnabledModifier}} class C + { + {{EnabledModifier}} string? {|{{AnnotateApiId}}:ChangedField|}; + } + """; var shippedText = $@"#nullable enable"; var unshippedText = @"C C.C() -> void @@ -474,12 +487,12 @@ public class C [Fact] public async Task LegacyAPIShouldBeAnnotatedWithObliviousMarkerAsync() { - var source = @" -public class C -{ - public string {|RS0036:{|RS0041:Field|}|}; // oblivious -} -"; + var source = $$""" + {{EnabledModifier}} class C + { + {{EnabledModifier}} string {|{{AnnotateApiId}}:{|{{ObliviousApiId}}:Field|}|}; // oblivious + } + """; var shippedText = $@"#nullable enable"; var unshippedText = @"C C.C() -> void @@ -493,12 +506,12 @@ public class C [Fact] public async Task LegacyAPIShouldBeAnnotatedWithObliviousMarker_ShippedFileAsync() { - var source = @" -public class C -{ - public string {|RS0036:{|RS0041:Field|}|}; // oblivious -} -"; + var source = $$""" + {{EnabledModifier}} class C + { + {{EnabledModifier}} string {|{{AnnotateApiId}}:{|{{ObliviousApiId}}:Field|}|}; // oblivious + } + """; var shippedText = $@"#nullable enable C C.C() -> void @@ -514,13 +527,13 @@ public class C [Fact] public async Task LegacyAPIWithObliviousMarkerGetsAnnotatedAsNullableAsync() { - var source = @" -#nullable enable -public class C -{ - public string? {|RS0036:Field|}; -} -"; + var source = $$""" + #nullable enable + {{EnabledModifier}} class C + { + {{EnabledModifier}} string? {|{{AnnotateApiId}}:Field|}; + } + """; var shippedText = $@"#nullable enable C C.C() -> void @@ -536,13 +549,13 @@ public class C [Fact] public async Task LegacyAPIWithObliviousMarkerGetsAnnotatedAsNotNullableAsync() { - var source = @" -#nullable enable -public class C -{ - public string {|RS0036:Field|}; -} -"; + var source = $$""" + #nullable enable + {{EnabledModifier}} class C + { + {{EnabledModifier}} string {|{{AnnotateApiId}}:Field|}; + } + """; var shippedText = $@"#nullable enable C C.C() -> void diff --git a/src/PublicApiAnalyzers/UnitTests/AnnotatePublicApiAnalyzerTestsInternal.cs b/src/PublicApiAnalyzers/UnitTests/AnnotatePublicApiAnalyzerTestsInternal.cs new file mode 100644 index 0000000000..fc53281daf --- /dev/null +++ b/src/PublicApiAnalyzers/UnitTests/AnnotatePublicApiAnalyzerTestsInternal.cs @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. + +using System.Collections.Generic; +using Roslyn.Diagnostics.Analyzers; + +namespace Microsoft.CodeAnalysis.PublicApiAnalyzers.UnitTests +{ + public class AnnotatePublicApiAnalyzerTestsInternal : AnnotatePublicApiAnalyzerTestsBase + { + protected override bool IsInternalTest => true; + protected override string EnabledModifier => "internal"; + protected override string ShippedFileName => DeclarePublicApiAnalyzer.InternalShippedFileName; + protected override string UnshippedFileName => DeclarePublicApiAnalyzer.InternalUnshippedFileName; + protected override string UnshippedFileNamePrefix => DeclarePublicApiAnalyzer.InternalUnshippedFileNamePrefix; + protected override string AnnotateApiId => RoslynDiagnosticIds.AnnotateInternalApiRuleId; + protected override string ShouldAnnotateApiFilesId => RoslynDiagnosticIds.ShouldAnnotateInternalApiFilesRuleId; + protected override string ObliviousApiId => RoslynDiagnosticIds.ObliviousInternalApiRuleId; + + protected override IEnumerable DisabledDiagnostics => new[] { + RoslynDiagnosticIds.DeclarePublicApiRuleId, + RoslynDiagnosticIds.RemoveDeletedPublicApiRuleId, + RoslynDiagnosticIds.PublicApiFilesInvalid, + RoslynDiagnosticIds.DuplicatedSymbolInPublicApiFiles, + RoslynDiagnosticIds.AnnotatePublicApiRuleId, + RoslynDiagnosticIds.ShouldAnnotatePublicApiFilesRuleId, + RoslynDiagnosticIds.ObliviousPublicApiRuleId, + RoslynDiagnosticIds.PublicApiFileMissing, + RoslynDiagnosticIds.AvoidMultipleOverloadsWithOptionalParametersPublic, + RoslynDiagnosticIds.OverloadWithOptionalParametersShouldHaveMostParametersPublic, + RoslynDiagnosticIds.ExposedNoninstantiableTypeRuleIdPublic, + }; + } +} diff --git a/src/PublicApiAnalyzers/UnitTests/AnnotatePublicApiAnalyzerTestsPublic.cs b/src/PublicApiAnalyzers/UnitTests/AnnotatePublicApiAnalyzerTestsPublic.cs new file mode 100644 index 0000000000..adcc4c58fe --- /dev/null +++ b/src/PublicApiAnalyzers/UnitTests/AnnotatePublicApiAnalyzerTestsPublic.cs @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. + +using System.Collections.Generic; +using Roslyn.Diagnostics.Analyzers; + +namespace Microsoft.CodeAnalysis.PublicApiAnalyzers.UnitTests +{ + public class AnnotatePublicApiAnalyzerTestsPublic : AnnotatePublicApiAnalyzerTestsBase + { + protected override bool IsInternalTest => false; + protected override string EnabledModifier => "public"; + protected override string ShippedFileName => DeclarePublicApiAnalyzer.PublicShippedFileName; + protected override string UnshippedFileName => DeclarePublicApiAnalyzer.PublicUnshippedFileName; + protected override string UnshippedFileNamePrefix => DeclarePublicApiAnalyzer.PublicUnshippedFileNamePrefix; + protected override string AnnotateApiId => RoslynDiagnosticIds.AnnotatePublicApiRuleId; + protected override string ShouldAnnotateApiFilesId => RoslynDiagnosticIds.ShouldAnnotatePublicApiFilesRuleId; + protected override string ObliviousApiId => RoslynDiagnosticIds.ObliviousPublicApiRuleId; + + protected override IEnumerable DisabledDiagnostics => new[] { + RoslynDiagnosticIds.DeclareInternalApiRuleId, + RoslynDiagnosticIds.RemoveDeletedInternalApiRuleId, + RoslynDiagnosticIds.InternalApiFilesInvalid, + RoslynDiagnosticIds.DuplicatedSymbolInInternalApiFiles, + RoslynDiagnosticIds.AnnotateInternalApiRuleId, + RoslynDiagnosticIds.ShouldAnnotateInternalApiFilesRuleId, + RoslynDiagnosticIds.ObliviousInternalApiRuleId, + RoslynDiagnosticIds.InternalApiFileMissing, + RoslynDiagnosticIds.AvoidMultipleOverloadsWithOptionalParametersInternal, + RoslynDiagnosticIds.OverloadWithOptionalParametersShouldHaveMostParametersInternal, + RoslynDiagnosticIds.ExposedNoninstantiableTypeRuleIdInternal, + }; + } +} diff --git a/src/PublicApiAnalyzers/UnitTests/DeclarePublicAPIAnalyzerTestsBase.cs b/src/PublicApiAnalyzers/UnitTests/DeclarePublicAPIAnalyzerTestsBase.cs index 94832036c0..5120761271 100644 --- a/src/PublicApiAnalyzers/UnitTests/DeclarePublicAPIAnalyzerTestsBase.cs +++ b/src/PublicApiAnalyzers/UnitTests/DeclarePublicAPIAnalyzerTestsBase.cs @@ -4,8 +4,10 @@ #pragma warning disable CA1305 using System; +using System.Collections.Generic; using System.Globalization; using System.IO; +using System.Linq; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp.Testing; using Microsoft.CodeAnalysis.Testing; @@ -16,8 +18,33 @@ namespace Microsoft.CodeAnalysis.PublicApiAnalyzers.UnitTests { - public class DeclarePublicApiAnalyzerTests + public abstract class DeclarePublicApiAnalyzerTestsBase { + protected abstract bool IsInternalTest { get; } + protected abstract string EnabledModifierCSharp { get; } + protected abstract string DisabledModifierCSharp { get; } + protected abstract string EnabledModifierVB { get; } + protected abstract string DisabledModifierVB { get; } + protected abstract string ShippedFileName { get; } + protected abstract string UnshippedFileName { get; } + protected abstract string UnshippedFileNamePrefix { get; } + protected abstract string AddNewApiId { get; } + protected abstract string RemoveApiId { get; } + protected abstract string DuplicatedSymbolInApiFileId { get; } + protected abstract string ShouldAnnotateApiFilesId { get; } + protected abstract string ObliviousApiId { get; } + + protected abstract DiagnosticDescriptor DeclareNewApiRule { get; } + protected abstract DiagnosticDescriptor RemoveDeletedApiRule { get; } + protected abstract DiagnosticDescriptor DuplicateSymbolInApiFiles { get; } + protected abstract DiagnosticDescriptor AvoidMultipleOverloadsWithOptionalParameters { get; } + protected abstract DiagnosticDescriptor OverloadWithOptionalParametersShouldHaveMostParameters { get; } + protected abstract DiagnosticDescriptor AnnotateApiRule { get; } + protected abstract DiagnosticDescriptor ObliviousApiRule { get; } + protected abstract DiagnosticDescriptor ApiFilesInvalid { get; } + protected abstract DiagnosticDescriptor ApiFileMissing { get; } + protected abstract IEnumerable DisabledDiagnostics { get; } + #region Helpers private static DiagnosticResult GetAdditionalFileResultAt(int line, int column, string path, DiagnosticDescriptor descriptor, params object[] arguments) { @@ -59,15 +86,16 @@ private async Task VerifyBasicAsync(string source, string shippedApiText, string if (shippedApiText != null) { - test.TestState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.ShippedFileName, shippedApiText)); + test.TestState.AdditionalFiles.Add((ShippedFileName, shippedApiText)); } if (unshippedApiText != null) { - test.TestState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.UnshippedFileName, unshippedApiText)); + test.TestState.AdditionalFiles.Add((UnshippedFileName, unshippedApiText)); } test.ExpectedDiagnostics.AddRange(expected); + test.DisabledDiagnostics.AddRange(DisabledDiagnostics); await test.RunAsync(); } @@ -84,15 +112,16 @@ private async Task VerifyCSharpAsync(string source, string? shippedApiText, stri if (shippedApiText != null) { - test.TestState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.ShippedFileName, shippedApiText)); + test.TestState.AdditionalFiles.Add((ShippedFileName, shippedApiText)); } if (unshippedApiText != null) { - test.TestState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.UnshippedFileName, unshippedApiText)); + test.TestState.AdditionalFiles.Add((UnshippedFileName, unshippedApiText)); } test.ExpectedDiagnostics.AddRange(expected); + test.DisabledDiagnostics.AddRange(DisabledDiagnostics); await test.RunAsync(); } @@ -110,15 +139,16 @@ private async Task VerifyCSharpAsync(string source, string? shippedApiText, stri if (shippedApiText != null) { - test.TestState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.ShippedFileName, shippedApiText)); + test.TestState.AdditionalFiles.Add((ShippedFileName, shippedApiText)); } if (unshippedApiText != null) { - test.TestState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.UnshippedFileName, unshippedApiText)); + test.TestState.AdditionalFiles.Add((UnshippedFileName, unshippedApiText)); } test.ExpectedDiagnostics.AddRange(expected); + test.DisabledDiagnostics.AddRange(DisabledDiagnostics); await test.RunAsync(); } @@ -144,6 +174,7 @@ private async Task VerifyCSharpAsync(string source, string shippedApiText, strin } test.ExpectedDiagnostics.AddRange(expected); + test.DisabledDiagnostics.AddRange(DisabledDiagnostics); await test.RunAsync(); } @@ -171,12 +202,13 @@ private async Task VerifyAdditionalFileFixAsync(string language, string source, test.TestState.Sources.Add(source); if (shippedApiText != null) - test.TestState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.ShippedFileName, shippedApiText)); + test.TestState.AdditionalFiles.Add((ShippedFileName, shippedApiText)); if (oldUnshippedApiText != null) - test.TestState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.UnshippedFileName, oldUnshippedApiText)); + test.TestState.AdditionalFiles.Add((UnshippedFileName, oldUnshippedApiText)); - test.FixedState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.ShippedFileName, shippedApiText ?? string.Empty)); - test.FixedState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.UnshippedFileName, newUnshippedApiText)); + test.FixedState.AdditionalFiles.Add((ShippedFileName, shippedApiText ?? string.Empty)); + test.FixedState.AdditionalFiles.Add((UnshippedFileName, newUnshippedApiText)); + test.DisabledDiagnostics.AddRange(DisabledDiagnostics); await test.RunAsync(); } @@ -188,18 +220,19 @@ private async Task VerifyAdditionalFileFixAsync(string language, string source, [WorkItem(2622, "https://github.com/dotnet/roslyn-analyzers/issues/2622")] public async Task AnalyzerFileMissing_ShippedAsync() { - var source = @" -public class C -{ - private C() { } -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} class C + { + private C() { } + } + """; string? shippedText = null; string? unshippedText = @""; - var expected = new DiagnosticResult(DeclarePublicApiAnalyzer.PublicApiFileMissing) - .WithArguments(DeclarePublicApiAnalyzer.ShippedFileName); + var expected = new DiagnosticResult(ApiFileMissing) + .WithArguments(ShippedFileName); await VerifyCSharpAsync(source, shippedText, unshippedText, expected); } @@ -207,18 +240,18 @@ private C() { } [WorkItem(2622, "https://github.com/dotnet/roslyn-analyzers/issues/2622")] public async Task AnalyzerFileMissing_UnshippedAsync() { - var source = @" -public class C -{ - private C() { } -} -"; + var source = $$""" + {{EnabledModifierCSharp}} class C + { + private C() { } + } + """; string? shippedText = @""; string? unshippedText = null; - var expected = new DiagnosticResult(DeclarePublicApiAnalyzer.PublicApiFileMissing) - .WithArguments(DeclarePublicApiAnalyzer.UnshippedFileName); + var expected = new DiagnosticResult(ApiFileMissing) + .WithArguments(UnshippedFileName); await VerifyCSharpAsync(source, shippedText, unshippedText, expected); } @@ -229,12 +262,13 @@ private C() { } [WorkItem(2622, "https://github.com/dotnet/roslyn-analyzers/issues/2622")] public async Task AnalyzerFileMissing_BothAsync(string editorconfigText) { - var source = @" -public class C -{ - private C() { } -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} class C + { + private C() { } + } + """; string? shippedText = null; string? unshippedText = null; @@ -242,7 +276,7 @@ private C() { } var expectedDiagnostics = Array.Empty(); if (!editorconfigText.EndsWith("true", StringComparison.OrdinalIgnoreCase)) { - expectedDiagnostics = new[] { GetCSharpResultAt(2, 14, DeclarePublicApiAnalyzer.DeclareNewApiRule, "C") }; + expectedDiagnostics = new[] { GetCSharpResultAt(2, 8 + EnabledModifierCSharp.Length, DeclareNewApiRule, "C") }; } await VerifyCSharpAsync(source, shippedText, unshippedText, $"[*]\r\n{editorconfigText}", expectedDiagnostics); @@ -262,29 +296,31 @@ public async Task EmptyPublicAPIFilesAsync() [Fact] public async Task SimpleMissingTypeAsync() { - var source = @" -public class C -{ - private C() { } -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} class C + { + private C() { } + } + """; var shippedText = @""; var unshippedText = @""; - await VerifyCSharpAsync(source, shippedText, unshippedText, GetCSharpResultAt(2, 14, DeclarePublicApiAnalyzer.DeclareNewApiRule, "C")); + await VerifyCSharpAsync(source, shippedText, unshippedText, GetCSharpResultAt(2, 8 + EnabledModifierCSharp.Length, DeclareNewApiRule, "C")); } [Fact, WorkItem(2690, "https://github.com/dotnet/wpf/issues/2690")] public async Task XamlGeneratedNamespaceWorkaroundAsync() { - var source = @" -namespace XamlGeneratedNamespace { - public sealed class GeneratedInternalTypeHelper - { - } -} -"; + var source = $$""" + + namespace XamlGeneratedNamespace { + {{EnabledModifierCSharp}} sealed class GeneratedInternalTypeHelper + { + } + } + """; var shippedText = @""; var unshippedText = @""; @@ -295,117 +331,121 @@ public sealed class GeneratedInternalTypeHelper [Fact] public async Task SimpleMissingMember_CSharpAsync() { - var source = @" -public class C -{ - public int Field; - public int Property { get; set; } - public void Method() { } - public int ArrowExpressionProperty => 0; -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} int Field; + {{EnabledModifierCSharp}} int Property { get; set; } + {{EnabledModifierCSharp}} void Method() { } + {{EnabledModifierCSharp}} int ArrowExpressionProperty => 0; + } + """; var shippedText = @""; var unshippedText = @""; await VerifyCSharpAsync(source, shippedText, unshippedText, // Test0.cs(2,14): error RS0016: Symbol 'C' is not part of the declared API. - GetCSharpResultAt(2, 14, DeclarePublicApiAnalyzer.DeclareNewApiRule, "C"), + GetCSharpResultAt(2, 8 + EnabledModifierCSharp.Length, DeclareNewApiRule, "C"), // Test0.cs(2,14): warning RS0016: Symbol 'implicit constructor for C' is not part of the declared API. - GetCSharpResultAt(2, 14, DeclarePublicApiAnalyzer.DeclareNewApiRule, string.Format(PublicApiAnalyzerResources.PublicImplicitConstructorErrorMessageName, "C")), + GetCSharpResultAt(2, 8 + EnabledModifierCSharp.Length, DeclareNewApiRule, string.Format(PublicApiAnalyzerResources.ImplicitConstructorErrorMessageName, "C")), // Test0.cs(4,16): error RS0016: Symbol 'Field' is not part of the declared API. - GetCSharpResultAt(4, 16, DeclarePublicApiAnalyzer.DeclareNewApiRule, "Field"), + GetCSharpResultAt(4, 10 + EnabledModifierCSharp.Length, DeclareNewApiRule, "Field"), // Test0.cs(5,27): error RS0016: Symbol 'Property.get' is not part of the declared API. - GetCSharpResultAt(5, 27, DeclarePublicApiAnalyzer.DeclareNewApiRule, "Property.get"), + GetCSharpResultAt(5, 21 + EnabledModifierCSharp.Length, DeclareNewApiRule, "Property.get"), // Test0.cs(5,32): error RS0016: Symbol 'Property.set' is not part of the declared API. - GetCSharpResultAt(5, 32, DeclarePublicApiAnalyzer.DeclareNewApiRule, "Property.set"), + GetCSharpResultAt(5, 26 + EnabledModifierCSharp.Length, DeclareNewApiRule, "Property.set"), // Test0.cs(6,17): error RS0016: Symbol 'Method' is not part of the declared API. - GetCSharpResultAt(6, 17, DeclarePublicApiAnalyzer.DeclareNewApiRule, "Method"), + GetCSharpResultAt(6, 11 + EnabledModifierCSharp.Length, DeclareNewApiRule, "Method"), // Test0.cs(7,43): error RS0016: Symbol 'ArrowExpressionProperty.get' is not part of the declared API. - GetCSharpResultAt(7, 43, DeclarePublicApiAnalyzer.DeclareNewApiRule, "ArrowExpressionProperty.get")); + GetCSharpResultAt(7, 37 + EnabledModifierCSharp.Length, DeclareNewApiRule, "ArrowExpressionProperty.get")); } [Fact, WorkItem(821, "https://github.com/dotnet/roslyn-analyzers/issues/821")] public async Task SimpleMissingMember_BasicAsync() { - var source = @" -Imports System - -Public Class C - Public Field As Integer - - Public Property [Property]() As Integer - Get - Return m_Property - End Get - Set - m_Property = Value - End Set - End Property - Private m_Property As Integer - - Public Sub Method() - End Sub - - Public ReadOnly Property ReadOnlyAutoProperty As Integer = 0 - Public Property NormalAutoProperty As Integer = 0 -End Class -"; + var source = $""" + + Imports System + + {EnabledModifierVB} Class C + {EnabledModifierVB} Field As Integer + + {EnabledModifierVB} Property [Property]() As Integer + Get + Return m_Property + End Get + Set + m_Property = Value + End Set + End Property + Private m_Property As Integer + + {EnabledModifierVB} Sub Method() + End Sub + + {EnabledModifierVB} ReadOnly Property ReadOnlyAutoProperty As Integer = 0 + {EnabledModifierVB} Property NormalAutoProperty As Integer = 0 + End Class + """; var shippedText = @""; var unshippedText = @""; await VerifyBasicAsync(source, shippedText, unshippedText, // Test0.vb(4,14): warning RS0016: Symbol 'C' is not part of the declared API. - GetBasicResultAt(4, 14, DeclarePublicApiAnalyzer.DeclareNewApiRule, "C"), + GetBasicResultAt(4, 14, DeclareNewApiRule, "C"), // Test0.cs(2,14): warning RS0016: Symbol 'implicit constructor for C' is not part of the declared API. - GetBasicResultAt(4, 14, DeclarePublicApiAnalyzer.DeclareNewApiRule, string.Format(PublicApiAnalyzerResources.PublicImplicitConstructorErrorMessageName, "C")), + GetBasicResultAt(4, 14, DeclareNewApiRule, string.Format(PublicApiAnalyzerResources.ImplicitConstructorErrorMessageName, "C")), // Test0.vb(5,12): warning RS0016: Symbol 'Field' is not part of the declared API. - GetBasicResultAt(5, 12, DeclarePublicApiAnalyzer.DeclareNewApiRule, "Field"), + GetBasicResultAt(5, 12, DeclareNewApiRule, "Field"), // Test0.vb(8,9): warning RS0016: Symbol 'Property' is not part of the declared API. - GetBasicResultAt(8, 9, DeclarePublicApiAnalyzer.DeclareNewApiRule, "Property"), + GetBasicResultAt(8, 9, DeclareNewApiRule, "Property"), // Test0.vb(11,9): warning RS0016: Symbol 'Property' is not part of the declared API. - GetBasicResultAt(11, 9, DeclarePublicApiAnalyzer.DeclareNewApiRule, "Property"), + GetBasicResultAt(11, 9, DeclareNewApiRule, "Property"), // Test0.vb(17,16): warning RS0016: Symbol 'Method' is not part of the declared API. - GetBasicResultAt(17, 16, DeclarePublicApiAnalyzer.DeclareNewApiRule, "Method"), + GetBasicResultAt(17, 16, DeclareNewApiRule, "Method"), // Test0.vb(20,30): warning RS0016: Symbol 'implicit get-accessor for ReadOnlyAutoProperty' is not part of the declared API. - GetBasicResultAt(20, 30, DeclarePublicApiAnalyzer.DeclareNewApiRule, string.Format(PublicApiAnalyzerResources.PublicImplicitGetAccessor, "ReadOnlyAutoProperty")), + GetBasicResultAt(20, 30, DeclareNewApiRule, string.Format(PublicApiAnalyzerResources.ImplicitGetAccessor, "ReadOnlyAutoProperty")), // Test0.vb(21,21): warning RS0016: Symbol 'implicit get-accessor for NormalAutoProperty' is not part of the declared API. - GetBasicResultAt(21, 21, DeclarePublicApiAnalyzer.DeclareNewApiRule, string.Format(PublicApiAnalyzerResources.PublicImplicitGetAccessor, "NormalAutoProperty")), + GetBasicResultAt(21, 21, DeclareNewApiRule, string.Format(PublicApiAnalyzerResources.ImplicitGetAccessor, "NormalAutoProperty")), // Test0.vb(21,21): warning RS0016: Symbol 'implicit set-accessor for NormalAutoProperty' is not part of the declared API. - GetBasicResultAt(21, 21, DeclarePublicApiAnalyzer.DeclareNewApiRule, string.Format(PublicApiAnalyzerResources.PublicImplicitSetAccessor, "NormalAutoProperty"))); + GetBasicResultAt(21, 21, DeclareNewApiRule, string.Format(PublicApiAnalyzerResources.ImplicitSetAccessor, "NormalAutoProperty"))); } [Fact(), WorkItem(821, "https://github.com/dotnet/roslyn-analyzers/issues/821")] public async Task SimpleMissingMember_Basic1Async() { - var source = @" -Imports System -Public Class C - Private m_Property As Integer - Public Property [Property]() As Integer - ' Get - ' Return m_Property - ' End Get - ' Set - ' m_Property = Value - ' End Set - ' End Property - Public ReadOnly Property ReadOnlyProperty0() As Integer - Get - Return m_Property - End Get - End Property - Public WriteOnly Property WriteOnlyProperty0() As Integer - Set - m_Property = Value - End Set - End Property - Public ReadOnly Property ReadOnlyProperty1 As Integer = 0 - Public ReadOnly Property ReadOnlyProperty2 As Integer - Public Property Property1 As Integer -End Class -"; + var source = $""" + + Imports System + {EnabledModifierVB} Class C + Private m_Property As Integer + {EnabledModifierVB} Property [Property]() As Integer + ' Get + ' Return m_Property + ' End Get + ' Set + ' m_Property = Value + ' End Set + ' End Property + {EnabledModifierVB} ReadOnly Property ReadOnlyProperty0() As Integer + Get + Return m_Property + End Get + End Property + {EnabledModifierVB} WriteOnly Property WriteOnlyProperty0() As Integer + Set + m_Property = Value + End Set + End Property + {EnabledModifierVB} ReadOnly Property ReadOnlyProperty1 As Integer = 0 + {EnabledModifierVB} ReadOnly Property ReadOnlyProperty2 As Integer + {EnabledModifierVB} Property Property1 As Integer + End Class + + """; var shippedText = @" C @@ -426,12 +466,13 @@ End Class [Fact, WorkItem(806, "https://github.com/dotnet/roslyn-analyzers/issues/806")] public async Task ShippedTextWithImplicitConstructorAsync() { - var source = @" -public class C -{ - private C() { } -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} class C + { + private C() { } + } + """; var shippedText = @" C @@ -440,17 +481,18 @@ private C() { } await VerifyCSharpAsync(source, shippedText, unshippedText, // PublicAPI.Shipped.txt(3,1): warning RS0017: Symbol 'C -> void()' is part of the declared API, but is either not public or could not be found - GetAdditionalFileResultAt(3, 1, DeclarePublicApiAnalyzer.ShippedFileName, DeclarePublicApiAnalyzer.RemoveDeletedApiRule, "C -> void()")); + GetAdditionalFileResultAt(3, 1, ShippedFileName, RemoveDeletedApiRule, "C -> void()")); } [Fact, WorkItem(806, "https://github.com/dotnet/roslyn-analyzers/issues/806")] public async Task ShippedTextForImplicitConstructorAsync() { - var source = @" -public class C -{ -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} class C + { + } + """; var shippedText = @" C @@ -463,11 +505,12 @@ public class C [Fact, WorkItem(806, "https://github.com/dotnet/roslyn-analyzers/issues/806")] public async Task UnshippedTextForImplicitConstructorAsync() { - var source = @" -public class C -{ -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} class C + { + } + """; var shippedText = @" C"; @@ -480,31 +523,33 @@ public class C [Fact, WorkItem(806, "https://github.com/dotnet/roslyn-analyzers/issues/806")] public async Task ShippedTextWithMissingImplicitConstructorAsync() { - var source = @" -public class C -{ -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} class C + { + } + """; var shippedText = @" C"; var unshippedText = @""; - var arg = string.Format(CultureInfo.CurrentCulture, PublicApiAnalyzerResources.PublicImplicitConstructorErrorMessageName, "C"); + var arg = string.Format(CultureInfo.CurrentCulture, PublicApiAnalyzerResources.ImplicitConstructorErrorMessageName, "C"); await VerifyCSharpAsync(source, shippedText, unshippedText, // Test0.cs(2,14): warning RS0016: Symbol 'implicit constructor for C' is not part of the declared API. - GetCSharpResultAt(2, 14, DeclarePublicApiAnalyzer.DeclareNewApiRule, arg)); + GetCSharpResultAt(2, 8 + EnabledModifierCSharp.Length, DeclareNewApiRule, arg)); } [Fact, WorkItem(806, "https://github.com/dotnet/roslyn-analyzers/issues/806")] public async Task ShippedTextWithImplicitConstructorAndBreakingCodeChangeAsync() { - var source = @" -public class C -{ - private C() { } -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} class C + { + private C() { } + } + """; var shippedText = @" C @@ -513,20 +558,22 @@ private C() { } await VerifyCSharpAsync(source, shippedText, unshippedText, // PublicAPI.Shipped.txt(3,1): warning RS0017: Symbol 'C.C() -> void' is part of the declared API, but is either not public or could not be found - GetAdditionalFileResultAt(3, 1, DeclarePublicApiAnalyzer.ShippedFileName, DeclarePublicApiAnalyzer.RemoveDeletedApiRule, "C.C() -> void")); + GetAdditionalFileResultAt(3, 1, ShippedFileName, RemoveDeletedApiRule, "C.C() -> void")); } [Fact] public async Task SimpleMemberAsync() { - var source = @" -public class C -{ - public int Field; - public int Property { get; set; } - public void Method() { } -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} int Field; + {{EnabledModifierCSharp}} int Property { get; set; } + {{EnabledModifierCSharp}} void Method() { } + } + + """; var shippedText = @" C @@ -544,14 +591,15 @@ public void Method() { } [Fact] public async Task SplitBetweenShippedUnshippedAsync() { - var source = @" -public class C -{ - public int Field; - public int Property { get; set; } - public void Method() { } -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} int Field; + {{EnabledModifierCSharp}} int Property { get; set; } + {{EnabledModifierCSharp}} void Method() { } + } + """; var shippedText = @" C @@ -570,14 +618,16 @@ public void Method() { } [Fact] public async Task EnumSplitBetweenFilesAsync() { - var source = @" -public enum E -{ - V1 = 1, - V2 = 2, - V3 = 3, -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} enum E + { + V1 = 1, + V2 = 2, + V3 = 3, + } + + """; var shippedText = @" E @@ -595,13 +645,14 @@ public enum E [Fact] public async Task SimpleRemovedMemberAsync() { - var source = @" -public class C -{ - public int Field; - public int Property { get; set; } -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} class C + { + public int Field; + public int Property { get; set; } + } + """; var shippedText = @" C @@ -624,14 +675,15 @@ public class C [WorkItem(3329, "https://github.com/dotnet/roslyn-analyzers/issues/3329")] public async Task RemovedPrefixForNonRemovedApiAsync(bool includeInShipped) { - var source = @" -public class C -{ - public int Field; - public int Property { get; set; } - public void Method() { } -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} int Field; + {{EnabledModifierCSharp}} int Property { get; set; } + {{EnabledModifierCSharp}} void Method() { } + } + """; var shippedText = @" C @@ -651,33 +703,37 @@ public void Method() { } {DeclarePublicApiAnalyzer.RemovedApiPrefix}C.Method() -> void "; + var diagnostics = new[] { + // PublicAPI.Unshipped.txt(2,1): warning RS0050: Symbol 'C.Method() -> void' is marked as removed but it isn't deleted in source code + GetAdditionalFileResultAt(2, 1, UnshippedFileName, DeclarePublicApiAnalyzer.RemovedApiIsNotActuallyRemovedRule, "C.Method() -> void") + }; if (includeInShipped) { - await VerifyCSharpAsync(source, shippedText, unshippedText, - // PublicAPI.Unshipped.txt(2,1): warning RS0050: Symbol 'C.Method() -> void' is marked as removed but it isn't deleted in source code - GetAdditionalFileResultAt(2, 1, DeclarePublicApiAnalyzer.UnshippedFileName, DeclarePublicApiAnalyzer.RemovedApiIsNotActuallyRemovedRule, "C.Method() -> void")); + await VerifyCSharpAsync(source, shippedText, unshippedText, diagnostics); } else { - await VerifyCSharpAsync(source, shippedText, unshippedText, - // PublicAPI.Unshipped.txt(2,1): warning RS0050: Symbol 'C.Method() -> void' is marked as removed but it isn't deleted in source code - GetAdditionalFileResultAt(2, 1, DeclarePublicApiAnalyzer.UnshippedFileName, DeclarePublicApiAnalyzer.RemovedApiIsNotActuallyRemovedRule, "C.Method() -> void"), - // /0/Test0.cs(6,17): warning RS0016: Symbol 'Method' is not part of the declared API - GetCSharpResultAt(6, 17, DeclarePublicApiAnalyzer.DeclareNewApiRule, "Method") - ); + // /0/Test0.cs(6,17): warning RS0016: Symbol 'Method' is not part of the declared API + var secondDiagnostic = new[] { GetCSharpResultAt(6, 11 + EnabledModifierCSharp.Length, DeclareNewApiRule, "Method") }; + + // Ordering depends on file name + diagnostics = (IsInternalTest ? secondDiagnostic.Concat(diagnostics) : diagnostics.Concat(secondDiagnostic)).ToArray(); + + await VerifyCSharpAsync(source, shippedText, unshippedText, diagnostics); } } [Fact] public async Task ApiFileShippedWithRemovedAsync() { - var source = @" -public class C -{ - public int Field; - public int Property { get; set; } -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} int Field; + {{EnabledModifierCSharp}} int Property { get; set; } + } + """; string shippedText = $@" C @@ -689,7 +745,7 @@ public class C string unshippedText = $@""; - var expected = new DiagnosticResult(DeclarePublicApiAnalyzer.PublicApiFilesInvalid) + var expected = new DiagnosticResult(ApiFilesInvalid) .WithArguments(DeclarePublicApiAnalyzer.InvalidReasonShippedCantHaveRemoved); await VerifyCSharpAsync(source, shippedText, unshippedText, expected); } @@ -698,13 +754,14 @@ public class C [WorkItem(312, "https://github.com/dotnet/roslyn-analyzers/issues/312")] public async Task DuplicateSymbolInSameAPIFileAsync() { - var source = @" -public class C -{ - public int Field; - public int Property { get; set; } -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} int Field; + {{EnabledModifierCSharp}} int Property { get; set; } + } + """; var shippedText = @" C @@ -718,10 +775,10 @@ public class C #pragma warning disable RS0030 // Do not used banned APIs #pragma warning disable RS0030 // Do not used banned APIs - var expected = new DiagnosticResult(DeclarePublicApiAnalyzer.DuplicateSymbolInApiFiles) - .WithLocation(DeclarePublicApiAnalyzer.ShippedFileName, 6, 1) + var expected = new DiagnosticResult(DuplicateSymbolInApiFiles) + .WithLocation(ShippedFileName, 6, 1) #pragma warning restore RS0030 // Do not used banned APIs - .WithLocation(DeclarePublicApiAnalyzer.ShippedFileName, 4, 1) + .WithLocation(ShippedFileName, 4, 1) #pragma warning restore RS0030 // Do not used banned APIs .WithArguments("C.Property.get -> int"); await VerifyCSharpAsync(source, shippedText, unshippedText, expected); @@ -731,13 +788,15 @@ public class C [WorkItem(312, "https://github.com/dotnet/roslyn-analyzers/issues/312")] public async Task DuplicateSymbolInDifferentAPIFilesAsync() { - var source = @" -public class C -{ - public int Field; - public int Property { get; set; } -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} int Field; + {{EnabledModifierCSharp}} int Property { get; set; } + } + + """; var shippedText = @" C @@ -752,10 +811,10 @@ public class C #pragma warning disable RS0030 // Do not used banned APIs #pragma warning disable RS0030 // Do not used banned APIs - var expected = new DiagnosticResult(DeclarePublicApiAnalyzer.DuplicateSymbolInApiFiles) - .WithLocation(DeclarePublicApiAnalyzer.UnshippedFileName, 2, 1) + var expected = new DiagnosticResult(DuplicateSymbolInApiFiles) + .WithLocation(UnshippedFileName, 2, 1) #pragma warning restore RS0030 // Do not used banned APIs - .WithLocation(DeclarePublicApiAnalyzer.ShippedFileName, 5, 1) + .WithLocation(ShippedFileName, 5, 1) #pragma warning restore RS0030 // Do not used banned APIs .WithArguments("C.Property.get -> int"); await VerifyCSharpAsync(source, shippedText, unshippedText, expected); @@ -765,22 +824,24 @@ public class C [WorkItem(4584, "https://github.com/dotnet/roslyn-analyzers/issues/4584")] public async Task DuplicateObliviousSymbolsInSameApiFileAsync() { - var source = @" -public class C -{ - public int Field; - public int Property { get; set; } -} -"; + var source = $$""" - var shippedText = @"#nullable enable -C -C.C() -> void -C.Field -> int -C.Property.set -> void -~C.Property.get -> int -{|RS0025:~C.Property.get -> int|} -"; + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} int Field; + {{EnabledModifierCSharp}} int Property { get; set; } + } + """; + + var shippedText = $$""" + #nullable enable + C + C.C() -> void + C.Field -> int + C.Property.set -> void + ~C.Property.get -> int + {|{{DuplicatedSymbolInApiFileId}}:~C.Property.get -> int|} + """; var unshippedText = @""; @@ -791,22 +852,25 @@ public class C [WorkItem(4584, "https://github.com/dotnet/roslyn-analyzers/issues/4584")] public async Task DuplicateSymbolUsingObliviousInSameApiFilesAsync() { - var source = @" -public class C -{ - public int Field; - public int Property { get; set; } -} -"; + var source = $$""" - var shippedText = @"#nullable enable -C -C.C() -> void -C.Field -> int -C.Property.get -> int -C.Property.set -> void -{|RS0025:~C.Property.get -> int|} -"; + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} int Field; + {{EnabledModifierCSharp}} int Property { get; set; } + } + """; + + var shippedText = $$""" + #nullable enable + C + C.C() -> void + C.Field -> int + C.Property.get -> int + C.Property.set -> void + {|{{DuplicatedSymbolInApiFileId}}:~C.Property.get -> int|} + + """; var unshippedText = @""; @@ -817,13 +881,14 @@ public class C [WorkItem(4584, "https://github.com/dotnet/roslyn-analyzers/issues/4584")] public async Task DuplicateSymbolUsingObliviousInDifferentApiFilesAsync() { - var source = @" -public class C -{ - public int Field; - public int Property { get; set; } -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} int Field; + {{EnabledModifierCSharp}} int Property { get; set; } + } + """; var shippedText = @"#nullable enable C @@ -833,8 +898,10 @@ public class C C.Property.set -> void "; - var unshippedText = @"#nullable enable -{|RS0025:C.Property.get -> int|}"; + var unshippedText = $$""" + #nullable enable + {|{{DuplicatedSymbolInApiFileId}}:C.Property.get -> int|} + """; await VerifyCSharpAsync(source, shippedText, unshippedText); } @@ -843,13 +910,15 @@ public class C [WorkItem(4584, "https://github.com/dotnet/roslyn-analyzers/issues/4584")] public async Task MultipleDuplicateSymbolsUsingObliviousInDifferentApiFilesAsync() { - var source = @" -public class C -{ - public int Field; - public int Property { get; set; } -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} int Field; + {{EnabledModifierCSharp}} int Property { get; set; } + } + + """; var shippedText = @"#nullable enable C @@ -859,10 +928,12 @@ public class C C.Property.set -> void "; - var unshippedText = @"#nullable enable -{|RS0025:~C.Property.get -> int|} -{|RS0025:C.Property.get -> int|} -{|RS0025:~C.Property.set -> void|}"; + var unshippedText = $$""" + #nullable enable + {|{{DuplicatedSymbolInApiFileId}}:~C.Property.get -> int|} + {|{{DuplicatedSymbolInApiFileId}}:C.Property.get -> int|} + {|{{DuplicatedSymbolInApiFileId}}:~C.Property.set -> void|} + """; await VerifyCSharpAsync(source, shippedText, unshippedText); } @@ -871,14 +942,16 @@ public class C public async Task ApiFileShippedWithNonExistentMembersAsync() { // Type C has no public member "Method", but the shipped API has an entry for it. - var source = @" -public class C -{ - public int Field; - public int Property { get; set; } - private void Method() { } -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} int Field; + {{EnabledModifierCSharp}} int Property { get; set; } + private void Method() { } + } + + """; string shippedText = $@" C @@ -892,21 +965,22 @@ private void Method() { } await VerifyCSharpAsync(source, shippedText, unshippedText, // PublicAPI.Shipped.txt(7,1): warning RS0017: Symbol 'C.Method() -> void' is part of the declared API, but is either not public or could not be found - GetAdditionalFileResultAt(7, 1, DeclarePublicApiAnalyzer.ShippedFileName, DeclarePublicApiAnalyzer.RemoveDeletedApiRule, "C.Method() -> void")); + GetAdditionalFileResultAt(7, 1, ShippedFileName, RemoveDeletedApiRule, "C.Method() -> void")); } [Fact, WorkItem(773, "https://github.com/dotnet/roslyn-analyzers/issues/773")] public async Task ApiFileShippedWithNonExistentMembers_TestFullPathAsync() { // Type C has no public member "Method", but the shipped API has an entry for it. - var source = @" -public class C -{ - public int Field; - public int Property { get; set; } - private void Method() { } -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} int Field; + {{EnabledModifierCSharp}} int Property { get; set; } + private void Method() { } + } + """; var tempPath = Path.GetTempPath(); string shippedText = $@" @@ -917,19 +991,24 @@ private void Method() { } C.Property.set -> void C.Method() -> void "; - var shippedFilePath = Path.Combine(tempPath, DeclarePublicApiAnalyzer.ShippedFileName); + var shippedFilePath = Path.Combine(tempPath, ShippedFileName); string unshippedText = $@""; - var unshippedFilePath = Path.Combine(tempPath, DeclarePublicApiAnalyzer.UnshippedFileName); + var unshippedFilePath = Path.Combine(tempPath, UnshippedFileName); await VerifyCSharpAsync(source, shippedText, unshippedText, shippedFilePath, unshippedFilePath, // <%TEMP_PATH%>\PublicAPI.Shipped.txt(7,1): warning RS0017: Symbol 'C.Method() -> void' is part of the declared API, but is either not public or could not be found - GetAdditionalFileResultAt(7, 1, shippedFilePath, DeclarePublicApiAnalyzer.RemoveDeletedApiRule, "C.Method() -> void")); + GetAdditionalFileResultAt(7, 1, shippedFilePath, RemoveDeletedApiRule, "C.Method() -> void")); } [Fact] public async Task TypeForwardsAreProcessed1Async() { + if (IsInternalTest) + { + return; + } + var source = @" [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.StringComparison))] "; @@ -956,6 +1035,11 @@ public async Task TypeForwardsAreProcessed1Async() [Fact] public async Task TypeForwardsAreProcessed2Async() { + if (IsInternalTest) + { + return; + } + var source = @" [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.StringComparer))] "; @@ -1004,6 +1088,11 @@ static System.StringComparer.FromComparison(System.StringComparison comparisonTy [Fact, WorkItem(1192, "https://github.com/dotnet/roslyn-analyzers/issues/1192")] public async Task OpenGenericTypeForwardsAreProcessedAsync() { + if (IsInternalTest) + { + return; + } + var source = @" [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Collections.Generic.IEnumerable<>))] "; @@ -1014,17 +1103,22 @@ public async Task OpenGenericTypeForwardsAreProcessedAsync() await VerifyCSharpAsync(source, shippedText, unshippedText, #if NETCOREAPP // /0/Test0.cs(2,12): warning RS0037: PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - GetCSharpResultAt(2, 12, DeclarePublicApiAnalyzer.ShouldAnnotateApiFilesRule), + GetCSharpResultAt(2, 12, DeclarePublicApiAnalyzer.ShouldAnnotatePublicApiFilesRule), #endif // /0/Test0.cs(2,12): warning RS0016: Symbol 'GetEnumerator' is not part of the declared API - GetCSharpResultAt(2, 12, DeclarePublicApiAnalyzer.DeclareNewApiRule, "GetEnumerator"), + GetCSharpResultAt(2, 12, DeclareNewApiRule, "GetEnumerator"), // /0/Test0.cs(2,12): warning RS0016: Symbol 'GetEnumerator' is not part of the declared API - GetCSharpResultAt(2, 12, DeclarePublicApiAnalyzer.DeclareNewApiRule, "IEnumerable")); + GetCSharpResultAt(2, 12, DeclareNewApiRule, "IEnumerable")); } [Fact, WorkItem(1192, "https://github.com/dotnet/roslyn-analyzers/issues/1192")] public async Task GenericTypeForwardsAreProcessedAsync() { + if (IsInternalTest) + { + return; + } + var source = @" [assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Collections.Generic.IEnumerable))] "; @@ -1035,175 +1129,218 @@ public async Task GenericTypeForwardsAreProcessedAsync() await VerifyCSharpAsync(source, shippedText, unshippedText, #if NETCOREAPP // /0/Test0.cs(2,12): warning RS0037: PublicAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. - GetCSharpResultAt(2, 12, DeclarePublicApiAnalyzer.ShouldAnnotateApiFilesRule), + GetCSharpResultAt(2, 12, DeclarePublicApiAnalyzer.ShouldAnnotatePublicApiFilesRule), #endif // /0/Test0.cs(2,12): warning RS0016: Symbol 'GetEnumerator' is not part of the declared API - GetCSharpResultAt(2, 12, DeclarePublicApiAnalyzer.DeclareNewApiRule, "GetEnumerator"), + GetCSharpResultAt(2, 12, DeclareNewApiRule, "GetEnumerator"), // /0/Test0.cs(2,12): warning RS0016: Symbol 'GetEnumerator' is not part of the declared API - GetCSharpResultAt(2, 12, DeclarePublicApiAnalyzer.DeclareNewApiRule, "IEnumerable")); + GetCSharpResultAt(2, 12, DeclareNewApiRule, "IEnumerable")); } [Fact, WorkItem(851, "https://github.com/dotnet/roslyn-analyzers/issues/851")] public async Task TestAvoidMultipleOverloadsWithOptionalParametersAsync() { - var source = @" -public class C -{ - // ok - single overload with optional params, 2 overloads have no public API entries. - public void Method1(int p1, int p2, int p3 = 0) { } - public void Method1() { } - public void Method1(int p1, int p2) { } - public void Method1(char p1, params int[] p2) { } - - // ok - multiple overloads with optional params, but only one is public. - public void Method2(int p1 = 0) { } - internal void Method2(char p1 = '0') { } - private void Method2(string p1 = null) { } - - // ok - multiple overloads with optional params, but all are shipped. - public void Method3(int p1 = 0) { } - public void Method3(string p1 = null) { } - - // fire on unshipped (1) - multiple overloads with optional params, all but first are shipped. - public void Method4(int p1 = 0) { } - public void Method4(char p1 = 'a') { } - public void Method4(string p1 = null) { } - - // fire on all unshipped (3) - multiple overloads with optional params, all are unshipped, 2 have unshipped entries. - public void Method5(int p1 = 0) { } - public void Method5(char p1 = 'a') { } - public void Method5(string p1 = null) { } - - // ok - multiple overloads with optional params, but all have same params (differ only by generic vs non-generic). - public object Method6(int p1 = 0) { return Method6(p1); } - public T Method6(int p1 = 0) { return default(T); } -} -"; - - string shippedText = $@" -C.Method3(int p1 = 0) -> void -C.Method3(string p1 = null) -> void -C.Method4(char p1 = 'a') -> void -C.Method4(string p1 = null) -> void -"; - string unshippedText = $@" -C -C.C() -> void -C.Method1() -> void -C.Method1(int p1, int p2) -> void -C.Method2(int p1 = 0) -> void -C.Method4(int p1 = 0) -> void -C.Method5(char p1 = 'a') -> void -C.Method5(string p1 = null) -> void -C.Method6(int p1 = 0) -> object -C.Method6(int p1 = 0) -> T -"; + var source = $$""" - await VerifyCSharpAsync(source, shippedText, unshippedText, - // Test0.cs(5,17): warning RS0016: Symbol 'Method1' is not part of the declared API. - GetCSharpResultAt(5, 17, DeclarePublicApiAnalyzer.DeclareNewApiRule, "Method1"), - // Test0.cs(8,17): warning RS0016: Symbol 'Method1' is not part of the declared API. - GetCSharpResultAt(8, 17, DeclarePublicApiAnalyzer.DeclareNewApiRule, "Method1"), - // Test0.cs(20,17): warning RS0026: Symbol 'Method4' violates the backcompat requirement: 'Do not add multiple overloads with optional parameters'. See 'https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md' for details. - GetCSharpResultAt(20, 17, DeclarePublicApiAnalyzer.AvoidMultipleOverloadsWithOptionalParameters, "Method4", DeclarePublicApiAnalyzer.AvoidMultipleOverloadsWithOptionalParameters.HelpLinkUri), - // Test0.cs(25,17): warning RS0016: Symbol 'Method5' is not part of the declared API. - GetCSharpResultAt(25, 17, DeclarePublicApiAnalyzer.DeclareNewApiRule, "Method5"), - // Test0.cs(25,17): warning RS0026: Symbol 'Method5' violates the backcompat requirement: 'Do not add multiple overloads with optional parameters'. See 'https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md' for details. - GetCSharpResultAt(25, 17, DeclarePublicApiAnalyzer.AvoidMultipleOverloadsWithOptionalParameters, "Method5", DeclarePublicApiAnalyzer.AvoidMultipleOverloadsWithOptionalParameters.HelpLinkUri), - // Test0.cs(26,17): warning RS0026: Symbol 'Method5' violates the backcompat requirement: 'Do not add multiple overloads with optional parameters'. See 'https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md' for details. - GetCSharpResultAt(26, 17, DeclarePublicApiAnalyzer.AvoidMultipleOverloadsWithOptionalParameters, "Method5", DeclarePublicApiAnalyzer.AvoidMultipleOverloadsWithOptionalParameters.HelpLinkUri), - // Test0.cs(27,17): warning RS0026: Symbol 'Method5' violates the backcompat requirement: 'Do not add multiple overloads with optional parameters'. See 'https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md' for details. - GetCSharpResultAt(27, 17, DeclarePublicApiAnalyzer.AvoidMultipleOverloadsWithOptionalParameters, "Method5", DeclarePublicApiAnalyzer.AvoidMultipleOverloadsWithOptionalParameters.HelpLinkUri)); + public class C + { + // ok - single overload with optional params, 2 overloads have no public API entries. + {{EnabledModifierCSharp}} void Method1(int p1, int p2, int p3 = 0) { } + {{EnabledModifierCSharp}} void Method1() { } + {{EnabledModifierCSharp}} void Method1(int p1, int p2) { } + {{EnabledModifierCSharp}} void Method1(char p1, params int[] p2) { } + + // ok - multiple overloads with optional params, but only one is public. + {{EnabledModifierCSharp}} void Method2(int p1 = 0) { } + {{DisabledModifierCSharp}} void Method2(char p1 = '0') { } + private void Method2(string p1 = null) { } + + // ok - multiple overloads with optional params, but all are shipped. + {{EnabledModifierCSharp}} void Method3(int p1 = 0) { } + {{EnabledModifierCSharp}} void Method3(string p1 = null) { } + + // fire on unshipped (1) - multiple overloads with optional params, all but first are shipped. + {{EnabledModifierCSharp}} void Method4(int p1 = 0) { } + {{EnabledModifierCSharp}} void Method4(char p1 = 'a') { } + {{EnabledModifierCSharp}} void Method4(string p1 = null) { } + + // fire on all unshipped (3) - multiple overloads with optional params, all are unshipped, 2 have unshipped entries. + {{EnabledModifierCSharp}} void Method5(int p1 = 0) { } + {{EnabledModifierCSharp}} void Method5(char p1 = 'a') { } + {{EnabledModifierCSharp}} void Method5(string p1 = null) { } + + // ok - multiple overloads with optional params, but all have same params (differ only by generic vs non-generic). + {{EnabledModifierCSharp}} object Method6(int p1 = 0) { return Method6(p1); } + {{EnabledModifierCSharp}} T Method6(int p1 = 0) { return default(T); } + } + """; + + string shippedText = """ + C.Method3(int p1 = 0) -> void + C.Method3(string p1 = null) -> void + C.Method4(char p1 = 'a') -> void + C.Method4(string p1 = null) -> void + """; + string unshippedText = + (IsInternalTest ? "" : + """ + C + C.C() -> void + + """) + + """ + C.Method1() -> void + C.Method1(int p1, int p2) -> void + C.Method2(int p1 = 0) -> void + C.Method4(int p1 = 0) -> void + C.Method5(char p1 = 'a') -> void + C.Method5(string p1 = null) -> void + C.Method6(int p1 = 0) -> object + C.Method6(int p1 = 0) -> T + """; + + // The error on Method2 is the difference between internal and public results + var result = IsInternalTest + ? new DiagnosticResult[] + { + // Test0.cs(5,17): warning RS0016: Symbol 'Method1' is not part of the declared API. + GetCSharpResultAt(5, 19, DeclareNewApiRule, "Method1"), + // Test0.cs(8,17): warning RS0016: Symbol 'Method1' is not part of the declared API. + GetCSharpResultAt(8, 19, DeclareNewApiRule, "Method1"), + // /0/Test0.cs(11,19): warning RS0059: Symbol 'Method2' violates the backcompat requirement: 'Do not add multiple overloads with optional parameters'. See 'https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md' for details. + GetCSharpResultAt(11, 19, AvoidMultipleOverloadsWithOptionalParameters, "Method2", AvoidMultipleOverloadsWithOptionalParameters.HelpLinkUri), + // Test0.cs(20,17): warning RS0026: Symbol 'Method4' violates the backcompat requirement: 'Do not add multiple overloads with optional parameters'. See 'https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md' for details. + GetCSharpResultAt(20, 19, AvoidMultipleOverloadsWithOptionalParameters, "Method4", AvoidMultipleOverloadsWithOptionalParameters.HelpLinkUri), + // Test0.cs(25,17): warning RS0016: Symbol 'Method5' is not part of the declared API. + GetCSharpResultAt(25, 19, DeclareNewApiRule, "Method5"), + // Test0.cs(25,17): warning RS0026: Symbol 'Method5' violates the backcompat requirement: 'Do not add multiple overloads with optional parameters'. See 'https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md' for details. + GetCSharpResultAt(25, 19, AvoidMultipleOverloadsWithOptionalParameters, "Method5", AvoidMultipleOverloadsWithOptionalParameters.HelpLinkUri), + // Test0.cs(26,17): warning RS0026: Symbol 'Method5' violates the backcompat requirement: 'Do not add multiple overloads with optional parameters'. See 'https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md' for details. + GetCSharpResultAt(26, 19, AvoidMultipleOverloadsWithOptionalParameters, "Method5", AvoidMultipleOverloadsWithOptionalParameters.HelpLinkUri), + // Test0.cs(27,17): warning RS0026: Symbol 'Method5' violates the backcompat requirement: 'Do not add multiple overloads with optional parameters'. See 'https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md' for details. + GetCSharpResultAt(27, 19, AvoidMultipleOverloadsWithOptionalParameters, "Method5", AvoidMultipleOverloadsWithOptionalParameters.HelpLinkUri) + } + : new[] { + // Test0.cs(5,17): warning RS0016: Symbol 'Method1' is not part of the declared API. + GetCSharpResultAt(5, 17, DeclareNewApiRule, "Method1"), + // Test0.cs(8,17): warning RS0016: Symbol 'Method1' is not part of the declared API. + GetCSharpResultAt(8, 17, DeclareNewApiRule, "Method1"), + // Test0.cs(20,17): warning RS0026: Symbol 'Method4' violates the backcompat requirement: 'Do not add multiple overloads with optional parameters'. See 'https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md' for details. + GetCSharpResultAt(20, 17, AvoidMultipleOverloadsWithOptionalParameters, "Method4", AvoidMultipleOverloadsWithOptionalParameters.HelpLinkUri), + // Test0.cs(25,17): warning RS0016: Symbol 'Method5' is not part of the declared API. + GetCSharpResultAt(25, 17, DeclareNewApiRule, "Method5"), + // Test0.cs(25,17): warning RS0026: Symbol 'Method5' violates the backcompat requirement: 'Do not add multiple overloads with optional parameters'. See 'https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md' for details. + GetCSharpResultAt(25, 17, AvoidMultipleOverloadsWithOptionalParameters, "Method5", AvoidMultipleOverloadsWithOptionalParameters.HelpLinkUri), + // Test0.cs(26,17): warning RS0026: Symbol 'Method5' violates the backcompat requirement: 'Do not add multiple overloads with optional parameters'. See 'https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md' for details. + GetCSharpResultAt(26, 17, AvoidMultipleOverloadsWithOptionalParameters, "Method5", AvoidMultipleOverloadsWithOptionalParameters.HelpLinkUri), + // Test0.cs(27,17): warning RS0026: Symbol 'Method5' violates the backcompat requirement: 'Do not add multiple overloads with optional parameters'. See 'https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md' for details. + GetCSharpResultAt(27, 17, AvoidMultipleOverloadsWithOptionalParameters, "Method5", AvoidMultipleOverloadsWithOptionalParameters.HelpLinkUri) + }; + + await VerifyCSharpAsync(source, shippedText, unshippedText, result); } [Fact, WorkItem(851, "https://github.com/dotnet/roslyn-analyzers/issues/851")] public async Task TestOverloadWithOptionalParametersShouldHaveMostParametersAsync() { - var source = @" -public class C -{ - // ok - single overload with optional params has most parameters. - public void Method1(int p1, int p2, int p3 = 0) { } - public void Method1() { } - public void Method1(int p1, int p2) { } - public void Method1(char p1, params int[] p2) { } - - // ok - multiple overloads with optional params violating most params requirement, but only one is public. - public void Method2(int p1 = 0) { } - internal void Method2(int p1, char p2 = '0') { } - private void Method2(string p1 = null) { } - - // ok - multiple overloads with optional params violating most params requirement, but all are shipped. - public void Method3(int p1 = 0) { } - public void Method3(string p1 = null) { } - public void Method3(int p1, int p2) { } - - // fire on unshipped (1) - single overload with optional params and violating most params requirement. - public void Method4(int p1 = 0) { } // unshipped - public void Method4(char p1, int p2) { } // unshipped - public void Method4(string p1, int p2) { } // unshipped - - // fire on shipped (1) - single shipped overload with optional params and violating most params requirement due to a new unshipped API. - public void Method5(int p1 = 0) { } // shipped - public void Method5(char p1) { } // shipped - public void Method5(string p1) { } // unshipped - - // fire on multiple shipped (2) - multiple shipped overloads with optional params and violating most params requirement due to a new unshipped API - public void Method6(int p1 = 0) { } // shipped - public void Method6(char p1 = 'a') { } // shipped - public void Method6(string p1) { } // unshipped -} -"; - - string shippedText = $@" -C.Method3(int p1 = 0) -> void -C.Method3(int p1, int p2) -> void -C.Method3(string p1 = null) -> void -C.Method5(char p1) -> void -C.Method5(int p1 = 0) -> void -C.Method6(char p1 = 'a') -> void -C.Method6(int p1 = 0) -> void -"; - string unshippedText = $@" -C -C.C() -> void -C.Method1() -> void -C.Method1(char p1, params int[] p2) -> void -C.Method1(int p1, int p2) -> void -C.Method1(int p1, int p2, int p3 = 0) -> void -C.Method2(int p1 = 0) -> void -C.Method4(char p1, int p2) -> void -C.Method4(int p1 = 0) -> void -C.Method4(string p1, int p2) -> void -C.Method5(string p1) -> void -C.Method6(string p1) -> void -"; + var source = $$""" - await VerifyCSharpAsync(source, shippedText, unshippedText, + public class C + { + // ok - single overload with optional params has most parameters. + {{EnabledModifierCSharp}} void Method1(int p1, int p2, int p3 = 0) { } + {{EnabledModifierCSharp}} void Method1() { } + {{EnabledModifierCSharp}} void Method1(int p1, int p2) { } + {{EnabledModifierCSharp}} void Method1(char p1, params int[] p2) { } + + // ok - multiple overloads with optional params violating most params requirement, but only one is public. + {{EnabledModifierCSharp}} void Method2(int p1 = 0) { } + {{DisabledModifierCSharp}} void Method2(int p1, char p2 = '0') { } + private void Method2(string p1 = null) { } + + // ok - multiple overloads with optional params violating most params requirement, but all are shipped. + {{EnabledModifierCSharp}} void Method3(int p1 = 0) { } + {{EnabledModifierCSharp}} void Method3(string p1 = null) { } + {{EnabledModifierCSharp}} void Method3(int p1, int p2) { } + + // fire on unshipped (1) - single overload with optional params and violating most params requirement. + {{EnabledModifierCSharp}} void Method4(int p1 = 0) { } // unshipped + {{EnabledModifierCSharp}} void Method4(char p1, int p2) { } // unshipped + {{EnabledModifierCSharp}} void Method4(string p1, int p2) { } // unshipped + + // fire on shipped (1) - single shipped overload with optional params and violating most params requirement due to a new unshipped API. + {{EnabledModifierCSharp}} void Method5(int p1 = 0) { } // shipped + {{EnabledModifierCSharp}} void Method5(char p1) { } // shipped + {{EnabledModifierCSharp}} void Method5(string p1) { } // unshipped + + // fire on multiple shipped (2) - multiple shipped overloads with optional params and violating most params requirement due to a new unshipped API + {{EnabledModifierCSharp}} void Method6(int p1 = 0) { } // shipped + {{EnabledModifierCSharp}} void Method6(char p1 = 'a') { } // shipped + {{EnabledModifierCSharp}} void Method6(string p1) { } // unshipped + } + """; + + string shippedText = """ + C.Method3(int p1 = 0) -> void + C.Method3(int p1, int p2) -> void + C.Method3(string p1 = null) -> void + C.Method5(char p1) -> void + C.Method5(int p1 = 0) -> void + C.Method6(char p1 = 'a') -> void + C.Method6(int p1 = 0) -> void + """; + string unshippedText = (IsInternalTest ? "" : + """ + C + C.C() -> void + + """) + """ + C.Method1() -> void + C.Method1(char p1, params int[] p2) -> void + C.Method1(int p1, int p2) -> void + C.Method1(int p1, int p2, int p3 = 0) -> void + C.Method2(int p1 = 0) -> void + C.Method4(char p1, int p2) -> void + C.Method4(int p1 = 0) -> void + C.Method4(string p1, int p2) -> void + C.Method5(string p1) -> void + C.Method6(string p1) -> void + """; + + var diagnostics = IsInternalTest ? new DiagnosticResult[] { + // /0/Test0.cs(11,19): warning RS0059: Symbol 'Method2' violates the backcompat requirement: 'Do not add multiple overloads with optional parameters'. See 'https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md' for details. + GetCSharpResultAt(11, 19, AvoidMultipleOverloadsWithOptionalParameters, "Method2", AvoidMultipleOverloadsWithOptionalParameters.HelpLinkUri), + } : new DiagnosticResult[0]; + + diagnostics = diagnostics.Concat(new[] { // Test0.cs(21,17): warning RS0027: Symbol 'Method4' violates the backcompat requirement: 'Public API with optional parameter(s) should have the most parameters amongst its public overloads'. See 'https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md' for details. - GetCSharpResultAt(21, 17, DeclarePublicApiAnalyzer.OverloadWithOptionalParametersShouldHaveMostParameters, "Method4", DeclarePublicApiAnalyzer.OverloadWithOptionalParametersShouldHaveMostParameters.HelpLinkUri), + GetCSharpResultAt(21, 11 + EnabledModifierCSharp.Length, OverloadWithOptionalParametersShouldHaveMostParameters, "Method4", OverloadWithOptionalParametersShouldHaveMostParameters.HelpLinkUri), // Test0.cs(26,17): warning RS0027: Symbol 'Method5' violates the backcompat requirement: 'Public API with optional parameter(s) should have the most parameters amongst its public overloads'. See 'https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md' for details. - GetCSharpResultAt(26, 17, DeclarePublicApiAnalyzer.OverloadWithOptionalParametersShouldHaveMostParameters, "Method5", DeclarePublicApiAnalyzer.OverloadWithOptionalParametersShouldHaveMostParameters.HelpLinkUri), + GetCSharpResultAt(26, 11 + EnabledModifierCSharp.Length, OverloadWithOptionalParametersShouldHaveMostParameters, "Method5", OverloadWithOptionalParametersShouldHaveMostParameters.HelpLinkUri), // Test0.cs(31,17): warning RS0027: Symbol 'Method6' violates the backcompat requirement: 'Public API with optional parameter(s) should have the most parameters amongst its public overloads'. See 'https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md' for details. - GetCSharpResultAt(31, 17, DeclarePublicApiAnalyzer.OverloadWithOptionalParametersShouldHaveMostParameters, "Method6", DeclarePublicApiAnalyzer.OverloadWithOptionalParametersShouldHaveMostParameters.HelpLinkUri), + GetCSharpResultAt(31, 11 + EnabledModifierCSharp.Length, OverloadWithOptionalParametersShouldHaveMostParameters, "Method6", OverloadWithOptionalParametersShouldHaveMostParameters.HelpLinkUri), // Test0.cs(32,17): warning RS0027: Symbol 'Method6' violates the backcompat requirement: 'Public API with optional parameter(s) should have the most parameters amongst its public overloads'. See 'https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md' for details. - GetCSharpResultAt(32, 17, DeclarePublicApiAnalyzer.OverloadWithOptionalParametersShouldHaveMostParameters, "Method6", DeclarePublicApiAnalyzer.OverloadWithOptionalParametersShouldHaveMostParameters.HelpLinkUri)); + GetCSharpResultAt(32, 11 + EnabledModifierCSharp.Length, OverloadWithOptionalParametersShouldHaveMostParameters, "Method6", OverloadWithOptionalParametersShouldHaveMostParameters.HelpLinkUri) + }).ToArray(); + + await VerifyCSharpAsync(source, shippedText, unshippedText, diagnostics); } [Fact, WorkItem(4766, "https://github.com/dotnet/roslyn-analyzers/issues/4766")] public async Task TestObsoleteOverloadWithOptionalParameters_NoDiagnosticAsync() { - var source = @" -using System; + var source = $$""" -public class C -{ - public void M(int p1 = 0) { } + using System; - [Obsolete] - public void M(char p1, int p2) { } -} -"; + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} void M(int p1 = 0) { } + + [Obsolete] + {{EnabledModifierCSharp}} void M(char p1, int p2) { } + } + """; string shippedText = string.Empty; string unshippedText = @" @@ -1220,17 +1357,18 @@ public void M(char p1, int p2) { } [Fact, WorkItem(4766, "https://github.com/dotnet/roslyn-analyzers/issues/4766")] public async Task TestMultipleOverloadsWithOptionalParameter_OneIsObsoleteAsync() { - var source = @" -using System; + var source = $$""" -public class C -{ - public void M(int p1 = 0) { } + using System; - [Obsolete] - public void M(char p1 = '0') { } -} -"; + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} void M(int p1 = 0) { } + + [Obsolete] + {{EnabledModifierCSharp}} void M(char p1 = '0') { } + } + """; string shippedText = @"C C.C() -> void @@ -1243,15 +1381,16 @@ public void M(char p1 = '0') { } [Fact] public async Task ObliviousMember_SimpleAsync() { - var source = @" -public class C -{ - public string Field; - public string Property { get; set; } - public string Method(string x) => throw null!; - public string ArrowExpressionProperty => throw null!; -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} string Field; + {{EnabledModifierCSharp}} string Property { get; set; } + {{EnabledModifierCSharp}} string Method(string x) => throw null!; + {{EnabledModifierCSharp}} string ArrowExpressionProperty => throw null!; + } + """; var shippedText = @"#nullable enable C @@ -1265,45 +1404,47 @@ public class C var unshippedText = @""; await VerifyCSharpAsync(source, shippedText, unshippedText, - GetCSharpResultAt(4, 19, DeclarePublicApiAnalyzer.AnnotateApiRule, "Field"), - GetCSharpResultAt(4, 19, DeclarePublicApiAnalyzer.ObliviousApiRule, "Field"), - GetCSharpResultAt(5, 30, DeclarePublicApiAnalyzer.AnnotateApiRule, "Property.get"), - GetCSharpResultAt(5, 30, DeclarePublicApiAnalyzer.ObliviousApiRule, "Property.get"), - GetCSharpResultAt(5, 35, DeclarePublicApiAnalyzer.AnnotateApiRule, "Property.set"), - GetCSharpResultAt(5, 35, DeclarePublicApiAnalyzer.ObliviousApiRule, "Property.set"), - GetCSharpResultAt(6, 19, DeclarePublicApiAnalyzer.AnnotateApiRule, "Method"), - GetCSharpResultAt(6, 19, DeclarePublicApiAnalyzer.ObliviousApiRule, "Method"), - GetCSharpResultAt(7, 46, DeclarePublicApiAnalyzer.AnnotateApiRule, "ArrowExpressionProperty.get"), - GetCSharpResultAt(7, 46, DeclarePublicApiAnalyzer.ObliviousApiRule, "ArrowExpressionProperty.get") + GetCSharpResultAt(4, 13 + EnabledModifierCSharp.Length, AnnotateApiRule, "Field"), + GetCSharpResultAt(4, 13 + EnabledModifierCSharp.Length, ObliviousApiRule, "Field"), + GetCSharpResultAt(5, 24 + EnabledModifierCSharp.Length, AnnotateApiRule, "Property.get"), + GetCSharpResultAt(5, 24 + EnabledModifierCSharp.Length, ObliviousApiRule, "Property.get"), + GetCSharpResultAt(5, 29 + EnabledModifierCSharp.Length, AnnotateApiRule, "Property.set"), + GetCSharpResultAt(5, 29 + EnabledModifierCSharp.Length, ObliviousApiRule, "Property.set"), + GetCSharpResultAt(6, 13 + EnabledModifierCSharp.Length, AnnotateApiRule, "Method"), + GetCSharpResultAt(6, 13 + EnabledModifierCSharp.Length, ObliviousApiRule, "Method"), + GetCSharpResultAt(7, 40 + EnabledModifierCSharp.Length, AnnotateApiRule, "ArrowExpressionProperty.get"), + GetCSharpResultAt(7, 40 + EnabledModifierCSharp.Length, ObliviousApiRule, "ArrowExpressionProperty.get") ); } [Fact] public async Task ObliviousMember_AlreadyMarkedAsObliviousAsync() { - var source = @" -public class C -{ - public string Field; - public D Field2; -#nullable disable - public string Property { get; set; } - public void Method(string x) => throw null!; - public string Method2() => throw null!; - public string ArrowExpressionProperty => throw null!; -#nullable enable - public D.E< -#nullable disable - string -#nullable enable - > Method3() => throw null!; -#nullable disable - public string this[string x] { get => throw null!; set => throw null!; } -} -public class D { public class E { } } -"; + var source = $$""" + + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} string Field; + {{EnabledModifierCSharp}} D Field2; + #nullable disable + {{EnabledModifierCSharp}} string Property { get; set; } + {{EnabledModifierCSharp}} void Method(string x) => throw null!; + {{EnabledModifierCSharp}} string Method2() => throw null!; + {{EnabledModifierCSharp}} string ArrowExpressionProperty => throw null!; + #nullable enable + {{EnabledModifierCSharp}} D.E< + #nullable disable + string + #nullable enable + > Method3() => throw null!; + #nullable disable + {{EnabledModifierCSharp}} string this[string x] { get => throw null!; set => throw null!; } + } + {{EnabledModifierCSharp}} class D { public class E { } } + + """; var shippedText = @"#nullable enable C @@ -1326,35 +1467,36 @@ public class D { public class E { } } var unshippedText = @""; await VerifyCSharpAsync(source, shippedText, unshippedText, - GetCSharpResultAt(4, 19, DeclarePublicApiAnalyzer.ObliviousApiRule, "Field"), - GetCSharpResultAt(7, 11, DeclarePublicApiAnalyzer.ObliviousApiRule, "Field2"), - GetCSharpResultAt(9, 30, DeclarePublicApiAnalyzer.ObliviousApiRule, "Property.get"), - GetCSharpResultAt(9, 35, DeclarePublicApiAnalyzer.ObliviousApiRule, "Property.set"), - GetCSharpResultAt(10, 17, DeclarePublicApiAnalyzer.ObliviousApiRule, "Method"), - GetCSharpResultAt(11, 19, DeclarePublicApiAnalyzer.ObliviousApiRule, "Method2"), - GetCSharpResultAt(12, 46, DeclarePublicApiAnalyzer.ObliviousApiRule, "ArrowExpressionProperty.get"), - GetCSharpResultAt(18, 15, DeclarePublicApiAnalyzer.ObliviousApiRule, "Method3"), - GetCSharpResultAt(20, 36, DeclarePublicApiAnalyzer.ObliviousApiRule, "this.get"), - GetCSharpResultAt(20, 56, DeclarePublicApiAnalyzer.ObliviousApiRule, "this.set") + GetCSharpResultAt(4, 13 + EnabledModifierCSharp.Length, ObliviousApiRule, "Field"), + GetCSharpResultAt(7, 11, ObliviousApiRule, "Field2"), + GetCSharpResultAt(9, 24 + EnabledModifierCSharp.Length, ObliviousApiRule, "Property.get"), + GetCSharpResultAt(9, 29 + EnabledModifierCSharp.Length, ObliviousApiRule, "Property.set"), + GetCSharpResultAt(10, 11 + EnabledModifierCSharp.Length, ObliviousApiRule, "Method"), + GetCSharpResultAt(11, 13 + EnabledModifierCSharp.Length, ObliviousApiRule, "Method2"), + GetCSharpResultAt(12, 40 + EnabledModifierCSharp.Length, ObliviousApiRule, "ArrowExpressionProperty.get"), + GetCSharpResultAt(18, 15, ObliviousApiRule, "Method3"), + GetCSharpResultAt(20, 30 + EnabledModifierCSharp.Length, ObliviousApiRule, "this.get"), + GetCSharpResultAt(20, 50 + EnabledModifierCSharp.Length, ObliviousApiRule, "this.set") ); } [Fact] public async Task ObliviousMember_AlreadyMarkedAsOblivious_TypeParametersWithClassConstraintAsync() { - var source = @" -public class C -{ - public void M(T t) where T : class { } + var source = $$""" -#nullable enable - public void M2(T t) where T : class { } - public void M3(T t) where T : class? { } -#nullable disable -} -public class D where T : class { } -public class E { public class F where T : class { } } -"; + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} void M(T t) where T : class { } + + #nullable enable + {{EnabledModifierCSharp}} void M2(T t) where T : class { } + {{EnabledModifierCSharp}} void M3(T t) where T : class? { } + #nullable disable + } + {{EnabledModifierCSharp}} class D where T : class { } + {{EnabledModifierCSharp}} class E { public class F where T : class { } } + """; var shippedText = @"#nullable enable C @@ -1373,25 +1515,26 @@ public class E { public class F where T : class { } } var unshippedText = @""; await VerifyCSharpAsync(source, shippedText, unshippedText, - GetCSharpResultAt(4, 17, DeclarePublicApiAnalyzer.ObliviousApiRule, "M"), - GetCSharpResultAt(11, 14, DeclarePublicApiAnalyzer.ObliviousApiRule, "D"), - GetCSharpResultAt(12, 31, DeclarePublicApiAnalyzer.ObliviousApiRule, "F") + GetCSharpResultAt(4, 11 + EnabledModifierCSharp.Length, ObliviousApiRule, "M"), + GetCSharpResultAt(11, 8 + EnabledModifierCSharp.Length, ObliviousApiRule, "D"), + GetCSharpResultAt(12, 25 + EnabledModifierCSharp.Length, ObliviousApiRule, "F") ); } [Fact] public async Task ObliviousMember_AlreadyMarkedAsOblivious_TypeParametersWithNotNullConstraintAsync() { - var source = @" -public class C -{ - public void M(T t) where T : notnull { } + var source = $$""" -#nullable enable - public void M2(T t) where T : notnull { } -#nullable disable -} -"; + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} void M(T t) where T : notnull { } + + #nullable enable + {{EnabledModifierCSharp}} void M2(T t) where T : notnull { } + #nullable disable + } + """; var shippedText = @"#nullable enable C @@ -1408,21 +1551,22 @@ public void M2(T t) where T : notnull { } [Fact] public async Task ObliviousMember_AlreadyMarkedAsOblivious_TypeParametersWithMiscConstraintsAsync() { - var source = @" -public interface I { } -public class C -{ - public void M1() where T : I { } - public void M2() where T : C { } - public void M3() where T : U where U : class { } + var source = $$""" -#nullable enable - public void M1b() where T : I { } - public void M2b() where T : C? { } - public void M3b() where T : U where U : class { } -#nullable disable -} -"; + {{EnabledModifierCSharp}} interface I { } + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} void M1() where T : I { } + {{EnabledModifierCSharp}} void M2() where T : C { } + {{EnabledModifierCSharp}} void M3() where T : U where U : class { } + + #nullable enable + {{EnabledModifierCSharp}} void M1b() where T : I { } + {{EnabledModifierCSharp}} void M2b() where T : C? { } + {{EnabledModifierCSharp}} void M3b() where T : U where U : class { } + #nullable disable + } + """; var shippedText = @"#nullable enable I @@ -1439,28 +1583,30 @@ public void M3b() where T : U where U : class { } var unshippedText = @""; await VerifyCSharpAsync(source, shippedText, unshippedText, - GetCSharpResultAt(5, 17, DeclarePublicApiAnalyzer.ObliviousApiRule, "M1"), - GetCSharpResultAt(6, 17, DeclarePublicApiAnalyzer.ObliviousApiRule, "M2"), - GetCSharpResultAt(7, 17, DeclarePublicApiAnalyzer.ObliviousApiRule, "M3") + GetCSharpResultAt(5, 11 + EnabledModifierCSharp.Length, ObliviousApiRule, "M1"), + GetCSharpResultAt(6, 11 + EnabledModifierCSharp.Length, ObliviousApiRule, "M2"), + GetCSharpResultAt(7, 11 + EnabledModifierCSharp.Length, ObliviousApiRule, "M3") ); } [Fact] public async Task ObliviousMember_AlreadyMarkedAsOblivious_TypeParametersWithMiscConstraints2Async() { - var source = @" -public interface I { } -public class C -{ -#nullable enable - public void M1() where T : I< -#nullable disable - string -#nullable enable - > { } -#nullable disable -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} interface I { } + {{EnabledModifierCSharp}} class C + { + #nullable enable + {{EnabledModifierCSharp}} void M1() where T : I< + #nullable disable + string + #nullable enable + > { } + #nullable disable + } + + """; var shippedText = @"#nullable enable I @@ -1472,23 +1618,24 @@ public void M1() where T : I< var unshippedText = @""; await VerifyCSharpAsync(source, shippedText, unshippedText, - GetCSharpResultAt(6, 17, DeclarePublicApiAnalyzer.ObliviousApiRule, "M1") + GetCSharpResultAt(6, 11 + EnabledModifierCSharp.Length, ObliviousApiRule, "M1") ); } [Fact] public async Task ObliviousMember_NestedEnumIsNotObliviousAsync() { - var source = @" -public class C -{ - public enum E - { - None, - Some - } -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} enum E + { + None, + Some + } + } + """; var shippedText = @"#nullable enable C @@ -1505,17 +1652,18 @@ public enum E [Fact] public async Task NestedEnumIsNotObliviousAsync() { - var source = @" -#nullable enable -public class C -{ - public enum E - { - None, - Some - } -} -"; + var source = $$""" + + #nullable enable + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} enum E + { + None, + Some + } + } + """; var shippedText = @"#nullable enable C @@ -1532,19 +1680,20 @@ public enum E [Fact] public async Task ObliviousTypeArgumentInContainingTypeAsync() { - var source = @" -#nullable enable -public class C -{ - public struct Nested { } + var source = $$""" - public C< -#nullable disable - string -#nullable enable - >.Nested field; -} -"; + #nullable enable + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} struct Nested { } + + {{EnabledModifierCSharp}} C< + #nullable disable + string + #nullable enable + >.Nested field; + } + """; var shippedText = @"#nullable enable C @@ -1556,23 +1705,25 @@ public C< var unshippedText = @""; await VerifyCSharpAsync(source, shippedText, unshippedText, - GetCSharpResultAt(11, 22, DeclarePublicApiAnalyzer.ObliviousApiRule, "field") + GetCSharpResultAt(11, 22, ObliviousApiRule, "field") ); } [Fact] public async Task ImplicitContainingType_TClassAsync() { - var source = @" -#nullable enable -public class C where T : class -{ - public struct Nested { } + var source = $$""" - public Nested field; - public C.Nested field2; -} -"; + #nullable enable + {{EnabledModifierCSharp}} class C where T : class + { + {{EnabledModifierCSharp}} struct Nested { } + + {{EnabledModifierCSharp}} Nested field; + {{EnabledModifierCSharp}} C.Nested field2; + } + + """; var shippedText = @"#nullable enable C @@ -1594,23 +1745,24 @@ public struct Nested { } // Another recourse is to make the containing type explicit: `C.Nested` await VerifyCSharpAsync(source, shippedText, unshippedText, // /0/Test0.cs(7,19): warning RS0041: Symbol 'field' uses some oblivious reference types. - GetCSharpResultAt(7, 19, DeclarePublicApiAnalyzer.ObliviousApiRule, "field") + GetCSharpResultAt(7, 13 + EnabledModifierCSharp.Length, ObliviousApiRule, "field") ); } [Fact] public async Task ImplicitContainingType_TOpenAsync() { - var source = @" -#nullable enable -public class C -{ - public struct Nested { } + var source = $$""" - public Nested field; - public Nested field2; -} -"; + #nullable enable + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} struct Nested { } + + {{EnabledModifierCSharp}} Nested field; + {{EnabledModifierCSharp}} Nested field2; + } + """; var shippedText = @"#nullable enable C @@ -1632,11 +1784,11 @@ public struct Nested { } [Fact] public async Task ShippedTextWithMissingImplicitStructConstructorAsync() { - var source = @" -public struct {|RS0016:C|} -{ -} -"; + var source = $$""" + {{EnabledModifierCSharp}} struct {|{{AddNewApiId}}:C|} + { + } + """; var shippedText = @" C"; @@ -1649,12 +1801,12 @@ public struct {|RS0016:C|} [Fact] public async Task ShippedTextWithMissingImplicitStructConstructorWithExplicitPrivateCtorWithParametersAsync() { - var source = @" -public struct {|RS0016:C|} -{ - private C(string x) {} -} -"; + var source = $$""" + {{EnabledModifierCSharp}} struct {|{{AddNewApiId}}:C|} + { + private C(string x) {} + } + """; var shippedText = @" C"; @@ -1667,14 +1819,14 @@ private C(string x) {} [Fact] public async Task ShippedTextWithMissingImplicitStructConstructorWithOtherOverloadsAsync() { - var source = @" -public struct {|RS0016:C|} -{ - public C(int value) - { - } -} -"; + var source = $$""" + {{EnabledModifierCSharp}} struct {|{{AddNewApiId}}:C|} + { + {{EnabledModifierCSharp}} C(int value) + { + } + } + """; var shippedText = @" C @@ -1689,12 +1841,12 @@ public C(int value) [WorkItem(2622, "https://github.com/dotnet/roslyn-analyzers/issues/2622")] public async Task AnalyzerFileMissing_Both_FixAsync() { - var source = @" -public class {|RS0016:C|} -{ - private C() { } -} -"; + var source = $$""" + {{EnabledModifierCSharp}} class {|{{AddNewApiId}}:C|} + { + private C() { } + } + """; string? shippedText = null; string? unshippedText = null; @@ -1706,17 +1858,17 @@ private C() { } [Fact] public async Task TestSimpleMissingMember_FixAsync() { - var source = @" -public class C -{ - public int Field; - public int Property { get; set; } - public void Method() { } - public int ArrowExpressionProperty => 0; + var source = $$""" + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} int Field; + {{EnabledModifierCSharp}} int Property { get; set; } + {{EnabledModifierCSharp}} void Method() { } + {{EnabledModifierCSharp}} int ArrowExpressionProperty => 0; - public int {|RS0016:NewField|}; // Newly added field, not in current public API. -} -"; + {{EnabledModifierCSharp}} int {|{{AddNewApiId}}:NewField|}; // Newly added field, not in current public API. + } + """; var shippedText = @""; var unshippedText = @"C @@ -1744,15 +1896,15 @@ public void Method() { } [InlineData("\n")] // Linux line ending. public async Task TestUseExistingLineEndingsAsync(string lineEnding) { - var source = @" -public class C -{ - private C() { } - public int Field1; - public int Field2; - public int {|RS0016:Field3|}; // Newly added field, not in current public API. -} -"; + var source = $$""" + {{EnabledModifierCSharp}} class C + { + private C() { } + {{EnabledModifierCSharp}} int Field1; + {{EnabledModifierCSharp}} int Field2; + {{EnabledModifierCSharp}} int {|{{AddNewApiId}}:Field3|}; // Newly added field, not in current public API. + } + """; var shippedText = @""; var unshippedText = $"C{lineEnding}C.Field1 -> int{lineEnding}C.Field2 -> int"; @@ -1764,13 +1916,13 @@ private C() { } [WorkItem(4749, "https://github.com/dotnet/roslyn-analyzers/issues/4749")] public async Task TestUseOSLineEndingAsync() { - var source = @" -public class C -{ - private C() { } - public int {|RS0016:Field1|}; // Newly added field, not in current public API. -} -"; + var source = $$""" + {{EnabledModifierCSharp}} class C + { + private C() { } + {{EnabledModifierCSharp}} int {|{{AddNewApiId}}:Field1|}; // Newly added field, not in current public API. + } + """; var shippedText = @""; var unshippedText = $"C"; var fixedUnshippedText = $"C{Environment.NewLine}C.Field1 -> int"; @@ -1780,13 +1932,13 @@ private C() { } [Fact] public async Task TestSimpleMissingMember_Fix_WithoutNullabilityAsync() { - var source = @" -#nullable enable -public class C -{ - public string? {|RS0037:{|RS0016:NewField|}|}; // Newly added field, not in current public API. -} -"; + var source = $$""" + #nullable enable + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} string? {|{{ShouldAnnotateApiFilesId}}:{|{{AddNewApiId}}:NewField|}|}; // Newly added field, not in current public API. + } + """; var shippedText = @""; var unshippedText = @"C @@ -1803,13 +1955,13 @@ public class C [Theory] public async Task TestSimpleMissingMember_Fix_WithoutNullability_MultipleFilesAsync(int index) { - var source = @" -#nullable enable -public class C -{ - public string? {|RS0037:{|RS0016:NewField|}|}; // Newly added field, not in current public API. -} -"; + var source = $$""" + #nullable enable + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} string? {|{{ShouldAnnotateApiFilesId}}:{|{{AddNewApiId}}:NewField|}|}; // Newly added field, not in current public API. + } + """; var shippedText = @""; var unshippedText1 = @"C @@ -1820,26 +1972,26 @@ public class C C.NewField -> string"; var fixedUnshippedText1_index1 = "C.NewField -> string"; - var unshippedTextName2 = DeclarePublicApiAnalyzer.UnshippedFileNamePrefix + "test" + DeclarePublicApiAnalyzer.Extension; + var unshippedTextName2 = UnshippedFileNamePrefix + "test" + DeclarePublicApiAnalyzer.Extension; var test = new CSharpCodeFixTest(); test.TestState.Sources.Add(source); - test.TestState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.ShippedFileName, shippedText)); - test.TestState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.UnshippedFileName, unshippedText1)); + test.TestState.AdditionalFiles.Add((ShippedFileName, shippedText)); + test.TestState.AdditionalFiles.Add((UnshippedFileName, unshippedText1)); test.TestState.AdditionalFiles.Add((unshippedTextName2, unshippedText2)); test.CodeActionIndex = index; - test.FixedState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.ShippedFileName, shippedText)); + test.FixedState.AdditionalFiles.Add((ShippedFileName, shippedText)); if (index == 0) { - test.FixedState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.UnshippedFileName, fixedUnshippedText1_index0)); + test.FixedState.AdditionalFiles.Add((UnshippedFileName, fixedUnshippedText1_index0)); test.FixedState.AdditionalFiles.Add((unshippedTextName2, unshippedText2)); } else if (index == 1) { - test.FixedState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.UnshippedFileName, unshippedText1)); + test.FixedState.AdditionalFiles.Add((UnshippedFileName, unshippedText1)); test.FixedState.AdditionalFiles.Add((unshippedTextName2, fixedUnshippedText1_index1)); } else @@ -1853,13 +2005,13 @@ public class C [Fact] public async Task TestSimpleMissingMember_Fix_WithNullabilityAsync() { - var source = @" -#nullable enable -public class C -{ - public string? {|RS0016:NewField|}; // Newly added field, not in current public API. -} -"; + var source = $$""" + #nullable enable + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} string? {|{{AddNewApiId}}:NewField|}; // Newly added field, not in current public API. + } + """; var shippedText = $@"#nullable enable"; var unshippedText = @"C @@ -1874,14 +2026,14 @@ public class C [Fact] public async Task TestSimpleMissingMember_Fix_WithNullability2Async() { - var source = @" -#nullable enable -public class C -{ - public string? OldField; - public string? {|RS0016:NewField|}; // Newly added field, not in current public API. -} -"; + var source = $$""" + #nullable enable + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} string? OldField; + {{EnabledModifierCSharp}} string? {|{{AddNewApiId}}:NewField|}; // Newly added field, not in current public API. + } + """; var shippedText = $@"#nullable enable"; var unshippedText = @"C C.C() -> void @@ -1897,14 +2049,14 @@ public class C [Fact] public async Task TestSimpleMissingMember_Fix_WithNullability3Async() { - var source = @" -#nullable enable -public class C -{ - public string? OldField; - public string? NewField; -} -"; + var source = $$""" + #nullable enable + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} string? OldField; + {{EnabledModifierCSharp}} string? NewField; + } + """; var shippedText = $@"#nullable enable C C.C() -> void @@ -1919,16 +2071,18 @@ public class C [Fact] public async Task TestAddAndRemoveMembers_CSharp_Fix_WithRemovedNullabilityAsync() { - var source = @" -public class C -{ - public string {|RS0041:{|RS0016:ChangedField|}|}; // oblivious -} -"; + var source = $$""" + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} string {|{{ObliviousApiId}}:{|{{AddNewApiId}}:ChangedField|}|}; // oblivious + } + """; var shippedText = $@"#nullable enable"; - var unshippedText = @"C -C.C() -> void -{|RS0017:C.ChangedField -> string?|}"; + var unshippedText = $$""" + C + C.C() -> void + {|{{RemoveApiId}}:C.ChangedField -> string?|} + """; var fixedUnshippedText = @"C C.C() -> void ~C.ChangedField -> string"; @@ -1939,123 +2093,131 @@ public class C public async Task ObliviousApiDiagnosticInGeneratedFileStillWarnAsync() { // We complain about oblivious APIs in generated files too (no special treatment) - var source = @" -// -public class C -{ - public string ObliviousField; -} -"; + var source = $$""" + + // + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} string ObliviousField; + } + """; var shippedText = "#nullable enable"; var unshippedText = @"C C.C() -> void C.ObliviousField -> string"; await VerifyCSharpAsync(source, shippedText, unshippedText, // /0/Test0.cs(5,19): warning RS0036: Symbol 'ObliviousField' is missing nullability annotations in the declared API. - GetCSharpResultAt(5, 19, DeclarePublicApiAnalyzer.AnnotateApiRule, "ObliviousField"), + GetCSharpResultAt(5, 13 + EnabledModifierCSharp.Length, AnnotateApiRule, "ObliviousField"), // /0/Test0.cs(5,19): warning RS0041: Symbol 'ObliviousField' uses some oblivious reference types. - GetCSharpResultAt(5, 19, DeclarePublicApiAnalyzer.ObliviousApiRule, "ObliviousField") + GetCSharpResultAt(5, 13 + EnabledModifierCSharp.Length, ObliviousApiRule, "ObliviousField") ); } [Fact, WorkItem(3672, "https://github.com/dotnet/roslyn-analyzers/issues/3672")] public async Task TypeArgumentRefersToTypeParameter_OnMethodAsync() { - var source = @" -#nullable enable -public static class C -{ - public static void M() - where T : System.IComparable - { - } -} -"; + var source = $$""" + + #nullable enable + {{EnabledModifierCSharp}} static class C + { + {{EnabledModifierCSharp}} static void M() + where T : System.IComparable + { + } + } + """; var shippedText = "#nullable enable"; var unshippedText = @""; await VerifyCSharpAsync(source, shippedText, unshippedText, // /0/Test0.cs(3,21): warning RS0016: Symbol 'C' is not part of the declared API. - GetCSharpResultAt(3, 21, DeclarePublicApiAnalyzer.DeclareNewApiRule, "C"), + GetCSharpResultAt(3, 15 + EnabledModifierCSharp.Length, DeclareNewApiRule, "C"), // /0/Test0.cs(5,24): warning RS0016: Symbol 'M' is not part of the declared API. - GetCSharpResultAt(5, 24, DeclarePublicApiAnalyzer.DeclareNewApiRule, "M") + GetCSharpResultAt(5, 18 + EnabledModifierCSharp.Length, DeclareNewApiRule, "M") ); } [Fact, WorkItem(3672, "https://github.com/dotnet/roslyn-analyzers/issues/3672")] public async Task TypeArgumentRefersToTypeParameter_OnTypeAsync() { - var source = @" -#nullable enable -public static class C - where T : System.IComparable -{ -} -"; + var source = $$""" + + #nullable enable + {{EnabledModifierCSharp}} static class C + where T : System.IComparable + { + } + """; var shippedText = "#nullable enable"; var unshippedText = @""; await VerifyCSharpAsync(source, shippedText, unshippedText, // /0/Test0.cs(3,21): warning RS0016: Symbol 'C' is not part of the declared API. - GetCSharpResultAt(3, 21, DeclarePublicApiAnalyzer.DeclareNewApiRule, "C") + GetCSharpResultAt(3, 15 + EnabledModifierCSharp.Length, DeclareNewApiRule, "C") ); } [Fact, WorkItem(3672, "https://github.com/dotnet/roslyn-analyzers/issues/3672")] public async Task TypeArgumentRefersToTypeParameter_OnType_SecondTypeArgumentAsync() { - var source = @" -#nullable enable -public static class C - where T1 : class - where T2 : System.IComparable< -#nullable disable - T1 -#nullable enable - > -{ -} -"; + var source = $$""" + + #nullable enable + {{EnabledModifierCSharp}} static class C + where T1 : class + where T2 : System.IComparable< + #nullable disable + T1 + #nullable enable + > + { + } + """; var shippedText = "#nullable enable"; var unshippedText = @""; await VerifyCSharpAsync(source, shippedText, unshippedText, // /0/Test0.cs(3,21): warning RS0016: Symbol 'C' is not part of the declared API. - GetCSharpResultAt(3, 21, DeclarePublicApiAnalyzer.DeclareNewApiRule, "C"), + GetCSharpResultAt(3, 15 + EnabledModifierCSharp.Length, DeclareNewApiRule, "C"), // /0/Test0.cs(3,21): warning RS0041: Symbol 'C' uses some oblivious reference types. - GetCSharpResultAt(3, 21, DeclarePublicApiAnalyzer.ObliviousApiRule, "C") + GetCSharpResultAt(3, 15 + EnabledModifierCSharp.Length, ObliviousApiRule, "C") ); } [Fact, WorkItem(3672, "https://github.com/dotnet/roslyn-analyzers/issues/3672")] public async Task TypeArgumentRefersToTypeParameter_OnType_ObliviousReferenceAsync() { - var source = @" -#nullable enable -public static class C - where T : class, System.IComparable< -#nullable disable - T -#nullable enable -> -{ -} -"; + var source = $$""" + + #nullable enable + {{EnabledModifierCSharp}} static class C + where T : class, System.IComparable< + #nullable disable + T + #nullable enable + > + { + } + + """; var shippedText = "#nullable enable"; var unshippedText = @""; await VerifyCSharpAsync(source, shippedText, unshippedText, // /0/Test0.cs(3,21): warning RS0016: Symbol 'C' is not part of the declared API. - GetCSharpResultAt(3, 21, DeclarePublicApiAnalyzer.DeclareNewApiRule, "C"), + GetCSharpResultAt(3, 15 + EnabledModifierCSharp.Length, DeclareNewApiRule, "C"), // /0/Test0.cs(3,21): warning RS0041: Symbol 'C' uses some oblivious reference types. - GetCSharpResultAt(3, 21, DeclarePublicApiAnalyzer.ObliviousApiRule, "C") + GetCSharpResultAt(3, 15 + EnabledModifierCSharp.Length, ObliviousApiRule, "C") ); } [Fact] public async Task ApiFileShippedWithDuplicateNullableEnableAsync() { - var source = @" -public class C -{ -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} class C + { + } + + """; string shippedText = $@" #nullable enable @@ -2064,7 +2226,7 @@ public class C string unshippedText = $@""; - var expected = new DiagnosticResult(DeclarePublicApiAnalyzer.PublicApiFilesInvalid) + var expected = new DiagnosticResult(ApiFilesInvalid) .WithArguments(DeclarePublicApiAnalyzer.InvalidReasonMisplacedNullableEnable); await VerifyCSharpAsync(source, shippedText, unshippedText, expected); } @@ -2072,11 +2234,12 @@ public class C [Fact] public async Task ApiFileUnshippedWithDuplicateNullableEnableAsync() { - var source = @" -public class C -{ -} -"; + var source = $$""" + + {{EnabledModifierCSharp}} class C + { + } + """; string shippedText = $@""; @@ -2085,7 +2248,7 @@ public class C #nullable enable "; - var expected = new DiagnosticResult(DeclarePublicApiAnalyzer.PublicApiFilesInvalid) + var expected = new DiagnosticResult(ApiFilesInvalid) .WithArguments(DeclarePublicApiAnalyzer.InvalidReasonMisplacedNullableEnable); await VerifyCSharpAsync(source, shippedText, unshippedText, expected); } @@ -2093,11 +2256,11 @@ public class C [Fact] public async Task ApiFileShippedWithoutNullableEnable_AvoidUnnecessaryDiagnosticAsync() { - var source = @" -public class C -{ -} -"; + var source = $$""" + {{EnabledModifierCSharp}} class C + { + } + """; string shippedText = $@"C C.C() -> void"; @@ -2112,26 +2275,28 @@ public class C public async Task TestAddAndRemoveMembers_CSharp_FixAsync() { // Unshipped file has a state 'ObsoleteField' entry and a missing 'NewField' entry. - var source = @" -public class C -{ - public int Field; - public int Property { get; set; } - public void Method() { } - public int ArrowExpressionProperty => 0; + var source = $$""" + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} int Field; + {{EnabledModifierCSharp}} int Property { get; set; } + {{EnabledModifierCSharp}} void Method() { } + {{EnabledModifierCSharp}} int ArrowExpressionProperty => 0; - public int {|RS0016:NewField|}; -} -"; + {{EnabledModifierCSharp}} int {|{{AddNewApiId}}:NewField|}; + } + """; var shippedText = @""; - var unshippedText = @"C -C.ArrowExpressionProperty.get -> int -C.C() -> void -C.Field -> int -C.Method() -> void -{|RS0017:C.ObsoleteField -> int|} -C.Property.get -> int -C.Property.set -> void"; + var unshippedText = $$""" + C + C.ArrowExpressionProperty.get -> int + C.C() -> void + C.Field -> int + C.Method() -> void + {|{{RemoveApiId}}:C.ObsoleteField -> int|} + C.Property.get -> int + C.Property.set -> void + """; var fixedUnshippedText = @"C C.ArrowExpressionProperty.get -> int C.C() -> void @@ -2147,12 +2312,12 @@ public void Method() { } [Fact] public async Task TestSimpleMissingType_FixAsync() { - var source = @" -public class {|RS0016:C|} -{ - private C() { } -} -"; + var source = $$""" + {{EnabledModifierCSharp}} class {|{{AddNewApiId}}:C|} + { + private C() { } + } + """; var shippedText = @""; var unshippedText = @""; @@ -2164,15 +2329,15 @@ private C() { } [Fact] public async Task TestMultipleMissingTypeAndMember_FixAsync() { - var source = @" -public class {|RS0016:C|} -{ - private C() { } - public int {|RS0016:Field|}; -} + var source = $$""" + {{EnabledModifierCSharp}} class {|{{AddNewApiId}}:C|} + { + private C() { } + {{EnabledModifierCSharp}} int {|{{AddNewApiId}}:Field|}; + } -public class {|RS0016:{|RS0016:C2|}|} { } -"; + {{EnabledModifierCSharp}} class {|{{AddNewApiId}}:{|{{AddNewApiId}}:C2|}|} { } + """; var shippedText = @""; var unshippedText = @""; @@ -2187,18 +2352,18 @@ public class {|RS0016:{|RS0016:C2|}|} { } [Fact] public async Task TestMultipleMissingTypeAndMember_CaseSensitiveFixAsync() { - var source = @" -public class {|RS0016:C|} -{ - private C() { } - public int {|RS0016:Field_A|}; - public int {|RS0016:Field_b|}; - public int {|RS0016:Field_C|}; - public int {|RS0016:Field_d|}; -} + var source = $$""" + {{EnabledModifierCSharp}} class {|{{AddNewApiId}}:C|} + { + private C() { } + {{EnabledModifierCSharp}} int {|{{AddNewApiId}}:Field_A|}; + {{EnabledModifierCSharp}} int {|{{AddNewApiId}}:Field_b|}; + {{EnabledModifierCSharp}} int {|{{AddNewApiId}}:Field_C|}; + {{EnabledModifierCSharp}} int {|{{AddNewApiId}}:Field_d|}; + } -public class {|RS0016:{|RS0016:C2|}|} { } -"; + {{EnabledModifierCSharp}} class {|{{AddNewApiId}}:{|{{AddNewApiId}}:C2|}|} { } + """; var shippedText = @""; var unshippedText = @""; @@ -2216,17 +2381,17 @@ public class {|RS0016:{|RS0016:C2|}|} { } [Fact] public async Task TestChangingMethodSignatureForAnUnshippedMethod_FixAsync() { - var source = @" -public class C -{ - private C() { } - public void {|RS0016:Method|}(int p1){ } -} -"; + var source = $$""" + {{EnabledModifierCSharp}} class C + { + private C() { } + {{EnabledModifierCSharp}} void {|{{AddNewApiId}}:Method|}(int p1){ } + } + """; var shippedText = @"C"; // previously method had no params, so the fix should remove the previous overload. - var unshippedText = @"{|RS0017:C.Method() -> void|}"; + var unshippedText = $$"""{|{{RemoveApiId}}:C.Method() -> void|}"""; var fixedUnshippedText = @"C.Method(int p1) -> void"; await VerifyCSharpAdditionalFileFixAsync(source, shippedText, unshippedText, fixedUnshippedText); @@ -2235,18 +2400,18 @@ private C() { } [Fact] public async Task TestChangingMethodSignatureForAnUnshippedMethod_Fix_WithNullabilityAsync() { - var source = @" -public class C -{ - private C() { } - public void {|RS0016:Method|}(object? p1){ } -} -"; + var source = $$""" + {{EnabledModifierCSharp}} class C + { + private C() { } + {{EnabledModifierCSharp}} void {|{{AddNewApiId}}:Method|}(object? p1){ } + } + """; var shippedText = $@"#nullable enable C"; // previously method had no params, so the fix should remove the previous overload. - var unshippedText = @"{|RS0017:C.Method(string p1) -> void|}"; + var unshippedText = $$"""{|{{RemoveApiId}}:C.Method(string p1) -> void|}"""; var fixedUnshippedText = @"C.Method(object? p1) -> void"; await VerifyCSharpAdditionalFileFixAsync(source, shippedText, unshippedText, fixedUnshippedText); @@ -2255,21 +2420,21 @@ private C() { } [Fact] public async Task TestChangingMethodSignatureForAnUnshippedMethodWithShippedOverloads_FixAsync() { - var source = @" -public class C -{ - private C() { } - public void Method(int p1){ } - public void Method(int p1, int p2){ } - public void {|RS0016:Method|}(char p1){ } -} -"; + var source = $$""" + {{EnabledModifierCSharp}} class C + { + private C() { } + {{EnabledModifierCSharp}} void Method(int p1){ } + {{EnabledModifierCSharp}} void Method(int p1, int p2){ } + {{EnabledModifierCSharp}} void {|{{AddNewApiId}}:Method|}(char p1){ } + } + """; var shippedText = @"C C.Method(int p1) -> void C.Method(int p1, int p2) -> void"; // previously method had no params, so the fix should remove the previous overload. - var unshippedText = @"{|RS0017:C.Method() -> void|}"; + var unshippedText = $$"""{|{{RemoveApiId}}:C.Method() -> void|}"""; var fixedUnshippedText = @"C.Method(char p1) -> void"; await VerifyCSharpAdditionalFileFixAsync(source, shippedText, unshippedText, fixedUnshippedText); @@ -2278,23 +2443,36 @@ public void Method(int p1, int p2){ } [Fact] public async Task TestAddingNewPublicOverload_FixAsync() { - var source = @" -public class C -{ - private C() { } - public void {|RS0016:Method|}(){ } - internal void Method(int p1){ } - internal void Method(int p1, int p2){ } - public void Method(char p1){ } -} -"; + var source = $$""" + public class C + { + private C() { } + {{EnabledModifierCSharp}} void {|{{AddNewApiId}}:Method|}(){ } + {{DisabledModifierCSharp}} void Method(int p1){ } + {{DisabledModifierCSharp}} void Method(int p1, int p2){ } + {{EnabledModifierCSharp}} void Method(char p1){ } + } + """; var shippedText = @""; - var unshippedText = @"C -C.Method(char p1) -> void"; - var fixedUnshippedText = @"C -C.Method() -> void -C.Method(char p1) -> void"; + var unshippedText = IsInternalTest + ? """ + C.Method(char p1) -> void + """ + : """ + C + C.Method(char p1) -> void + """; + var fixedUnshippedText = IsInternalTest + ? """ + C.Method() -> void + C.Method(char p1) -> void + """ + : """ + C + C.Method() -> void + C.Method(char p1) -> void + """; await VerifyCSharpAdditionalFileFixAsync(source, shippedText, unshippedText, fixedUnshippedText); } @@ -2302,20 +2480,20 @@ public void Method(char p1){ } [Fact] public async Task TestMissingTypeAndMemberAndNestedMembers_FixAsync() { - var source = @" -public class {|RS0016:C|} -{ - private C() { } - public int {|RS0016:Field|}; + var source = $$""" + {{EnabledModifierCSharp}} class {|{{AddNewApiId}}:C|} + { + private C() { } + {{EnabledModifierCSharp}} int {|{{AddNewApiId}}:Field|}; - public class CC - { - public int {|RS0016:Field|}; - } -} + {{EnabledModifierCSharp}} class CC + { + public int {|{{AddNewApiId}}:Field|}; + } + } -public class {|RS0016:{|RS0016:C2|}|} { } -"; + {{EnabledModifierCSharp}} class {|{{AddNewApiId}}:{|{{AddNewApiId}}:C2|}|} { } + """; var shippedText = @"C.CC C.CC.CC() -> void"; @@ -2332,52 +2510,54 @@ public class {|RS0016:{|RS0016:C2|}|} { } [Fact] public async Task TestMissingNestedGenericMembersAndStaleMembers_FixAsync() { - var source = @" -public class {|RS0016:C|} -{ - private C() { } - public CC {|RS0016:Field|}; - private C3.C4 Field2; - private C3.C4 Method(C3.C4 p1) { throw new System.NotImplementedException(); } - - public class CC - { - public int {|RS0016:Field|}; - public CC {|RS0016:Field2|}; - } - - public class C3 - { - public class C4 { } - } -} + var source = $$""" + {{EnabledModifierCSharp}} class {|{{AddNewApiId}}:C|} + { + private C() { } + {{EnabledModifierCSharp}} CC {|{{AddNewApiId}}:Field|}; + private C3.C4 Field2; + private C3.C4 Method(C3.C4 p1) { throw new System.NotImplementedException(); } + + {{EnabledModifierCSharp}} class CC + { + {{EnabledModifierCSharp}} int {|{{AddNewApiId}}:Field|}; + {{EnabledModifierCSharp}} CC {|{{AddNewApiId}}:Field2|}; + } + + {{EnabledModifierCSharp}} class C3 + { + {{EnabledModifierCSharp}} class C4 { } + } + } -public class {|RS0016:{|RS0016:C2|}|} { } -"; + {{EnabledModifierCSharp}} class {|{{AddNewApiId}}:{|{{AddNewApiId}}:C2|}|} { } + """; var shippedText = @""; - var unshippedText = @"C.C3 -C.C3.C3() -> void -C.C3.C4 -C.C3.C4.C4() -> void -C.CC -C.CC.CC() -> void -{|RS0017:C.Field2 -> C.C3.C4|} -{|RS0017:C.Method(C.C3.C4 p1) -> C.C3.C4|} -"; - var fixedUnshippedText = @"C -C.C3 -C.C3.C3() -> void -C.C3.C4 -C.C3.C4.C4() -> void -C.CC -C.CC.CC() -> void -C.CC.Field -> int -C.CC.Field2 -> C.CC -C.Field -> C.CC -C2 -C2.C2() -> void -"; + var unshippedText = $$""" + C.C3 + C.C3.C3() -> void + C.C3.C4 + C.C3.C4.C4() -> void + C.CC + C.CC.CC() -> void + {|{{RemoveApiId}}:C.Field2 -> C.C3.C4|} + {|{{RemoveApiId}}:C.Method(C.C3.C4 p1) -> C.C3.C4|} + """; + var fixedUnshippedText = """ + C + C.C3 + C.C3.C3() -> void + C.C3.C4 + C.C3.C4.C4() -> void + C.CC + C.CC.CC() -> void + C.CC.Field -> int + C.CC.Field2 -> C.CC + C.Field -> C.CC + C2 + C2.C2() -> void + """; await VerifyCSharpAdditionalFileFixAsync(source, shippedText, unshippedText, fixedUnshippedText); } @@ -2385,20 +2565,20 @@ public class {|RS0016:{|RS0016:C2|}|} { } [Fact] public async Task TestWithExistingUnshippedNestedMembers_FixAsync() { - var source = @" -public class {|RS0016:C|} -{ - private C() { } - public int {|RS0016:Field|}; + var source = $$""" + {{EnabledModifierCSharp}} class {|{{AddNewApiId}}:C|} + { + private C() { } + {{EnabledModifierCSharp}} int {|{{AddNewApiId}}:Field|}; - public class CC - { - public int Field; - } -} + {{EnabledModifierCSharp}} class CC + { + {{EnabledModifierCSharp}} int Field; + } + } -public class {|RS0016:{|RS0016:C2|}|} { } -"; + {{EnabledModifierCSharp}} class {|{{AddNewApiId}}:{|{{AddNewApiId}}:C2|}|} { } + """; var shippedText = @""; var unshippedText = @"C.CC @@ -2418,22 +2598,22 @@ public class {|RS0016:{|RS0016:C2|}|} { } [Fact] public async Task TestWithExistingUnshippedNestedGenericMembers_FixAsync() { - var source = @" -public class C -{ - private C() { } - public class {|RS0016:CC|} - { - public int Field; - } - - public class CC - { - private CC() { } - public int Field; - } -} -"; + var source = $$""" + {{EnabledModifierCSharp}} class C + { + private C() { } + {{EnabledModifierCSharp}} class {|{{AddNewApiId}}:CC|} + { + {{EnabledModifierCSharp}} int Field; + } + + {{EnabledModifierCSharp}} class CC + { + private CC() { } + {{EnabledModifierCSharp}} int Field; + } + } + """; var shippedText = @""; var unshippedText = @"C @@ -2454,20 +2634,20 @@ private CC() { } [Fact] public async Task TestWithExistingShippedNestedMembers_FixAsync() { - var source = @" -public class {|RS0016:C|} -{ - private C() { } - public int {|RS0016:Field|}; + var source = $$""" + {{EnabledModifierCSharp}} class {|{{AddNewApiId}}:C|} + { + private C() { } + {{EnabledModifierCSharp}} int {|{{AddNewApiId}}:Field|}; - public class CC - { - public int Field; - } -} + {{EnabledModifierCSharp}} class CC + { + {{EnabledModifierCSharp}} int Field; + } + } -public class {|RS0016:{|RS0016:C2|}|} { } -"; + {{EnabledModifierCSharp}} class {|{{AddNewApiId}}:{|{{AddNewApiId}}:C2|}|} { } + """; var shippedText = @"C.CC C.CC.CC() -> void @@ -2484,33 +2664,37 @@ public class {|RS0016:{|RS0016:C2|}|} { } [Fact] public async Task TestOnlyRemoveStaleSiblingEntries_FixAsync() { - var source = @" -public class {|RS0016:C|} -{ - private C() { } - public int {|RS0016:Field|}; + var source = $$""" + {{EnabledModifierCSharp}} class {|{{AddNewApiId}}:C|} + { + private C() { } + {{EnabledModifierCSharp}} int {|{{AddNewApiId}}:Field|}; - public class CC - { - private int Field; // This has a stale public API entry, but this shouldn't be removed unless we attempt to add a public API entry for a sibling. - } -} + {{EnabledModifierCSharp}} class CC + { + private int Field; // This has a stale public API entry, but this shouldn't be removed unless we attempt to add a public API entry for a sibling. + } + } -public class {|RS0016:{|RS0016:C2|}|} { } -"; + {{EnabledModifierCSharp}} class {|{{AddNewApiId}}:{|{{AddNewApiId}}:C2|}|} { } + """; var shippedText = @""; - var unshippedText = @" -C.CC -C.CC.CC() -> void -{|RS0017:C.CC.Field -> int|}"; - var fixedUnshippedText = @"C -C.CC -C.CC.CC() -> void -{|RS0017:C.CC.Field -> int|} -C.Field -> int -C2 -C2.C2() -> void"; + var unshippedText = $$""" + + C.CC + C.CC.CC() -> void + {|{{RemoveApiId}}:C.CC.Field -> int|} + """; + var fixedUnshippedText = $$""" + C + C.CC + C.CC.CC() -> void + {|{{RemoveApiId}}:C.CC.Field -> int|} + C.Field -> int + C2 + C2.C2() -> void + """; await VerifyCSharpAdditionalFileFixAsync(source, shippedText, unshippedText, fixedUnshippedText); } @@ -2521,14 +2705,14 @@ public class {|RS0016:{|RS0016:C2|}|} { } [InlineData("\r\n\r\n", "\r\n")] public async Task TestPreserveTrailingNewlineAsync(string originalEndOfFile, string expectedEndOfFile) { - var source = @" -public class C -{ - public int Property { get; } + var source = $$""" + {{EnabledModifierCSharp}} class C + { + {{EnabledModifierCSharp}} int Property { get; } - public int {|RS0016:NewField|}; // Newly added field, not in current public API. -} -"; + {{EnabledModifierCSharp}} int {|{{AddNewApiId}}:NewField|}; // Newly added field, not in current public API. + } + """; var shippedText = @""; var unshippedText = $@"C @@ -2549,11 +2733,11 @@ await VerifyCSharpAdditionalFileFixAsync( [Fact] public async Task MissingType_AAsync() { - var source = @" -public class {|RS0016:{|RS0016:A|}|} { } -public class B { } -public class D { } -"; + var source = $$""" + {{EnabledModifierCSharp}} class {|{{AddNewApiId}}:{|{{AddNewApiId}}:A|}|} { } + {{EnabledModifierCSharp}} class B { } + {{EnabledModifierCSharp}} class D { } + """; var unshippedText = @"B B.B() -> void @@ -2572,11 +2756,11 @@ public class D { } [Fact] public async Task MissingType_CAsync() { - var source = @" -public class B { } -public class {|RS0016:{|RS0016:C|}|} { } -public class D { } -"; + var source = $$""" + {{EnabledModifierCSharp}} class B { } + {{EnabledModifierCSharp}} class {|{{AddNewApiId}}:{|{{AddNewApiId}}:C|}|} { } + {{EnabledModifierCSharp}} class D { } + """; var unshippedText = @"B B.B() -> void @@ -2595,11 +2779,11 @@ public class D { } [Fact] public async Task MissingType_EAsync() { - var source = @" -public class B { } -public class D { } -public class {|RS0016:{|RS0016:E|}|} { } -"; + var source = $$""" + {{EnabledModifierCSharp}} class B { } + {{EnabledModifierCSharp}} class D { } + {{EnabledModifierCSharp}} class {|{{AddNewApiId}}:{|{{AddNewApiId}}:E|}|} { } + """; var unshippedText = @"B B.B() -> void @@ -2618,11 +2802,11 @@ public class {|RS0016:{|RS0016:E|}|} { } [Fact] public async Task MissingType_Unordered_AAsync() { - var source = @" -public class {|RS0016:{|RS0016:A|}|} { } -public class B { } -public class D { } -"; + var source = $$""" + {{EnabledModifierCSharp}} class {|{{AddNewApiId}}:{|{{AddNewApiId}}:A|}|} { } + {{EnabledModifierCSharp}} class B { } + {{EnabledModifierCSharp}} class D { } + """; var unshippedText = @"D D.D() -> void @@ -2641,11 +2825,11 @@ public class D { } [Fact] public async Task MissingType_Unordered_CAsync() { - var source = @" -public class B { } -public class {|RS0016:{|RS0016:C|}|} { } -public class D { } -"; + var source = $$""" + {{EnabledModifierCSharp}} class B { } + {{EnabledModifierCSharp}} class {|{{AddNewApiId}}:{|{{AddNewApiId}}:C|}|} { } + {{EnabledModifierCSharp}} class D { } + """; var unshippedText = @"D D.D() -> void @@ -2664,11 +2848,11 @@ public class D { } [Fact] public async Task MissingType_Unordered_EAsync() { - var source = @" -public class B { } -public class D { } -public class {|RS0016:{|RS0016:E|}|} { } -"; + var source = $$""" + {{EnabledModifierCSharp}} class B { } + {{EnabledModifierCSharp}} class D { } + {{EnabledModifierCSharp}} class {|{{AddNewApiId}}:{|{{AddNewApiId}}:E|}|} { } + """; var unshippedText = @"D D.D() -> void @@ -2687,15 +2871,15 @@ public class {|RS0016:{|RS0016:E|}|} { } [Fact, WorkItem(2195, "https://github.com/dotnet/roslyn-analyzers/issues/2195")] public async Task TestPartialTypeAsync() { - var source = @" -public partial class {|RS0016:{|RS0016:C|}|} -{ -} + var source = $$""" + {{EnabledModifierCSharp}} partial class {|{{AddNewApiId}}:{|{{AddNewApiId}}:C|}|} + { + } -public partial class {|RS0016:{|RS0016:C|}|} -{ -} -"; + {{EnabledModifierCSharp}} partial class {|{{AddNewApiId}}:{|{{AddNewApiId}}:C|}|} + { + } + """; var shippedText = @""; var unshippedText = @""; @@ -2708,9 +2892,9 @@ public partial class {|RS0016:{|RS0016:C|}|} [Fact, WorkItem(4133, "https://github.com/dotnet/roslyn-analyzers/issues/4133")] public async Task Record_ImplicitProperty_FixAsync() { - var source = @" -public record R(int {|RS0016:P|}); -"; + var source = $$""" + {{EnabledModifierCSharp}} record R(int {|{{AddNewApiId}}:P|}); + """; var shippedText = @""; var unshippedText = @"R diff --git a/src/PublicApiAnalyzers/UnitTests/DeclarePublicAPIAnalyzerTestsInternal.cs b/src/PublicApiAnalyzers/UnitTests/DeclarePublicAPIAnalyzerTestsInternal.cs new file mode 100644 index 0000000000..73c0179314 --- /dev/null +++ b/src/PublicApiAnalyzers/UnitTests/DeclarePublicAPIAnalyzerTestsInternal.cs @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. + +using System.Collections.Generic; +using Roslyn.Diagnostics.Analyzers; + +namespace Microsoft.CodeAnalysis.PublicApiAnalyzers.UnitTests +{ + public class DeclarePublicApiAnalyzerTestsInternal : DeclarePublicApiAnalyzerTestsBase + { + protected override bool IsInternalTest => true; + protected override string EnabledModifierCSharp => "internal"; + protected override string DisabledModifierCSharp => "public"; + protected override string EnabledModifierVB => "Friend"; + protected override string DisabledModifierVB => "Public"; + protected override string ShippedFileName => DeclarePublicApiAnalyzer.InternalShippedFileName; + protected override string UnshippedFileName => DeclarePublicApiAnalyzer.InternalUnshippedFileName; + protected override string UnshippedFileNamePrefix => DeclarePublicApiAnalyzer.InternalUnshippedFileNamePrefix; + protected override string AddNewApiId => RoslynDiagnosticIds.DeclareInternalApiRuleId; + protected override string RemoveApiId => RoslynDiagnosticIds.RemoveDeletedInternalApiRuleId; + protected override string DuplicatedSymbolInApiFileId => RoslynDiagnosticIds.DuplicatedSymbolInInternalApiFiles; + protected override string ShouldAnnotateApiFilesId => RoslynDiagnosticIds.ShouldAnnotateInternalApiFilesRuleId; + protected override string ObliviousApiId => RoslynDiagnosticIds.ObliviousInternalApiRuleId; + protected override DiagnosticDescriptor DeclareNewApiRule => DeclarePublicApiAnalyzer.DeclareNewInternalApiRule; + protected override DiagnosticDescriptor RemoveDeletedApiRule => DeclarePublicApiAnalyzer.RemoveDeletedInternalApiRule; + protected override DiagnosticDescriptor DuplicateSymbolInApiFiles => DeclarePublicApiAnalyzer.DuplicateSymbolInInternalApiFiles; + protected override DiagnosticDescriptor AvoidMultipleOverloadsWithOptionalParameters => DeclarePublicApiAnalyzer.AvoidMultipleOverloadsWithOptionalParametersInternal; + protected override DiagnosticDescriptor OverloadWithOptionalParametersShouldHaveMostParameters => DeclarePublicApiAnalyzer.OverloadWithOptionalParametersShouldHaveMostParametersInternal; + protected override DiagnosticDescriptor AnnotateApiRule => DeclarePublicApiAnalyzer.AnnotateInternalApiRule; + protected override DiagnosticDescriptor ObliviousApiRule => DeclarePublicApiAnalyzer.ObliviousInternalApiRule; + protected override DiagnosticDescriptor ApiFilesInvalid => DeclarePublicApiAnalyzer.InternalApiFilesInvalid; + protected override DiagnosticDescriptor ApiFileMissing => DeclarePublicApiAnalyzer.InternalApiFileMissing; + + protected override IEnumerable DisabledDiagnostics => new[] { + RoslynDiagnosticIds.DeclarePublicApiRuleId, + RoslynDiagnosticIds.RemoveDeletedPublicApiRuleId, + RoslynDiagnosticIds.PublicApiFilesInvalid, + RoslynDiagnosticIds.DuplicatedSymbolInPublicApiFiles, + RoslynDiagnosticIds.AnnotatePublicApiRuleId, + RoslynDiagnosticIds.ShouldAnnotatePublicApiFilesRuleId, + RoslynDiagnosticIds.ObliviousPublicApiRuleId, + RoslynDiagnosticIds.PublicApiFileMissing, + RoslynDiagnosticIds.AvoidMultipleOverloadsWithOptionalParametersPublic, + RoslynDiagnosticIds.OverloadWithOptionalParametersShouldHaveMostParametersPublic, + RoslynDiagnosticIds.ExposedNoninstantiableTypeRuleIdPublic, + }; + } +} diff --git a/src/PublicApiAnalyzers/UnitTests/DeclarePublicAPIAnalyzerTestsPublic.cs b/src/PublicApiAnalyzers/UnitTests/DeclarePublicAPIAnalyzerTestsPublic.cs new file mode 100644 index 0000000000..743150c436 --- /dev/null +++ b/src/PublicApiAnalyzers/UnitTests/DeclarePublicAPIAnalyzerTestsPublic.cs @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. + +using System.Collections.Generic; +using Roslyn.Diagnostics.Analyzers; + +namespace Microsoft.CodeAnalysis.PublicApiAnalyzers.UnitTests +{ + public class DeclarePublicApiAnalyzerTestsPublic : DeclarePublicApiAnalyzerTestsBase + { + protected override bool IsInternalTest => false; + protected override string EnabledModifierCSharp => "public"; + protected override string DisabledModifierCSharp => "internal"; + protected override string EnabledModifierVB => "Public"; + protected override string DisabledModifierVB => "Friend"; + protected override string ShippedFileName => DeclarePublicApiAnalyzer.PublicShippedFileName; + protected override string UnshippedFileName => DeclarePublicApiAnalyzer.PublicUnshippedFileName; + protected override string UnshippedFileNamePrefix => DeclarePublicApiAnalyzer.PublicUnshippedFileNamePrefix; + protected override string AddNewApiId => RoslynDiagnosticIds.DeclarePublicApiRuleId; + protected override string RemoveApiId => RoslynDiagnosticIds.RemoveDeletedPublicApiRuleId; + protected override string DuplicatedSymbolInApiFileId => RoslynDiagnosticIds.DuplicatedSymbolInPublicApiFiles; + protected override string ShouldAnnotateApiFilesId => RoslynDiagnosticIds.ShouldAnnotatePublicApiFilesRuleId; + protected override string ObliviousApiId => RoslynDiagnosticIds.ObliviousPublicApiRuleId; + protected override DiagnosticDescriptor DeclareNewApiRule => DeclarePublicApiAnalyzer.DeclareNewPublicApiRule; + protected override DiagnosticDescriptor RemoveDeletedApiRule => DeclarePublicApiAnalyzer.RemoveDeletedPublicApiRule; + protected override DiagnosticDescriptor DuplicateSymbolInApiFiles => DeclarePublicApiAnalyzer.DuplicateSymbolInPublicApiFiles; + protected override DiagnosticDescriptor AvoidMultipleOverloadsWithOptionalParameters => DeclarePublicApiAnalyzer.AvoidMultipleOverloadsWithOptionalParametersPublic; + protected override DiagnosticDescriptor OverloadWithOptionalParametersShouldHaveMostParameters => DeclarePublicApiAnalyzer.OverloadWithOptionalParametersShouldHaveMostParametersPublic; + protected override DiagnosticDescriptor AnnotateApiRule => DeclarePublicApiAnalyzer.AnnotatePublicApiRule; + protected override DiagnosticDescriptor ObliviousApiRule => DeclarePublicApiAnalyzer.ObliviousPublicApiRule; + protected override DiagnosticDescriptor ApiFilesInvalid => DeclarePublicApiAnalyzer.PublicApiFilesInvalid; + protected override DiagnosticDescriptor ApiFileMissing => DeclarePublicApiAnalyzer.PublicApiFileMissing; + + protected override IEnumerable DisabledDiagnostics => new[] { + RoslynDiagnosticIds.DeclareInternalApiRuleId, + RoslynDiagnosticIds.RemoveDeletedInternalApiRuleId, + RoslynDiagnosticIds.InternalApiFilesInvalid, + RoslynDiagnosticIds.DuplicatedSymbolInInternalApiFiles, + RoslynDiagnosticIds.AnnotateInternalApiRuleId, + RoslynDiagnosticIds.ShouldAnnotateInternalApiFilesRuleId, + RoslynDiagnosticIds.ObliviousInternalApiRuleId, + RoslynDiagnosticIds.InternalApiFileMissing, + RoslynDiagnosticIds.AvoidMultipleOverloadsWithOptionalParametersInternal, + RoslynDiagnosticIds.OverloadWithOptionalParametersShouldHaveMostParametersInternal, + RoslynDiagnosticIds.ExposedNoninstantiableTypeRuleIdInternal, + }; + } +} diff --git a/src/PublicApiAnalyzers/UnitTests/NullableEnablePublicApiAnalyzerTests.cs b/src/PublicApiAnalyzers/UnitTests/NullableEnablePublicApiAnalyzerTests.cs index 35ca8bd72d..7eeee0d53b 100644 --- a/src/PublicApiAnalyzers/UnitTests/NullableEnablePublicApiAnalyzerTests.cs +++ b/src/PublicApiAnalyzers/UnitTests/NullableEnablePublicApiAnalyzerTests.cs @@ -26,12 +26,12 @@ private async Task VerifyCSharpAsync(string source, string shippedApiText, strin if (shippedApiText != null) { - test.TestState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.ShippedFileName, shippedApiText)); + test.TestState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.PublicShippedFileName, shippedApiText)); } if (unshippedApiText != null) { - test.TestState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.UnshippedFileName, unshippedApiText)); + test.TestState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.PublicUnshippedFileName, unshippedApiText)); } test.ExpectedDiagnostics.AddRange(expected); @@ -48,12 +48,12 @@ private async Task VerifyAdditionalFileFixAsync(string source, string oldShipped var test = new CSharpCodeFixTest(); test.TestState.Sources.Add(source); - test.TestState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.ShippedFileName, oldShippedApiText)); - test.TestState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.UnshippedFileName, oldUnshippedApiText)); + test.TestState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.PublicShippedFileName, oldShippedApiText)); + test.TestState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.PublicUnshippedFileName, oldUnshippedApiText)); test.FixedState.Sources.Add(newSource); - test.FixedState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.ShippedFileName, newShippedApiText)); - test.FixedState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.UnshippedFileName, newUnshippedApiText)); + test.FixedState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.PublicShippedFileName, newShippedApiText)); + test.FixedState.AdditionalFiles.Add((DeclarePublicApiAnalyzer.PublicUnshippedFileName, newUnshippedApiText)); await test.RunAsync(); } diff --git a/src/Roslyn.Diagnostics.Analyzers/Core/RoslynDiagnosticIds.cs b/src/Roslyn.Diagnostics.Analyzers/Core/RoslynDiagnosticIds.cs index 8d001d661d..cfbb634991 100644 --- a/src/Roslyn.Diagnostics.Analyzers/Core/RoslynDiagnosticIds.cs +++ b/src/Roslyn.Diagnostics.Analyzers/Core/RoslynDiagnosticIds.cs @@ -20,17 +20,17 @@ internal static class RoslynDiagnosticIds // public const string DoNotCallLinqOnIndexable = "RS0014"; // Now RS0014 => System.Runtime.Analyzers.DoNotUseEnumerableMethodsOnIndexableCollectionsInsteadUseTheCollectionDirectlyAnalyzer // public const string ConsumePreserveSigRuleId = "RS0015"; // Now CA2010 => System.Runtime.InteropServices.Analyzers.AlwaysConsumeTheValueReturnedByMethodsMarkedWithPreserveSigAttributeAnalyzer public const string DeclarePublicApiRuleId = "RS0016"; - public const string RemoveDeletedApiRuleId = "RS0017"; + public const string RemoveDeletedPublicApiRuleId = "RS0017"; // public const string DoNotCreateTasksWithoutTaskSchedulerRuleId = "RS0018"; // Now CA2008 => System.Threading.Tasks.Analyzers.DoNotCreateTasksWithoutPassingATaskSchedulerAnalyzer public const string SymbolDeclaredEventRuleId = "RS0019"; // public const string DeadCodeRuleId = "RS0020"; // Now ??? // public const string DeadCodeTriggerRuleId = "RS0021"; // Now ??? - public const string ExposedNoninstantiableTypeRuleId = "RS0022"; + public const string ExposedNoninstantiableTypeRuleIdPublic = "RS0022"; public const string MissingSharedAttributeRuleId = "RS0023"; public const string PublicApiFilesInvalid = "RS0024"; public const string DuplicatedSymbolInPublicApiFiles = "RS0025"; - public const string AvoidMultipleOverloadsWithOptionalParameters = "RS0026"; - public const string OverloadWithOptionalParametersShouldHaveMostParameters = "RS0027"; + public const string AvoidMultipleOverloadsWithOptionalParametersPublic = "RS0026"; + public const string OverloadWithOptionalParametersShouldHaveMostParametersPublic = "RS0027"; public const string RoslynAnalyzerMustUseIdInSpecifiedRangeRuleId = "RS0028"; public const string RoslynAnalyzerMustUseCategoriesFromSpecifiedRangeRuleId = "RS0029"; public const string SymbolIsBannedRuleId = "RS0030"; @@ -40,7 +40,7 @@ internal static class RoslynDiagnosticIds public const string ExportedPartsShouldHaveImportingConstructorRuleId = "RS0034"; public const string RestrictedInternalsVisibleToRuleId = "RS0035"; public const string AnnotatePublicApiRuleId = "RS0036"; - public const string ShouldAnnotateApiFilesRuleId = "RS0037"; + public const string ShouldAnnotatePublicApiFilesRuleId = "RS0037"; public const string PreferNullLiteralRuleId = "RS0038"; public const string RelaxTestNamingSuppressionRuleId = "RS0039"; public const string DefaultableTypeShouldHaveDefaultableFieldsRuleId = "RS0040"; @@ -56,6 +56,18 @@ internal static class RoslynDiagnosticIds public const string RemovedApiIsNotActuallyRemovedRuleId = "RS0050"; + public const string DeclareInternalApiRuleId = "RS0051"; + public const string RemoveDeletedInternalApiRuleId = "RS0052"; + public const string InternalApiFilesInvalid = "RS0053"; + public const string DuplicatedSymbolInInternalApiFiles = "RS0054"; + public const string AnnotateInternalApiRuleId = "RS0055"; + public const string ShouldAnnotateInternalApiFilesRuleId = "RS0056"; + public const string ObliviousInternalApiRuleId = "RS0057"; + public const string InternalApiFileMissing = "RS0058"; + public const string AvoidMultipleOverloadsWithOptionalParametersInternal = "RS0059"; + public const string OverloadWithOptionalParametersShouldHaveMostParametersInternal = "RS0060"; + public const string ExposedNoninstantiableTypeRuleIdInternal = "RS0061"; + //public const string WrapStatementsRuleId = "RS0100"; // Now ported to dotnet/roslyn https://github.com/dotnet/roslyn/pull/50358 //public const string BlankLinesRuleId = "RS0101"; // Now ported to dotnet/roslyn https://github.com/dotnet/roslyn/pull/50358 //public const string BracePlacementRuleId = "RS0102"; // Now ported to dotnet/roslyn https://github.com/dotnet/roslyn/pull/50358 diff --git a/test.sh b/test.sh old mode 100644 new mode 100755