C#: Add .editorconfig file (#4129)

This commit is contained in:
Tamás Vajk
2020-08-26 12:41:00 +02:00
committed by GitHub
parent 28d3343e2b
commit 9ef827641f
23 changed files with 265 additions and 42 deletions

213
csharp/.editorconfig Normal file
View File

@@ -0,0 +1,213 @@
# Taken as is from https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference?view=vs-2019
# Customizations are added at the bottom of the file.
# Remove the line below if you want to inherit .editorconfig settings from higher directories
root = true
# C# files
[*.cs]
#### Core EditorConfig Options ####
# Indentation and spacing
indent_size = 4
indent_style = space
tab_width = 4
# New line preferences
end_of_line = crlf
insert_final_newline = false
#### .NET Coding Conventions ####
# Organize usings
dotnet_separate_import_directive_groups = false
dotnet_sort_system_directives_first = false
# this. and Me. preferences
dotnet_style_qualification_for_event = false:silent
dotnet_style_qualification_for_field = false:silent
dotnet_style_qualification_for_method = false:silent
dotnet_style_qualification_for_property = false:silent
# Language keywords vs BCL types preferences
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
dotnet_style_predefined_type_for_member_access = true:silent
# Parentheses preferences
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
# Modifier preferences
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
# Expression-level preferences
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_object_initializer = true:suggestion
dotnet_style_prefer_auto_properties = true:silent
dotnet_style_prefer_compound_assignment = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_simplified_interpolation = true:suggestion
# Field preferences
dotnet_style_readonly_field = true:suggestion
# Parameter preferences
dotnet_code_quality_unused_parameters = all:suggestion
#### C# Coding Conventions ####
# var preferences
csharp_style_var_elsewhere = false:silent
csharp_style_var_for_built_in_types = false:silent
csharp_style_var_when_type_is_apparent = false:silent
# Expression-bodied members
csharp_style_expression_bodied_accessors = true:silent
csharp_style_expression_bodied_constructors = false:silent
csharp_style_expression_bodied_indexers = true:silent
csharp_style_expression_bodied_lambdas = true:silent
csharp_style_expression_bodied_local_functions = false:silent
csharp_style_expression_bodied_methods = false:silent
csharp_style_expression_bodied_operators = false:silent
csharp_style_expression_bodied_properties = true:silent
# Pattern matching preferences
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_prefer_switch_expression = true:suggestion
# Null-checking preferences
csharp_style_conditional_delegate_call = true:suggestion
# Modifier preferences
csharp_prefer_static_local_function = true:suggestion
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent
# Code-block preferences
csharp_prefer_braces = true:silent
csharp_prefer_simple_using_statement = true:suggestion
# Expression-level preferences
csharp_prefer_simple_default_expression = true:suggestion
csharp_style_deconstructed_variable_declaration = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
csharp_style_pattern_local_over_anonymous_function = true:suggestion
csharp_style_prefer_index_operator = true:suggestion
csharp_style_prefer_range_operator = true:suggestion
csharp_style_throw_expression = true:suggestion
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
# 'using' directive preferences
csharp_using_directive_placement = outside_namespace:silent
#### C# Formatting Rules ####
# New line preferences
csharp_new_line_before_catch = true
csharp_new_line_before_else = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = all
csharp_new_line_between_query_expression_clauses = true
# Indentation preferences
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_labels = one_less_than_current
csharp_indent_switch_labels = true
# Space preferences
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false
# Wrapping preferences
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true
#### Naming styles ####
# Naming rules
dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
# Symbol specifications
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interface.required_modifiers =
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.required_modifiers =
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers =
# Naming styles
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case
#
# Customizations
#
# IDE0055: Fix formatting
dotnet_diagnostic.IDE0055.severity = warning
[extractor/Semmle.Extraction/Tuples.cs,
extractor/Semmle.Extraction.CSharp/Tuples.cs,
extractor/Semmle.Extraction.CIL/Tuples.cs]
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = none

View File

