17

StyleCop はスペースの一貫した使用をチェックすることを提案しますが、悲しいことに反対の考えが欠けています: ソースコードにタブを使用するように強制します。この機能を追加する方法はありますか? StyleCop である必要はありません。他のツールも歓迎します。

4

7 に答える 7

12

私もスペースではなくタブを使用する人ですが、どちらかを使用する理由はたくさんあります。:)

私は実際に同じこと、つまりタブのインデントをチェックするルールが欲しかったので、StyleCop の SpacingRules ソースに基づいて作成しました。これまでにいくつかのプロジェクトでしか使用していませんが、かなりうまく機能しているようです。おそらく最適化されている可能性がありますが、機能します。

using System;
using System.Text.RegularExpressions;
using Microsoft.StyleCop;
using Microsoft.StyleCop.CSharp;

namespace CustomRules.StyleCop.CSharp
{
  [SourceAnalyzer(typeof(CsParser))]
  public class SpacingRules : SourceAnalyzer
  {
    public SpacingRules()
    {
    }

    public override void AnalyzeDocument(CodeDocument document)
    {
      Param.RequireNotNull(document, "document");

      CsDocument csdocument = (CsDocument)document;
      if (csdocument.RootElement != null && !csdocument.RootElement.Generated)
      {
        this.CheckSpacing(csdocument.Tokens);
      }
    }

    private void CheckSpacing(MasterList<CsToken> tokens)
    {
      Param.AssertNotNull(tokens, "tokens");

      foreach (var token in tokens)
      {
        if (this.Cancel)
        {
          break;
        }

        if (token.Generated)
        {
          continue;
        }

        switch (token.CsTokenType)
        {
          case CsTokenType.WhiteSpace:
            this.CheckWhitespace(token as Whitespace);
            break;

          case CsTokenType.XmlHeader:
            XmlHeader header = (XmlHeader)token;
            foreach (var xmlChild in header.ChildTokens)
            {
              this.CheckTabsInComment(xmlChild);
            }
            break;

          case CsTokenType.SingleLineComment:
          case CsTokenType.MultiLineComment:
            this.CheckTabsInComment(token);
            break;
        }

        switch (token.CsTokenClass)
        {
          case CsTokenClass.ConstructorConstraint:
            this.CheckSpacing(((ConstructorConstraint)token).ChildTokens);
            break;

          case CsTokenClass.GenericType:
            this.CheckGenericSpacing((GenericType)token);
            this.CheckSpacing(((TypeToken)token).ChildTokens);
            break;

          case CsTokenClass.Type:
            this.CheckSpacing(((TypeToken)token).ChildTokens);
            break;
        }
      }
    }

    private void CheckGenericSpacing(GenericType generic)
    {
      Param.AssertNotNull(generic, "generic");
      if (generic.ChildTokens.Count == 0)
      {
        return;
      }

      foreach (var token in generic.ChildTokens)
      {
        if (this.Cancel)
        {
          break;
        }

        if (token.CsTokenClass == CsTokenClass.GenericType)
        {
          this.CheckGenericSpacing(token as GenericType);
        }

        if (!token.Generated && token.CsTokenType == CsTokenType.WhiteSpace)
        {
          this.CheckWhitespace(token as Whitespace);
        }
      }
    }

    private void CheckWhitespace(Whitespace whitespace)
    {
      Param.AssertNotNull(whitespace, "whitespace");

      if (whitespace.Location.StartPoint.IndexOnLine == 0 && Regex.IsMatch(whitespace.Text, "^ +"))
      {
        this.AddViolation(whitespace.FindParentElement(), whitespace.LineNumber, "TabsMustBeUsed");
      }
    }

    private void CheckTabsInComment(CsToken comment)
    {
      Param.AssertNotNull(comment, "comment");

      var lines = comment.Text.Split('\n');
      for (int i = 0; i < lines.Length; i++)
      {
        if (Regex.IsMatch(lines[i], "^ +"))
        {
          this.AddViolation(comment.FindParentElement(), comment.LineNumber + i, "TabsMustBeUsed");
        }
      }
    }
  }
}

このことと一緒に、アセンブリに埋め込まれた XML ファイル「SpacingRules.xml」も必要であることに注意してください。(詳細については、StyleCop SDK のドキュメントを参照してください。)

<?xml version="1.0" encoding="utf-8" ?>
<SourceAnalyzer Name="Custom Spacing Rules">
  <Description>
    Rules which verify the spacing placed between keywords and symbols in the code.
  </Description>
  <Rules>
    <Rule Name="TabsMustBeUsed" CheckId="MY1027">
      <Context>Spaces are not allowed. Use tabs instead.</Context>
      <Description>Verifies that the code does not contain spaces.</Description>
    </Rule>
  </Rules>
</SourceAnalyzer>
于 2011-04-07T23:23:36.770 に答える
8

StyleCop+プラグインを使用して、タブの使用を強制できます。

ダウンロード後、メインの StyleCop フォルダー内のフォルダーにStyleCopPlus.dll配置するか、メイン フォルダーに直接配置します。Custom RulesC:\Program Files (x86)\StyleCop 4.7\Custom Rules

Settings.StyleCopこれで、 withを開くと、StyleCopSettingsEditorルールを設定できるようになりますSP2001: CheckAllowedIndentationCharacters

このルールは、StyleCop+タブ、More Custom Rulesサブタブ、Formatting見出しの下にあります。

ルール オプション

于 2012-05-16T10:57:50.760 に答える
3

Visual Studio を IDE として使用していて、チームメイトがこのアイデアに賛同していると仮定すると、できることの 1 つは、スペースの代わりにタブを使用するように VS を設定し、設定ファイルをエクスポートして共有することです。

この設定は、[ツール] > [オプション] > [テキスト エディター] > [すべての言語] (または使用する言語) > [タブ] の下にあり、右側で [スペースを挿入] または [タブを保持] を選択できます。

ビジュアル スタジオから設定をエクスポートするには: [ツール] > [設定のインポートとエクスポート] > [選択した環境設定のエクスポート] > [オプション] を選択します。

ちょっと考えただけですが、正直なところ、本当の問題はチームメイトからの賛同にあるようです。それ以外の場合は、いつでも設定に戻すことができます。または、サムが提案したように、チェックイン時に、自動化された再フォーマットを行うことができます。

HTH

于 2010-02-17T19:52:13.533 に答える
2

StyleCop はカスタム ルールの作成をサポートしているため、独自の「スペースの代わりに先頭のタブを使用する」ルールを追加できます。独自のルールを作成したくない場合は、http://stylecopcontrib.codeplex.com/またはhttp://github.com/AArnott/nerdbank.stylecop.rulesで既存のルールを取得できます。

于 2010-02-17T19:59:50.853 に答える
2

この警告が表示される理由は、開発者がコードをコピーして貼り付けることがあるためです。

VS2010 を使用している場合は、ソリューション エクスプローラーに移動し、Setting Style Cop にチェックを入れてから、style Cop 内の設定を変更します。たとえば、設定を無効にするか、チェックを外します [Spacing.....]

于 2011-06-01T11:29:36.553 に答える
1

ソース管理サーバー内で実行してください。pre-commit スクリプトを使用して、複数のスペースで始まる行がないかファイルをチェックし、コミットを防止します。

タブはスペースよりも優れていることに同意します。個人的な好みですが、チームの一貫性は非常に重要です。

于 2010-02-17T18:54:07.690 に答える