Nested types must be last
This commit is contained in:
parent
46604d68b3
commit
2467cf2ade
|
|
@ -16,14 +16,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
{
|
{
|
||||||
public class Frame : FrameContext, IFrameControl
|
public class Frame : FrameContext, IFrameControl
|
||||||
{
|
{
|
||||||
enum Mode
|
|
||||||
{
|
|
||||||
StartLine,
|
|
||||||
MessageHeader,
|
|
||||||
MessageBody,
|
|
||||||
Terminated,
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Encoding _ascii = Encoding.ASCII;
|
private static Encoding _ascii = Encoding.ASCII;
|
||||||
private Mode _mode;
|
private Mode _mode;
|
||||||
private bool _responseStarted;
|
private bool _responseStarted;
|
||||||
|
|
@ -690,5 +682,13 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
statusCode != 205 &&
|
statusCode != 205 &&
|
||||||
statusCode != 304;
|
statusCode != 304;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum Mode
|
||||||
|
{
|
||||||
|
StartLine,
|
||||||
|
MessageHeader,
|
||||||
|
MessageBody,
|
||||||
|
Terminated,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,35 +10,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
{
|
{
|
||||||
private static readonly byte[] EmptyArray = new byte[0];
|
private static readonly byte[] EmptyArray = new byte[0];
|
||||||
|
|
||||||
class Pool<T>
|
|
||||||
{
|
|
||||||
private readonly Stack<T[]> _stack = new Stack<T[]>();
|
|
||||||
private readonly object _sync = new object();
|
|
||||||
|
|
||||||
public T[] Alloc(int size)
|
|
||||||
{
|
|
||||||
lock (_sync)
|
|
||||||
{
|
|
||||||
if (_stack.Count != 0)
|
|
||||||
{
|
|
||||||
return _stack.Pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new T[size];
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Free(T[] value, int limit)
|
|
||||||
{
|
|
||||||
lock (_sync)
|
|
||||||
{
|
|
||||||
if (_stack.Count < limit)
|
|
||||||
{
|
|
||||||
_stack.Push(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly Pool<byte> _pool1 = new Pool<byte>();
|
private readonly Pool<byte> _pool1 = new Pool<byte>();
|
||||||
private readonly Pool<byte> _pool2 = new Pool<byte>();
|
private readonly Pool<byte> _pool2 = new Pool<byte>();
|
||||||
private readonly Pool<char> _pool3 = new Pool<char>();
|
private readonly Pool<char> _pool3 = new Pool<char>();
|
||||||
|
|
@ -121,5 +92,34 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
{
|
{
|
||||||
FreeByte(segment.Array);
|
FreeByte(segment.Array);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Pool<T>
|
||||||
|
{
|
||||||
|
private readonly Stack<T[]> _stack = new Stack<T[]>();
|
||||||
|
private readonly object _sync = new object();
|
||||||
|
|
||||||
|
public T[] Alloc(int size)
|
||||||
|
{
|
||||||
|
lock (_sync)
|
||||||
|
{
|
||||||
|
if (_stack.Count != 0)
|
||||||
|
{
|
||||||
|
return _stack.Pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new T[size];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Free(T[] value, int limit)
|
||||||
|
{
|
||||||
|
lock (_sync)
|
||||||
|
{
|
||||||
|
if (_stack.Count < limit)
|
||||||
|
{
|
||||||
|
_stack.Push(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -148,15 +148,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
|
|
||||||
private Mode _mode = Mode.ChunkSizeLine;
|
private Mode _mode = Mode.ChunkSizeLine;
|
||||||
|
|
||||||
private enum Mode
|
|
||||||
{
|
|
||||||
ChunkSizeLine,
|
|
||||||
ChunkData,
|
|
||||||
ChunkDataCRLF,
|
|
||||||
Complete,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
public ForChunkedEncoding(bool keepAlive, FrameContext context)
|
public ForChunkedEncoding(bool keepAlive, FrameContext context)
|
||||||
: base(context)
|
: base(context)
|
||||||
{
|
{
|
||||||
|
|
@ -305,6 +296,14 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private enum Mode
|
||||||
|
{
|
||||||
|
ChunkSizeLine,
|
||||||
|
ChunkData,
|
||||||
|
ChunkDataCRLF,
|
||||||
|
Complete,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,14 +12,14 @@ namespace Microsoft.StandardsPolice
|
||||||
public int Main(string[] args)
|
public int Main(string[] args)
|
||||||
{
|
{
|
||||||
var tree = CSharpSyntaxTree.ParseText(@"
|
var tree = CSharpSyntaxTree.ParseText(@"
|
||||||
public class Hello { protected int _foo; int _bar; }
|
public class Hello { public Hello(int foo){}; protected int _foo; int _bar; }
|
||||||
public class World { protected int _foo; int _bar; }
|
public class World { public World(int foo){}; protected int _foo; int _bar; static int _quux = 4; enum Blah{} class Clazz{} }
|
||||||
");
|
");
|
||||||
var diags = new List<Diagnostic>();
|
var diags = new List<Diagnostic>();
|
||||||
|
|
||||||
var comp = CSharpCompilation.Create("Comp", new[] { tree });
|
var comp = CSharpCompilation.Create("Comp", new[] { tree });
|
||||||
|
|
||||||
StandardsPoliceCompileModule.ScanSyntaxTree(diags, tree);
|
StandardsPoliceCompileModule.ScanCompilation(diags, comp);
|
||||||
|
|
||||||
var hello = comp.GetTypeByMetadataName("Hello");
|
var hello = comp.GetTypeByMetadataName("Hello");
|
||||||
foreach (var f in hello.GetMembers().OfType<IFieldSymbol>())
|
foreach (var f in hello.GetMembers().OfType<IFieldSymbol>())
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp;
|
||||||
|
|
||||||
namespace Microsoft.StandardsPolice
|
namespace Microsoft.StandardsPolice
|
||||||
{
|
{
|
||||||
|
|
@ -14,13 +15,18 @@ namespace Microsoft.StandardsPolice
|
||||||
{
|
{
|
||||||
public void BeforeCompile(BeforeCompileContext context)
|
public void BeforeCompile(BeforeCompileContext context)
|
||||||
{
|
{
|
||||||
ScanNamespace(context.Diagnostics, context.Compilation.GlobalNamespace);
|
ScanCompilation(context.Diagnostics, context.Compilation);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var st in context.Compilation.SyntaxTrees)
|
internal static void ScanCompilation(IList<Diagnostic> diagnostics, CSharpCompilation compilation)
|
||||||
|
{
|
||||||
|
ScanNamespace(diagnostics, compilation.GlobalNamespace);
|
||||||
|
|
||||||
|
foreach (var st in compilation.SyntaxTrees)
|
||||||
{
|
{
|
||||||
if (!st.FilePath.EndsWith(".Generated.cs"))
|
if (!st.FilePath.EndsWith(".Generated.cs"))
|
||||||
{
|
{
|
||||||
ScanSyntaxTree(context.Diagnostics, st);
|
ScanSyntaxTree(diagnostics, st);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -61,6 +67,20 @@ namespace Microsoft.StandardsPolice
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ScanType(IList<Diagnostic> diagnostics, INamedTypeSymbol typeSymbol)
|
private static void ScanType(IList<Diagnostic> diagnostics, INamedTypeSymbol typeSymbol)
|
||||||
|
{
|
||||||
|
if (typeSymbol.Locations.Any(location => location.IsInSource))
|
||||||
|
{
|
||||||
|
RuleFieldPrivateKeyword(diagnostics, typeSymbol);
|
||||||
|
RuleNestedTypesAreLast(diagnostics, typeSymbol);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var member in typeSymbol.GetTypeMembers())
|
||||||
|
{
|
||||||
|
ScanType(diagnostics, member);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RuleFieldPrivateKeyword(IList<Diagnostic> diagnostics, INamedTypeSymbol typeSymbol)
|
||||||
{
|
{
|
||||||
foreach (var member in typeSymbol.GetMembers().OfType<IFieldSymbol>())
|
foreach (var member in typeSymbol.GetMembers().OfType<IFieldSymbol>())
|
||||||
{
|
{
|
||||||
|
|
@ -97,11 +117,39 @@ namespace Microsoft.StandardsPolice
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (var member in typeSymbol.GetTypeMembers())
|
}
|
||||||
|
|
||||||
|
private static void RuleNestedTypesAreLast(IList<Diagnostic> diagnostics, INamedTypeSymbol typeSymbol)
|
||||||
|
{
|
||||||
|
var otherThingsWereLower = false;
|
||||||
|
var members = typeSymbol.GetMembers().Reverse().ToArray();
|
||||||
|
foreach (var member in members)
|
||||||
{
|
{
|
||||||
ScanType(diagnostics, member);
|
var namedType = member as INamedTypeSymbol;
|
||||||
|
if (namedType == null || (namedType.TypeKind != TypeKind.Class && namedType.TypeKind != TypeKind.Enum && namedType.TypeKind != TypeKind.Struct))
|
||||||
|
{
|
||||||
|
if (member.IsImplicitlyDeclared == false)
|
||||||
|
{
|
||||||
|
otherThingsWereLower = true;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (otherThingsWereLower)
|
||||||
|
{
|
||||||
|
if (member.Locations.Count() == 1)
|
||||||
|
{
|
||||||
|
diagnostics.Add(Diagnostic.Create(
|
||||||
|
"SP1003", "StandardsPolice", $"nested types must be last {typeSymbol.Name}:{member.Name}",
|
||||||
|
DiagnosticSeverity.Warning,
|
||||||
|
DiagnosticSeverity.Warning,
|
||||||
|
false,
|
||||||
|
3,
|
||||||
|
location: member.Locations.Single()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AfterCompile(AfterCompileContext context)
|
public void AfterCompile(AfterCompileContext context)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue