diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 6ed6ab63..8e71c656 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -19,6 +19,12 @@ "commands": [ "fsdocs" ] + }, + "dotnet-fsharplint": { + "version": "0.21.3", + "commands": [ + "dotnet-fsharplint" + ] } } } \ No newline at end of file diff --git a/fsharplint.json b/fsharplint.json new file mode 100644 index 00000000..f8d5494c --- /dev/null +++ b/fsharplint.json @@ -0,0 +1,436 @@ +{ + "ignoreFiles": [ + "assemblyinfo.*" + ], + "global": { + "numIndentationSpaces": 4 + }, + "typedItemSpacing": { + "enabled": false, + "config": { + "typedItemStyle": "NoSpaces" + } + }, + "typePrefixing": { "enabled": false }, + "unionDefinitionIndentation": { "enabled": false }, + "moduleDeclSpacing": { "enabled": false }, + "classMemberSpacing": { "enabled": false }, + "tupleCommaSpacing": { "enabled": false }, + "tupleIndentation": { "enabled": false }, + "tupleParentheses": { "enabled": false }, + "patternMatchClausesOnNewLine": { "enabled": false }, + "patternMatchOrClausesOnNewLine": { "enabled": false }, + "patternMatchClauseIndentation": { "enabled": false }, + "patternMatchExpressionIndentation": { "enabled": false }, + "recursiveAsyncFunction": { "enabled": false }, + "redundantNewKeyword": { "enabled": false }, + "nestedStatements": { + "enabled": false, + "config": { + "depth": 8 + } + }, + "cyclomaticComplexity": { + "enabled": false, + "config": { + "maxComplexity": 40 + } + }, + "reimplementsFunction": { "enabled": true }, + "canBeReplacedWithComposition": { "enabled": true }, + "failwithWithSingleArgument": { "enabled": true }, + "raiseWithSingleArgument": { "enabled": true }, + "nullArgWithSingleArgument": { "enabled": true }, + "invalidOpWithSingleArgument": { "enabled": true }, + "invalidArgWithTwoArguments": { "enabled": true }, + "failwithfWithArgumentsMatchingFormatString": { "enabled": true }, + "failwithBadUsage": { "enabled": true }, + "maxLinesInLambdaFunction": { + "enabled": false, + "config": { + "maxLines": 7 + } + }, + "maxLinesInMatchLambdaFunction": { + "enabled": false, + "config": { + "maxLines": 100 + } + }, + "maxLinesInValue": { + "enabled": false, + "config": { + "maxLines": 100 + } + }, + "maxLinesInFunction": { + "enabled": false, + "config": { + "maxLines": 100 + } + }, + "maxLinesInMember": { + "enabled": false, + "config": { + "maxLines": 100 + } + }, + "maxLinesInConstructor": { + "enabled": false, + "config": { + "maxLines": 100 + } + }, + "maxLinesInProperty": { + "enabled": false, + "config": { + "maxLines": 70 + } + }, + "maxLinesInModule": { + "enabled": false, + "config": { + "maxLines": 1000 + } + }, + "maxLinesInRecord": { + "enabled": false, + "config": { + "maxLines": 500 + } + }, + "maxLinesInEnum": { + "enabled": false, + "config": { + "maxLines": 500 + } + }, + "maxLinesInUnion": { + "enabled": false, + "config": { + "maxLines": 500 + } + }, + "maxLinesInClass": { + "enabled": false, + "config": { + "maxLines": 500 + } + }, + "interfaceNames": { + "enabled": false, + "config": { + "naming": "PascalCase", + "underscores": "None", + "prefix": "I" + } + }, + "exceptionNames": { + "enabled": false, + "config": { + "naming": "PascalCase", + "underscores": "None", + "suffix": "Exception" + } + }, + "typeNames": { + "enabled": false, + "config": { + "naming": "PascalCase", + "underscores": "None" + } + }, + "recordFieldNames": { + "enabled": false, + "config": { + "naming": "PascalCase", + "underscores": "None" + } + }, + "enumCasesNames": { + "enabled": true, + "config": { + "naming": "PascalCase", + "underscores": "None" + } + }, + "unionCasesNames": { + "enabled": false, + "config": { + "naming": "PascalCase", + "underscores": "None" + } + }, + "moduleNames": { + "enabled": false, + "config": { + "naming": "PascalCase", + "underscores": "None" + } + }, + "literalNames": { + "enabled": false, + "config": { + "naming": "PascalCase", + "underscores": "None" + } + }, + "namespaceNames": { + "enabled": false, + "config": { + "naming": "PascalCase", + "underscores": "None" + } + }, + "memberNames": { + "enabled": false, + "config": { + "naming": "PascalCase", + "underscores": "AllowPrefix" + } + }, + "parameterNames": { + "enabled": false, + "config": { + "naming": "CamelCase", + "underscores": "AllowPrefix" + } + }, + "measureTypeNames": { + "enabled": false, + "config": { + "underscores": "None" + } + }, + "activePatternNames": { + "enabled": false, + "config": { + "naming": "PascalCase", + "underscores": "None" + } + }, + "genericTypesNames": { + "enabled": false, + "config": { + "naming": "PascalCase", + "underscores": "None" + } + }, + "publicValuesNames": { + "enabled": false, + "config": { + "underscores": "AllowPrefix" + } + }, + "privateValuesNames": { + "enabled": false, + "config": { + "naming": "CamelCase", + "underscores": "AllowPrefix" + } + }, + "internalValuesNames": { + "enabled": false, + "config": { + "naming": "CamelCase", + "underscores": "AllowPrefix" + } + }, + "maxNumberOfItemsInTuple": { + "enabled": false, + "config": { + "maxItems": 4 + } + }, + "maxNumberOfFunctionParameters": { + "enabled": false, + "config": { + "maxItems": 5 + } + }, + "maxNumberOfMembers": { + "enabled": false, + "config": { + "maxItems": 32 + } + }, + "maxNumberOfBooleanOperatorsInCondition": { + "enabled": false, + "config": { + "maxItems": 4 + } + }, + "favourIgnoreOverLetWild": { "enabled": false }, + "wildcardNamedWithAsPattern": { "enabled": true }, + "uselessBinding": { "enabled": true }, + "tupleOfWildcards": { "enabled": true }, + "favourTypedIgnore": { "enabled": false }, + "favourReRaise": { "enabled": true }, + "favourStaticEmptyFields": { "enabled": false }, + "favourConsistentThis": { + "enabled": false, + "config": { + "symbol": "this" + } + }, + "avoidTooShortNames": { "enabled": false }, + "indentation": { + "enabled": false + }, + "maxCharactersOnLine": { + "enabled": false, + "config": { + "maxCharactersOnLine": 120 + } + }, + "trailingWhitespaceOnLine": { + "enabled": false, + "config": { + "numberOfSpacesAllowed": 1, + "oneSpaceAllowedAfterOperator": true, + "ignoreBlankLines": true + } + }, + "maxLinesInFile": { + "enabled": false, + "config": { + "maxLinesInFile": 1000 + } + }, + "trailingNewLineInFile": { "enabled": false }, + "noTabCharacters": { "enabled": true }, + "noPartialFunctions": { + "enabled": false, + "config": { + "allowedPartials": [], + "additionalPartials": [] + } + }, + "hints": { + "add": [ + "not (a = b) ===> a <> b", + "not (a <> b) ===> a = b", + "not (a > b) ===> a <= b", + "not (a >= b) ===> a < b", + "not (a < b) ===> a >= b", + "not (a <= b) ===> a > b", + "compare x y <> 1 ===> x <= y", + "compare x y = -1 ===> x < y", + "compare x y <> -1 ===> x >= y", + "compare x y = 1 ===> x > y", + "compare x y <= 0 ===> x <= y", + "compare x y < 0 ===> x < y", + "compare x y >= 0 ===> x >= y", + "compare x y > 0 ===> x > y", + "compare x y = 0 ===> x = y", + "compare x y <> 0 ===> x <> y", + + "List.head (List.sort x) ===> List.min x", + "List.head (List.sortBy f x) ===> List.minBy f x", + + "List.map f (List.map g x) ===> List.map (g >> f) x", + "Array.map f (Array.map g x) ===> Array.map (g >> f) x", + "Seq.map f (Seq.map g x) ===> Seq.map (g >> f) x", + "List.nth x 0 ===> List.head x", + "List.map f (List.replicate n x) ===> List.replicate n (f x)", + "List.rev (List.rev x) ===> x", + "Array.rev (Array.rev x) ===> x", + "List.fold (@) [] x ===> List.concat x", + "List.map id x ===> id x", + "Array.map id x ===> id x", + "Seq.map id x ===> id x", + "(List.length x) = 0 ===> List.isEmpty x", + "(Array.length x) = 0 ===> Array.isEmpty x", + "(Seq.length x) = 0 ===> Seq.isEmpty x", + "x = [] ===> List.isEmpty x", + "x = [||] ===> Array.isEmpty x", + "(List.length x) <> 0 ===> not (List.isEmpty x)", + "(Array.length x) <> 0 ===> not (Array.isEmpty x)", + "(Seq.length x) <> 0 ===> not (Seq.isEmpty x)", + "(List.length x) > 0 ===> not (List.isEmpty x)", + "(Array.length x) <> 0 ===> not (Array.isEmpty x)", + "(Seq.length x) <> 0 ===> not (Seq.isEmpty x)", + + "List.concat (List.map f x) ===> List.collect f x", + "Array.concat (Array.map f x) ===> Array.collect f x", + "Seq.concat (Seq.map f x) ===> Seq.collect f x", + + "List.isEmpty (List.filter f x) ===> not (List.exists f x)", + "Array.isEmpty (Array.filter f x) ===> not (Array.exists f x)", + "Seq.isEmpty (Seq.filter f x) ===> not (Seq.exists f x)", + "not (List.isEmpty (List.filter f x)) ===> List.exists f x", + "not (Array.isEmpty (Array.filter f x)) ===> Array.exists f x", + "not (Seq.isEmpty (Seq.filter f x)) ===> Seq.exists f x", + + "List.length x >= 0 ===> true", + "Array.length x >= 0 ===> true", + "Seq.length x >= 0 ===> true", + + "x = true ===> x", + "x = false ===> not x", + "true = a ===> a", + "false = a ===> not a", + "a <> true ===> not a", + "a <> false ===> a", + "true <> a ===> not a", + "false <> a ===> a", + "if a then true else false ===> a", + "if a then false else true ===> not a", + "not (not x) ===> x", + + "(fst x, snd x) ===> x", + + "true && x ===> x", + "false && x ===> false", + "true || x ===> true", + "false || x ===> x", + "not true ===> false", + "not false ===> true", + "fst (x, y) ===> x", + "snd (x, y) ===> y", + "List.fold f x [] ===> x", + "Array.fold f x [||] ===> x", + "List.foldBack f [] x ===> x", + "Array.foldBack f [||] x ===> x", + "x - 0 ===> x", + "x * 1 ===> x", + "x / 1 ===> x", + + "List.fold (+) 0 x ===> List.sum x", + "Array.fold (+) 0 x ===> Array.sum x", + "Seq.fold (+) 0 x ===> Seq.sum x", + "List.sum (List.map x y) ===> List.sumBy x y", + "Array.sum (Array.map x y) ===> Array.sumBy x y", + "Seq.sum (Seq.map x y) ===> Seq.sumBy x y", + "List.average (List.map x y) ===> List.averageBy x y", + "Array.average (Array.map x y) ===> Array.averageBy x y", + "Seq.average (Seq.map x y) ===> Seq.averageBy x y", + "(List.take x y, List.skip x y) ===> List.splitAt x y", + "(Array.take x y, Array.skip x y) ===> Array.splitAt x y", + "(Seq.take x y, Seq.skip x y) ===> Seq.splitAt x y", + + "List.empty ===> []", + "Array.empty ===> [||]", + + "x::[] ===> [x]", + "pattern: x::[] ===> [x]", + + "x @ [] ===> x", + + "List.isEmpty [] ===> true", + "Array.isEmpty [||] ===> true", + + "fun x -> x ===> id", + "id x ===> x", + "id >> f ===> f", + "f >> id ===> f", + + "x = null ===> isNull x", + "null = x ===> isNull x", + "x <> null ===> not (isNull x)", + "null <> x ===> not (isNull x)", + + "Array.append a (Array.append b c) ===> Array.concat [|a; b; c|]" + ] + } +} diff --git a/src/ProvidedTypes.fs b/src/ProvidedTypes.fs index ab342553..bec08052 100644 --- a/src/ProvidedTypes.fs +++ b/src/ProvidedTypes.fs @@ -613,7 +613,7 @@ type ProvidedTypeSymbol(kind: ProvidedTypeSymbolKind, typeArgs: Type list, typeB | ProvidedTypeSymbolKind.ByRef, [| arg |] -> arg.Name + "&" | ProvidedTypeSymbolKind.Generic gty, _typeArgs -> gty.Name | ProvidedTypeSymbolKind.FSharpTypeAbbreviation (_, _, path), _ -> path.[path.Length-1] - | _ -> failwith "unreachable" + | c -> failwithf "unreachable %O" c override __.BaseType = match kind with @@ -669,7 +669,7 @@ type ProvidedTypeSymbol(kind: ProvidedTypeSymbolKind, typeArgs: Type list, typeB | ProvidedTypeSymbolKind.ByRef, [| arg |] -> 43904 + hash arg | ProvidedTypeSymbolKind.Generic gty, _ -> 9797 + hash gty + Array.sumBy hash typeArgs | ProvidedTypeSymbolKind.FSharpTypeAbbreviation _, _ -> 3092 - | _ -> failwith "unreachable" + | c -> failwithf "unreachable %O" c override this.Equals(other: obj) = eqTypeObj this other @@ -1449,7 +1449,7 @@ and ProvidedTypeDefinition(isTgt: bool, container:TypeContainer, className: stri let save (key: BindingFlags) f : 'T = let key = int key - if bindings = null then + if isNull bindings then bindings <- Dictionary<_, _>(HashIdentity.Structural) if not (moreMembers()) && bindings.ContainsKey(key) then @@ -1558,13 +1558,13 @@ and ProvidedTypeDefinition(isTgt: bool, container:TypeContainer, className: stri (//save ("methods", bindingFlags, None) (fun () -> getMembers() |> Array.choose (function :? MethodInfo as m when memberBinds false bindingFlags m.IsStatic m.IsPublic -> Some m | _ -> None) - |> (if hasFlag bindingFlags BindingFlags.DeclaredOnly || this.BaseType = null then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetMethods(bindingFlags))))) + |> (if hasFlag bindingFlags BindingFlags.DeclaredOnly || isNull this.BaseType then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetMethods(bindingFlags))))) override this.GetFields bindingFlags = (//save ("fields", bindingFlags, None) (fun () -> getMembers() |> Array.choose (function :? FieldInfo as m when memberBinds false bindingFlags m.IsStatic m.IsPublic -> Some m | _ -> None) - |> (if hasFlag bindingFlags BindingFlags.DeclaredOnly || this.BaseType = null then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetFields(bindingFlags))))) + |> (if hasFlag bindingFlags BindingFlags.DeclaredOnly || isNull this.BaseType then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetFields(bindingFlags))))) override this.GetProperties bindingFlags = (//save ("props", bindingFlags, None) (fun () -> @@ -1572,7 +1572,7 @@ and ProvidedTypeDefinition(isTgt: bool, container:TypeContainer, className: stri getMembers() |> Array.choose (function :? PropertyInfo as m when memberBinds false bindingFlags m.IsStatic m.IsPublic -> Some m | _ -> None) staticOrPublic - |> (if hasFlag bindingFlags BindingFlags.DeclaredOnly || this.BaseType = null + |> (if hasFlag bindingFlags BindingFlags.DeclaredOnly || isNull this.BaseType then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetProperties(bindingFlags))))) @@ -1580,13 +1580,13 @@ and ProvidedTypeDefinition(isTgt: bool, container:TypeContainer, className: stri (//save ("events", bindingFlags, None) (fun () -> getMembers() |> Array.choose (function :? EventInfo as m when memberBinds false bindingFlags m.IsStatic m.IsPublic -> Some m | _ -> None) - |> (if hasFlag bindingFlags BindingFlags.DeclaredOnly || this.BaseType = null then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetEvents(bindingFlags))))) + |> (if hasFlag bindingFlags BindingFlags.DeclaredOnly || isNull this.BaseType then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetEvents(bindingFlags))))) override __.GetNestedTypes bindingFlags = (//save ("nested", bindingFlags, None) (fun () -> getMembers() |> Array.choose (function :? Type as m when memberBinds true bindingFlags false m.IsPublic || m.IsNestedPublic -> Some m | _ -> None) - |> (if hasFlag bindingFlags BindingFlags.DeclaredOnly || this.BaseType = null then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetNestedTypes(bindingFlags))))) + |> (if hasFlag bindingFlags BindingFlags.DeclaredOnly || isNull this.BaseType then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetNestedTypes(bindingFlags))))) override this.GetConstructorImpl(bindingFlags, _binder, _callConventions, _types, _modifiers) = let xs = this.GetConstructors bindingFlags |> Array.filter (fun m -> m.Name = ".ctor") @@ -1602,7 +1602,7 @@ and ProvidedTypeDefinition(isTgt: bool, container:TypeContainer, className: stri let methods = this.GetMethods bindingFlags methods |> Seq.groupBy (fun m -> m.Name) |> Seq.map (fun (k, v) -> k, Seq.toArray v) |> dict) - let xs = if table.ContainsKey name then table.[name] else [| |] + let xs = match table.TryGetValue name with | true, tn -> tn | false, _ -> [| |] //let xs = this.GetMethods bindingFlags |> Array.filter (fun m -> m.Name = name) if xs.Length > 1 then failwithf "GetMethodImpl. not support overloads, name = '%s', methods - '%A', callstack = '%A'" name xs Environment.StackTrace if xs.Length > 0 then xs.[0] else null) @@ -1618,7 +1618,7 @@ and ProvidedTypeDefinition(isTgt: bool, container:TypeContainer, className: stri save (bindingFlags ||| BindingFlags.GetProperty) (fun () -> let methods = this.GetProperties bindingFlags methods |> Seq.groupBy (fun m -> m.Name) |> Seq.map (fun (k, v) -> k, Seq.toArray v) |> dict) - let xs = if table.ContainsKey name then table.[name] else [| |] + let xs = match table.TryGetValue name with | true, tn -> tn | false, _ -> [| |] //let xs = this.GetProperties bindingFlags |> Array.filter (fun m -> m.Name = name) if xs.Length > 0 then xs.[0] else null) @@ -1805,7 +1805,7 @@ and ProvidedTypeDefinition(isTgt: bool, container:TypeContainer, className: stri match keylist with | [] -> () | key::rest -> - buckets.[key] <- (rest, v) :: (if buckets.ContainsKey key then buckets.[key] else []); + buckets.[key] <- (rest, v) :: (match buckets.TryGetValue key with |true, bucket -> bucket | false, _ -> []); [ for (KeyValue(key, items)) in buckets -> nodef key items ] @@ -2361,9 +2361,9 @@ module internal AssemblyReader = | ILType.Array (ILArrayShape(s), ty) -> ty.BasicQualifiedName + "[" + System.String(',', s.Length-1) + "]" | ILType.Value tr | ILType.Boxed tr -> tr.BasicQualifiedName | ILType.Void -> "void" - | ILType.Ptr _ty -> failwith "unexpected pointer type" - | ILType.Byref _ty -> failwith "unexpected byref type" - | ILType.FunctionPointer _mref -> failwith "unexpected function pointer type" + | ILType.Ptr _ty -> failwithf "unexpected pointer type %O" _ty + | ILType.Byref _ty -> failwithf "unexpected byref type %O" _ty + | ILType.FunctionPointer _mref -> failwithf "unexpected function pointer type %O" _mref member x.QualifiedNameExtension = match x with @@ -2372,9 +2372,9 @@ module internal AssemblyReader = | ILType.Array (ILArrayShape(_s), ty) -> ty.QualifiedNameExtension | ILType.Value tr | ILType.Boxed tr -> tr.QualifiedNameExtension | ILType.Void -> failwith "void" - | ILType.Ptr _ty -> failwith "unexpected pointer type" - | ILType.Byref _ty -> failwith "unexpected byref type" - | ILType.FunctionPointer _mref -> failwith "unexpected function pointer type" + | ILType.Ptr _ty -> failwithf "unexpected pointer type %O" _ty + | ILType.Byref _ty -> failwithf "unexpected byref type %O" _ty + | ILType.FunctionPointer _mref -> failwithf "unexpected function pointer type %O" _mref member x.QualifiedName = x.BasicQualifiedName + x.QualifiedNameExtension @@ -2382,18 +2382,18 @@ module internal AssemblyReader = member x.TypeSpec = match x with | ILType.Boxed tr | ILType.Value tr -> tr - | _ -> failwithf "not a nominal type" + | c -> failwithf "not a nominal type %O" c member x.Boxity = match x with | ILType.Boxed _ -> AsObject | ILType.Value _ -> AsValue - | _ -> failwithf "not a nominal type" + | c -> failwithf "not a nominal type %O" c member x.TypeRef = match x with | ILType.Boxed tspec | ILType.Value tspec -> tspec.TypeRef - | _ -> failwithf "not a nominal type" + | c -> failwithf "not a nominal type %O" c member x.IsNominal = match x with @@ -2844,14 +2844,13 @@ module internal AssemblyReader = let mutable lmap = null let getmap() = - if lmap = null then + if isNull lmap then lmap <- Dictionary() for y in larr.Force() do let key = y.Name - if lmap.ContainsKey key then - lmap.[key] <- Array.append [| y |] lmap.[key] - else - lmap.[key] <- [| y |] + match lmap.TryGetValue key with + | true, lmpak -> lmap.[key] <- Array.append [| y |] lmpak + | false, _ -> lmap.[key] <- [| y |] lmap member __.Entries = larr.Force() @@ -3062,7 +3061,7 @@ module internal AssemblyReader = let mutable lmap = null let getmap() = - if lmap = null then + if isNull lmap then lmap <- Dictionary() for (nsp, nm, ltd) in larr.Force() do let key = nsp, nm @@ -3075,9 +3074,10 @@ module internal AssemblyReader = member __.TryFindByName (nsp, nm) = let tdefs = getmap() let key = (nsp, nm) - if tdefs.ContainsKey key then - Some (tdefs.[key].Force()) - else + match tdefs.TryGetValue key with + | true, tdefFal -> + Some (tdefFal.Force()) + | false, _ -> None type ILNestedExportedType = @@ -3106,7 +3106,7 @@ module internal AssemblyReader = and ILExportedTypesAndForwarders(larr:Lazy) = let mutable lmap = null let getmap() = - if lmap = null then + if isNull lmap then lmap <- Dictionary() for ltd in larr.Force() do let key = ltd.Namespace, ltd.Name @@ -4568,8 +4568,9 @@ module internal AssemblyReader = | null -> cache := new Dictionary<_, _>(11 (* sz:int *) ) | _ -> () !cache - if cache.ContainsKey idx then cache.[idx] - else let res = f idx in cache.[idx] <- res; res + match cache.TryGetValue idx with + | true, cached -> cached + | false, _ -> let res = f idx in cache.[idx] <- res; res let seekFindRow numRows rowChooser = let mutable i = 1 @@ -5111,18 +5112,18 @@ module internal AssemblyReader = seekReadIdx tableBigness.[tab.Index] &addr - let seekReadResolutionScopeIdx (addr: byref) = seekReadTaggedIdx (fun idx -> ResolutionScopeTag idx) 2 rsBigness &addr - let seekReadTypeDefOrRefOrSpecIdx (addr: byref) = seekReadTaggedIdx (fun idx -> TypeDefOrRefOrSpecTag idx) 2 tdorBigness &addr - let seekReadTypeOrMethodDefIdx (addr: byref) = seekReadTaggedIdx (fun idx -> TypeOrMethodDefTag idx) 1 tomdBigness &addr - let seekReadHasConstantIdx (addr: byref) = seekReadTaggedIdx (fun idx -> HasConstantTag idx) 2 hcBigness &addr - let seekReadHasCustomAttributeIdx (addr: byref) = seekReadTaggedIdx (fun idx -> HasCustomAttributeTag idx) 5 hcaBigness &addr - //let seekReadHasFieldMarshalIdx (addr: byref) = seekReadTaggedIdx (fun idx -> HasFieldMarshalTag idx) 1 hfmBigness &addr - //let seekReadHasDeclSecurityIdx (addr: byref) = seekReadTaggedIdx (fun idx -> HasDeclSecurityTag idx) 2 hdsBigness &addr - let seekReadMemberRefParentIdx (addr: byref) = seekReadTaggedIdx (fun idx -> MemberRefParentTag idx) 3 mrpBigness &addr - let seekReadHasSemanticsIdx (addr: byref) = seekReadTaggedIdx (fun idx -> HasSemanticsTag idx) 1 hsBigness &addr - let seekReadMethodDefOrRefIdx (addr: byref) = seekReadTaggedIdx (fun idx -> MethodDefOrRefTag idx) 1 mdorBigness &addr - let seekReadImplementationIdx (addr: byref) = seekReadTaggedIdx (fun idx -> ImplementationTag idx) 2 iBigness &addr - let seekReadCustomAttributeTypeIdx (addr: byref) = seekReadTaggedIdx (fun idx -> CustomAttributeTypeTag idx) 3 catBigness &addr + let seekReadResolutionScopeIdx (addr: byref) = seekReadTaggedIdx ResolutionScopeTag 2 rsBigness &addr + let seekReadTypeDefOrRefOrSpecIdx (addr: byref) = seekReadTaggedIdx TypeDefOrRefOrSpecTag 2 tdorBigness &addr + let seekReadTypeOrMethodDefIdx (addr: byref) = seekReadTaggedIdx TypeOrMethodDefTag 1 tomdBigness &addr + let seekReadHasConstantIdx (addr: byref) = seekReadTaggedIdx HasConstantTag 2 hcBigness &addr + let seekReadHasCustomAttributeIdx (addr: byref) = seekReadTaggedIdx HasCustomAttributeTag 5 hcaBigness &addr + //let seekReadHasFieldMarshalIdx (addr: byref) = seekReadTaggedIdx HasFieldMarshalTag 1 hfmBigness &addr + //let seekReadHasDeclSecurityIdx (addr: byref) = seekReadTaggedIdx HasDeclSecurityTag 2 hdsBigness &addr + let seekReadMemberRefParentIdx (addr: byref) = seekReadTaggedIdx MemberRefParentTag 3 mrpBigness &addr + let seekReadHasSemanticsIdx (addr: byref) = seekReadTaggedIdx HasSemanticsTag 1 hsBigness &addr + let seekReadMethodDefOrRefIdx (addr: byref) = seekReadTaggedIdx MethodDefOrRefTag 1 mdorBigness &addr + let seekReadImplementationIdx (addr: byref) = seekReadTaggedIdx ImplementationTag 2 iBigness &addr + let seekReadCustomAttributeTypeIdx (addr: byref) = seekReadTaggedIdx CustomAttributeTypeTag 3 catBigness &addr let seekReadStringIdx (addr: byref) = seekReadIdx stringsBigness &addr let seekReadGuidIdx (addr: byref) = seekReadIdx guidsBigness &addr let seekReadBlobIdx (addr: byref) = seekReadIdx blobsBigness &addr @@ -5695,7 +5696,7 @@ module internal AssemblyReader = | tag when tag = ImplementationTag.File -> ILScopeRef.Module (seekReadFile idx) | tag when tag = ImplementationTag.AssemblyRef -> ILScopeRef.Assembly (seekReadAssemblyRef idx) | tag when tag = ImplementationTag.ExportedType -> failwith "seekReadImplAsScopeRef" - | _ -> failwith "seekReadImplAsScopeRef" + | c -> failwithf "seekReadImplAsScopeRef %O" c and seekReadTypeRefScope (TaggedIndex(tag, idx) ): ILTypeRefScope = match tag with @@ -5703,7 +5704,7 @@ module internal AssemblyReader = | tag when tag = ResolutionScopeTag.ModuleRef -> ILTypeRefScope.Top(ILScopeRef.Module (seekReadModuleRef idx)) | tag when tag = ResolutionScopeTag.AssemblyRef -> ILTypeRefScope.Top(ILScopeRef.Assembly (seekReadAssemblyRef idx)) | tag when tag = ResolutionScopeTag.TypeRef -> ILTypeRefScope.Nested (seekReadTypeRef idx) - | _ -> failwith "seekReadTypeRefScope" + | c -> failwithf "seekReadTypeRefScope %O" c and seekReadOptionalTypeDefOrRef numtypars boxity idx = if idx = TaggedIndex(TypeDefOrRefOrSpecTag.TypeDef, 0) then None @@ -5935,7 +5936,7 @@ module internal AssemblyReader = let tidx = seekReadIndexedRow (getNumRows ILTableNames.TypeDef, (fun i -> i, seekReadTypeDefRowWithExtents i), - (fun r -> r), + id, (fun (_, ((_, _, _, _, _, methodsIdx), (_, endMethodsIdx))) -> if endMethodsIdx <= idx then 1 @@ -6423,7 +6424,7 @@ module internal AssemblyReader = | :? Type as ty -> encodeCustomAttrString ty.FullName | :? (obj[]) as elems -> [| yield! i32AsBytes elems.Length; for elem in elems do yield! encodeCustomAttrPrimValue elem |] - | _ -> failwith "unexpected value in custom attribute" + | c -> failwithf "unexpected value in custom attribute (%O)" c and encodeCustomAttrValue ty (c: obj) = match ty, c with @@ -6691,7 +6692,7 @@ module internal AssemblyReader = (argty, box (char n)), sigptr | ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "Boolean" -> let n, sigptr = sigptr_get_byte bytes sigptr - (argty, box (not (n = 0))), sigptr + (argty, box (n <> 0)), sigptr | ILType.Boxed tspec when tspec.Namespace = USome "System" && tspec.Name = "String" -> //printfn "parsing string, sigptr = %d" sigptr let n, sigptr = sigptr_get_serstring_possibly_null bytes sigptr @@ -6808,7 +6809,7 @@ module internal AssemblyReader = // Auto-clear the cache every 30.0 seconds. // We would use System.Runtime.Caching but some version constraints make this difficult. - let enableAutoClear = try Environment.GetEnvironmentVariable("FSHARP_TPREADER_AUTOCLEAR_OFF") = null with _ -> true + let enableAutoClear = try isNull (Environment.GetEnvironmentVariable "FSHARP_TPREADER_AUTOCLEAR_OFF") with _ -> true let clearSpanDefault = 30000 let clearSpan = try (match Environment.GetEnvironmentVariable("FSHARP_TPREADER_AUTOCLEAR_SPAN") with null -> clearSpanDefault | s -> int32 s) with _ -> clearSpanDefault let lastAccessLock = obj() @@ -6957,9 +6958,9 @@ namespace ProviderImplementation.ProvidedTypes type TxTable<'T2>() = let tab = Dictionary() member __.Get inp f = - if tab.ContainsKey inp then - tab.[inp] - else + match tab.TryGetValue inp with + | true, tabVal -> tabVal + | false, _ -> let res = f() tab.[inp] <- res res @@ -8031,7 +8032,7 @@ namespace ProviderImplementation.ProvidedTypes override __.GetEnumUnderlyingType() = if this.IsEnum then txILType ([| |], [| |]) ilGlobals.typ_Int32 // TODO: in theory the assumption of "Int32" is not accurate for all enums, howver in practice .NET only uses enums with backing field Int32 - else failwithf "not enum type" + else failwithf "not enum type %O" this override __.IsArrayImpl() = false override __.IsByRefImpl() = false @@ -9125,7 +9126,7 @@ namespace ProviderImplementation.ProvidedTypes if i < 0 then let msg = if toTgt then sprintf "The design-time type '%O' utilized by a type provider was not found in the target reference assembly set '%A'. You may be referencing a profile which contains fewer types than those needed by the type provider you are using." t (getTargetAssemblies() |> Seq.toList) - elif getSourceAssemblies() |> Seq.length = 0 then sprintf "A failure occured while determining compilation references" + elif getSourceAssemblies() |> Seq.isEmpty then sprintf "A failure occured while determining compilation references" else sprintf "The target type '%O' utilized by a type provider was not found in the design-time assembly set '%A'. Please report this problem to the project site for the type provider." t (getSourceAssemblies() |> Seq.toList) failwith msg else @@ -9694,10 +9695,10 @@ namespace ProviderImplementation.ProvidedTypes /// Check that the data held at a fixup is some special magic value, as a sanity check /// to ensure the fixup is being placed at a ood location. let checkFixup32 (data: byte[]) offset exp = - if data.[offset + 3] <> b3 exp then failwith "fixup sanity check failed" - if data.[offset + 2] <> b2 exp then failwith "fixup sanity check failed" - if data.[offset + 1] <> b1 exp then failwith "fixup sanity check failed" - if data.[offset] <> b0 exp then failwith "fixup sanity check failed" + if data.[offset + 3] <> b3 exp then failwithf "fixup sanity check failed at %O" offset + if data.[offset + 2] <> b2 exp then failwithf "fixup sanity check failed at %O" offset + if data.[offset + 1] <> b1 exp then failwithf "fixup sanity check failed at %O" offset + if data.[offset] <> b0 exp then failwithf "fixup sanity check failed at %O" offset let applyFixup32 (data:byte[]) offset v = data.[offset] <- b0 v @@ -10125,9 +10126,9 @@ namespace ProviderImplementation.ProvidedTypes let splitNameAt (nm:string) idx = - if idx < 0 then failwith "splitNameAt: idx < 0"; + if idx < 0 then failwithf "splitNameAt: idx < 0: %O" idx; let last = nm.Length - 1 - if idx > last then failwith "splitNameAt: idx > last"; + if idx > last then failwithf "splitNameAt: idx > last: %O %O" idx last; (nm.Substring(0, idx)), (if idx < last then nm.Substring (idx+1, last - idx) else "") @@ -10303,9 +10304,9 @@ namespace ProviderImplementation.ProvidedTypes let lobounded = Array.filter (function (Some _, _) -> true | _ -> false) shape bb.EmitZ32 shape.Length bb.EmitZ32 sized.Length - sized |> Array.iter (function (_, Some sz) -> bb.EmitZ32 sz | _ -> failwith "?") + sized |> Array.iter (function (_, Some sz) -> bb.EmitZ32 sz | c -> failwithf "%O ?" c) bb.EmitZ32 lobounded.Length - lobounded |> Array.iter (function (Some low, _) -> bb.EmitZ32 low | _ -> failwith "?") + lobounded |> Array.iter (function (Some low, _) -> bb.EmitZ32 low | c -> failwithf "%O ?" c) let hasthisToByte hasthis = match hasthis with @@ -10816,8 +10817,8 @@ namespace ProviderImplementation.ProvidedTypes | _ -> () UnsharedRow - [| HasCustomAttribute (fst hca, snd hca) - CustomAttributeType (fst cat, snd cat) + [| HasCustomAttribute hca + CustomAttributeType cat Blob (GetCustomAttrDataAsBlobIdx cenv attr.Data) |] @@ -11081,8 +11082,9 @@ namespace ProviderImplementation.ProvidedTypes if not (origAvailBrFixups.ContainsKey tg) then printfn "%s" ("branch target " + formatCodeLabel tg + " not found in code") let origDest = - if origAvailBrFixups.ContainsKey tg then origAvailBrFixups.[tg] - else 666666 + match origAvailBrFixups.TryGetValue tg with + | true, oaVal -> oaVal + | false, _ -> 666666 let origRelOffset = origDest - origEndOfInstr -128 <= origRelOffset && origRelOffset <= 127 end @@ -11390,7 +11392,7 @@ namespace ProviderImplementation.ProvidedTypes | DT_R4 -> i_stind_r4 | DT_R8 -> i_stind_r8 | DT_REF -> i_stind_ref - | _ -> failwith "stelem") + | x -> failwithf "stelem %O" x) | I_switch labs -> codebuf.RecordReqdBrFixups (i_switch, None) labs @@ -11422,12 +11424,12 @@ namespace ProviderImplementation.ProvidedTypes | (tag, idx) when tag = TypeDefOrRefOrSpecTag.TypeDef -> getUncodedToken ILTableNames.TypeDef idx | (tag, idx) when tag = TypeDefOrRefOrSpecTag.TypeRef -> getUncodedToken ILTableNames.TypeRef idx | (tag, idx) when tag = TypeDefOrRefOrSpecTag.TypeSpec -> getUncodedToken ILTableNames.TypeSpec idx - | _ -> failwith "?" + | x -> failwithf "%O ?" x | ILToken.ILMethod mspec -> match GetMethodSpecAsMethodDefOrRef cenv env (mspec, None) with | (tag, idx) when tag = MethodDefOrRefTag.MethodDef -> getUncodedToken ILTableNames.Method idx | (tag, idx) when tag = MethodDefOrRefTag.MemberRef -> getUncodedToken ILTableNames.MemberRef idx - | _ -> failwith "?" + | x -> failwithf "%O ?" x | ILToken.ILField fspec -> match GetFieldSpecAsFieldDefOrRef cenv env fspec with @@ -11608,7 +11610,7 @@ namespace ProviderImplementation.ProvidedTypes let pc2pos = Array.zeroCreate (instrs.Length+1) let pc2labs = Dictionary() for (KeyValue(lab, pc)) in code.Labels do - if pc2labs.ContainsKey pc then pc2labs.[pc] <- lab :: pc2labs.[pc] else pc2labs.[pc] <- [lab] + match pc2labs.TryGetValue pc with | true, pcVal -> pc2labs.[pc] <- lab :: pcVal | false, _ -> pc2labs.[pc] <- [lab] // Emit the instructions for pc = 0 to instrs.Length do @@ -11832,14 +11834,14 @@ namespace ProviderImplementation.ProvidedTypes SharedRow [| UShort (uint16 idx) UShort (uint16 flags) - TypeOrMethodDef (fst owner, snd owner) + TypeOrMethodDef owner StringE (GetStringHeapIdx cenv gp.Name) TypeDefOrRefOrSpec (TypeDefOrRefOrSpecTag.TypeDef, 0) (* empty kind field in deprecated metadata *) |] else SharedRow [| UShort (uint16 idx) UShort (uint16 flags) - TypeOrMethodDef (fst owner, snd owner) + TypeOrMethodDef owner StringE (GetStringHeapIdx cenv gp.Name) |] and GenTypeAsGenericParamConstraintRow cenv env gpidx ty = @@ -12168,7 +12170,7 @@ namespace ProviderImplementation.ProvidedTypes [| data ULong (match r.Access with ILResourceAccess.Public -> 0x01 | ILResourceAccess.Private -> 0x02) StringE (GetStringHeapIdx cenv r.Name) - Implementation (fst impl, snd impl) |] + Implementation impl |] and GenResourcePass3 cenv r = let idx = AddUnsharedRow cenv ILTableNames.ManifestResource (GetResourceAsManifestResourceRow cenv r) @@ -12266,7 +12268,7 @@ namespace ProviderImplementation.ProvidedTypes ULong 0x0 nelem nselem - Implementation (fst impl, snd impl) |]) + Implementation impl |]) GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.ExportedType, cidx) ce.CustomAttrs GenNestedExportedTypesPass3 cenv cidx ce.Nested @@ -12310,8 +12312,9 @@ namespace ProviderImplementation.ProvidedTypes // Record the entrypoint decl if needed. match m.EntrypointElsewhere with | Some mref -> - if cenv.entrypoint <> None then failwith "duplicate entrypoint" - else cenv.entrypoint <- Some (false, GetModuleRefAsIdx cenv mref) + match cenv.entrypoint with + | Some e -> failwithf "duplicate entrypoint %O" e + | None -> cenv.entrypoint <- Some (false, GetModuleRefAsIdx cenv mref) | None -> () and newGuid (modul: ILModuleDef) = @@ -15445,7 +15448,7 @@ namespace ProviderImplementation.ProvidedTypes and transTypeRefScope (ty: Type): ILTypeRefScope = match ty.DeclaringType with | null -> - if ty.Assembly = null then failwithf "null assembly for type %s" ty.FullName + if isNull ty.Assembly then failwithf "null assembly for type %s" ty.FullName ILTypeRefScope.Top (transScopeRef ty.Assembly) | dt -> ILTypeRefScope.Nested (transTypeRef dt) @@ -15565,7 +15568,7 @@ namespace ProviderImplementation.ProvidedTypes let otb, _ = ((None, ""), ns) ||> List.fold (fun (otb:ILTypeBuilder option, fullName) n -> let fullName = if fullName = "" then n else fullName + "." + n - let priorType = if typeMapExtra.ContainsKey(fullName) then Some typeMapExtra.[fullName] else None + let priorType = match typeMapExtra.TryGetValue fullName with | true, typeVal -> Some typeVal | false, _ -> None let tb = match priorType with | Some tbb -> tbb @@ -15892,7 +15895,7 @@ namespace ProviderImplementation.ProvidedTypes failwithf "expected identical assembly name keys '%s' and '%s'" origAssemblyName newAssemblyName // check the type really exists - if t.Assembly.GetType(tyName) = null then + if isNull (t.Assembly.GetType tyName) then failwithf "couldn't find type '%s' in assembly '%O'" tyName t.Assembly t @@ -16029,7 +16032,7 @@ namespace ProviderImplementation.ProvidedTypes | :? ProvidedMethod as mT when (match methodBaseT.DeclaringType with :? ProvidedTypeDefinition as pt -> pt.IsErased | _ -> true) -> match mT.GetInvokeCode with | Some _ when methodBaseT.DeclaringType.IsInterface -> - failwith "The provided type definition is an interface; therefore, it should not define an implementation for its members." + failwithf "The provided type definition is an interface; therefore, it should not define an implementation for its members. %O" methodBaseT.DeclaringType (* NOTE: These checks appear to fail for generative abstract and virtual methods. | Some _ when mT.IsAbstract -> failwith "The provided method is defined as abstract; therefore, it should not define an implementation."