@@ -3,5 +3,11 @@
"dotnet-test-explorer.testProjectPath": "**/*Tests.@(csproj|vbproj|fsproj)",
"dotnet-test-explorer.testArguments": "/property:GenerateTargetFrameworkAttribute=false",
"csharp.supressBuildAssetsNotification": true,
"csharp.suppressDotnetRestoreNotification": true
"csharp.suppressDotnetRestoreNotification": true,
"[csharp]": {
"editor.defaultFormatter": "ms-dotnettools.csharp"
},
"omnisharp.enableMsBuildLoadProjectsOnDemand": true,
"omnisharp.enableEditorConfigSupport": true,
"omnisharp.enableRoslynAnalyzers": true,
}

View File

@@ -501,7 +501,7 @@ namespace Semmle.Extraction.CIL.Entities
unboundMethod.WriteId(trapFile);
trapFile.Write('<');
int index = 0;
foreach(var param in typeParams)
foreach (var param in typeParams)
{
trapFile.WriteSeparator(",", ref index);
trapFile.WriteSubId(param);

View File

@@ -38,7 +38,7 @@ namespace Semmle.Extraction.CIL.Entities
trapFile.Write('.');
trapFile.Write(cx.GetString(pd.Name));
trapFile.Write("(");
int index=0;
int index = 0;
var signature = pd.DecodeSignature(new SignatureDecoder(), gc);
foreach (var param in signature.ParameterTypes)
{

View File

@@ -771,7 +771,7 @@ namespace Semmle.Extraction.CIL.Entities
public override bool Equals(object obj)
{
if(obj is ConstructedType t && Equals(unboundGenericType, t.unboundGenericType) && Equals(containingType, t.containingType))
if (obj is ConstructedType t && Equals(unboundGenericType, t.unboundGenericType) && Equals(containingType, t.containingType))
{
if (thisTypeArguments is null) return t.thisTypeArguments is null;
if (!(t.thisTypeArguments is null)) return thisTypeArguments.SequenceEqual(t.thisTypeArguments);
@@ -1208,7 +1208,7 @@ namespace Semmle.Extraction.CIL.Entities
{
elementType.WriteId(trapFile, gc);
trapFile.Write('[');
for (int i=1; i<shape.Rank; ++i)
for (int i = 1; i < shape.Rank; ++i)
trapFile.Write(',');
trapFile.Write(']');
}
@@ -1254,7 +1254,7 @@ namespace Semmle.Extraction.CIL.Entities
genericType.WriteId(trapFile, gc);
trapFile.Write('<');
int index = 0;
foreach(var arg in typeArguments)
foreach (var arg in typeArguments)
{
trapFile.WriteSeparator(",", ref index);
arg.WriteId(trapFile, gc);
@@ -1451,8 +1451,7 @@ namespace Semmle.Extraction.CIL.Entities
genericContext.GetGenericTypeParameter(index);
Type ISignatureTypeProvider<Type, GenericContext>.GetModifiedType(Type modifier, Type unmodifiedType, bool isRequired) =>
// !! Not implemented properly
unmodifiedType;
unmodifiedType; // !! Not implemented properly
Type ISignatureTypeProvider<Type, GenericContext>.GetPinnedType(Type elementType) =>
cx.Populate(new PointerType(cx, elementType));

View File

@@ -26,28 +26,28 @@ namespace Semmle.Extraction.CSharp.Entities
// Arguments
int index = 0;
foreach(var arg in args)
foreach (var arg in args)
{
trapFile.compilation_args(this, index++, arg);
}
// Files
index = 0;
foreach(var file in cx.Compilation.SyntaxTrees.Select(tree => Extraction.Entities.File.Create(cx, tree.FilePath)))
foreach (var file in cx.Compilation.SyntaxTrees.Select(tree => Extraction.Entities.File.Create(cx, tree.FilePath)))
{
trapFile.compilation_compiling_files(this, index++, file);
}
// References
index = 0;
foreach(var file in cx.Compilation.References.OfType<PortableExecutableReference>().Select(r => Extraction.Entities.File.Create(cx, r.FilePath)))
foreach (var file in cx.Compilation.References.OfType<PortableExecutableReference>().Select(r => Extraction.Entities.File.Create(cx, r.FilePath)))
{
trapFile.compilation_referencing_files(this, index++, file);
}
// Diagnostics
index = 0;
foreach(var diag in cx.Compilation.GetDiagnostics().Select(d => new Diagnostic(cx, d)))
foreach (var diag in cx.Compilation.GetDiagnostics().Select(d => new Diagnostic(cx, d)))
{
trapFile.diagnostic_for(diag, this, 0, index++);
}
@@ -57,7 +57,7 @@ namespace Semmle.Extraction.CSharp.Entities
{
var trapFile = cx.TrapWriter.Writer;
int index = 0;
foreach(float metric in p.Metrics)
foreach (float metric in p.Metrics)
{
trapFile.compilation_time(this, -1, index++, metric);
}

View File

@@ -53,7 +53,7 @@ namespace Semmle.Extraction.CSharp.Entities
trapFile.type_nullability(this, n);
}
if(Info.FlowState != NullableFlowState.None)
if (Info.FlowState != NullableFlowState.None)
{
trapFile.expr_flowstate(this, (int)Info.FlowState);
}
@@ -292,7 +292,7 @@ namespace Semmle.Extraction.CSharp.Entities
protected Expression(ExpressionNodeInfo info)
: base(info)
{
Syntax = (SyntaxNode)info.Node;
Syntax = (SyntaxNode)info.Node;
}
/// <summary>
@@ -307,7 +307,7 @@ namespace Semmle.Extraction.CSharp.Entities
protected new Expression TryPopulate()
{
cx.Try(Syntax, null, ()=>PopulateExpression(cx.TrapWriter.Writer));
cx.Try(Syntax, null, () => PopulateExpression(cx.TrapWriter.Writer));
return this;
}
}

View File

@@ -22,7 +22,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
}
public ImplicitCast(ExpressionNodeInfo info, IMethodSymbol method)
: base(new ExpressionInfo(info.Context, Entities.Type.Create(info.Context, info.ConvertedType), info.Location, ExprKind.OPERATOR_INVOCATION, info.Parent, info.Child, true, info.ExprValue) )
: base(new ExpressionInfo(info.Context, Entities.Type.Create(info.Context, info.ConvertedType), info.Location, ExprKind.OPERATOR_INVOCATION, info.Parent, info.Child, true, info.ExprValue))
{
Expr = Factory.Create(info.SetParent(this, 0));

View File

@@ -50,7 +50,8 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
public static Lambda Create(ExpressionNodeInfo info, SimpleLambdaExpressionSyntax node) => new Lambda(info, node);
Lambda(ExpressionNodeInfo info, AnonymousMethodExpressionSyntax node) :
this(info.SetKind(ExprKind.ANONYMOUS_METHOD), node.Body, node.ParameterList == null ? Enumerable.Empty<ParameterSyntax>() : node.ParameterList.Parameters) { }
this(info.SetKind(ExprKind.ANONYMOUS_METHOD), node.Body, node.ParameterList == null ? Enumerable.Empty<ParameterSyntax>() : node.ParameterList.Parameters)
{ }
public static Lambda Create(ExpressionNodeInfo info, AnonymousMethodExpressionSyntax node) => new Lambda(info, node);
}

View File

@@ -9,7 +9,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
{
class Literal : Expression<LiteralExpressionSyntax>
{
Literal(ExpressionNodeInfo info) : base(info.SetKind(GetKind(info)) ) { }
Literal(ExpressionNodeInfo info) : base(info.SetKind(GetKind(info))) { }
public static Expression Create(ExpressionNodeInfo info) => new Literal(info).TryPopulate();
@@ -17,7 +17,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
static ExprKind GetKind(ExpressionNodeInfo info)
{
switch(info.Node.Kind())
switch (info.Node.Kind())
{
case SyntaxKind.DefaultLiteralExpression:
return ExprKind.DEFAULT;

View File

@@ -27,10 +27,12 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
}
}
public static Expression Create(ExpressionNodeInfo info, ConditionalAccessExpressionSyntax node) =>
public static Expression Create(ExpressionNodeInfo info, ConditionalAccessExpressionSyntax node)
{
// The qualifier is located by walking the syntax tree.
// `node.WhenNotNull` will contain a MemberBindingExpressionSyntax, calling the method below.
CreateFromNode(new ExpressionNodeInfo(info.Context, node.WhenNotNull, info.Parent, info.Child, info.TypeInfo));
return CreateFromNode(new ExpressionNodeInfo(info.Context, node.WhenNotNull, info.Parent, info.Child, info.TypeInfo));
}
public static Expression Create(ExpressionNodeInfo info, MemberBindingExpressionSyntax node)
{

View File

@@ -23,7 +23,7 @@ namespace Semmle.Extraction.CSharp.Entities
protected override void Populate(TextWriter trapFile)
{
var @namespace = (INamespaceSymbol) cx.GetModel(Node).GetSymbolInfo(Node.Name).Symbol;
var @namespace = (INamespaceSymbol)cx.GetModel(Node).GetSymbolInfo(Node.Name).Symbol;
var ns = Namespace.Create(cx, @namespace);
trapFile.namespace_declarations(this, ns);
trapFile.namespace_declaration_location(this, cx.Create(Node.Name.GetLocation()));

View File

@@ -64,7 +64,7 @@ namespace Semmle.Extraction.CSharp.Entities
Emit(trapFile, Loc ?? Syntax.GetLocation(), Parent, Type);
Create(cx, nts.ElementType, this, nt.symbol.IsReferenceType ? nt : nt.TypeArguments[0]);
}
else if(Type is ArrayType array)
else if (Type is ArrayType array)
{
Create(cx, nts.ElementType, Parent, array);
}

View File

@@ -35,14 +35,14 @@ namespace Semmle.Extraction.CSharp.Entities
if (symbol.HasConstructorConstraint)
trapFile.general_type_parameter_constraints(constraints, 3);
if(symbol.HasUnmanagedTypeConstraint)
if (symbol.HasUnmanagedTypeConstraint)
trapFile.general_type_parameter_constraints(constraints, 4);
ITypeSymbol baseType = symbol.HasValueTypeConstraint ?
Context.Compilation.GetTypeByMetadataName(valueTypeName) :
Context.Compilation.ObjectType;
if(symbol.ReferenceTypeConstraintNullableAnnotation == NullableAnnotation.Annotated)
if (symbol.ReferenceTypeConstraintNullableAnnotation == NullableAnnotation.Annotated)
trapFile.general_type_parameter_constraints(constraints, 5);
foreach (var abase in symbol.GetAnnotatedTypeConstraints())

View File

@@ -140,6 +140,12 @@ namespace Semmle.Extraction.CSharp
return ExitCode.Failed;
}
// csc.exe (CSharpCompiler.cs) also provides CompilationOptions
// .WithMetadataReferenceResolver(),
// .WithXmlReferenceResolver() and
// .WithSourceReferenceResolver().
// These would be needed if we hadn't explicitly provided the source/references
// already.
var compilation = CSharpCompilation.Create(
compilerArguments.CompilationName,
syntaxTrees,
@@ -147,11 +153,6 @@ namespace Semmle.Extraction.CSharp
compilerArguments.CompilationOptions.
WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default).
WithStrongNameProvider(new DesktopStrongNameProvider(compilerArguments.KeyFileSearchPaths))
// csc.exe (CSharpCompiler.cs) also provides WithMetadataReferenceResolver,
// WithXmlReferenceResolver and
// WithSourceReferenceResolver.
// These would be needed if we hadn't explicitly provided the source/references
// already.
);
analyser.EndInitialize(compilerArguments, commandLineArguments, compilation);

View File

@@ -49,7 +49,7 @@ namespace Semmle.Extraction
/// <param name="factory">The entity factory.</param>
/// <param name="init">The initializer for the entity.</param>
/// <returns>The new/existing entity.</returns>
public Entity CreateEntity<Type, Entity>(ICachedEntityFactory<Type, Entity> factory, Type init) where Entity : ICachedEntity where Type:struct
public Entity CreateEntity<Type, Entity>(ICachedEntityFactory<Type, Entity> factory, Type init) where Entity : ICachedEntity where Type : struct
{
return CreateNonNullEntity(factory, init);
}
@@ -73,7 +73,7 @@ namespace Semmle.Extraction
/// <returns>The new/existing entity.</returns>
public Entity CreateEntityFromSymbol<Type, Entity>(ICachedEntityFactory<Type, Entity> factory, Type init)
where Entity : ICachedEntity
where Type: ISymbol
where Type : ISymbol
{
return init == null ? CreateEntity2(factory, init) : CreateNonNullEntity(factory, init);
}
@@ -500,7 +500,7 @@ namespace Semmle.Extraction
{
ExtractionError(message, optionalSymbol.ToDisplayString(), Entities.Location.Create(this, optionalSymbol.Locations.FirstOrDefault()));
}
else if(!(optionalEntity is null))
else if (!(optionalEntity is null))
{
ExtractionError(message, optionalEntity.Label.ToString(), Entities.Location.Create(this, optionalEntity.ReportingLocation));
}

View File

@@ -14,7 +14,7 @@ namespace Semmle.Extraction.Entities
protected override void Populate(TextWriter trapFile)
{
trapFile.extractor_messages(this, msg.Severity, "C# extractor", msg.Text, msg.EntityText, msg.Location ?? GeneratedLocation.Create(cx), msg.StackTrace);
trapFile.extractor_messages(this, msg.Severity, "C# extractor", msg.Text, msg.EntityText, msg.Location ?? GeneratedLocation.Create(cx), msg.StackTrace);
}
public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel;

View File

@@ -4,7 +4,8 @@ using Microsoft.CodeAnalysis;
namespace Semmle.Extraction.Entities
{
public abstract class SourceLocation : Location {
public abstract class SourceLocation : Location
{
protected SourceLocation(Context cx, Microsoft.CodeAnalysis.Location? init) : base(cx, init)
{
}

View File

@@ -153,7 +153,7 @@ namespace Semmle.Extraction
{
entity.WriteQuotedId(trapFile);
}
catch(Exception ex) // lgtm[cs/catch-of-all-exceptions]
catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
{
trapFile.WriteLine("\"");
extractor.Message(new Message("Unhandled exception generating id", entity.ToString() ?? "", null, ex.StackTrace));

View File

@@ -61,7 +61,7 @@ namespace Semmle.Extraction
/// </summary>
/// <param name="srcFile">The source file.</param>
/// <returns>A newly created TrapWriter.</returns>
public TrapWriter CreateTrapWriter(ILogger logger, string srcFile, bool discardDuplicates, TrapWriter.CompressionMode trapCompression) =>
public TrapWriter CreateTrapWriter(ILogger logger, string srcFile, bool discardDuplicates, TrapWriter.CompressionMode trapCompression) =>
new TrapWriter(logger, srcFile, TRAP_FOLDER, SOURCE_ARCHIVE, discardDuplicates, trapCompression);
}

View File

@@ -9,7 +9,7 @@ namespace Semmle.Util
/// dictionary. If a list does not already exist, a new list is
/// created.
/// </summary>
public static void AddAnother<T1, T2>(this Dictionary<T1, List<T2>> dict, T1 key, T2 element) where T1:notnull
public static void AddAnother<T1, T2>(this Dictionary<T1, List<T2>> dict, T1 key, T2 element) where T1 : notnull
{
if (!dict.TryGetValue(key, out var list))
{

View File

@@ -37,7 +37,7 @@ namespace Semmle.Util
/// </remarks>
///
/// <typeparam name="T">The value type.</typeparam>
public class FuzzyDictionary<T> where T:class
public class FuzzyDictionary<T> where T : class
{
// All data items indexed by the "base string" (stripped of numbers)
readonly Dictionary<string, List<KeyValuePair<string, T>>> index = new Dictionary<string, List<KeyValuePair<string, T>>>();
@@ -61,7 +61,7 @@ namespace Semmle.Util
/// <param name="v1">Vector 1</param>
/// <param name="v2">Vector 2</param>
/// <returns>The Hamming Distance.</returns>
static int HammingDistance<U>(IEnumerable<U> v1, IEnumerable<U> v2) where U: notnull
static int HammingDistance<U>(IEnumerable<U> v1, IEnumerable<U> v2) where U : notnull
{
return v1.Zip(v2, (x, y) => x.Equals(y) ? 0 : 1).Sum();
}

View File

@@ -93,7 +93,7 @@ namespace Semmle.Util
/// <typeparam name="T">The type of the item.</typeparam>
/// <param name="items">The list of items to hash.</param>
/// <returns>The hash code.</returns>
public static int SequenceHash<T>(this IEnumerable<T> items) where T: notnull
public static int SequenceHash<T>(this IEnumerable<T> items) where T : notnull
{
int h = 0;
foreach (var i in items)