codeformatter icon indicating copy to clipboard operation
codeformatter copied to clipboard

HasUsingsOutsideNamespace rule can introduce warning CS0105

Open nslottow opened this issue 11 years ago • 7 comments

namespace A
{
    using System;
}

namespace B
{
    using System;
}

results in

using System;

using System;
namespace A
{
}

namespace B
{
}

warning CS0105: The using directive for 'System' appeared previously in this namespace

See nslottow@ef3bbba6a153f4168022f80e2b0702e8a68b728d

nslottow avatar Jan 20 '15 02:01 nslottow

We should probably add a rule which cleans up usings

krwq avatar Jan 20 '15 18:01 krwq

We should do that, but we should also catch this case when we promote usings.

AlexGhiondea avatar Jan 23 '15 23:01 AlexGhiondea

if we clean them up later then we can remove duplicates. I don't think there is a purpose in doing it twice

krwq avatar Jan 26 '15 18:01 krwq

I think a rule should not make the code worse. What if the rule to clean-up the usings is not run? That will leave the code with a warning.

I think we can code this rule in such a way that we don't introduce a warning.

AlexGhiondea avatar Jan 26 '15 19:01 AlexGhiondea

Properly implementing this rule requires some level of semantic analysis.

CC'd @jasonmalinowski in case he knows of an API that could help us here.

jaredpar avatar Jan 26 '15 20:01 jaredpar

We don't have any public cleanup API for this, just the building blocks.

Don't forget that promotion itself requires semantics: if you have "using C" inside a namespace A it might either bind to A.C or to global::C, and you don't know which. Also, using aliases can include unqualified types that can't be moved to the top level. Moving a declaration might also change binding and break other code if there's now an ambiguous type. This is very hard to get right. Unless we have a major codebase right now that's breaking the rule and we need and automated tool to fix it, I'd say just flag it, don't try to fix it, and have the developer do it for now.

jasonmalinowski avatar Jan 26 '15 20:01 jasonmalinowski

Some instances of this seem detectable, like having the rule say "if the exact clause I'm adding already exists, just ignore it". HashSet and sort the output to just rewrite the whole section.

This seemed particularly interesting on a file just now:

// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using global::System;
using global::System.Diagnostics;
using global::System.Security.Cryptography;

namespace System.Security.Cryptography
{
    using global::System;
    using global::System.Diagnostics;
    using global::System.Security.Cryptography;
    public partial interface ICspAsymmetricAlgorithm
    {
        CspKeyContainerInfo CspKeyContainerInfo { get;}
        byte[] ExportCspBlob(bool includePrivateParameters);
        void ImportCspBlob(byte[] rawData);
    }
}

The difference being "but, it was already there..." instead of "oh, that's funny, you moved it twice."

(And in this case it's particularly sad, because none of the types were resolved via usings, they were all "in the current namespace" or keywords)

bartonjs avatar May 21 '15 21:05 bartonjs